@gadmin2n/schematics 0.0.142 → 0.0.144

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (140) hide show
  1. package/dist/lib/application/files/gadmin2-game-angle-demo/config/prisma/workflow.prisma +5 -23
  2. package/dist/lib/application/files/gadmin2-game-angle-demo/server/scripts/lib/page-helpers.ts +4 -2
  3. package/dist/lib/application/files/gadmin2-game-angle-demo/server/scripts/page-manage.ts +36 -1
  4. package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/agenda.seed.ts +14 -14
  5. package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/bootstrap.ts +18 -13
  6. package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/canvas.seed.ts +14 -14
  7. package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/index.ts +1 -1
  8. package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/workflow-node-types.ts +67 -404
  9. package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/workflow.seed.ts +16 -40
  10. package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/workflows.ts +12 -124
  11. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/app.module.ts +3 -0
  12. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/config/index.ts +0 -21
  13. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/codeRuntime/code-runtime.controller.ts +3 -10
  14. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/codeRuntime/codeRuntime.module.ts +1 -2
  15. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/externalInteraction/external-callback.controller.spec.ts +48 -0
  16. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/externalInteraction/external-callback.controller.ts +96 -0
  17. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/externalInteraction/external-interaction-runtime.controller.spec.ts +1 -59
  18. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/externalInteraction/external-interaction-runtime.controller.ts +8 -43
  19. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/externalInteraction/external-interaction-runtime.dto.ts +0 -23
  20. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/externalInteraction/external-interaction.service.ts +2 -0
  21. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/externalInteraction/external-wait.handler.ts +2 -0
  22. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/externalInteraction/externalInteraction.module.ts +7 -3
  23. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/externalInteraction/workflow-callback-url.controller.ts +2 -2
  24. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/externalInteraction/workflow-callback-url.service.spec.ts +18 -123
  25. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/externalInteraction/workflow-callback-url.service.ts +4 -0
  26. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/httpRequest/http-request-runtime.controller.ts +3 -10
  27. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/httpRequest/httpRequest.module.ts +1 -2
  28. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/humanApproval/human-approval.controller.ts +0 -10
  29. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/humanApproval/human-approval.dto.ts +12 -4
  30. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/humanApproval/human-approval.errors.ts +1 -1
  31. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/humanApproval/human-approval.external-decision.spec.ts +42 -209
  32. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/humanApproval/human-approval.service.ts +108 -225
  33. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/humanApproval/humanApproval.module.ts +0 -2
  34. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/humanApproval/runtime/human-approval-runtime.controller.ts +27 -22
  35. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/humanApproval/runtime/human-approval-runtime.dto.ts +9 -1
  36. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/humanApproval/runtime/runtime-token.guard.spec.ts +30 -0
  37. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/humanApproval/runtime/runtime-token.guard.ts +8 -15
  38. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/index.ts +0 -2
  39. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/temporalTenantConfig/runtime-connectivity-probe.service.spec.ts +14 -0
  40. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/temporalTenantConfig/runtime-connectivity-probe.service.ts +37 -0
  41. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/temporalTenantConfig/temporalTenantConfig.controller.spec.ts +41 -0
  42. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/temporalTenantConfig/temporalTenantConfig.controller.ts +53 -0
  43. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/temporalTenantConfig/temporalTenantConfig.module.ts +7 -2
  44. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/temporalTenantConfig/workflow-runtime-health.controller.ts +21 -0
  45. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/dsl-validate.util.spec.ts +2 -2
  46. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-callable.spec.ts +16 -88
  47. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-callable.ts +23 -59
  48. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-compiler.service.spec.ts +125 -39
  49. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-compiler.service.ts +95 -28
  50. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-handle-validator.ts +0 -20
  51. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-http-response.spec.ts +23 -26
  52. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-http-response.ts +6 -52
  53. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow.controller.ts +2 -2
  54. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow.service.spec.ts +24 -0
  55. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow.service.ts +26 -21
  56. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowConfig/widget-catalog.service.spec.ts +0 -1
  57. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowConfig/widget-catalog.service.ts +0 -1
  58. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowRuntimeConfig/workflow-runtime-config.service.spec.ts +32 -0
  59. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowRuntimeConfig/workflow-runtime-config.service.ts +41 -0
  60. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowRuntimeConfig/workflowRuntimeConfig.module.ts +10 -0
  61. package/dist/lib/application/files/gadmin2-game-angle-demo/server/tsconfig.build.json +10 -1
  62. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/README.md +16 -12
  63. package/dist/lib/application/files/gadmin2-game-angle-demo/web/package.json +1 -1
  64. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/PageHeader.tsx +1 -1
  65. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/agentPanel/inspectorActions.ts +19 -19
  66. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/contexts/color-mode/index.tsx +1 -1
  67. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/layout/header.tsx +15 -11
  68. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/config/routeRegistry.tsx +0 -6
  69. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/dev-shell/AddDataModal.tsx +3 -3
  70. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/dev-shell/AddPageModal.tsx +1 -1
  71. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/dev-shell/DeleteDataConfirm.tsx +1 -1
  72. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/dev-shell/EditDataModal.tsx +1 -1
  73. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/hooks/useDynamicResources.tsx +1 -0
  74. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/locales/en/workflow.json +85 -95
  75. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/locales/zh_CN/workflow.json +85 -95
  76. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/agenda/index.tsx +2 -2
  77. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/agendaJob/list.tsx +21 -2
  78. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/game/list.tsx +21 -2
  79. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/human-approval/inbox.tsx +14 -66
  80. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/page/list.tsx +4 -4
  81. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/resource/list.tsx +3 -3
  82. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/role/list.tsx +3 -3
  83. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/CustomNode.test.tsx +29 -0
  84. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/CustomNode.tsx +4 -2
  85. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/EnhancedFlowRenderer.tsx +4 -6
  86. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/ExecutionStatusNode.test.tsx +3 -0
  87. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/ExecutionStatusNode.tsx +3 -1
  88. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/FlowRenderer.tsx +4 -6
  89. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/NewNodeDefaults.test.tsx +23 -92
  90. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/NodeOutputSummary.tsx +200 -0
  91. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/NodePropertyPanel.test.tsx +61 -136
  92. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/NodePropertyPanel.tsx +96 -195
  93. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/NodeTypeBadge.tsx +36 -0
  94. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/components/CreateNodeInstanceModal.tsx +5 -10
  95. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/components/NodeInstanceForm.tsx +47 -22
  96. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/create.tsx +7 -5
  97. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/edit.tsx +8 -6
  98. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/node-config.css +35 -0
  99. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/schema-form/default-widgets.tsx +1 -6
  100. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/ApproverSourceEditor.tsx +1 -4
  101. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/CodeConfigEditor.tsx +1 -1
  102. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/ExternalRequestConfigEditor.tsx +1 -1
  103. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/ExternalWaitConfigEditor.tsx +82 -259
  104. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/HttpRequestConfigEditor.tsx +1 -2
  105. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/HumanApprovalConfigEditor.test.tsx +7 -6
  106. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/HumanApprovalConfigEditor.tsx +77 -71
  107. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/ReturnResultConfigEditor.test.tsx +10 -57
  108. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/ReturnResultConfigEditor.tsx +8 -273
  109. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/temporal-tenant/index.test.tsx +54 -0
  110. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/temporal-tenant/index.tsx +110 -20
  111. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/newNodeConfig.ts +4 -34
  112. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/resolveOutputs.test.ts +3 -10
  113. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/resolveOutputs.ts +2 -37
  114. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflowEventOutbox/list.tsx +26 -2
  115. package/package.json +1 -1
  116. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/approvalChannel/approval-channel.controller.ts +0 -89
  117. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/approvalChannel/approval-channel.dto.ts +0 -68
  118. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/approvalChannel/approval-channel.service.spec.ts +0 -177
  119. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/approvalChannel/approval-channel.service.ts +0 -283
  120. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/approvalChannel/approvalChannel.module.ts +0 -10
  121. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/approval-channels/ApprovalChannelModal.test.tsx +0 -84
  122. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/approval-channels/ApprovalChannelModal.tsx +0 -141
  123. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/approval-channels/approval-channel.types.ts +0 -16
  124. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/approval-channels/index.tsx +0 -210
  125. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/ApprovalRequestTriggerConfigEditor.tsx +0 -39
  126. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/SubmitApprovalResultConfigEditor.tsx +0 -104
  127. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/SubmitExternalResultConfigEditor.tsx +0 -98
  128. /package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/page/{Components → components}/AssignRolesModal.tsx +0 -0
  129. /package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/page/{Components → components}/CreatePageModal.tsx +0 -0
  130. /package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/page/{Components → components}/EditPageModal.tsx +0 -0
  131. /package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/page/{Components → components}/PageDetailDrawer.tsx +0 -0
  132. /package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/page/{Components → components}/PageFormModal.tsx +0 -0
  133. /package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/resource/{Components → components}/CreateModal.tsx +0 -0
  134. /package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/resource/{Components → components}/EditModal.tsx +0 -0
  135. /package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/resource/{Components → components}/ResourceDetailDrawer.tsx +0 -0
  136. /package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/resource/{Components → components}/modal.tsx +0 -0
  137. /package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/role/{Components → components}/CreateModal.tsx +0 -0
  138. /package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/role/{Components → components}/EditModal.tsx +0 -0
  139. /package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/role/{Components → components}/RoleDetailDrawer.tsx +0 -0
  140. /package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/role/{Components → components}/modal.tsx +0 -0
@@ -1,33 +1,18 @@
1
- import { DeleteOutlined, PlusOutlined } from '@ant-design/icons';
2
- import {
3
- Alert,
4
- Button,
5
- Card,
6
- Input,
7
- InputNumber,
8
- Select,
9
- Space,
10
- Switch,
11
- Typography,
12
- message,
13
- } from 'antd';
14
- import { customRequest } from 'helpers/http';
15
- import { useEffect, useState } from 'react';
1
+ import { Alert, Card, InputNumber, Radio, Space, Typography } from 'antd';
16
2
  import { useTranslation } from 'react-i18next';
17
3
  import { ParameterBindingEditor } from '../../components/ParameterBindingEditor';
18
4
  import type { ParameterBinding } from '../../types/parameter-binding';
19
5
  import type { WidgetProps } from '../schema-form/widget-registry';
20
6
 
21
- type Outcome = { code: string; label: string };
7
+ type TimeoutConfig =
8
+ | { mode: 'DEADLINE'; deadlineBinding: ParameterBinding }
9
+ | { mode: 'DURATION'; durationSeconds: number }
10
+ | { mode: 'NONE' };
11
+
22
12
  type ExternalWaitConfig = {
23
- dispatchWorkflowId?: string;
24
- callbackWorkflowId?: string;
25
- outcomes?: Outcome[];
26
- timeout?: { durationSeconds?: number; outcome?: string };
27
- businessDataBinding?: ParameterBinding;
28
- participantsBinding?: ParameterBinding;
13
+ callbackTokenBinding?: ParameterBinding;
14
+ timeout?: TimeoutConfig;
29
15
  };
30
- type WorkflowOption = { id: string; name: string };
31
16
 
32
17
  export function ExternalWaitConfigEditor({
33
18
  value,
@@ -36,41 +21,32 @@ export function ExternalWaitConfigEditor({
36
21
  }: WidgetProps<ExternalWaitConfig>) {
37
22
  const { t } = useTranslation('workflow');
38
23
  const config = value ?? {};
39
- const outcomes = config.outcomes ?? [];
40
- const [options, setOptions] = useState<{
41
- dispatchWorkflows: WorkflowOption[];
42
- callbackWorkflows: WorkflowOption[];
43
- }>({ dispatchWorkflows: [], callbackWorkflows: [] });
44
-
45
- useEffect(() => {
46
- customRequest<{
47
- dispatchWorkflows: WorkflowOption[];
48
- callbackWorkflows: WorkflowOption[];
49
- }>('workflow/external-interaction-options', 'GET')
50
- .then(setOptions)
51
- .catch((error: any) =>
52
- message.error(error?.message ?? t('externalWait.workflowLoadFailed')),
53
- );
54
- }, [t]);
24
+ const timeout = config.timeout ?? {
25
+ mode: 'DEADLINE' as const,
26
+ deadlineBinding: { source: 'WORKFLOW' as const, path: 'expiresAt' },
27
+ };
55
28
 
56
29
  function update(patch: Partial<ExternalWaitConfig>) {
57
- const next = { ...config, ...patch };
58
- for (const [key, item] of Object.entries(patch)) {
59
- if (item === undefined) delete (next as Record<string, unknown>)[key];
60
- }
61
- onChange(next);
30
+ onChange({ ...config, ...patch });
62
31
  }
63
32
 
64
- function updateOutcome(index: number, patch: Partial<Outcome>) {
65
- update({
66
- outcomes: outcomes.map((item, itemIndex) =>
67
- itemIndex === index ? { ...item, ...patch } : item,
68
- ),
69
- });
33
+ function changeTimeoutMode(mode: TimeoutConfig['mode']) {
34
+ if (mode === 'DEADLINE') {
35
+ update({
36
+ timeout: {
37
+ mode,
38
+ deadlineBinding: { source: 'WORKFLOW', path: 'expiresAt' },
39
+ },
40
+ });
41
+ } else if (mode === 'DURATION') {
42
+ update({ timeout: { mode, durationSeconds: 86400 } });
43
+ } else {
44
+ update({ timeout: { mode } });
45
+ }
70
46
  }
71
47
 
72
48
  return (
73
- <Space direction="vertical" size={16} style={{ width: '100%' }}>
49
+ <Space direction="vertical" size={12} style={{ width: '100%' }}>
74
50
  <Alert
75
51
  type="info"
76
52
  showIcon
@@ -78,215 +54,69 @@ export function ExternalWaitConfigEditor({
78
54
  description={t('externalWait.hint')}
79
55
  />
80
56
 
81
- <Card size="small" title={t('externalWait.workflows')}>
82
- <Space direction="vertical" size={12} style={{ width: '100%' }}>
83
- <div>
84
- <Typography.Text strong>
85
- {t('externalWait.dispatchWorkflow')} *
86
- </Typography.Text>
87
- <Select
88
- value={config.dispatchWorkflowId || undefined}
57
+ <Card size="small" title={t('externalWait.callbackToken')}>
58
+ <ParameterBindingEditor
59
+ name={t('externalWait.callbackToken')}
60
+ defaultPath="callbackToken"
61
+ value={
62
+ config.callbackTokenBinding ?? {
63
+ source: 'WORKFLOW',
64
+ path: 'callbackToken',
65
+ }
66
+ }
67
+ disabled={disabled}
68
+ onChange={(callbackTokenBinding) => update({ callbackTokenBinding })}
69
+ />
70
+ </Card>
71
+
72
+ <Card size="small" title={t('externalWait.timeout')}>
73
+ <Radio.Group
74
+ value={timeout.mode}
75
+ disabled={disabled}
76
+ onChange={(event) => changeTimeoutMode(event.target.value)}
77
+ >
78
+ <Space direction="vertical">
79
+ <Radio value="DEADLINE">{t('externalWait.deadline')}</Radio>
80
+ <Radio value="DURATION">{t('externalWait.duration')}</Radio>
81
+ <Radio value="NONE">{t('externalWait.noTimeout')}</Radio>
82
+ </Space>
83
+ </Radio.Group>
84
+
85
+ {timeout.mode === 'DEADLINE' && (
86
+ <div style={{ marginTop: 12 }}>
87
+ <ParameterBindingEditor
88
+ name={t('externalWait.deadlineField')}
89
+ defaultPath="expiresAt"
90
+ value={timeout.deadlineBinding}
89
91
  disabled={disabled}
90
- options={options.dispatchWorkflows.map((workflow) => ({
91
- value: workflow.id,
92
- label: workflow.name,
93
- }))}
94
- placeholder={t('externalWait.selectDispatchWorkflow')}
95
- onChange={(dispatchWorkflowId) => update({ dispatchWorkflowId })}
96
- showSearch
97
- optionFilterProp="label"
98
- style={{ width: '100%', marginTop: 6 }}
92
+ onChange={(deadlineBinding) =>
93
+ update({ timeout: { mode: 'DEADLINE', deadlineBinding } })
94
+ }
99
95
  />
100
- <Typography.Text type="secondary">
101
- {t('externalWait.dispatchHint')}
102
- </Typography.Text>
103
96
  </div>
97
+ )}
104
98
 
105
- <div>
106
- <Typography.Text strong>
107
- {t('externalWait.callbackWorkflow')}
108
- </Typography.Text>
109
- <Select
110
- value={config.callbackWorkflowId || undefined}
99
+ {timeout.mode === 'DURATION' && (
100
+ <div style={{ marginTop: 12 }}>
101
+ <InputNumber
102
+ min={1}
103
+ precision={0}
104
+ value={timeout.durationSeconds}
111
105
  disabled={disabled}
112
- allowClear
113
- options={options.callbackWorkflows.map((workflow) => ({
114
- value: workflow.id,
115
- label: workflow.name,
116
- }))}
117
- placeholder={t('externalWait.selectCallbackWorkflow')}
118
- onChange={(callbackWorkflowId) => update({ callbackWorkflowId })}
119
- showSearch
120
- optionFilterProp="label"
121
- style={{ width: '100%', marginTop: 6 }}
106
+ addonAfter={t('externalWait.seconds')}
107
+ onChange={(durationSeconds) =>
108
+ update({
109
+ timeout: {
110
+ mode: 'DURATION',
111
+ durationSeconds: durationSeconds ?? 86400,
112
+ },
113
+ })
114
+ }
115
+ style={{ width: '100%' }}
122
116
  />
123
- <Typography.Text type="secondary">
124
- {t('externalWait.callbackHint')}
125
- </Typography.Text>
126
- </div>
127
- </Space>
128
- </Card>
129
-
130
- <Card size="small" title={t('externalWait.data')}>
131
- <Space direction="vertical" size={14} style={{ width: '100%' }}>
132
- <div>
133
- <Space>
134
- <Switch
135
- size="small"
136
- checked={Boolean(config.businessDataBinding)}
137
- disabled={disabled}
138
- onChange={(checked) =>
139
- update({
140
- businessDataBinding: checked
141
- ? { source: 'INPUT', path: 'data' }
142
- : undefined,
143
- })
144
- }
145
- />
146
- <Typography.Text>
147
- {t('externalWait.customBusinessData')}
148
- </Typography.Text>
149
- </Space>
150
- {!config.businessDataBinding && (
151
- <Typography.Paragraph
152
- type="secondary"
153
- style={{ margin: '6px 0 0' }}
154
- >
155
- {t('externalWait.defaultBusinessData')}
156
- </Typography.Paragraph>
157
- )}
158
- {config.businessDataBinding && (
159
- <div style={{ marginTop: 8 }}>
160
- <ParameterBindingEditor
161
- name={t('externalWait.businessData')}
162
- defaultPath="data"
163
- value={config.businessDataBinding}
164
- disabled={disabled}
165
- onChange={(businessDataBinding) =>
166
- update({ businessDataBinding })
167
- }
168
- />
169
- </div>
170
- )}
171
- </div>
172
-
173
- <div>
174
- <Space>
175
- <Switch
176
- size="small"
177
- checked={Boolean(config.participantsBinding)}
178
- disabled={disabled}
179
- onChange={(checked) =>
180
- update({
181
- participantsBinding: checked
182
- ? { source: 'WORKFLOW', path: 'participants' }
183
- : undefined,
184
- })
185
- }
186
- />
187
- <Typography.Text>
188
- {t('externalWait.sendParticipants')}
189
- </Typography.Text>
190
- </Space>
191
- {config.participantsBinding && (
192
- <div style={{ marginTop: 8 }}>
193
- <ParameterBindingEditor
194
- name={t('externalWait.participants')}
195
- defaultPath="participants"
196
- value={config.participantsBinding}
197
- disabled={disabled}
198
- onChange={(participantsBinding) =>
199
- update({ participantsBinding })
200
- }
201
- />
202
- </div>
203
- )}
204
117
  </div>
205
- </Space>
206
- </Card>
207
-
208
- <Card
209
- size="small"
210
- title={t('externalWait.outcomes')}
211
- extra={
212
- <Button
213
- type="link"
214
- size="small"
215
- icon={<PlusOutlined />}
216
- disabled={disabled}
217
- onClick={() =>
218
- update({
219
- outcomes: [
220
- ...outcomes,
221
- { code: `RESULT_${outcomes.length + 1}`, label: '' },
222
- ],
223
- })
224
- }
225
- >
226
- {t('externalWait.addOutcome')}
227
- </Button>
228
- }
229
- >
230
- <Space direction="vertical" size={10} style={{ width: '100%' }}>
231
- {outcomes.map((outcome, index) => (
232
- <Space.Compact key={index} style={{ width: '100%' }}>
233
- <Input
234
- aria-label={t('externalWait.outcomeLabel')}
235
- value={outcome.label}
236
- disabled={disabled}
237
- placeholder={t('externalWait.outcomeLabel')}
238
- onChange={(event) =>
239
- updateOutcome(index, { label: event.target.value })
240
- }
241
- />
242
- <Input
243
- aria-label={t('externalWait.outcomeCode')}
244
- value={outcome.code}
245
- disabled={disabled}
246
- placeholder="COMPLETED"
247
- onChange={(event) =>
248
- updateOutcome(index, {
249
- code: normalizeOutcomeCode(event.target.value),
250
- })
251
- }
252
- />
253
- <Button
254
- aria-label={t('externalWait.removeOutcome')}
255
- icon={<DeleteOutlined />}
256
- disabled={disabled || outcomes.length <= 1}
257
- onClick={() =>
258
- update({
259
- outcomes: outcomes.filter(
260
- (_item, itemIndex) => itemIndex !== index,
261
- ),
262
- })
263
- }
264
- />
265
- </Space.Compact>
266
- ))}
267
- <Typography.Text type="secondary">
268
- {t('externalWait.outcomeHint')}
269
- </Typography.Text>
270
- </Space>
271
- </Card>
118
+ )}
272
119
 
273
- <Card size="small" title={t('externalWait.timeout')}>
274
- <InputNumber
275
- min={1}
276
- precision={0}
277
- value={config.timeout?.durationSeconds ?? 86400}
278
- disabled={disabled}
279
- addonAfter={t('externalWait.seconds')}
280
- onChange={(durationSeconds) =>
281
- update({
282
- timeout: {
283
- durationSeconds: durationSeconds ?? 86400,
284
- outcome: 'TIMEOUT',
285
- },
286
- })
287
- }
288
- style={{ width: '100%' }}
289
- />
290
120
  <Typography.Paragraph type="secondary" style={{ margin: '8px 0 0' }}>
291
121
  {t('externalWait.timeoutHint')}
292
122
  </Typography.Paragraph>
@@ -294,10 +124,3 @@ export function ExternalWaitConfigEditor({
294
124
  </Space>
295
125
  );
296
126
  }
297
-
298
- function normalizeOutcomeCode(value: string): string {
299
- return value
300
- .toUpperCase()
301
- .replace(/[^A-Z0-9_]/g, '_')
302
- .replace(/_+/g, '_');
303
- }
@@ -83,7 +83,6 @@ export function HttpRequestConfigEditor({
83
83
  value: 'approval.requestId',
84
84
  label: t('systemData.approvalRequestId'),
85
85
  },
86
- { value: 'approval.channel', label: t('systemData.approvalChannel') },
87
86
  {
88
87
  value: 'approval.candidates',
89
88
  label: t('systemData.approvalCandidates'),
@@ -121,7 +120,7 @@ export function HttpRequestConfigEditor({
121
120
  }
122
121
 
123
122
  return (
124
- <Space direction="vertical" size={16} style={{ width: '100%' }}>
123
+ <Space direction="vertical" size={12} style={{ width: '100%' }}>
125
124
  <Card
126
125
  size="small"
127
126
  title={
@@ -29,7 +29,7 @@ describe('HumanApprovalConfigEditor', () => {
29
29
  await i18n.changeLanguage('zh_CN');
30
30
  vi.mocked(customRequest).mockResolvedValue([
31
31
  {
32
- code: 'myoa',
32
+ id: '11',
33
33
  name: 'MyOA',
34
34
  isEnabled: true,
35
35
  inputParameters: [
@@ -40,14 +40,14 @@ describe('HumanApprovalConfigEditor', () => {
40
40
  ] as never);
41
41
  });
42
42
 
43
- it('shows the selected channel contract and stores AP argument bindings', async () => {
43
+ it('shows the selected Workflow contract and stores input bindings', async () => {
44
44
  const onChange = vi.fn();
45
45
 
46
46
  render(
47
47
  <HumanApprovalConfigEditor
48
48
  value={{
49
- channelRef: 'myoa',
50
- channelInputBindings: {
49
+ approvalWorkflowId: '11',
50
+ approvalWorkflowInputBindings: {
51
51
  title: { source: 'WORKFLOW', path: 'requestTitle' },
52
52
  content: { source: 'INPUT', path: 'description' },
53
53
  },
@@ -63,7 +63,7 @@ describe('HumanApprovalConfigEditor', () => {
63
63
  );
64
64
 
65
65
  await waitFor(() =>
66
- expect(screen.getByText('单据信息')).toBeInTheDocument(),
66
+ expect(screen.getByText('传给审批 Workflow 的数据')).toBeInTheDocument(),
67
67
  );
68
68
  expect(screen.getByText('单据标题')).toBeInTheDocument();
69
69
  expect(screen.getByText('审批内容')).toBeInTheDocument();
@@ -77,10 +77,11 @@ describe('HumanApprovalConfigEditor', () => {
77
77
 
78
78
  expect(onChange).toHaveBeenLastCalledWith(
79
79
  expect.objectContaining({
80
- channelInputBindings: expect.objectContaining({
80
+ approvalWorkflowInputBindings: expect.objectContaining({
81
81
  title: { source: 'WORKFLOW', path: 'approval.title' },
82
82
  }),
83
83
  }),
84
84
  );
85
+ expect(customRequest).toHaveBeenCalledWith('workflow/callable', 'GET');
85
86
  });
86
87
  });
@@ -32,8 +32,8 @@ type Rule = {
32
32
  percentage?: number;
33
33
  };
34
34
  type ApprovalConfig = {
35
- channelRef?: string;
36
- channelInputBindings?: Record<string, ParameterBinding>;
35
+ approvalWorkflowId?: string;
36
+ approvalWorkflowInputBindings?: Record<string, ParameterBinding>;
37
37
  approverSources?: ApproverSourceConfig[];
38
38
  subjects: SubjectSource[];
39
39
  approvalRule: Rule;
@@ -41,10 +41,9 @@ type ApprovalConfig = {
41
41
  timeout: { durationSeconds: number; action: 'APPROVED' | 'REJECTED' };
42
42
  };
43
43
 
44
- type ApprovalChannelOption = {
45
- code: string;
44
+ type ApprovalWorkflowOption = {
45
+ id: string;
46
46
  name: string;
47
- isEnabled: boolean;
48
47
  inputParameters: Array<{
49
48
  key: string;
50
49
  label?: string;
@@ -64,10 +63,12 @@ export function HumanApprovalConfigEditor({
64
63
  schema,
65
64
  }: WidgetProps<ApprovalConfig | undefined>) {
66
65
  const { t } = useTranslation('workflow');
67
- const [channels, setChannels] = useState<ApprovalChannelOption[]>([]);
66
+ const [approvalWorkflows, setApprovalWorkflows] = useState<
67
+ ApprovalWorkflowOption[]
68
+ >([]);
68
69
  const config: ApprovalConfig = {
69
- channelRef: value?.channelRef,
70
- channelInputBindings: value?.channelInputBindings ?? {},
70
+ approvalWorkflowId: value?.approvalWorkflowId,
71
+ approvalWorkflowInputBindings: value?.approvalWorkflowInputBindings ?? {},
71
72
  approverSources: value?.approverSources ?? [],
72
73
  subjects: value?.subjects ?? [],
73
74
  approvalRule: value?.approvalRule ?? { mode: 'ANY' },
@@ -75,9 +76,9 @@ export function HumanApprovalConfigEditor({
75
76
  timeout: value?.timeout ?? { durationSeconds: 0, action: 'REJECTED' },
76
77
  };
77
78
  useEffect(() => {
78
- customRequest<ApprovalChannelOption[]>('approval-channels', 'GET')
79
- .then((items) => setChannels(items.filter((item) => item.isEnabled)))
80
- .catch(() => setChannels([]));
79
+ customRequest<ApprovalWorkflowOption[]>('workflow/callable', 'GET')
80
+ .then(setApprovalWorkflows)
81
+ .catch(() => setApprovalWorkflows([]));
81
82
  }, []);
82
83
  const staticSelections = useMemo<SubjectSelection[]>(() => {
83
84
  const grouped = new Map<string, string[]>();
@@ -93,8 +94,8 @@ export function HumanApprovalConfigEditor({
93
94
  (subject): subject is Extract<SubjectSource, { source: 'DYNAMIC' }> =>
94
95
  subject.source === 'DYNAMIC',
95
96
  );
96
- const selectedChannel = channels.find(
97
- (channel) => channel.code === config.channelRef,
97
+ const selectedApprovalWorkflow = approvalWorkflows.find(
98
+ (workflow) => workflow.id === config.approvalWorkflowId,
98
99
  );
99
100
 
100
101
  function update(patch: Partial<ApprovalConfig>) {
@@ -124,7 +125,7 @@ export function HumanApprovalConfigEditor({
124
125
  }
125
126
 
126
127
  return (
127
- <Space direction="vertical" size={16} style={{ width: '100%' }}>
128
+ <Space direction="vertical" size={12} style={{ width: '100%' }}>
128
129
  <Card
129
130
  size="small"
130
131
  title={
@@ -252,33 +253,35 @@ export function HumanApprovalConfigEditor({
252
253
  title={
253
254
  <Space>
254
255
  <ApiOutlined />
255
- <span>{t('approval.channel')}</span>
256
+ <span>{t('approval.workflow')}</span>
256
257
  </Space>
257
258
  }
258
259
  >
259
260
  <Typography.Paragraph type="secondary">
260
- {t('approval.channelDescription')}
261
+ {t('approval.workflowDescription')}
261
262
  </Typography.Paragraph>
262
263
  <Select
263
264
  allowClear
264
265
  showSearch
265
266
  optionFilterProp="label"
266
267
  disabled={disabled}
267
- value={config.channelRef}
268
+ value={config.approvalWorkflowId}
268
269
  placeholder={t('approval.builtInInbox')}
269
- options={channels.map((channel) => ({
270
- value: channel.code,
271
- label: channel.name,
270
+ options={approvalWorkflows.map((workflow) => ({
271
+ value: workflow.id,
272
+ label: workflow.name,
272
273
  }))}
273
- onChange={(channelRef) => {
274
- const channel = channels.find((item) => item.code === channelRef);
274
+ onChange={(approvalWorkflowId) => {
275
+ const workflow = approvalWorkflows.find(
276
+ (item) => item.id === approvalWorkflowId,
277
+ );
275
278
  update({
276
- channelRef,
277
- channelInputBindings: channel
279
+ approvalWorkflowId,
280
+ approvalWorkflowInputBindings: workflow
278
281
  ? Object.fromEntries(
279
- channel.inputParameters.map((parameter) => [
282
+ workflow.inputParameters.map((parameter) => [
280
283
  parameter.key,
281
- config.channelInputBindings?.[parameter.key] ?? {
284
+ config.approvalWorkflowInputBindings?.[parameter.key] ?? {
282
285
  source: 'WORKFLOW',
283
286
  path: parameter.key,
284
287
  },
@@ -293,53 +296,56 @@ export function HumanApprovalConfigEditor({
293
296
  type="secondary"
294
297
  style={{ display: 'block', fontSize: 12, marginTop: 8 }}
295
298
  >
296
- {config.channelRef
297
- ? t('approval.externalChannelHint')
299
+ {config.approvalWorkflowId
300
+ ? t('approval.workflowHint')
298
301
  : t('approval.builtInInboxHint')}
299
302
  </Typography.Text>
300
- {selectedChannel && selectedChannel.inputParameters.length > 0 && (
301
- <>
302
- <Divider />
303
- <Typography.Text strong>
304
- {t('approval.channelInputs')}
305
- </Typography.Text>
306
- <Typography.Paragraph
307
- type="secondary"
308
- style={{ marginTop: 4, marginBottom: 12 }}
309
- >
310
- {t('approval.channelInputsDescription')}
311
- </Typography.Paragraph>
312
- <Space direction="vertical" size={14} style={{ width: '100%' }}>
313
- {selectedChannel.inputParameters.map((parameter) => {
314
- const name = parameter.label?.trim() || parameter.key;
315
- return (
316
- <div key={parameter.key}>
317
- <Space size={6} style={{ marginBottom: 6 }}>
318
- <Typography.Text strong>{name}</Typography.Text>
319
- {parameter.required && (
320
- <Tag color="blue">{t('approval.required')}</Tag>
321
- )}
322
- </Space>
323
- <ParameterBindingEditor
324
- name={name}
325
- defaultPath={parameter.key}
326
- value={config.channelInputBindings?.[parameter.key]}
327
- disabled={disabled}
328
- onChange={(binding) =>
329
- update({
330
- channelInputBindings: {
331
- ...config.channelInputBindings,
332
- [parameter.key]: binding,
333
- },
334
- })
335
- }
336
- />
337
- </div>
338
- );
339
- })}
340
- </Space>
341
- </>
342
- )}
303
+ {selectedApprovalWorkflow &&
304
+ selectedApprovalWorkflow.inputParameters.length > 0 && (
305
+ <>
306
+ <Divider />
307
+ <Typography.Text strong>
308
+ {t('approval.workflowInputs')}
309
+ </Typography.Text>
310
+ <Typography.Paragraph
311
+ type="secondary"
312
+ style={{ marginTop: 4, marginBottom: 12 }}
313
+ >
314
+ {t('approval.workflowInputsDescription')}
315
+ </Typography.Paragraph>
316
+ <Space direction="vertical" size={14} style={{ width: '100%' }}>
317
+ {selectedApprovalWorkflow.inputParameters.map((parameter) => {
318
+ const name = parameter.label?.trim() || parameter.key;
319
+ return (
320
+ <div key={parameter.key}>
321
+ <Space size={6} style={{ marginBottom: 6 }}>
322
+ <Typography.Text strong>{name}</Typography.Text>
323
+ {parameter.required && (
324
+ <Tag color="blue">{t('approval.required')}</Tag>
325
+ )}
326
+ </Space>
327
+ <ParameterBindingEditor
328
+ name={name}
329
+ defaultPath={parameter.key}
330
+ value={
331
+ config.approvalWorkflowInputBindings?.[parameter.key]
332
+ }
333
+ disabled={disabled}
334
+ onChange={(binding) =>
335
+ update({
336
+ approvalWorkflowInputBindings: {
337
+ ...config.approvalWorkflowInputBindings,
338
+ [parameter.key]: binding,
339
+ },
340
+ })
341
+ }
342
+ />
343
+ </div>
344
+ );
345
+ })}
346
+ </Space>
347
+ </>
348
+ )}
343
349
  </Card>
344
350
 
345
351
  <TimeoutSection