Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions models/tracker/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -679,6 +679,10 @@ export function createModel (builder: Builder): void {
presenter: tracker.component.ProjectTitlePresenter
})

builder.mixin(tracker.class.Team, core.class.Class, view.mixin.AttributePresenter, {
presenter: tracker.component.TeamPresenter
})

classPresenter(
builder,
tracker.class.Project,
Expand Down
3 changes: 3 additions & 0 deletions plugins/tracker-assets/assets/icons.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions plugins/tracker-assets/lang/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@
"Completed": "Completed",
"Canceled": "Canceled",
"CreateTeam": "Create team",
"NewTeam": "New team",
"TeamTitlePlaceholder": "Team title",
"MakePrivate": "Make private",
"MakePrivateDescription": "Only members can see it",
"ChooseIcon": "Choose icon",
"AddIssue": "Add Issue",
"NewIssue": "New issue",
"ResumeDraft": "Resume draft",
Expand Down
5 changes: 5 additions & 0 deletions plugins/tracker-assets/lang/ru.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@
"Completed": "Завершен",
"Canceled": "Отменено",
"CreateTeam": "Создать команду",
"NewTeam": "Новая команда",
"TeamTitlePlaceholder": "Название команды",
"MakePrivate": "Сделать личным",
"MakePrivateDescription": "Только пользователи могут видеть это",
"ChooseIcon": "Выбрать иконку",
"AddIssue": "Добавить задачу",
"NewIssue": "Новая задача",
"ResumeDraft": "Восстановить черновик",
Expand Down
1 change: 1 addition & 0 deletions plugins/tracker-assets/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ loadMetadata(tracker.icon, {
NewIssue: `${icons}#newissue`,
Magnifier: `${icons}#magnifier`,
Home: `${icons}#home`,
RedCircle: `${icons}#red-circle`,
Labels: `${icons}#priority-nopriority`, // TODO: add icon
DueDate: `${icons}#inbox`, // TODO: add icon
Parent: `${icons}#myissues`, // TODO: add icon
Expand Down
3 changes: 2 additions & 1 deletion plugins/tracker-resources/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
"@hcengineering/attachment-resources": "~0.6.0",
"@hcengineering/workbench": "~0.6.2",
"@hcengineering/attachment": "~0.6.1",
"@hcengineering/chunter-resources": "~0.6.0"
"@hcengineering/chunter-resources": "~0.6.0",
"@hcengineering/workbench-resources": "~0.6.1"
}
}
84 changes: 84 additions & 0 deletions plugins/tracker-resources/src/components/teams/CreateTeam.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
<!--
// Copyright © 2022 Hardcore Engineering Inc.
//
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. You may
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//
// See the License for the specific language governing permissions and
// limitations under the License.
-->
<script lang="ts">
import { createEventDispatcher } from 'svelte'
import { Button, EditBox, eventToHTMLElement, Label, showPopup, ToggleWithLabel } from '@hcengineering/ui'
import { getClient, SpaceCreateCard } from '@hcengineering/presentation'
import core, { getCurrentAccount, Ref } from '@hcengineering/core'
import { IssueStatus } from '@hcengineering/tracker'
import { StyledTextBox } from '@hcengineering/text-editor'
import { Asset } from '@hcengineering/platform'
import tracker from '../../plugin'
import TeamIconChooser from './TeamIconChooser.svelte'

let name: string = ''
let description: string = ''
let isPrivate: boolean = false
let icon: Asset | undefined = undefined

const dispatch = createEventDispatcher()
const client = getClient()

async function createTeam () {
await client.createDoc(tracker.class.Team, core.space.Space, {
name,
description,
private: isPrivate,
members: [getCurrentAccount()._id],
archived: false,
identifier: name.toUpperCase().replaceAll(' ', '_'),
sequence: 0,
issueStatuses: 0,
defaultIssueStatus: '' as Ref<IssueStatus>,
icon
})
}

function chooseIcon (ev: MouseEvent) {
showPopup(TeamIconChooser, { icon }, eventToHTMLElement(ev), (result) => {
if (result !== undefined && result !== null) {
icon = result
}
})
}
</script>

<SpaceCreateCard
label={tracker.string.NewTeam}
okAction={createTeam}
canSave={name.length > 0}
on:close={() => {
dispatch('close')
}}
>
<EditBox bind:value={name} placeholder={tracker.string.TeamTitlePlaceholder} kind={'large-style'} focus />
<StyledTextBox
alwaysEdit
showButtons={false}
bind:content={description}
placeholder={tracker.string.IssueDescriptionPlaceholder}
/>
<ToggleWithLabel
label={tracker.string.MakePrivate}
description={tracker.string.MakePrivateDescription}
bind:on={isPrivate}
/>
<div class="flex-between">
<div class="caption">
<Label label={tracker.string.ChooseIcon} />
</div>
<Button icon={icon ?? tracker.icon.Home} kind="no-border" size="medium" on:click={chooseIcon} />
</div>
</SpaceCreateCard>
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<script lang="ts">
import { Metadata } from '@hcengineering/platform'
import presentation, { Card } from '@hcengineering/presentation'
import { Button } from '@hcengineering/ui'
import tracker from '../../plugin'
import { createEventDispatcher } from 'svelte'

export let icon: Metadata<string> | undefined = undefined

const dispatch = createEventDispatcher()
const icons = [tracker.icon.Home, tracker.icon.RedCircle]

function save () {
dispatch('close', icon)
}
</script>

<Card
label={tracker.string.ChooseIcon}
okLabel={presentation.string.Save}
okAction={save}
canSave={icon !== undefined}
on:close={() => {
dispatch('close')
}}
>
<div class="float-left-box">
{#each icons as obj}
<div class="float-left p-2">
<Button
icon={obj}
size="medium"
kind={obj === icon ? 'primary' : 'transparent'}
on:click={() => {
icon = obj
}}
/>
</div>
{/each}
</div>
</Card>
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<!--
// Copyright © 2022 Hardcore Engineering Inc.
//
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. You may
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//
// See the License for the specific language governing permissions and
// limitations under the License.
-->
<script lang="ts">
import { Ref, Space } from '@hcengineering/core'
import { Team } from '@hcengineering/tracker'
import { SpacesNavModel } from '@hcengineering/workbench'
import { TreeNode, SpecialElement } from '@hcengineering/workbench-resources'
import { createEventDispatcher } from 'svelte'

export let space: Team
export let model: SpacesNavModel
export let currentSpace: Ref<Space> | undefined
export let currentSpecial: string | undefined
export let selectSpace: Function
export let getActions: Function

const dispatch = createEventDispatcher()
</script>

{#if model.specials}
<TreeNode icon={space?.icon ?? model.icon} title={space.name} indent={'ml-2'} actions={() => getActions(space)}>
{#each model.specials as special}
<SpecialElement
indent={'ml-4'}
label={special.label}
icon={special.icon}
on:click={() => dispatch('special', special.id)}
selected={currentSpace === space._id && special.id === currentSpecial}
on:click={() => {
selectSpace(space._id, special.id)
}}
/>
{/each}
</TreeNode>
{/if}
7 changes: 6 additions & 1 deletion plugins/tracker-resources/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,9 @@ import IssueTemplates from './components/templates/IssueTemplates.svelte'
import EditIssueTemplate from './components/templates/EditIssueTemplate.svelte'
import TemplateEstimationEditor from './components/templates/EstimationEditor.svelte'

import CreateTeam from './components/teams/CreateTeam.svelte'
import TeamPresenter from './components/teams/TeamPresenter.svelte'

export async function queryIssue<D extends Issue> (
_class: Ref<Class<D>>,
client: Client,
Expand Down Expand Up @@ -216,7 +219,9 @@ export default async (): Promise<Resources> => ({
IssueTemplates,
IssueTemplatePresenter,
EditIssueTemplate,
TemplateEstimationEditor
TemplateEstimationEditor,
CreateTeam,
TeamPresenter
},
completion: {
IssueQuery: async (client: Client, query: string, filter?: { in?: RelatedDocument[], nin?: RelatedDocument[] }) =>
Expand Down
6 changes: 6 additions & 0 deletions plugins/tracker-resources/src/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,11 @@ export default mergeIds(trackerId, tracker, {
Completed: '' as IntlString,
Canceled: '' as IntlString,
CreateTeam: '' as IntlString,
NewTeam: '' as IntlString,
TeamTitlePlaceholder: '' as IntlString,
MakePrivate: '' as IntlString,
MakePrivateDescription: '' as IntlString,
ChooseIcon: '' as IntlString,
AddIssue: '' as IntlString,
NewIssue: '' as IntlString,
ResumeDraft: '' as IntlString,
Expand Down Expand Up @@ -273,6 +278,7 @@ export default mergeIds(trackerId, tracker, {
DueDatePresenter: '' as AnyComponent,
EditIssueTemplate: '' as AnyComponent,
CreateTeam: '' as AnyComponent,
TeamPresenter: '' as AnyComponent,
NewIssueHeader: '' as AnyComponent,
IconPresenter: '' as AnyComponent,
LeadPresenter: '' as AnyComponent,
Expand Down
3 changes: 2 additions & 1 deletion plugins/tracker/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,11 @@ export interface IssueStatusCategory extends Doc {
* @public
*/
export interface Team extends Space {
teamLogo?: string | null
identifier: string // Team identifier
sequence: number
issueStatuses: number
defaultIssueStatus: Ref<IssueStatus>
icon?: Asset
}

/**
Expand Down Expand Up @@ -413,6 +413,7 @@ export default plugin(trackerId, {
NewIssue: '' as Asset,
Magnifier: '' as Asset,
Home: '' as Asset,
RedCircle: '' as Asset,
Labels: '' as Asset,
DueDate: '' as Asset,
Parent: '' as Asset,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,11 @@
import preference from '@hcengineering/preference'
import { getClient } from '@hcengineering/presentation'
import { Action, getCurrentLocation, IconAdd, IconEdit, IconSearch, navigate, showPopup } from '@hcengineering/ui'
import { getActions as getContributedActions } from '@hcengineering/view-resources'
import { getActions as getContributedActions, getObjectPresenter } from '@hcengineering/view-resources'
import { SpacesNavModel } from '@hcengineering/workbench'
import { createEventDispatcher } from 'svelte'
import plugin from '../../plugin'
import { classIcon, getSpaceName } from '../../utils'
import SpecialElement from './SpecialElement.svelte'
import TreeItem from './TreeItem.svelte'
import TreeNode from './TreeNode.svelte'

Expand Down Expand Up @@ -113,36 +112,33 @@

<TreeNode label={model.label} parent actions={async () => getParentActions()} indent={'ml-2'}>
{#each spaces as space (space._id)}
{#if model.specials}
<TreeNode icon={model.icon} title={space.name} indent={'ml-2'} actions={() => getActions(space)}>
{#each model.specials as special}
<SpecialElement
{#await getObjectPresenter(client, space._class, { key: '' }) then presenter}
{#if model.specials && presenter}
<svelte:component
this={presenter.presenter}
{space}
{model}
{currentSpace}
{currentSpecial}
{getActions}
{selectSpace}
/>
{:else}
{#await getSpaceName(client, space) then name}
<TreeItem
indent={'ml-4'}
label={special.label}
icon={special.icon}
on:click={() => dispatch('special', special.id)}
selected={currentSpace === space._id && special.id === currentSpecial}
_id={space._id}
title={name}
icon={classIcon(client, space._class)}
selected={currentSpace === space._id}
actions={() => getActions(space)}
bold={isChanged(space, $lastViews)}
on:click={() => {
selectSpace(space._id, special.id)
selectSpace(space._id)
}}
/>
{/each}
</TreeNode>
{:else}
{#await getSpaceName(client, space) then name}
<TreeItem
indent={'ml-4'}
_id={space._id}
title={name}
icon={classIcon(client, space._class)}
selected={currentSpace === space._id}
actions={() => getActions(space)}
bold={isChanged(space, $lastViews)}
on:click={() => {
selectSpace(space._id)
}}
/>
{/await}
{/if}
{/await}
{/if}
{/await}
{/each}
</TreeNode>
2 changes: 2 additions & 0 deletions plugins/workbench-resources/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ function hasArchiveSpaces (spaces: Space[]): boolean {
return spaces.find((sp) => sp.archived) !== undefined
}
export { default as SpaceBrowser } from './components/SpaceBrowser.svelte'
export { default as TreeNode } from './components/navigator/TreeNode.svelte'
export { default as SpecialElement } from './components/navigator/SpecialElement.svelte'
export default async (): Promise<Resources> => ({
component: {
WorkbenchApp,
Expand Down