mirror of
https://github.com/hcengineering/platform.git
synced 2024-12-22 19:11:33 +03:00
Allow to create new team (#2375)
Signed-off-by: muhtimur <timur.mukhamedishin@xored.com>
This commit is contained in:
parent
7e03e8f59d
commit
2cd894e7ad
@ -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,
|
||||
|
@ -50,6 +50,9 @@
|
||||
<path d="M4.92886 7.49494C4.99698 7.22733 5.21443 7 5.49057 7C5.76671 7 5.98416 7.22733 6.05228 7.49494C6.27254 8.36012 7.05683 9 7.99057 9C8.92431 9 9.7086 8.36012 9.92886 7.49494C9.99698 7.22733 10.2144 7 10.4906 7C10.7667 7 10.9842 7.22733 11.0523 7.49494C11.2725 8.36012 12.0568 9 12.9906 9C14.0154 9 14.8602 8.22917 14.9768 7.23566C14.9949 7.08147 14.9544 6.92771 14.885 6.78885L12.267 1.55279C12.0976 1.214 11.7513 1 11.3725 1H4.6086C4.22983 1 3.88357 1.214 3.71418 1.55279L1.09614 6.78885C1.02672 6.92771 0.98621 7.08147 1.00431 7.23566C1.12092 8.22917 1.96573 9 2.99057 9C3.92431 9 4.7086 8.36012 4.92886 7.49494Z"/>
|
||||
<path d="M3.01079 10C4.05518 10 4.97364 9.46684 5.51079 8.65844C6.04793 9.46684 6.9664 10 8.01079 10C9.05518 10 9.97365 9.46684 10.5108 8.65844C11.0479 9.46684 11.9664 10 13.0108 10C13.3538 10 13.6833 9.94247 13.9902 9.83653V13.5C13.9902 14.3284 13.3187 15 12.4902 15H10.5C10.2239 15 10 14.7761 10 14.5V13C10 12.4477 9.55229 12 9 12H7C6.44772 12 6 12.4477 6 13V14.5C6 14.7761 5.77614 15 5.5 15H3.49023C2.66181 15 1.99023 14.3284 1.99023 13.5V9.82201C2.30876 9.9372 2.6524 10 3.01079 10Z"/>
|
||||
</symbol>
|
||||
<symbol id="red-circle" viewBox="0 0 16 16" fill="#ff324cee">
|
||||
<path d="M7,0C3.1,0,0,3.1,0,7c0,3.9,3.1,7,7,7c3.9,0,7-3.1,7-7C14,3.1,10.9,0,7,0z M7,12c-2.8,0-5-2.2-5-5s2.2-5,5-5s5,2.2,5,5S9.8,12,7,12z" />
|
||||
</symbol>
|
||||
|
||||
<symbol id="status-backlog" viewBox="0 0 14 14">
|
||||
<path d="M13.9,7.9l-2-0.3c0-0.2,0-0.4,0-0.7s0-0.4,0-0.7l2-0.3C14,6.4,14,6.7,14,7S14,7.6,13.9,7.9z M13.5,4.3c-0.2-0.6-0.5-1.1-0.9-1.6L11,4c0.3,0.3,0.5,0.7,0.7,1.1L13.5,4.3z M11.3,1.4L10,3C9.7,2.8,9.3,2.5,8.9,2.4l0.8-1.8C10.2,0.8,10.8,1.1,11.3,1.4z M7.9,0.1L7.7,2C7.4,2,7.2,2,7,2S6.6,2,6.3,2l-0.3-2C6.4,0,6.7,0,7,0S7.6,0,7.9,0.1z M4.3,0.5l0.8,1.8C4.7,2.5,4.3,2.8,4,3L2.7,1.4C3.2,1.1,3.8,0.8,4.3,0.5z M1.4,2.7L3,4C2.8,4.3,2.5,4.7,2.4,5.1L0.5,4.3C0.8,3.8,1.1,3.2,1.4,2.7z M0.1,6.1C0,6.4,0,6.7,0,7s0,0.6,0.1,0.9l2-0.3C2,7.4,2,7.2,2,7s0-0.4,0-0.7L0.1,6.1z M0.5,9.7l1.8-0.8C2.5,9.3,2.8,9.7,3,10l-1.6,1.2C1.1,10.8,0.8,10.2,0.5,9.7z M2.7,12.6L4,11c0.3,0.3,0.7,0.5,1.1,0.7l-0.8,1.8C3.8,13.2,3.2,12.9,2.7,12.6z M6.1,13.9l0.3-2c0.2,0,0.4,0,0.7,0s0.4,0,0.7,0l0.3,2C7.6,14,7.3,14,7,14S6.4,14,6.1,13.9z M9.7,13.5l-0.8-1.8c0.4-0.2,0.8-0.4,1.1-0.7l1.2,1.6C10.8,12.9,10.2,13.2,9.7,13.5z M12.6,11.3L11,10c0.3-0.3,0.5-0.7,0.7-1.1l1.8,0.8C13.2,10.2,12.9,10.8,12.6,11.3z" />
|
||||
|
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 31 KiB |
@ -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",
|
||||
|
@ -40,6 +40,11 @@
|
||||
"Completed": "Завершен",
|
||||
"Canceled": "Отменено",
|
||||
"CreateTeam": "Создать команду",
|
||||
"NewTeam": "Новая команда",
|
||||
"TeamTitlePlaceholder": "Название команды",
|
||||
"MakePrivate": "Сделать личным",
|
||||
"MakePrivateDescription": "Только пользователи могут видеть это",
|
||||
"ChooseIcon": "Выбрать иконку",
|
||||
"AddIssue": "Добавить задачу",
|
||||
"NewIssue": "Новая задача",
|
||||
"ResumeDraft": "Восстановить черновик",
|
||||
|
@ -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
|
||||
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
@ -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>
|
@ -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>
|
@ -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}
|
@ -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,
|
||||
@ -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[] }) =>
|
||||
|
@ -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,
|
||||
@ -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,
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
/**
|
||||
@ -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,
|
||||
|
@ -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'
|
||||
|
||||
@ -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>
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user