mirror of
https://github.com/hcengineering/platform.git
synced 2026-09-22 17:45:02 +02:00
Fix processes triggers (On card update, on subprocesses done) (#9841)
Signed-off-by: Denis Bykhov <bykhov.denis@gmail.com>
This commit is contained in:
@@ -1118,6 +1118,7 @@ export function createModel (builder: Builder): void {
|
||||
{
|
||||
label: process.string.OnSubProcessesDone,
|
||||
icon: process.icon.WaitSubprocesses,
|
||||
checkFunction: process.triggerCheck.SubProcessesDoneCheck,
|
||||
requiredParams: [],
|
||||
init: false,
|
||||
auto: true
|
||||
|
||||
@@ -16,7 +16,7 @@ import core, { type Doc } from '@hcengineering/core'
|
||||
import { Mixin, type Builder } from '@hcengineering/model'
|
||||
import { TMethod, TProcessFunction, TTrigger } from '@hcengineering/model-process'
|
||||
import type { Resource } from '@hcengineering/platform'
|
||||
import process, { ExecutionStatus, type CheckFunc } from '@hcengineering/process'
|
||||
import process, { ExecutionStatus } from '@hcengineering/process'
|
||||
import serverCore from '@hcengineering/server-core'
|
||||
import serverProcess, {
|
||||
type RollbackFunc,
|
||||
@@ -24,7 +24,8 @@ import serverProcess, {
|
||||
type FuncImpl,
|
||||
type MethodImpl,
|
||||
type TransformFunc,
|
||||
type TriggerImpl
|
||||
type TriggerImpl,
|
||||
type CheckFunc
|
||||
} from '@hcengineering/server-process'
|
||||
|
||||
export { serverProcessId } from '@hcengineering/server-process'
|
||||
@@ -68,7 +69,8 @@ export function createModel (builder: Builder): void {
|
||||
})
|
||||
|
||||
builder.mixin(process.trigger.OnSubProcessesDone, process.class.Trigger, serverProcess.mixin.TriggerImpl, {
|
||||
preventRollback: true
|
||||
preventRollback: true,
|
||||
serverCheckFunc: serverProcess.func.CheckSubProcessesDone
|
||||
})
|
||||
|
||||
builder.mixin(process.method.RunSubProcess, process.class.Method, serverProcess.mixin.MethodImpl, {
|
||||
|
||||
@@ -78,6 +78,10 @@
|
||||
items={triggersItems}
|
||||
bind:selected={selectedTrigger}
|
||||
label={plugin.string.Trigger}
|
||||
on:change={() => {
|
||||
params = {}
|
||||
result = null
|
||||
}}
|
||||
justify={'left'}
|
||||
width={'100%'}
|
||||
kind={'no-border'}
|
||||
|
||||
@@ -80,7 +80,8 @@ import {
|
||||
showDoneQuery,
|
||||
timeTransitionCheck,
|
||||
todoTranstionCheck,
|
||||
updateCardTranstionCheck
|
||||
updateCardTranstionCheck,
|
||||
subProcessesDoneCheck
|
||||
} from './utils'
|
||||
|
||||
export * from './query'
|
||||
@@ -160,6 +161,7 @@ export default async (): Promise<Resources> => ({
|
||||
},
|
||||
triggerCheck: {
|
||||
UpdateCheck: updateCardTranstionCheck,
|
||||
SubProcessesDoneCheck: subProcessesDoneCheck,
|
||||
ToDo: todoTranstionCheck,
|
||||
Time: timeTransitionCheck
|
||||
},
|
||||
|
||||
@@ -88,13 +88,7 @@ export class ProcessMiddleware extends BasePresentationMiddleware implements Pre
|
||||
from: execution.currentState,
|
||||
trigger: process.trigger.OnCardUpdate
|
||||
})
|
||||
const transition = await pickTransition(
|
||||
this.client.getModel(),
|
||||
this.client.getHierarchy(),
|
||||
execution,
|
||||
transitions,
|
||||
updated
|
||||
)
|
||||
const transition = await pickTransition(this.client, execution, transitions, updated)
|
||||
if (transition === undefined) return
|
||||
const context = await getNextStateUserInput(execution, transition, execution.context)
|
||||
const txop = new TxOperations(this.client, getCurrentAccount().primarySocialId)
|
||||
@@ -158,13 +152,7 @@ export class ProcessMiddleware extends BasePresentationMiddleware implements Pre
|
||||
from: execution.currentState,
|
||||
trigger: process.trigger.OnToDoClose
|
||||
})
|
||||
const transition = await pickTransition(
|
||||
this.client.getModel(),
|
||||
this.client.getHierarchy(),
|
||||
execution,
|
||||
transitions,
|
||||
todo
|
||||
)
|
||||
const transition = await pickTransition(this.client, execution, transitions, todo)
|
||||
if (transition === undefined) return
|
||||
const context = await getNextStateUserInput(execution, transition, execution.context)
|
||||
const txop = new TxOperations(this.client, getCurrentAccount().primarySocialId)
|
||||
|
||||
@@ -149,7 +149,7 @@ export function parseValue (modes: Mode[], value: any): [any, Mode] {
|
||||
if (mode.parse !== undefined) {
|
||||
return [mode.parse(obj2[key2]), mode]
|
||||
}
|
||||
return [obj2[key2], mode]
|
||||
return [mode.withoutEditor === true ? undefined : obj2[key2], mode]
|
||||
}
|
||||
obj1 = obj1[key1]
|
||||
obj2 = obj2[key2]
|
||||
@@ -168,10 +168,10 @@ export function buildResult (mode: Mode, value: any): any {
|
||||
const key = Object.keys(q)[0]
|
||||
const v: any = (q as any)[key]
|
||||
if (typeof v !== 'object') {
|
||||
if (typeof value === 'string') {
|
||||
if (typeof value === 'string' && typeof v === 'string') {
|
||||
res[key] = v.replace('$val', value)
|
||||
} else {
|
||||
res[key] = value
|
||||
res[key] = mode.withoutEditor === true ? v : value ?? v
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
@@ -21,9 +21,7 @@ import core, {
|
||||
type Doc,
|
||||
type DocumentQuery,
|
||||
generateId,
|
||||
type Hierarchy,
|
||||
matchQuery,
|
||||
type ModelDb,
|
||||
type Ref,
|
||||
type RefTo,
|
||||
type Space,
|
||||
@@ -110,20 +108,19 @@ export function getContextMasterTag (
|
||||
}
|
||||
|
||||
export async function pickTransition (
|
||||
model: ModelDb,
|
||||
hierarchy: Hierarchy,
|
||||
client: Client,
|
||||
execution: Execution,
|
||||
transitions: Transition[],
|
||||
doc: Doc
|
||||
): Promise<Transition | undefined> {
|
||||
for (const tr of transitions) {
|
||||
const trigger = model.findObject(tr.trigger)
|
||||
const trigger = client.getModel().findObject(tr.trigger)
|
||||
if (trigger === undefined) continue
|
||||
if (trigger.checkFunction === undefined) return tr
|
||||
const filled = fillParams(tr.triggerParams, execution)
|
||||
const checkFunc = await getResource(trigger.checkFunction)
|
||||
if (checkFunc === undefined) continue
|
||||
const res = await checkFunc(filled, doc, hierarchy)
|
||||
const res = await checkFunc(client, execution, filled, doc)
|
||||
if (res) return tr
|
||||
}
|
||||
}
|
||||
@@ -596,21 +593,49 @@ export async function requestResult (
|
||||
})
|
||||
}
|
||||
|
||||
export function todoTranstionCheck (params: Record<string, any>, doc: Doc): boolean {
|
||||
export function todoTranstionCheck (
|
||||
client: Client,
|
||||
execution: Execution,
|
||||
params: Record<string, any>,
|
||||
doc: Doc
|
||||
): boolean {
|
||||
if (params._id === undefined) return false
|
||||
return doc._id === params._id
|
||||
}
|
||||
|
||||
export function timeTransitionCheck (params: Record<string, any>): boolean {
|
||||
export function timeTransitionCheck (
|
||||
client: Client,
|
||||
execution: Execution,
|
||||
params: Record<string, any>,
|
||||
context: Record<string, any>
|
||||
): boolean {
|
||||
if (params.value === undefined) return false
|
||||
return params.value <= Date.now()
|
||||
}
|
||||
|
||||
export function updateCardTranstionCheck (params: Record<string, any>, doc: Doc, hierarchy: Hierarchy): boolean {
|
||||
const res = matchQuery([doc], params, doc._class, hierarchy, true)
|
||||
export function updateCardTranstionCheck (
|
||||
client: Client,
|
||||
execution: Execution,
|
||||
params: Record<string, any>,
|
||||
doc: Doc
|
||||
): boolean {
|
||||
const res = matchQuery([doc], params, doc._class, client.getHierarchy(), true)
|
||||
return res.length > 0
|
||||
}
|
||||
|
||||
export async function subProcessesDoneCheck (
|
||||
client: Client,
|
||||
execution: Execution,
|
||||
params: Record<string, any>,
|
||||
context: Record<string, any>
|
||||
): Promise<boolean> {
|
||||
const res = client.findOne(process.class.Execution, {
|
||||
parentId: execution._id,
|
||||
status: ExecutionStatus.Active
|
||||
})
|
||||
return res === undefined
|
||||
}
|
||||
|
||||
export function getCirteriaEditor (of: Ref<Class<Doc>>, category: AttributeCategory): AnyComponent | undefined {
|
||||
const client = getClient()
|
||||
if (category !== 'attribute') {
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
// limitations under the License.
|
||||
|
||||
import { Card, MasterTag, Tag } from '@hcengineering/card'
|
||||
import { Association, Class, Doc, DocumentUpdate, Hierarchy, ObjQueryType, Ref, Tx, Type } from '@hcengineering/core'
|
||||
import { Association, Class, Client, Doc, DocumentUpdate, ObjQueryType, Ref, Tx, Type } from '@hcengineering/core'
|
||||
import { Asset, IntlString, Plugin, plugin, Resource } from '@hcengineering/platform'
|
||||
import { ToDo } from '@hcengineering/time'
|
||||
import { AnyComponent } from '@hcengineering/ui'
|
||||
@@ -84,9 +84,10 @@ export enum ExecutionLogAction {
|
||||
}
|
||||
|
||||
export type CheckFunc = (
|
||||
client: Client,
|
||||
execution: Execution,
|
||||
params: Record<string, any>,
|
||||
context: Record<string, any>,
|
||||
hierarchy: Hierarchy
|
||||
context: Record<string, any>
|
||||
) => Promise<boolean>
|
||||
|
||||
export enum ExecutionStatus {
|
||||
@@ -216,6 +217,7 @@ export default plugin(processId, {
|
||||
triggerCheck: {
|
||||
ToDo: '' as Resource<CheckFunc>,
|
||||
UpdateCheck: '' as Resource<CheckFunc>,
|
||||
SubProcessesDoneCheck: '' as Resource<CheckFunc>,
|
||||
Time: '' as Resource<CheckFunc>
|
||||
},
|
||||
string: {
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
//
|
||||
|
||||
import cardPlugin, { Card, MasterTag, Tag } from '@hcengineering/card'
|
||||
import core, { Association, Data, Doc, generateId, Hierarchy, matchQuery, Ref, Relation, Tx } from '@hcengineering/core'
|
||||
import core, { Association, Data, Doc, generateId, matchQuery, Ref, Relation, Tx } from '@hcengineering/core'
|
||||
import process, {
|
||||
Execution,
|
||||
ExecutionContext,
|
||||
@@ -27,23 +27,37 @@ import process, {
|
||||
import { ExecuteResult, ProcessControl } from '@hcengineering/server-process'
|
||||
import time, { ToDoPriority } from '@hcengineering/time'
|
||||
|
||||
export function CheckToDo (params: Record<string, any>, context: Record<string, any>): boolean {
|
||||
export function CheckToDo (
|
||||
control: ProcessControl,
|
||||
execution: Execution,
|
||||
params: Record<string, any>,
|
||||
context: Record<string, any>
|
||||
): boolean {
|
||||
if (params._id === undefined) return false
|
||||
if (context.todo === undefined) return false
|
||||
return context.todo._id === params._id
|
||||
}
|
||||
|
||||
export async function CheckSubProcessesDone (control: ProcessControl, execution: Execution): Promise<boolean> {
|
||||
const res = control.client.findOne(process.class.Execution, {
|
||||
parentId: execution._id,
|
||||
status: ExecutionStatus.Active
|
||||
})
|
||||
return res === undefined
|
||||
}
|
||||
|
||||
export function OnCardUpdateCheck (
|
||||
control: ProcessControl,
|
||||
execution: Execution,
|
||||
params: Record<string, any>,
|
||||
context: Record<string, any>,
|
||||
hierarchy: Hierarchy
|
||||
context: Record<string, any>
|
||||
): boolean {
|
||||
if (context.card === undefined) return false
|
||||
const res = matchQuery([context.card], params, context.card._class, hierarchy, true)
|
||||
const res = matchQuery([context.card], params, context.card._class, control.client.getHierarchy(), true)
|
||||
return res.length > 0
|
||||
}
|
||||
|
||||
export function CheckTime (params: Record<string, any>): boolean {
|
||||
export function CheckTime (control: ProcessControl, execution: Execution, params: Record<string, any>): boolean {
|
||||
if (params.value === undefined) return false
|
||||
return params.value <= Date.now()
|
||||
}
|
||||
|
||||
@@ -80,6 +80,7 @@ import {
|
||||
AddTag,
|
||||
CheckToDo,
|
||||
OnCardUpdateCheck,
|
||||
CheckSubProcessesDone,
|
||||
CheckTime
|
||||
} from './functions'
|
||||
import { ToDoCancellRollback, ToDoCloseRollback } from './rollback'
|
||||
@@ -356,6 +357,7 @@ export default async () => ({
|
||||
AddTag,
|
||||
CheckToDo,
|
||||
OnCardUpdateCheck,
|
||||
CheckSubProcessesDone,
|
||||
CheckTime
|
||||
},
|
||||
transform: {
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { Doc, Mixin, Ref } from '@hcengineering/core'
|
||||
import type { Plugin, Resource } from '@hcengineering/platform'
|
||||
import { plugin } from '@hcengineering/platform'
|
||||
import { CheckFunc, Method, ProcessFunction, Trigger } from '@hcengineering/process'
|
||||
import { Execution, Method, ProcessFunction, Trigger } from '@hcengineering/process'
|
||||
import { TriggerFunc } from '@hcengineering/server-core'
|
||||
import { ExecuteFunc, RollbackFunc, TransformFunc } from './types'
|
||||
import { ExecuteFunc, ProcessControl, RollbackFunc, TransformFunc } from './types'
|
||||
|
||||
export * from './types'
|
||||
|
||||
@@ -12,6 +12,13 @@ export * from './types'
|
||||
*/
|
||||
export const serverProcessId = 'server-process' as Plugin
|
||||
|
||||
export type CheckFunc = (
|
||||
control: ProcessControl,
|
||||
execution: Execution,
|
||||
params: Record<string, any>,
|
||||
context: Record<string, any>
|
||||
) => Promise<boolean>
|
||||
|
||||
export interface TriggerImpl extends Trigger {
|
||||
serverCheckFunc?: Resource<CheckFunc>
|
||||
rollbackFunc?: Resource<RollbackFunc>
|
||||
@@ -49,6 +56,7 @@ export default plugin(serverProcessId, {
|
||||
AddTag: '' as Resource<ExecuteFunc>,
|
||||
CheckToDo: '' as Resource<CheckFunc>,
|
||||
OnCardUpdateCheck: '' as Resource<CheckFunc>,
|
||||
CheckSubProcessesDone: '' as Resource<CheckFunc>,
|
||||
CheckTime: '' as Resource<CheckFunc>
|
||||
},
|
||||
transform: {
|
||||
|
||||
@@ -529,13 +529,12 @@ export async function pickTransition (
|
||||
for (const tr of transitions) {
|
||||
const trigger = control.client.getModel().findObject(tr.trigger)
|
||||
if (trigger === undefined) continue
|
||||
if (trigger.checkFunction === undefined) return tr
|
||||
const impl = control.client.getHierarchy().as(trigger, serverProcess.mixin.TriggerImpl)
|
||||
if (impl?.serverCheckFunc === undefined) return tr
|
||||
const filled = await fillParams(tr.triggerParams, execution, control)
|
||||
const checkFunc = await getResource(impl.serverCheckFunc)
|
||||
if (checkFunc === undefined) continue
|
||||
const res = await checkFunc(filled, context, control.client.getHierarchy())
|
||||
const res = await checkFunc(control, execution, filled, context)
|
||||
if (res) return tr
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user