From 1bd0ce6f77f09f080bc79008942ea75e45da7bed Mon Sep 17 00:00:00 2001 From: Vyacheslav Tumanov Date: Fri, 5 May 2023 17:54:47 +0500 Subject: [PATCH 1/5] TSK-1436: add generic action for archiving spaces. Set override where needed Signed-off-by: Vyacheslav Tumanov --- models/hr/src/index.ts | 11 ++++++----- models/hr/src/plugin.ts | 2 +- models/task/src/index.ts | 3 ++- models/tracker/src/index.ts | 3 ++- models/view/src/index.ts | 18 ++++++++++++++++++ models/view/src/plugin.ts | 1 + plugins/view-assets/lang/en.json | 2 ++ plugins/view-assets/lang/ru.json | 4 +++- plugins/view-resources/src/actionImpl.ts | 24 +++++++++++++++++++++++- plugins/view-resources/src/plugin.ts | 2 ++ plugins/view/src/index.ts | 1 + 11 files changed, 61 insertions(+), 10 deletions(-) diff --git a/models/hr/src/index.ts b/models/hr/src/index.ts index b861edf6a0..4873f60431 100644 --- a/models/hr/src/index.ts +++ b/models/hr/src/index.ts @@ -328,9 +328,9 @@ export function createModel (builder: Builder): void { createAction( builder, { - action: view.actionImpl.Delete, - label: view.string.Delete, - icon: view.icon.Delete, + action: view.actionImpl.Archive, + label: view.string.Archive, + icon: view.icon.Archive, input: 'any', category: hr.category.HR, keyBinding: ['Meta + Backspace', 'Ctrl + Backspace'], @@ -339,9 +339,10 @@ export function createModel (builder: Builder): void { _id: { $nin: [hr.ids.Head] } }, target: hr.class.Department, - context: { mode: 'context', application: hr.app.HR, group: 'create' } + context: { mode: ['context', 'browser'], group: 'tools' }, + override: [view.action.Archive, view.action.Delete] }, - hr.action.DeleteDepartment + hr.action.ArchiveDepartment ) createAction( diff --git a/models/hr/src/plugin.ts b/models/hr/src/plugin.ts index 8289ac2651..a36359cb4d 100644 --- a/models/hr/src/plugin.ts +++ b/models/hr/src/plugin.ts @@ -57,7 +57,7 @@ export default mergeIds(hrId, hr, { }, action: { EditDepartment: '' as Ref, - DeleteDepartment: '' as Ref, + ArchiveDepartment: '' as Ref, EditRequest: '' as Ref, EditRequestType: '' as Ref, DeleteRequest: '' as Ref diff --git a/models/task/src/index.ts b/models/task/src/index.ts index fbae6560bc..1f82497795 100644 --- a/models/task/src/index.ts +++ b/models/task/src/index.ts @@ -252,7 +252,8 @@ export const actionTemplates = template({ context: { mode: ['context', 'browser'], group: 'tools' - } + }, + override: [view.action.Archive, view.action.Delete] }, unarchiveSpace: { label: task.string.Unarchive, diff --git a/models/tracker/src/index.ts b/models/tracker/src/index.ts index b56e59998d..6c4fc95d25 100644 --- a/models/tracker/src/index.ts +++ b/models/tracker/src/index.ts @@ -1187,7 +1187,8 @@ export function createModel (builder: Builder): void { context: { mode: ['context', 'browser'], group: 'edit' - } + }, + override: [view.action.Archive, view.action.Delete] }, tracker.action.DeleteProject ) diff --git a/models/view/src/index.ts b/models/view/src/index.ts index f2beedf910..40f721b2ee 100644 --- a/models/view/src/index.ts +++ b/models/view/src/index.ts @@ -508,6 +508,24 @@ export function createModel (builder: Builder): void { view.action.Delete ) + createAction( + builder, + { + action: view.actionImpl.Archive, + label: view.string.Archive, + icon: view.icon.Archive, + category: view.category.General, + input: 'any', + query: { + archived: false + }, + target: core.class.Space, + context: { mode: ['context', 'browser'], group: 'tools' }, + override: [view.action.Delete] + }, + view.action.Archive + ) + // Keyboard actions. createAction( builder, diff --git a/models/view/src/plugin.ts b/models/view/src/plugin.ts index 7c2a2998a0..4d12bd68df 100644 --- a/models/view/src/plugin.ts +++ b/models/view/src/plugin.ts @@ -21,6 +21,7 @@ import view from '@hcengineering/view-resources/src/plugin' export default mergeIds(viewId, view, { actionImpl: { Delete: '' as ViewAction, + Archive: '' as ViewAction, Move: '' as ViewAction, MoveLeft: '' as ViewAction, MoveRight: '' as ViewAction, diff --git a/plugins/view-assets/lang/en.json b/plugins/view-assets/lang/en.json index 6adedec38e..cab5582e2d 100644 --- a/plugins/view-assets/lang/en.json +++ b/plugins/view-assets/lang/en.json @@ -13,6 +13,8 @@ "Role": "Role", "DeleteObject": "Delete object", "DeleteObjectConfirm": "Do you want to delete this {count, plural, =1 {object} other {# objects}}?", + "Archive": "Archive", + "ArchiveConfirm": "Do you want to archive this {count, plural, =1 {object} other {# objects}}?", "Open": "Open", "Assignees": "Assignees", "Labels": "Labels", diff --git a/plugins/view-assets/lang/ru.json b/plugins/view-assets/lang/ru.json index 59ba4560ff..ffb8bf59e8 100644 --- a/plugins/view-assets/lang/ru.json +++ b/plugins/view-assets/lang/ru.json @@ -12,7 +12,9 @@ "Table": "Таблица", "Role": "Роль", "DeleteObject": "Удалить объект", - "DeleteObjectConfirm": "Вы действительно хотите удалить {count, plural, =1 {этот обьект} other {эти # обьекта}}?", + "DeleteObjectConfirm": "Вы действительно хотите удалить {count, plural, =1 {этот объект} other {эти # объекта}}?", + "Archive": "Архивировать", + "ArchiveConfirm": "Вы действительно хотите заархивировать {count, plural, =1 {этот объект} other {эти # объекта}}?", "Open": "Открыть", "Assignees": "Исполнители", "Labels": "Метки", diff --git a/plugins/view-resources/src/actionImpl.ts b/plugins/view-resources/src/actionImpl.ts index 654892b791..e8deebbe4f 100644 --- a/plugins/view-resources/src/actionImpl.ts +++ b/plugins/view-resources/src/actionImpl.ts @@ -1,4 +1,4 @@ -import { Class, Doc, DocumentQuery, Hierarchy, Ref } from '@hcengineering/core' +import { Class, Doc, DocumentQuery, Hierarchy, Ref, Space, TxResult } from '@hcengineering/core' import { Asset, getResource, IntlString, Resource } from '@hcengineering/platform' import { getClient, MessageBox, updateAttribute } from '@hcengineering/presentation' import { @@ -70,6 +70,27 @@ function Delete (object: Doc | Doc[]): void { ) } +function Archive (object: Space | Space[]): void { + showPopup( + MessageBox, + { + label: view.string.Archive, + message: view.string.ArchiveConfirm, + params: { count: Array.isArray(object) ? object.length : 1 }, + action: async () => { + const objs = Array.isArray(object) ? object : [object] + const client = getClient() + const promises: Array> = [] + for (const obj of objs) { + promises.push(client.update(obj, { archived: true })) + } + await Promise.all(promises) + } + }, + undefined + ) +} + async function Move (docs: Doc | Doc[]): Promise { showPopup(MoveView, { selected: docs }) } @@ -408,6 +429,7 @@ async function getPopupAlignment ( export const actionImpl = { CopyTextToClipboard, Delete, + Archive, Move, MoveUp, MoveDown, diff --git a/plugins/view-resources/src/plugin.ts b/plugins/view-resources/src/plugin.ts index 9c22387482..e95436dd70 100644 --- a/plugins/view-resources/src/plugin.ts +++ b/plugins/view-resources/src/plugin.ts @@ -34,6 +34,8 @@ export default mergeIds(viewId, view, { ChooseAColor: '' as IntlString, DeleteObject: '' as IntlString, DeleteObjectConfirm: '' as IntlString, + Archive: '' as IntlString, + ArchiveConfirm: '' as IntlString, Assignees: '' as IntlString, Labels: '' as IntlString, ActionPlaceholder: '' as IntlString, diff --git a/plugins/view/src/index.ts b/plugins/view/src/index.ts index 5a4d7f5bab..490963baeb 100644 --- a/plugins/view/src/index.ts +++ b/plugins/view/src/index.ts @@ -652,6 +652,7 @@ const view = plugin(viewId, { }, action: { Delete: '' as Ref, + Archive: '' as Ref, Move: '' as Ref, MoveLeft: '' as Ref, MoveRight: '' as Ref, From a06fa351ac89c23a18e7c2d193552e1689fdee7f Mon Sep 17 00:00:00 2001 From: Vyacheslav Tumanov Date: Fri, 5 May 2023 17:56:13 +0500 Subject: [PATCH 2/5] TSK-1436: fix ignoring override due to no match in query Signed-off-by: Vyacheslav Tumanov --- plugins/view-resources/src/actions.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/plugins/view-resources/src/actions.ts b/plugins/view-resources/src/actions.ts index 58d102de76..6bbadd9424 100644 --- a/plugins/view-resources/src/actions.ts +++ b/plugins/view-resources/src/actions.ts @@ -159,12 +159,6 @@ export function filterActions ( if (role < AccountRole.Maintainer && action.secured === true) { continue } - if (action.query !== undefined) { - const r = matchQuery([doc], action.query, doc._class, hierarchy) - if (r.length === 0) { - continue - } - } if ( (hierarchy.isDerived(doc._class, action.target) && client.getHierarchy().isDerived(action.target, derived)) || (hierarchy.isMixin(action.target) && hierarchy.hasMixin(doc, action.target)) @@ -172,6 +166,12 @@ export function filterActions ( if (action.override !== undefined) { overrideRemove.push(...action.override) } + if (action.query !== undefined) { + const r = matchQuery([doc], action.query, doc._class, hierarchy) + if (r.length === 0) { + continue + } + } result.push(action) } } From d62884bf983c367de453843fb31f6097017067c4 Mon Sep 17 00:00:00 2001 From: Vyacheslav Tumanov Date: Fri, 5 May 2023 17:56:42 +0500 Subject: [PATCH 3/5] TSK-1436: fix txMatch for Staff mixin Signed-off-by: Vyacheslav Tumanov --- models/server-hr/src/index.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/models/server-hr/src/index.ts b/models/server-hr/src/index.ts index b87444276a..cb74a45971 100644 --- a/models/server-hr/src/index.ts +++ b/models/server-hr/src/index.ts @@ -27,9 +27,8 @@ export function createModel (builder: Builder): void { builder.createDoc(serverCore.class.Trigger, core.space.Model, { trigger: serverHr.trigger.OnDepartmentStaff, txMatch: { - _class: core.class.TxCollectionCUD, - 'tx.objectClass': hr.mixin.Staff, - 'tx._class': core.class.TxMixin + _class: core.class.TxMixin, + mixin: hr.mixin.Staff } }) From d169a73e7c0852ef6a9f72d71420b0ca0e280b5e Mon Sep 17 00:00:00 2001 From: Vyacheslav Tumanov Date: Fri, 5 May 2023 17:57:47 +0500 Subject: [PATCH 4/5] TSK-1436: add upgrade action to move requests from non-existing Departments. And rename variable Signed-off-by: Vyacheslav Tumanov --- models/hr/src/migration.ts | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/models/hr/src/migration.ts b/models/hr/src/migration.ts index b0b5b3c71a..e5be82ae47 100644 --- a/models/hr/src/migration.ts +++ b/models/hr/src/migration.ts @@ -60,9 +60,9 @@ async function fixDepartmentsFromStaff (tx: TxOperations): Promise { if (department._id === hr.ids.Head) continue ancestors.set(department._id, department.space) } - for (const departmentTest of departments) { - const parents: Department[] = parentsWithDepartmentMap.get(departmentTest._id) ?? [] - let _id = departmentTest._id + for (const departmentItem of departments) { + const parents: Department[] = parentsWithDepartmentMap.get(departmentItem._id) ?? [] + let _id = departmentItem._id while (true) { const department = departmentsMap.get(_id) if (department === undefined) break @@ -71,7 +71,7 @@ async function fixDepartmentsFromStaff (tx: TxOperations): Promise { if (next === undefined) break _id = next } - parentsWithDepartmentMap.set(departmentTest._id, parents) + parentsWithDepartmentMap.set(departmentItem._id, parents) } const staff = await tx.findAll(hr.mixin.Staff, {}) const promises = [] @@ -93,6 +93,24 @@ async function fixDepartmentsFromStaff (tx: TxOperations): Promise { } await Promise.all(promises) } + +async function fixInvalidRequests (tx: TxOperations): Promise { + const departments = await tx.findAll(hr.class.Department, {}) + const staff = await tx.findAll(hr.mixin.Staff, {}) + const staffDepartmentMap = new Map(staff.map((s) => [s._id, s.department])) + const requests = await tx.findAll(hr.class.Request, { space: { $nin: departments.map((d) => d._id) } }) + const res = [] + for (const request of requests) { + const currentStaffDepartment = staffDepartmentMap.get(request.attachedTo) + if (currentStaffDepartment !== null) { + res.push(tx.update(request, { space: currentStaffDepartment })) + } else { + res.push(tx.update(request, { space: hr.ids.Head })) + } + } + await Promise.all(res) +} + function toTzDate (date: number): TzDate { const res = new Date(date) return { @@ -234,5 +252,6 @@ export const hrOperation: MigrateOperation = { await createSpace(tx) await fixDuplicatesInDepartments(tx) await fixDepartmentsFromStaff(tx) + await fixInvalidRequests(tx) } } From 289749367e3e3560853d55c8370195c8955a6132 Mon Sep 17 00:00:00 2001 From: Vyacheslav Tumanov Date: Fri, 5 May 2023 17:58:17 +0500 Subject: [PATCH 5/5] TSK-1436: show only not archived Departments in hr structure Signed-off-by: Vyacheslav Tumanov --- plugins/hr-resources/src/components/Structure.svelte | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/plugins/hr-resources/src/components/Structure.svelte b/plugins/hr-resources/src/components/Structure.svelte index 67716b24f4..7098084d7c 100644 --- a/plugins/hr-resources/src/components/Structure.svelte +++ b/plugins/hr-resources/src/components/Structure.svelte @@ -51,7 +51,10 @@ query.query( hr.class.Department, - resultQuery, + { + ...resultQuery, + archived: false + }, (res) => { head = res.find((p) => p._id === hr.ids.Head) descendants.clear()