Skip to content

Commit

Permalink
EQMS-1451/1453/1455: reference tweaks for QMS documents (#8083)
Browse files Browse the repository at this point in the history
* EQMS-1451/1453/1455: reference tweaks for QMS documents

Signed-off-by: Victor Ilyushchenko <[email protected]>

* fmt

Signed-off-by: Victor Ilyushchenko <[email protected]>

---------

Signed-off-by: Victor Ilyushchenko <[email protected]>
  • Loading branch information
mr1name authored Feb 24, 2025
1 parent f981529 commit c6e752c
Show file tree
Hide file tree
Showing 22 changed files with 195 additions and 40 deletions.
14 changes: 13 additions & 1 deletion models/controlled-documents/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ export function createModel (builder: Builder): void {
})

builder.mixin(documents.class.DocumentMeta, core.class.Class, view.mixin.ObjectTitle, {
titleProvider: documents.function.ControlledDocumentTitleProvider
titleProvider: documents.function.DocumentMetaTitleProvider
})

builder.mixin(documents.class.DocumentApprovalRequest, core.class.Class, view.mixin.ObjectPresenter, {
Expand Down Expand Up @@ -406,6 +406,10 @@ export function createModel (builder: Builder): void {
presenter: documents.component.DocumentPresenter
})

builder.mixin(documents.class.ControlledDocument, core.class.Class, view.mixin.LinkProvider, {
encode: documents.function.GetControlledDocumentLinkFragment
})

builder.mixin(documents.class.Document, core.class.Class, view.mixin.IgnoreActions, {
actions: [view.action.Delete]
})
Expand Down Expand Up @@ -741,6 +745,14 @@ export function createModel (builder: Builder): void {
provider: documents.function.DocumentIdentifierProvider
})

builder.mixin(documents.class.ControlledDocument, core.class.Class, view.mixin.ReferenceObjectProvider, {
provider: documents.function.ControlledDocumentReferenceObjectProvider
})

builder.mixin(documents.class.ProjectDocument, core.class.Class, view.mixin.ReferenceObjectProvider, {
provider: documents.function.ProjectDocumentReferenceObjectProvider
})

createAction(
builder,
{
Expand Down
6 changes: 6 additions & 0 deletions models/controlled-documents/src/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,12 @@ export default mergeIds(documentsId, documents, {
DocumentIdentifierProvider: '' as Resource<
<T extends Doc>(client: Client, ref: Ref<T>, doc?: T) => Promise<string>
>,
ControlledDocumentReferenceObjectProvider: '' as Resource<
<T extends Doc>(client: Client, ref: Ref<T>, doc?: T) => Promise<Doc>
>,
ProjectDocumentReferenceObjectProvider: '' as Resource<
<T extends Doc>(client: Client, ref: Ref<T>, doc?: T) => Promise<Doc>
>,
Comment: '' as Resource<TextActionFunction>,
IsCommentVisible: '' as Resource<TextActionVisibleFunction>
},
Expand Down
7 changes: 7 additions & 0 deletions models/view/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ import {
type ViewletDescriptor,
type ViewletPreference,
type ObjectIdentifier,
type ReferenceObjectProvider,
type ObjectIcon,
type ObjectTooltip,
type AttrPresenter,
Expand Down Expand Up @@ -253,6 +254,11 @@ export class TObjectIdentifier extends TClass implements ObjectIdentifier {
provider!: Resource<<T extends Doc>(client: Client, ref: Ref<T>, doc?: T) => Promise<string>>
}

@Mixin(view.mixin.ReferenceObjectProvider, core.class.Class)
export class TReferenceObjectProvider extends TClass implements ReferenceObjectProvider {
provider!: Resource<<T extends Doc>(client: Client, ref: Ref<T>, doc?: T) => Promise<Doc | undefined>>
}

@Mixin(view.mixin.ObjectTooltip, core.class.Class)
export class TObjectTooltip extends TClass implements ObjectTooltip {
provider!: Resource<(client: Client, doc?: Doc | null) => Promise<LabelAndProps | undefined>>
Expand Down Expand Up @@ -465,6 +471,7 @@ export function createModel (builder: Builder): void {
TAggregation,
TGroupping,
TObjectIdentifier,
TReferenceObjectProvider,
TObjectTooltip,
TObjectIcon,
TAttrPresenter,
Expand Down
4 changes: 3 additions & 1 deletion plugins/controlled-documents-assets/lang/cs.json
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,9 @@
"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}?"
"MakeDocumentObsoleteConfirm": "Opravdu chcete označit následující dokumenty jako zastaralé: {titles}?",

"LatestVersionHint": "nejnovější"
},
"controlledDocStates": {
"Empty": "",
Expand Down
4 changes: 3 additions & 1 deletion plugins/controlled-documents-assets/lang/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,9 @@
"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}?"
"MakeDocumentObsoleteConfirm": "Möchten Sie die folgenden Dokumente wirklich als veraltet markieren: {titles}?",

"LatestVersionHint": "neueste"
},
"controlledDocStates": {
"Empty": "",
Expand Down
4 changes: 3 additions & 1 deletion plugins/controlled-documents-assets/lang/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,9 @@

"CreateFolder": "Create new folder",
"RenameFolder": "Rename folder",
"CreateChildFolder": "Create child folder"
"CreateChildFolder": "Create child folder",

"LatestVersionHint": "latest"
},
"controlledDocStates": {
"Empty": "",
Expand Down
4 changes: 3 additions & 1 deletion plugins/controlled-documents-assets/lang/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,9 @@
"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} ?"
"MakeDocumentObsoleteConfirm": "Voulez-vous vraiment marquer les documents suivants comme obsolètes : {titles} ?",

"LatestVersionHint": "dernier"
},
"controlledDocStates": {
"Empty": "",
Expand Down
4 changes: 3 additions & 1 deletion plugins/controlled-documents-assets/lang/it.json
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,9 @@
"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}?"
"MakeDocumentObsoleteConfirm": "Vuoi davvero segnare i seguenti documenti come obsoleti: {titles}?",

"LatestVersionHint": "ultimo"
},
"controlledDocStates": {
"Empty": "",
Expand Down
4 changes: 3 additions & 1 deletion plugins/controlled-documents-assets/lang/ru.json
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,9 @@
"Obsolete": "Устаревший",
"MakeDocumentObsolete": "Пометить как устаревшее",
"MakeDocumentObsoleteDialog": "Пометить {count, plural, one {документ как устаревший} other {документы как устаревшие}}",
"MakeDocumentObsoleteConfirm": "Вы действительно хотите пометить следующие документы как устаревшие: {titles}?"
"MakeDocumentObsoleteConfirm": "Вы действительно хотите пометить следующие документы как устаревшие: {titles}?",

"LatestVersionHint": "последняя"
},
"controlledDocStates": {
"Empty": "",
Expand Down
4 changes: 3 additions & 1 deletion plugins/controlled-documents-assets/lang/zh.json
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,9 @@
"Obsolete": "已过时",
"MakeDocumentObsolete": "标记为过时",
"MakeDocumentObsoleteDialog": "标记 {count, plural, one {文档为过时} other {文档为过时}}",
"MakeDocumentObsoleteConfirm": "您确定要将以下文档标记为过时吗:{titles}?"
"MakeDocumentObsoleteConfirm": "您确定要将以下文档标记为过时吗:{titles}?",

"LatestVersionHint": "最新"
},
"controlledDocStates": {
"Empty": "",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,12 @@
$documentComments as documentComments,
documentCommentsDisplayRequested,
documentCommentsHighlightUpdated,
documentCommentsLocationNavigateRequested
documentCommentsLocationNavigateRequested,
$documentReleasedVersions as documentReleasedVersions
} from '../../stores/editors/document'
import DocumentTitle from './DocumentTitle.svelte'
import DocumentPrintTitlePage from '../print/DocumentPrintTitlePage.svelte'
import { syncDocumentMetaTitle } from '../../utils'
const client = getClient()
const hierarchy = client.getHierarchy()
Expand Down Expand Up @@ -111,14 +113,17 @@
unsubscribeNavigateToLocation()
})
const handleUpdateTitle = () => {
const handleUpdateTitle = async () => {
if (!$controlledDocument || !title) {
return
}
const titleTrimmed = title.trim()
if (titleTrimmed.length > 0 && titleTrimmed !== $controlledDocument.title) {
client.update($controlledDocument, { title: titleTrimmed })
await client.update($controlledDocument, { title: titleTrimmed })
if ($documentReleasedVersions.length === 0 && $controlledDocument.state === DocumentState.Draft) {
await syncDocumentMetaTitle(client, $controlledDocument.attachedTo, $controlledDocument.code, titleTrimmed)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,15 @@

<script lang="ts">
import { createEventDispatcher } from 'svelte'
import documents, { Document } from '@hcengineering/controlled-documents'
import documents, { ControlledDocument } from '@hcengineering/controlled-documents'
import presentation, { createQuery, getClient } from '@hcengineering/presentation'
import { Button, EditBox, Label } from '@hcengineering/ui'
import IconWarning from '../../icons/IconWarning.svelte'
import documentsRes from '../../../plugin'
import { syncDocumentMetaTitle } from '../../../utils'
export let object: Document
export let object: ControlledDocument
const client = getClient()
const dispatch = createEventDispatcher()
Expand Down Expand Up @@ -59,6 +60,7 @@
}
await client.update(object, { code })
await syncDocumentMetaTitle(client, object.attachedTo, code, object.title)
dispatch('close')
}
</script>
Expand Down
6 changes: 6 additions & 0 deletions plugins/controlled-documents-resources/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,10 @@ import {
createTemplate,
deleteFolder,
documentIdentifierProvider,
controlledDocumentReferenceObjectProvider,
projectDocumentReferenceObjectProvider,
getAllDocumentStates,
getControlledDocumentLinkFragment,
getControlledDocumentTitle,
getDocumentMetaLinkFragment,
getDocumentMetaTitle,
Expand Down Expand Up @@ -450,13 +453,16 @@ export default async (): Promise<Resources> => ({
DocumentStateSort: sortDocumentStates,
GetAllDocumentStates: getAllDocumentStates,
GetDocumentMetaLinkFragment: getDocumentMetaLinkFragment,
GetControlledDocumentLinkFragment: getControlledDocumentLinkFragment,
CanDeleteDocument: canDeleteDocument,
CanArchiveDocument: canArchiveDocument,
CanMakeDocumentObsolete: canMakeDocumentObsolete,
CanTransferDocument: canTransferDocument,
CanOpenDocument: canOpenDocument,
CanPrintDocument: canPrintDocument,
DocumentIdentifierProvider: documentIdentifierProvider,
ControlledDocumentReferenceObjectProvider: controlledDocumentReferenceObjectProvider,
ProjectDocumentReferenceObjectProvider: projectDocumentReferenceObjectProvider,
ControlledDocumentTitleProvider: getControlledDocumentTitle,
DocumentMetaTitleProvider: getDocumentMetaTitle,
Comment: comment,
Expand Down
5 changes: 4 additions & 1 deletion plugins/controlled-documents-resources/src/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,9 @@ export default mergeIds(documentsId, documents, {

CreateDocumentFailed: '' as IntlString,
CreateDocumentTemplateFailed: '' as IntlString,
TryAgain: '' as IntlString
TryAgain: '' as IntlString,

LatestVersionHint: '' as IntlString
},
controlledDocStates: {
Empty: '' as IntlString,
Expand Down Expand Up @@ -240,6 +242,7 @@ export default mergeIds(documentsId, documents, {
GetAllDocumentStates: '' as Resource<() => Promise<DocumentState[]>>,
GetVisibleFilters: '' as Resource<(filters: KeyFilter[], space?: Ref<Space>) => Promise<KeyFilter[]>>,
GetDocumentMetaLinkFragment: '' as Resource<(doc: Doc, props: Record<string, any>) => Promise<Location>>,
GetControlledDocumentLinkFragment: '' 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>>,
Expand Down
72 changes: 67 additions & 5 deletions plugins/controlled-documents-resources/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { type Employee, type Person, type PersonAccount } from '@hcengineering/c
import documents, {
type ControlledDocument,
type Document,
type DocumentBundle,
type DocumentCategory,
type DocumentComment,
type DocumentMeta,
Expand All @@ -27,12 +28,12 @@ import documents, {
type ProjectDocument,
type ProjectMeta,
ControlledDocumentState,
type DocumentBundle,
DocumentState,
ProjectDocumentTree,
compareDocumentVersions,
emptyBundle,
getDocumentName,
getFirstRank,
ProjectDocumentTree
getFirstRank
} from '@hcengineering/controlled-documents'
import core, {
type Class,
Expand Down Expand Up @@ -195,6 +196,18 @@ export async function getDocumentMetaLinkFragment (document: Doc): Promise<Locat
return getProjectDocumentLink(targetDocument, project)
}

export async function getControlledDocumentLinkFragment (document: ControlledDocument): Promise<Location> {
const client = getClient()
const targetDocument = await client.findOne(documents.class.ProjectDocument, { document: document._id })

if (targetDocument === undefined) {
throw new Error('Cannot resolve a ProjectDocument for document ' + document._id)
}

const project = targetDocument.project ?? documents.ids.NoProject
return getProjectDocumentLink(document, project)
}

export interface TeamPopupData {
controlledDoc: ControlledDocument
requestClass: Ref<Class<DocumentRequest>>
Expand Down Expand Up @@ -707,6 +720,41 @@ export async function documentIdentifierProvider (client: Client, ref: Ref<Docum
return document.code
}

export async function controlledDocumentReferenceObjectProvider (
client: Client,
ref: Ref<ControlledDocument>,
doc?: ControlledDocument
): Promise<Doc | undefined> {
const document = doc ?? (await client.findOne(documents.class.ControlledDocument, { _id: ref }))
if (document === undefined) return

const meta = await client.findOne(documents.class.DocumentMeta, { _id: document.attachedTo })
if (meta === undefined) return

let documentSeq: ControlledDocument[] = await client.findAll(documents.class.ControlledDocument, {
attachedTo: meta._id
})

const allowStates = [DocumentState.Draft, DocumentState.Effective]
documentSeq = documentSeq.filter((d) => allowStates.includes(d.state)).sort(compareDocumentVersions)

const effIndex = documentSeq.findIndex((d) => d.state === DocumentState.Effective)
const docIndex = documentSeq.findIndex((d) => d._id === document._id)

return docIndex >= 0 && (docIndex <= effIndex || effIndex < 0) ? meta : document
}

export async function projectDocumentReferenceObjectProvider (
client: Client,
ref: Ref<ProjectDocument>,
doc?: ProjectDocument
): Promise<Doc | undefined> {
const prjdoc = doc ?? (await client.findOne(documents.class.ProjectDocument, { _id: ref }))
if (prjdoc === undefined) return

return await controlledDocumentReferenceObjectProvider(client, prjdoc.document as Ref<ControlledDocument>)
}

export function documentCompareFn (doc1: Document, doc2: Document): number {
return doc1.major - doc2.major !== 0 ? doc1.major - doc2.major : doc1.minor - doc2.minor
}
Expand All @@ -724,7 +772,7 @@ export async function getControlledDocumentTitle (

if (object === undefined) return ''

return object.title
return object.title + ` (${getDocumentVersionString(object)})`
}

export async function getDocumentMetaTitle (
Expand All @@ -736,7 +784,9 @@ export async function getDocumentMetaTitle (

if (object === undefined) return ''

return object.title
const hint = await translate(documentsResources.string.LatestVersionHint, {})

return object.title + ` (${hint})`
}

export const getCurrentEmployee = (): Ref<Employee> | undefined => {
Expand Down Expand Up @@ -932,3 +982,15 @@ export class DocumentHiearchyQuery {
export function createDocumentHierarchyQuery (): DocumentHiearchyQuery {
return new DocumentHiearchyQuery()
}

export async function syncDocumentMetaTitle (
client: Client & TxOperations,
_id: Ref<DocumentMeta>,
code: string,
title: string
): Promise<void> {
const meta = await client.findOne(documents.class.DocumentMeta, { _id })
if (meta !== undefined) {
await client.update(meta, { title: `${code} ${title}` })
}
}
2 changes: 1 addition & 1 deletion plugins/controlled-documents/src/docutils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ export async function createControlledDocMetadata (
space,
{
documents: 0,
title: `${prefix}-${seqNumber} ${specTitle}`
title: `${specCode} ${specTitle}`
},
metaId
)
Expand Down
Loading

0 comments on commit c6e752c

Please sign in to comment.