diff --git a/packages/ui/src/components/Modal.svelte b/packages/ui/src/components/Modal.svelte index 1b63f232d9..4b422c5e72 100644 --- a/packages/ui/src/components/Modal.svelte +++ b/packages/ui/src/components/Modal.svelte @@ -26,6 +26,7 @@ export let label: IntlString | undefined = undefined export let labelProps: any | undefined = undefined export let okAction: () => Promise | void = () => {} + export let okLoading: boolean = false export let okTooltip: LabelAndProps | undefined = undefined export let onCancel: (() => void) | undefined = undefined export let canSave: boolean = false @@ -112,6 +113,7 @@ size={type === 'type-aside' ? 'large' : 'medium'} tooltip={okTooltip} label={okLabel} + loading={okLoading} on:click={okAction} disabled={!canSave} /> diff --git a/plugins/card-resources/src/components/CreateCardPopup.svelte b/plugins/card-resources/src/components/CreateCardPopup.svelte index 84fe8139a0..b52f4504ad 100644 --- a/plugins/card-resources/src/components/CreateCardPopup.svelte +++ b/plugins/card-resources/src/components/CreateCardPopup.svelte @@ -47,6 +47,8 @@ let description: Markup = EmptyMarkup let collaborators: Ref[] = [me] + let creating = false + async function addCollaborators (): Promise { const accounts = collaborators .filter((it) => it !== me) @@ -61,22 +63,28 @@ async function okAction (): Promise { if (_space === undefined) return - if (extension?.canCreate) { - const fn = await getResource(extension.canCreate) - const res = await fn(_space, data) - if (res === false) { - dispatch('close') - return - } else if (typeof res === 'string') { - dispatch('close', res) - return + try { + creating = true + + if (extension?.canCreate) { + const fn = await getResource(extension.canCreate) + const res = await fn(_space, data) + if (res === false) { + dispatch('close') + return + } else if (typeof res === 'string') { + dispatch('close', res) + return + } } + + await createCard(type, _space, data, description, _id) + await addCollaborators() + + dispatch('close', _id) + } finally { + creating = false } - - await createCard(type, _space, data, description, _id) - await addCollaborators() - - dispatch('close', _id) } function handleCancel (): void { @@ -132,6 +140,7 @@ width="large" okLabel={presentation.string.Create} {okAction} + okLoading={creating} canSave={data.title != null && data.title.trim().length > 0 && _space != null} onCancel={handleCancel} on:close diff --git a/plugins/communication-resources/src/components/DirectIcon.svelte b/plugins/communication-resources/src/components/DirectIcon.svelte index aa24223e09..754ce21d74 100644 --- a/plugins/communication-resources/src/components/DirectIcon.svelte +++ b/plugins/communication-resources/src/components/DirectIcon.svelte @@ -97,17 +97,17 @@ it._id !== me) ?? persons[0]} size={avatarSize} name={persons[0].name} showStatus={false} clipPath="url(#direct-count-marker)" /> - {#if persons.length > 9} + {#if persons.length > 10} 9+ {:else} - {persons.length} + {persons.length - 1} {/if} diff --git a/server-plugins/card-resources/src/index.ts b/server-plugins/card-resources/src/index.ts index 357d25048c..ebee2ab0ad 100644 --- a/server-plugins/card-resources/src/index.ts +++ b/server-plugins/card-resources/src/index.ts @@ -50,7 +50,7 @@ import { MessageEventType } from '@hcengineering/communication-sdk-types' import { getEmployee, getPersonSpaces } from '@hcengineering/server-contact' -import contact, { Employee, Person } from '@hcengineering/contact' +import contact, { Employee, formatName, Person } from '@hcengineering/contact' import communication, { Direct } from '@hcengineering/communication' import { CardPeer } from '@hcengineering/communication-types' @@ -516,35 +516,45 @@ async function createThreadCardPeers (direct: Direct, doc: Card, control: Trigge return res } +function getDirectTitle (employees: Employee[], me: Ref): string { + if (employees.length === 1) { + return employees.map((e) => formatName(e.name)).join(', ') + } else { + return employees + .filter((it) => it._id !== me) + .map((e) => formatName(e.name)) + .join(', ') + } +} + async function createDirectCardPeers (doc: Card, members: Ref[], control: TriggerControl): Promise { const res: Tx[] = [] const cardIds = new Map, Ref>([[doc._id, doc.space]]) if (members.length === 0) return [] - const personSpaces = (await getPersonSpaces(control)).filter( - (it) => it._id !== doc.space && members.includes(it.person) - ) - if (personSpaces.length === 0) return [] - const accounts = ( - await control.findAll(control.ctx, contact.mixin.Employee, { - _id: { $in: personSpaces.map((it) => it.person) as Ref[] } - }) - ) - .map((it) => it.personUuid) - .filter(notEmpty) + const personSpaces = (await getPersonSpaces(control)).filter((it) => members.includes(it.person)) + if (personSpaces.length <= 1) return [] + const employees = await control.findAll(control.ctx, contact.mixin.Employee, { + _id: { $in: personSpaces.map((it) => it.person) as Ref[] } + }) + const accounts = employees.map((it) => it.personUuid).filter(notEmpty) if (accounts.length === 0) return [] // TODO: create directs in person_workspace for (const personSpace of personSpaces) { + if (personSpace._id === doc.space) continue const _id = generateId() const _class = doc._class cardIds.set(_id, personSpace._id) + const title = getDirectTitle(employees, personSpace.person) + res.push( control.txFactory.createTxCreateDoc( _class, personSpace._id, { - ...doc + ...doc, + title }, _id )