@nocobase/flow-engine 2.0.0-alpha.4 → 2.0.0-alpha.41
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.
- package/lib/BlockScopedFlowEngine.d.ts +23 -0
- package/lib/BlockScopedFlowEngine.js +90 -0
- package/lib/FlowContextProvider.d.ts +2 -2
- package/lib/FlowContextProvider.js +3 -3
- package/lib/FlowDefinition.d.ts +4 -2
- package/lib/JSRunner.js +3 -0
- package/lib/ViewScopedFlowEngine.d.ts +1 -1
- package/lib/ViewScopedFlowEngine.js +12 -0
- package/lib/acl/Acl.d.ts +1 -0
- package/lib/acl/Acl.js +11 -0
- package/lib/components/FieldModelRenderer.js +14 -6
- package/lib/components/FieldSkeleton.d.ts +10 -0
- package/lib/components/FieldSkeleton.js +64 -0
- package/lib/components/FlowContextSelector.js +7 -2
- package/lib/components/FlowModelRenderer.d.ts +3 -6
- package/lib/components/FlowModelRenderer.js +16 -47
- package/lib/components/FormItem.js +5 -1
- package/lib/components/MobilePopup.d.ts +20 -0
- package/lib/components/MobilePopup.js +102 -0
- package/lib/components/MobilePopup.style.d.ts +17 -0
- package/lib/components/MobilePopup.style.js +186 -0
- package/lib/components/index.d.ts +1 -0
- package/lib/components/index.js +3 -1
- package/lib/components/settings/independents/dropdown/FlowsDropdownButton.js +2 -2
- package/lib/components/settings/wrappers/contextual/DefaultSettingsIcon.js +17 -5
- package/lib/components/settings/wrappers/contextual/FlowsContextMenu.js +2 -2
- package/lib/components/settings/wrappers/contextual/FlowsFloatContextMenu.d.ts +2 -2
- package/lib/components/settings/wrappers/contextual/FlowsFloatContextMenu.js +35 -6
- package/lib/components/settings/wrappers/contextual/StepSettingsDialog.js +7 -1
- package/lib/components/variables/VariableInput.js +19 -5
- package/lib/components/variables/VariableTag.js +43 -2
- package/lib/components/variables/types.d.ts +2 -0
- package/lib/data-source/index.d.ts +15 -4
- package/lib/data-source/index.js +42 -13
- package/lib/data-source/sortCollectionsByInherits.d.ts +10 -0
- package/lib/data-source/sortCollectionsByInherits.js +71 -0
- package/lib/emitter.d.ts +6 -0
- package/lib/emitter.js +12 -0
- package/lib/executor/FlowExecutor.d.ts +4 -5
- package/lib/executor/FlowExecutor.js +168 -99
- package/lib/flow-registry/GlobalFlowRegistry.d.ts +1 -0
- package/lib/flow-registry/GlobalFlowRegistry.js +3 -0
- package/lib/flow-registry/InstanceFlowRegistry.d.ts +1 -0
- package/lib/flow-registry/InstanceFlowRegistry.js +3 -0
- package/lib/flowContext.d.ts +37 -5
- package/lib/flowContext.js +224 -87
- package/lib/flowEngine.d.ts +24 -1
- package/lib/flowEngine.js +81 -8
- package/lib/flowSettings.d.ts +2 -1
- package/lib/flowSettings.js +16 -8
- package/lib/hooks/useApplyAutoFlows.js +2 -1
- package/lib/index.d.ts +7 -1
- package/lib/index.js +32 -3
- package/lib/locale/en-US.json +4 -2
- package/lib/locale/index.d.ts +4 -0
- package/lib/locale/zh-CN.json +4 -2
- package/lib/models/CollectionFieldModel.d.ts +3 -0
- package/lib/models/CollectionFieldModel.js +52 -6
- package/lib/models/flowModel.d.ts +30 -29
- package/lib/models/flowModel.js +153 -100
- package/lib/models/forkFlowModel.d.ts +8 -4
- package/lib/models/forkFlowModel.js +38 -8
- package/lib/provider.d.ts +3 -1
- package/lib/provider.js +7 -5
- package/lib/resources/multiRecordResource.js +25 -1
- package/lib/resources/singleRecordResource.js +19 -1
- package/lib/resources/sqlResource.d.ts +1 -0
- package/lib/resources/sqlResource.js +20 -24
- package/lib/runjs-context/contexts/FormJSFieldItemRunJSContext.d.ts +1 -6
- package/lib/runjs-context/contexts/FormJSFieldItemRunJSContext.js +27 -20
- package/lib/runjs-context/contexts/JSBlockRunJSContext.d.ts +1 -6
- package/lib/runjs-context/contexts/JSBlockRunJSContext.js +46 -33
- package/lib/runjs-context/contexts/JSCollectionActionRunJSContext.d.ts +1 -2
- package/lib/runjs-context/contexts/JSCollectionActionRunJSContext.js +14 -15
- package/lib/runjs-context/contexts/{LinkageRunJSContext.d.ts → JSColumnRunJSContext.d.ts} +6 -3
- package/lib/runjs-context/contexts/JSColumnRunJSContext.js +78 -0
- package/lib/runjs-context/contexts/JSFieldRunJSContext.d.ts +1 -6
- package/lib/runjs-context/contexts/JSFieldRunJSContext.js +28 -24
- package/lib/runjs-context/contexts/JSItemRunJSContext.d.ts +1 -6
- package/lib/runjs-context/contexts/JSItemRunJSContext.js +24 -20
- package/lib/runjs-context/contexts/JSRecordActionRunJSContext.d.ts +1 -2
- package/lib/runjs-context/contexts/JSRecordActionRunJSContext.js +16 -17
- package/lib/runjs-context/contexts/base.d.ts +9 -0
- package/lib/runjs-context/contexts/base.js +205 -0
- package/lib/runjs-context/helpers.d.ts +5 -2
- package/lib/runjs-context/helpers.js +36 -27
- package/lib/runjs-context/registry.d.ts +7 -4
- package/lib/runjs-context/registry.js +10 -42
- package/lib/runjs-context/setup.d.ts +9 -0
- package/lib/runjs-context/setup.js +82 -0
- package/lib/runjs-context/snippets/global/{copy-record-json.snippet.js → api-request.snippet.js} +25 -10
- package/lib/runjs-context/snippets/global/clipboard-copy-text.snippet.js +61 -0
- package/lib/runjs-context/snippets/global/{view-navigation-push.snippet.js → import-esm.snippet.js} +26 -12
- package/lib/runjs-context/snippets/global/message-error.snippet.js +6 -0
- package/lib/runjs-context/snippets/global/message-success.snippet.js +6 -0
- package/lib/runjs-context/snippets/global/notification-open.snippet.d.ts +3 -8
- package/lib/runjs-context/snippets/global/notification-open.snippet.js +8 -1
- package/lib/runjs-context/snippets/global/open-view-dialog.snippet.js +10 -3
- package/lib/runjs-context/snippets/global/open-view-drawer.snippet.js +10 -3
- package/lib/runjs-context/snippets/global/query-selector.snippet.js +53 -0
- package/lib/runjs-context/snippets/global/require-amd.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/global/{requireAsync.snippet.js → require-amd.snippet.js} +16 -13
- package/lib/runjs-context/snippets/global/window-open.snippet.d.ts +3 -8
- package/lib/runjs-context/snippets/global/window-open.snippet.js +8 -1
- package/lib/runjs-context/snippets/index.d.ts +14 -3
- package/lib/runjs-context/snippets/index.js +162 -40
- package/lib/runjs-context/snippets/scene/block/add-event-listener.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/{jsblock → block}/add-event-listener.snippet.js +11 -2
- package/lib/runjs-context/snippets/scene/block/api-fetch-render-list.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/block/api-fetch-render-list.snippet.js +64 -0
- package/lib/runjs-context/snippets/scene/block/chartjs-bar.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/block/chartjs-bar.snippet.js +99 -0
- package/lib/runjs-context/snippets/{libs → scene/block}/echarts-init.snippet.js +24 -7
- package/lib/runjs-context/snippets/scene/block/render-antd-icons.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/block/render-antd-icons.snippet.js +65 -0
- package/lib/runjs-context/snippets/scene/block/render-button-handler.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/{jsblock → block}/render-button-handler.snippet.js +17 -9
- package/lib/runjs-context/snippets/scene/block/render-iframe.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/block/render-iframe.snippet.js +57 -0
- package/lib/runjs-context/snippets/scene/block/render-info-card.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/block/render-info-card.snippet.js +71 -0
- package/lib/runjs-context/snippets/scene/block/render-react-jsx.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/{jsblock/render-card.snippet.js → block/render-react-jsx.snippet.js} +26 -13
- package/lib/runjs-context/snippets/scene/block/render-react.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/{jsblock → block}/render-react.snippet.js +18 -17
- package/lib/runjs-context/snippets/scene/block/render-statistics.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/block/render-statistics.snippet.js +95 -0
- package/lib/runjs-context/snippets/scene/block/render-timeline.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/block/render-timeline.snippet.js +84 -0
- package/lib/runjs-context/snippets/scene/block/resource-example.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/block/resource-example.snippet.js +60 -0
- package/lib/runjs-context/snippets/scene/block/three-users-orbit.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/block/three-users-orbit.snippet.js +283 -0
- package/lib/runjs-context/snippets/scene/block/vue-component.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/block/vue-component.snippet.js +124 -0
- package/lib/runjs-context/snippets/scene/detail/color-by-value.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/{jsfield → detail}/color-by-value.snippet.js +13 -3
- package/lib/runjs-context/snippets/scene/detail/copy-to-clipboard.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/{global → scene/detail}/copy-to-clipboard.snippet.js +28 -6
- package/lib/runjs-context/snippets/scene/detail/format-number.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/{jsfield → detail}/format-number.snippet.js +13 -3
- package/lib/runjs-context/snippets/scene/detail/innerHTML-value.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/{jsfield → detail}/innerHTML-value.snippet.js +13 -3
- package/lib/runjs-context/snippets/scene/detail/percentage-bar.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/detail/percentage-bar.snippet.js +82 -0
- package/lib/runjs-context/snippets/scene/detail/relative-time.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/detail/relative-time.snippet.js +80 -0
- package/lib/runjs-context/snippets/scene/detail/status-tag.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/detail/status-tag.snippet.js +74 -0
- package/lib/runjs-context/snippets/scene/form/calculate-total.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/form/calculate-total.snippet.js +63 -0
- package/lib/runjs-context/snippets/scene/form/cascade-select.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/form/cascade-select.snippet.js +81 -0
- package/lib/runjs-context/snippets/scene/form/conditional-required.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/form/conditional-required.snippet.js +64 -0
- package/lib/runjs-context/snippets/scene/form/copy-field-values.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/form/copy-field-values.snippet.js +74 -0
- package/lib/runjs-context/snippets/scene/form/render-basic.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/{jsitem → form}/render-basic.snippet.js +11 -2
- package/lib/runjs-context/snippets/scene/form/set-disabled.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/{linkage → form}/set-disabled.snippet.js +12 -3
- package/lib/runjs-context/snippets/scene/form/set-field-value.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/{linkage → form}/set-field-value.snippet.js +12 -3
- package/lib/runjs-context/snippets/scene/form/set-required.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/{linkage → form}/set-required.snippet.js +12 -3
- package/lib/runjs-context/snippets/scene/form/toggle-multiple-fields.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/form/toggle-multiple-fields.snippet.js +67 -0
- package/lib/runjs-context/snippets/scene/form/toggle-visible.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/{linkage → form}/toggle-visible.snippet.js +12 -3
- package/lib/runjs-context/snippets/scene/table/cell-open-dialog.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/table/cell-open-dialog.snippet.js +64 -0
- package/lib/runjs-context/snippets/scene/table/collection-selected-count.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/{actions → table}/collection-selected-count.snippet.js +11 -2
- package/lib/runjs-context/snippets/scene/table/concat-fields.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/table/concat-fields.snippet.js +79 -0
- package/lib/runjs-context/snippets/scene/table/destroy-selected.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/{global/log-json-record.snippet.js → scene/table/destroy-selected.snippet.js} +24 -11
- package/lib/runjs-context/snippets/scene/table/export-selected-json.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/table/export-selected-json.snippet.js +64 -0
- package/lib/runjs-context/snippets/scene/table/iterate-selected-rows.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/{actions → table}/iterate-selected-rows.snippet.js +11 -2
- package/lib/runjs-context/snippets/types.d.ts +9 -1
- package/lib/scheduler/ModelOperationScheduler.d.ts +51 -0
- package/lib/scheduler/ModelOperationScheduler.js +262 -0
- package/lib/types.d.ts +28 -3
- package/lib/types.js +4 -3
- package/lib/utils/associationObjectVariable.d.ts +32 -0
- package/lib/utils/associationObjectVariable.js +157 -0
- package/lib/utils/buildSettingsViewInputArgs.d.ts +19 -0
- package/lib/utils/buildSettingsViewInputArgs.js +75 -0
- package/lib/utils/createEphemeralContext.d.ts +13 -0
- package/lib/utils/createEphemeralContext.js +140 -0
- package/lib/utils/flows.d.ts +10 -0
- package/lib/{runjs-context/snippets/global/api-request-post.snippet.js → utils/flows.js} +21 -15
- package/lib/utils/index.d.ts +7 -2
- package/lib/utils/index.js +21 -2
- package/lib/utils/jsxTransform.d.ts +15 -0
- package/lib/utils/jsxTransform.js +68 -0
- package/lib/utils/params-resolvers.js +3 -3
- package/lib/utils/parsePathnameToViewParams.d.ts +1 -1
- package/lib/utils/parsePathnameToViewParams.js +41 -5
- package/lib/utils/pruneFilter.d.ts +21 -0
- package/lib/{runjs-context/snippets/global/try-catch-async.snippet.js → utils/pruneFilter.js} +24 -16
- package/lib/utils/safeGlobals.d.ts +5 -3
- package/lib/utils/safeGlobals.js +40 -0
- package/lib/utils/schema-utils.js +2 -2
- package/lib/utils/serverContextParams.d.ts +1 -0
- package/lib/utils/translation.d.ts +4 -1
- package/lib/utils/translation.js +6 -2
- package/lib/utils/variablesParams.d.ts +22 -5
- package/lib/utils/variablesParams.js +132 -36
- package/lib/views/DrawerComponent.js +21 -2
- package/lib/views/PageComponent.js +2 -1
- package/lib/views/ViewNavigation.d.ts +3 -9
- package/lib/views/ViewNavigation.js +16 -2
- package/lib/views/createViewMeta.d.ts +29 -1
- package/lib/views/createViewMeta.js +338 -72
- package/lib/views/index.d.ts +1 -0
- package/lib/views/index.js +3 -0
- package/lib/views/useDialog.d.ts +9 -8
- package/lib/views/useDialog.js +19 -14
- package/lib/views/useDrawer.d.ts +9 -8
- package/lib/views/useDrawer.js +54 -35
- package/lib/views/usePage.d.ts +9 -8
- package/lib/views/usePage.js +20 -14
- package/package.json +6 -3
- package/src/BlockScopedFlowEngine.ts +86 -0
- package/src/FlowContextProvider.tsx +4 -2
- package/src/JSRunner.ts +3 -0
- package/src/ViewScopedFlowEngine.ts +15 -1
- package/src/__tests__/JSRunner.test.ts +62 -53
- package/src/__tests__/blockScopedFlowEngine.test.ts +154 -0
- package/src/__tests__/createViewMeta.popup.test.ts +132 -0
- package/src/__tests__/flow-engine.test.ts +3 -0
- package/src/__tests__/flowContext.test.ts +52 -0
- package/src/__tests__/flowContextCreateJSRunner.test.ts +163 -0
- package/src/__tests__/flowEngine.saveModel.test.ts +4 -0
- package/src/__tests__/flowRunJSContextDefine.test.ts +508 -0
- package/src/__tests__/flowSettings.open.test.tsx +2 -0
- package/src/__tests__/flowSettings.test.ts +2 -0
- package/src/__tests__/globalFlowRegistry.test.ts +1 -1
- package/src/__tests__/modelOperationScheduler.test.ts +346 -0
- package/src/__tests__/objectVariable.test.ts +464 -0
- package/src/__tests__/runjsContext.test.ts +216 -35
- package/src/__tests__/runjsContextImplementations.test.ts +217 -0
- package/src/__tests__/runjsContextRuntime.test.ts +269 -0
- package/src/__tests__/runjsEdgeCases.test.ts +281 -0
- package/src/__tests__/runjsLocales.test.ts +36 -0
- package/src/__tests__/runjsRuntimeFeatures.test.ts +461 -0
- package/src/__tests__/runjsSnippets.test.ts +140 -0
- package/src/__tests__/viewScopedFlowEngine.test.ts +3 -3
- package/src/acl/Acl.tsx +14 -0
- package/src/acl/__tests__/Acl.test.tsx +43 -0
- package/src/components/DynamicFlowsEditor.tsx +3 -4
- package/src/components/FieldModelRenderer.tsx +20 -7
- package/src/components/FieldSkeleton.tsx +27 -0
- package/src/components/FlowContextSelector.tsx +6 -2
- package/src/components/FlowModelRenderer.tsx +33 -81
- package/src/components/FormItem.tsx +8 -1
- package/src/components/MobilePopup.style.ts +220 -0
- package/src/components/MobilePopup.tsx +86 -0
- package/src/components/__tests__/flow-model-render-error-fallback.test.tsx +6 -6
- package/src/components/index.ts +1 -0
- package/src/components/settings/independents/dropdown/FlowsDropdownButton.tsx +1 -1
- package/src/components/settings/wrappers/contextual/DefaultSettingsIcon.tsx +17 -4
- package/src/components/settings/wrappers/contextual/FlowsContextMenu.tsx +1 -1
- package/src/components/settings/wrappers/contextual/FlowsFloatContextMenu.tsx +39 -10
- package/src/components/settings/wrappers/contextual/StepSettingsDialog.tsx +14 -1
- package/src/components/settings/wrappers/contextual/__tests__/DefaultSettingsIcon.test.tsx +425 -0
- package/src/components/subModel/__tests__/AddSubModelButton.test.tsx +5 -7
- package/src/components/variables/VariableInput.tsx +25 -5
- package/src/components/variables/VariableTag.tsx +54 -2
- package/src/components/variables/types.ts +2 -0
- package/src/data-source/__tests__/sortCollectionsByInherits.test.ts +125 -0
- package/src/data-source/index.ts +42 -11
- package/src/data-source/sortCollectionsByInherits.ts +61 -0
- package/src/emitter.ts +14 -0
- package/src/executor/FlowExecutor.ts +213 -119
- package/src/executor/__tests__/ctx-defs-injection.test.ts +197 -0
- package/src/executor/__tests__/flowExecutor.test.ts +151 -5
- package/src/flow-registry/GlobalFlowRegistry.ts +1 -0
- package/src/flow-registry/InstanceFlowRegistry.ts +1 -0
- package/src/flow-registry/__tests__/globalFlowRegistry.test.ts +54 -0
- package/src/flowContext.ts +303 -104
- package/src/flowEngine.ts +96 -6
- package/src/flowSettings.ts +12 -4
- package/src/hooks/useApplyAutoFlows.ts +3 -1
- package/src/index.ts +12 -1
- package/src/locale/en-US.json +4 -2
- package/src/locale/zh-CN.json +4 -2
- package/src/models/CollectionFieldModel.tsx +60 -8
- package/src/models/__tests__/dispatchEvent.behavior.test.ts +169 -0
- package/src/models/__tests__/flowModel.getFlows.sort.test.ts +33 -9
- package/src/models/__tests__/flowModel.scheduleModelOperation.test.tsx +129 -0
- package/src/models/__tests__/flowModel.test.ts +234 -111
- package/src/models/__tests__/forkFlowModel.test.ts +40 -7
- package/src/models/flowModel.tsx +197 -132
- package/src/models/forkFlowModel.ts +48 -8
- package/src/provider.tsx +10 -7
- package/src/resources/multiRecordResource.ts +28 -1
- package/src/resources/singleRecordResource.ts +19 -1
- package/src/resources/sqlResource.ts +20 -25
- package/src/runjs-context/contexts/FormJSFieldItemRunJSContext.ts +28 -21
- package/src/runjs-context/contexts/JSBlockRunJSContext.ts +46 -34
- package/src/runjs-context/contexts/JSCollectionActionRunJSContext.ts +15 -16
- package/src/runjs-context/contexts/JSColumnRunJSContext.ts +58 -0
- package/src/runjs-context/contexts/JSFieldRunJSContext.ts +30 -25
- package/src/runjs-context/contexts/JSItemRunJSContext.ts +25 -21
- package/src/runjs-context/contexts/JSRecordActionRunJSContext.ts +17 -18
- package/src/runjs-context/contexts/base.ts +196 -0
- package/src/runjs-context/helpers.ts +32 -30
- package/src/runjs-context/registry.ts +16 -47
- package/src/runjs-context/setup.ts +51 -0
- package/src/runjs-context/snippets/global/api-request.snippet.ts +38 -0
- package/src/runjs-context/snippets/global/clipboard-copy-text.snippet.ts +42 -0
- package/src/runjs-context/snippets/global/import-esm.snippet.ts +39 -0
- package/src/runjs-context/snippets/global/message-error.snippet.ts +6 -0
- package/src/runjs-context/snippets/global/message-success.snippet.ts +6 -0
- package/src/runjs-context/snippets/global/notification-open.snippet.ts +11 -1
- package/src/runjs-context/snippets/global/open-view-dialog.snippet.ts +10 -3
- package/src/runjs-context/snippets/global/open-view-drawer.snippet.ts +10 -3
- package/src/runjs-context/snippets/global/query-selector.snippet.ts +34 -0
- package/src/runjs-context/snippets/global/require-amd.snippet.ts +30 -0
- package/src/runjs-context/snippets/global/window-open.snippet.ts +11 -1
- package/src/runjs-context/snippets/index.ts +178 -39
- package/src/runjs-context/snippets/scene/{jsblock → block}/add-event-listener.snippet.ts +14 -2
- package/src/runjs-context/snippets/scene/block/api-fetch-render-list.snippet.ts +45 -0
- package/src/runjs-context/snippets/scene/block/chartjs-bar.snippet.ts +80 -0
- package/src/runjs-context/snippets/scene/block/echarts-init.snippet.ts +44 -0
- package/src/runjs-context/snippets/scene/block/render-antd-icons.snippet.ts +46 -0
- package/src/runjs-context/snippets/scene/block/render-button-handler.snippet.ts +35 -0
- package/src/runjs-context/snippets/scene/block/render-iframe.snippet.ts +38 -0
- package/src/runjs-context/snippets/scene/block/render-info-card.snippet.ts +52 -0
- package/src/runjs-context/snippets/scene/block/render-react-jsx.snippet.ts +39 -0
- package/src/runjs-context/snippets/scene/block/render-react.snippet.ts +38 -0
- package/src/runjs-context/snippets/scene/block/render-statistics.snippet.ts +76 -0
- package/src/runjs-context/snippets/scene/block/render-timeline.snippet.ts +65 -0
- package/src/runjs-context/snippets/scene/block/resource-example.snippet.ts +46 -0
- package/src/runjs-context/snippets/scene/block/three-users-orbit.snippet.ts +264 -0
- package/src/runjs-context/snippets/scene/block/vue-component.snippet.ts +105 -0
- package/src/runjs-context/snippets/scene/detail/color-by-value.snippet.ts +33 -0
- package/src/runjs-context/snippets/scene/detail/copy-to-clipboard.snippet.ts +45 -0
- package/src/runjs-context/snippets/scene/detail/format-number.snippet.ts +32 -0
- package/src/runjs-context/snippets/scene/detail/innerHTML-value.snippet.ts +31 -0
- package/src/runjs-context/snippets/scene/detail/percentage-bar.snippet.ts +63 -0
- package/src/runjs-context/snippets/scene/detail/relative-time.snippet.ts +61 -0
- package/src/runjs-context/snippets/scene/detail/status-tag.snippet.ts +55 -0
- package/src/runjs-context/snippets/scene/form/calculate-total.snippet.ts +44 -0
- package/src/runjs-context/snippets/scene/form/cascade-select.snippet.ts +62 -0
- package/src/runjs-context/snippets/scene/form/conditional-required.snippet.ts +45 -0
- package/src/runjs-context/snippets/scene/form/copy-field-values.snippet.ts +55 -0
- package/src/runjs-context/snippets/scene/{jsitem → form}/render-basic.snippet.ts +14 -2
- package/src/runjs-context/snippets/scene/{linkage → form}/set-disabled.snippet.ts +15 -3
- package/src/runjs-context/snippets/scene/{linkage → form}/set-field-value.snippet.ts +15 -3
- package/src/runjs-context/snippets/scene/{linkage → form}/set-required.snippet.ts +15 -3
- package/src/runjs-context/snippets/scene/form/toggle-multiple-fields.snippet.ts +48 -0
- package/src/runjs-context/snippets/scene/{linkage → form}/toggle-visible.snippet.ts +15 -3
- package/src/runjs-context/snippets/scene/table/cell-open-dialog.snippet.ts +45 -0
- package/src/runjs-context/snippets/scene/{actions → table}/collection-selected-count.snippet.ts +14 -2
- package/src/runjs-context/snippets/scene/table/concat-fields.snippet.ts +60 -0
- package/src/runjs-context/snippets/scene/table/destroy-selected.snippet.ts +36 -0
- package/src/runjs-context/snippets/scene/table/export-selected-json.snippet.ts +45 -0
- package/src/runjs-context/snippets/scene/{actions → table}/iterate-selected-rows.snippet.ts +14 -2
- package/src/runjs-context/snippets/types.ts +5 -1
- package/src/scheduler/ModelOperationScheduler.ts +304 -0
- package/src/types.ts +34 -0
- package/src/utils/__tests__/flows.test.ts +65 -0
- package/src/utils/__tests__/jsxTransform.test.ts +38 -0
- package/src/utils/__tests__/parsePathnameToViewParams.test.ts +25 -0
- package/src/utils/__tests__/pruneFilter.test.ts +38 -0
- package/src/utils/__tests__/safeGlobals.test.ts +22 -1
- package/src/utils/__tests__/variablesParams.test.ts +63 -0
- package/src/utils/associationObjectVariable.ts +180 -0
- package/src/utils/buildSettingsViewInputArgs.ts +72 -0
- package/src/utils/createEphemeralContext.ts +142 -0
- package/src/utils/flows.ts +23 -0
- package/src/utils/index.ts +11 -2
- package/src/utils/jsxTransform.ts +39 -0
- package/src/utils/params-resolvers.ts +2 -2
- package/src/utils/parsePathnameToViewParams.ts +50 -6
- package/src/utils/pruneFilter.ts +41 -0
- package/src/utils/safeGlobals.ts +49 -3
- package/src/utils/schema-utils.ts +1 -1
- package/src/utils/serverContextParams.ts +1 -0
- package/src/utils/translation.ts +7 -2
- package/src/utils/variablesParams.ts +156 -38
- package/src/views/DrawerComponent.tsx +21 -2
- package/src/views/PageComponent.tsx +1 -1
- package/src/views/ViewNavigation.ts +20 -12
- package/src/views/__tests__/ViewNavigation.test.ts +10 -0
- package/src/views/createViewMeta.ts +393 -70
- package/src/views/index.tsx +1 -0
- package/src/views/useDialog.tsx +24 -18
- package/src/views/useDrawer.tsx +74 -45
- package/src/views/usePage.tsx +26 -17
- package/lib/runjs-context/contexts/FlowRunJSContext.d.ts +0 -38
- package/lib/runjs-context/contexts/FlowRunJSContext.js +0 -217
- package/lib/runjs-context/contexts/LinkageRunJSContext.js +0 -62
- package/lib/runjs-context/index.d.ts +0 -19
- package/lib/runjs-context/index.js +0 -57
- package/lib/runjs-context/snippets/global/api-request-get.snippet.d.ts +0 -16
- package/lib/runjs-context/snippets/global/api-request-get.snippet.js +0 -42
- package/lib/runjs-context/snippets/global/api-request-post.snippet.d.ts +0 -16
- package/lib/runjs-context/snippets/global/console-log-ctx.snippet.d.ts +0 -16
- package/lib/runjs-context/snippets/global/console-log-ctx.snippet.js +0 -41
- package/lib/runjs-context/snippets/global/requireAsync.snippet.d.ts +0 -16
- package/lib/runjs-context/snippets/global/sleep.snippet.d.ts +0 -16
- package/lib/runjs-context/snippets/global/sleep.snippet.js +0 -43
- package/lib/runjs-context/snippets/global/try-catch-async.snippet.d.ts +0 -16
- package/lib/runjs-context/snippets/libs/echarts-init.snippet.d.ts +0 -15
- package/lib/runjs-context/snippets/scene/actions/collection-selected-count.snippet.d.ts +0 -15
- package/lib/runjs-context/snippets/scene/actions/iterate-selected-rows.snippet.d.ts +0 -15
- package/lib/runjs-context/snippets/scene/actions/record-id-message.snippet.d.ts +0 -15
- package/lib/runjs-context/snippets/scene/actions/record-id-message.snippet.js +0 -43
- package/lib/runjs-context/snippets/scene/actions/run-action-basic.snippet.d.ts +0 -15
- package/lib/runjs-context/snippets/scene/actions/run-action-basic.snippet.js +0 -40
- package/lib/runjs-context/snippets/scene/jsblock/add-event-listener.snippet.d.ts +0 -15
- package/lib/runjs-context/snippets/scene/jsblock/append-style.snippet.d.ts +0 -15
- package/lib/runjs-context/snippets/scene/jsblock/append-style.snippet.js +0 -42
- package/lib/runjs-context/snippets/scene/jsblock/jsx-mount.snippet.d.ts +0 -15
- package/lib/runjs-context/snippets/scene/jsblock/jsx-mount.snippet.js +0 -46
- package/lib/runjs-context/snippets/scene/jsblock/jsx-unmount.snippet.d.ts +0 -15
- package/lib/runjs-context/snippets/scene/jsblock/jsx-unmount.snippet.js +0 -41
- package/lib/runjs-context/snippets/scene/jsblock/render-basic.snippet.d.ts +0 -15
- package/lib/runjs-context/snippets/scene/jsblock/render-basic.snippet.js +0 -41
- package/lib/runjs-context/snippets/scene/jsblock/render-button-handler.snippet.d.ts +0 -15
- package/lib/runjs-context/snippets/scene/jsblock/render-react.snippet.d.ts +0 -15
- package/lib/runjs-context/snippets/scene/jsfield/color-by-value.snippet.d.ts +0 -15
- package/lib/runjs-context/snippets/scene/jsfield/format-number.snippet.d.ts +0 -15
- package/lib/runjs-context/snippets/scene/jsfield/innerHTML-value.snippet.d.ts +0 -15
- package/lib/runjs-context/snippets/scene/jsitem/render-basic.snippet.d.ts +0 -15
- package/lib/runjs-context/snippets/scene/linkage/set-disabled.snippet.d.ts +0 -15
- package/lib/runjs-context/snippets/scene/linkage/set-field-value.snippet.d.ts +0 -15
- package/lib/runjs-context/snippets/scene/linkage/set-required.snippet.d.ts +0 -15
- package/lib/runjs-context/snippets/scene/linkage/toggle-visible.snippet.d.ts +0 -15
- package/src/runjs-context/contexts/FlowRunJSContext.ts +0 -190
- package/src/runjs-context/contexts/LinkageRunJSContext.ts +0 -35
- package/src/runjs-context/index.ts +0 -20
- package/src/runjs-context/snippets/global/api-request-get.snippet.ts +0 -20
- package/src/runjs-context/snippets/global/api-request-post.snippet.ts +0 -20
- package/src/runjs-context/snippets/global/console-log-ctx.snippet.ts +0 -19
- package/src/runjs-context/snippets/global/copy-record-json.snippet.ts +0 -21
- package/src/runjs-context/snippets/global/copy-to-clipboard.snippet.ts +0 -21
- package/src/runjs-context/snippets/global/log-json-record.snippet.ts +0 -21
- package/src/runjs-context/snippets/global/requireAsync.snippet.ts +0 -24
- package/src/runjs-context/snippets/global/sleep.snippet.ts +0 -21
- package/src/runjs-context/snippets/global/try-catch-async.snippet.ts +0 -22
- package/src/runjs-context/snippets/global/view-navigation-push.snippet.ts +0 -23
- package/src/runjs-context/snippets/libs/echarts-init.snippet.ts +0 -24
- package/src/runjs-context/snippets/scene/actions/record-id-message.snippet.ts +0 -21
- package/src/runjs-context/snippets/scene/actions/run-action-basic.snippet.ts +0 -18
- package/src/runjs-context/snippets/scene/jsblock/append-style.snippet.ts +0 -20
- package/src/runjs-context/snippets/scene/jsblock/jsx-mount.snippet.ts +0 -24
- package/src/runjs-context/snippets/scene/jsblock/jsx-unmount.snippet.ts +0 -19
- package/src/runjs-context/snippets/scene/jsblock/render-basic.snippet.ts +0 -24
- package/src/runjs-context/snippets/scene/jsblock/render-button-handler.snippet.ts +0 -24
- package/src/runjs-context/snippets/scene/jsblock/render-card.snippet.ts +0 -30
- package/src/runjs-context/snippets/scene/jsblock/render-react.snippet.ts +0 -34
- package/src/runjs-context/snippets/scene/jsfield/color-by-value.snippet.ts +0 -20
- package/src/runjs-context/snippets/scene/jsfield/format-number.snippet.ts +0 -19
- package/src/runjs-context/snippets/scene/jsfield/innerHTML-value.snippet.ts +0 -18
- /package/lib/runjs-context/snippets/global/{copy-record-json.snippet.d.ts → api-request.snippet.d.ts} +0 -0
- /package/lib/runjs-context/snippets/global/{copy-to-clipboard.snippet.d.ts → clipboard-copy-text.snippet.d.ts} +0 -0
- /package/lib/runjs-context/snippets/global/{log-json-record.snippet.d.ts → import-esm.snippet.d.ts} +0 -0
- /package/lib/runjs-context/snippets/global/{view-navigation-push.snippet.d.ts → query-selector.snippet.d.ts} +0 -0
- /package/lib/runjs-context/snippets/scene/{jsblock/render-card.snippet.d.ts → block/echarts-init.snippet.d.ts} +0 -0
package/src/flowEngine.ts
CHANGED
|
@@ -17,6 +17,9 @@ import { FlowSettings } from './flowSettings';
|
|
|
17
17
|
import { ErrorFlowModel, FlowModel } from './models';
|
|
18
18
|
import { ReactView } from './ReactView';
|
|
19
19
|
import { APIResource, FlowResource, MultiRecordResource, SingleRecordResource, SQLResource } from './resources';
|
|
20
|
+
import { Emitter } from './emitter';
|
|
21
|
+
import ModelOperationScheduler from './scheduler/ModelOperationScheduler';
|
|
22
|
+
import type { ScheduleOptions, ScheduledCancel } from './scheduler/ModelOperationScheduler';
|
|
20
23
|
import type {
|
|
21
24
|
ActionDefinition,
|
|
22
25
|
ApplyFlowCacheEntry,
|
|
@@ -114,6 +117,15 @@ export class FlowEngine {
|
|
|
114
117
|
|
|
115
118
|
private _resources = new Map<string, typeof FlowResource>();
|
|
116
119
|
|
|
120
|
+
/**
|
|
121
|
+
* 引擎事件总线(目前用于模型生命周期等事件)。
|
|
122
|
+
* ViewScopedFlowEngine 持有自己的实例,实现作用域隔离。
|
|
123
|
+
*/
|
|
124
|
+
public emitter: Emitter = new Emitter();
|
|
125
|
+
|
|
126
|
+
/** 调度器:仅在 View 作用域引擎本地启用;根/Block 作用域默认不持有 */
|
|
127
|
+
private _modelOperationScheduler?: ModelOperationScheduler;
|
|
128
|
+
|
|
117
129
|
logger: pino.Logger;
|
|
118
130
|
|
|
119
131
|
/**
|
|
@@ -130,7 +142,7 @@ export class FlowEngine {
|
|
|
130
142
|
*/
|
|
131
143
|
public reactView: ReactView;
|
|
132
144
|
/**
|
|
133
|
-
* Flow executor that runs
|
|
145
|
+
* Flow executor that runs event flows.
|
|
134
146
|
*/
|
|
135
147
|
public executor: FlowExecutor;
|
|
136
148
|
|
|
@@ -165,6 +177,35 @@ export class FlowEngine {
|
|
|
165
177
|
this.executor = new FlowExecutor(this);
|
|
166
178
|
}
|
|
167
179
|
|
|
180
|
+
/** 获取/创建当前引擎的调度器(仅在本地作用域) */
|
|
181
|
+
public getScheduler(): ModelOperationScheduler {
|
|
182
|
+
if (!this._modelOperationScheduler) {
|
|
183
|
+
this._modelOperationScheduler = new ModelOperationScheduler(this);
|
|
184
|
+
}
|
|
185
|
+
return this._modelOperationScheduler;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/** 释放并清理当前引擎本地调度器(若存在) */
|
|
189
|
+
public disposeScheduler(): void {
|
|
190
|
+
if (this._modelOperationScheduler) {
|
|
191
|
+
try {
|
|
192
|
+
this._modelOperationScheduler.dispose();
|
|
193
|
+
} finally {
|
|
194
|
+
this._modelOperationScheduler = undefined;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/** 在目标模型生命周期达成时执行操作(仅在 View 引擎本地存储计划) */
|
|
200
|
+
public scheduleModelOperation(
|
|
201
|
+
fromModelOrUid: FlowModel | string,
|
|
202
|
+
toUid: string,
|
|
203
|
+
fn: (model: FlowModel) => Promise<void> | void,
|
|
204
|
+
options?: ScheduleOptions,
|
|
205
|
+
): ScheduledCancel {
|
|
206
|
+
return this.getScheduler().schedule(fromModelOrUid, toUid, fn, options);
|
|
207
|
+
}
|
|
208
|
+
|
|
168
209
|
/** 上一个引擎(根引擎为 undefined) */
|
|
169
210
|
get previousEngine(): FlowEngine | undefined {
|
|
170
211
|
return this._previousEngine;
|
|
@@ -447,6 +488,12 @@ export class FlowEngine {
|
|
|
447
488
|
|
|
448
489
|
modelInstance.onInit(options);
|
|
449
490
|
|
|
491
|
+
// 发射 created 生命周期事件
|
|
492
|
+
void this.emitter.emitAsync('model:created', {
|
|
493
|
+
uid: modelInstance.uid,
|
|
494
|
+
model: modelInstance,
|
|
495
|
+
});
|
|
496
|
+
|
|
450
497
|
// 在模型实例化阶段应用 flow 级 defaultParams(仅填充缺失的 stepParams,不覆盖)
|
|
451
498
|
// 不阻塞创建流程:允许 defaultParams 为异步函数
|
|
452
499
|
this._applyFlowDefinitionDefaultParams(modelInstance as FlowModel).catch((err) => {
|
|
@@ -555,16 +602,32 @@ export class FlowEngine {
|
|
|
555
602
|
if (index !== -1) {
|
|
556
603
|
subModelValue.splice(index, 1);
|
|
557
604
|
modelInstance.parent.emitter.emit('onSubModelRemoved', modelInstance);
|
|
605
|
+
this.emitter?.emit('model:subModel:removed', {
|
|
606
|
+
parentUid: modelInstance.parent.uid,
|
|
607
|
+
parent: modelInstance.parent,
|
|
608
|
+
model: modelInstance,
|
|
609
|
+
});
|
|
558
610
|
break;
|
|
559
611
|
}
|
|
560
612
|
} else if (subModelValue && subModelValue === modelInstance) {
|
|
561
613
|
delete modelInstance.parent.subModels[subKey];
|
|
562
614
|
modelInstance.parent.emitter.emit('onSubModelRemoved', modelInstance);
|
|
615
|
+
this.emitter?.emit('model:subModel:removed', {
|
|
616
|
+
parentUid: modelInstance.parent.uid,
|
|
617
|
+
parent: modelInstance.parent,
|
|
618
|
+
model: modelInstance,
|
|
619
|
+
});
|
|
563
620
|
break;
|
|
564
621
|
}
|
|
565
622
|
}
|
|
566
623
|
}
|
|
567
624
|
this._modelInstances.delete(uid);
|
|
625
|
+
|
|
626
|
+
// 发射 destroyed 生命周期事件(在移除后,但携带实例便于调度器传递;严格模式:不吞错)
|
|
627
|
+
void this.emitter.emitAsync('model:destroyed', {
|
|
628
|
+
uid,
|
|
629
|
+
model: modelInstance,
|
|
630
|
+
});
|
|
568
631
|
return true;
|
|
569
632
|
}
|
|
570
633
|
|
|
@@ -734,6 +797,17 @@ export class FlowEngine {
|
|
|
734
797
|
return this.removeModel(uid);
|
|
735
798
|
}
|
|
736
799
|
|
|
800
|
+
/**
|
|
801
|
+
* Duplicate a model tree via repository API.
|
|
802
|
+
* Returns the duplicated model JSON (root with subModels) or null if not available.
|
|
803
|
+
* @param {string} uid UID of the model to duplicate
|
|
804
|
+
* @returns {Promise<any | null>} Duplicated model JSON or null
|
|
805
|
+
*/
|
|
806
|
+
async duplicateModel(uid: string) {
|
|
807
|
+
if (!this.ensureModelRepository()) return null;
|
|
808
|
+
return this._modelRepository.duplicate(uid);
|
|
809
|
+
}
|
|
810
|
+
|
|
737
811
|
/**
|
|
738
812
|
* Replace a model instance with a new instance of a class.
|
|
739
813
|
* @template T New model type
|
|
@@ -803,9 +877,15 @@ export class FlowEngine {
|
|
|
803
877
|
// 7. 触发事件以通知其他部分模型已替换
|
|
804
878
|
if (currentParent) {
|
|
805
879
|
currentParent.emitter.setPaused(false);
|
|
806
|
-
currentParent.parent.
|
|
880
|
+
currentParent.parent.invalidateFlowCache('beforeRender', true);
|
|
807
881
|
currentParent.parent?.rerender();
|
|
808
882
|
currentParent.emitter.emit('onSubModelReplaced', { oldModel, newModel });
|
|
883
|
+
this.emitter?.emit('model:subModel:replaced', {
|
|
884
|
+
parentUid: currentParent.uid,
|
|
885
|
+
parent: currentParent,
|
|
886
|
+
oldModel,
|
|
887
|
+
newModel,
|
|
888
|
+
});
|
|
809
889
|
}
|
|
810
890
|
await newModel.save();
|
|
811
891
|
return newModel;
|
|
@@ -837,7 +917,8 @@ export class FlowEngine {
|
|
|
837
917
|
return false;
|
|
838
918
|
}
|
|
839
919
|
|
|
840
|
-
const
|
|
920
|
+
const subModelsCopy = [...subModels];
|
|
921
|
+
const findIndex = (model: FlowModel) => subModelsCopy.findIndex((item) => item.uid === model.uid);
|
|
841
922
|
|
|
842
923
|
const currentIndex = findIndex(sourceModel);
|
|
843
924
|
const targetIndex = findIndex(targetModel);
|
|
@@ -853,14 +934,17 @@ export class FlowEngine {
|
|
|
853
934
|
}
|
|
854
935
|
|
|
855
936
|
// 使用splice直接移动数组元素(O(n)比排序O(n log n)更快)
|
|
856
|
-
const [movedModel] =
|
|
857
|
-
|
|
937
|
+
const [movedModel] = subModelsCopy.splice(currentIndex, 1);
|
|
938
|
+
subModelsCopy.splice(targetIndex, 0, movedModel);
|
|
858
939
|
|
|
859
940
|
// 重新分配连续的sortIndex
|
|
860
|
-
|
|
941
|
+
subModelsCopy.forEach((model, index) => {
|
|
861
942
|
model.sortIndex = index;
|
|
862
943
|
});
|
|
863
944
|
|
|
945
|
+
// 更新父模型的subModels引用
|
|
946
|
+
sourceModel.parent.subModels[sourceModel.subKey] = subModelsCopy;
|
|
947
|
+
|
|
864
948
|
return true;
|
|
865
949
|
};
|
|
866
950
|
move(sourceModel, targetModel);
|
|
@@ -870,6 +954,12 @@ export class FlowEngine {
|
|
|
870
954
|
}
|
|
871
955
|
// 触发事件以通知其他部分模型已移动
|
|
872
956
|
sourceModel.parent.emitter.emit('onSubModelMoved', { source: sourceModel, target: targetModel });
|
|
957
|
+
this.emitter?.emit('model:subModel:moved', {
|
|
958
|
+
parentUid: sourceModel.parent?.uid,
|
|
959
|
+
parent: sourceModel.parent,
|
|
960
|
+
source: sourceModel,
|
|
961
|
+
target: targetModel,
|
|
962
|
+
});
|
|
873
963
|
}
|
|
874
964
|
|
|
875
965
|
/**
|
package/src/flowSettings.ts
CHANGED
|
@@ -29,6 +29,7 @@ import {
|
|
|
29
29
|
resolveStepUiSchema,
|
|
30
30
|
resolveUiMode,
|
|
31
31
|
setupRuntimeContextSteps,
|
|
32
|
+
buildSettingsViewInputArgs,
|
|
32
33
|
} from './utils';
|
|
33
34
|
import { FlowStepContext } from './hooks/useFlowStep';
|
|
34
35
|
|
|
@@ -205,8 +206,7 @@ export class FlowSettings {
|
|
|
205
206
|
Upload,
|
|
206
207
|
} = await import('@formily/antd-v5');
|
|
207
208
|
|
|
208
|
-
|
|
209
|
-
const { Button } = await import('antd');
|
|
209
|
+
const { Button, Alert } = await import('antd');
|
|
210
210
|
|
|
211
211
|
// 注册基础组件
|
|
212
212
|
this.components.Form = Form;
|
|
@@ -254,6 +254,7 @@ export class FlowSettings {
|
|
|
254
254
|
this.components.Space = Space;
|
|
255
255
|
this.components.Editable = Editable;
|
|
256
256
|
this.components.PreviewText = PreviewText;
|
|
257
|
+
this.components.Alert = Alert;
|
|
257
258
|
|
|
258
259
|
// 注册按钮组件
|
|
259
260
|
this.components.Button = Button;
|
|
@@ -464,12 +465,14 @@ export class FlowSettings {
|
|
|
464
465
|
flowEngine,
|
|
465
466
|
form,
|
|
466
467
|
onFormValuesChange,
|
|
468
|
+
key,
|
|
467
469
|
}: {
|
|
468
470
|
uiSchema: any;
|
|
469
471
|
initialValues: any;
|
|
470
472
|
flowEngine: any;
|
|
471
473
|
form?: any;
|
|
472
474
|
onFormValuesChange?: (form: any) => void;
|
|
475
|
+
key?: string;
|
|
473
476
|
}): React.ReactElement {
|
|
474
477
|
// 获取 scopes 和 components
|
|
475
478
|
const scopes = {
|
|
@@ -496,7 +499,7 @@ export class FlowSettings {
|
|
|
496
499
|
|
|
497
500
|
return React.createElement(
|
|
498
501
|
FormProviderWithForm,
|
|
499
|
-
{ form, initialValues, onFormValuesChange },
|
|
502
|
+
{ form, initialValues, onFormValuesChange, key },
|
|
500
503
|
React.createElement(SchemaField as any, {
|
|
501
504
|
schema: compiledSchema,
|
|
502
505
|
components: flowEngine?.flowSettings?.components || {},
|
|
@@ -601,7 +604,7 @@ export class FlowSettings {
|
|
|
601
604
|
let actionDefaultParams: Record<string, any> = {};
|
|
602
605
|
let uiMode;
|
|
603
606
|
if (step.use) {
|
|
604
|
-
const action =
|
|
607
|
+
const action = model.getAction?.(step.use);
|
|
605
608
|
if (action) {
|
|
606
609
|
actionDefaultParams = action.defaultParams || {};
|
|
607
610
|
stepTitle = stepTitle || action.title;
|
|
@@ -615,6 +618,9 @@ export class FlowSettings {
|
|
|
615
618
|
const flowRuntimeContext = new FlowRuntimeContext(model as any, fk, 'settings');
|
|
616
619
|
setupRuntimeContextSteps(flowRuntimeContext as any, flow.steps, model as any, fk);
|
|
617
620
|
flowRuntimeContext.defineProperty('currentStep', { value: step });
|
|
621
|
+
flowRuntimeContext.defineMethod('getStepFormValues', (flowKey: string, stepKey: string) => {
|
|
622
|
+
return forms.get(keyOf({ flowKey, stepKey }))?.values;
|
|
623
|
+
});
|
|
618
624
|
|
|
619
625
|
// 解析默认值 + 当前参数
|
|
620
626
|
const modelStepParams = (model as any).getStepParams(fk, sk) || {};
|
|
@@ -764,6 +770,8 @@ export class FlowSettings {
|
|
|
764
770
|
zIndex: 5000,
|
|
765
771
|
// 允许透传其它 props(如 maskClosable、footer 等),但确保 content 由我们接管
|
|
766
772
|
...modeProps,
|
|
773
|
+
// 统一构造 settings 弹窗的 inputArgs(集合/记录/父导航/关联)
|
|
774
|
+
inputArgs: buildSettingsViewInputArgs(model as any, (modeProps as any)?.inputArgs),
|
|
767
775
|
content: (currentView, viewCtx) => {
|
|
768
776
|
viewCtx?.defineMethod('getStepFormValues', (flowKey: string, stepKey: string) => {
|
|
769
777
|
return forms.get(keyOf({ flowKey, stepKey }))?.values;
|
|
@@ -35,7 +35,9 @@ export function useApplyAutoFlows(
|
|
|
35
35
|
|
|
36
36
|
const { loading, error } = useRequest(
|
|
37
37
|
async () => {
|
|
38
|
-
|
|
38
|
+
if (!model) return;
|
|
39
|
+
// beforeRender 在模型层默认顺序执行并默认使用缓存(可覆盖)
|
|
40
|
+
await model.dispatchEvent('beforeRender', inputArgs);
|
|
39
41
|
},
|
|
40
42
|
{
|
|
41
43
|
refreshDeps: [model, inputArgs],
|
package/src/index.ts
CHANGED
|
@@ -12,6 +12,7 @@ export * from './types';
|
|
|
12
12
|
|
|
13
13
|
// 工具函数
|
|
14
14
|
export * from './utils';
|
|
15
|
+
export { compileRunJs } from './utils/jsxTransform';
|
|
15
16
|
|
|
16
17
|
// 资源类
|
|
17
18
|
export * from './resources';
|
|
@@ -31,8 +32,18 @@ export * from './ElementProxy';
|
|
|
31
32
|
export * from './flowContext';
|
|
32
33
|
export * from './FlowContextProvider';
|
|
33
34
|
export * from './JSRunner';
|
|
34
|
-
export
|
|
35
|
+
export {
|
|
36
|
+
getRunJSDocFor,
|
|
37
|
+
createJSRunnerWithVersion,
|
|
38
|
+
getRunJSScenesForModel,
|
|
39
|
+
getRunJSScenesForContext,
|
|
40
|
+
} from './runjs-context/helpers';
|
|
41
|
+
export { RunJSContextRegistry, getModelClassName } from './runjs-context/registry';
|
|
42
|
+
export { setupRunJSContexts } from './runjs-context/setup';
|
|
43
|
+
export { getSnippetBody, listSnippetsForContext } from './runjs-context/snippets';
|
|
35
44
|
|
|
36
45
|
export * from './views';
|
|
37
46
|
|
|
38
47
|
export * from './FlowDefinition';
|
|
48
|
+
export { createViewScopedEngine } from './ViewScopedFlowEngine';
|
|
49
|
+
export { createBlockScopedEngine } from './BlockScopedFlowEngine';
|
package/src/locale/en-US.json
CHANGED
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
"UID copied to clipboard": "UID copied to clipboard",
|
|
24
24
|
"Copy failed": "Copy failed",
|
|
25
25
|
"Copy failed, please copy [{{uid}}] manually.": "Copy failed, please copy [{{uid}}] manually.",
|
|
26
|
+
"Copy failed under HTTP. Clipboard API is unavailable on non-HTTPS pages. Please copy [{{uid}}] manually.": "Copy failed under HTTP. Clipboard API is unavailable on non-HTTPS pages. Please copy [{{uid}}] manually.",
|
|
26
27
|
"Confirm delete": "Confirm delete",
|
|
27
28
|
"Are you sure you want to delete this item? This action cannot be undone.": "Are you sure you want to delete this item? This action cannot be undone.",
|
|
28
29
|
"Delete operation failed": "Delete operation failed",
|
|
@@ -57,5 +58,6 @@
|
|
|
57
58
|
"Name": "Name",
|
|
58
59
|
"Model with ID {{uid}} not found": "Model with ID {{uid}} not found",
|
|
59
60
|
"Common actions": "Common actions",
|
|
60
|
-
"This variable is not available": "This variable is not available"
|
|
61
|
-
|
|
61
|
+
"This variable is not available": "This variable is not available",
|
|
62
|
+
"Copy popup UID": "Copy popup UID"
|
|
63
|
+
}
|
package/src/locale/zh-CN.json
CHANGED
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
"UID copied to clipboard": "UID 已复制到剪贴板",
|
|
24
24
|
"Copy failed": "复制失败",
|
|
25
25
|
"Copy failed, please copy [{{uid}}] manually.": "复制失败,请手动复制 [{{uid}}]。",
|
|
26
|
+
"Copy failed under HTTP. Clipboard API is unavailable on non-HTTPS pages. Please copy [{{uid}}] manually.": "HTTP 环境下复制失败。非 HTTPS 页面不支持剪贴板 API,请手动复制 [{{uid}}]。",
|
|
26
27
|
"Confirm delete": "确认删除",
|
|
27
28
|
"Are you sure you want to delete this item? This action cannot be undone.": "确定要删除此项吗?此操作不可撤销。",
|
|
28
29
|
"Delete operation failed": "删除操作失败",
|
|
@@ -57,5 +58,6 @@
|
|
|
57
58
|
"Name": "名称",
|
|
58
59
|
"Model with ID {{uid}} not found": "未找到 ID 为 {{uid}} 的模型",
|
|
59
60
|
"Common actions": "通用操作",
|
|
60
|
-
"This variable is not available": "此变量不可用"
|
|
61
|
-
|
|
61
|
+
"This variable is not available": "此变量不可用",
|
|
62
|
+
"Copy popup UID": "复制弹窗 UID"
|
|
63
|
+
}
|
|
@@ -9,14 +9,17 @@
|
|
|
9
9
|
|
|
10
10
|
import { Card, Form } from 'antd';
|
|
11
11
|
import _ from 'lodash';
|
|
12
|
-
import React from 'react';
|
|
12
|
+
import React, { useMemo } from 'react';
|
|
13
|
+
import { useTranslation } from 'react-i18next';
|
|
13
14
|
import { CollectionField } from '../data-source';
|
|
14
15
|
import { FlowEngineContext } from '../flowContext';
|
|
16
|
+
import { useFlowModel } from '../hooks';
|
|
15
17
|
import { DefaultStructure } from '../types';
|
|
16
18
|
import { escapeT } from '../utils';
|
|
17
19
|
import { FlowModel } from './flowModel';
|
|
18
20
|
|
|
19
21
|
export function FieldPlaceholder() {
|
|
22
|
+
const { t } = useTranslation();
|
|
20
23
|
return (
|
|
21
24
|
<Form.Item>
|
|
22
25
|
<Card
|
|
@@ -27,12 +30,42 @@ export function FieldPlaceholder() {
|
|
|
27
30
|
},
|
|
28
31
|
}}
|
|
29
32
|
>
|
|
30
|
-
|
|
33
|
+
{t(
|
|
34
|
+
'This field has been hidden and you cannot view it (this content is only visible when the UI Editor is activated).',
|
|
35
|
+
)}
|
|
31
36
|
</Card>
|
|
32
37
|
</Form.Item>
|
|
33
38
|
);
|
|
34
39
|
}
|
|
35
40
|
|
|
41
|
+
export function FieldDeletePlaceholder() {
|
|
42
|
+
const { t } = useTranslation();
|
|
43
|
+
const model: any = useFlowModel();
|
|
44
|
+
const blockModel = model.context.blockModel;
|
|
45
|
+
const dataSource = blockModel.collection.dataSource;
|
|
46
|
+
const collection = blockModel.collection;
|
|
47
|
+
const name = model.fieldPath;
|
|
48
|
+
const nameValue = useMemo(() => {
|
|
49
|
+
const dataSourcePrefix = `${t(dataSource.displayName || dataSource.key)} > `;
|
|
50
|
+
const collectionPrefix = collection ? `${t(collection.title) || collection.name || collection.tableName} > ` : '';
|
|
51
|
+
return `${dataSourcePrefix}${collectionPrefix}${name}`;
|
|
52
|
+
}, []);
|
|
53
|
+
return (
|
|
54
|
+
<Form.Item>
|
|
55
|
+
<div
|
|
56
|
+
style={{
|
|
57
|
+
color: 'rgba(0,0,0,0.45)',
|
|
58
|
+
}}
|
|
59
|
+
>
|
|
60
|
+
{t(`The {{type}} "{{name}}" may have been deleted. Please remove this {{blockType}}.`, {
|
|
61
|
+
type: t('Field'),
|
|
62
|
+
name: nameValue,
|
|
63
|
+
blockType: t('Field'),
|
|
64
|
+
}).replaceAll('>', '>')}
|
|
65
|
+
</div>
|
|
66
|
+
</Form.Item>
|
|
67
|
+
);
|
|
68
|
+
}
|
|
36
69
|
export interface FieldSettingsInitParams {
|
|
37
70
|
dataSourceKey: string;
|
|
38
71
|
collectionName: string;
|
|
@@ -51,8 +84,12 @@ const defaultWhen = () => true;
|
|
|
51
84
|
|
|
52
85
|
export class CollectionFieldModel<T extends DefaultStructure = DefaultStructure> extends FlowModel<T> {
|
|
53
86
|
private static _bindings = new Map();
|
|
87
|
+
fieldDeleted = false;
|
|
54
88
|
|
|
55
89
|
renderHiddenInConfig(): React.ReactNode | undefined {
|
|
90
|
+
if (this.fieldDeleted) {
|
|
91
|
+
return <FieldDeletePlaceholder />;
|
|
92
|
+
}
|
|
56
93
|
return <FieldPlaceholder />;
|
|
57
94
|
}
|
|
58
95
|
|
|
@@ -76,12 +113,14 @@ export class CollectionFieldModel<T extends DefaultStructure = DefaultStructure>
|
|
|
76
113
|
return this.fieldPath;
|
|
77
114
|
},
|
|
78
115
|
});
|
|
79
|
-
this.context.blockModel
|
|
80
|
-
|
|
116
|
+
if (this.context.blockModel) {
|
|
117
|
+
this.context.blockModel.addAppends(this.fieldPath);
|
|
118
|
+
this.context.blockModel.addAppends(this.associationPathName);
|
|
119
|
+
}
|
|
81
120
|
}
|
|
82
121
|
|
|
83
122
|
getFieldSettingsInitParams(): FieldSettingsInitParams {
|
|
84
|
-
return this.getStepParams('fieldSettings', 'init');
|
|
123
|
+
return this.getStepParams('fieldSettings', 'init') || {};
|
|
85
124
|
}
|
|
86
125
|
|
|
87
126
|
get fieldPath(): string {
|
|
@@ -103,6 +142,9 @@ export class CollectionFieldModel<T extends DefaultStructure = DefaultStructure>
|
|
|
103
142
|
}
|
|
104
143
|
|
|
105
144
|
static getBindingsByField(ctx: FlowEngineContext, collectionField: CollectionField): BindingOptions[] {
|
|
145
|
+
if (!collectionField) {
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
106
148
|
const interfaceName = collectionField.interface;
|
|
107
149
|
|
|
108
150
|
// Check if the interface exists in the map
|
|
@@ -120,13 +162,23 @@ export class CollectionFieldModel<T extends DefaultStructure = DefaultStructure>
|
|
|
120
162
|
static getDefaultBindingByField(
|
|
121
163
|
ctx: FlowEngineContext,
|
|
122
164
|
collectionField: CollectionField,
|
|
123
|
-
options: {
|
|
165
|
+
options: {
|
|
166
|
+
useStrict?: boolean;
|
|
167
|
+
fallbackToTargetTitleField?: boolean;
|
|
168
|
+
targetCollectionTitleField?: CollectionField;
|
|
169
|
+
} = {},
|
|
124
170
|
): BindingOptions | null {
|
|
125
171
|
if (options.fallbackToTargetTitleField) {
|
|
126
172
|
const binding = this.getDefaultBindingByField(ctx, collectionField, { useStrict: true });
|
|
127
173
|
if (!binding) {
|
|
128
|
-
if (
|
|
129
|
-
|
|
174
|
+
if (
|
|
175
|
+
(collectionField.isAssociationField() && options?.targetCollectionTitleField) ||
|
|
176
|
+
collectionField.targetCollectionTitleField
|
|
177
|
+
) {
|
|
178
|
+
return this.getDefaultBindingByField(
|
|
179
|
+
ctx,
|
|
180
|
+
options?.targetCollectionTitleField || collectionField.targetCollectionTitleField,
|
|
181
|
+
);
|
|
130
182
|
}
|
|
131
183
|
}
|
|
132
184
|
return binding;
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of the NocoBase (R) project.
|
|
3
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
+
* Authors: NocoBase Team.
|
|
5
|
+
*
|
|
6
|
+
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
+
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { describe, test, expect } from 'vitest';
|
|
11
|
+
import { FlowEngine } from '../../flowEngine';
|
|
12
|
+
import { FlowModel } from '../../models/flowModel';
|
|
13
|
+
|
|
14
|
+
describe('dispatchEvent behavior (defaults, parallel, errors)', () => {
|
|
15
|
+
test('non-beforeRender defaults to sequential execution and respects getEventFlows order', async () => {
|
|
16
|
+
const engine = new FlowEngine();
|
|
17
|
+
class M extends FlowModel {}
|
|
18
|
+
engine.registerModels({ M });
|
|
19
|
+
|
|
20
|
+
const calls: string[] = [];
|
|
21
|
+
|
|
22
|
+
// Static flow with higher sort
|
|
23
|
+
M.registerFlow({
|
|
24
|
+
key: 'S',
|
|
25
|
+
on: { eventName: 'go' },
|
|
26
|
+
sort: 10,
|
|
27
|
+
steps: { s: { handler: async () => void calls.push('static') } as any },
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
const model = engine.createModel({ use: 'M' });
|
|
31
|
+
|
|
32
|
+
// Instance flows
|
|
33
|
+
model.registerFlow('I1', {
|
|
34
|
+
on: { eventName: 'go' },
|
|
35
|
+
sort: 0,
|
|
36
|
+
steps: { i1: { handler: async () => void calls.push('inst1') } as any },
|
|
37
|
+
});
|
|
38
|
+
model.registerFlow('I2', {
|
|
39
|
+
on: { eventName: 'go' },
|
|
40
|
+
sort: 5,
|
|
41
|
+
steps: { i2: { handler: async () => void calls.push('inst2') } as any },
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
// No options provided -> should default to sequential execution
|
|
45
|
+
await model.dispatchEvent('go');
|
|
46
|
+
|
|
47
|
+
// Expected order should match getEventFlows('go') order
|
|
48
|
+
const expected = model.getEventFlows('go').map((f) => f.key);
|
|
49
|
+
expect(calls).toEqual(expected.map((k) => (k === 'I1' ? 'inst1' : k === 'I2' ? 'inst2' : 'static')));
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
test('parallel mode (sequential=false) runs all and tolerates non-beforeRender errors', async () => {
|
|
53
|
+
const engine = new FlowEngine();
|
|
54
|
+
class M extends FlowModel {}
|
|
55
|
+
engine.registerModels({ M });
|
|
56
|
+
|
|
57
|
+
const calls: string[] = [];
|
|
58
|
+
|
|
59
|
+
M.registerFlow({
|
|
60
|
+
key: 'S',
|
|
61
|
+
on: { eventName: 'go' },
|
|
62
|
+
sort: 1,
|
|
63
|
+
steps: { s: { handler: async () => 'static-ok' } as any },
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
const model = engine.createModel({ use: 'M' });
|
|
67
|
+
|
|
68
|
+
model.registerFlow('I1', {
|
|
69
|
+
on: { eventName: 'go' },
|
|
70
|
+
sort: 0,
|
|
71
|
+
steps: { i1: { handler: async () => (calls.push('inst1'), 'i1-ok') } as any },
|
|
72
|
+
});
|
|
73
|
+
model.registerFlow('I2', {
|
|
74
|
+
on: { eventName: 'go' },
|
|
75
|
+
sort: 2,
|
|
76
|
+
steps: { i2: { handler: async () => (calls.push('inst2'), 'i2-ok') } as any },
|
|
77
|
+
});
|
|
78
|
+
model.registerFlow('ERR', {
|
|
79
|
+
on: { eventName: 'go' },
|
|
80
|
+
sort: 3,
|
|
81
|
+
steps: {
|
|
82
|
+
e: {
|
|
83
|
+
handler: async () => {
|
|
84
|
+
calls.push('err');
|
|
85
|
+
throw new Error('boom');
|
|
86
|
+
},
|
|
87
|
+
} as any,
|
|
88
|
+
},
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
const results = await model.dispatchEvent('go', undefined, { sequential: false });
|
|
92
|
+
|
|
93
|
+
// All handlers ran; order is not guaranteed in parallel mode
|
|
94
|
+
expect(new Set(calls)).toEqual(new Set(['inst1', 'inst2', 'err']));
|
|
95
|
+
// The error flow returns undefined and is filtered out; others return stepResults objects
|
|
96
|
+
// Expect one result object per successful flow with its step key
|
|
97
|
+
expect(Array.isArray(results)).toBe(true);
|
|
98
|
+
const keys = (results as any[]).flatMap((o) => Object.keys(o));
|
|
99
|
+
expect(new Set(keys)).toEqual(new Set(['i1', 'i2', 's']));
|
|
100
|
+
const byKey = Object.assign({}, ...(results as any[]));
|
|
101
|
+
expect(byKey['i1']).toBe('i1-ok');
|
|
102
|
+
expect(byKey['i2']).toBe('i2-ok');
|
|
103
|
+
expect(byKey['s']).toBe('static-ok');
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
test('sequential non-beforeRender: stops subsequent flows on error', async () => {
|
|
107
|
+
const engine = new FlowEngine();
|
|
108
|
+
class M extends FlowModel {}
|
|
109
|
+
engine.registerModels({ M });
|
|
110
|
+
|
|
111
|
+
const calls: string[] = [];
|
|
112
|
+
const model = engine.createModel({ use: 'M' });
|
|
113
|
+
|
|
114
|
+
model.registerFlow('I1', {
|
|
115
|
+
on: { eventName: 'go' },
|
|
116
|
+
sort: 0,
|
|
117
|
+
steps: { i1: { handler: async () => void calls.push('i1') } as any },
|
|
118
|
+
});
|
|
119
|
+
model.registerFlow('ERR', {
|
|
120
|
+
on: { eventName: 'go' },
|
|
121
|
+
sort: 1,
|
|
122
|
+
steps: {
|
|
123
|
+
e: {
|
|
124
|
+
handler: async () => {
|
|
125
|
+
throw new Error('X');
|
|
126
|
+
},
|
|
127
|
+
} as any,
|
|
128
|
+
},
|
|
129
|
+
});
|
|
130
|
+
model.registerFlow('I2', {
|
|
131
|
+
on: { eventName: 'go' },
|
|
132
|
+
sort: 2,
|
|
133
|
+
steps: { i2: { handler: async () => void calls.push('i2') } as any },
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
await model.dispatchEvent('go', undefined, { sequential: true }).catch(() => undefined);
|
|
137
|
+
// 只应执行第一个 flow,后续被中止
|
|
138
|
+
expect(calls).toEqual(['i1']);
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
test('beforeRender errors are thrown (sequential default)', async () => {
|
|
142
|
+
const engine = new FlowEngine();
|
|
143
|
+
class M extends FlowModel {}
|
|
144
|
+
engine.registerModels({ M });
|
|
145
|
+
|
|
146
|
+
const calls: string[] = [];
|
|
147
|
+
const model = engine.createModel({ use: 'M' });
|
|
148
|
+
|
|
149
|
+
model.registerFlow('F1', {
|
|
150
|
+
on: 'beforeRender',
|
|
151
|
+
sort: 0,
|
|
152
|
+
steps: {
|
|
153
|
+
a: {
|
|
154
|
+
handler: async () => {
|
|
155
|
+
throw new Error('BR');
|
|
156
|
+
},
|
|
157
|
+
} as any,
|
|
158
|
+
},
|
|
159
|
+
});
|
|
160
|
+
model.registerFlow('F2', {
|
|
161
|
+
on: 'beforeRender',
|
|
162
|
+
sort: 1,
|
|
163
|
+
steps: { b: { handler: async () => void calls.push('b') } as any },
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
await expect(model.dispatchEvent('beforeRender', undefined, { useCache: false })).rejects.toThrow('BR');
|
|
167
|
+
expect(calls).toEqual([]);
|
|
168
|
+
});
|
|
169
|
+
});
|