From f7391c0c44236b4e543d1c0b2ff7004f5107d58c Mon Sep 17 00:00:00 2001 From: Denis Bykhov Date: Sun, 28 Jun 2026 03:42:19 +0500 Subject: [PATCH] Todo required fields Signed-off-by: Denis Bykhov --- models/process/src/index.ts | 3 +++ .../src/components/settings/ToDoEditor.svelte | 16 +++++++++++ plugins/process-resources/src/middleware.ts | 25 +++++++++++++++-- plugins/process/src/index.ts | 1 + .../process-resources/src/functions.ts | 27 ++++++++++++++++--- 5 files changed, 67 insertions(+), 5 deletions(-) diff --git a/models/process/src/index.ts b/models/process/src/index.ts index ade16ff60b4..4017d9373e4 100644 --- a/models/process/src/index.ts +++ b/models/process/src/index.ts @@ -216,6 +216,9 @@ export class TProcessToDo extends TToDo implements ProcessToDo { @Prop(TypeBoolean(), process.string.Rollback) withRollback!: boolean + + @Prop(TypeBoolean(), process.string.AskRequired) + askRequired?: boolean } @Model(process.class.ApproveRequest, process.class.ProcessToDo) diff --git a/plugins/process-resources/src/components/settings/ToDoEditor.svelte b/plugins/process-resources/src/components/settings/ToDoEditor.svelte index 47d22b50da7..8fdb3712a66 100644 --- a/plugins/process-resources/src/components/settings/ToDoEditor.svelte +++ b/plugins/process-resources/src/components/settings/ToDoEditor.svelte @@ -64,6 +64,16 @@ step.params = params dispatch('change', step) } + let askRequired = params.askRequired ?? false + $: askRequired = params.askRequired ?? false + + function changeAskRequired (e: CustomEvent): void { + if (e.detail !== undefined) { + params.askRequired = e.detail + step.params = params + dispatch('change', step) + } + } @@ -87,6 +97,12 @@ +
+
+
+ +
diff --git a/plugins/process-resources/src/middleware.ts b/plugins/process-resources/src/middleware.ts index 5a22fe55d9f..6fcf26ee64d 100644 --- a/plugins/process-resources/src/middleware.ts +++ b/plugins/process-resources/src/middleware.ts @@ -28,8 +28,9 @@ import core, { type TxResult, type TxUpdateDoc } from '@hcengineering/core' +import { translate } from '@hcengineering/platform' import { BasePresentationMiddleware, type PresentationMiddleware } from '@hcengineering/presentation' -import { type ApproveRequest, ExecutionStatus, isUpdateTx, type ProcessToDo } from '@hcengineering/process' +import { ExecutionStatus, isUpdateTx, type ApproveRequest, type ProcessToDo } from '@hcengineering/process' import process from './plugin' import { createExecution, getNextStateUserInput, pickTransition, requestResult } from './utils' @@ -237,7 +238,27 @@ export class ProcessMiddleware extends BasePresentationMiddleware implements Pre }) if (execution === undefined) return - const context = await requestResult(execution, todo.results, execution.context) + let results = todo.results ?? [] + if (results.length > 0) { + results = await Promise.all( + results.map(async (r) => { + if (r.key !== undefined) { + const h = this.client.getHierarchy() + const _process = this.client.getModel().findObject(execution.process) + if (_process !== undefined) { + const attr = h.findAttribute(_process.masterTag, r.key) + if (attr?.label !== undefined) { + const name = await translate(attr.label, {}) + return { ...r, name } + } + } + } + return r + }) + ) + } + + const context = await requestResult(execution, results, execution.context) const transitions = this.client.getModel().findAllSync(process.class.Transition, { process: execution.process, diff --git a/plugins/process/src/index.ts b/plugins/process/src/index.ts index 370a96b17be..8a8446cccc4 100644 --- a/plugins/process/src/index.ts +++ b/plugins/process/src/index.ts @@ -140,6 +140,7 @@ export interface ProcessToDo extends ToDo { results?: UserResult[] field?: string + askRequired?: boolean } export interface ApproveRequest extends ProcessToDo { diff --git a/server-plugins/process-resources/src/functions.ts b/server-plugins/process-resources/src/functions.ts index 0a7f2c29705..25b20cadaa4 100644 --- a/server-plugins/process-resources/src/functions.ts +++ b/server-plugins/process-resources/src/functions.ts @@ -45,7 +45,8 @@ import process, { Process, processError, ProcessToDo, - UserResult + UserResult, + ContextId } from '@hcengineering/process' import { ExecuteResult, ProcessControl, SuccessExecutionContext } from '@hcengineering/server-process' import { isEmptyMarkup } from '@hcengineering/text-core' @@ -756,6 +757,25 @@ export async function CreateToDo ( const _process = control.client.getModel().findObject(execution.process) if (_process === undefined) return { txes: [], rollback: [], context: null } const field = resolveAttributeId(_process, (params as any).field) + const todoResults = results ?? [] + if (params.askRequired === true) { + const hierarchy = control.client.getHierarchy() + const classId = _process.masterTag + const allAttributes = Array.from(hierarchy.getAllAttributes(classId, core.class.Doc).values()) + + for (const attr of allAttributes) { + if (attr.hidden === true || attr.required !== true) continue + if (todoResults.some((r) => r.key === attr.name)) continue + + todoResults.push({ + _id: generateId() as any as ContextId, + name: attr.name, + key: attr.name, + type: attr.type + }) + } + } + const tx = control.client.txFactory.createTxCreateDoc( process.class.ProcessToDo, time.space.ToDos, @@ -774,8 +794,9 @@ export async function CreateToDo ( doneOn: null, rank: '', withRollback: params.withRollback ?? false, - results, - field + results: todoResults, + field, + askRequired: params.askRequired }, id )