ezqms-1149: allow archiving effective doc (#6489)

Signed-off-by: Alexey Zinoviev <alexey.zinoviev@xored.com>
This commit is contained in:
Alexey Zinoviev 2024-09-05 21:35:22 +04:00 committed by GitHub
parent b8b196ecd9
commit 579caad220
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 109 additions and 7 deletions

View File

@ -696,6 +696,27 @@ 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,
{

View File

@ -27,6 +27,16 @@ export function definePermissions (builder: Builder): void {
documents.permission.ApproveDocument
)
builder.createDoc(
core.class.Permission,
core.space.Model,
{
label: documents.string.ArchiveDocumentPermission,
description: documents.string.ArchiveDocumentDescription
},
documents.permission.ArchiveDocument
)
builder.createDoc(
core.class.Permission,
core.space.Model,

View File

@ -62,6 +62,7 @@ export default mergeIds(documentsId, documents, {
CreateDocument: '' as ViewAction,
CreateTemplate: '' as ViewAction,
DeleteDocument: '' as ViewAction,
ArchiveDocument: '' as ViewAction,
EditDocSpace: '' as ViewAction
},
viewlet: {

View File

@ -38,6 +38,7 @@ export const roles = [
documents.permission.ReviewDocument,
documents.permission.ApproveDocument,
documents.permission.CoAuthorDocument,
documents.permission.ArchiveDocument,
documents.permission.UpdateDocumentOwner,
documents.permission.CreateDocumentCategory,
documents.permission.UpdateDocumentCategory,

View File

@ -26,6 +26,7 @@ export const documentPermissions: Ref<Permission>[] = [
documents.permission.ReviewDocument,
documents.permission.ApproveDocument,
documents.permission.CoAuthorDocument,
documents.permission.ArchiveDocument,
documents.permission.UpdateDocumentOwner,
documents.permission.CreateDocumentCategory,
documents.permission.UpdateDocumentCategory,

View File

@ -60,6 +60,7 @@ const productPermissions: Ref<Permission>[] = [
documents.permission.ReviewDocument,
documents.permission.ApproveDocument,
documents.permission.CoAuthorDocument,
documents.permission.ArchiveDocument,
documents.permission.UpdateDocumentOwner,
core.permission.UpdateSpace,
core.permission.ArchiveSpace

View File

@ -50,6 +50,7 @@ export const roles = [
documents.permission.ReviewDocument,
documents.permission.ApproveDocument,
documents.permission.CoAuthorDocument,
documents.permission.ArchiveDocument,
documents.permission.UpdateDocumentOwner
]
}

View File

@ -223,6 +223,9 @@
"MarkDocsAsDeleted": "Marking multiple documents as deleted",
"MarkDocAsDeletedConfirm": "Do you really want to mark the following documents as deleted: {titles}?",
"ArchiveDocs": "Archive {count, plural, =0 {document} other {documents}}",
"ArchiveDocsConfirm": "Do you really want to archive the following documents: {titles}?",
"DocumentInHierarchy": "Document in hierarchy",
"FirstDraftVersion": "This is the first draft version of the document. There's no history yet.",
@ -274,6 +277,8 @@
"ReviewDocumentDescription": "Grants users ability to review a document",
"ApproveDocumentPermission": "Approve document",
"ApproveDocumentDescription": "Grants users ability to approve a document",
"ArchiveDocumentPermission": "Archive document",
"ArchiveDocumentDescription": "Grants users ability to archive a document",
"CoAuthorDocumentPermission": "Co-author document",
"CoAuthorDocumentDescription": "Grants users ability to co-author a document",
"CreateDocumentPermission": "Create document",

View File

@ -191,6 +191,8 @@
"MarkDocAsDeleted": "Marquer le document comme supprimé",
"MarkDocsAsDeleted": "Marquer plusieurs documents comme supprimés",
"MarkDocAsDeletedConfirm": "Voulez-vous vraiment marquer les documents suivants comme supprimés : {titles} ?",
"ArchiveDocs": "Archiver {count, plural, =0 {document} other {documents}}",
"ArchiveDocsConfirm": "Voulez-vous vraiment archiver les documents suivants : {titles} ?",
"DocumentInHierarchy": "Document dans la hiérarchie",
"FirstDraftVersion": "Ceci est la première version brouillon du document. Il n'y a pas encore d'historique.",
"EffectiveDocumentLifecycle": "Cycle de vie du document effectif",
@ -234,6 +236,8 @@
"ReviewDocumentDescription": "Accorde aux utilisateurs la capacité de réviser un document",
"ApproveDocumentPermission": "Approuver le document",
"ApproveDocumentDescription": "Accorde aux utilisateurs la capacité d'approuver un document",
"ArchiveDocumentPermission": "Archiver le document",
"ArchiveDocumentDescription": "Accorde aux utilisateurs la capacité d'archiver un document",
"CoAuthorDocumentPermission": "Co-auteur du document",
"CoAuthorDocumentDescription": "Accorde aux utilisateurs la capacité de co-auteur un document",
"CreateDocumentPermission": "Créer un document",

View File

@ -222,6 +222,8 @@
"MarkDocAsDeleted": "Пометить документ как удаленный",
"MarkDocsAsDeleted": "Пометить несколько документов как удаленные",
"MarkDocAsDeletedConfirm": "Вы действительно хотите пометить следующие документы как удаленные: {titles}?",
"ArchiveDocs": "Архивировать {count, plural, =0 {документ} other {документы}}",
"ArchiveDocsConfirm": "Вы действительно хотите архивировать следующие документы: {titles}?",
"DocumentInHierarchy": "Документ в иерархии",
"FirstDraftVersion": "Это первая рабочая копия документа. Для него пока нет истории.",
@ -275,6 +277,8 @@
"ReviewDocumentDescription": "Предоставляет пользователям разрешение рецензировать документ",
"ApproveDocumentPermission": "Утверждать документ",
"ApproveDocumentDescription": "Предоставляет пользователям разрешение утверждать документ",
"ArchiveDocumentPermission": "Архивировать документ",
"ArchiveDocumentDescription": "Предоставляет пользователям разрешение архивировать документ",
"CoAuthorDocumentPermission": "Быть со-автором документа",
"CoAuthorDocumentDescription": "Предоставляет пользователям разрешение быть со-автором документа",
"CreateDocumentPermission": "Создавать документ",

View File

@ -222,6 +222,8 @@
"MarkDocAsDeleted": "标记文档为已删除",
"MarkDocsAsDeleted": "标记多个文档为已删除",
"MarkDocAsDeletedConfirm": "您真的想将以下文档标记为已删除吗:{titles}",
"ArchiveDocs": "归档 {count, plural, =0 {文档} other {文档}}",
"ArchiveDocsConfirm": "您真的想将以下文档归档吗:{titles}",
"DocumentInHierarchy": "层级中的文档",
"FirstDraftVersion": "这是文档的第一个草稿版本。尚无历史记录。",
@ -274,6 +276,8 @@
"ReviewDocumentDescription": "授予用户审查文档的权限",
"ApproveDocumentPermission": "批准文档",
"ApproveDocumentDescription": "授予用户批准文档的权限",
"ArchiveDocumentPermission": "归档文档",
"ArchiveDocumentDescription": "授予用户归档文档的权限",
"CoAuthorDocumentPermission": "共同撰写文档",
"CoAuthorDocumentDescription": "授予用户共同撰写文档的权限",
"CreateDocumentPermission": "创建文档",

View File

@ -21,7 +21,8 @@ import {
SortingOrder,
type WithLookup,
type Doc,
getCurrentAccount
getCurrentAccount,
checkPermission
} from '@hcengineering/core'
import {
type Document,
@ -150,6 +151,24 @@ async function deleteDocuments (obj: Document | Document[]): Promise<void> {
})
}
async function archiveDocuments (obj: Document | Document[]): Promise<void> {
const docs = Array.isArray(obj) ? obj : [obj]
const docNames = docs.map((d) => `${d.title} (${d.prefix}-${d.seqNumber})`).join(', ')
showPopup(MessageBox, {
label: documents.string.ArchiveDocs,
labelProps: { count: docs.length },
message: documents.string.ArchiveDocsConfirm,
params: { titles: docNames },
action: async () => {
const client = getClient()
for (const doc of docs) {
await client.update(doc, { state: DocumentState.Archived })
}
}
})
}
async function canDeleteDocument (obj?: Doc | Doc[]): Promise<boolean> {
if (obj == null) {
return false
@ -166,6 +185,28 @@ async function canDeleteDocument (obj?: Doc | Doc[]): Promise<boolean> {
return await isLatestDraftDoc(obj)
}
async function canArchiveDocument (obj?: Doc | Doc[]): Promise<boolean> {
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 isLatestDraftDoc (obj?: Doc | Doc[]): Promise<boolean> {
if (obj == null) {
return false
@ -280,6 +321,7 @@ export default async (): Promise<Resources> => ({
GetAllDocumentStates: getAllDocumentStates,
GetDocumentMetaLinkFragment: getDocumentMetaLinkFragment,
CanDeleteDocument: canDeleteDocument,
CanArchiveDocument: canArchiveDocument,
DocumentIdentifierProvider: documentIdentifierProvider,
ControlledDocumentTitleProvider: getControlledDocumentTitle,
Comment: comment,
@ -291,6 +333,7 @@ export default async (): Promise<Resources> => ({
CreateDocument: createDocument,
CreateTemplate: createTemplate,
DeleteDocument: deleteDocuments,
ArchiveDocument: archiveDocuments,
EditDocSpace: editDocSpace
},
resolver: {

View File

@ -172,6 +172,9 @@ export default mergeIds(documentsId, documents, {
MarkDocsAsDeleted: '' as IntlString,
MarkDocAsDeletedConfirm: '' as IntlString,
ArchiveDocs: '' as IntlString,
ArchiveDocsConfirm: '' as IntlString,
DocumentInHierarchy: '' as IntlString,
FirstDraftVersion: '' as IntlString,
@ -232,6 +235,7 @@ export default mergeIds(documentsId, documents, {
GetVisibleFilters: '' as Resource<(filters: KeyFilter[], space?: Ref<Space>) => Promise<KeyFilter[]>>,
GetDocumentMetaLinkFragment: '' as Resource<(doc: Doc, props: Record<string, any>) => Promise<Location>>,
CanDeleteDocument: '' as Resource<(doc?: Doc | Doc[]) => Promise<boolean>>,
CanArchiveDocument: '' as Resource<(doc?: Doc | Doc[]) => Promise<boolean>>,
ControlledDocumentTitleProvider: '' as Resource<(client: Client, ref: Ref<Doc>, doc?: Doc) => Promise<string>>
}
})

View File

@ -17,15 +17,13 @@ import { DocumentState } from '@hcengineering/controlled-documents'
import { combine } from 'effector'
import { $controlledDocument, $documentAllVersionsDescSorted } from './editor'
const states: DocumentState[] = [DocumentState.Deleted, DocumentState.Effective]
export const $canCreateNewDraft = combine($controlledDocument, $documentAllVersionsDescSorted, (document, versions) => {
if (document == null) return false
const effectiveIndex = versions.findIndex((p) => p.state === DocumentState.Effective)
const currentIndex = versions.findIndex((p) => p._id === document._id)
return effectiveIndex === -1
? states.includes(document.state)
: currentIndex <= effectiveIndex && versions.slice(0, effectiveIndex).every((p) => states.includes(p.state))
return (
versions.slice(0, currentIndex).every((p) => p.state === DocumentState.Deleted) &&
document.state !== DocumentState.Draft
)
})

View File

@ -115,6 +115,7 @@ export const documentsPlugin = plugin(documentsId, {
CreateTemplate: '' as Ref<Action<DocumentSpace, any>>,
DeleteDocumentCategory: '' as Ref<Action<Doc, any>>,
DeleteDocument: '' as Ref<Action>,
ArchiveDocument: '' as Ref<Action>,
EditDocSpace: '' as Ref<Action>,
Print: '' as Ref<Action<Doc, { signed: boolean }>>
},
@ -242,6 +243,8 @@ export const documentsPlugin = plugin(documentsId, {
ReviewDocumentDescription: '' as IntlString,
ApproveDocumentPermission: '' as IntlString,
ApproveDocumentDescription: '' as IntlString,
ArchiveDocumentPermission: '' as IntlString,
ArchiveDocumentDescription: '' as IntlString,
CoAuthorDocumentPermission: '' as IntlString,
CoAuthorDocumentDescription: '' as IntlString,
CreateDocumentPermission: '' as IntlString,
@ -282,6 +285,7 @@ export const documentsPlugin = plugin(documentsId, {
permission: {
ReviewDocument: '' as Ref<Permission>,
ApproveDocument: '' as Ref<Permission>,
ArchiveDocument: '' as Ref<Permission>,
CoAuthorDocument: '' as Ref<Permission>,
CreateDocument: '' as Ref<Permission>,
UpdateDocumentOwner: '' as Ref<Permission>,