From 984c7d90abe5f1d50eb3df604c0eefe716dfd8fc Mon Sep 17 00:00:00 2001 From: Victor Ilyushchenko Date: Wed, 29 Jan 2025 17:18:46 +0300 Subject: [PATCH 01/15] EZQMS-1392: Obsolete documents (#7833) Signed-off-by: Victor Ilyushchenko --- models/controlled-documents/src/index.ts | 31 ++++++++++++-- models/controlled-documents/src/plugin.ts | 1 + .../controlled-documents-assets/lang/cs.json | 7 +++- .../controlled-documents-assets/lang/de.json | 7 +++- .../controlled-documents-assets/lang/en.json | 5 +++ .../controlled-documents-assets/lang/fr.json | 7 +++- .../controlled-documents-assets/lang/it.json | 7 +++- .../controlled-documents-assets/lang/ru.json | 7 +++- .../controlled-documents-assets/lang/zh.json | 7 +++- .../src/components/DocumentsContainer.svelte | 3 +- .../components/document/EditDocRelease.svelte | 1 + .../document/common/DocumentStatusTag.svelte | 6 +-- .../hierarchy/DocHierarchyLevel.svelte | 9 ++-- .../print/DocumentPrintTitlePage.svelte | 5 ++- .../src/index.ts | 42 +++++++++++++++++++ .../src/plugin.ts | 1 + .../editors/document/canCreateNewDraft.ts | 3 +- .../src/utils.ts | 9 +++- plugins/controlled-documents/src/plugin.ts | 5 +++ plugins/controlled-documents/src/types.ts | 3 +- 20 files changed, 143 insertions(+), 23 deletions(-) diff --git a/models/controlled-documents/src/index.ts b/models/controlled-documents/src/index.ts index fed07c2329..0885da5aee 100644 --- a/models/controlled-documents/src/index.ts +++ b/models/controlled-documents/src/index.ts @@ -150,6 +150,7 @@ export function createModel (builder: Builder): void { ['inProgress', documents.string.InProgress, {}], ['effective', documents.string.Effective, {}], ['archived', documents.string.Archived, {}], + ['obsolete', documents.string.Obsolete, {}], ['all', documents.string.All, {}] ] } @@ -170,6 +171,7 @@ export function createModel (builder: Builder): void { ['effective', documents.string.Effective, {}], ['inProgress', documents.string.InProgress, {}], ['archived', documents.string.Archived, {}], + ['obsolete', documents.string.Obsolete, {}], ['all', documents.string.All, {}] ] } @@ -774,16 +776,37 @@ export function createModel (builder: Builder): void { documents.action.DeleteDocument ) + // createAction( + // builder, + // { + // action: documents.actionImpl.ArchiveDocument, + // label: view.string.Archive, + // icon: view.icon.Archive, + // input: 'any', + // category: view.category.General, + // target: documents.class.Document, + // visibilityTester: documents.function.CanArchiveDocument, + // query: { + // state: DocumentState.Effective + // }, + // context: { + // mode: ['context', 'browser'], + // group: 'remove' + // } + // }, + // documents.action.ArchiveDocument + // ) + createAction( builder, { - action: documents.actionImpl.ArchiveDocument, - label: view.string.Archive, + action: documents.actionImpl.MakeDocumentObsolete, + label: documents.string.MakeDocumentObsolete, icon: view.icon.Archive, input: 'any', category: view.category.General, target: documents.class.Document, - visibilityTester: documents.function.CanArchiveDocument, + visibilityTester: documents.function.CanMakeDocumentObsolete, query: { state: DocumentState.Effective }, @@ -792,7 +815,7 @@ export function createModel (builder: Builder): void { group: 'remove' } }, - documents.action.ArchiveDocument + documents.action.MakeDocumentObsolete ) createAction( diff --git a/models/controlled-documents/src/plugin.ts b/models/controlled-documents/src/plugin.ts index 64e6f5692b..8d9c54b779 100644 --- a/models/controlled-documents/src/plugin.ts +++ b/models/controlled-documents/src/plugin.ts @@ -68,6 +68,7 @@ export default mergeIds(documentsId, documents, { TransferTemplate: '' as ViewAction, DeleteDocument: '' as ViewAction, ArchiveDocument: '' as ViewAction, + MakeDocumentObsolete: '' as ViewAction, TransferDocument: '' as ViewAction, EditDocSpace: '' as ViewAction }, diff --git a/plugins/controlled-documents-assets/lang/cs.json b/plugins/controlled-documents-assets/lang/cs.json index e2619c2ef8..72564318c7 100644 --- a/plugins/controlled-documents-assets/lang/cs.json +++ b/plugins/controlled-documents-assets/lang/cs.json @@ -295,7 +295,12 @@ "CreateFolder": "Vytvořit novou složku", "RenameFolder": "Přejmenovat složku", - "CreateChildFolder": "Vytvořit podsložku" + "CreateChildFolder": "Vytvořit podsložku", + + "Obsolete": "Zastaralé", + "MakeDocumentObsolete": "Označit jako zastaralé", + "MakeDocumentObsoleteDialog": "Označit {count, plural, one {dokument jako zastaralý} other {dokumenty jako zastaralé}}", + "MakeDocumentObsoleteConfirm": "Opravdu chcete označit následující dokumenty jako zastaralé: {titles}?" }, "controlledDocStates": { "Empty": "", diff --git a/plugins/controlled-documents-assets/lang/de.json b/plugins/controlled-documents-assets/lang/de.json index 22ef0595b0..3c44f68fda 100644 --- a/plugins/controlled-documents-assets/lang/de.json +++ b/plugins/controlled-documents-assets/lang/de.json @@ -302,7 +302,12 @@ "CreateFolder": "Neuen Ordner erstellen", "RenameFolder": "Ordner umbenennen", - "CreateChildFolder": "Unterordner erstellen" + "CreateChildFolder": "Unterordner erstellen", + + "Obsolete": "Veraltet", + "MakeDocumentObsolete": "Als veraltet markieren", + "MakeDocumentObsoleteDialog": "{count, plural, one {Dokument als veraltet markieren} other {Dokumente als veraltet markieren}}", + "MakeDocumentObsoleteConfirm": "Möchten Sie die folgenden Dokumente wirklich als veraltet markieren: {titles}?" }, "controlledDocStates": { "Empty": "", diff --git a/plugins/controlled-documents-assets/lang/en.json b/plugins/controlled-documents-assets/lang/en.json index 0ad18214f6..9bbde8a196 100644 --- a/plugins/controlled-documents-assets/lang/en.json +++ b/plugins/controlled-documents-assets/lang/en.json @@ -119,6 +119,11 @@ "Archived": "Archived", "Deleted": "Deleted", "MetaAbstract": "Abstract", + + "Obsolete": "Obsolete", + "MakeDocumentObsolete": "Mark as obsolete", + "MakeDocumentObsoleteDialog": "Mark {count, plural, =0 {document} other {documents}} as obsolete", + "MakeDocumentObsoleteConfirm": "Do you really want to mark the following documents as obsolete: {titles}?", "ContentTab": "Content", "TeamTab": "Team", diff --git a/plugins/controlled-documents-assets/lang/fr.json b/plugins/controlled-documents-assets/lang/fr.json index 9100cfe799..5ccba0a666 100644 --- a/plugins/controlled-documents-assets/lang/fr.json +++ b/plugins/controlled-documents-assets/lang/fr.json @@ -262,7 +262,12 @@ "CreateFolder": "Créer un nouveau dossier", "RenameFolder": "Renommer le dossier", - "CreateChildFolder": "Créer un sous-dossier" + "CreateChildFolder": "Créer un sous-dossier", + + "Obsolete": "Obsolète", + "MakeDocumentObsolete": "Marquer comme obsolète", + "MakeDocumentObsoleteDialog": "Marquer {count, plural, one {le document comme obsolète} other {les documents comme obsolètes}}", + "MakeDocumentObsoleteConfirm": "Voulez-vous vraiment marquer les documents suivants comme obsolètes : {titles} ?" }, "controlledDocStates": { "Empty": "", diff --git a/plugins/controlled-documents-assets/lang/it.json b/plugins/controlled-documents-assets/lang/it.json index 61fe609756..5fcaf63e52 100644 --- a/plugins/controlled-documents-assets/lang/it.json +++ b/plugins/controlled-documents-assets/lang/it.json @@ -260,7 +260,12 @@ "CreateFolder": "Crea nuova cartella", "RenameFolder": "Rinomina cartella", - "CreateChildFolder": "Crea sottocartella" + "CreateChildFolder": "Crea sottocartella", + + "Obsolete": "Obsoleto", + "MakeDocumentObsolete": "Segna come obsoleto", + "MakeDocumentObsoleteDialog": "Segna {count, plural, one {il documento come obsoleto} other {i documenti come obsoleti}}", + "MakeDocumentObsoleteConfirm": "Vuoi davvero segnare i seguenti documenti come obsoleti: {titles}?" }, "controlledDocStates": { "Empty": "", diff --git a/plugins/controlled-documents-assets/lang/ru.json b/plugins/controlled-documents-assets/lang/ru.json index 3afb969e8d..9093c92ee1 100644 --- a/plugins/controlled-documents-assets/lang/ru.json +++ b/plugins/controlled-documents-assets/lang/ru.json @@ -304,7 +304,12 @@ "CreateFolder": "Создать новую папку", "RenameFolder": "Переименовать папку", - "CreateChildFolder": "Создать подпапку" + "CreateChildFolder": "Создать подпапку", + + "Obsolete": "Устаревший", + "MakeDocumentObsolete": "Пометить как устаревшее", + "MakeDocumentObsoleteDialog": "Пометить {count, plural, one {документ как устаревший} other {документы как устаревшие}}", + "MakeDocumentObsoleteConfirm": "Вы действительно хотите пометить следующие документы как устаревшие: {titles}?" }, "controlledDocStates": { "Empty": "", diff --git a/plugins/controlled-documents-assets/lang/zh.json b/plugins/controlled-documents-assets/lang/zh.json index 83021ea4c1..f7ac73621a 100644 --- a/plugins/controlled-documents-assets/lang/zh.json +++ b/plugins/controlled-documents-assets/lang/zh.json @@ -301,7 +301,12 @@ "CreateFolder": "创建新文件夹", "RenameFolder": "重命名文件夹", - "CreateChildFolder": "创建子文件夹" + "CreateChildFolder": "创建子文件夹", + + "Obsolete": "已过时", + "MakeDocumentObsolete": "标记为过时", + "MakeDocumentObsoleteDialog": "标记 {count, plural, one {文档为过时} other {文档为过时}}", + "MakeDocumentObsoleteConfirm": "您确定要将以下文档标记为过时吗:{titles}?" }, "controlledDocStates": { "Empty": "", diff --git a/plugins/controlled-documents-resources/src/components/DocumentsContainer.svelte b/plugins/controlled-documents-resources/src/components/DocumentsContainer.svelte index 0f7cfbe967..6ca5759f70 100644 --- a/plugins/controlled-documents-resources/src/components/DocumentsContainer.svelte +++ b/plugins/controlled-documents-resources/src/components/DocumentsContainer.svelte @@ -57,9 +57,10 @@ $: inProgress = { state: { $in: [DocumentState.Draft] }, space: { $in: spaces } } $: effective = { state: { $in: [DocumentState.Effective] }, space: { $in: spaces } } $: archived = { state: { $in: [DocumentState.Archived, DocumentState.Deleted] }, space: { $in: spaces } } + $: obsolete = { state: { $in: [DocumentState.Obsolete] }, space: { $in: spaces } } $: all = { space: { $in: spaces } } - $: queries = { inProgress, effective, archived, all } + $: queries = { inProgress, effective, archived, obsolete, all } $: mode = $resolvedLocationStore.query?.mode ?? undefined $: if (mode === undefined || (queries as any)[mode] === undefined) { diff --git a/plugins/controlled-documents-resources/src/components/document/EditDocRelease.svelte b/plugins/controlled-documents-resources/src/components/document/EditDocRelease.svelte index 44456f32e4..efe2ffc34c 100644 --- a/plugins/controlled-documents-resources/src/components/document/EditDocRelease.svelte +++ b/plugins/controlled-documents-resources/src/components/document/EditDocRelease.svelte @@ -118,6 +118,7 @@ DocumentState.Archived, DocumentState.Deleted, DocumentState.Effective, + DocumentState.Obsolete, ControlledDocumentState.InApproval, ControlledDocumentState.Approved, ControlledDocumentState.ToReview diff --git a/plugins/controlled-documents-resources/src/components/document/common/DocumentStatusTag.svelte b/plugins/controlled-documents-resources/src/components/document/common/DocumentStatusTag.svelte index 5939ec0f64..ec664b47cc 100644 --- a/plugins/controlled-documents-resources/src/components/document/common/DocumentStatusTag.svelte +++ b/plugins/controlled-documents-resources/src/components/document/common/DocumentStatusTag.svelte @@ -37,11 +37,11 @@ } &.obsolete { - background: var(--theme-state-ghost-background-color); - border-color: var(--theme-state-ghost-border-color); + background: var(--theme-state-negative-background-color); + border-color: var(--theme-state-negative-border-color); .label { - color: var(--theme-state-ghost-color); + color: var(--theme-state-negative-color); } } diff --git a/plugins/controlled-documents-resources/src/components/hierarchy/DocHierarchyLevel.svelte b/plugins/controlled-documents-resources/src/components/hierarchy/DocHierarchyLevel.svelte index f878052779..3be626ba9c 100644 --- a/plugins/controlled-documents-resources/src/components/hierarchy/DocHierarchyLevel.svelte +++ b/plugins/controlled-documents-resources/src/components/hierarchy/DocHierarchyLevel.svelte @@ -148,9 +148,10 @@ {@const title = doc ? getDocumentName(doc) : meta?.title ?? ''} {@const docid = doc?._id ?? prjdoc._id} {@const isFolder = prjdoc.document === documents.ids.Folder} + {@const isObsolete = doc ? doc.state === DocumentState.Obsolete : false} + {@const children = metaid ? childrenByParent[metaid] ?? [] : []} - {#if metaid} - {@const children = childrenByParent[metaid] ?? []} + {#if metaid && (!isObsolete || children.length > 0)} {@const isDraggedOver = draggedOver === metaid}
{#if isDraggedOver} @@ -160,12 +161,12 @@ _id={docid} icon={isFolder ? documents.icon.Folder : documents.icon.Document} iconProps={{ - fill: 'currentColor' + fill: isObsolete ? 'var(--dangerous-bg-color)' : 'currentColor' }} {title} selected={selected === docid || selected === prjdoc._id} isFold - empty={children.length === 0 || children === undefined} + empty={children.length === 0} actions={getMoreActions !== undefined ? () => getDocMoreActions(prjdoc) : undefined} {level} {collapsedPrefix} diff --git a/plugins/controlled-documents-resources/src/components/print/DocumentPrintTitlePage.svelte b/plugins/controlled-documents-resources/src/components/print/DocumentPrintTitlePage.svelte index ddc44074d4..a6dade36ef 100644 --- a/plugins/controlled-documents-resources/src/components/print/DocumentPrintTitlePage.svelte +++ b/plugins/controlled-documents-resources/src/components/print/DocumentPrintTitlePage.svelte @@ -38,6 +38,9 @@ case DocumentState.Archived: statusWMLabel = plugin.string.Archived break + case DocumentState.Obsolete: + statusWMLabel = plugin.string.Obsolete + break } } @@ -51,7 +54,7 @@ $controlledDocument != null && (isOrgSpace ? $controlledDocument.state !== DocumentState.Effective - : ![DocumentState.Effective, DocumentState.Archived].includes($controlledDocument.state)) + : ![DocumentState.Effective, DocumentState.Obsolete, DocumentState.Archived].includes($controlledDocument.state)) {#if $controlledDocument !== null} diff --git a/plugins/controlled-documents-resources/src/index.ts b/plugins/controlled-documents-resources/src/index.ts index 5f22385e3f..e0b32883c5 100644 --- a/plugins/controlled-documents-resources/src/index.ts +++ b/plugins/controlled-documents-resources/src/index.ts @@ -182,6 +182,24 @@ async function archiveDocuments (obj: Document | Document[]): Promise { }) } +async function makeDocumentObsolete (obj: Document | Document[]): Promise { + const docs = Array.isArray(obj) ? obj : [obj] + const docNames = docs.map((d) => `${d.title} (${d.prefix}-${d.seqNumber})`).join(', ') + + showPopup(MessageBox, { + label: documents.string.MakeDocumentObsoleteDialog, + labelProps: { count: docs.length }, + message: documents.string.MakeDocumentObsoleteConfirm, + params: { titles: docNames }, + action: async () => { + const client = getClient() + for (const doc of docs) { + await client.update(doc, { state: DocumentState.Obsolete }) + } + } + }) +} + async function canDeleteDocument (obj?: Doc | Doc[]): Promise { if (obj == null) { return false @@ -220,6 +238,28 @@ async function canArchiveDocument (obj?: Doc | Doc[]): Promise { ).then((res) => res.every((r) => r)) } +async function canMakeDocumentObsolete (obj?: Doc | Doc[]): Promise { + if (obj == null) { + return false + } + + const objs = (Array.isArray(obj) ? obj : [obj]) as Document[] + const currentUser = getCurrentAccount() as PersonAccount + const isOwner = objs.every((doc) => doc.owner === currentUser.person) + + if (isOwner) { + return true + } + + const spaces = new Set(objs.map((doc) => doc.space)) + + return await Promise.all( + Array.from(spaces).map( + async (space) => await checkPermission(getClient(), documents.permission.ArchiveDocument, space) + ) + ).then((res) => res.every((r) => r)) +} + async function canOpenDocument (obj?: ProjectDocument | ProjectDocument[]): Promise { if (obj == null) { return false @@ -411,6 +451,7 @@ export default async (): Promise => ({ GetDocumentMetaLinkFragment: getDocumentMetaLinkFragment, CanDeleteDocument: canDeleteDocument, CanArchiveDocument: canArchiveDocument, + CanMakeDocumentObsolete: canMakeDocumentObsolete, CanTransferDocument: canTransferDocument, CanOpenDocument: canOpenDocument, CanPrintDocument: canPrintDocument, @@ -430,6 +471,7 @@ export default async (): Promise => ({ CreateFolder: createFolder, DeleteDocument: deleteDocuments, ArchiveDocument: archiveDocuments, + MakeDocumentObsolete: makeDocumentObsolete, TransferDocument: transferDocuments, EditDocSpace: editDocSpace }, diff --git a/plugins/controlled-documents-resources/src/plugin.ts b/plugins/controlled-documents-resources/src/plugin.ts index 164838e64e..b91b51218d 100644 --- a/plugins/controlled-documents-resources/src/plugin.ts +++ b/plugins/controlled-documents-resources/src/plugin.ts @@ -242,6 +242,7 @@ export default mergeIds(documentsId, documents, { GetDocumentMetaLinkFragment: '' as Resource<(doc: Doc, props: Record) => Promise>, CanDeleteDocument: '' as Resource<(doc?: Doc | Doc[]) => Promise>, CanArchiveDocument: '' as Resource<(doc?: Doc | Doc[]) => Promise>, + CanMakeDocumentObsolete: '' as Resource<(doc?: Doc | Doc[]) => Promise>, CanOpenDocument: '' as Resource<(doc?: Doc | Doc[]) => Promise>, CanPrintDocument: '' as Resource<(doc?: Doc | Doc[]) => Promise>, CanTransferDocument: '' as Resource<(doc?: Doc | Doc[]) => Promise>, diff --git a/plugins/controlled-documents-resources/src/stores/editors/document/canCreateNewDraft.ts b/plugins/controlled-documents-resources/src/stores/editors/document/canCreateNewDraft.ts index faad3302cf..bc8d6cca34 100644 --- a/plugins/controlled-documents-resources/src/stores/editors/document/canCreateNewDraft.ts +++ b/plugins/controlled-documents-resources/src/stores/editors/document/canCreateNewDraft.ts @@ -21,9 +21,10 @@ export const $canCreateNewDraft = combine($controlledDocument, $documentAllVersi if (document == null) return false const currentIndex = versions.findIndex((p) => p._id === document._id) + const forbiddenStates = [DocumentState.Draft, DocumentState.Obsolete] return ( versions.slice(0, currentIndex).every((p) => p.state === DocumentState.Deleted) && - document.state !== DocumentState.Draft + !forbiddenStates.includes(document.state) ) }) diff --git a/plugins/controlled-documents-resources/src/utils.ts b/plugins/controlled-documents-resources/src/utils.ts index 926e258897..b20fef6285 100644 --- a/plugins/controlled-documents-resources/src/utils.ts +++ b/plugins/controlled-documents-resources/src/utils.ts @@ -82,7 +82,8 @@ export async function getTranslatedDocumentStates (lang: string): Promise>, DeleteDocument: '' as Ref, ArchiveDocument: '' as Ref, + MakeDocumentObsolete: '' as Ref, EditDocSpace: '' as Ref, TransferDocument: '' as Ref, Print: '' as Ref>, @@ -202,6 +203,10 @@ export const documentsPlugin = plugin(documentsId, { Deleted: '' as IntlString, Effective: '' as IntlString, Archived: '' as IntlString, + Obsolete: '' as IntlString, + MakeDocumentObsolete: '' as IntlString, + MakeDocumentObsoleteDialog: '' as IntlString, + MakeDocumentObsoleteConfirm: '' as IntlString, Parent: '' as IntlString, Template: '' as IntlString, GeneralInfo: '' as IntlString, diff --git a/plugins/controlled-documents/src/types.ts b/plugins/controlled-documents/src/types.ts index 7bfaaef133..a6eb794240 100644 --- a/plugins/controlled-documents/src/types.ts +++ b/plugins/controlled-documents/src/types.ts @@ -194,7 +194,8 @@ export enum DocumentState { Draft = 'draft', Effective = 'effective', Archived = 'archived', - Deleted = 'deleted' + Deleted = 'deleted', + Obsolete = 'obsolete' } /** From a20bd98d05d1baab066f66813abf0e4cf4c22107 Mon Sep 17 00:00:00 2001 From: Denis Bykhov Date: Wed, 29 Jan 2025 20:47:12 +0500 Subject: [PATCH 02/15] Fix cards activity (#7832) Signed-off-by: Denis Bykhov --- .../src/components/Activity.svelte | 24 +++++++++++++++---- .../src/components/ChannelInput.svelte | 19 ++++++++++++++- 2 files changed, 38 insertions(+), 5 deletions(-) diff --git a/plugins/activity-resources/src/components/Activity.svelte b/plugins/activity-resources/src/components/Activity.svelte index f8bae86e2e..0b8e0563d5 100644 --- a/plugins/activity-resources/src/components/Activity.svelte +++ b/plugins/activity-resources/src/components/Activity.svelte @@ -20,7 +20,7 @@ DisplayActivityMessage, WithReferences } from '@hcengineering/activity' - import { Doc, Ref, SortingOrder } from '@hcengineering/core' + import { Class, Doc, Ref, SortingOrder } from '@hcengineering/core' import { createQuery, getClient } from '@hcengineering/presentation' import { Grid, Label, Section, Spinner, location, Lazy } from '@hcengineering/ui' import { onDestroy, onMount } from 'svelte' @@ -39,6 +39,7 @@ export let boundary: HTMLElement | undefined = undefined const client = getClient() + const hierarchy = client.getHierarchy() const activityMessagesQuery = createQuery() const refsQuery = createQuery() @@ -170,9 +171,24 @@ let isNewestFirst = JSON.parse(localStorage.getItem('activity-newest-first') ?? 'false') - $: void client.findAll(activity.class.ActivityExtension, { ofClass: object._class }).then((res) => { - extensions = res - }) + $: extensions = getExtensions(object._class) + + function getExtensions (_class: Ref>): ActivityExtension[] { + try { + let clazz: Ref> | undefined = _class + while (clazz !== undefined) { + const res = client.getModel().findAllSync(activity.class.ActivityExtension, { ofClass: clazz }) + if (res.length > 0) { + return res + } + clazz = hierarchy.getClass(_class).extends + } + } catch (e) { + console.error(e) + return [] + } + return [] + } // Load references from other spaces separately because they can have any different spaces $: if ((object.references ?? 0) > 0) { diff --git a/plugins/chunter-resources/src/components/ChannelInput.svelte b/plugins/chunter-resources/src/components/ChannelInput.svelte index fdf241f020..4590d6634e 100644 --- a/plugins/chunter-resources/src/components/ChannelInput.svelte +++ b/plugins/chunter-resources/src/components/ChannelInput.svelte @@ -35,7 +35,24 @@ const hierarchy = client.getHierarchy() let extensions: ActivityExtension[] = [] - $: extensions = client.getModel().findAllSync(activity.class.ActivityExtension, { ofClass: object._class }) + $: extensions = getExtensions(object._class) + + function getExtensions (_class: Ref>): ActivityExtension[] { + try { + let clazz: Ref> | undefined = _class + while (clazz !== undefined) { + const res = client.getModel().findAllSync(activity.class.ActivityExtension, { ofClass: clazz }) + if (res.length > 0) { + return res + } + clazz = hierarchy.getClass(_class).extends + } + } catch (e) { + console.error(e) + return [] + } + return [] + } let icon: Asset | AnySvelteComponent | undefined = undefined From 80f3bbe851c11d98e9e1622cfc507e19e18790a5 Mon Sep 17 00:00:00 2001 From: Denis Bykhov Date: Thu, 30 Jan 2025 08:09:40 +0500 Subject: [PATCH 03/15] Fix double DM context (#7835) --- plugins/chunter-resources/src/utils.ts | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/plugins/chunter-resources/src/utils.ts b/plugins/chunter-resources/src/utils.ts index 438232254c..c24e77e646 100644 --- a/plugins/chunter-resources/src/utils.ts +++ b/plugins/chunter-resources/src/utils.ts @@ -629,24 +629,6 @@ export async function createDirect (employeeIds: Array>): Promise< if (context.hidden) { await client.updateDoc(context._class, context.space, context._id, { hidden: false }) } - - return dmId } - - const space = await client.findOne( - contact.class.PersonSpace, - { person: me.person as Ref }, - { projection: { _id: 1 } } - ) - if (space == null) return dmId - await client.createDoc(notification.class.DocNotifyContext, space._id, { - user: me._id, - objectId: dmId, - objectClass: chunter.class.DirectMessage, - objectSpace: core.space.Space, - hidden: false, - isPinned: false - }) - return dmId } From 5c9e71be096bdb086ff5441de555f1dea4995697 Mon Sep 17 00:00:00 2001 From: Alexander Platov Date: Thu, 30 Jan 2025 06:10:47 +0300 Subject: [PATCH 04/15] CreateCandidate: added a button to change the places of the first and last name (#7836) --- plugins/recruit-assets/lang/cs.json | 3 ++- plugins/recruit-assets/lang/de.json | 3 ++- plugins/recruit-assets/lang/en.json | 3 ++- plugins/recruit-assets/lang/es.json | 3 ++- plugins/recruit-assets/lang/fr.json | 3 ++- plugins/recruit-assets/lang/it.json | 3 ++- plugins/recruit-assets/lang/pt.json | 3 ++- plugins/recruit-assets/lang/ru.json | 3 ++- plugins/recruit-assets/lang/zh.json | 3 ++- .../src/components/CreateCandidate.svelte | 17 ++++++++++-- .../src/components/icons/Shuffle.svelte | 26 +++++++++++++++++++ plugins/recruit-resources/src/plugin.ts | 3 ++- 12 files changed, 61 insertions(+), 12 deletions(-) create mode 100644 plugins/recruit-resources/src/components/icons/Shuffle.svelte diff --git a/plugins/recruit-assets/lang/cs.json b/plugins/recruit-assets/lang/cs.json index 9451575d66..0bd3217c48 100644 --- a/plugins/recruit-assets/lang/cs.json +++ b/plugins/recruit-assets/lang/cs.json @@ -121,7 +121,8 @@ "HideDoneState": "Skrýt dokončené přihlášky", "HideArchivedVacancies": "Skrýt archivované pozice", "HideApplicantsFromArchivedVacancies": "Skrýt z archivovaných pozic", - "CreateNewSkills": "Vytvořit nové dovednosti, pokud neexistují" + "CreateNewSkills": "Vytvořit nové dovednosti, pokud neexistují", + "SwapFirstAndLastNames": "Vyměňte jméno a příjmení" }, "status": { "ApplicationExists": "Přihláška již existuje", diff --git a/plugins/recruit-assets/lang/de.json b/plugins/recruit-assets/lang/de.json index aa849e3b98..c730be5d36 100644 --- a/plugins/recruit-assets/lang/de.json +++ b/plugins/recruit-assets/lang/de.json @@ -121,7 +121,8 @@ "HideDoneState": "Abgeschlossene Bewerbungen ausblenden", "HideArchivedVacancies": "Archivierte Stellen ausblenden", "HideApplicantsFromArchivedVacancies": "Aus archivierten Stellen ausblenden", - "CreateNewSkills": "Neue Fähigkeiten erstellen, wenn keine bestehenden gefunden werden" + "CreateNewSkills": "Neue Fähigkeiten erstellen, wenn keine bestehenden gefunden werden", + "SwapFirstAndLastNames": "Vor- und Nachnamen tauschen" }, "status": { "ApplicationExists": "Bewerbung existiert bereits", diff --git a/plugins/recruit-assets/lang/en.json b/plugins/recruit-assets/lang/en.json index cf29e2adf6..c8a45adecc 100644 --- a/plugins/recruit-assets/lang/en.json +++ b/plugins/recruit-assets/lang/en.json @@ -121,7 +121,8 @@ "HideDoneState": "Hide complete applications", "HideArchivedVacancies": "Hide archived Vacancies", "HideApplicantsFromArchivedVacancies": "Hide from archived Vacancies", - "CreateNewSkills": "Create new skills if existing not found" + "CreateNewSkills": "Create new skills if existing not found", + "SwapFirstAndLastNames": "Swap first and last names" }, "status": { "ApplicationExists": "Application already exists", diff --git a/plugins/recruit-assets/lang/es.json b/plugins/recruit-assets/lang/es.json index e7aa4d4bbe..4d4a299ad5 100644 --- a/plugins/recruit-assets/lang/es.json +++ b/plugins/recruit-assets/lang/es.json @@ -118,7 +118,8 @@ "HideDoneState": "Ocultar solicitudes completadas", "HideArchivedVacancies": "Ocultar vacantes archivadas", "HideApplicantsFromArchivedVacancies": "Ocultar de vacantes archivadas", - "CreateNewSkills": "Crear nuevas habilidades si no se encuentran las existentes" + "CreateNewSkills": "Crear nuevas habilidades si no se encuentran las existentes", + "SwapFirstAndLastNames": "Intercambie nombres y apellidos" }, "status": { "ApplicationExists": "La solicitud ya existe", diff --git a/plugins/recruit-assets/lang/fr.json b/plugins/recruit-assets/lang/fr.json index ea9d74d52e..5d15dfd695 100644 --- a/plugins/recruit-assets/lang/fr.json +++ b/plugins/recruit-assets/lang/fr.json @@ -118,7 +118,8 @@ "HideDoneState": "Masquer les candidatures terminées", "HideArchivedVacancies": "Masquer les postes vacants archivés", "HideApplicantsFromArchivedVacancies": "Masquer les candidats des postes vacants archivés", - "CreateNewSkills": "Créer de nouvelles compétences si les existantes ne sont pas trouvées" + "CreateNewSkills": "Créer de nouvelles compétences si les existantes ne sont pas trouvées", + "SwapFirstAndLastNames": "Permuter le prénom et le nom" }, "status": { "ApplicationExists": "La candidature existe déjà", diff --git a/plugins/recruit-assets/lang/it.json b/plugins/recruit-assets/lang/it.json index 1aaf8e6780..75da996945 100644 --- a/plugins/recruit-assets/lang/it.json +++ b/plugins/recruit-assets/lang/it.json @@ -119,7 +119,8 @@ "HideDoneState": "Nascondi candidature completate", "HideArchivedVacancies": "Nascondi posizioni archiviate", "HideApplicantsFromArchivedVacancies": "Nascondi da posizioni archiviate", - "CreateNewSkills": "Crea nuove competenze se quelle esistenti non vengono trovate" + "CreateNewSkills": "Crea nuove competenze se quelle esistenti non vengono trovate", + "SwapFirstAndLastNames": "Scambia nome e cognome" }, "status": { "ApplicationExists": "La candidatura esiste già", diff --git a/plugins/recruit-assets/lang/pt.json b/plugins/recruit-assets/lang/pt.json index 8f0f5efab7..3337675aef 100644 --- a/plugins/recruit-assets/lang/pt.json +++ b/plugins/recruit-assets/lang/pt.json @@ -118,7 +118,8 @@ "HideDoneState": "Ocultar candidaturas concluídas", "HideArchivedVacancies": "Ocultar vagas arquivadas", "HideApplicantsFromArchivedVacancies": "Ocultar de vagas arquivadas", - "CreateNewSkills": "Criar novas competências se as existentes não forem encontradas" + "CreateNewSkills": "Criar novas competências se as existentes não forem encontradas", + "SwapFirstAndLastNames": "Trocar primeiro e último nome" }, "status": { "ApplicationExists": "A candidatura já existe", diff --git a/plugins/recruit-assets/lang/ru.json b/plugins/recruit-assets/lang/ru.json index 1c5838c79c..b75c55fa3e 100644 --- a/plugins/recruit-assets/lang/ru.json +++ b/plugins/recruit-assets/lang/ru.json @@ -121,7 +121,8 @@ "HideDoneState": "Скрыть завершенных кандидатов", "HideArchivedVacancies": "Скрыть архивные вакансии", "HideApplicantsFromArchivedVacancies": "Скрыть из архивных вакансии", - "CreateNewSkills": "Создать навыки, если не найдены существующие" + "CreateNewSkills": "Создать навыки, если не найдены существующие", + "SwapFirstAndLastNames": "Поменять местами имя и фамилию" }, "status": { "ApplicationExists": "Кандидат уже существует", diff --git a/plugins/recruit-assets/lang/zh.json b/plugins/recruit-assets/lang/zh.json index 77fdfcd6c4..b59643db7a 100644 --- a/plugins/recruit-assets/lang/zh.json +++ b/plugins/recruit-assets/lang/zh.json @@ -121,7 +121,8 @@ "HideDoneState": "隐藏已完成的申请", "HideArchivedVacancies": "隐藏已归档的职位", "HideApplicantsFromArchivedVacancies": "从已归档职位中隐藏", - "CreateNewSkills": "如果未找到现有技能,则创建新技能" + "CreateNewSkills": "如果未找到现有技能,则创建新技能", + "SwapFirstAndLastNames": "交换名字和姓氏" }, "status": { "ApplicationExists": "申请已存在", diff --git a/plugins/recruit-resources/src/components/CreateCandidate.svelte b/plugins/recruit-resources/src/components/CreateCandidate.svelte index df2b2808ba..9767c92bf5 100644 --- a/plugins/recruit-resources/src/components/CreateCandidate.svelte +++ b/plugins/recruit-resources/src/components/CreateCandidate.svelte @@ -67,12 +67,15 @@ Label, MiniToggle, showPopup, - Spinner + Spinner, + ActionIcon } from '@hcengineering/ui' import { createEventDispatcher, onDestroy } from 'svelte' import recruit from '../plugin' import { getCandidateIdentifier } from '../utils' import YesNo from './YesNo.svelte' + import IconSwitch from './icons/Switch.svelte' + import IconShuffle from './icons/Shuffle.svelte' export let shouldSaveDraft: boolean = true @@ -631,7 +634,7 @@ maxWidth={'30rem'} />
-
+
+ { + const first = object.firstName + object.firstName = object.lastName + object.lastName = first + }} + />
diff --git a/plugins/recruit-resources/src/components/icons/Shuffle.svelte b/plugins/recruit-resources/src/components/icons/Shuffle.svelte new file mode 100644 index 0000000000..a48e340a82 --- /dev/null +++ b/plugins/recruit-resources/src/components/icons/Shuffle.svelte @@ -0,0 +1,26 @@ + + + + + + diff --git a/plugins/recruit-resources/src/plugin.ts b/plugins/recruit-resources/src/plugin.ts index c6e4c67081..a22e2b7c0d 100644 --- a/plugins/recruit-resources/src/plugin.ts +++ b/plugins/recruit-resources/src/plugin.ts @@ -127,7 +127,8 @@ export default mergeIds(recruitId, recruit, { OpenVacancyList: '' as IntlString, Export: '' as IntlString, GetTalentIds: '' as IntlString, - CreateNewSkills: '' as IntlString + CreateNewSkills: '' as IntlString, + SwapFirstAndLastNames: '' as IntlString }, category: { Other: '' as Ref, From 9c3a1cc64104b85a63e974b32afae27150d74805 Mon Sep 17 00:00:00 2001 From: Andrey Sobolev Date: Thu, 30 Jan 2025 10:11:31 +0700 Subject: [PATCH 05/15] UBERF-9299: Fix backup service backup order (#7826) --- .vscode/launch.json | 2 +- packages/ui/src/components/Expandable.svelte | 5 + .../src/components/AdminWorkspaces.svelte | 95 +++++++++++++++---- server/account/src/operations.ts | 22 +++-- server/backup/src/service.ts | 28 +++++- server/client/src/account.ts | 2 +- 6 files changed, 125 insertions(+), 29 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 87af79d1b6..8e1ce88500 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -394,7 +394,7 @@ "DB_URL": "mongodb://localhost:27017", "MODEL_JSON": "${workspaceRoot}/models/all/bundle/model.json", "SECRET": "secret", - "REGION": "pg", + "REGION": "cockroach", "BUCKET_NAME":"backups", "INTERVAL":"30" }, diff --git a/packages/ui/src/components/Expandable.svelte b/packages/ui/src/components/Expandable.svelte index dab2991974..b4e1144114 100644 --- a/packages/ui/src/components/Expandable.svelte +++ b/packages/ui/src/components/Expandable.svelte @@ -51,6 +51,11 @@ {#if label} + {#if $$slots['title-tools']} +
+ +
+ {/if} {#if $$slots.tools}
diff --git a/plugins/login-resources/src/components/AdminWorkspaces.svelte b/plugins/login-resources/src/components/AdminWorkspaces.svelte index 827f0b6f43..19e7905bab 100644 --- a/plugins/login-resources/src/components/AdminWorkspaces.svelte +++ b/plugins/login-resources/src/components/AdminWorkspaces.svelte @@ -1,5 +1,14 @@ + +{#if object} + ({ id: cat._id, label: cat.title }))} + selected={object.category} + on:close={(e) => handleSubmit(e.detail)} + /> +{/if} diff --git a/plugins/controlled-documents-resources/src/components/document/presenters/CategoryPresenter.svelte b/plugins/controlled-documents-resources/src/components/document/presenters/CategoryPresenter.svelte index d5888a2512..920f17d156 100644 --- a/plugins/controlled-documents-resources/src/components/document/presenters/CategoryPresenter.svelte +++ b/plugins/controlled-documents-resources/src/components/document/presenters/CategoryPresenter.svelte @@ -5,21 +5,41 @@ import { getClient } from '@hcengineering/presentation' import { Label } from '@hcengineering/ui' import view from '@hcengineering/view' + import { createEventDispatcher } from 'svelte' export let value: Ref | undefined + export let editable: boolean = false let category: DocumentCategory | undefined = undefined const client = getClient() + const dispatch = createEventDispatcher() + $: if (value) { client.findOne(documents.class.DocumentCategory, { _id: value }).then((result) => { category = result }) } + + function handleClick (event: MouseEvent): void { + if (!editable) { + return + } + + dispatch('edit', event) + } {#if category} - {category.title} + + {category.title} + {:else}