EQMS-1471: Fixed authorship and ownership semantics & labels in qms to prevent confusion (#8629)
Some checks are pending
CI / build (push) Waiting to run
CI / svelte-check (push) Blocked by required conditions
CI / formatting (push) Blocked by required conditions
CI / test (push) Blocked by required conditions
CI / uitest (push) Waiting to run
CI / uitest-pg (push) Waiting to run
CI / uitest-qms (push) Waiting to run
CI / uitest-workspaces (push) Waiting to run
CI / docker-build (push) Blocked by required conditions
CI / dist-build (push) Blocked by required conditions

Signed-off-by: Victor Ilyushchenko <alt13ri@gmail.com>
This commit is contained in:
Victor Ilyushchenko 2025-04-21 16:31:47 +03:00 committed by GitHub
parent d4517bbbdb
commit d450a7397f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 79 additions and 68 deletions

View File

@ -32,6 +32,7 @@ import tracker from '@hcengineering/model-tracker'
import view, { classPresenter, createAction } from '@hcengineering/model-view'
import workbench from '@hcengineering/model-workbench'
import notification from '@hcengineering/notification'
import contacts from '@hcengineering/model-contact'
import setting from '@hcengineering/setting'
import tags from '@hcengineering/tags'
import textEditor from '@hcengineering/text-editor'
@ -266,7 +267,7 @@ export function createModel (builder: Builder): void {
},
{
key: '$lookup.owner',
label: documents.string.Owner,
label: documents.string.Author,
presenter: documents.component.OwnerPresenter,
props: { shouldShowLabel: true, isEditable: false },
sortingKey: '$lookup.owner.name'
@ -329,7 +330,7 @@ export function createModel (builder: Builder): void {
},
{
key: '$lookup.owner',
label: documents.string.Owner,
label: documents.string.Author,
presenter: documents.component.OwnerPresenter,
props: { shouldShowLabel: true, isEditable: false },
sortingKey: '$lookup.owner.name'
@ -630,13 +631,23 @@ export function createModel (builder: Builder): void {
'state',
'space',
'template',
'owner',
{
_class: documents.class.Document,
component: contacts.component.EmployeeFilter,
key: 'owner',
label: documents.string.Author
},
'category',
'modifiedOn',
'labels',
'major',
'minor',
'author'
{
_class: documents.class.Document,
component: contacts.component.EmployeeFilter,
key: 'author',
label: documents.string.Creator
}
],
getVisibleFilters: documents.function.GetVisibleFilters
})

View File

@ -22,11 +22,12 @@
"Minor": "Vedlejší",
"Patch": "Oprava",
"ValidationWorkflow": "Ověřovací pracovní postup",
"ChangeOwner": "Změnit vlastníka dokumentu",
"ChangeOwnerHintBeginning": "Převést vlastnictví",
"Creator": "Tvůrce",
"ChangeOwner": "Změnit autora dokumentu",
"ChangeOwnerHintBeginning": "Převést autorství dokumentu",
"ChangeOwnerHintEnd": "na jinou osobu.",
"ChangeOwnerWarning": "Po této akci nebudete moci dokument upravovat.",
"SelectOwner": "Vyberte nového vlastníka",
"SelectOwner": "Vyberte nového autora",
"CreateDocument": "Vytvořit nový dokument",
"CreateTemplate": "Vytvořit novou šablonu",
"Documents": "Dokumenty",

View File

@ -22,11 +22,12 @@
"Minor": "Nebenversion",
"Patch": "Patch",
"ValidationWorkflow": "Validierungsworkflow",
"ChangeOwner": "Dokumentenbesitzer ändern",
"ChangeOwnerHintBeginning": "Übertragen Sie den Besitz des",
"Creator": "Ersteller",
"ChangeOwner": "Dokumentautor ändern",
"ChangeOwnerHintBeginning": "Autorschaft des Dokuments übertragen",
"ChangeOwnerHintEnd": "an eine andere Person.",
"ChangeOwnerWarning": "Sie können dieses Dokument nach dieser Aktion nicht mehr bearbeiten.",
"SelectOwner": "Neuen Besitzer auswählen",
"SelectOwner": "Neuen Autor auswählen",
"CreateDocument": "Neues Dokument erstellen",
"CreateTemplate": "Neue Vorlage erstellen",
"Documents": "Dokumente",

View File

@ -22,11 +22,12 @@
"Minor": "Minor",
"Patch": "Patch",
"ValidationWorkflow": "Validation workflow",
"ChangeOwner": "Change document owner",
"ChangeOwnerHintBeginning": "Transfer ownership of the",
"Creator": "Creator",
"ChangeOwner": "Change document author",
"ChangeOwnerHintBeginning": "Transfer authorship of the",
"ChangeOwnerHintEnd": "to another person.",
"ChangeOwnerWarning": "You will not be able to edit this document after this action.",
"SelectOwner": "Select new owner",
"SelectOwner": "Select new author",
"CreateDocument": "Create new document",
"CreateTemplate": "Create new template",
"Documents": "Documents",

View File

@ -22,11 +22,12 @@
"Minor": "Mineur",
"Patch": "Correctif",
"ValidationWorkflow": "Flux de validation",
"ChangeOwner": "Changer le propriétaire du document",
"ChangeOwnerHintBeginning": "Transférer la propriété du",
"Creator": "Créateur",
"ChangeOwner": "Changer lauteur du document",
"ChangeOwnerHintBeginning": "Transférer lauteur du document",
"ChangeOwnerHintEnd": "à une autre personne.",
"ChangeOwnerWarning": "Vous ne pourrez plus modifier ce document après cette action.",
"SelectOwner": "Sélectionner un nouveau propriétaire",
"SelectOwner": "Sélectionner un nouvel auteur",
"CreateDocument": "Créer un nouveau document",
"CreateTemplate": "Créer un nouveau modèle",
"Documents": "Documents",

View File

@ -22,11 +22,12 @@
"Minor": "Minore",
"Patch": "Patch",
"ValidationWorkflow": "Flusso di convalida",
"ChangeOwner": "Cambia proprietario del documento",
"ChangeOwnerHintBeginning": "Trasferisci la proprietà del",
"Creator": "Creatore",
"ChangeOwner": "Modifica autore del documento",
"ChangeOwnerHintBeginning": "Trasferisci la paternità del documento",
"ChangeOwnerHintEnd": "a un'altra persona.",
"ChangeOwnerWarning": "Non potrai modificare questo documento dopo questa azione.",
"SelectOwner": "Seleziona nuovo proprietario",
"SelectOwner": "Seleziona un nuovo autore",
"CreateDocument": "Crea nuovo documento",
"CreateTemplate": "Crea nuovo modello",
"Documents": "Documenti",

View File

@ -22,11 +22,12 @@
"Minor": "Secundária",
"Patch": "Correção",
"ValidationWorkflow": "Fluxo de validação",
"ChangeOwner": "Alterar responsável pelo documento",
"ChangeOwnerHintBeginning": "Transferir a propriedade do",
"Creator": "Criador",
"ChangeOwner": "Alterar autor do documento",
"ChangeOwnerHintBeginning": "Transferir autoria do documento",
"ChangeOwnerHintEnd": "para outra pessoa.",
"ChangeOwnerWarning": "Você não poderá mais editar este documento após essa ação.",
"SelectOwner": "Selecionar novo responsável",
"SelectOwner": "Selecionar novo autor",
"CreateDocument": "Criar novo documento",
"CreateTemplate": "Criar novo modelo",
"Documents": "Documentos",

View File

@ -22,11 +22,12 @@
"Minor": "Минорная",
"Patch": "Патч",
"ValidationWorkflow": "Процесс валидации",
"ChangeOwner": "Изменить владельца документа",
"ChangeOwnerHintBeginning": "Передайте права владельца документа",
"Creator": "Создатель",
"ChangeOwner": "Сменить автора документа",
"ChangeOwnerHintBeginning": "Передать авторство документа",
"ChangeOwnerHintEnd": "другому лицу.",
"ChangeOwnerWarning": "Вы не сможете редактировать документ после этой операции.",
"SelectOwner": "Выберите нового владельца",
"SelectOwner": "Выберите нового автора",
"CreateDocument": "Создать документ",
"CreateTemplate": "Создать шаблон",
"Documents": "Документы",

View File

@ -22,11 +22,12 @@
"Minor": "次要",
"Patch": "补丁",
"ValidationWorkflow": "验证工作流程",
"ChangeOwner": "更改文档所有者",
"ChangeOwnerHintBeginning": "转移所有权",
"Creator": "创建者",
"ChangeOwner": "更改文档作者",
"ChangeOwnerHintBeginning": "转移文档的作者身份",
"ChangeOwnerHintEnd": "给其他人。",
"ChangeOwnerWarning": "此操作后您将无法编辑此文档。",
"SelectOwner": "选择新所有者",
"SelectOwner": "选择新的作者",
"CreateDocument": "创建新文档",
"CreateTemplate": "创建新模板",
"Documents": "文档",

View File

@ -143,7 +143,7 @@
<StatePresenter value={$controlledDocument} showTag={false} />
</DocumentInfo>
<DocumentInfo label={documentsRes.string.Owner}>
<DocumentInfo label={documentsRes.string.Author}>
<OwnerPresenter
_id={$controlledDocument.owner}
object={$controlledDocument}
@ -153,7 +153,7 @@
/>
</DocumentInfo>
<DocumentInfo label={documentsRes.string.Author}>
<DocumentInfo label={documentsRes.string.Creator}>
<PersonPresenter value={$controlledDocument.author} disabled={true} />
</DocumentInfo>
</div>

View File

@ -172,6 +172,7 @@ export const documentsPlugin = plugin(documentsId, {
Category: '' as IntlString,
Author: '' as IntlString,
Owner: '' as IntlString,
Creator: '' as IntlString,
Status: '' as IntlString,
Labels: '' as IntlString,
Description: '' as IntlString,

View File

@ -133,13 +133,13 @@ test.describe('QMS. Documents tests', () => {
await attachScreenshot('TESTS-125_create_child_document.png', page)
})
test('TESTS-126. Change document owner', async ({ page }) => {
await allure.description('Requirement\nUsers need to change document owner')
test('TESTS-126. Change document author', async ({ page }) => {
await allure.description('Requirement\nUsers need to change document author')
await allure.tms('TESTS-126', 'https://front.hc.engineering/workbench/platform/tracker/TESTS-126')
const changeDocument: NewDocument = {
template: 'HR (HR)',
title: `Change document owner Document-${generateId()}`,
description: `Change document owner Document description-${generateId()}`
title: `Change document author Document-${generateId()}`,
description: `Change document author Document description-${generateId()}`
}
const documentDetails: DocumentDetails = {
type: 'HR',
@ -152,11 +152,11 @@ test.describe('QMS. Documents tests', () => {
await prepareDocumentStep(page, changeDocument)
const documentContentPage = new DocumentContentPage(page)
await test.step('2. Change document owner', async () => {
await test.step('2. Change document author', async () => {
await documentContentPage.checkDocumentTitle(changeDocument.title)
await documentContentPage.checkDocument(documentDetails)
await documentContentPage.executeMoreActions('Change document owner')
await documentContentPage.fillChangeDocumentOwnerPopup('Dirak Kainin')
await documentContentPage.executeMoreActions('Change document author')
await documentContentPage.fillChangeDocumentAuthorPopup('Dirak Kainin')
})
await test.step('3. Check the updated document information', async () => {
@ -681,7 +681,7 @@ test.describe('QMS. Documents tests', () => {
})
})
test('TESTS-155. Change document owner. QARA user changes owner from one user to another', async ({
test('TESTS-155. Change document author. QARA user changes owner from one user to another', async ({
page,
browser
}) => {
@ -691,8 +691,8 @@ test.describe('QMS. Documents tests', () => {
const newDocumentOwner = 'Dirak Kainin'
const changeQaraDocument: NewDocument = {
template: 'HR (HR)',
title: `Change document owner by QARA user Document-${generateId()}`,
description: `Change document owner by QARA user Document description-${generateId()}`
title: `Change document author by QARA user Document-${generateId()}`,
description: `Change document author by QARA user Document description-${generateId()}`
}
const documentDetails: DocumentDetails = {
type: 'HR',
@ -720,8 +720,8 @@ test.describe('QMS. Documents tests', () => {
const documentsPageQara = new DocumentsPage(qaraManagerPage)
await documentsPageQara.openDocument(changeQaraDocument.title)
await documentContentPageQara.executeMoreActions('Change document owner')
await documentContentPageQara.fillChangeDocumentOwnerPopupByQaraManager(newDocumentOwner)
await documentContentPageQara.executeMoreActions('Change document author')
await documentContentPageQara.fillChangeDocumentAuthorPopupByQaraManager(newDocumentOwner)
})
await test.step('4. As QARA manager Check the updated document information', async () => {

View File

@ -14,10 +14,10 @@ export class DocumentContentPage extends DocumentCommonPage {
readonly textCategory: Locator
readonly textVersion: Locator
readonly textStatus: Locator
readonly textOwner: Locator
readonly textAuthor: Locator
readonly buttonSelectNewOwner: Locator
readonly buttonSelectNewOwnerChange: Locator
readonly textCreator: Locator
readonly buttonSelectNewAuthor: Locator
readonly buttonSelectNewAuthorChange: Locator
readonly buttonSendForReview: Locator
readonly buttonSendForApproval: Locator
readonly buttonAddMembers: Locator
@ -41,7 +41,7 @@ export class DocumentContentPage extends DocumentCommonPage {
readonly buttonDocument: Locator
readonly buttonDocumentApprovals: Locator
readonly textPageHeader: Locator
readonly buttonSelectNewOwnerChangeByQaraManager: Locator
readonly buttonSelectNewAuthorChangeByQaraManager: Locator
readonly textId: Locator
readonly contentLocator: Locator
readonly addSpaceButton: Locator
@ -113,10 +113,10 @@ export class DocumentContentPage extends DocumentCommonPage {
this.textCategory = page.locator('div.flex:has(div.label:text("Category")) div.field')
this.textVersion = page.locator('div.flex:has(div.label:text("Version")) div.field')
this.textStatus = page.locator('div.flex:has(div.label:text("Status")) div.field')
this.textOwner = page.locator('div.flex:has(div.label:text("Owner")) div.field')
this.textAuthor = page.locator('div.flex:has(div.label:text("Author")) div.field')
this.buttonSelectNewOwner = page.locator('div.popup button.small')
this.buttonSelectNewOwnerChange = page.locator('div.popup button.dangerous')
this.textCreator = page.locator('div.flex:has(div.label:text("Creator")) div.field')
this.buttonSelectNewAuthor = page.locator('div.popup button.small')
this.buttonSelectNewAuthorChange = page.locator('div.popup button.dangerous')
this.buttonSendForReview = page.locator('div.hulyHeader-buttonsGroup.extra button[type="button"] > span', {
hasText: 'Send for review'
})
@ -152,7 +152,7 @@ export class DocumentContentPage extends DocumentCommonPage {
this.buttonDocumentInformation = page.locator('button[id$="info"]')
this.buttonDocumentApprovals = page.locator('button[id$="approvals"]')
this.textPageHeader = page.locator('div.hulyNavPanel-header')
this.buttonSelectNewOwnerChangeByQaraManager = page.locator('div.popup button[type="submit"]')
this.buttonSelectNewAuthorChangeByQaraManager = page.locator('div.popup button[type="submit"]')
this.textId = page.locator('div.flex:has(div.label:text("ID")) div.field')
this.contentLocator = page.locator('div.textInput div.tiptap')
this.addSpaceButton = page.locator('#tree-orgspaces')
@ -707,20 +707,20 @@ export class DocumentContentPage extends DocumentCommonPage {
await expect(this.textStatus).toHaveText(data.status)
}
if (data.owner != null) {
await expect(this.textOwner).toHaveText(data.owner)
await expect(this.textAuthor).toHaveText(data.owner)
}
if (data.author != null) {
await expect(this.textAuthor).toHaveText(data.author)
await expect(this.textCreator).toHaveText(data.author)
}
if (data.id != null) {
await expect(this.textId).toHaveText(data.id)
}
}
async fillChangeDocumentOwnerPopup (newOwner: string): Promise<void> {
await this.buttonSelectNewOwner.click()
await this.selectListItemWithSearch(this.page, newOwner)
await this.buttonSelectNewOwnerChange.click()
async fillChangeDocumentAuthorPopup (newAuthor: string): Promise<void> {
await this.buttonSelectNewAuthor.click()
await this.selectListItemWithSearch(this.page, newAuthor)
await this.buttonSelectNewAuthorChange.click()
}
async fillSelectReviewersForm (reviewers: Array<string>): Promise<void> {
@ -858,9 +858,9 @@ export class DocumentContentPage extends DocumentCommonPage {
await this.buttonDocumentApprovals.click({ position: { x: 1, y: 1 }, force: true })
}
async fillChangeDocumentOwnerPopupByQaraManager (newOwner: string): Promise<void> {
await this.buttonSelectNewOwner.click()
async fillChangeDocumentAuthorPopupByQaraManager (newOwner: string): Promise<void> {
await this.buttonSelectNewAuthor.click()
await this.selectListItemWithSearch(this.page, newOwner)
await this.buttonSelectNewOwnerChangeByQaraManager.click()
await this.buttonSelectNewAuthorChangeByQaraManager.click()
}
}

View File

@ -84,14 +84,6 @@ function updateMeta (doc: ControlledDocument, txFactory: TxFactory): Tx[] {
]
}
function updateAuthor (doc: ControlledDocument, txFactory: TxFactory): Tx[] {
return [
txFactory.createTxUpdateDoc(doc._class, doc.space, doc._id, {
author: doc.owner
})
]
}
// TODO: Find a way to avoid duplicate logic and reuse createTrainingRequest() from `training-resources`
async function createDocumentTrainingRequest (doc: ControlledDocument, control: TriggerControl): Promise<Tx[]> {
if (!control.hierarchy.hasMixin(doc, documents.mixin.DocumentTraining)) {
@ -281,7 +273,6 @@ export async function OnDocHasBecomeEffective (
const olderEffective = await getDocsOlderThanDoc(doc, control, [DocumentState.Effective])
result.push(
...updateAuthor(doc, control.txFactory),
...archiveDocs(olderEffective, control.txFactory),
...updateMeta(doc, control.txFactory),
...updateTemplate(doc, olderEffective, control),