@gadmin2n/schematics 0.0.144 → 0.0.145

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 (279) hide show
  1. package/dist/lib/application/files/gadmin2-game-angle-demo/config/.types.d.ts +10 -0
  2. package/dist/lib/application/files/gadmin2-game-angle-demo/config/prisma/approval.prisma +2 -0
  3. package/dist/lib/application/files/gadmin2-game-angle-demo/config/prisma/workflow.prisma +140 -19
  4. package/dist/lib/application/files/gadmin2-game-angle-demo/server/package.json +2 -2
  5. package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/data-mngt.seed.ts +0 -2
  6. package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/workflow-node-types.ts +694 -327
  7. package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/workflow-outbox.ts +57 -0
  8. package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/workflow.seed.ts +35 -5
  9. package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/workflows.ts +224 -59
  10. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/codeRuntime/code-executor.spec.ts +23 -0
  11. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/codeRuntime/code-executor.ts +16 -5
  12. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/codeRuntime/code-runtime.controller.spec.ts +98 -0
  13. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/codeRuntime/code-runtime.controller.ts +26 -6
  14. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/codeRuntime/code-runtime.dto.ts +17 -2
  15. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/externalInteraction/external-interaction-runtime.controller.spec.ts +1 -0
  16. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/externalInteraction/external-interaction-runtime.controller.ts +3 -0
  17. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/externalInteraction/external-interaction-runtime.dto.ts +0 -2
  18. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/externalInteraction/external-interaction-signal-outbox.service.spec.ts +30 -0
  19. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/externalInteraction/external-interaction-signal-outbox.service.ts +28 -6
  20. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/externalInteraction/external-interaction.service.spec.ts +63 -0
  21. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/externalInteraction/external-interaction.service.ts +151 -38
  22. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/externalInteraction/external-wait.handler.ts +4 -1
  23. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/externalInteraction/human-approval.handler.spec.ts +16 -5
  24. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/externalInteraction/human-approval.handler.ts +23 -6
  25. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/httpRequest/http-request-runtime.controller.spec.ts +130 -0
  26. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/httpRequest/http-request-runtime.controller.ts +62 -62
  27. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/httpRequest/http-request-runtime.dto.ts +15 -1
  28. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/httpRequest/http-request-runtime.util.spec.ts +70 -9
  29. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/httpRequest/http-request-runtime.util.ts +31 -7
  30. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/humanApproval/approval-signal-outbox.service.spec.ts +30 -0
  31. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/humanApproval/approval-signal-outbox.service.ts +28 -6
  32. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/humanApproval/approval-subject-source.util.spec.ts +50 -3
  33. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/humanApproval/approval-subject-source.util.ts +26 -3
  34. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/humanApproval/human-approval.dto.ts +53 -47
  35. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/humanApproval/human-approval.errors.ts +0 -1
  36. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/humanApproval/human-approval.service.spec.ts +541 -0
  37. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/humanApproval/human-approval.service.ts +442 -200
  38. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/humanApproval/outbox-retry.util.ts +1 -0
  39. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/humanApproval/runtime/human-approval-runtime.controller.spec.ts +150 -0
  40. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/humanApproval/runtime/human-approval-runtime.controller.ts +56 -40
  41. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/humanApproval/runtime/human-approval-runtime.dto.ts +16 -60
  42. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/integrationConnection/integration-connection.controller.ts +13 -0
  43. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/integrationConnection/integration-connection.service.spec.ts +44 -0
  44. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/integrationConnection/integration-connection.service.ts +6 -0
  45. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/dsl-validate.util.spec.ts +258 -12
  46. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/dsl-validate.util.ts +127 -14
  47. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/manual-workflow-execution.spec.ts +85 -0
  48. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/manual-workflow-execution.ts +108 -0
  49. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/parameter-binding.ts +5 -5
  50. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/temporal.service.spec.ts +96 -25
  51. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/temporal.service.ts +77 -34
  52. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-callable.spec.ts +23 -34
  53. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-callable.ts +0 -21
  54. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-cancellation.spec.ts +245 -0
  55. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-compiler.service.spec.ts +639 -188
  56. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-compiler.service.ts +408 -235
  57. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-compiler.types.ts +1 -3
  58. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-data-edge.util.spec.ts +279 -95
  59. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-data-edge.util.ts +360 -80
  60. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-event-catalog.spec.ts +323 -0
  61. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-execution-idempotency.spec.ts +773 -0
  62. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-execution.dto.ts +7 -13
  63. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-export.dto.ts +0 -16
  64. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-export.service.spec.ts +184 -0
  65. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-export.service.ts +69 -138
  66. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-handle-validator.spec.ts +113 -0
  67. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-handle-validator.ts +59 -13
  68. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-runtime.facade.ts +86 -0
  69. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-switch-config.spec.ts +25 -0
  70. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-switch-config.ts +45 -0
  71. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow.controller.spec.ts +78 -43
  72. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow.controller.ts +103 -40
  73. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow.dto.ts +57 -0
  74. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow.module.ts +3 -1
  75. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow.service.spec.ts +1000 -240
  76. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow.service.ts +2184 -317
  77. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowConfig/node-config-validator.service.spec.ts +279 -2
  78. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowConfig/node-config-validator.service.ts +5 -1
  79. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowConfig/subject-config-validator.service.spec.ts +4 -1
  80. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowConfig/subject-config-validator.service.ts +5 -1
  81. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowConfig/widget-catalog.service.spec.ts +12 -3
  82. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowConfig/widget-catalog.service.ts +10 -1
  83. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowNodeInstance/workflowNodeInstance.service.spec.ts +2 -24
  84. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowNodeInstance/workflowNodeInstance.service.ts +3 -70
  85. package/dist/lib/application/files/gadmin2-game-angle-demo/web/package.json +3 -1
  86. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/RowActions.tsx +25 -5
  87. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/WorkflowActionButton.test.tsx +71 -0
  88. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/WorkflowActionButton.tsx +89 -0
  89. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/index.ts +1 -0
  90. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/layout/header.tsx +52 -12
  91. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/config/routeRegistry.tsx +12 -0
  92. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/constants/layout.ts +2 -2
  93. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/dev-shell/AddDataModal.tsx +10 -33
  94. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/dev-shell/AddPageModal.tsx +13 -37
  95. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/dev-shell/DevShell.tsx +55 -7
  96. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/dev-shell/style.css +14 -0
  97. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/helpers/http.ts +10 -0
  98. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/helpers/list.tsx +1 -0
  99. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/helpers/workflowAction.ts +19 -0
  100. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/hooks/index.ts +1 -0
  101. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/hooks/types.ts +3 -1
  102. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/hooks/useDynamicResources.tsx +1 -6
  103. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/hooks/useReferenceUpload.ts +95 -0
  104. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/locales/en/common.json +2 -2
  105. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/locales/en/workflow.json +672 -110
  106. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/locales/zh_CN/common.json +2 -2
  107. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/locales/zh_CN/workflow.json +676 -114
  108. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/plugins/devShellPlugin.ts +13 -1
  109. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/agenda/index.tsx +1 -0
  110. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/CanvasEditPage.tsx +38 -4
  111. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/CanvasListPage.tsx +276 -376
  112. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/components/CanvasAiModal.tsx +126 -6
  113. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/human-approval/DecisionModal.test.tsx +50 -0
  114. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/human-approval/DecisionModal.tsx +48 -11
  115. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/human-approval/inbox.tsx +32 -34
  116. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/business-events/RegisterBusinessEventModal.test.tsx +111 -0
  117. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/business-events/RegisterBusinessEventModal.tsx +167 -0
  118. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/business-events/business-events.css +99 -0
  119. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/business-events/detail.test.tsx +106 -0
  120. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/business-events/detail.tsx +324 -0
  121. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/business-events/index.test.tsx +73 -0
  122. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/business-events/index.tsx +359 -0
  123. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/CanvasZoomControls.tsx +46 -0
  124. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/CreateNodeInstanceDrawer.tsx +9 -1
  125. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/CustomNode.test.tsx +105 -4
  126. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/CustomNode.tsx +90 -48
  127. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/DeletableEdge.tsx +3 -2
  128. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/DslView.test.tsx +259 -0
  129. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/DslView.tsx +167 -103
  130. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/EnhancedFlowRenderer.tsx +142 -140
  131. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/ExecutionStatusNode.test.tsx +60 -15
  132. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/ExecutionStatusNode.tsx +25 -12
  133. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/FlowRenderer.tsx +364 -200
  134. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/NewNodeDefaults.test.tsx +220 -52
  135. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/NodeOutputSummary.test.tsx +260 -0
  136. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/NodeOutputSummary.tsx +300 -130
  137. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/NodePropertyPanel.test.tsx +507 -33
  138. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/NodePropertyPanel.tsx +630 -592
  139. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/ParameterBindingEditor.tsx +67 -70
  140. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/ReadonlyNodePanel.test.tsx +90 -0
  141. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/ReadonlyNodePanel.tsx +325 -0
  142. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/RunWorkflowModal.test.tsx +52 -0
  143. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/RunWorkflowModal.tsx +14 -9
  144. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/StatusCards.tsx +2 -1
  145. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/VersionPanel.tsx +2 -1
  146. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/WorkflowCodeEditor.test.tsx +42 -0
  147. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/WorkflowCodeEditor.tsx +76 -0
  148. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/WorkflowWorkspaceHeader.tsx +56 -0
  149. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/parameter-binding-editor.css +46 -0
  150. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/workflow-code-editor.css +34 -0
  151. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/connections/ConnectionModal.test.tsx +53 -7
  152. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/connections/ConnectionModal.tsx +123 -62
  153. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/connections/connections.css +85 -0
  154. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/connections/connectionsApi.ts +29 -0
  155. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/connections/index.test.tsx +75 -0
  156. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/connections/index.tsx +69 -36
  157. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/editor.test.tsx +494 -0
  158. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/editor.tsx +665 -194
  159. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/hooks/useReferencedNodeInstanceConfigs.test.tsx +92 -0
  160. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/hooks/useReferencedNodeInstanceConfigs.ts +96 -0
  161. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/hooks/useWorkflowAgent.test.tsx +297 -0
  162. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/hooks/useWorkflowAgent.ts +135 -65
  163. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/index.tsx +53 -42
  164. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/instance-detail.tsx +344 -155
  165. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/instances.tsx +79 -58
  166. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/components/CreateNodeInstanceModal.tsx +123 -144
  167. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/components/NodeInstanceForm.tsx +169 -98
  168. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/components/node-instance-form.css +91 -0
  169. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/index.tsx +54 -31
  170. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/node-config.css +854 -0
  171. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/schema-form/SchemaField.tsx +41 -14
  172. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/schema-form/SchemaForm.test.tsx +75 -0
  173. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/schema-form/SchemaForm.tsx +3 -0
  174. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/schema-form/default-widgets.tsx +20 -2
  175. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/schema-form/widget-registry.tsx +2 -1
  176. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/show.tsx +61 -66
  177. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/ApprovalRuleEditor.test.tsx +33 -1
  178. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/ApprovalRuleEditor.tsx +47 -15
  179. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/BranchConfigEditors.test.tsx +104 -0
  180. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/CallableInputParametersEditor.tsx +22 -52
  181. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/CodeConfigEditor.test.tsx +72 -0
  182. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/CodeConfigEditor.tsx +78 -70
  183. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/CronTriggerConfigEditor.tsx +569 -0
  184. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/DbExecuteConfigEditor.tsx +130 -0
  185. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/DelayConfigEditor.tsx +100 -0
  186. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/EventTriggerConfigEditor.tsx +620 -0
  187. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/ExternalRequestConfigEditor.test.tsx +22 -45
  188. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/ExternalRequestConfigEditor.tsx +25 -92
  189. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/ExternalWaitConfigEditor.tsx +3 -11
  190. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/ForEachConfigEditor.test.tsx +58 -0
  191. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/ForEachConfigEditor.tsx +107 -0
  192. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/HttpRequestConfigEditor.test.tsx +212 -31
  193. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/HttpRequestConfigEditor.tsx +214 -304
  194. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/HumanApprovalConfigEditor.test.tsx +175 -40
  195. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/HumanApprovalConfigEditor.tsx +693 -293
  196. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/IfElseConfigEditor.tsx +190 -0
  197. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/ManualTriggerConfigEditor.test.tsx +152 -0
  198. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/ManualTriggerConfigEditor.tsx +286 -0
  199. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/ParallelConfigEditor.tsx +101 -0
  200. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/ParameterBindingListEditor.tsx +99 -0
  201. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/SimplifiedNodeEditors.test.tsx +495 -0
  202. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/SubWorkflowConfigEditor.test.tsx +124 -0
  203. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/SubWorkflowConfigEditor.tsx +222 -0
  204. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/SubjectPicker.tsx +2 -4
  205. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/SwitchConfigEditor.tsx +204 -0
  206. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/UserGroupCreateModal.tsx +3 -1
  207. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/UserGroupEditModal.tsx +9 -6
  208. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/callable-workflow.ts +4 -0
  209. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/code-config.css +96 -0
  210. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/event-catalog.api.ts +117 -0
  211. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/http-request-config.css +242 -0
  212. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/human-approval-config.css +194 -0
  213. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/show.tsx +264 -167
  214. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/temporal-tenant/index.tsx +6 -9
  215. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/types/parameter-binding.ts +19 -16
  216. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/types.ts +28 -4
  217. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/useWorkflowFormValidation.test.tsx +59 -0
  218. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/useWorkflowFormValidation.ts +24 -0
  219. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/forEachConnection.test.ts +311 -0
  220. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/forEachConnection.ts +198 -0
  221. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/mainFlowConnection.test.ts +143 -0
  222. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/mainFlowConnection.ts +19 -0
  223. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/newNodeConfig.ts +103 -5
  224. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/removeWorkflowEdges.test.ts +158 -3
  225. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/removeWorkflowEdges.ts +117 -9
  226. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/resolveEffectiveOutput.test.ts +70 -0
  227. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/resolveEffectiveOutput.ts +48 -0
  228. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/resolveLookupPorts.test.ts +55 -0
  229. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/resolveLookupPorts.ts +95 -22
  230. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/resolveOutputs.test.ts +148 -1
  231. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/resolveOutputs.ts +62 -11
  232. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/resolveWorkflowDisplay.test.ts +19 -0
  233. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/resolveWorkflowDisplay.ts +1 -1
  234. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/subWorkflowChange.test.ts +45 -0
  235. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/subWorkflowChange.ts +26 -0
  236. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/validateWorkflowDsl.test.ts +502 -0
  237. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/validateWorkflowDsl.ts +694 -0
  238. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/workflowDateTime.test.ts +27 -0
  239. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/workflowDateTime.ts +33 -0
  240. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/workflowHistory.test.ts +34 -0
  241. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/workflowHistory.ts +52 -0
  242. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/workflowPublishError.test.ts +99 -0
  243. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/workflowPublishError.ts +91 -0
  244. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/workflowSkillPrompt.test.ts +74 -0
  245. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/workflowSkillPrompt.ts +120 -0
  246. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/workflow-ui.css +481 -0
  247. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/styles/index.css +1 -1
  248. package/package.json +1 -1
  249. package/dist/lib/application/files/gadmin2-game-angle-demo/config/ui/WorkflowEventOutbox.ts +0 -62
  250. package/dist/lib/application/files/gadmin2-game-angle-demo/server/scripts/migrate-human-approval-configs.ts +0 -86
  251. package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/workflow-event-trigger.ts +0 -60
  252. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/humanApproval/human-approval.external-decision.spec.ts +0 -183
  253. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/humanApproval/legacy-approval-config-migration.ts +0 -227
  254. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-http-response.spec.ts +0 -82
  255. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-http-response.ts +0 -111
  256. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowEventOutbox/workflowEventOutbox.controller.spec.ts +0 -54
  257. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowEventOutbox/workflowEventOutbox.controller.ts +0 -147
  258. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowEventOutbox/workflowEventOutbox.module.ts +0 -10
  259. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowEventOutbox/workflowEventOutbox.service.spec.ts +0 -350
  260. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowEventOutbox/workflowEventOutbox.service.ts +0 -110
  261. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/audit/index.ts +0 -1
  262. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/InstanceRequiredDialog.tsx +0 -106
  263. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/LookupConnectionDialog.test.tsx +0 -45
  264. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/LookupConnectionDialog.tsx +0 -43
  265. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/NodeTypeBadge.tsx +0 -36
  266. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/hooks/useNodeInstanceLibrary.ts +0 -41
  267. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/ApproverSourceEditor.test.tsx +0 -47
  268. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/ApproverSourceEditor.tsx +0 -182
  269. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/ReturnResultConfigEditor.test.tsx +0 -34
  270. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/ReturnResultConfigEditor.tsx +0 -16
  271. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/approver-source.test.ts +0 -25
  272. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/approver-source.ts +0 -42
  273. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/lookupConnection.test.ts +0 -208
  274. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/lookupConnection.ts +0 -246
  275. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflowEventOutbox/create.tsx +0 -111
  276. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflowEventOutbox/edit.tsx +0 -127
  277. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflowEventOutbox/index.tsx +0 -4
  278. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflowEventOutbox/list.tsx +0 -282
  279. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflowEventOutbox/show.tsx +0 -74
@@ -0,0 +1,569 @@
1
+ import { DeleteOutlined, PlusOutlined } from '@ant-design/icons';
2
+ import { Button, Select, TimePicker, Typography } from 'antd';
3
+ import dayjs from 'dayjs';
4
+ import { useTranslation } from 'react-i18next';
5
+ import type { WidgetProps } from '../schema-form/widget-registry';
6
+
7
+ type CronTriggerConfig = {
8
+ cronExpressions?: string[];
9
+ timezone?: string;
10
+ };
11
+
12
+ type Frequency =
13
+ | 'HOURLY'
14
+ | 'DAILY'
15
+ | 'WEEKDAYS'
16
+ | 'WEEKLY'
17
+ | 'MONTHLY'
18
+ | 'YEARLY';
19
+
20
+ type ScheduleSelection = {
21
+ frequency: Frequency;
22
+ hour: number;
23
+ minute: number;
24
+ weekdays: number[];
25
+ monthDays: number[];
26
+ months: number[];
27
+ hourlyMinutes: number[];
28
+ executionTimes: Array<{ hour: number; minute: number }>;
29
+ };
30
+
31
+ const DEFAULT_SCHEDULE: ScheduleSelection = {
32
+ frequency: 'DAILY',
33
+ hour: 9,
34
+ minute: 0,
35
+ weekdays: [1],
36
+ monthDays: [1],
37
+ months: [1],
38
+ hourlyMinutes: [0],
39
+ executionTimes: [{ hour: 9, minute: 0 }],
40
+ };
41
+
42
+ const TIMEZONE_VALUES = [
43
+ 'Asia/Shanghai',
44
+ 'Asia/Singapore',
45
+ 'Asia/Tokyo',
46
+ 'Europe/London',
47
+ 'America/New_York',
48
+ 'UTC',
49
+ ] as const;
50
+
51
+ function parseCronExpression(value: string): ScheduleSelection | null {
52
+ const parts = value?.trim().split(/\s+/);
53
+ if (!parts || parts.length !== 5) return null;
54
+
55
+ const [minuteText, hourText, monthDayText, monthText, weekdayText] = parts;
56
+
57
+ if (
58
+ hourText === '*' &&
59
+ monthDayText === '*' &&
60
+ monthText === '*' &&
61
+ weekdayText === '*'
62
+ ) {
63
+ const hourlyMinutes = minuteText.split(',').map(Number);
64
+ if (
65
+ hourlyMinutes.length === 0 ||
66
+ !hourlyMinutes.every(
67
+ (minute, index) =>
68
+ Number.isInteger(minute) &&
69
+ minute >= 0 &&
70
+ minute <= 59 &&
71
+ hourlyMinutes.indexOf(minute) === index,
72
+ )
73
+ ) {
74
+ return null;
75
+ }
76
+ return {
77
+ ...DEFAULT_SCHEDULE,
78
+ frequency: 'HOURLY',
79
+ minute: hourlyMinutes[0],
80
+ hourlyMinutes,
81
+ };
82
+ }
83
+
84
+ const minute = Number(minuteText);
85
+ if (!Number.isInteger(minute) || minute < 0 || minute > 59) return null;
86
+
87
+ const hour = Number(hourText);
88
+ if (!Number.isInteger(hour) || hour < 0 || hour > 23) {
89
+ return null;
90
+ }
91
+
92
+ if (monthText === '*' && monthDayText === '*' && weekdayText === '*') {
93
+ return { ...DEFAULT_SCHEDULE, frequency: 'DAILY', hour, minute };
94
+ }
95
+ if (monthText === '*' && monthDayText === '*' && weekdayText === '1-5') {
96
+ return { ...DEFAULT_SCHEDULE, frequency: 'WEEKDAYS', hour, minute };
97
+ }
98
+
99
+ const weekdays = weekdayText.split(',').map(Number);
100
+ if (
101
+ monthText === '*' &&
102
+ monthDayText === '*' &&
103
+ weekdays.length > 0 &&
104
+ weekdays.every(
105
+ (weekday, index) =>
106
+ Number.isInteger(weekday) &&
107
+ weekday >= 0 &&
108
+ weekday <= 6 &&
109
+ weekdays.indexOf(weekday) === index,
110
+ )
111
+ ) {
112
+ return {
113
+ ...DEFAULT_SCHEDULE,
114
+ frequency: 'WEEKLY',
115
+ hour,
116
+ minute,
117
+ weekdays,
118
+ };
119
+ }
120
+
121
+ const monthDay = Number(monthDayText);
122
+ if (
123
+ monthText === '*' &&
124
+ weekdayText === '*' &&
125
+ Number.isInteger(monthDay) &&
126
+ monthDay >= 1 &&
127
+ monthDay <= 31
128
+ ) {
129
+ return {
130
+ ...DEFAULT_SCHEDULE,
131
+ frequency: 'MONTHLY',
132
+ hour,
133
+ minute,
134
+ monthDays: [monthDay],
135
+ };
136
+ }
137
+
138
+ const monthDays = monthDayText.split(',').map(Number);
139
+ if (
140
+ monthText === '*' &&
141
+ weekdayText === '*' &&
142
+ monthDays.length > 0 &&
143
+ monthDays.every(
144
+ (day, index) =>
145
+ Number.isInteger(day) &&
146
+ day >= 1 &&
147
+ day <= 31 &&
148
+ monthDays.indexOf(day) === index,
149
+ )
150
+ ) {
151
+ return {
152
+ ...DEFAULT_SCHEDULE,
153
+ frequency: 'MONTHLY',
154
+ hour,
155
+ minute,
156
+ monthDays,
157
+ };
158
+ }
159
+
160
+ const months = monthText.split(',').map(Number);
161
+ if (
162
+ weekdayText === '*' &&
163
+ Number.isInteger(monthDay) &&
164
+ monthDay >= 1 &&
165
+ monthDay <= 31 &&
166
+ months.length > 0 &&
167
+ months.every(
168
+ (month, index) =>
169
+ Number.isInteger(month) &&
170
+ month >= 1 &&
171
+ month <= 12 &&
172
+ months.indexOf(month) === index,
173
+ )
174
+ ) {
175
+ return {
176
+ ...DEFAULT_SCHEDULE,
177
+ frequency: 'YEARLY',
178
+ hour,
179
+ minute,
180
+ monthDays: [monthDay],
181
+ months,
182
+ };
183
+ }
184
+
185
+ return null;
186
+ }
187
+
188
+ function parseSchedule(values?: string[]): ScheduleSelection | null {
189
+ if (!values?.length) return null;
190
+ const parsed = values.map(parseCronExpression);
191
+ if (parsed.some((item) => !item)) return null;
192
+ const schedules = parsed as ScheduleSelection[];
193
+ const first = schedules[0];
194
+ if (!schedules.every((item) => item.frequency === first.frequency)) {
195
+ return null;
196
+ }
197
+ if (first.frequency === 'HOURLY') {
198
+ return schedules.length === 1 ? first : null;
199
+ }
200
+
201
+ const scopeKey = (item: ScheduleSelection) => {
202
+ if (item.frequency === 'WEEKLY') {
203
+ return [...item.weekdays].sort((a, b) => a - b).join(',');
204
+ }
205
+ if (item.frequency === 'MONTHLY') {
206
+ return [...item.monthDays].sort((a, b) => a - b).join(',');
207
+ }
208
+ if (item.frequency === 'YEARLY') {
209
+ return `${[...item.months].sort((a, b) => a - b).join(',')}:${item.monthDays[0]}`;
210
+ }
211
+ return '';
212
+ };
213
+ if (!schedules.every((item) => scopeKey(item) === scopeKey(first))) {
214
+ return null;
215
+ }
216
+
217
+ const executionTimes = schedules.map(({ hour, minute }) => ({
218
+ hour,
219
+ minute,
220
+ }));
221
+ if (
222
+ new Set(executionTimes.map(({ hour, minute }) => `${hour}:${minute}`))
223
+ .size !== executionTimes.length
224
+ ) {
225
+ return null;
226
+ }
227
+ return { ...first, executionTimes };
228
+ }
229
+
230
+ function buildCronExpressions(selection: ScheduleSelection): string[] {
231
+ const { frequency, weekdays, monthDays, months } = selection;
232
+ if (frequency === 'HOURLY') {
233
+ return [
234
+ `${[...selection.hourlyMinutes].sort((a, b) => a - b).join(',')} * * * *`,
235
+ ];
236
+ }
237
+ if (frequency === 'DAILY') {
238
+ return selection.executionTimes.map(
239
+ (time) => `${time.minute} ${time.hour} * * *`,
240
+ );
241
+ }
242
+ if (frequency === 'WEEKDAYS') {
243
+ return selection.executionTimes.map(
244
+ (time) => `${time.minute} ${time.hour} * * 1-5`,
245
+ );
246
+ }
247
+ if (frequency === 'WEEKLY') {
248
+ const weekdayText = [...weekdays]
249
+ .sort((a, b) => (a === 0 ? 7 : a) - (b === 0 ? 7 : b))
250
+ .join(',');
251
+ return selection.executionTimes.map(
252
+ (time) => `${time.minute} ${time.hour} * * ${weekdayText}`,
253
+ );
254
+ }
255
+ if (frequency === 'MONTHLY') {
256
+ const monthDayText = [...monthDays].sort((a, b) => a - b).join(',');
257
+ return selection.executionTimes.map(
258
+ (time) => `${time.minute} ${time.hour} ${monthDayText} * *`,
259
+ );
260
+ }
261
+ if (frequency === 'YEARLY') {
262
+ const monthText = [...months].sort((a, b) => a - b).join(',');
263
+ return selection.executionTimes.map(
264
+ (time) => `${time.minute} ${time.hour} ${monthDays[0]} ${monthText} *`,
265
+ );
266
+ }
267
+ return [];
268
+ }
269
+
270
+ function nextExecutionTime(times: ScheduleSelection['executionTimes']) {
271
+ const occupied = new Set(times.map(({ hour, minute }) => hour * 60 + minute));
272
+ const last = times[times.length - 1] ?? { hour: 8, minute: 0 };
273
+ const start = last.hour * 60 + last.minute;
274
+ for (let offset = 60; offset <= 24 * 60; offset += 5) {
275
+ const candidate = (start + offset) % (24 * 60);
276
+ if (!occupied.has(candidate)) {
277
+ return { hour: Math.floor(candidate / 60), minute: candidate % 60 };
278
+ }
279
+ }
280
+ return null;
281
+ }
282
+
283
+ export function CronTriggerConfigEditor({
284
+ value,
285
+ onChange,
286
+ disabled,
287
+ }: WidgetProps<CronTriggerConfig | undefined>) {
288
+ const { t } = useTranslation('workflow');
289
+ const config = value ?? {};
290
+ const parsedSchedule = parseSchedule(config.cronExpressions);
291
+ const selection =
292
+ parsedSchedule ??
293
+ (config.cronExpressions?.length === 0
294
+ ? { ...DEFAULT_SCHEDULE, executionTimes: [], hourlyMinutes: [] }
295
+ : DEFAULT_SCHEDULE);
296
+
297
+ const updateSchedule = (next: ScheduleSelection) =>
298
+ onChange({
299
+ cronExpressions: buildCronExpressions(next),
300
+ ...(config.timezone ? { timezone: config.timezone } : {}),
301
+ });
302
+
303
+ const changeFrequency = (frequency: Frequency) =>
304
+ updateSchedule({
305
+ ...selection,
306
+ frequency,
307
+ ...(frequency === 'HOURLY'
308
+ ? { hourlyMinutes: [selection.minute] }
309
+ : {
310
+ executionTimes: [
311
+ { hour: selection.hour, minute: selection.minute },
312
+ ],
313
+ }),
314
+ });
315
+
316
+ return (
317
+ <div className="cron-trigger-config">
318
+ <div className="cron-trigger-config__field">
319
+ <Typography.Text className="workflow-node-config__field-label">
320
+ {t('nodeEditors.cron.frequency')}
321
+ </Typography.Text>
322
+ <Select
323
+ aria-label={t('nodeEditors.cron.frequency')}
324
+ value={parsedSchedule?.frequency}
325
+ disabled={disabled}
326
+ placeholder={t('nodeEditors.cron.frequencyPlaceholder')}
327
+ options={(
328
+ [
329
+ 'HOURLY',
330
+ 'DAILY',
331
+ 'WEEKDAYS',
332
+ 'WEEKLY',
333
+ 'MONTHLY',
334
+ 'YEARLY',
335
+ ] as const
336
+ ).map((frequency) => ({
337
+ value: frequency,
338
+ label: t(`nodeEditors.cron.frequencies.${frequency}`),
339
+ }))}
340
+ onChange={changeFrequency}
341
+ />
342
+ {!parsedSchedule && config.cronExpressions?.length && (
343
+ <Typography.Text
344
+ type="secondary"
345
+ className="cron-trigger-config__hint"
346
+ >
347
+ {t('nodeEditors.cron.chooseNewSchedule')}
348
+ </Typography.Text>
349
+ )}
350
+ </div>
351
+
352
+ {selection.frequency === 'HOURLY' ? (
353
+ <div className="cron-trigger-config__field">
354
+ <Typography.Text className="workflow-node-config__field-label">
355
+ {t('nodeEditors.cron.minute')}
356
+ </Typography.Text>
357
+ <Select
358
+ mode="multiple"
359
+ aria-label={t('nodeEditors.cron.minute')}
360
+ value={selection.hourlyMinutes}
361
+ disabled={disabled || !parsedSchedule}
362
+ options={Array.from({ length: 60 }, (_, minute) => ({
363
+ value: minute,
364
+ label: t('nodeEditors.cron.minuteOption', { minute }),
365
+ }))}
366
+ onChange={(hourlyMinutes) =>
367
+ updateSchedule({ ...selection, hourlyMinutes })
368
+ }
369
+ />
370
+ </div>
371
+ ) : (
372
+ <div className="cron-trigger-config__field">
373
+ <Typography.Text className="workflow-node-config__field-label">
374
+ {t('nodeEditors.cron.times')}
375
+ </Typography.Text>
376
+ <div className="cron-trigger-config__time-list">
377
+ {selection.executionTimes.map((time, index) => (
378
+ <div
379
+ key={`${time.hour}:${time.minute}`}
380
+ className="cron-trigger-config__time-row"
381
+ >
382
+ <TimePicker
383
+ aria-label={t('nodeEditors.cron.timeNumber', {
384
+ number: index + 1,
385
+ })}
386
+ format="HH:mm"
387
+ minuteStep={5}
388
+ value={dayjs().hour(time.hour).minute(time.minute).second(0)}
389
+ disabled={disabled || !parsedSchedule}
390
+ onChange={(nextTime) => {
391
+ if (!nextTime) {
392
+ updateSchedule({
393
+ ...selection,
394
+ executionTimes: selection.executionTimes.filter(
395
+ (_, itemIndex) => itemIndex !== index,
396
+ ),
397
+ });
398
+ return;
399
+ }
400
+ const next = {
401
+ hour: nextTime.hour(),
402
+ minute: nextTime.minute(),
403
+ };
404
+ updateSchedule({
405
+ ...selection,
406
+ executionTimes: selection.executionTimes.map(
407
+ (item, itemIndex) =>
408
+ itemIndex === index ? next : item,
409
+ ),
410
+ });
411
+ }}
412
+ />
413
+ <Button
414
+ type="text"
415
+ danger
416
+ icon={<DeleteOutlined />}
417
+ aria-label={t('nodeEditors.cron.removeTime', {
418
+ number: index + 1,
419
+ })}
420
+ disabled={disabled}
421
+ onClick={() =>
422
+ updateSchedule({
423
+ ...selection,
424
+ executionTimes: selection.executionTimes.filter(
425
+ (_, itemIndex) => itemIndex !== index,
426
+ ),
427
+ })
428
+ }
429
+ />
430
+ </div>
431
+ ))}
432
+ </div>
433
+ <Button
434
+ className="workflow-panel-action"
435
+ icon={<PlusOutlined />}
436
+ aria-label={t('nodeEditors.cron.addTime')}
437
+ disabled={disabled || !parsedSchedule}
438
+ onClick={() => {
439
+ const next = nextExecutionTime(selection.executionTimes);
440
+ if (next) {
441
+ updateSchedule({
442
+ ...selection,
443
+ executionTimes: [...selection.executionTimes, next],
444
+ });
445
+ }
446
+ }}
447
+ >
448
+ {t('nodeEditors.cron.addTime')}
449
+ </Button>
450
+ </div>
451
+ )}
452
+
453
+ {selection.frequency === 'WEEKLY' && (
454
+ <div className="cron-trigger-config__field">
455
+ <Typography.Text className="workflow-node-config__field-label">
456
+ {t('nodeEditors.cron.weekday')}
457
+ </Typography.Text>
458
+ <Select
459
+ mode="multiple"
460
+ aria-label={t('nodeEditors.cron.weekday')}
461
+ value={selection.weekdays}
462
+ disabled={disabled || !parsedSchedule}
463
+ options={[1, 2, 3, 4, 5, 6, 0].map((weekday) => ({
464
+ value: weekday,
465
+ label: t(`nodeEditors.cron.weekdays.${weekday}`),
466
+ }))}
467
+ onChange={(weekdays) => updateSchedule({ ...selection, weekdays })}
468
+ />
469
+ </div>
470
+ )}
471
+
472
+ {selection.frequency === 'MONTHLY' && (
473
+ <div className="cron-trigger-config__field">
474
+ <Typography.Text className="workflow-node-config__field-label">
475
+ {t('nodeEditors.cron.monthDay')}
476
+ </Typography.Text>
477
+ <Select
478
+ mode="multiple"
479
+ aria-label={t('nodeEditors.cron.monthDay')}
480
+ value={selection.monthDays}
481
+ disabled={disabled || !parsedSchedule}
482
+ options={Array.from({ length: 31 }, (_, index) => ({
483
+ value: index + 1,
484
+ label: t('nodeEditors.cron.monthDayOption', { day: index + 1 }),
485
+ }))}
486
+ onChange={(monthDays) =>
487
+ updateSchedule({ ...selection, monthDays })
488
+ }
489
+ />
490
+ </div>
491
+ )}
492
+
493
+ {selection.frequency === 'YEARLY' && (
494
+ <>
495
+ <div className="cron-trigger-config__field">
496
+ <Typography.Text className="workflow-node-config__field-label">
497
+ {t('nodeEditors.cron.months')}
498
+ </Typography.Text>
499
+ <Select
500
+ mode="multiple"
501
+ aria-label={t('nodeEditors.cron.months')}
502
+ value={selection.months}
503
+ disabled={disabled || !parsedSchedule}
504
+ options={Array.from({ length: 12 }, (_, index) => ({
505
+ value: index + 1,
506
+ label: t('nodeEditors.cron.monthOption', {
507
+ month: index + 1,
508
+ }),
509
+ }))}
510
+ onChange={(months) => updateSchedule({ ...selection, months })}
511
+ />
512
+ </div>
513
+ <div className="cron-trigger-config__field">
514
+ <Typography.Text className="workflow-node-config__field-label">
515
+ {t('nodeEditors.cron.monthDay')}
516
+ </Typography.Text>
517
+ <Select
518
+ aria-label={t('nodeEditors.cron.monthDay')}
519
+ value={selection.monthDays[0]}
520
+ disabled={disabled || !parsedSchedule}
521
+ options={Array.from({ length: 31 }, (_, index) => ({
522
+ value: index + 1,
523
+ label: t('nodeEditors.cron.yearMonthDayOption', {
524
+ day: index + 1,
525
+ }),
526
+ }))}
527
+ onChange={(monthDay) =>
528
+ updateSchedule({ ...selection, monthDays: [monthDay] })
529
+ }
530
+ />
531
+ </div>
532
+ </>
533
+ )}
534
+
535
+ <div className="cron-trigger-config__field">
536
+ <Typography.Text className="workflow-node-config__field-label">
537
+ {t('nodeEditors.cron.timezone')}
538
+ </Typography.Text>
539
+ <Select
540
+ aria-label={t('nodeEditors.cron.timezone')}
541
+ value={
542
+ TIMEZONE_VALUES.includes(
543
+ config.timezone as (typeof TIMEZONE_VALUES)[number],
544
+ )
545
+ ? config.timezone
546
+ : undefined
547
+ }
548
+ disabled={disabled}
549
+ allowClear
550
+ placeholder={t('nodeEditors.cron.timezonePlaceholder')}
551
+ options={TIMEZONE_VALUES.map((timezone) => ({
552
+ value: timezone,
553
+ label: t(`nodeEditors.cron.timezones.${timezone}`),
554
+ }))}
555
+ onChange={(timezone) =>
556
+ onChange({
557
+ cronExpressions:
558
+ config.cronExpressions ?? buildCronExpressions(selection),
559
+ ...(timezone ? { timezone } : {}),
560
+ })
561
+ }
562
+ />
563
+ <Typography.Text type="secondary" className="cron-trigger-config__hint">
564
+ {t('nodeEditors.cron.timezoneHint')}
565
+ </Typography.Text>
566
+ </div>
567
+ </div>
568
+ );
569
+ }
@@ -0,0 +1,130 @@
1
+ import { Input, InputNumber, Space, Switch, Typography } from 'antd';
2
+ import { useTranslation } from 'react-i18next';
3
+ import type { ParameterBinding } from '../../types/parameter-binding';
4
+ import type { WidgetProps } from '../schema-form/widget-registry';
5
+ import { ParameterBindingListEditor } from './ParameterBindingListEditor';
6
+
7
+ type DbExecuteConfig = {
8
+ allowWrite?: boolean;
9
+ sql?: string;
10
+ parameters?: ParameterBinding[];
11
+ timeoutSeconds?: number | null;
12
+ };
13
+
14
+ function normalizeSql(sql: string): string {
15
+ const withoutContent = sql
16
+ .replace(/\$(\w*)\$[\s\S]*?\$\1\$/g, ' ')
17
+ .replace(/'(?:''|[^'])*'/g, ' ')
18
+ .replace(/"(?:""|[^"])*"/g, ' ')
19
+ .replace(/\/\*[\s\S]*?\*\//g, ' ')
20
+ .replace(/--[^\r\n]*/g, ' ')
21
+ .trim();
22
+ const withoutTrailingSemicolon = withoutContent.replace(/;\s*$/, '').trim();
23
+ return withoutTrailingSemicolon.includes(';') ? '' : withoutTrailingSemicolon;
24
+ }
25
+
26
+ export function isDatabaseSqlAllowed(
27
+ sql: string,
28
+ allowWrite: boolean,
29
+ ): boolean {
30
+ const normalized = normalizeSql(sql);
31
+ if (!normalized) return false;
32
+ const readOnly =
33
+ /^(select|with)\b/i.test(normalized) &&
34
+ !/\b(insert|update|delete|merge|call|copy|create|alter|drop|truncate|grant|revoke|vacuum|refresh)\b/i.test(
35
+ normalized,
36
+ );
37
+ const writableCte =
38
+ /^with\b/i.test(normalized) &&
39
+ /\b(insert|update|delete)\b/i.test(normalized) &&
40
+ !/\b(merge|call|copy|create|alter|drop|truncate|grant|revoke|vacuum|refresh)\b/i.test(
41
+ normalized,
42
+ );
43
+ return (
44
+ readOnly ||
45
+ (allowWrite &&
46
+ (/^(insert|update|delete)\b/i.test(normalized) || writableCte))
47
+ );
48
+ }
49
+
50
+ export function DbExecuteConfigEditor({
51
+ value,
52
+ onChange,
53
+ disabled,
54
+ }: WidgetProps<DbExecuteConfig | undefined>) {
55
+ const { t } = useTranslation('workflow');
56
+ const config = value ?? {};
57
+ const allowWrite = config.allowWrite === true;
58
+
59
+ return (
60
+ <Space direction="vertical" size={14} style={{ width: '100%' }}>
61
+ <div className="db-execute-config__permission">
62
+ <div>
63
+ <Typography.Text strong>
64
+ {t('nodeEditors.database.allowWrite')}
65
+ </Typography.Text>
66
+ <Typography.Text type="secondary" className="db-execute-config__hint">
67
+ {t(
68
+ allowWrite
69
+ ? 'nodeEditors.database.readWriteDescription'
70
+ : 'nodeEditors.database.readOnlyDescription',
71
+ )}
72
+ </Typography.Text>
73
+ </div>
74
+ <Switch
75
+ aria-label={t('nodeEditors.database.allowWrite')}
76
+ checked={allowWrite}
77
+ disabled={disabled}
78
+ onChange={(nextAllowWrite) =>
79
+ onChange({ ...config, allowWrite: nextAllowWrite })
80
+ }
81
+ />
82
+ </div>
83
+
84
+ <Space direction="vertical" size={6} style={{ width: '100%' }}>
85
+ <Typography.Text>{t('nodeEditors.database.sql')}</Typography.Text>
86
+ <Input.TextArea
87
+ aria-label={t('nodeEditors.database.sql')}
88
+ value={config.sql ?? ''}
89
+ disabled={disabled}
90
+ rows={7}
91
+ placeholder={
92
+ allowWrite
93
+ ? 'UPDATE users SET active = $1 WHERE id = $2'
94
+ : 'SELECT id, name FROM users WHERE id = $1'
95
+ }
96
+ onChange={(event) => onChange({ ...config, sql: event.target.value })}
97
+ />
98
+ </Space>
99
+
100
+ <Space direction="vertical" size={6} style={{ width: '100%' }}>
101
+ <Typography.Text>
102
+ {t('nodeEditors.database.parameters')}
103
+ </Typography.Text>
104
+ <Typography.Text type="secondary" className="db-execute-config__hint">
105
+ {t('nodeEditors.database.parametersHint')}
106
+ </Typography.Text>
107
+ <ParameterBindingListEditor
108
+ value={config.parameters}
109
+ disabled={disabled}
110
+ addLabel={t('nodeEditors.database.addParameter')}
111
+ onChange={(parameters) => onChange({ ...config, parameters })}
112
+ />
113
+ </Space>
114
+
115
+ <Space direction="vertical" size={6} style={{ width: '100%' }}>
116
+ <Typography.Text>{t('nodeEditors.database.timeout')}</Typography.Text>
117
+ <InputNumber
118
+ precision={0}
119
+ value={
120
+ config.timeoutSeconds === undefined ? 30 : config.timeoutSeconds
121
+ }
122
+ disabled={disabled}
123
+ addonAfter={t('nodeEditors.database.seconds')}
124
+ onChange={(timeoutSeconds) => onChange({ ...config, timeoutSeconds })}
125
+ style={{ width: '100%' }}
126
+ />
127
+ </Space>
128
+ </Space>
129
+ );
130
+ }