@gadmin2n/schematics 0.0.141 → 0.0.143

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/package.json +1 -1
  3. package/dist/lib/application/files/gadmin2-game-angle-demo/server/scripts/lib/page-helpers.ts +4 -2
  4. package/dist/lib/application/files/gadmin2-game-angle-demo/server/scripts/page-manage.ts +36 -1
  5. package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/agenda.seed.ts +14 -14
  6. package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/bootstrap.ts +18 -13
  7. package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/canvas.seed.ts +14 -14
  8. package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/index.ts +1 -1
  9. package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/workflow-node-types.ts +67 -404
  10. package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/workflow.seed.ts +16 -40
  11. package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/workflows.ts +12 -124
  12. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/app.module.ts +3 -0
  13. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/config/index.ts +0 -21
  14. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/codeRuntime/code-runtime.controller.ts +3 -10
  15. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/codeRuntime/codeRuntime.module.ts +1 -2
  16. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/externalInteraction/external-callback.controller.spec.ts +48 -0
  17. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/externalInteraction/external-callback.controller.ts +96 -0
  18. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/externalInteraction/external-interaction-runtime.controller.spec.ts +1 -59
  19. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/externalInteraction/external-interaction-runtime.controller.ts +8 -43
  20. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/externalInteraction/external-interaction-runtime.dto.ts +0 -23
  21. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/externalInteraction/external-interaction.service.ts +2 -0
  22. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/externalInteraction/external-wait.handler.ts +2 -0
  23. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/externalInteraction/externalInteraction.module.ts +7 -3
  24. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/externalInteraction/workflow-callback-url.controller.ts +2 -2
  25. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/externalInteraction/workflow-callback-url.service.spec.ts +18 -123
  26. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/externalInteraction/workflow-callback-url.service.ts +4 -0
  27. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/httpRequest/http-request-runtime.controller.ts +3 -10
  28. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/httpRequest/httpRequest.module.ts +1 -2
  29. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/humanApproval/human-approval.controller.ts +0 -10
  30. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/humanApproval/human-approval.dto.ts +12 -4
  31. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/humanApproval/human-approval.errors.ts +1 -1
  32. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/humanApproval/human-approval.external-decision.spec.ts +42 -209
  33. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/humanApproval/human-approval.service.ts +108 -225
  34. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/humanApproval/humanApproval.module.ts +0 -2
  35. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/humanApproval/runtime/human-approval-runtime.controller.ts +27 -22
  36. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/humanApproval/runtime/human-approval-runtime.dto.ts +9 -1
  37. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/humanApproval/runtime/runtime-token.guard.spec.ts +30 -0
  38. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/humanApproval/runtime/runtime-token.guard.ts +8 -15
  39. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/index.ts +0 -2
  40. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/temporalTenantConfig/runtime-connectivity-probe.service.spec.ts +14 -0
  41. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/temporalTenantConfig/runtime-connectivity-probe.service.ts +37 -0
  42. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/temporalTenantConfig/temporalTenantConfig.controller.spec.ts +41 -0
  43. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/temporalTenantConfig/temporalTenantConfig.controller.ts +53 -0
  44. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/temporalTenantConfig/temporalTenantConfig.module.ts +7 -2
  45. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/temporalTenantConfig/workflow-runtime-health.controller.ts +21 -0
  46. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/dsl-validate.util.spec.ts +2 -2
  47. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-callable.spec.ts +16 -88
  48. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-callable.ts +23 -59
  49. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-compiler.service.spec.ts +125 -39
  50. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-compiler.service.ts +95 -28
  51. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-handle-validator.ts +0 -20
  52. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-http-response.spec.ts +23 -26
  53. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-http-response.ts +6 -52
  54. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow.controller.ts +2 -2
  55. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow.service.spec.ts +24 -0
  56. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow.service.ts +26 -21
  57. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowConfig/widget-catalog.service.spec.ts +0 -1
  58. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowConfig/widget-catalog.service.ts +0 -1
  59. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowRuntimeConfig/workflow-runtime-config.service.spec.ts +32 -0
  60. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowRuntimeConfig/workflow-runtime-config.service.ts +41 -0
  61. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowRuntimeConfig/workflowRuntimeConfig.module.ts +10 -0
  62. package/dist/lib/application/files/gadmin2-game-angle-demo/server/tsconfig.build.json +10 -1
  63. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/README.md +16 -12
  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
@@ -0,0 +1,200 @@
1
+ import { Tag, Typography } from 'antd';
2
+ import { useTranslation } from 'react-i18next';
3
+ import type { WorkflowNode, WorkflowNodeType } from '../types';
4
+ import { resolveOutputs } from '../utils/resolveOutputs';
5
+
6
+ const { Text } = Typography;
7
+
8
+ interface OutputField {
9
+ path: string;
10
+ type: string;
11
+ description?: string;
12
+ required: boolean;
13
+ }
14
+
15
+ interface Props {
16
+ node: WorkflowNode;
17
+ nodeType?: WorkflowNodeType;
18
+ }
19
+
20
+ const DYNAMIC_OUTPUT_KEYS: Partial<Record<string, string>> = {
21
+ cron_trigger: 'workflowData',
22
+ manual_trigger: 'workflowData',
23
+ callable_trigger: 'workflowData',
24
+ code: 'codeReturn',
25
+ sub_workflow: 'workflowReturn',
26
+ return_result: 'returnPrevious',
27
+ };
28
+
29
+ function schemaType(schema: Record<string, any>): string {
30
+ if (Array.isArray(schema.type)) return schema.type.join(' | ');
31
+ if (typeof schema.type === 'string') return schema.type;
32
+ if (schema.enum) return 'enum';
33
+ return 'any';
34
+ }
35
+
36
+ function outputFields(schema: Record<string, any>): OutputField[] {
37
+ const properties =
38
+ schema.properties && typeof schema.properties === 'object'
39
+ ? schema.properties
40
+ : {};
41
+ const required = new Set<string>(
42
+ Array.isArray(schema.required) ? schema.required : [],
43
+ );
44
+
45
+ return Object.entries<Record<string, any>>(properties).map(
46
+ ([name, property]) => ({
47
+ path: `input.${name}`,
48
+ type: schemaType(property ?? {}),
49
+ description:
50
+ typeof property?.description === 'string'
51
+ ? property.description
52
+ : undefined,
53
+ required: required.has(name),
54
+ }),
55
+ );
56
+ }
57
+
58
+ export function NodeOutputSummary({ node, nodeType }: Props) {
59
+ const { t } = useTranslation('workflow');
60
+ const branches = resolveOutputs(node, nodeType);
61
+ const dynamicOutputKey = DYNAMIC_OUTPUT_KEYS[node.type];
62
+ const fields = dynamicOutputKey
63
+ ? []
64
+ : outputFields((nodeType?.outputSchema ?? {}) as Record<string, any>);
65
+ const schemaDescription =
66
+ typeof nodeType?.outputSchema?.description === 'string'
67
+ ? nodeType.outputSchema.description
68
+ : undefined;
69
+
70
+ const branchLabel = (branch: string) => {
71
+ if (node.type === 'external_wait') {
72
+ return branch === 'RECEIVED'
73
+ ? t('editor.output.branchLabels.received')
74
+ : t('editor.output.branchLabels.timedOut');
75
+ }
76
+ if (node.type === 'approval' || node.type === 'human_approval') {
77
+ return branch === 'true'
78
+ ? t('editor.output.branchLabels.approved')
79
+ : t('editor.output.branchLabels.rejected');
80
+ }
81
+ if (node.type === 'if_else') {
82
+ return branch === 'true'
83
+ ? t('editor.output.branchLabels.matched')
84
+ : t('editor.output.branchLabels.notMatched');
85
+ }
86
+ return branch;
87
+ };
88
+
89
+ return (
90
+ <section
91
+ aria-label={t('editor.output.title')}
92
+ style={{
93
+ border: '1px solid var(--ant-color-border-secondary)',
94
+ borderRadius: 8,
95
+ overflow: 'hidden',
96
+ background: 'var(--ant-color-fill-quaternary)',
97
+ }}
98
+ >
99
+ <div
100
+ style={{
101
+ padding: '10px 12px',
102
+ borderBottom: '1px solid var(--ant-color-border-secondary)',
103
+ background: 'var(--ant-color-bg-container)',
104
+ }}
105
+ >
106
+ <Text strong style={{ fontSize: 13 }}>
107
+ {t('editor.output.title')}
108
+ </Text>
109
+ <Text
110
+ type="secondary"
111
+ style={{ display: 'block', marginTop: 2, fontSize: 11 }}
112
+ >
113
+ {t('editor.output.hint')}
114
+ </Text>
115
+ </div>
116
+
117
+ <div style={{ padding: '10px 12px' }}>
118
+ {branches.length > 1 && (
119
+ <div style={{ marginBottom: fields.length > 0 ? 10 : 0 }}>
120
+ <Text
121
+ type="secondary"
122
+ style={{ display: 'block', marginBottom: 6, fontSize: 11 }}
123
+ >
124
+ {t('editor.output.flowBranches')}
125
+ </Text>
126
+ <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6 }}>
127
+ {branches.map((branch) => (
128
+ <Tag key={branch} color="blue" style={{ marginInlineEnd: 0 }}>
129
+ {branchLabel(branch)}
130
+ </Tag>
131
+ ))}
132
+ </div>
133
+ </div>
134
+ )}
135
+
136
+ {fields.length > 0 ? (
137
+ <div
138
+ style={{
139
+ display: 'grid',
140
+ gap: 1,
141
+ borderRadius: 6,
142
+ overflow: 'hidden',
143
+ background: 'var(--ant-color-border-secondary)',
144
+ }}
145
+ >
146
+ {fields.map((field) => (
147
+ <div
148
+ key={field.path}
149
+ style={{
150
+ display: 'grid',
151
+ gridTemplateColumns: 'minmax(0, 1fr) auto',
152
+ gap: 8,
153
+ alignItems: 'center',
154
+ padding: '7px 9px',
155
+ background: 'var(--ant-color-bg-container)',
156
+ }}
157
+ >
158
+ <div style={{ minWidth: 0 }}>
159
+ <Text
160
+ code
161
+ style={{ display: 'block', fontSize: 11, margin: 0 }}
162
+ >
163
+ {field.path}
164
+ </Text>
165
+ {field.description && (
166
+ <Text
167
+ type="secondary"
168
+ ellipsis={{ tooltip: field.description }}
169
+ style={{ display: 'block', marginTop: 2, fontSize: 11 }}
170
+ >
171
+ {field.description}
172
+ </Text>
173
+ )}
174
+ </div>
175
+ <div style={{ display: 'flex', alignItems: 'center', gap: 4 }}>
176
+ {field.required && (
177
+ <Text type="secondary" style={{ fontSize: 10 }}>
178
+ {t('editor.output.required')}
179
+ </Text>
180
+ )}
181
+ <Tag bordered={false} style={{ marginInlineEnd: 0 }}>
182
+ {t(`editor.output.types.${field.type}`, {
183
+ defaultValue: field.type,
184
+ })}
185
+ </Tag>
186
+ </div>
187
+ </div>
188
+ ))}
189
+ </div>
190
+ ) : (
191
+ <Text type="secondary" style={{ fontSize: 12 }}>
192
+ {dynamicOutputKey
193
+ ? t(`editor.output.dynamic.${dynamicOutputKey}`)
194
+ : schemaDescription || t('editor.output.dynamic.anyValue')}
195
+ </Text>
196
+ )}
197
+ </div>
198
+ </section>
199
+ );
200
+ }
@@ -54,6 +54,7 @@ describe('NodePropertyPanel instance references', () => {
54
54
  it('renders a referenced node with the editable template config form', async () => {
55
55
  vi.mocked(customRequest).mockImplementation((path) => {
56
56
  if (path === 'subject-providers') return Promise.resolve([]) as never;
57
+ if (path === 'workflow/callable') return Promise.resolve([]) as never;
57
58
  return Promise.resolve({
58
59
  data: [
59
60
  {
@@ -88,8 +89,14 @@ describe('NodePropertyPanel instance references', () => {
88
89
  });
89
90
  expect(screen.getByText('Who can approve')).toBeInTheDocument();
90
91
  expect(
91
- screen.getByText('修改只会保存在当前 Workflow,不会修改 Node Template。'),
92
+ screen.getByText('Changes apply only to this Workflow.'),
92
93
  ).toBeInTheDocument();
94
+ expect(
95
+ screen.getByRole('heading', { name: 'Node configuration' }),
96
+ ).toBeInTheDocument();
97
+ expect(screen.getByText('Node type')).toBeInTheDocument();
98
+ expect(screen.getByText('Human Approval')).toBeInTheDocument();
99
+ expect(screen.queryByText('approval')).not.toBeInTheDocument();
93
100
  expect(
94
101
  screen.getByRole('button', { name: 'Save changes' }),
95
102
  ).toBeInTheDocument();
@@ -99,22 +106,19 @@ describe('NodePropertyPanel instance references', () => {
99
106
  const returnNodeType = {
100
107
  id: '9',
101
108
  type: 'return_result',
102
- label: 'Return result',
109
+ label: 'Finish and return',
103
110
  category: 'ACTION',
104
111
  instancePolicy: 'INLINE_ONLY',
105
112
  configSchema: {
106
113
  type: 'object',
107
- properties: {
108
- resultType: { type: 'string' },
109
- path: { type: 'string' },
110
- },
114
+ properties: {},
111
115
  },
112
116
  uiSchema: {},
113
117
  } as unknown as WorkflowNodeType;
114
118
  const returnNode: WorkflowNode = {
115
119
  id: 'return-1',
116
120
  type: 'return_result',
117
- label: 'Return result',
121
+ label: 'Finish and return',
118
122
  position: { x: 0, y: 0 },
119
123
  config: {},
120
124
  };
@@ -131,9 +135,57 @@ describe('NodePropertyPanel instance references', () => {
131
135
  );
132
136
 
133
137
  expect(
134
- screen.getByText('Return the previous node result'),
138
+ screen.getByText('Returns the previous node result'),
135
139
  ).toBeInTheDocument();
136
- expect(screen.queryByLabelText('Workflow data field')).toBeNull();
140
+ expect(screen.queryByText('Result type')).toBeNull();
141
+ });
142
+
143
+ it('shows the node output contract as read-only input paths', () => {
144
+ const httpNodeType = {
145
+ id: '10',
146
+ type: 'http_request',
147
+ label: 'HTTP Request',
148
+ category: 'ACTION',
149
+ instancePolicy: 'INLINE_ONLY',
150
+ configSchema: { type: 'object', properties: {} },
151
+ outputSchema: {
152
+ type: 'object',
153
+ properties: {
154
+ status: { type: 'number', description: 'HTTP status code' },
155
+ data: { description: 'Response body' },
156
+ headers: { type: 'object' },
157
+ },
158
+ },
159
+ outputs: [],
160
+ uiSchema: {},
161
+ } as unknown as WorkflowNodeType;
162
+ const httpNode: WorkflowNode = {
163
+ id: 'http-1',
164
+ type: 'http_request',
165
+ label: 'Create order',
166
+ position: { x: 0, y: 0 },
167
+ config: {},
168
+ };
169
+
170
+ render(
171
+ <NodePropertyPanel
172
+ node={httpNode}
173
+ nodeTypes={[httpNodeType]}
174
+ onSave={vi.fn()}
175
+ onLabelChange={vi.fn()}
176
+ onAiEdit={vi.fn()}
177
+ aiLoading={false}
178
+ />,
179
+ );
180
+
181
+ expect(
182
+ screen.getByRole('region', { name: 'Output (read-only)' }),
183
+ ).toBeInTheDocument();
184
+ expect(screen.getByText('input.status')).toBeInTheDocument();
185
+ expect(screen.getByText('input.data')).toBeInTheDocument();
186
+ expect(screen.getByText('input.headers')).toBeInTheDocument();
187
+ expect(screen.getByText('HTTP status code')).toBeInTheDocument();
188
+ expect(screen.getByText('Any value')).toBeInTheDocument();
137
189
  });
138
190
 
139
191
  it('uses nested UI Schema widgets for Callable Trigger parameters', async () => {
@@ -205,131 +257,4 @@ describe('NodePropertyPanel instance references', () => {
205
257
  }),
206
258
  );
207
259
  });
208
-
209
- it('does not carry Code configuration into Submit External Result when switching nodes', async () => {
210
- const user = userEvent.setup();
211
- const onSave = vi.fn();
212
- const codeNodeType = {
213
- id: 'code',
214
- type: 'code',
215
- label: 'Code',
216
- category: 'ACTION',
217
- instancePolicy: 'INLINE_ONLY',
218
- configSchema: {
219
- type: 'object',
220
- properties: {
221
- mode: { type: 'string' },
222
- script: { type: 'string' },
223
- timeout: { type: 'integer' },
224
- },
225
- },
226
- uiSchema: { widget: 'code-config' },
227
- } as unknown as WorkflowNodeType;
228
- const submitNodeType = {
229
- id: 'submit-external-result',
230
- type: 'submit_external_result',
231
- label: 'Submit external result',
232
- category: 'ACTION',
233
- instancePolicy: 'INLINE_ONLY',
234
- configSchema: {
235
- type: 'object',
236
- properties: {
237
- inputBindings: { type: 'object' },
238
- },
239
- },
240
- uiSchema: { widget: 'submit-external-result-config' },
241
- } as unknown as WorkflowNodeType;
242
- const codeNode: WorkflowNode = {
243
- id: 'code-1',
244
- type: 'code',
245
- label: 'Transform callback',
246
- position: { x: 0, y: 0 },
247
- config: {
248
- mode: 'runOnceForAll',
249
- script: 'return input;',
250
- timeout: 1000,
251
- },
252
- };
253
- const inputBindings = {
254
- callbackToken: { source: 'INPUT' as const, path: 'callbackToken' },
255
- eventId: { source: 'INPUT' as const, path: 'eventId' },
256
- outcome: { source: 'INPUT' as const, path: 'outcome' },
257
- };
258
- const submitNode: WorkflowNode = {
259
- id: 'submit-1',
260
- type: 'submit_external_result',
261
- label: 'Submit external result',
262
- position: { x: 100, y: 0 },
263
- config: { inputBindings },
264
- };
265
- const nodeTypes = [codeNodeType, submitNodeType];
266
- const commonProps = {
267
- nodeTypes,
268
- onSave,
269
- onLabelChange: vi.fn(),
270
- onAiEdit: vi.fn(),
271
- aiLoading: false,
272
- };
273
-
274
- const { rerender } = render(
275
- <NodePropertyPanel {...commonProps} node={codeNode} />,
276
- );
277
-
278
- rerender(<NodePropertyPanel {...commonProps} node={submitNode} />);
279
- await user.click(screen.getByRole('button', { name: 'Save changes' }));
280
-
281
- expect(onSave).toHaveBeenLastCalledWith('submit-1', {
282
- label: 'Submit external result',
283
- config: { inputBindings },
284
- });
285
- });
286
-
287
- it('hides legacy trigger and approval callback nodes from the palette', () => {
288
- render(
289
- <NodePropertyPanel
290
- node={null}
291
- nodeTypes={
292
- [
293
- {
294
- id: 'callable',
295
- type: 'callable_trigger',
296
- label: '接收调用',
297
- category: 'TRIGGER',
298
- },
299
- {
300
- id: 'legacy-approval',
301
- type: 'approval_request_trigger',
302
- label: '接收审批请求',
303
- category: 'TRIGGER',
304
- },
305
- {
306
- id: 'webhook',
307
- type: 'webhook_trigger',
308
- label: 'Webhook Trigger',
309
- category: 'TRIGGER',
310
- },
311
- {
312
- id: 'submit-result',
313
- type: 'submit_approval_result',
314
- label: 'Submit approval result',
315
- category: 'ACTION',
316
- },
317
- ] as WorkflowNodeType[]
318
- }
319
- onSave={vi.fn()}
320
- onLabelChange={vi.fn()}
321
- onAiEdit={vi.fn()}
322
- aiLoading={false}
323
- />,
324
- );
325
-
326
- expect(screen.getByText('Receive call')).toBeInTheDocument();
327
- expect(
328
- screen.queryByText('Receive approval request'),
329
- ).not.toBeInTheDocument();
330
- expect(screen.getByText('Receive external request')).toBeInTheDocument();
331
- expect(
332
- screen.queryByText('Submit approval result'),
333
- ).not.toBeInTheDocument();
334
- });
335
260
  });