@gadmin2n/schematics 0.0.142 → 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 (139) 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/src/components/PageHeader.tsx +1 -1
  64. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/agentPanel/inspectorActions.ts +19 -19
  65. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/contexts/color-mode/index.tsx +1 -1
  66. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/layout/header.tsx +15 -11
  67. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/config/routeRegistry.tsx +0 -6
  68. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/dev-shell/AddDataModal.tsx +3 -3
  69. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/dev-shell/AddPageModal.tsx +1 -1
  70. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/dev-shell/DeleteDataConfirm.tsx +1 -1
  71. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/dev-shell/EditDataModal.tsx +1 -1
  72. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/hooks/useDynamicResources.tsx +1 -0
  73. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/locales/en/workflow.json +85 -95
  74. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/locales/zh_CN/workflow.json +85 -95
  75. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/agenda/index.tsx +2 -2
  76. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/agendaJob/list.tsx +21 -2
  77. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/game/list.tsx +21 -2
  78. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/human-approval/inbox.tsx +14 -66
  79. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/page/list.tsx +4 -4
  80. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/resource/list.tsx +3 -3
  81. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/role/list.tsx +3 -3
  82. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/CustomNode.test.tsx +29 -0
  83. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/CustomNode.tsx +4 -2
  84. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/EnhancedFlowRenderer.tsx +4 -6
  85. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/ExecutionStatusNode.test.tsx +3 -0
  86. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/ExecutionStatusNode.tsx +3 -1
  87. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/FlowRenderer.tsx +4 -6
  88. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/NewNodeDefaults.test.tsx +23 -92
  89. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/NodeOutputSummary.tsx +200 -0
  90. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/NodePropertyPanel.test.tsx +61 -136
  91. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/NodePropertyPanel.tsx +96 -195
  92. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/NodeTypeBadge.tsx +36 -0
  93. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/components/CreateNodeInstanceModal.tsx +5 -10
  94. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/components/NodeInstanceForm.tsx +47 -22
  95. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/create.tsx +7 -5
  96. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/edit.tsx +8 -6
  97. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/node-config.css +35 -0
  98. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/schema-form/default-widgets.tsx +1 -6
  99. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/ApproverSourceEditor.tsx +1 -4
  100. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/CodeConfigEditor.tsx +1 -1
  101. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/ExternalRequestConfigEditor.tsx +1 -1
  102. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/ExternalWaitConfigEditor.tsx +82 -259
  103. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/HttpRequestConfigEditor.tsx +1 -2
  104. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/HumanApprovalConfigEditor.test.tsx +7 -6
  105. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/HumanApprovalConfigEditor.tsx +77 -71
  106. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/ReturnResultConfigEditor.test.tsx +10 -57
  107. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/ReturnResultConfigEditor.tsx +8 -273
  108. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/temporal-tenant/index.test.tsx +54 -0
  109. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/temporal-tenant/index.tsx +110 -20
  110. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/newNodeConfig.ts +4 -34
  111. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/resolveOutputs.test.ts +3 -10
  112. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/resolveOutputs.ts +2 -37
  113. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflowEventOutbox/list.tsx +26 -2
  114. package/package.json +1 -1
  115. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/approvalChannel/approval-channel.controller.ts +0 -89
  116. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/approvalChannel/approval-channel.dto.ts +0 -68
  117. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/approvalChannel/approval-channel.service.spec.ts +0 -177
  118. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/approvalChannel/approval-channel.service.ts +0 -283
  119. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/approvalChannel/approvalChannel.module.ts +0 -10
  120. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/approval-channels/ApprovalChannelModal.test.tsx +0 -84
  121. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/approval-channels/ApprovalChannelModal.tsx +0 -141
  122. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/approval-channels/approval-channel.types.ts +0 -16
  123. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/approval-channels/index.tsx +0 -210
  124. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/ApprovalRequestTriggerConfigEditor.tsx +0 -39
  125. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/SubmitApprovalResultConfigEditor.tsx +0 -104
  126. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/SubmitExternalResultConfigEditor.tsx +0 -98
  127. /package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/page/{Components → components}/AssignRolesModal.tsx +0 -0
  128. /package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/page/{Components → components}/CreatePageModal.tsx +0 -0
  129. /package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/page/{Components → components}/EditPageModal.tsx +0 -0
  130. /package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/page/{Components → components}/PageDetailDrawer.tsx +0 -0
  131. /package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/page/{Components → components}/PageFormModal.tsx +0 -0
  132. /package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/resource/{Components → components}/CreateModal.tsx +0 -0
  133. /package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/resource/{Components → components}/EditModal.tsx +0 -0
  134. /package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/resource/{Components → components}/ResourceDetailDrawer.tsx +0 -0
  135. /package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/resource/{Components → components}/modal.tsx +0 -0
  136. /package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/role/{Components → components}/CreateModal.tsx +0 -0
  137. /package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/role/{Components → components}/EditModal.tsx +0 -0
  138. /package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/role/{Components → components}/RoleDetailDrawer.tsx +0 -0
  139. /package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/role/{Components → components}/modal.tsx +0 -0
@@ -18,7 +18,6 @@ import {
18
18
  Space,
19
19
  Spin,
20
20
  Switch,
21
- Tag,
22
21
  Tooltip,
23
22
  Typography,
24
23
  } from 'antd';
@@ -32,7 +31,9 @@ import type {
32
31
  WorkflowNodeType,
33
32
  } from '../types';
34
33
  import type { ParameterBinding } from '../types/parameter-binding';
34
+ import { NodeOutputSummary } from './NodeOutputSummary';
35
35
  import { ParameterBindingEditor } from './ParameterBindingEditor';
36
+ import '../node-instances/node-config.css';
36
37
 
37
38
  const { Text, Title } = Typography;
38
39
  const { TextArea } = Input;
@@ -41,20 +42,18 @@ const CATEGORY_COLORS: Record<string, { bg: string; border: string }> = {
41
42
  TRIGGER: { bg: '#e6f7ff', border: '#91caff' },
42
43
  ACTION: { bg: '#f6ffed', border: '#b7eb8f' },
43
44
  CONDITION: { bg: '#fff7e6', border: '#ffd591' },
44
- LOOP: { bg: '#f9f0ff', border: '#d3adf7' },
45
- FLOW_CONTROL: { bg: '#f0f5ff', border: '#adc6ff' },
45
+ FLOW_CONTROL: { bg: '#f9f0ff', border: '#d3adf7' },
46
46
  APPROVAL: { bg: '#fff1f0', border: '#ffa39e' },
47
47
  SUB_WORKFLOW: { bg: '#f0f5ff', border: '#adc6ff' },
48
48
  };
49
49
 
50
50
  const CATEGORY_LABELS: Record<string, string> = {
51
- TRIGGER: '触发器',
52
- ACTION: '动作',
53
- CONDITION: '条件',
54
- LOOP: '循环',
51
+ TRIGGER: '触发流程',
52
+ ACTION: '执行操作',
53
+ CONDITION: '判断与分支',
55
54
  FLOW_CONTROL: '流程控制',
56
- APPROVAL: '审批',
57
- SUB_WORKFLOW: '子流程',
55
+ APPROVAL: '人工审批',
56
+ SUB_WORKFLOW: 'Workflow 调用',
58
57
  };
59
58
 
60
59
  // Fields that should use TextArea for longer input
@@ -69,7 +68,6 @@ const TEXTAREA_FIELDS = new Set([
69
68
  'rawSql',
70
69
  'data',
71
70
  'responseBody',
72
- 'fallbackExpression',
73
71
  ]);
74
72
 
75
73
  function hasUiSchemaWidget(value: unknown): boolean {
@@ -87,110 +85,6 @@ function hasUiSchemaWidget(value: unknown): boolean {
87
85
  );
88
86
  }
89
87
 
90
- // Rich tooltip content for node types (hardcoded)
91
- const NODE_TOOLTIPS: Record<string, string> = {
92
- cron_trigger:
93
- '定时触发工作流\n' +
94
- '━━━━━━━━━━━━━━━━━━━━\n' +
95
- '示例: 每天零点生成日报、每5分钟检查队列、每月1号结算\n' +
96
- 'Temporal: ScheduleClient 创建定时 Schedule,到点启动 Workflow',
97
- event_trigger:
98
- '监听内部业务事件,事件发生时自动触发\n' +
99
- '━━━━━━━━━━━━━━━━━━━━\n' +
100
- '事件类别:\n' +
101
- '• 数据变更: record.created, record.updated\n' +
102
- '• 状态变更: order.paid, ticket.escalated\n' +
103
- '• 用户行为: user.registered, login_failed_3x\n' +
104
- '• 系统事件: deployment.completed, health_check.failed\n' +
105
- '━━━━━━━━━━━━━━━━━━━━\n' +
106
- 'Temporal: 事件总线收到事件后调用 WorkflowClient.start() 启动新 Workflow,或通过 Signal 唤醒等待中的 Workflow\n\n' +
107
- '通常后端会有一个事件总线(如 Redis Pub/Sub、NATS、Kafka、或简单的内存 EventEmitter),当业务代码 emit("order.paid", payload)时,事件中间件查找所有订阅了该事件的 active workflow 定义,并启动对应的 Temporal Workflow。',
108
- webhook_trigger:
109
- '接收外部 HTTP 请求并启动 Workflow\n' +
110
- '━━━━━━━━━━━━━━━━━━━━\n' +
111
- '示例: 第三方支付回调、GitHub Webhook、表单提交\n' +
112
- '收到的请求体、查询参数和请求头分别放在 workflow.body、workflow.query 和 workflow.headers',
113
- submit_approval_result:
114
- '提交外部审批结果\n' +
115
- '━━━━━━━━━━━━━━━━━━━━\n' +
116
- '把 requestId、审批人和审批决定提交给正在等待的人工审核节点',
117
- manual_trigger:
118
- '手动触发,用于调试或一次性执行\n' +
119
- '━━━━━━━━━━━━━━━━━━━━\n' +
120
- '示例: 手动跑数据迁移、调试新 Workflow、一次性批处理\n' +
121
- 'Temporal: 直接调用 WorkflowClient.start() 并传入自定义 input',
122
- http_request:
123
- '向外部 API 发送 HTTP 请求\n' +
124
- '━━━━━━━━━━━━━━━━━━━━\n' +
125
- '示例: 调用第三方 API、推送数据到下游系统、获取外部数据\n' +
126
- 'Temporal: 封装为 Activity,自带超时和重试策略',
127
- db_query:
128
- '执行数据库查询(读操作)\n' +
129
- '━━━━━━━━━━━━━━━━━━━━\n' +
130
- '示例: 查询订单状态、获取用户列表、统计聚合\n' +
131
- 'Temporal: 封装为 Activity,支持参数化查询防注入',
132
- db_execute:
133
- '执行数据库写操作\n' +
134
- '━━━━━━━━━━━━━━━━━━━━\n' +
135
- '示例: 插入审批记录、更新订单状态、批量删除过期数据\n' +
136
- 'Temporal: 封装为 Activity,失败时 Workflow 可选择重试或补偿',
137
- send_notification:
138
- '发送通知消息\n' +
139
- '━━━━━━━━━━━━━━━━━━━━\n' +
140
- '示例: 审批结果邮件、Slack 告警、企微/钉钉群消息\n' +
141
- 'Temporal: 封装为 Activity,支持模板变量和多渠道',
142
- code:
143
- '执行自定义 JavaScript 代码\n' +
144
- '━━━━━━━━━━━━━━━━━━━━\n' +
145
- '示例: 数据格式转换、复杂计算、JSON 结构重组、条件逻辑\n' +
146
- 'Temporal: 封装为 Activity,通过应用侧受限 Code Runtime 执行',
147
- set_variable:
148
- '设置、转换或重命名工作流变量\n' +
149
- '━━━━━━━━━━━━━━━━━━━━\n' +
150
- '示例: 提取嵌套字段、重命名 API 返回字段、构造下游所需结构\n' +
151
- 'Temporal: 读取 input,并把结果传给下一个节点',
152
- if_else:
153
- '根据条件走不同分支\n' +
154
- '━━━━━━━━━━━━━━━━━━━━\n' +
155
- '示例: 金额>1万走人工审批、VIP用户走快速通道\n' +
156
- 'Temporal: Workflow 代码中的 if/else 控制流',
157
- switch:
158
- '根据字段值走多路分支\n' +
159
- '━━━━━━━━━━━━━━━━━━━━\n' +
160
- '示例: 按订单类型分发、按地区选择处理逻辑\n' +
161
- 'Temporal: Workflow 代码中的 switch/case 控制流',
162
- for_each:
163
- '遍历数组,对每个元素执行子流程\n' +
164
- '━━━━━━━━━━━━━━━━━━━━\n' +
165
- '示例: 批量发送通知、逐个处理订单项、并行调用多个 API\n' +
166
- 'Temporal: 循环内启动 Activity 或 Child Workflow,支持并行控制',
167
- delay:
168
- '暂停工作流执行,等待指定时间或信号\n' +
169
- '━━━━━━━━━━━━━━━━━━━━\n' +
170
- '示例: 等待30分钟后发提醒、等到指定时间执行、等待外部回调\n' +
171
- 'Temporal: workflow.sleep()(持久化定时器,服务重启不丢失)',
172
- parallel:
173
- '并行执行多个分支,等待完成后合并\n' +
174
- '━━━━━━━━━━━━━━━━━━━━\n' +
175
- '示例: 同时调用多个 API 聚合结果、并行审批多个部门\n' +
176
- 'Temporal: Promise.all() 并行启动多个 Activity/Child Workflow',
177
- error_handler:
178
- '捕获上游节点错误,执行降级逻辑\n' +
179
- '━━━━━━━━━━━━━━━━━━━━\n' +
180
- '示例: API 失败后走备用方案、超时后发告警通知\n' +
181
- 'Temporal: try/catch + RetryPolicy(支持固定/指数退避重试)',
182
- approval:
183
- '暂停流程等待人工审批\n' +
184
- '━━━━━━━━━━━━━━━━━━━━\n' +
185
- '示例: 费用报销审批、上线发布审批、权限申请审批\n' +
186
- 'Temporal: workflow.condition() 等待 Signal,审批人通过 SignalWorkflow 发送结果',
187
- sub_workflow:
188
- '调用另一个已定义的工作流作为子流程\n' +
189
- '━━━━━━━━━━━━━━━━━━━━\n' +
190
- '示例: 复用通用审批流程、嵌套调用数据处理 Pipeline\n' +
191
- 'Temporal: executeChild() 启动 Child Workflow,支持同步等待或异步触发',
192
- };
193
-
194
88
  // Placeholder hints for specific fields
195
89
  const FIELD_PLACEHOLDERS: Record<string, string> = {
196
90
  cron: '0 0 * * * (每天零点)',
@@ -201,7 +95,6 @@ const FIELD_PLACEHOLDERS: Record<string, string> = {
201
95
  query: 'SELECT * FROM table WHERE id = $1',
202
96
  rawSql: 'INSERT INTO table (col) VALUES ($1)',
203
97
  condition: 'data.amount > 1000',
204
- fallbackExpression: 'data.status === "active"',
205
98
  iteratorField: 'data.items',
206
99
  message: '通知内容,支持 {{variable}} 模板变量',
207
100
  subject: '邮件主题',
@@ -212,8 +105,6 @@ const FIELD_PLACEHOLDERS: Record<string, string> = {
212
105
  table: '表名',
213
106
  where: 'id = $1',
214
107
  datasource: 'default',
215
- signalName: 'approval_signal',
216
- gotoNodeId: '目标节点 ID',
217
108
  };
218
109
 
219
110
  interface Props {
@@ -247,7 +138,7 @@ export function NodePropertyPanel({
247
138
  onAbort,
248
139
  aiLoading,
249
140
  }: Props) {
250
- const { t } = useTranslation('workflow');
141
+ const { t, i18n } = useTranslation('workflow');
251
142
  const [label, setLabel] = useState('');
252
143
  const [config, setConfig] = useState<Record<string, any>>({});
253
144
  const [prompt, setPrompt] = useState('');
@@ -277,6 +168,14 @@ export function NodePropertyPanel({
277
168
 
278
169
  // Find configSchema for current node type
279
170
  const currentNodeType = nodeTypes.find((nt) => nt.type === node?.type);
171
+ const currentNodeTypeLabel = currentNodeType
172
+ ? t(`nodeTypes.${currentNodeType.type}`, {
173
+ defaultValue: currentNodeType.label,
174
+ })
175
+ : node?.type;
176
+ const currentNodeTypeColors =
177
+ CATEGORY_COLORS[currentNodeType?.category ?? 'ACTION'] ??
178
+ CATEGORY_COLORS.ACTION;
280
179
  const configSchema = (currentNodeType?.configSchema || {}) as any;
281
180
  const requiredFields: string[] = configSchema.required || [];
282
181
  const properties: Record<string, any> = configSchema.properties || {};
@@ -311,18 +210,6 @@ export function NodePropertyPanel({
311
210
  widget: 'external-request-config',
312
211
  };
313
212
  }
314
- if (currentNodeType?.type === 'submit_approval_result') {
315
- return {
316
- ...currentUiSchema,
317
- widget: 'submit-approval-result-config',
318
- };
319
- }
320
- if (currentNodeType?.type === 'submit_external_result') {
321
- return {
322
- ...currentUiSchema,
323
- widget: 'submit-external-result-config',
324
- };
325
- }
326
213
  if (currentNodeType?.type === 'external_wait') {
327
214
  return {
328
215
  ...currentUiSchema,
@@ -499,18 +386,12 @@ export function NodePropertyPanel({
499
386
  拖拽节点到左侧画布
500
387
  </Text>
501
388
  {Object.entries(
502
- nodeTypes
503
- .filter(
504
- (nt) =>
505
- nt.type !== 'approval_request_trigger' &&
506
- nt.type !== 'submit_approval_result',
507
- )
508
- .reduce<Record<string, WorkflowNodeType[]>>((acc, nt) => {
509
- const cat = nt.category || 'ACTION';
510
- if (!acc[cat]) acc[cat] = [];
511
- acc[cat].push(nt);
512
- return acc;
513
- }, {}),
389
+ nodeTypes.reduce<Record<string, WorkflowNodeType[]>>((acc, nt) => {
390
+ const cat = nt.category || 'ACTION';
391
+ if (!acc[cat]) acc[cat] = [];
392
+ acc[cat].push(nt);
393
+ return acc;
394
+ }, {}),
514
395
  ).map(([category, types]) => {
515
396
  const colors = CATEGORY_COLORS[category] || CATEGORY_COLORS.ACTION;
516
397
  return (
@@ -538,12 +419,12 @@ export function NodePropertyPanel({
538
419
  lineHeight: 1.6,
539
420
  }}
540
421
  >
541
- {NODE_TOOLTIPS[nt.type] || nt.description || nt.label}
422
+ {nt.description || nt.label}
542
423
  </div>
543
424
  }
544
425
  placement="left"
545
426
  mouseEnterDelay={0.3}
546
- overlayStyle={{ maxWidth: 360 }}
427
+ styles={{ root: { maxWidth: 320 } }}
547
428
  >
548
429
  <div
549
430
  draggable
@@ -705,13 +586,11 @@ export function NodePropertyPanel({
705
586
  const value = config[key];
706
587
  const placeholder = FIELD_PLACEHOLDERS[key] || '';
707
588
  const fieldLabel =
708
- node?.type === 'sub_workflow'
709
- ? ({
710
- workflowId: '调用哪个 Workflow',
711
- waitForCompletion: '等待它运行完成',
712
- timeout: '最长等待时间(秒)',
713
- }[key] ?? key)
714
- : key;
589
+ i18n.resolvedLanguage === 'zh_CN'
590
+ ? t(`schema.fields.${key}`, {
591
+ defaultValue: schema.title ?? key,
592
+ })
593
+ : (schema.title ?? key);
715
594
 
716
595
  // Special: workflowId → Select with workflow list
717
596
  if (key === 'workflowId') {
@@ -1064,8 +943,12 @@ export function NodePropertyPanel({
1064
943
 
1065
944
  return (
1066
945
  <div
946
+ className="workflow-node-config"
1067
947
  style={{
1068
- width: usesCustomConfigEditor ? 520 : 320,
948
+ width:
949
+ usesCustomConfigEditor && currentNodeType?.type !== 'return_result'
950
+ ? 500
951
+ : 360,
1069
952
  borderLeft: '1px solid var(--ant-color-border-secondary)',
1070
953
  background: 'var(--ant-color-bg-container)',
1071
954
  display: 'flex',
@@ -1083,18 +966,36 @@ export function NodePropertyPanel({
1083
966
  alignItems: 'flex-start',
1084
967
  }}
1085
968
  >
1086
- <Space direction="vertical" size={4}>
969
+ <Space direction="vertical" size={8} style={{ minWidth: 0 }}>
1087
970
  <Title level={5} style={{ margin: 0, fontSize: 14 }}>
1088
- 节点属性
971
+ {t('editor.nodeConfiguration')}
1089
972
  </Title>
1090
- <Tag color="blue">{node.type}</Tag>
973
+ <div
974
+ style={{
975
+ minWidth: 180,
976
+ padding: '7px 10px',
977
+ background: currentNodeTypeColors.bg,
978
+ border: `1px solid ${currentNodeTypeColors.border}`,
979
+ borderRadius: 6,
980
+ }}
981
+ >
982
+ <Text
983
+ type="secondary"
984
+ style={{ display: 'block', fontSize: 11, lineHeight: 1.2 }}
985
+ >
986
+ {t('editor.nodeType')}
987
+ </Text>
988
+ <Text strong style={{ display: 'block', marginTop: 2 }}>
989
+ {currentNodeTypeLabel}
990
+ </Text>
991
+ </div>
1091
992
  </Space>
1092
993
  <Button
1093
994
  type="text"
1094
995
  danger
1095
996
  icon={<DeleteOutlined />}
1096
997
  onClick={() => onDelete?.(node.id)}
1097
- title="删除节点"
998
+ title={t('editor.deleteNode')}
1098
999
  />
1099
1000
  </div>
1100
1001
 
@@ -1109,8 +1010,8 @@ export function NodePropertyPanel({
1109
1010
  value={activeTab}
1110
1011
  onChange={(val) => setActiveTab(val as 'config' | 'ai')}
1111
1012
  options={[
1112
- { label: '节点配置', value: 'config' },
1113
- { label: 'AI 生成', value: 'ai' },
1013
+ { label: t('editor.configurationTab'), value: 'config' },
1014
+ { label: t('editor.aiEditTab'), value: 'ai' },
1114
1015
  ]}
1115
1016
  block
1116
1017
  style={{ marginBottom: 12 }}
@@ -1120,7 +1021,17 @@ export function NodePropertyPanel({
1120
1021
  {/* Form */}
1121
1022
  <div style={{ flex: 1, overflow: 'auto', padding: 16 }}>
1122
1023
  {activeTab === 'config' && (
1123
- <Space direction="vertical" size={12} style={{ width: '100%' }}>
1024
+ <Space direction="vertical" size={14} style={{ width: '100%' }}>
1025
+ <div>
1026
+ <Text className="workflow-node-config__section-title">
1027
+ {t('editor.nodeName')}
1028
+ </Text>
1029
+ <Input
1030
+ value={label}
1031
+ onChange={(e) => handleLabelChange(e.target.value)}
1032
+ />
1033
+ </div>
1034
+
1124
1035
  {/* Instance Selector / Reference Banner */}
1125
1036
  {currentNodeType?.instancePolicy !== 'INLINE_ONLY' &&
1126
1037
  !node.instanceRef && (
@@ -1135,17 +1046,17 @@ export function NodePropertyPanel({
1135
1046
  type="secondary"
1136
1047
  style={{ fontSize: 12, display: 'block', marginBottom: 6 }}
1137
1048
  >
1138
- 复用已有实例
1049
+ {t('editor.reuseInstance')}
1139
1050
  </Text>
1140
1051
  <Select
1141
1052
  value={selectedInstanceId ?? undefined}
1142
1053
  onChange={(v) => setSelectedInstanceId(v)}
1143
1054
  placeholder={
1144
1055
  instanceLoading
1145
- ? '加载中...'
1056
+ ? t('editor.loadingInstances')
1146
1057
  : instances.length === 0
1147
- ? '暂无可用实例'
1148
- : '选择实例...'
1058
+ ? t('editor.noInstances')
1059
+ : t('editor.selectInstance')
1149
1060
  }
1150
1061
  options={instances.map((i) => ({
1151
1062
  label: i.name,
@@ -1169,11 +1080,11 @@ export function NodePropertyPanel({
1169
1080
  icon={<LinkOutlined />}
1170
1081
  onClick={handleReferenceInstance}
1171
1082
  >
1172
- 引用实例
1083
+ {t('editor.referenceInstance')}
1173
1084
  </Button>
1174
1085
  {currentNodeType?.instancePolicy === 'OPTIONAL' && (
1175
1086
  <Button size="small" onClick={handleCopyAsTemplate}>
1176
- 复制为模板
1087
+ {t('editor.copyInstanceConfig')}
1177
1088
  </Button>
1178
1089
  )}
1179
1090
  </Space>
@@ -1192,7 +1103,8 @@ export function NodePropertyPanel({
1192
1103
  }}
1193
1104
  >
1194
1105
  <Text style={{ fontSize: 13 }}>
1195
- 🔗 引用实例: {node.instanceRef.instanceCode}
1106
+ {t('editor.referencedInstance')}:{' '}
1107
+ {node.instanceRef.instanceCode}
1196
1108
  </Text>
1197
1109
  {currentNodeType?.instancePolicy === 'OPTIONAL' && (
1198
1110
  <Button
@@ -1200,40 +1112,25 @@ export function NodePropertyPanel({
1200
1112
  icon={<DisconnectOutlined />}
1201
1113
  onClick={handleDetachReference}
1202
1114
  >
1203
- 解除引用
1115
+ {t('editor.detach')}
1204
1116
  </Button>
1205
1117
  )}
1206
1118
  </div>
1207
1119
  )}
1208
1120
  {node.instanceRef && (
1209
1121
  <Text type="secondary" style={{ fontSize: 12 }}>
1210
- 修改只会保存在当前 Workflow,不会修改 Node Template。
1122
+ {t('editor.referenceHint')}
1211
1123
  </Text>
1212
1124
  )}
1213
1125
 
1214
- {/* Label */}
1215
- <div>
1216
- <Text
1217
- strong
1218
- style={{ fontSize: 14, display: 'block', marginBottom: 4 }}
1219
- >
1220
- {t('editor.label')}
1221
- </Text>
1222
- <Input
1223
- value={label}
1224
- onChange={(e) => handleLabelChange(e.target.value)}
1225
- />
1226
- </div>
1227
-
1228
1126
  {/* Schema-driven config fields */}
1229
- {Object.keys(properties).length > 0 && (
1127
+ {(Object.keys(properties).length > 0 || usesCustomConfigEditor) && (
1230
1128
  <div>
1231
- <Text
1232
- strong
1233
- style={{ fontSize: 14, display: 'block', marginBottom: 8 }}
1234
- >
1235
- {t('editor.config')}
1236
- </Text>
1129
+ {Object.keys(properties).length > 0 && (
1130
+ <Text className="workflow-node-config__section-title">
1131
+ {t('editor.parameters')}
1132
+ </Text>
1133
+ )}
1237
1134
  {usesCustomConfigEditor ? (
1238
1135
  <Form
1239
1136
  form={configForm}
@@ -1262,6 +1159,8 @@ export function NodePropertyPanel({
1262
1159
  </div>
1263
1160
  )}
1264
1161
 
1162
+ <NodeOutputSummary node={node} nodeType={currentNodeType} />
1163
+
1265
1164
  {/* Save section */}
1266
1165
  <div>
1267
1166
  {!node.instanceRef &&
@@ -1272,7 +1171,9 @@ export function NodePropertyPanel({
1272
1171
  onChange={(e) => setAlsoSaveAsInstance(e.target.checked)}
1273
1172
  style={{ marginBottom: 8 }}
1274
1173
  >
1275
- <Text style={{ fontSize: 13 }}>同时保存为实例(模版)</Text>
1174
+ <Text style={{ fontSize: 13 }}>
1175
+ {t('editor.saveAsInstance')}
1176
+ </Text>
1276
1177
  </Checkbox>
1277
1178
  {alsoSaveAsInstance && (
1278
1179
  <Space
@@ -1283,13 +1184,13 @@ export function NodePropertyPanel({
1283
1184
  <Input
1284
1185
  value={newInstanceName}
1285
1186
  onChange={(e) => setNewInstanceName(e.target.value)}
1286
- placeholder="实例名称(必填)"
1187
+ placeholder={t('editor.instanceNamePlaceholder')}
1287
1188
  size="small"
1288
1189
  />
1289
1190
  <Input
1290
1191
  value={newInstanceDesc}
1291
1192
  onChange={(e) => setNewInstanceDesc(e.target.value)}
1292
- placeholder="描述(可选)"
1193
+ placeholder={t('common.optionalDescription')}
1293
1194
  size="small"
1294
1195
  />
1295
1196
  </Space>
@@ -1319,13 +1220,13 @@ export function NodePropertyPanel({
1319
1220
  type="secondary"
1320
1221
  style={{ fontSize: 13, display: 'block', marginBottom: 8 }}
1321
1222
  >
1322
- 描述复杂修改,AI 将更新此节点
1223
+ {t('editor.aiEditHint')}
1323
1224
  </Text>
1324
1225
  <div style={{ display: 'flex', gap: 4 }}>
1325
1226
  <TextArea
1326
1227
  value={prompt}
1327
1228
  onChange={(e) => setPrompt(e.target.value)}
1328
- placeholder="例: 将超时改为30分钟..."
1229
+ placeholder={t('editor.aiEditPlaceholder')}
1329
1230
  autoSize={{ minRows: 4, maxRows: 8 }}
1330
1231
  onPressEnter={(e) => {
1331
1232
  if (e.ctrlKey) handleAiSubmit();
@@ -1341,7 +1242,7 @@ export function NodePropertyPanel({
1341
1242
  style={{ marginTop: 8 }}
1342
1243
  block
1343
1244
  >
1344
- 发送
1245
+ {t('editor.send')}
1345
1246
  </Button>
1346
1247
  </div>
1347
1248
  )}
@@ -0,0 +1,36 @@
1
+ import { useTranslation } from 'react-i18next';
2
+
3
+ export function NodeTypeBadge({
4
+ type,
5
+ borderColor,
6
+ }: {
7
+ type?: string;
8
+ borderColor: string;
9
+ }) {
10
+ const { t } = useTranslation('workflow');
11
+ if (!type) return null;
12
+
13
+ const typeName = t(`nodeTypes.${type}`, { defaultValue: type });
14
+
15
+ return (
16
+ <div
17
+ style={{
18
+ display: 'inline-flex',
19
+ alignItems: 'center',
20
+ maxWidth: '100%',
21
+ marginBottom: 5,
22
+ padding: '1px 7px',
23
+ border: `1px solid ${borderColor}`,
24
+ borderRadius: 999,
25
+ background: 'rgba(255, 255, 255, 0.72)',
26
+ color: '#595959',
27
+ fontSize: 10,
28
+ fontWeight: 500,
29
+ lineHeight: '16px',
30
+ whiteSpace: 'nowrap',
31
+ }}
32
+ >
33
+ {t('nodeTypeBadge', { type: typeName })}
34
+ </div>
35
+ );
36
+ }
@@ -41,15 +41,11 @@ const CATEGORY_PROMPT_CONFIG: Record<
41
41
  scenarioHint:
42
42
  'This is a condition/branching node. Generate config for evaluating conditions to decide the flow path.',
43
43
  },
44
- LOOP: {
45
- placeholder: 'e.g. Iterate over the "items" array field with concurrency 3',
46
- scenarioHint:
47
- 'This is a loop node. Generate config for iterating over data collections.',
48
- },
49
44
  FLOW_CONTROL: {
50
- placeholder: 'e.g. Wait 30 seconds before proceeding to the next step',
45
+ placeholder:
46
+ 'e.g. Wait 30 seconds, iterate over items, or run branches in parallel',
51
47
  scenarioHint:
52
- 'This is a flow control node. Generate config for managing execution flow (delay, parallel, error handling).',
48
+ 'This is a flow control node. Generate config for waiting, iteration, or parallel execution.',
53
49
  },
54
50
  APPROVAL: {
55
51
  placeholder:
@@ -59,9 +55,8 @@ const CATEGORY_PROMPT_CONFIG: Record<
59
55
  },
60
56
  SUB_WORKFLOW: {
61
57
  placeholder:
62
- 'e.g. Call the "order-processing" workflow and wait for completion',
63
- scenarioHint:
64
- 'This is a sub-workflow node. Generate config for invoking another workflow as a child process.',
58
+ 'e.g. Call the "order-processing" Workflow and wait for its return value',
59
+ scenarioHint: 'This node defines or performs an internal Workflow call.',
65
60
  },
66
61
  };
67
62