TSK-1436: change deleting spaces to removing, add action to move all non-valid requests to correct spaces (#3149)

Signed-off-by: Vyacheslav Tumanov <me@slavatumanov.me>
This commit is contained in:
Vyacheslav Tumanov 2023-05-10 16:41:21 +05:00 committed by GitHub
parent 93268d4dbc
commit 238f2da750
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 96 additions and 24 deletions

View File

@ -328,9 +328,9 @@ export function createModel (builder: Builder): void {
createAction( createAction(
builder, builder,
{ {
action: view.actionImpl.Delete, action: view.actionImpl.Archive,
label: view.string.Delete, label: view.string.Archive,
icon: view.icon.Delete, icon: view.icon.Archive,
input: 'any', input: 'any',
category: hr.category.HR, category: hr.category.HR,
keyBinding: ['Meta + Backspace', 'Ctrl + Backspace'], keyBinding: ['Meta + Backspace', 'Ctrl + Backspace'],
@ -339,9 +339,10 @@ export function createModel (builder: Builder): void {
_id: { $nin: [hr.ids.Head] } _id: { $nin: [hr.ids.Head] }
}, },
target: hr.class.Department, 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( createAction(

View File

@ -60,9 +60,9 @@ async function fixDepartmentsFromStaff (tx: TxOperations): Promise<void> {
if (department._id === hr.ids.Head) continue if (department._id === hr.ids.Head) continue
ancestors.set(department._id, department.space) ancestors.set(department._id, department.space)
} }
for (const departmentTest of departments) { for (const departmentItem of departments) {
const parents: Department[] = parentsWithDepartmentMap.get(departmentTest._id) ?? [] const parents: Department[] = parentsWithDepartmentMap.get(departmentItem._id) ?? []
let _id = departmentTest._id let _id = departmentItem._id
while (true) { while (true) {
const department = departmentsMap.get(_id) const department = departmentsMap.get(_id)
if (department === undefined) break if (department === undefined) break
@ -71,7 +71,7 @@ async function fixDepartmentsFromStaff (tx: TxOperations): Promise<void> {
if (next === undefined) break if (next === undefined) break
_id = next _id = next
} }
parentsWithDepartmentMap.set(departmentTest._id, parents) parentsWithDepartmentMap.set(departmentItem._id, parents)
} }
const staff = await tx.findAll(hr.mixin.Staff, {}) const staff = await tx.findAll(hr.mixin.Staff, {})
const promises = [] const promises = []
@ -93,6 +93,24 @@ async function fixDepartmentsFromStaff (tx: TxOperations): Promise<void> {
} }
await Promise.all(promises) await Promise.all(promises)
} }
async function fixInvalidRequests (tx: TxOperations): Promise<void> {
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 { function toTzDate (date: number): TzDate {
const res = new Date(date) const res = new Date(date)
return { return {
@ -234,5 +252,6 @@ export const hrOperation: MigrateOperation = {
await createSpace(tx) await createSpace(tx)
await fixDuplicatesInDepartments(tx) await fixDuplicatesInDepartments(tx)
await fixDepartmentsFromStaff(tx) await fixDepartmentsFromStaff(tx)
await fixInvalidRequests(tx)
} }
} }

View File

@ -57,7 +57,7 @@ export default mergeIds(hrId, hr, {
}, },
action: { action: {
EditDepartment: '' as Ref<Action>, EditDepartment: '' as Ref<Action>,
DeleteDepartment: '' as Ref<Action>, ArchiveDepartment: '' as Ref<Action>,
EditRequest: '' as Ref<Action>, EditRequest: '' as Ref<Action>,
EditRequestType: '' as Ref<Action>, EditRequestType: '' as Ref<Action>,
DeleteRequest: '' as Ref<Action> DeleteRequest: '' as Ref<Action>

View File

@ -27,9 +27,8 @@ export function createModel (builder: Builder): void {
builder.createDoc(serverCore.class.Trigger, core.space.Model, { builder.createDoc(serverCore.class.Trigger, core.space.Model, {
trigger: serverHr.trigger.OnDepartmentStaff, trigger: serverHr.trigger.OnDepartmentStaff,
txMatch: { txMatch: {
_class: core.class.TxCollectionCUD, _class: core.class.TxMixin,
'tx.objectClass': hr.mixin.Staff, mixin: hr.mixin.Staff
'tx._class': core.class.TxMixin
} }
}) })

View File

@ -252,7 +252,8 @@ export const actionTemplates = template({
context: { context: {
mode: ['context', 'browser'], mode: ['context', 'browser'],
group: 'tools' group: 'tools'
} },
override: [view.action.Archive, view.action.Delete]
}, },
unarchiveSpace: { unarchiveSpace: {
label: task.string.Unarchive, label: task.string.Unarchive,

View File

@ -1183,7 +1183,8 @@ export function createModel (builder: Builder): void {
context: { context: {
mode: ['context', 'browser'], mode: ['context', 'browser'],
group: 'edit' group: 'edit'
} },
override: [view.action.Archive, view.action.Delete]
}, },
tracker.action.DeleteProject tracker.action.DeleteProject
) )

View File

@ -508,6 +508,24 @@ export function createModel (builder: Builder): void {
view.action.Delete 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. // Keyboard actions.
createAction( createAction(
builder, builder,

View File

@ -21,6 +21,7 @@ import view from '@hcengineering/view-resources/src/plugin'
export default mergeIds(viewId, view, { export default mergeIds(viewId, view, {
actionImpl: { actionImpl: {
Delete: '' as ViewAction, Delete: '' as ViewAction,
Archive: '' as ViewAction,
Move: '' as ViewAction, Move: '' as ViewAction,
MoveLeft: '' as ViewAction, MoveLeft: '' as ViewAction,
MoveRight: '' as ViewAction, MoveRight: '' as ViewAction,

View File

@ -51,7 +51,10 @@
query.query( query.query(
hr.class.Department, hr.class.Department,
resultQuery, {
...resultQuery,
archived: false
},
(res) => { (res) => {
head = res.find((p) => p._id === hr.ids.Head) head = res.find((p) => p._id === hr.ids.Head)
descendants.clear() descendants.clear()

View File

@ -13,6 +13,8 @@
"Role": "Role", "Role": "Role",
"DeleteObject": "Delete object", "DeleteObject": "Delete object",
"DeleteObjectConfirm": "Do you want to delete this {count, plural, =1 {object} other {# objects}}?", "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", "Open": "Open",
"Assignees": "Assignees", "Assignees": "Assignees",
"Labels": "Labels", "Labels": "Labels",

View File

@ -12,7 +12,9 @@
"Table": "Таблица", "Table": "Таблица",
"Role": "Роль", "Role": "Роль",
"DeleteObject": "Удалить объект", "DeleteObject": "Удалить объект",
"DeleteObjectConfirm": "Вы действительно хотите удалить {count, plural, =1 {этот обьект} other {эти # обьекта}}?", "DeleteObjectConfirm": "Вы действительно хотите удалить {count, plural, =1 {этот объект} other {эти # объекта}}?",
"Archive": "Архивировать",
"ArchiveConfirm": "Вы действительно хотите заархивировать {count, plural, =1 {этот объект} other {эти # объекта}}?",
"Open": "Открыть", "Open": "Открыть",
"Assignees": "Исполнители", "Assignees": "Исполнители",
"Labels": "Метки", "Labels": "Метки",

View File

@ -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 { Asset, getResource, IntlString, Resource } from '@hcengineering/platform'
import { getClient, MessageBox, updateAttribute } from '@hcengineering/presentation' import { getClient, MessageBox, updateAttribute } from '@hcengineering/presentation'
import { 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<Promise<TxResult>> = []
for (const obj of objs) {
promises.push(client.update(obj, { archived: true }))
}
await Promise.all(promises)
}
},
undefined
)
}
async function Move (docs: Doc | Doc[]): Promise<void> { async function Move (docs: Doc | Doc[]): Promise<void> {
showPopup(MoveView, { selected: docs }) showPopup(MoveView, { selected: docs })
} }
@ -408,6 +429,7 @@ async function getPopupAlignment (
export const actionImpl = { export const actionImpl = {
CopyTextToClipboard, CopyTextToClipboard,
Delete, Delete,
Archive,
Move, Move,
MoveUp, MoveUp,
MoveDown, MoveDown,

View File

@ -159,12 +159,6 @@ export function filterActions (
if (role < AccountRole.Maintainer && action.secured === true) { if (role < AccountRole.Maintainer && action.secured === true) {
continue continue
} }
if (action.query !== undefined) {
const r = matchQuery([doc], action.query, doc._class, hierarchy)
if (r.length === 0) {
continue
}
}
if ( if (
(hierarchy.isDerived(doc._class, action.target) && client.getHierarchy().isDerived(action.target, derived)) || (hierarchy.isDerived(doc._class, action.target) && client.getHierarchy().isDerived(action.target, derived)) ||
(hierarchy.isMixin(action.target) && hierarchy.hasMixin(doc, action.target)) (hierarchy.isMixin(action.target) && hierarchy.hasMixin(doc, action.target))
@ -172,6 +166,12 @@ export function filterActions (
if (action.override !== undefined) { if (action.override !== undefined) {
overrideRemove.push(...action.override) 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) result.push(action)
} }
} }

View File

@ -34,6 +34,8 @@ export default mergeIds(viewId, view, {
ChooseAColor: '' as IntlString, ChooseAColor: '' as IntlString,
DeleteObject: '' as IntlString, DeleteObject: '' as IntlString,
DeleteObjectConfirm: '' as IntlString, DeleteObjectConfirm: '' as IntlString,
Archive: '' as IntlString,
ArchiveConfirm: '' as IntlString,
Assignees: '' as IntlString, Assignees: '' as IntlString,
Labels: '' as IntlString, Labels: '' as IntlString,
ActionPlaceholder: '' as IntlString, ActionPlaceholder: '' as IntlString,

View File

@ -652,6 +652,7 @@ const view = plugin(viewId, {
}, },
action: { action: {
Delete: '' as Ref<Action>, Delete: '' as Ref<Action>,
Archive: '' as Ref<Action>,
Move: '' as Ref<Action>, Move: '' as Ref<Action>,
MoveLeft: '' as Ref<Action>, MoveLeft: '' as Ref<Action>,
MoveRight: '' as Ref<Action>, MoveRight: '' as Ref<Action>,