From bf8bdaf08a88f78d7af9c8b9be6408f320811040 Mon Sep 17 00:00:00 2001 From: Alexey Zinoviev Date: Wed, 24 Jul 2024 20:52:41 +0400 Subject: [PATCH 1/3] ezqms-1069: fix request model Signed-off-by: Alexey Zinoviev Signed-off-by: Alexey Zinoviev --- models/all/src/migration.ts | 2 + models/request/src/index.ts | 15 +-- models/request/src/migration.ts | 99 +++++++++++++++++++ .../document/DocumentSignatories.svelte | 14 ++- .../right-panel/DocumentApprovalItem.svelte | 16 ++- .../src/stores/editors/document/editor.ts | 8 +- .../src/utils.ts | 32 ++---- .../src/components/RequestActions.svelte | 8 +- .../src/components/RequestDetail.svelte | 21 ++-- plugins/request/src/index.ts | 8 +- 10 files changed, 153 insertions(+), 70 deletions(-) create mode 100644 models/request/src/migration.ts diff --git a/models/all/src/migration.ts b/models/all/src/migration.ts index 55bf9ca300b..a2b530d78e1 100644 --- a/models/all/src/migration.ts +++ b/models/all/src/migration.ts @@ -48,6 +48,7 @@ import { questionsOperation } from '@hcengineering/model-questions' import { trainingOperation } from '@hcengineering/model-training' import { documentsOperation } from '@hcengineering/model-controlled-documents' import { productsOperation } from '@hcengineering/model-products' +import { requestOperation } from '@hcengineering/model-request' export const migrateOperations: [string, MigrateOperation][] = [ ['core', coreOperation], @@ -71,6 +72,7 @@ export const migrateOperations: [string, MigrateOperation][] = [ ['documents', documentsOperation], ['questions', questionsOperation], ['training', trainingOperation], + ['request', requestOperation], ['products', productsOperation], ['board', boardOperation], ['hr', hrOperation], diff --git a/models/request/src/index.ts b/models/request/src/index.ts index 8570a747bc8..0f695343afc 100644 --- a/models/request/src/index.ts +++ b/models/request/src/index.ts @@ -14,7 +14,7 @@ // import activity from '@hcengineering/activity' -import type { PersonAccount } from '@hcengineering/contact' +import type { Person } from '@hcengineering/contact' import contact from '@hcengineering/contact' import { type Timestamp, type Domain, type Ref, type Tx } from '@hcengineering/core' import { @@ -43,6 +43,7 @@ import { import { type AnyComponent } from '@hcengineering/ui/src/types' import request from './plugin' +export { requestOperation } from './migration' export { requestId } from '@hcengineering/request' export { default } from './plugin' @@ -51,13 +52,13 @@ export const DOMAIN_REQUEST = 'request' as Domain @Model(request.class.Request, core.class.AttachedDoc, DOMAIN_REQUEST) @UX(request.string.Request, request.icon.Requests) export class TRequest extends TAttachedDoc implements Request { - @Prop(ArrOf(TypeRef(contact.class.PersonAccount)), request.string.Requested) + @Prop(ArrOf(TypeRef(contact.class.Person)), request.string.Requested) // @Index(IndexKind.Indexed) - requested!: Ref[] + requested!: Ref[] - @Prop(ArrOf(TypeRef(contact.class.PersonAccount)), request.string.Approved) + @Prop(ArrOf(TypeRef(contact.class.Person)), request.string.Approved) @ReadOnly() - approved!: Ref[] + approved!: Ref[] approvedDates?: Timestamp[] @@ -70,9 +71,9 @@ export class TRequest extends TAttachedDoc implements Request { tx!: Tx rejectedTx?: Tx - @Prop(TypeRef(contact.class.PersonAccount), request.string.Rejected) + @Prop(TypeRef(contact.class.Person), request.string.Rejected) @ReadOnly() - rejected?: Ref + rejected?: Ref @Prop(Collection(chunter.class.ChatMessage), chunter.string.Comments) comments?: number diff --git a/models/request/src/migration.ts b/models/request/src/migration.ts new file mode 100644 index 00000000000..4a727132e39 --- /dev/null +++ b/models/request/src/migration.ts @@ -0,0 +1,99 @@ +// +// Copyright © 2024 Hardcore Engineering Inc. +// +// Licensed under the Eclipse Public License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. You may +// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// +// See the License for the specific language governing permissions and +// limitations under the License. +// +import core, { DOMAIN_TX, type Ref, type TxCreateDoc } from '@hcengineering/core' +import request, { requestId, type Request } from '@hcengineering/request' +import { + tryMigrate, + type MigrateOperation, + type MigrationClient, + type MigrationUpgradeClient, + type ModelLogger +} from '@hcengineering/model' +import contact, { type Person, type PersonAccount } from '@hcengineering/contact' + +import { DOMAIN_REQUEST } from '.' + +async function migrateRequestPersonAccounts (client: MigrationClient): Promise { + const descendants = client.hierarchy.getDescendants(request.class.Request) + const requests = await client.find(DOMAIN_REQUEST, { + _class: { $in: descendants } + }) + const personAccountsCreateTxes = await client.find(DOMAIN_TX, { + _class: core.class.TxCreateDoc, + objectClass: contact.class.PersonAccount + }) + const personAccountToPersonMap = personAccountsCreateTxes.reduce, Ref>>( + (map, tx) => { + const ctx = tx as TxCreateDoc + + map[ctx.objectId] = ctx.attributes.person + + return map + }, + {} + ) + + for (const request of requests) { + const newRequestedPersons = request.requested + .map((paId) => personAccountToPersonMap[paId as unknown as Ref]) + .filter((p) => p != null) + const newApprovedPersons = request.approved + .map((paId) => personAccountToPersonMap[paId as unknown as Ref]) + .filter((p) => p != null) + const newRejectedPerson = + request.rejected != null ? personAccountToPersonMap[request.rejected as unknown as Ref] : undefined + + if (newRequestedPersons.length > 0) { + await client.update( + DOMAIN_REQUEST, + { + _id: request._id + }, + { + $set: { + requested: newRequestedPersons, + approved: newApprovedPersons + } + } + ) + } + + if (newRejectedPerson !== undefined) { + await client.update( + DOMAIN_REQUEST, + { + _id: request._id + }, + { + $set: { + rejected: newRejectedPerson + } + } + ) + } + } +} + +export const requestOperation: MigrateOperation = { + async migrate (client: MigrationClient, logger: ModelLogger): Promise { + await tryMigrate(client, requestId, [ + { + state: 'migrateRequestPersonAccounts', + func: migrateRequestPersonAccounts + } + ]) + }, + async upgrade (state: Map>, client: () => Promise): Promise {} +} diff --git a/plugins/controlled-documents-resources/src/components/document/DocumentSignatories.svelte b/plugins/controlled-documents-resources/src/components/document/DocumentSignatories.svelte index 29ec9d71697..5a398676ac4 100644 --- a/plugins/controlled-documents-resources/src/components/document/DocumentSignatories.svelte +++ b/plugins/controlled-documents-resources/src/components/document/DocumentSignatories.svelte @@ -1,5 +1,5 @@ - if (reviewRequest.approved?.includes(currentAccount)) { + const currentPerson = (getCurrentAccount() as PersonAccount).person + if (reviewRequest.approved?.includes(currentPerson)) { return ControlledDocumentState.Reviewed } } @@ -228,7 +228,7 @@ export const $documentState = $controlledDocument.map((doc) => { }) export const $documentReviewIsActive = combine($reviewRequest, $documentStateForCurrentUser, (reviewReq, state) => { - const me = getCurrentAccount()._id as Ref + const me = (getCurrentAccount() as PersonAccount).person if (reviewReq == null) { return false @@ -244,7 +244,7 @@ export const $documentApprovalIsActive = combine( $approvalRequest, $documentStateForCurrentUser, (doc, approvalReq, state) => { - const me = getCurrentAccount()._id as Ref + const me = (getCurrentAccount() as PersonAccount).person if (approvalReq == null) { return false diff --git a/plugins/controlled-documents-resources/src/utils.ts b/plugins/controlled-documents-resources/src/utils.ts index ef6a6f4917a..e8dea554e3d 100644 --- a/plugins/controlled-documents-resources/src/utils.ts +++ b/plugins/controlled-documents-resources/src/utils.ts @@ -31,7 +31,7 @@ import core, { } from '@hcengineering/core' import { type IntlString, getMetadata, getResource, translate } from '@hcengineering/platform' import presentation, { copyDocumentContent, getClient } from '@hcengineering/presentation' -import contact, { type Employee, type PersonAccount } from '@hcengineering/contact' +import { type Person, type Employee, type PersonAccount } from '@hcengineering/contact' import request, { RequestStatus } from '@hcengineering/request' import textEditor from '@hcengineering/text-editor' import { isEmptyMarkup } from '@hcengineering/text' @@ -313,16 +313,6 @@ export async function sendReviewRequest ( controlledDoc: ControlledDocument, reviewers: Array> ): Promise { - const reviewersAccounts = await client.findAll(contact.class.PersonAccount, { person: { $in: reviewers } }) - - if (reviewersAccounts.length === 0) { - return - } - - if (reviewersAccounts.length < reviewers.length) { - console.warn('Number of user accounts is less than requested for document review request') - } - const approveTx = client.txFactory.createTxUpdateDoc(controlledDoc._class, controlledDoc.space, controlledDoc._id, { controlledState: ControlledDocumentState.Reviewed }) @@ -338,7 +328,7 @@ export async function sendReviewRequest ( controlledDoc._class, documents.class.DocumentReviewRequest, controlledDoc.space, - reviewersAccounts.map((u) => u._id), + reviewers, approveTx, undefined, true @@ -350,16 +340,6 @@ export async function sendApprovalRequest ( controlledDoc: ControlledDocument, approvers: Array> ): Promise { - const approversAccounts = await client.findAll(contact.class.PersonAccount, { person: { $in: approvers } }) - - if (approversAccounts.length === 0) { - return - } - - if (approversAccounts.length < approvers.length) { - console.warn('Number of user accounts is less than requested for document approval request') - } - const approveTx = client.txFactory.createTxUpdateDoc(controlledDoc._class, controlledDoc.space, controlledDoc._id, { controlledState: ControlledDocumentState.Approved }) @@ -379,7 +359,7 @@ export async function sendApprovalRequest ( controlledDoc._class, documents.class.DocumentApprovalRequest, controlledDoc.space, - approversAccounts.map((u) => u._id), + approvers, approveTx, rejectTx, true @@ -392,7 +372,7 @@ async function createRequest ( attachedToClass: Ref>, reqClass: Ref>, space: Ref, - users: Array>, + users: Array>, approveTx: Tx, rejectedTx?: Tx, areAllApprovesRequired = true @@ -429,7 +409,7 @@ export async function completeRequest ( ): Promise { const req = await getActiveRequest(client, reqClass, controlledDoc) - const me = getCurrentAccount()._id as Ref + const me = (getCurrentAccount() as PersonAccount).person if (req == null || !req.requested.includes(me) || req.approved.includes(me)) { return @@ -465,7 +445,7 @@ export async function rejectRequest ( return } - const me = getCurrentAccount()._id as Ref + const me = (getCurrentAccount() as PersonAccount).person await saveComment(rejectionNote, req) diff --git a/plugins/request-resources/src/components/RequestActions.svelte b/plugins/request-resources/src/components/RequestActions.svelte index 7586d2552d9..62bfd80a090 100644 --- a/plugins/request-resources/src/components/RequestActions.svelte +++ b/plugins/request-resources/src/components/RequestActions.svelte @@ -32,14 +32,16 @@ const client = getClient() const me = getCurrentAccount()._id as Ref + const myPerson = (getCurrentAccount() as PersonAccount).person - const approvable = value.requested.filter((a) => a === me).length > value.approved.filter((a) => a === me).length + const approvable = + value.requested.filter((a) => a === myPerson).length > value.approved.filter((a) => a === myPerson).length async function approve () { await saveComment() await client.update(value, { $push: { - approved: me + approved: myPerson } }) } @@ -49,7 +51,7 @@ async function reject () { await saveComment() await client.update(value, { - rejected: me, + rejected: myPerson, status: RequestStatus.Rejected }) } diff --git a/plugins/request-resources/src/components/RequestDetail.svelte b/plugins/request-resources/src/components/RequestDetail.svelte index 6333aaf78ec..97972261648 100644 --- a/plugins/request-resources/src/components/RequestDetail.svelte +++ b/plugins/request-resources/src/components/RequestDetail.svelte @@ -13,29 +13,34 @@ // limitations under the License. -->