From 765ee77dc7651025ca7b99b8c966dc965811aeab Mon Sep 17 00:00:00 2001 From: Denis Bykhov Date: Sat, 11 Oct 2025 00:39:55 +0500 Subject: [PATCH] ToDo complete trigger can respect results Signed-off-by: Denis Bykhov --- packages/presentation/src/utils.ts | 24 ++-- .../criterias/AttributeCriteria.svelte | 4 +- .../criterias/BaseCriteriaEditor.svelte | 4 +- .../criterias/ContextCriteria.svelte | 99 +++++++++++++++++ .../components/criterias/RangeCriteria.svelte | 4 +- .../settings/AddRelationEditor.svelte | 26 ++--- .../settings/CardUpdateEditor.svelte | 4 +- .../settings/FieldChangesEditor.svelte | 4 +- .../settings/ResultCriteriaEditor.svelte | 104 ++++++++++++++++++ .../src/components/settings/TimeEditor.svelte | 20 +--- .../settings/ToDoParamsEditor.svelte | 13 ++- .../transformEditors/FilterEditor.svelte | 4 +- plugins/process-resources/src/utils.ts | 18 ++- .../process-resources/src/functions.ts | 15 ++- 14 files changed, 283 insertions(+), 60 deletions(-) create mode 100644 plugins/process-resources/src/components/criterias/ContextCriteria.svelte create mode 100644 plugins/process-resources/src/components/settings/ResultCriteriaEditor.svelte diff --git a/packages/presentation/src/utils.ts b/packages/presentation/src/utils.ts index f4719b9d68a..ff525b327dc 100644 --- a/packages/presentation/src/utils.ts +++ b/packages/presentation/src/utils.ts @@ -18,6 +18,7 @@ import { Analytics } from '@hcengineering/analytics' import core, { type Account, AccountRole, + type AnyAttribute, type ArrOf, type AttachedDoc, type Class, @@ -737,13 +738,8 @@ export function getAttrEditor (type: Type, hierarchy: Hierarchy): AnyCompon return editorMixin?.inlineEditor } -export function findAttributeEditor ( - client: Client, - _class: Ref>, - key: KeyedAttribute | string -): AnyComponent | undefined { +export function findAttributeEditorByAttribute (client: Client, attribute: AnyAttribute): AnyComponent | undefined { const hierarchy = client.getHierarchy() - const attribute = typeof key === 'string' ? hierarchy.findAttribute(_class, key) : key.attr if (attribute === undefined) return if (attribute.type._class === core.class.TypeAny) { @@ -779,16 +775,22 @@ export function findAttributeEditor ( const editorMixin = hierarchy.classHierarchyMixin(presenterClass.attrClass, mixin) if (editorMixin?.inlineEditor === undefined) { - // if (presenterClass.category === 'array') { - // // NOTE: Don't show error for array attributes for compatibility with previous implementation - // } else { - console.error(getAttributeEditorNotFoundError(_class, key)) - // } return } return editorMixin.inlineEditor } +export function findAttributeEditor ( + client: Client, + _class: Ref>, + key: KeyedAttribute | string +): AnyComponent | undefined { + const hierarchy = client.getHierarchy() + const attribute = typeof key === 'string' ? hierarchy.findAttribute(_class, key) : key.attr + if (attribute === undefined) return + return findAttributeEditorByAttribute(client, attribute) +} + export async function getAttributeEditor ( client: Client, _class: Ref>, diff --git a/plugins/process-resources/src/components/criterias/AttributeCriteria.svelte b/plugins/process-resources/src/components/criterias/AttributeCriteria.svelte index 59e7f7a3549..ee27f1a9d22 100644 --- a/plugins/process-resources/src/components/criterias/AttributeCriteria.svelte +++ b/plugins/process-resources/src/components/criterias/AttributeCriteria.svelte @@ -19,7 +19,7 @@ import { Process } from '@hcengineering/process' import { Component, Label, tooltip } from '@hcengineering/ui' import { createEventDispatcher } from 'svelte' - import { getCirteriaEditor, getContext } from '../../utils' + import { getCriteriaEditor, getContext } from '../../utils' export let _class: Ref> export let readonly: boolean @@ -34,7 +34,7 @@ $: attribute = hierarchy.getAttribute(_class, key) $: presenterClass = getAttributePresenterClass(hierarchy, attribute.type) - $: updateCriteria = getCirteriaEditor(presenterClass.attrClass, presenterClass.category) + $: updateCriteria = getCriteriaEditor(presenterClass.attrClass, presenterClass.category) $: editor = updateCriteria?.editor $: value = params[key] diff --git a/plugins/process-resources/src/components/criterias/BaseCriteriaEditor.svelte b/plugins/process-resources/src/components/criterias/BaseCriteriaEditor.svelte index 72f75fad990..635782812db 100644 --- a/plugins/process-resources/src/components/criterias/BaseCriteriaEditor.svelte +++ b/plugins/process-resources/src/components/criterias/BaseCriteriaEditor.svelte @@ -15,7 +15,7 @@
diff --git a/plugins/process-resources/src/components/criterias/ContextCriteria.svelte b/plugins/process-resources/src/components/criterias/ContextCriteria.svelte new file mode 100644 index 00000000000..6c783522cbd --- /dev/null +++ b/plugins/process-resources/src/components/criterias/ContextCriteria.svelte @@ -0,0 +1,99 @@ + + + + +{#if editor} + + +{/if} diff --git a/plugins/process-resources/src/components/criterias/RangeCriteria.svelte b/plugins/process-resources/src/components/criterias/RangeCriteria.svelte index 1f5932c2ed0..49bff10f702 100644 --- a/plugins/process-resources/src/components/criterias/RangeCriteria.svelte +++ b/plugins/process-resources/src/components/criterias/RangeCriteria.svelte @@ -15,7 +15,7 @@
diff --git a/plugins/process-resources/src/components/settings/AddRelationEditor.svelte b/plugins/process-resources/src/components/settings/AddRelationEditor.svelte index bd089e02aca..4afa96a8e06 100644 --- a/plugins/process-resources/src/components/settings/AddRelationEditor.svelte +++ b/plugins/process-resources/src/components/settings/AddRelationEditor.svelte @@ -13,12 +13,12 @@ // limitations under the License. --> diff --git a/plugins/process-resources/src/components/settings/CardUpdateEditor.svelte b/plugins/process-resources/src/components/settings/CardUpdateEditor.svelte index f5da2bfc6a7..c8f314a3b7e 100644 --- a/plugins/process-resources/src/components/settings/CardUpdateEditor.svelte +++ b/plugins/process-resources/src/components/settings/CardUpdateEditor.svelte @@ -20,7 +20,7 @@ import { Process } from '@hcengineering/process' import { Button, eventToHTMLElement, SelectPopup, showPopup } from '@hcengineering/ui' import { createEventDispatcher } from 'svelte' - import { getCirteriaEditor } from '../../utils' + import { getCriteriaEditor } from '../../utils' import CriteriasEditor from '../criterias/CriteriasEditor.svelte' export let readonly: boolean @@ -46,7 +46,7 @@ if (attr.hidden === true) continue if (ignoreKeys.includes(key)) continue const presenterClass = getAttributePresenterClass(hierarchy, attr.type) - const updateCriteria = getCirteriaEditor(presenterClass.attrClass, presenterClass.category) + const updateCriteria = getCriteriaEditor(presenterClass.attrClass, presenterClass.category) const editor = updateCriteria?.editor if (editor == null) continue res.push(attr) diff --git a/plugins/process-resources/src/components/settings/FieldChangesEditor.svelte b/plugins/process-resources/src/components/settings/FieldChangesEditor.svelte index c734c34c8c3..76b5331f01b 100644 --- a/plugins/process-resources/src/components/settings/FieldChangesEditor.svelte +++ b/plugins/process-resources/src/components/settings/FieldChangesEditor.svelte @@ -21,7 +21,7 @@ import { Button, eventToHTMLElement, SelectPopup, showPopup } from '@hcengineering/ui' import view from '@hcengineering/view' import { createEventDispatcher } from 'svelte' - import { getCirteriaEditor } from '../../utils' + import { getCriteriaEditor } from '../../utils' import CriteriasEditor from '../criterias/CriteriasEditor.svelte' export let readonly: boolean @@ -47,7 +47,7 @@ if (attr.hidden === true) continue if (ignoreKeys.includes(key)) continue const presenterClass = getAttributePresenterClass(hierarchy, attr.type) - const updateCriteria = getCirteriaEditor(presenterClass.attrClass, presenterClass.category) + const updateCriteria = getCriteriaEditor(presenterClass.attrClass, presenterClass.category) const editor = updateCriteria?.editor if (editor == null) continue res.push(attr) diff --git a/plugins/process-resources/src/components/settings/ResultCriteriaEditor.svelte b/plugins/process-resources/src/components/settings/ResultCriteriaEditor.svelte new file mode 100644 index 00000000000..43115fad227 --- /dev/null +++ b/plugins/process-resources/src/components/settings/ResultCriteriaEditor.svelte @@ -0,0 +1,104 @@ + + + + +{#each keys as key} + { + change(e, key) + }} + on:delete={() => { + remove(key) + }} + /> +{/each} +{#if !readonly && availableResults.length > 0} +
+
+{/if} diff --git a/plugins/process-resources/src/components/settings/TimeEditor.svelte b/plugins/process-resources/src/components/settings/TimeEditor.svelte index da6f829ab44..b0d7ac7180a 100644 --- a/plugins/process-resources/src/components/settings/TimeEditor.svelte +++ b/plugins/process-resources/src/components/settings/TimeEditor.svelte @@ -21,7 +21,7 @@ import { AnySvelteComponent } from '@hcengineering/ui' import view from '@hcengineering/view' import plugin from '../../plugin' - import { getContext } from '../../utils' + import { getContext, getMockAttribute } from '../../utils' import ProcessAttribute from '../ProcessAttribute.svelte' import { createEventDispatcher } from 'svelte' import { Analytics } from '@hcengineering/analytics' @@ -34,20 +34,10 @@ const h = client.getHierarchy() $: context = getContext(client, process, core.class.TypeDate, 'attribute') - const attribute: AnyAttribute = { - attributeOf: process.masterTag, - name: '', - type: { - label: core.string.Date, - _class: core.class.TypeDate - }, - _id: generateId(), - space: core.space.Model, - modifiedOn: 0, - modifiedBy: core.account.System, - _class: core.class.Attribute, - label: plugin.string.WaitUntil - } + const attribute: AnyAttribute = getMockAttribute(process.masterTag, plugin.string.WaitUntil, { + label: core.string.Date, + _class: core.class.TypeDate + }) let editor: AnySvelteComponent | undefined diff --git a/plugins/process-resources/src/components/settings/ToDoParamsEditor.svelte b/plugins/process-resources/src/components/settings/ToDoParamsEditor.svelte index 61e294dae76..b6d6b27df14 100644 --- a/plugins/process-resources/src/components/settings/ToDoParamsEditor.svelte +++ b/plugins/process-resources/src/components/settings/ToDoParamsEditor.svelte @@ -14,11 +14,12 @@ --> @@ -37,4 +45,7 @@
diff --git a/plugins/process-resources/src/components/transformEditors/FilterEditor.svelte b/plugins/process-resources/src/components/transformEditors/FilterEditor.svelte index def447ffeff..8c4b5dbc05e 100644 --- a/plugins/process-resources/src/components/transformEditors/FilterEditor.svelte +++ b/plugins/process-resources/src/components/transformEditors/FilterEditor.svelte @@ -18,7 +18,7 @@ import { Process, ProcessFunction } from '@hcengineering/process' import { Button, SelectPopup, eventToHTMLElement, showPopup } from '@hcengineering/ui' import { createEventDispatcher } from 'svelte' - import { getCirteriaEditor } from '../../utils' + import { getCriteriaEditor } from '../../utils' import CriteriasEditor from '../criterias/CriteriasEditor.svelte' export let func: ProcessFunction @@ -45,7 +45,7 @@ if (key === '_id' || key === '_class') continue if (attr.hidden === true) continue const presenterClass = getAttributePresenterClass(hierarchy, attr.type) - const updateCriteria = getCirteriaEditor(presenterClass.attrClass, presenterClass.category) + const updateCriteria = getCriteriaEditor(presenterClass.attrClass, presenterClass.category) const editor = updateCriteria?.editor if (editor == null) continue res.push(attr) diff --git a/plugins/process-resources/src/utils.ts b/plugins/process-resources/src/utils.ts index 195eae156e4..6c990061d82 100644 --- a/plugins/process-resources/src/utils.ts +++ b/plugins/process-resources/src/utils.ts @@ -28,7 +28,7 @@ import core, { type TxOperations, type Type } from '@hcengineering/core' -import { getResource, PlatformError, Severity, Status } from '@hcengineering/platform' +import { getResource, type IntlString, PlatformError, Severity, Status } from '@hcengineering/platform' import { getClient } from '@hcengineering/presentation' import { type Context, @@ -656,7 +656,7 @@ export async function subProcessesDoneCheck ( return res === undefined } -export function getCirteriaEditor ( +export function getCriteriaEditor ( of: Ref>, category: AttributeCategory ): UpdateCriteriaComponent | undefined { @@ -673,3 +673,17 @@ export function getCirteriaEditor ( })[0] return res } + +export function getMockAttribute (_class: Ref>, label: IntlString, type: Type): AnyAttribute { + return { + attributeOf: _class, + name: '', + _id: generateId(), + space: core.space.Model, + modifiedOn: 0, + modifiedBy: core.account.System, + _class: core.class.Attribute, + type, + label + } +} diff --git a/server-plugins/process-resources/src/functions.ts b/server-plugins/process-resources/src/functions.ts index 67b792b4eae..c3d582563bc 100644 --- a/server-plugins/process-resources/src/functions.ts +++ b/server-plugins/process-resources/src/functions.ts @@ -19,6 +19,7 @@ import core, { checkMixinKey, Data, Doc, + findProperty, generateId, getObjectValue, matchQuery, @@ -43,6 +44,15 @@ import process, { import { ExecuteResult, ProcessControl, SuccessExecutionContext } from '@hcengineering/server-process' import time, { ToDoPriority } from '@hcengineering/time' +function checkResult (execution: Execution, results: Record | undefined): boolean { + if (results === undefined) return true + for (const [key, value] of Object.entries(results)) { + const res = findProperty([execution.context as any], key, value) + if (res.length === 0) return false + } + return true +} + export async function CheckToDoDone ( control: ProcessControl, execution: Execution, @@ -51,11 +61,12 @@ export async function CheckToDoDone ( ): Promise { if (params._id === undefined) return false if (context.todo !== undefined) { - return context.todo._id === params._id + const matched = context.todo._id === params._id + return matched && checkResult(execution, params.result) } else { const todo = await control.client.findOne(process.class.ProcessToDo, { _id: params._id }) if (todo === undefined) return false - return todo.doneOn !== null + return todo.doneOn !== null && checkResult(execution, params.result) } }