mirror of
https://github.com/hcengineering/platform.git
synced 2026-08-17 18:05:42 +02:00
EZQMS-1392: Obsolete documents (#7833)
Signed-off-by: Victor Ilyushchenko <alt13ri@gmail.com>
This commit is contained in:
@@ -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(
|
||||
|
||||
@@ -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
|
||||
},
|
||||
|
||||
@@ -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": "",
|
||||
|
||||
@@ -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": "",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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": "",
|
||||
|
||||
@@ -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": "",
|
||||
|
||||
@@ -304,7 +304,12 @@
|
||||
|
||||
"CreateFolder": "Создать новую папку",
|
||||
"RenameFolder": "Переименовать папку",
|
||||
"CreateChildFolder": "Создать подпапку"
|
||||
"CreateChildFolder": "Создать подпапку",
|
||||
|
||||
"Obsolete": "Устаревший",
|
||||
"MakeDocumentObsolete": "Пометить как устаревшее",
|
||||
"MakeDocumentObsoleteDialog": "Пометить {count, plural, one {документ как устаревший} other {документы как устаревшие}}",
|
||||
"MakeDocumentObsoleteConfirm": "Вы действительно хотите пометить следующие документы как устаревшие: {titles}?"
|
||||
},
|
||||
"controlledDocStates": {
|
||||
"Empty": "",
|
||||
|
||||
@@ -301,7 +301,12 @@
|
||||
|
||||
"CreateFolder": "创建新文件夹",
|
||||
"RenameFolder": "重命名文件夹",
|
||||
"CreateChildFolder": "创建子文件夹"
|
||||
"CreateChildFolder": "创建子文件夹",
|
||||
|
||||
"Obsolete": "已过时",
|
||||
"MakeDocumentObsolete": "标记为过时",
|
||||
"MakeDocumentObsoleteDialog": "标记 {count, plural, one {文档为过时} other {文档为过时}}",
|
||||
"MakeDocumentObsoleteConfirm": "您确定要将以下文档标记为过时吗:{titles}?"
|
||||
},
|
||||
"controlledDocStates": {
|
||||
"Empty": "",
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -118,6 +118,7 @@
|
||||
DocumentState.Archived,
|
||||
DocumentState.Deleted,
|
||||
DocumentState.Effective,
|
||||
DocumentState.Obsolete,
|
||||
ControlledDocumentState.InApproval,
|
||||
ControlledDocumentState.Approved,
|
||||
ControlledDocumentState.ToReview
|
||||
|
||||
+3
-3
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+5
-4
@@ -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}
|
||||
<div class="flex-col relative">
|
||||
{#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}
|
||||
|
||||
+4
-1
@@ -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))
|
||||
</script>
|
||||
|
||||
{#if $controlledDocument !== null}
|
||||
|
||||
@@ -182,6 +182,24 @@ async function archiveDocuments (obj: Document | Document[]): Promise<void> {
|
||||
})
|
||||
}
|
||||
|
||||
async function makeDocumentObsolete (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.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<boolean> {
|
||||
if (obj == null) {
|
||||
return false
|
||||
@@ -220,6 +238,28 @@ async function canArchiveDocument (obj?: Doc | Doc[]): Promise<boolean> {
|
||||
).then((res) => res.every((r) => r))
|
||||
}
|
||||
|
||||
async function canMakeDocumentObsolete (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 canOpenDocument (obj?: ProjectDocument | ProjectDocument[]): Promise<boolean> {
|
||||
if (obj == null) {
|
||||
return false
|
||||
@@ -411,6 +451,7 @@ export default async (): Promise<Resources> => ({
|
||||
GetDocumentMetaLinkFragment: getDocumentMetaLinkFragment,
|
||||
CanDeleteDocument: canDeleteDocument,
|
||||
CanArchiveDocument: canArchiveDocument,
|
||||
CanMakeDocumentObsolete: canMakeDocumentObsolete,
|
||||
CanTransferDocument: canTransferDocument,
|
||||
CanOpenDocument: canOpenDocument,
|
||||
CanPrintDocument: canPrintDocument,
|
||||
@@ -430,6 +471,7 @@ export default async (): Promise<Resources> => ({
|
||||
CreateFolder: createFolder,
|
||||
DeleteDocument: deleteDocuments,
|
||||
ArchiveDocument: archiveDocuments,
|
||||
MakeDocumentObsolete: makeDocumentObsolete,
|
||||
TransferDocument: transferDocuments,
|
||||
EditDocSpace: editDocSpace
|
||||
},
|
||||
|
||||
@@ -242,6 +242,7 @@ export default mergeIds(documentsId, documents, {
|
||||
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>>,
|
||||
CanMakeDocumentObsolete: '' as Resource<(doc?: Doc | Doc[]) => Promise<boolean>>,
|
||||
CanOpenDocument: '' as Resource<(doc?: Doc | Doc[]) => Promise<boolean>>,
|
||||
CanPrintDocument: '' as Resource<(doc?: Doc | Doc[]) => Promise<boolean>>,
|
||||
CanTransferDocument: '' as Resource<(doc?: Doc | Doc[]) => Promise<boolean>>,
|
||||
|
||||
+2
-1
@@ -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)
|
||||
)
|
||||
})
|
||||
|
||||
@@ -82,7 +82,8 @@ export async function getTranslatedDocumentStates (lang: string): Promise<Transl
|
||||
[DocumentState.Draft]: await translate(documents.string.Draft, {}, lang),
|
||||
[DocumentState.Deleted]: await translate(documents.string.Deleted, {}, lang),
|
||||
[DocumentState.Effective]: await translate(documents.string.Effective, {}, lang),
|
||||
[DocumentState.Archived]: await translate(documents.string.Archived, {}, lang)
|
||||
[DocumentState.Archived]: await translate(documents.string.Archived, {}, lang),
|
||||
[DocumentState.Obsolete]: await translate(documents.string.Obsolete, {}, lang)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -159,6 +160,8 @@ export async function getDocumentMetaLinkFragment (document: Doc): Promise<Locat
|
||||
break
|
||||
} else if (doc.state === DocumentState.Deleted && targetDocument === undefined) {
|
||||
targetDocument = doc
|
||||
} else if (doc.state === DocumentState.Obsolete && targetDocument === undefined) {
|
||||
targetDocument = doc
|
||||
} else if (doc.state === DocumentState.Draft) {
|
||||
targetDocument = doc
|
||||
} else if (doc.state === DocumentState.Archived) {
|
||||
@@ -363,13 +366,15 @@ export const statesTags: StatesTags = {
|
||||
[DocumentState.Draft]: 'draft',
|
||||
[DocumentState.Effective]: 'effective',
|
||||
[DocumentState.Archived]: 'obsolete',
|
||||
[DocumentState.Deleted]: 'obsolete'
|
||||
[DocumentState.Deleted]: 'obsolete',
|
||||
[DocumentState.Obsolete]: 'obsolete'
|
||||
}
|
||||
|
||||
export const documentStatesOrder = [
|
||||
DocumentState.Draft,
|
||||
DocumentState.Effective,
|
||||
DocumentState.Archived,
|
||||
DocumentState.Obsolete,
|
||||
DocumentState.Deleted
|
||||
]
|
||||
|
||||
|
||||
@@ -121,6 +121,7 @@ export const documentsPlugin = plugin(documentsId, {
|
||||
DeleteDocumentCategory: '' as Ref<Action<Doc, any>>,
|
||||
DeleteDocument: '' as Ref<Action>,
|
||||
ArchiveDocument: '' as Ref<Action>,
|
||||
MakeDocumentObsolete: '' as Ref<Action>,
|
||||
EditDocSpace: '' as Ref<Action>,
|
||||
TransferDocument: '' as Ref<Action>,
|
||||
Print: '' as Ref<Action<Doc, { signed: boolean }>>,
|
||||
@@ -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,
|
||||
|
||||
@@ -194,7 +194,8 @@ export enum DocumentState {
|
||||
Draft = 'draft',
|
||||
Effective = 'effective',
|
||||
Archived = 'archived',
|
||||
Deleted = 'deleted'
|
||||
Deleted = 'deleted',
|
||||
Obsolete = 'obsolete'
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user