@nocobase/flow-engine 2.0.0-alpha.2
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/LICENSE +661 -0
- package/README.md +30 -0
- package/lib/ContextPathProxy.d.ts +17 -0
- package/lib/ContextPathProxy.js +65 -0
- package/lib/ElementProxy.d.ts +17 -0
- package/lib/ElementProxy.js +93 -0
- package/lib/FlowContextProvider.d.ts +24 -0
- package/lib/FlowContextProvider.js +82 -0
- package/lib/FlowDefinition.d.ts +423 -0
- package/lib/FlowDefinition.js +257 -0
- package/lib/JSRunner.d.ts +32 -0
- package/lib/JSRunner.js +95 -0
- package/lib/ReactView.d.ts +20 -0
- package/lib/ReactView.js +120 -0
- package/lib/ViewScopedFlowEngine.d.ts +23 -0
- package/lib/ViewScopedFlowEngine.js +81 -0
- package/lib/acl/Acl.d.ts +31 -0
- package/lib/acl/Acl.js +115 -0
- package/lib/action-registry/BaseActionRegistry.d.ts +23 -0
- package/lib/action-registry/BaseActionRegistry.js +57 -0
- package/lib/action-registry/EngineActionRegistry.d.ts +20 -0
- package/lib/action-registry/EngineActionRegistry.js +47 -0
- package/lib/action-registry/ModelActionRegistry.d.ts +34 -0
- package/lib/action-registry/ModelActionRegistry.js +79 -0
- package/lib/components/DynamicFlowsEditor.d.ts +17 -0
- package/lib/components/DynamicFlowsEditor.js +49 -0
- package/lib/components/FieldModelRenderer.d.ts +10 -0
- package/lib/components/FieldModelRenderer.js +94 -0
- package/lib/components/FlowContextSelector.d.ts +11 -0
- package/lib/components/FlowContextSelector.js +221 -0
- package/lib/components/FlowErrorFallback.d.ts +25 -0
- package/lib/components/FlowErrorFallback.js +264 -0
- package/lib/components/FlowModelRenderer.d.ts +64 -0
- package/lib/components/FlowModelRenderer.js +254 -0
- package/lib/components/FormItem.d.ts +18 -0
- package/lib/components/FormItem.js +147 -0
- package/lib/components/common/FlowSettingsButton.d.ts +11 -0
- package/lib/components/common/FlowSettingsButton.js +66 -0
- package/lib/components/common/index.d.ts +9 -0
- package/lib/components/common/index.js +30 -0
- package/lib/components/common/withFlowDesignMode.d.ts +26 -0
- package/lib/components/common/withFlowDesignMode.js +61 -0
- package/lib/components/dnd/getMousePositionOnElement.d.ts +50 -0
- package/lib/components/dnd/getMousePositionOnElement.js +95 -0
- package/lib/components/dnd/index.d.ts +24 -0
- package/lib/components/dnd/index.js +164 -0
- package/lib/components/dnd/moveBlock.d.ts +33 -0
- package/lib/components/dnd/moveBlock.js +302 -0
- package/lib/components/index.d.ts +18 -0
- package/lib/components/index.js +48 -0
- package/lib/components/settings/independents/dropdown/FlowsDropdownButton.d.ts +46 -0
- package/lib/components/settings/independents/dropdown/FlowsDropdownButton.js +225 -0
- package/lib/components/settings/independents/dropdown/index.d.ts +9 -0
- package/lib/components/settings/independents/dropdown/index.js +30 -0
- package/lib/components/settings/independents/index.d.ts +1 -0
- package/lib/components/settings/independents/index.js +30 -0
- package/lib/components/settings/index.d.ts +10 -0
- package/lib/components/settings/index.js +32 -0
- package/lib/components/settings/wrappers/contextual/DefaultSettingsIcon.d.ts +24 -0
- package/lib/components/settings/wrappers/contextual/DefaultSettingsIcon.js +501 -0
- package/lib/components/settings/wrappers/contextual/FlowsContextMenu.d.ts +45 -0
- package/lib/components/settings/wrappers/contextual/FlowsContextMenu.js +231 -0
- package/lib/components/settings/wrappers/contextual/FlowsFloatContextMenu.d.ts +111 -0
- package/lib/components/settings/wrappers/contextual/FlowsFloatContextMenu.js +484 -0
- package/lib/components/settings/wrappers/contextual/StepRequiredSettingsDialog.d.ts +26 -0
- package/lib/components/settings/wrappers/contextual/StepRequiredSettingsDialog.js +342 -0
- package/lib/components/settings/wrappers/contextual/StepSettings.d.ts +23 -0
- package/lib/components/settings/wrappers/contextual/StepSettings.js +110 -0
- package/lib/components/settings/wrappers/contextual/StepSettingsDialog.d.ts +20 -0
- package/lib/components/settings/wrappers/contextual/StepSettingsDialog.js +206 -0
- package/lib/components/settings/wrappers/contextual/StepSettingsDrawer.d.ts +20 -0
- package/lib/components/settings/wrappers/contextual/StepSettingsDrawer.js +47 -0
- package/lib/components/settings/wrappers/contextual/index.d.ts +14 -0
- package/lib/components/settings/wrappers/contextual/index.js +40 -0
- package/lib/components/settings/wrappers/embedded/FlowSettings.d.ts +33 -0
- package/lib/components/settings/wrappers/embedded/FlowSettings.js +207 -0
- package/lib/components/settings/wrappers/embedded/FlowsSettings.d.ts +41 -0
- package/lib/components/settings/wrappers/embedded/FlowsSettings.js +84 -0
- package/lib/components/settings/wrappers/embedded/FlowsSettingsContent.d.ts +16 -0
- package/lib/components/settings/wrappers/embedded/FlowsSettingsContent.js +88 -0
- package/lib/components/settings/wrappers/embedded/index.d.ts +10 -0
- package/lib/components/settings/wrappers/embedded/index.js +32 -0
- package/lib/components/settings/wrappers/index.d.ts +2 -0
- package/lib/components/settings/wrappers/index.js +32 -0
- package/lib/components/subModel/AddSubModelButton.d.ts +62 -0
- package/lib/components/subModel/AddSubModelButton.js +415 -0
- package/lib/components/subModel/LazyDropdown.d.ts +55 -0
- package/lib/components/subModel/LazyDropdown.js +524 -0
- package/lib/components/subModel/index.d.ts +10 -0
- package/lib/components/subModel/index.js +32 -0
- package/lib/components/subModel/utils.d.ts +34 -0
- package/lib/components/subModel/utils.js +287 -0
- package/lib/components/variables/InlineVariableTag.d.ts +21 -0
- package/lib/components/variables/InlineVariableTag.js +123 -0
- package/lib/components/variables/SlateVariableEditor.d.ts +46 -0
- package/lib/components/variables/SlateVariableEditor.js +302 -0
- package/lib/components/variables/VariableInput.d.ts +11 -0
- package/lib/components/variables/VariableInput.js +322 -0
- package/lib/components/variables/VariableTag.d.ts +11 -0
- package/lib/components/variables/VariableTag.js +148 -0
- package/lib/components/variables/VariableTrigger.d.ts +20 -0
- package/lib/components/variables/VariableTrigger.js +136 -0
- package/lib/components/variables/index.d.ts +15 -0
- package/lib/components/variables/index.js +53 -0
- package/lib/components/variables/types.d.ts +93 -0
- package/lib/components/variables/types.js +24 -0
- package/lib/components/variables/useResolvedMetaTree.d.ts +19 -0
- package/lib/components/variables/useResolvedMetaTree.js +91 -0
- package/lib/components/variables/utils.d.ts +22 -0
- package/lib/components/variables/utils.js +177 -0
- package/lib/data-source/index.d.ts +180 -0
- package/lib/data-source/index.js +733 -0
- package/lib/data-source/jioToJoiSchema.d.ts +19 -0
- package/lib/data-source/jioToJoiSchema.js +114 -0
- package/lib/decorators/index.d.ts +9 -0
- package/lib/decorators/index.js +36 -0
- package/lib/decorators/largeField.d.ts +9 -0
- package/lib/decorators/largeField.js +42 -0
- package/lib/emitter.d.ts +16 -0
- package/lib/emitter.js +58 -0
- package/lib/event-registry/BaseEventRegistry.d.ts +22 -0
- package/lib/event-registry/BaseEventRegistry.js +57 -0
- package/lib/event-registry/EngineEventRegistry.d.ts +19 -0
- package/lib/event-registry/EngineEventRegistry.js +47 -0
- package/lib/event-registry/ModelEventRegistry.d.ts +33 -0
- package/lib/event-registry/ModelEventRegistry.js +79 -0
- package/lib/executor/FlowExecutor.d.ts +26 -0
- package/lib/executor/FlowExecutor.js +262 -0
- package/lib/flow-registry/BaseFlowRegistry.d.ts +46 -0
- package/lib/flow-registry/BaseFlowRegistry.js +86 -0
- package/lib/flow-registry/GlobalFlowRegistry.d.ts +22 -0
- package/lib/flow-registry/GlobalFlowRegistry.js +95 -0
- package/lib/flow-registry/InstanceFlowRegistry.d.ts +21 -0
- package/lib/flow-registry/InstanceFlowRegistry.js +59 -0
- package/lib/flow-registry/index.d.ts +11 -0
- package/lib/flow-registry/index.js +34 -0
- package/lib/flowContext.d.ts +215 -0
- package/lib/flowContext.js +1266 -0
- package/lib/flowEngine.d.ts +340 -0
- package/lib/flowEngine.js +781 -0
- package/lib/flowI18n.d.ts +46 -0
- package/lib/flowI18n.js +117 -0
- package/lib/flowSettings.d.ts +266 -0
- package/lib/flowSettings.js +850 -0
- package/lib/hooks/index.d.ts +14 -0
- package/lib/hooks/index.js +40 -0
- package/lib/hooks/useApplyAutoFlows.d.ts +21 -0
- package/lib/hooks/useApplyAutoFlows.js +62 -0
- package/lib/hooks/useFlowModel.d.ts +29 -0
- package/lib/hooks/useFlowModel.js +72 -0
- package/lib/hooks/useFlowModelById.d.ts +11 -0
- package/lib/hooks/useFlowModelById.js +61 -0
- package/lib/hooks/useFlowSettingsContext.d.ts +20 -0
- package/lib/hooks/useFlowSettingsContext.js +61 -0
- package/lib/hooks/useFlowStep.d.ts +17 -0
- package/lib/hooks/useFlowStep.js +56 -0
- package/lib/hooks/useNiceDropdownMaxHeight.d.ts +13 -0
- package/lib/hooks/useNiceDropdownMaxHeight.js +52 -0
- package/lib/index.d.ts +27 -0
- package/lib/index.js +73 -0
- package/lib/locale/en-US.json +61 -0
- package/lib/locale/index.d.ts +141 -0
- package/lib/locale/index.js +70 -0
- package/lib/locale/zh-CN.json +61 -0
- package/lib/models/CollectionFieldModel.d.ts +50 -0
- package/lib/models/CollectionFieldModel.js +242 -0
- package/lib/models/DisplayItemModel.d.ts +12 -0
- package/lib/models/DisplayItemModel.js +41 -0
- package/lib/models/EditableItemModel.d.ts +12 -0
- package/lib/models/EditableItemModel.js +41 -0
- package/lib/models/FilterableItemModel.d.ts +12 -0
- package/lib/models/FilterableItemModel.js +41 -0
- package/lib/models/flowModel.d.ts +344 -0
- package/lib/models/flowModel.js +1133 -0
- package/lib/models/forkFlowModel.d.ts +83 -0
- package/lib/models/forkFlowModel.js +257 -0
- package/lib/models/index.d.ts +14 -0
- package/lib/models/index.js +40 -0
- package/lib/provider.d.ts +22 -0
- package/lib/provider.js +114 -0
- package/lib/resources/apiResource.d.ts +34 -0
- package/lib/resources/apiResource.js +153 -0
- package/lib/resources/baseRecordResource.d.ts +61 -0
- package/lib/resources/baseRecordResource.js +264 -0
- package/lib/resources/filterItem.d.ts +33 -0
- package/lib/resources/filterItem.js +93 -0
- package/lib/resources/flowResource.d.ts +45 -0
- package/lib/resources/flowResource.js +146 -0
- package/lib/resources/index.d.ts +15 -0
- package/lib/resources/index.js +42 -0
- package/lib/resources/multiRecordResource.d.ts +53 -0
- package/lib/resources/multiRecordResource.js +230 -0
- package/lib/resources/singleRecordResource.d.ts +23 -0
- package/lib/resources/singleRecordResource.js +111 -0
- package/lib/resources/sqlResource.d.ts +73 -0
- package/lib/resources/sqlResource.js +294 -0
- package/lib/runjs-context/contexts/FlowRunJSContext.d.ts +38 -0
- package/lib/runjs-context/contexts/FlowRunJSContext.js +217 -0
- package/lib/runjs-context/contexts/FormJSFieldItemRunJSContext.d.ts +16 -0
- package/lib/runjs-context/contexts/FormJSFieldItemRunJSContext.js +66 -0
- package/lib/runjs-context/contexts/JSBlockRunJSContext.d.ts +16 -0
- package/lib/runjs-context/contexts/JSBlockRunJSContext.js +78 -0
- package/lib/runjs-context/contexts/JSCollectionActionRunJSContext.d.ts +12 -0
- package/lib/runjs-context/contexts/JSCollectionActionRunJSContext.js +59 -0
- package/lib/runjs-context/contexts/JSFieldRunJSContext.d.ts +16 -0
- package/lib/runjs-context/contexts/JSFieldRunJSContext.js +70 -0
- package/lib/runjs-context/contexts/JSItemRunJSContext.d.ts +16 -0
- package/lib/runjs-context/contexts/JSItemRunJSContext.js +66 -0
- package/lib/runjs-context/contexts/JSRecordActionRunJSContext.d.ts +12 -0
- package/lib/runjs-context/contexts/JSRecordActionRunJSContext.js +61 -0
- package/lib/runjs-context/contexts/LinkageRunJSContext.d.ts +12 -0
- package/lib/runjs-context/contexts/LinkageRunJSContext.js +62 -0
- package/lib/runjs-context/helpers.d.ts +17 -0
- package/lib/runjs-context/helpers.js +79 -0
- package/lib/runjs-context/index.d.ts +19 -0
- package/lib/runjs-context/index.js +57 -0
- package/lib/runjs-context/registry.d.ts +17 -0
- package/lib/runjs-context/registry.js +93 -0
- package/lib/runjs-context/snippets/global/api-request-get.snippet.d.ts +16 -0
- package/lib/runjs-context/snippets/global/api-request-get.snippet.js +42 -0
- package/lib/runjs-context/snippets/global/api-request-post.snippet.d.ts +16 -0
- package/lib/runjs-context/snippets/global/api-request-post.snippet.js +42 -0
- package/lib/runjs-context/snippets/global/console-log-ctx.snippet.d.ts +16 -0
- package/lib/runjs-context/snippets/global/console-log-ctx.snippet.js +41 -0
- package/lib/runjs-context/snippets/global/copy-record-json.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/global/copy-record-json.snippet.js +42 -0
- package/lib/runjs-context/snippets/global/copy-to-clipboard.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/global/copy-to-clipboard.snippet.js +42 -0
- package/lib/runjs-context/snippets/global/log-json-record.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/global/log-json-record.snippet.js +42 -0
- package/lib/runjs-context/snippets/global/message-error.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/global/message-error.snippet.js +41 -0
- package/lib/runjs-context/snippets/global/message-success.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/global/message-success.snippet.js +41 -0
- package/lib/runjs-context/snippets/global/notification-open.snippet.d.ts +16 -0
- package/lib/runjs-context/snippets/global/notification-open.snippet.js +43 -0
- package/lib/runjs-context/snippets/global/open-view-dialog.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/global/open-view-dialog.snippet.js +47 -0
- package/lib/runjs-context/snippets/global/open-view-drawer.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/global/open-view-drawer.snippet.js +47 -0
- package/lib/runjs-context/snippets/global/requireAsync.snippet.d.ts +16 -0
- package/lib/runjs-context/snippets/global/requireAsync.snippet.js +46 -0
- package/lib/runjs-context/snippets/global/sleep.snippet.d.ts +16 -0
- package/lib/runjs-context/snippets/global/sleep.snippet.js +43 -0
- package/lib/runjs-context/snippets/global/try-catch-async.snippet.d.ts +16 -0
- package/lib/runjs-context/snippets/global/try-catch-async.snippet.js +44 -0
- package/lib/runjs-context/snippets/global/view-navigation-push.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/global/view-navigation-push.snippet.js +44 -0
- package/lib/runjs-context/snippets/global/window-open.snippet.d.ts +16 -0
- package/lib/runjs-context/snippets/global/window-open.snippet.js +41 -0
- package/lib/runjs-context/snippets/index.d.ts +11 -0
- package/lib/runjs-context/snippets/index.js +94 -0
- package/lib/runjs-context/snippets/libs/echarts-init.snippet.d.ts +15 -0
- package/lib/runjs-context/snippets/libs/echarts-init.snippet.js +46 -0
- package/lib/runjs-context/snippets/scene/actions/collection-selected-count.snippet.d.ts +15 -0
- package/lib/runjs-context/snippets/scene/actions/collection-selected-count.snippet.js +44 -0
- package/lib/runjs-context/snippets/scene/actions/iterate-selected-rows.snippet.d.ts +15 -0
- package/lib/runjs-context/snippets/scene/actions/iterate-selected-rows.snippet.js +43 -0
- package/lib/runjs-context/snippets/scene/actions/record-id-message.snippet.d.ts +15 -0
- package/lib/runjs-context/snippets/scene/actions/record-id-message.snippet.js +43 -0
- package/lib/runjs-context/snippets/scene/actions/run-action-basic.snippet.d.ts +15 -0
- package/lib/runjs-context/snippets/scene/actions/run-action-basic.snippet.js +40 -0
- package/lib/runjs-context/snippets/scene/jsblock/add-event-listener.snippet.d.ts +15 -0
- package/lib/runjs-context/snippets/scene/jsblock/add-event-listener.snippet.js +46 -0
- package/lib/runjs-context/snippets/scene/jsblock/append-style.snippet.d.ts +15 -0
- package/lib/runjs-context/snippets/scene/jsblock/append-style.snippet.js +42 -0
- package/lib/runjs-context/snippets/scene/jsblock/jsx-mount.snippet.d.ts +15 -0
- package/lib/runjs-context/snippets/scene/jsblock/jsx-mount.snippet.js +46 -0
- package/lib/runjs-context/snippets/scene/jsblock/jsx-unmount.snippet.d.ts +15 -0
- package/lib/runjs-context/snippets/scene/jsblock/jsx-unmount.snippet.js +41 -0
- package/lib/runjs-context/snippets/scene/jsblock/render-basic.snippet.d.ts +15 -0
- package/lib/runjs-context/snippets/scene/jsblock/render-basic.snippet.js +41 -0
- package/lib/runjs-context/snippets/scene/jsblock/render-button-handler.snippet.d.ts +15 -0
- package/lib/runjs-context/snippets/scene/jsblock/render-button-handler.snippet.js +46 -0
- package/lib/runjs-context/snippets/scene/jsblock/render-card.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/jsblock/render-card.snippet.js +45 -0
- package/lib/runjs-context/snippets/scene/jsblock/render-react.snippet.d.ts +15 -0
- package/lib/runjs-context/snippets/scene/jsblock/render-react.snippet.js +56 -0
- package/lib/runjs-context/snippets/scene/jsfield/color-by-value.snippet.d.ts +15 -0
- package/lib/runjs-context/snippets/scene/jsfield/color-by-value.snippet.js +42 -0
- package/lib/runjs-context/snippets/scene/jsfield/format-number.snippet.d.ts +15 -0
- package/lib/runjs-context/snippets/scene/jsfield/format-number.snippet.js +41 -0
- package/lib/runjs-context/snippets/scene/jsfield/innerHTML-value.snippet.d.ts +15 -0
- package/lib/runjs-context/snippets/scene/jsfield/innerHTML-value.snippet.js +40 -0
- package/lib/runjs-context/snippets/scene/jsitem/render-basic.snippet.d.ts +15 -0
- package/lib/runjs-context/snippets/scene/jsitem/render-basic.snippet.js +44 -0
- package/lib/runjs-context/snippets/scene/linkage/set-disabled.snippet.d.ts +15 -0
- package/lib/runjs-context/snippets/scene/linkage/set-disabled.snippet.js +60 -0
- package/lib/runjs-context/snippets/scene/linkage/set-field-value.snippet.d.ts +15 -0
- package/lib/runjs-context/snippets/scene/linkage/set-field-value.snippet.js +59 -0
- package/lib/runjs-context/snippets/scene/linkage/set-required.snippet.d.ts +15 -0
- package/lib/runjs-context/snippets/scene/linkage/set-required.snippet.js +60 -0
- package/lib/runjs-context/snippets/scene/linkage/toggle-visible.snippet.d.ts +15 -0
- package/lib/runjs-context/snippets/scene/linkage/toggle-visible.snippet.js +60 -0
- package/lib/runjs-context/snippets/types.d.ts +16 -0
- package/lib/runjs-context/snippets/types.js +24 -0
- package/lib/types.d.ts +398 -0
- package/lib/types.js +43 -0
- package/lib/utils/autoFlowError.d.ts +16 -0
- package/lib/utils/autoFlowError.js +53 -0
- package/lib/utils/constants.d.ts +29 -0
- package/lib/utils/constants.js +77 -0
- package/lib/utils/context.d.ts +40 -0
- package/lib/utils/context.js +63 -0
- package/lib/utils/createCollectionContextMeta.d.ts +11 -0
- package/lib/utils/createCollectionContextMeta.js +117 -0
- package/lib/utils/exceptions.d.ts +22 -0
- package/lib/utils/exceptions.js +62 -0
- package/lib/utils/flow-definitions.d.ts +11 -0
- package/lib/utils/flow-definitions.js +40 -0
- package/lib/utils/index.d.ts +22 -0
- package/lib/utils/index.js +117 -0
- package/lib/utils/inheritance.d.ts +16 -0
- package/lib/utils/inheritance.js +53 -0
- package/lib/utils/params-resolvers.d.ts +51 -0
- package/lib/utils/params-resolvers.js +309 -0
- package/lib/utils/parsePathnameToViewParams.d.ts +34 -0
- package/lib/utils/parsePathnameToViewParams.js +84 -0
- package/lib/utils/safeGlobals.d.ts +16 -0
- package/lib/utils/safeGlobals.js +179 -0
- package/lib/utils/schema-utils.d.ts +40 -0
- package/lib/utils/schema-utils.js +161 -0
- package/lib/utils/serverContextParams.d.ts +28 -0
- package/lib/utils/serverContextParams.js +106 -0
- package/lib/utils/setupRuntimeContextSteps.d.ts +19 -0
- package/lib/utils/setupRuntimeContextSteps.js +88 -0
- package/lib/utils/translation.d.ts +18 -0
- package/lib/utils/translation.js +58 -0
- package/lib/utils/variablesParams.d.ts +51 -0
- package/lib/utils/variablesParams.js +150 -0
- package/lib/views/DialogComponent.d.ts +22 -0
- package/lib/views/DialogComponent.js +98 -0
- package/lib/views/DrawerComponent.d.ts +11 -0
- package/lib/views/DrawerComponent.js +101 -0
- package/lib/views/FlowView.d.ts +76 -0
- package/lib/views/FlowView.js +81 -0
- package/lib/views/PageComponent.d.ts +10 -0
- package/lib/views/PageComponent.js +167 -0
- package/lib/views/ViewNavigation.d.ts +45 -0
- package/lib/views/ViewNavigation.js +97 -0
- package/lib/views/createViewMeta.d.ts +16 -0
- package/lib/views/createViewMeta.js +171 -0
- package/lib/views/index.d.ts +13 -0
- package/lib/views/index.js +48 -0
- package/lib/views/useDialog.d.ts +32 -0
- package/lib/views/useDialog.js +199 -0
- package/lib/views/useDrawer.d.ts +33 -0
- package/lib/views/useDrawer.js +206 -0
- package/lib/views/usePage.d.ts +32 -0
- package/lib/views/usePage.js +193 -0
- package/lib/views/usePatchElement.d.ts +10 -0
- package/lib/views/usePatchElement.js +54 -0
- package/lib/views/usePopover.d.ts +17 -0
- package/lib/views/usePopover.js +159 -0
- package/package.json +37 -0
- package/src/ContextPathProxy.ts +45 -0
- package/src/ElementProxy.ts +69 -0
- package/src/FlowContextProvider.tsx +40 -0
- package/src/FlowDefinition.ts +275 -0
- package/src/JSRunner.ts +84 -0
- package/src/ReactView.tsx +104 -0
- package/src/ViewScopedFlowEngine.ts +75 -0
- package/src/__tests__/ElementProxy.test.ts +51 -0
- package/src/__tests__/JSRunner.test.ts +92 -0
- package/src/__tests__/ReactView.test.tsx +63 -0
- package/src/__tests__/context-path-proxy.test.ts +35 -0
- package/src/__tests__/flow-engine.test.ts +189 -0
- package/src/__tests__/flowContext.test.ts +2012 -0
- package/src/__tests__/flowEngine.saveModel.test.ts +171 -0
- package/src/__tests__/flowI18n.test.ts +28 -0
- package/src/__tests__/flowModel.getFlows.test.ts +61 -0
- package/src/__tests__/flowModel.openView.navigation.test.ts +78 -0
- package/src/__tests__/flowRuntimeContext.test.ts +187 -0
- package/src/__tests__/flowSettings.open.test.tsx +1920 -0
- package/src/__tests__/flowSettings.test.ts +566 -0
- package/src/__tests__/globalFlowRegistry.test.ts +77 -0
- package/src/__tests__/isFieldInterfaceMatch.test.ts +51 -0
- package/src/__tests__/metaTreeNodeCache.test.ts +234 -0
- package/src/__tests__/path-aggregation.test.ts +85 -0
- package/src/__tests__/provider.test.tsx +28 -0
- package/src/__tests__/renderHiddenInConfig.test.tsx +91 -0
- package/src/__tests__/runjsContext.test.ts +60 -0
- package/src/__tests__/viewScopedFlowEngine.test.ts +212 -0
- package/src/acl/Acl.tsx +109 -0
- package/src/acl/__tests__/Acl.test.tsx +72 -0
- package/src/action-registry/BaseActionRegistry.ts +46 -0
- package/src/action-registry/EngineActionRegistry.ts +32 -0
- package/src/action-registry/ModelActionRegistry.ts +75 -0
- package/src/action-registry/__tests__/engineActionRegistry.test.ts +43 -0
- package/src/action-registry/__tests__/modelActionRegistry.test.ts +107 -0
- package/src/components/DynamicFlowsEditor.tsx +318 -0
- package/src/components/FieldModelRenderer.tsx +62 -0
- package/src/components/FlowContextSelector.tsx +255 -0
- package/src/components/FlowErrorFallback.tsx +316 -0
- package/src/components/FlowModelRenderer.tsx +428 -0
- package/src/components/FormItem.tsx +130 -0
- package/src/components/__tests__/flow-model-render-error-fallback.test.tsx +226 -0
- package/src/components/common/FlowSettingsButton.tsx +30 -0
- package/src/components/common/index.ts +10 -0
- package/src/components/common/withFlowDesignMode.tsx +49 -0
- package/src/components/dnd/getMousePositionOnElement.ts +115 -0
- package/src/components/dnd/index.tsx +128 -0
- package/src/components/dnd/moveBlock.ts +379 -0
- package/src/components/index.ts +20 -0
- package/src/components/settings/independents/dropdown/FlowsDropdownButton.tsx +279 -0
- package/src/components/settings/independents/dropdown/index.ts +10 -0
- package/src/components/settings/independents/index.ts +2 -0
- package/src/components/settings/index.ts +11 -0
- package/src/components/settings/wrappers/contextual/DefaultSettingsIcon.tsx +617 -0
- package/src/components/settings/wrappers/contextual/FlowsContextMenu.tsx +292 -0
- package/src/components/settings/wrappers/contextual/FlowsFloatContextMenu.tsx +655 -0
- package/src/components/settings/wrappers/contextual/StepRequiredSettingsDialog.tsx +446 -0
- package/src/components/settings/wrappers/contextual/StepSettings.tsx +109 -0
- package/src/components/settings/wrappers/contextual/StepSettingsDialog.tsx +217 -0
- package/src/components/settings/wrappers/contextual/StepSettingsDrawer.tsx +32 -0
- package/src/components/settings/wrappers/contextual/index.ts +15 -0
- package/src/components/settings/wrappers/embedded/FlowSettings.tsx +258 -0
- package/src/components/settings/wrappers/embedded/FlowsSettings.tsx +111 -0
- package/src/components/settings/wrappers/embedded/FlowsSettingsContent.tsx +96 -0
- package/src/components/settings/wrappers/embedded/index.ts +11 -0
- package/src/components/settings/wrappers/index.ts +5 -0
- package/src/components/subModel/AddSubModelButton.tsx +575 -0
- package/src/components/subModel/LazyDropdown.tsx +714 -0
- package/src/components/subModel/__tests__/AddSubModelButton.test.tsx +1185 -0
- package/src/components/subModel/__tests__/buildWrapperFieldChildren.test.ts +192 -0
- package/src/components/subModel/__tests__/utils.test.ts +425 -0
- package/src/components/subModel/index.ts +12 -0
- package/src/components/subModel/utils.ts +278 -0
- package/src/components/variables/InlineVariableTag.tsx +97 -0
- package/src/components/variables/SlateVariableEditor.tsx +384 -0
- package/src/components/variables/VariableInput.tsx +342 -0
- package/src/components/variables/VariableTag.tsx +123 -0
- package/src/components/variables/VariableTrigger.tsx +116 -0
- package/src/components/variables/__tests__/FlowContextSelector.test.tsx +553 -0
- package/src/components/variables/__tests__/VariableInput.test.tsx +550 -0
- package/src/components/variables/__tests__/VariableTag.test.tsx +347 -0
- package/src/components/variables/__tests__/test-utils.tsx +62 -0
- package/src/components/variables/__tests__/utils.test.ts +310 -0
- package/src/components/variables/index.ts +16 -0
- package/src/components/variables/types.ts +100 -0
- package/src/components/variables/useResolvedMetaTree.ts +76 -0
- package/src/components/variables/utils.ts +192 -0
- package/src/data-source/__tests__/collection.test.ts +58 -0
- package/src/data-source/__tests__/index.test.ts +82 -0
- package/src/data-source/__tests__/jioToJoiSchema.test.ts +56 -0
- package/src/data-source/index.ts +812 -0
- package/src/data-source/jioToJoiSchema.ts +103 -0
- package/src/decorators/index.ts +10 -0
- package/src/decorators/largeField.ts +14 -0
- package/src/emitter.ts +33 -0
- package/src/event-registry/BaseEventRegistry.ts +40 -0
- package/src/event-registry/EngineEventRegistry.ts +26 -0
- package/src/event-registry/ModelEventRegistry.ts +69 -0
- package/src/event-registry/__tests__/engineEventRegistry.test.ts +48 -0
- package/src/executor/FlowExecutor.ts +256 -0
- package/src/executor/__tests__/eventStep.test.ts +157 -0
- package/src/executor/__tests__/flowExecutor.test.ts +163 -0
- package/src/flow-registry/BaseFlowRegistry.ts +91 -0
- package/src/flow-registry/GlobalFlowRegistry.ts +82 -0
- package/src/flow-registry/InstanceFlowRegistry.ts +39 -0
- package/src/flow-registry/__tests__/globalFlowRegistry.test.ts +141 -0
- package/src/flow-registry/__tests__/instance-and-global-registry.test.ts +67 -0
- package/src/flow-registry/__tests__/instanceFlowRegistry.test.ts +83 -0
- package/src/flow-registry/index.ts +12 -0
- package/src/flowContext.ts +1639 -0
- package/src/flowEngine.ts +905 -0
- package/src/flowI18n.ts +96 -0
- package/src/flowSettings.ts +1045 -0
- package/src/hooks/index.ts +15 -0
- package/src/hooks/useApplyAutoFlows.ts +51 -0
- package/src/hooks/useFlowModel.tsx +59 -0
- package/src/hooks/useFlowModelById.ts +37 -0
- package/src/hooks/useFlowSettingsContext.tsx +37 -0
- package/src/hooks/useFlowStep.tsx +19 -0
- package/src/hooks/useNiceDropdownMaxHeight.ts +34 -0
- package/src/index.ts +38 -0
- package/src/locale/en-US.json +61 -0
- package/src/locale/index.ts +38 -0
- package/src/locale/zh-CN.json +61 -0
- package/src/models/CollectionFieldModel.tsx +269 -0
- package/src/models/DisplayItemModel.tsx +13 -0
- package/src/models/EditableItemModel.tsx +13 -0
- package/src/models/FilterableItemModel.tsx +13 -0
- package/src/models/__tests__/CollectionFieldModel.test.ts +122 -0
- package/src/models/__tests__/defaultParams-on-create.test.ts +83 -0
- package/src/models/__tests__/flow-model-oninit.test.ts +44 -0
- package/src/models/__tests__/flowModel.actions.integration.test.ts +100 -0
- package/src/models/__tests__/flowModel.getFlows.sort.test.ts +100 -0
- package/src/models/__tests__/flowModel.test.ts +2746 -0
- package/src/models/__tests__/flowRegistry.test.ts +512 -0
- package/src/models/__tests__/forkFlowModel.test.ts +1047 -0
- package/src/models/__tests__/model-actions.test.ts +70 -0
- package/src/models/__tests__/model-events.test.ts +69 -0
- package/src/models/flowModel.tsx +1398 -0
- package/src/models/forkFlowModel.ts +287 -0
- package/src/models/index.ts +17 -0
- package/src/provider.tsx +101 -0
- package/src/resources/__tests__/apiResource.test.ts +201 -0
- package/src/resources/__tests__/baseRecordResource.test.ts +262 -0
- package/src/resources/__tests__/filterItem.test.ts +260 -0
- package/src/resources/__tests__/flowResource.test.ts +127 -0
- package/src/resources/apiResource.ts +148 -0
- package/src/resources/baseRecordResource.ts +279 -0
- package/src/resources/filterItem.ts +74 -0
- package/src/resources/flowResource.ts +143 -0
- package/src/resources/index.ts +17 -0
- package/src/resources/multiRecordResource.ts +219 -0
- package/src/resources/singleRecordResource.ts +83 -0
- package/src/resources/sqlResource.ts +299 -0
- package/src/runjs-context/contexts/FlowRunJSContext.ts +190 -0
- package/src/runjs-context/contexts/FormJSFieldItemRunJSContext.ts +39 -0
- package/src/runjs-context/contexts/JSBlockRunJSContext.ts +52 -0
- package/src/runjs-context/contexts/JSCollectionActionRunJSContext.ts +32 -0
- package/src/runjs-context/contexts/JSFieldRunJSContext.ts +43 -0
- package/src/runjs-context/contexts/JSItemRunJSContext.ts +39 -0
- package/src/runjs-context/contexts/JSRecordActionRunJSContext.ts +34 -0
- package/src/runjs-context/contexts/LinkageRunJSContext.ts +35 -0
- package/src/runjs-context/helpers.ts +56 -0
- package/src/runjs-context/index.ts +20 -0
- package/src/runjs-context/registry.ts +65 -0
- package/src/runjs-context/snippets/global/api-request-get.snippet.ts +20 -0
- package/src/runjs-context/snippets/global/api-request-post.snippet.ts +20 -0
- package/src/runjs-context/snippets/global/console-log-ctx.snippet.ts +19 -0
- package/src/runjs-context/snippets/global/copy-record-json.snippet.ts +21 -0
- package/src/runjs-context/snippets/global/copy-to-clipboard.snippet.ts +21 -0
- package/src/runjs-context/snippets/global/log-json-record.snippet.ts +21 -0
- package/src/runjs-context/snippets/global/message-error.snippet.ts +20 -0
- package/src/runjs-context/snippets/global/message-success.snippet.ts +20 -0
- package/src/runjs-context/snippets/global/notification-open.snippet.ts +21 -0
- package/src/runjs-context/snippets/global/open-view-dialog.snippet.ts +26 -0
- package/src/runjs-context/snippets/global/open-view-drawer.snippet.ts +26 -0
- package/src/runjs-context/snippets/global/requireAsync.snippet.ts +24 -0
- package/src/runjs-context/snippets/global/sleep.snippet.ts +21 -0
- package/src/runjs-context/snippets/global/try-catch-async.snippet.ts +22 -0
- package/src/runjs-context/snippets/global/view-navigation-push.snippet.ts +23 -0
- package/src/runjs-context/snippets/global/window-open.snippet.ts +19 -0
- package/src/runjs-context/snippets/index.ts +59 -0
- package/src/runjs-context/snippets/libs/echarts-init.snippet.ts +24 -0
- package/src/runjs-context/snippets/scene/actions/collection-selected-count.snippet.ts +22 -0
- package/src/runjs-context/snippets/scene/actions/iterate-selected-rows.snippet.ts +21 -0
- package/src/runjs-context/snippets/scene/actions/record-id-message.snippet.ts +21 -0
- package/src/runjs-context/snippets/scene/actions/run-action-basic.snippet.ts +18 -0
- package/src/runjs-context/snippets/scene/jsblock/add-event-listener.snippet.ts +29 -0
- package/src/runjs-context/snippets/scene/jsblock/append-style.snippet.ts +20 -0
- package/src/runjs-context/snippets/scene/jsblock/jsx-mount.snippet.ts +24 -0
- package/src/runjs-context/snippets/scene/jsblock/jsx-unmount.snippet.ts +19 -0
- package/src/runjs-context/snippets/scene/jsblock/render-basic.snippet.ts +24 -0
- package/src/runjs-context/snippets/scene/jsblock/render-button-handler.snippet.ts +24 -0
- package/src/runjs-context/snippets/scene/jsblock/render-card.snippet.ts +30 -0
- package/src/runjs-context/snippets/scene/jsblock/render-react.snippet.ts +34 -0
- package/src/runjs-context/snippets/scene/jsfield/color-by-value.snippet.ts +20 -0
- package/src/runjs-context/snippets/scene/jsfield/format-number.snippet.ts +19 -0
- package/src/runjs-context/snippets/scene/jsfield/innerHTML-value.snippet.ts +18 -0
- package/src/runjs-context/snippets/scene/jsitem/render-basic.snippet.ts +27 -0
- package/src/runjs-context/snippets/scene/linkage/set-disabled.snippet.ts +38 -0
- package/src/runjs-context/snippets/scene/linkage/set-field-value.snippet.ts +37 -0
- package/src/runjs-context/snippets/scene/linkage/set-required.snippet.ts +38 -0
- package/src/runjs-context/snippets/scene/linkage/toggle-visible.snippet.ts +38 -0
- package/src/runjs-context/snippets/types.ts +17 -0
- package/src/types.ts +474 -0
- package/src/utils/__tests__/context.test.ts +93 -0
- package/src/utils/__tests__/params-resolvers.test.ts +652 -0
- package/src/utils/__tests__/parsePathnameToViewParams.test.ts +104 -0
- package/src/utils/__tests__/safeGlobals.test.ts +29 -0
- package/src/utils/__tests__/utils.test.ts +1021 -0
- package/src/utils/__tests__/variablesParams.test.ts +52 -0
- package/src/utils/autoFlowError.ts +29 -0
- package/src/utils/constants.ts +60 -0
- package/src/utils/context.ts +70 -0
- package/src/utils/createCollectionContextMeta.ts +122 -0
- package/src/utils/exceptions.ts +36 -0
- package/src/utils/flow-definitions.ts +16 -0
- package/src/utils/index.ts +63 -0
- package/src/utils/inheritance.ts +39 -0
- package/src/utils/params-resolvers.ts +482 -0
- package/src/utils/parsePathnameToViewParams.ts +103 -0
- package/src/utils/safeGlobals.ts +188 -0
- package/src/utils/schema-utils.ts +201 -0
- package/src/utils/serverContextParams.ts +111 -0
- package/src/utils/setupRuntimeContextSteps.ts +89 -0
- package/src/utils/translation.ts +37 -0
- package/src/utils/variablesParams.ts +175 -0
- package/src/views/DialogComponent.tsx +79 -0
- package/src/views/DrawerComponent.tsx +72 -0
- package/src/views/FlowView.tsx +103 -0
- package/src/views/PageComponent.tsx +150 -0
- package/src/views/ViewNavigation.ts +122 -0
- package/src/views/__tests__/FlowView.test.ts +31 -0
- package/src/views/__tests__/ViewNavigation.test.ts +191 -0
- package/src/views/__tests__/usePatchElement.test.tsx +28 -0
- package/src/views/createViewMeta.ts +157 -0
- package/src/views/index.tsx +14 -0
- package/src/views/useDialog.tsx +192 -0
- package/src/views/useDrawer.tsx +205 -0
- package/src/views/usePage.tsx +182 -0
- package/src/views/usePatchElement.tsx +27 -0
- package/src/views/usePopover.tsx +131 -0
|
@@ -0,0 +1,192 @@
|
|
|
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, expect, it } from 'vitest';
|
|
11
|
+
import { Collection } from '../../../data-source';
|
|
12
|
+
import { FlowEngine } from '../../../flowEngine';
|
|
13
|
+
import { FlowModel } from '../../../models';
|
|
14
|
+
import { buildWrapperFieldChildren } from '../utils';
|
|
15
|
+
|
|
16
|
+
describe('buildWrapperFieldChildren', () => {
|
|
17
|
+
it('generates a group with children per field and correct defaults', () => {
|
|
18
|
+
const engine = new FlowEngine();
|
|
19
|
+
const ds = engine.context.dataSourceManager.getDataSource('main');
|
|
20
|
+
const collection = new Collection({
|
|
21
|
+
name: 'posts',
|
|
22
|
+
fields: [
|
|
23
|
+
{ name: 'title', interface: 'input', title: 'Title' },
|
|
24
|
+
{ name: 'status', interface: 'select', title: 'Status' },
|
|
25
|
+
{ name: 'ignored', interface: undefined },
|
|
26
|
+
],
|
|
27
|
+
});
|
|
28
|
+
collection.setDataSource(ds);
|
|
29
|
+
ds.addCollection(collection);
|
|
30
|
+
const model = engine.createModel({ use: 'FlowModel' });
|
|
31
|
+
const ctx = model.context;
|
|
32
|
+
ctx.defineProperty('collection', { value: collection });
|
|
33
|
+
|
|
34
|
+
const groups = buildWrapperFieldChildren(ctx, {
|
|
35
|
+
useModel: 'TableColumnModel',
|
|
36
|
+
fieldUseModel: 'ReadPrettyFieldModel',
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
expect(groups).toHaveLength(1);
|
|
40
|
+
const group = groups[0];
|
|
41
|
+
expect(group.key).toBe(`addField_${collection.name}`);
|
|
42
|
+
expect(group.type).toBe('group');
|
|
43
|
+
expect(group.searchable).toBe(true);
|
|
44
|
+
expect(group.searchPlaceholder).toBe('Search fields');
|
|
45
|
+
|
|
46
|
+
const children = group.children as any[];
|
|
47
|
+
// filters out field without interface
|
|
48
|
+
expect(children.map((c) => c.key)).toEqual(['title', 'status']);
|
|
49
|
+
expect(children.map((c) => c.label)).toEqual(['Title', 'Status']);
|
|
50
|
+
// wrapper model is fixed from options
|
|
51
|
+
children.forEach((c) => expect(c.useModel).toBe('TableColumnModel'));
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it('resolves child use via fieldUseModel function and builds stepParams', async () => {
|
|
55
|
+
const engine = new FlowEngine();
|
|
56
|
+
const ds = engine.context.dataSourceManager.getDataSource('main');
|
|
57
|
+
const collection = new Collection({
|
|
58
|
+
name: 'posts',
|
|
59
|
+
fields: [
|
|
60
|
+
{ name: 'title', interface: 'input', title: 'Title' },
|
|
61
|
+
{ name: 'status', interface: 'select', title: 'Status' },
|
|
62
|
+
],
|
|
63
|
+
});
|
|
64
|
+
collection.setDataSource(ds);
|
|
65
|
+
ds.addCollection(collection);
|
|
66
|
+
const model = engine.createModel({ use: 'FlowModel' });
|
|
67
|
+
const ctx = model.context;
|
|
68
|
+
ctx.defineProperty('collection', { value: collection });
|
|
69
|
+
|
|
70
|
+
const groups = buildWrapperFieldChildren(ctx, {
|
|
71
|
+
useModel: 'DetailsItemModel',
|
|
72
|
+
fieldUseModel: (f) => (f.interface === 'select' ? 'SelectPrettyFieldModel' : 'ReadPrettyFieldModel'),
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
const group = groups[0];
|
|
76
|
+
const children = group.children;
|
|
77
|
+
const titleItem = children.find((c) => c.key === 'title');
|
|
78
|
+
const statusItem = children.find((c) => c.key === 'status');
|
|
79
|
+
|
|
80
|
+
const titleCreate = await (typeof titleItem.createModelOptions === 'function'
|
|
81
|
+
? titleItem.createModelOptions(ctx)
|
|
82
|
+
: titleItem.createModelOptions);
|
|
83
|
+
const statusCreate = await (typeof statusItem.createModelOptions === 'function'
|
|
84
|
+
? statusItem.createModelOptions(ctx)
|
|
85
|
+
: statusItem.createModelOptions);
|
|
86
|
+
|
|
87
|
+
expect(titleCreate.use).toBe('DetailsItemModel');
|
|
88
|
+
expect(titleCreate.stepParams).toEqual({
|
|
89
|
+
fieldSettings: {
|
|
90
|
+
init: {
|
|
91
|
+
dataSourceKey: 'main',
|
|
92
|
+
collectionName: 'posts',
|
|
93
|
+
fieldPath: 'title',
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
});
|
|
97
|
+
expect(titleCreate.subModels.field.use).toBe('ReadPrettyFieldModel');
|
|
98
|
+
expect(titleCreate.subModels.field.stepParams).toEqual({
|
|
99
|
+
fieldSettings: {
|
|
100
|
+
init: {
|
|
101
|
+
dataSourceKey: 'main',
|
|
102
|
+
collectionName: 'posts',
|
|
103
|
+
fieldPath: 'title',
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
expect(statusCreate.subModels.field.use).toBe('SelectPrettyFieldModel');
|
|
109
|
+
expect(statusCreate.stepParams.fieldSettings.init.fieldPath).toBe('status');
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
it('toggleable checks step params for fieldPath (using real FlowModel)', () => {
|
|
113
|
+
const engine = new FlowEngine();
|
|
114
|
+
const ds = engine.context.dataSourceManager.getDataSource('main');
|
|
115
|
+
const collection = new Collection({
|
|
116
|
+
name: 'posts',
|
|
117
|
+
fields: [
|
|
118
|
+
{ name: 'title', interface: 'input', title: 'Title' },
|
|
119
|
+
{ name: 'status', interface: 'select', title: 'Status' },
|
|
120
|
+
],
|
|
121
|
+
});
|
|
122
|
+
collection.setDataSource(ds);
|
|
123
|
+
ds.addCollection(collection);
|
|
124
|
+
const model = engine.createModel({ use: 'FlowModel' });
|
|
125
|
+
const ctx = model.context;
|
|
126
|
+
ctx.defineProperty('collection', { value: collection });
|
|
127
|
+
const groups = buildWrapperFieldChildren(ctx, {
|
|
128
|
+
useModel: 'TableColumnModel',
|
|
129
|
+
fieldUseModel: 'ReadPrettyFieldModel',
|
|
130
|
+
});
|
|
131
|
+
const group = groups[0];
|
|
132
|
+
const [titleItem, statusItem] = group.children;
|
|
133
|
+
|
|
134
|
+
// create real FlowModel instances and set stepParams
|
|
135
|
+
const titleModel = engine.createModel<FlowModel>({ use: 'FlowModel' });
|
|
136
|
+
titleModel.setStepParams('fieldSettings', 'init', { fieldPath: 'title' });
|
|
137
|
+
const statusModel = engine.createModel<FlowModel>({ use: 'FlowModel' });
|
|
138
|
+
statusModel.setStepParams('fieldSettings', 'init', { fieldPath: 'status' });
|
|
139
|
+
|
|
140
|
+
expect((titleItem.toggleable as (model: FlowModel) => boolean)(titleModel)).toBe(true);
|
|
141
|
+
expect((titleItem.toggleable as (model: FlowModel) => boolean)(statusModel)).toBe(false);
|
|
142
|
+
expect((statusItem.toggleable as (model: FlowModel) => boolean)(statusModel)).toBe(true);
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
it('prefers ctx.model.collection over ctx.collection for sub-table scenario', async () => {
|
|
146
|
+
const engine = new FlowEngine();
|
|
147
|
+
const ds = engine.context.dataSourceManager.getDataSource('main');
|
|
148
|
+
// Main collection (block-level)
|
|
149
|
+
const posts = new Collection({
|
|
150
|
+
name: 'posts',
|
|
151
|
+
fields: [
|
|
152
|
+
{ name: 'title', interface: 'input', title: 'Title' },
|
|
153
|
+
{ name: 'category', interface: 'select', title: 'Category' },
|
|
154
|
+
],
|
|
155
|
+
});
|
|
156
|
+
posts.setDataSource(ds);
|
|
157
|
+
ds.addCollection(posts);
|
|
158
|
+
|
|
159
|
+
// Target collection (association sub-table)
|
|
160
|
+
const comments = new Collection({
|
|
161
|
+
name: 'comments',
|
|
162
|
+
fields: [
|
|
163
|
+
{ name: 'content', interface: 'input', title: 'Content' },
|
|
164
|
+
{ name: 'status', interface: 'select', title: 'Status' },
|
|
165
|
+
],
|
|
166
|
+
});
|
|
167
|
+
comments.setDataSource(ds);
|
|
168
|
+
ds.addCollection(comments);
|
|
169
|
+
|
|
170
|
+
// we can't import the real sub table model, as they are in client core package
|
|
171
|
+
const model = engine.createModel({ use: 'FlowModel' });
|
|
172
|
+
const ctx = model.context;
|
|
173
|
+
// Block context collection is posts
|
|
174
|
+
ctx.defineProperty('collection', { value: posts });
|
|
175
|
+
// But model.collection points to the association target collection
|
|
176
|
+
(model as any).collection = comments;
|
|
177
|
+
|
|
178
|
+
const groups = buildWrapperFieldChildren(ctx, {
|
|
179
|
+
useModel: 'SubTableColumnModel',
|
|
180
|
+
fieldUseModel: 'FormFieldModel',
|
|
181
|
+
});
|
|
182
|
+
const group = groups[0];
|
|
183
|
+
const children = group.children as any[];
|
|
184
|
+
expect(children.map((c) => c.key)).toEqual(['content', 'status']);
|
|
185
|
+
|
|
186
|
+
const contentItem = children.find((c) => c.key === 'content');
|
|
187
|
+
const contentCreate = await (typeof contentItem.createModelOptions === 'function'
|
|
188
|
+
? contentItem.createModelOptions(ctx)
|
|
189
|
+
: contentItem.createModelOptions);
|
|
190
|
+
expect(contentCreate.stepParams.fieldSettings.init.collectionName).toBe('comments');
|
|
191
|
+
});
|
|
192
|
+
});
|
|
@@ -0,0 +1,425 @@
|
|
|
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, it, expect } from 'vitest';
|
|
11
|
+
import { buildItems, buildSubModelGroups, buildSubModelItem, buildSubModelItems } from '../utils';
|
|
12
|
+
import { mergeSubModelItems } from '../AddSubModelButton';
|
|
13
|
+
import { FlowEngine } from '../../../flowEngine';
|
|
14
|
+
import { FlowModel } from '../../../models';
|
|
15
|
+
import type { FlowModelContext } from '../../../flowContext';
|
|
16
|
+
import type { SubModelItem } from '../AddSubModelButton';
|
|
17
|
+
import type { ModelConstructor } from '../../../types';
|
|
18
|
+
|
|
19
|
+
type DefineChildren = (ctx: FlowModelContext) => SubModelItem[] | Promise<SubModelItem[]>;
|
|
20
|
+
type WithDefineChildren<T extends ModelConstructor = ModelConstructor> = T & { defineChildren: DefineChildren };
|
|
21
|
+
|
|
22
|
+
function attachDefineChildren<T extends ModelConstructor>(Base: T, def: DefineChildren): WithDefineChildren<T> {
|
|
23
|
+
Object.defineProperty(Base, 'defineChildren', {
|
|
24
|
+
value: def,
|
|
25
|
+
configurable: true,
|
|
26
|
+
writable: true,
|
|
27
|
+
});
|
|
28
|
+
return Base as WithDefineChildren<T>;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
describe('subModel/utils', () => {
|
|
32
|
+
describe('buildSubModelGroups', () => {
|
|
33
|
+
it('hides group when defineChildren resolves to empty array', async () => {
|
|
34
|
+
const engine = new FlowEngine();
|
|
35
|
+
|
|
36
|
+
class EmptyBase extends FlowModel {}
|
|
37
|
+
EmptyBase.define({ label: 'Empty Group' });
|
|
38
|
+
const EmptyBaseDC = attachDefineChildren(EmptyBase, async () => []);
|
|
39
|
+
|
|
40
|
+
class NonEmptyBase extends FlowModel {}
|
|
41
|
+
NonEmptyBase.define({ label: 'NonEmpty Group' });
|
|
42
|
+
const NonEmptyBaseDC = attachDefineChildren(NonEmptyBase, async () => [{ key: 'child-1', label: 'Child 1' }]);
|
|
43
|
+
|
|
44
|
+
engine.registerModels({ EmptyBase: EmptyBaseDC, NonEmptyBase: NonEmptyBaseDC });
|
|
45
|
+
|
|
46
|
+
const model = engine.createModel({ use: 'FlowModel' });
|
|
47
|
+
const ctx = model.context;
|
|
48
|
+
|
|
49
|
+
const groupsFactory = buildSubModelGroups([EmptyBaseDC, NonEmptyBaseDC]);
|
|
50
|
+
const groups = await groupsFactory(ctx);
|
|
51
|
+
|
|
52
|
+
expect(groups).toHaveLength(1);
|
|
53
|
+
expect(groups[0].type).toBe('group');
|
|
54
|
+
expect(groups[0].label).toBe('NonEmpty Group');
|
|
55
|
+
expect(groups[0].children).toBeTruthy();
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it('hides group when defineChildren throws', async () => {
|
|
59
|
+
const engine = new FlowEngine();
|
|
60
|
+
|
|
61
|
+
class ThrowBase extends FlowModel {}
|
|
62
|
+
ThrowBase.define({ label: 'Throw Group' });
|
|
63
|
+
const ThrowBaseDC = attachDefineChildren(ThrowBase, async () => {
|
|
64
|
+
throw new Error('boom');
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
class OkBase extends FlowModel {}
|
|
68
|
+
OkBase.define({ label: 'OK Group' });
|
|
69
|
+
const OkBaseDC = attachDefineChildren(OkBase, () => [{ key: 'ok', label: 'OK' }]);
|
|
70
|
+
|
|
71
|
+
engine.registerModels({ ThrowBase: ThrowBaseDC, OkBase: OkBaseDC });
|
|
72
|
+
|
|
73
|
+
const model = engine.createModel({ use: 'FlowModel' });
|
|
74
|
+
const ctx = model.context;
|
|
75
|
+
|
|
76
|
+
const groupsFactory = buildSubModelGroups([ThrowBaseDC, OkBaseDC]);
|
|
77
|
+
const groups = await groupsFactory(ctx);
|
|
78
|
+
|
|
79
|
+
expect(groups).toHaveLength(1);
|
|
80
|
+
expect(groups[0].label).toBe('OK Group');
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
it('shows group when defineChildren resolves to non-empty array', async () => {
|
|
84
|
+
const engine = new FlowEngine();
|
|
85
|
+
|
|
86
|
+
class Base extends FlowModel {}
|
|
87
|
+
Base.define({ label: 'Base Group' });
|
|
88
|
+
const BaseDC = attachDefineChildren(Base, async () => [{ key: 'a', label: 'A' }]);
|
|
89
|
+
|
|
90
|
+
engine.registerModels({ Base: BaseDC });
|
|
91
|
+
|
|
92
|
+
const model = engine.createModel({ use: 'FlowModel' });
|
|
93
|
+
const ctx = model.context;
|
|
94
|
+
|
|
95
|
+
const groupsFactory = buildSubModelGroups([BaseDC]);
|
|
96
|
+
const groups = await groupsFactory(ctx);
|
|
97
|
+
|
|
98
|
+
expect(groups).toHaveLength(1);
|
|
99
|
+
expect(groups[0].label).toBe('Base Group');
|
|
100
|
+
expect(groups[0].children).toBeTruthy();
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
it('invokes buildSubModelItems when meta.children is false', async () => {
|
|
104
|
+
const engine = new FlowEngine();
|
|
105
|
+
|
|
106
|
+
class Parent extends FlowModel {}
|
|
107
|
+
|
|
108
|
+
class Base extends FlowModel {}
|
|
109
|
+
Base.define({ label: 'Base', children: false });
|
|
110
|
+
|
|
111
|
+
class Derived extends Base {}
|
|
112
|
+
Derived.define({ label: 'Derived' });
|
|
113
|
+
|
|
114
|
+
engine.registerModels({ Parent, Base, Derived });
|
|
115
|
+
const parent = engine.createModel<Parent>({ use: 'Parent', uid: 'parent-children-false' });
|
|
116
|
+
const ctx = parent.context;
|
|
117
|
+
|
|
118
|
+
const groupsFactory = buildSubModelGroups([Base]);
|
|
119
|
+
const groups = await groupsFactory(ctx);
|
|
120
|
+
|
|
121
|
+
expect(groups).toHaveLength(1);
|
|
122
|
+
const group = groups[0];
|
|
123
|
+
expect(Array.isArray(group.children)).toBe(true);
|
|
124
|
+
expect((group.children as SubModelItem[]).map((item) => item.key)).toEqual(['Derived']);
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
it('excludes subclasses already contributed by previous base classes', async () => {
|
|
128
|
+
const engine = new FlowEngine();
|
|
129
|
+
|
|
130
|
+
class Parent extends FlowModel {}
|
|
131
|
+
class Root extends FlowModel {}
|
|
132
|
+
|
|
133
|
+
class FirstGroup extends Root {}
|
|
134
|
+
FirstGroup.define({ label: 'First Group', children: async () => [{ key: 'from-first', label: 'First' }] });
|
|
135
|
+
|
|
136
|
+
class SecondGroup extends Root {}
|
|
137
|
+
|
|
138
|
+
class SecondLeaf extends SecondGroup {}
|
|
139
|
+
SecondLeaf.define({ label: 'Second Leaf' });
|
|
140
|
+
|
|
141
|
+
engine.registerModels({ Parent, Root, FirstGroup, SecondGroup, SecondLeaf });
|
|
142
|
+
const parent = engine.createModel<Parent>({ use: 'Parent', uid: 'parent-exclude-groups' });
|
|
143
|
+
const ctx = parent.context;
|
|
144
|
+
|
|
145
|
+
const groupsFactory = buildSubModelGroups([FirstGroup, SecondGroup]);
|
|
146
|
+
const groups = await groupsFactory(ctx);
|
|
147
|
+
|
|
148
|
+
expect(groups).toHaveLength(2);
|
|
149
|
+
const second = groups[1];
|
|
150
|
+
expect(Array.isArray(second.children)).toBe(true);
|
|
151
|
+
expect((second.children as SubModelItem[]).map((item) => item.key)).toEqual(['SecondLeaf']);
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
describe('buildSubModelItem', () => {
|
|
156
|
+
it('returns undefined for hidden meta entries', () => {
|
|
157
|
+
const engine = new FlowEngine();
|
|
158
|
+
|
|
159
|
+
class Parent extends FlowModel {}
|
|
160
|
+
class HiddenChild extends FlowModel {}
|
|
161
|
+
HiddenChild.define({ hide: true });
|
|
162
|
+
|
|
163
|
+
engine.registerModels({ Parent, HiddenChild });
|
|
164
|
+
const parent = engine.createModel({ use: 'Parent', uid: 'parent-hidden' });
|
|
165
|
+
|
|
166
|
+
const item = buildSubModelItem(HiddenChild, parent.context);
|
|
167
|
+
expect(item).toBeUndefined();
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
it('maps meta fields and wraps children createModelOptions', async () => {
|
|
171
|
+
const engine = new FlowEngine();
|
|
172
|
+
|
|
173
|
+
class Parent extends FlowModel {}
|
|
174
|
+
class ChildGroup extends FlowModel {}
|
|
175
|
+
ChildGroup.define({
|
|
176
|
+
label: 'Child Group',
|
|
177
|
+
searchable: true,
|
|
178
|
+
searchPlaceholder: 'Search child',
|
|
179
|
+
toggleable: true,
|
|
180
|
+
createModelOptions: { stepParams: { fromMeta: true } },
|
|
181
|
+
children: async () => [
|
|
182
|
+
{
|
|
183
|
+
key: 'leaf',
|
|
184
|
+
label: 'Leaf',
|
|
185
|
+
createModelOptions: async (_ctx, extra) => ({
|
|
186
|
+
stepParams: { fromChild: true },
|
|
187
|
+
extra,
|
|
188
|
+
}),
|
|
189
|
+
},
|
|
190
|
+
],
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
engine.registerModels({ Parent, ChildGroup });
|
|
194
|
+
const parent = engine.createModel<Parent>({ use: 'Parent', uid: 'parent-child-group' });
|
|
195
|
+
const ctx = parent.context;
|
|
196
|
+
|
|
197
|
+
const item = buildSubModelItem(ChildGroup, ctx, false);
|
|
198
|
+
expect(item).toBeTruthy();
|
|
199
|
+
expect(item?.label).toBe('Child Group');
|
|
200
|
+
expect(item?.searchable).toBe(true);
|
|
201
|
+
expect(item?.searchPlaceholder).toBe('Search child');
|
|
202
|
+
expect(item?.toggleable).toBe(true);
|
|
203
|
+
expect(item?.useModel).toBe('ChildGroup');
|
|
204
|
+
|
|
205
|
+
const childrenFactory = item?.children as () => Promise<SubModelItem[]>;
|
|
206
|
+
expect(typeof childrenFactory).toBe('function');
|
|
207
|
+
const children = await childrenFactory();
|
|
208
|
+
expect(children).toHaveLength(1);
|
|
209
|
+
const leaf = children[0];
|
|
210
|
+
expect(leaf.label).toBe('Leaf');
|
|
211
|
+
|
|
212
|
+
const merged = await (leaf.createModelOptions as any)?.(ctx, { fromTest: true });
|
|
213
|
+
expect(merged?.stepParams).toMatchObject({ fromMeta: true, fromChild: true });
|
|
214
|
+
expect(merged?.extra).toMatchObject({ fromTest: true });
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
it('falls back to use=current class name when meta createModelOptions omitted', () => {
|
|
218
|
+
const engine = new FlowEngine();
|
|
219
|
+
|
|
220
|
+
class Parent extends FlowModel {}
|
|
221
|
+
class PlainChild extends FlowModel {}
|
|
222
|
+
|
|
223
|
+
engine.registerModels({ Parent, PlainChild });
|
|
224
|
+
const parent = engine.createModel<Parent>({ use: 'Parent', uid: 'parent-default-create-options' });
|
|
225
|
+
|
|
226
|
+
const item = buildSubModelItem(PlainChild, parent.context);
|
|
227
|
+
expect(item?.createModelOptions).toEqual({ use: 'PlainChild' });
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
it('still returns item when skipHide=true', () => {
|
|
231
|
+
const engine = new FlowEngine();
|
|
232
|
+
|
|
233
|
+
class Parent extends FlowModel {}
|
|
234
|
+
class HiddenChild extends FlowModel {}
|
|
235
|
+
HiddenChild.define({ hide: true, label: 'Hidden but allowed' });
|
|
236
|
+
|
|
237
|
+
engine.registerModels({ Parent, HiddenChild });
|
|
238
|
+
const parent = engine.createModel({ use: 'Parent', uid: 'parent-skip-hide' });
|
|
239
|
+
|
|
240
|
+
const item = buildSubModelItem(HiddenChild, parent.context, true);
|
|
241
|
+
expect(item).toBeTruthy();
|
|
242
|
+
expect(item?.label).toBe('Hidden but allowed');
|
|
243
|
+
});
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
describe('buildSubModelItems', () => {
|
|
247
|
+
it('sorts by meta.sort and respects exclusion list', async () => {
|
|
248
|
+
const engine = new FlowEngine();
|
|
249
|
+
|
|
250
|
+
class Parent extends FlowModel {}
|
|
251
|
+
class Base extends FlowModel {}
|
|
252
|
+
Base.define({ label: 'Base' });
|
|
253
|
+
|
|
254
|
+
class Early extends Base {}
|
|
255
|
+
Early.define({ label: 'Early', sort: 10 });
|
|
256
|
+
|
|
257
|
+
class Late extends Base {}
|
|
258
|
+
Late.define({ label: 'Late', sort: 50 });
|
|
259
|
+
|
|
260
|
+
class Hidden extends Base {}
|
|
261
|
+
Hidden.define({ label: 'Hidden', hide: true });
|
|
262
|
+
|
|
263
|
+
engine.registerModels({ Parent, Base, Early, Late, Hidden });
|
|
264
|
+
|
|
265
|
+
const parent = engine.createModel<Parent>({ use: 'Parent', uid: 'parent-sorting' });
|
|
266
|
+
const ctx = parent.context;
|
|
267
|
+
|
|
268
|
+
const items = await buildSubModelItems('Base')(ctx);
|
|
269
|
+
expect(items.map((it) => it.key)).toEqual(['Early', 'Late']);
|
|
270
|
+
|
|
271
|
+
const excluded = await buildSubModelItems('Base', ['Early'])(ctx);
|
|
272
|
+
expect(excluded.map((it) => it.key)).toEqual(['Late']);
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
it('excludes subclasses by constructor reference', async () => {
|
|
276
|
+
const engine = new FlowEngine();
|
|
277
|
+
|
|
278
|
+
class Parent extends FlowModel {}
|
|
279
|
+
class Base extends FlowModel {}
|
|
280
|
+
|
|
281
|
+
class KeepMe extends Base {}
|
|
282
|
+
KeepMe.define({ label: 'Keep' });
|
|
283
|
+
|
|
284
|
+
class RemoveMe extends Base {}
|
|
285
|
+
RemoveMe.define({ label: 'Remove' });
|
|
286
|
+
|
|
287
|
+
engine.registerModels({ Parent, Base, KeepMe, RemoveMe });
|
|
288
|
+
const parent = engine.createModel<Parent>({ use: 'Parent', uid: 'parent-exclude-ctor' });
|
|
289
|
+
const ctx = parent.context;
|
|
290
|
+
|
|
291
|
+
const items = await buildSubModelItems(Base, [RemoveMe])(ctx);
|
|
292
|
+
expect(items.map((it) => it.key)).toEqual(['KeepMe']);
|
|
293
|
+
});
|
|
294
|
+
});
|
|
295
|
+
|
|
296
|
+
it('buildSubModelItems respects meta.searchable and searchPlaceholder', async () => {
|
|
297
|
+
const engine = new FlowEngine();
|
|
298
|
+
|
|
299
|
+
class SearchableChild extends FlowModel {}
|
|
300
|
+
// Define meta with searchable flags
|
|
301
|
+
SearchableChild.define({ label: 'Searchable Child', searchable: true, searchPlaceholder: 'Search children' });
|
|
302
|
+
|
|
303
|
+
engine.registerModels({ SearchableChild });
|
|
304
|
+
|
|
305
|
+
const model = engine.createModel({ use: 'FlowModel' });
|
|
306
|
+
const ctx = model.context;
|
|
307
|
+
|
|
308
|
+
// Build items from base class FlowModel so our subclass is included
|
|
309
|
+
const itemsFactory = (await import('../utils')).buildSubModelItems('FlowModel');
|
|
310
|
+
const items = await itemsFactory(ctx);
|
|
311
|
+
|
|
312
|
+
const found = items.find((it) => it.key === 'SearchableChild');
|
|
313
|
+
expect(found).toBeTruthy();
|
|
314
|
+
expect(found?.searchable).toBe(true);
|
|
315
|
+
expect(found?.searchPlaceholder).toBe('Search children');
|
|
316
|
+
});
|
|
317
|
+
|
|
318
|
+
describe('buildSubModelGroups label and resolution', () => {
|
|
319
|
+
it('falls back to class key when meta label missing', async () => {
|
|
320
|
+
const engine = new FlowEngine();
|
|
321
|
+
|
|
322
|
+
class Parent extends FlowModel {}
|
|
323
|
+
class PlainGroup extends FlowModel {}
|
|
324
|
+
const PlainGroupDC = attachDefineChildren(PlainGroup, async () => [
|
|
325
|
+
{ key: 'leaf', label: 'Leaf', createModelOptions: { use: 'Parent' } },
|
|
326
|
+
]);
|
|
327
|
+
|
|
328
|
+
engine.registerModels({ Parent, PlainGroup: PlainGroupDC });
|
|
329
|
+
const parent = engine.createModel<Parent>({ use: 'Parent', uid: 'parent-label-fallback' });
|
|
330
|
+
const ctx = parent.context;
|
|
331
|
+
|
|
332
|
+
const groupsFactory = buildSubModelGroups(['PlainGroup']);
|
|
333
|
+
const groups = await groupsFactory(ctx);
|
|
334
|
+
|
|
335
|
+
expect(groups).toHaveLength(1);
|
|
336
|
+
expect(groups[0].label).toBe('PlainGroup');
|
|
337
|
+
});
|
|
338
|
+
|
|
339
|
+
it('buildItems unwraps first group children', async () => {
|
|
340
|
+
const engine = new FlowEngine();
|
|
341
|
+
|
|
342
|
+
class Parent extends FlowModel {}
|
|
343
|
+
class FirstGroup extends FlowModel {}
|
|
344
|
+
FirstGroup.define({
|
|
345
|
+
label: 'First Group',
|
|
346
|
+
children: () => [
|
|
347
|
+
{ key: 'leaf-1', label: 'Leaf 1', createModelOptions: { use: 'Parent' } },
|
|
348
|
+
{ key: 'leaf-2', label: 'Leaf 2', createModelOptions: { use: 'Parent' } },
|
|
349
|
+
],
|
|
350
|
+
});
|
|
351
|
+
|
|
352
|
+
engine.registerModels({ Parent, FirstGroup });
|
|
353
|
+
const parent = engine.createModel<Parent>({ use: 'Parent', uid: 'parent-build-items' });
|
|
354
|
+
const ctx = parent.context;
|
|
355
|
+
|
|
356
|
+
const factory = buildItems('FirstGroup');
|
|
357
|
+
const items = await factory(ctx);
|
|
358
|
+
expect(items.map((it) => it.key)).toEqual(['leaf-1', 'leaf-2']);
|
|
359
|
+
});
|
|
360
|
+
|
|
361
|
+
it('buildItems returns empty array when no groups available', async () => {
|
|
362
|
+
const engine = new FlowEngine();
|
|
363
|
+
|
|
364
|
+
class Parent extends FlowModel {}
|
|
365
|
+
class HiddenGroup extends FlowModel {}
|
|
366
|
+
HiddenGroup.define({ label: 'Hidden', hide: true });
|
|
367
|
+
|
|
368
|
+
engine.registerModels({ Parent, HiddenGroup });
|
|
369
|
+
const parent = engine.createModel<Parent>({ use: 'Parent', uid: 'parent-empty-build-items' });
|
|
370
|
+
const ctx = parent.context;
|
|
371
|
+
|
|
372
|
+
const items = await buildItems('HiddenGroup')(ctx);
|
|
373
|
+
expect(items).toEqual([]);
|
|
374
|
+
});
|
|
375
|
+
});
|
|
376
|
+
|
|
377
|
+
describe('mergeSubModelItems', () => {
|
|
378
|
+
it('merges multiple arrays and inserts dividers when requested', async () => {
|
|
379
|
+
const sourceA: SubModelItem[] = [{ key: 'a', label: 'A' }];
|
|
380
|
+
const sourceB: SubModelItem[] = [{ key: 'b', label: 'B' }];
|
|
381
|
+
const merged = mergeSubModelItems([sourceA, sourceB], { addDividers: true });
|
|
382
|
+
|
|
383
|
+
const ctx = {} as FlowModelContext;
|
|
384
|
+
const result = Array.isArray(merged) ? merged : await merged(ctx);
|
|
385
|
+
|
|
386
|
+
expect(result.map((i) => i.key)).toEqual(['a', 'divider-1', 'b']);
|
|
387
|
+
expect(result[1]?.type).toBe('divider');
|
|
388
|
+
});
|
|
389
|
+
|
|
390
|
+
it('flattens nested factories while preserving order', async () => {
|
|
391
|
+
const dynamic = async () => [{ key: 'dynamic', label: 'Dynamic' }];
|
|
392
|
+
const factory = mergeSubModelItems([[{ key: 'a', label: 'A' }], dynamic, async () => [{ key: 'c', label: 'C' }]]);
|
|
393
|
+
|
|
394
|
+
const ctx = {} as FlowModelContext;
|
|
395
|
+
const items = await (factory as (ctx: FlowModelContext) => Promise<SubModelItem[]>)(ctx);
|
|
396
|
+
|
|
397
|
+
expect(items.map((i) => i.key)).toEqual(['a', 'dynamic', 'c']);
|
|
398
|
+
});
|
|
399
|
+
|
|
400
|
+
it('awaits async sources while inserting dividers', async () => {
|
|
401
|
+
const factory = mergeSubModelItems(
|
|
402
|
+
[async () => [{ key: 'first', label: 'First' }], async () => [{ key: 'second', label: 'Second' }]],
|
|
403
|
+
{ addDividers: true },
|
|
404
|
+
);
|
|
405
|
+
|
|
406
|
+
const ctx = {} as FlowModelContext;
|
|
407
|
+
const items = await (factory as (ctx: FlowModelContext) => Promise<SubModelItem[]>)(ctx);
|
|
408
|
+
expect(items.map((i) => i.key)).toEqual(['first', 'divider-1', 'second']);
|
|
409
|
+
expect(items[1]?.type).toBe('divider');
|
|
410
|
+
});
|
|
411
|
+
|
|
412
|
+
it('returns empty array when sources are empty or null', async () => {
|
|
413
|
+
const merged = mergeSubModelItems([undefined, null, []]);
|
|
414
|
+
const ctx = {} as FlowModelContext;
|
|
415
|
+
const result = Array.isArray(merged) ? merged : await merged(ctx);
|
|
416
|
+
expect(result).toEqual([]);
|
|
417
|
+
});
|
|
418
|
+
|
|
419
|
+
it('returns original source when only one valid entry', () => {
|
|
420
|
+
const original: SubModelItem[] = [{ key: 'solo', label: 'Solo' }];
|
|
421
|
+
const merged = mergeSubModelItems([null, original, undefined]);
|
|
422
|
+
expect(merged).toBe(original);
|
|
423
|
+
});
|
|
424
|
+
});
|
|
425
|
+
});
|
|
@@ -0,0 +1,12 @@
|
|
|
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
|
+
export * from './AddSubModelButton';
|
|
11
|
+
export * from './utils';
|
|
12
|
+
//
|