@nocobase/flow-engine 2.0.0-alpha.3 → 2.0.0-alpha.30
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/components/FieldModelRenderer.js +10 -4
- 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 +2 -5
- package/lib/components/FlowModelRenderer.js +16 -47
- package/lib/components/FormItem.js +5 -1
- package/lib/{runjs-context/snippets/global/requireAsync.snippet.d.ts → components/dnd/findModelUidPosition.d.ts} +4 -7
- package/lib/{runjs-context/snippets/scene/jsblock/jsx-mount.snippet.js → components/dnd/findModelUidPosition.js} +23 -19
- package/lib/components/dnd/gridDragPlanner.d.ts +130 -0
- package/lib/components/dnd/gridDragPlanner.js +497 -0
- package/lib/components/dnd/index.d.ts +2 -2
- package/lib/components/dnd/index.js +5 -5
- 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/StepSettingsDialog.js +7 -1
- package/lib/components/variables/VariableInput.js +16 -2
- package/lib/components/variables/VariableTag.js +43 -2
- package/lib/components/variables/types.d.ts +2 -0
- package/lib/data-source/index.d.ts +12 -4
- package/lib/data-source/index.js +19 -13
- package/lib/data-source/sortCollectionsByInherits.d.ts +10 -0
- package/lib/data-source/sortCollectionsByInherits.js +71 -0
- package/lib/executor/FlowExecutor.d.ts +4 -5
- package/lib/executor/FlowExecutor.js +135 -100
- package/lib/flowContext.d.ts +33 -5
- package/lib/flowContext.js +193 -76
- package/lib/flowEngine.d.ts +8 -1
- package/lib/flowEngine.js +18 -6
- package/lib/flowSettings.d.ts +2 -1
- package/lib/flowSettings.js +12 -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 +2 -0
- package/lib/models/CollectionFieldModel.js +43 -3
- package/lib/models/flowModel.d.ts +28 -29
- package/lib/models/flowModel.js +114 -92
- package/lib/models/forkFlowModel.d.ts +4 -4
- package/lib/models/forkFlowModel.js +32 -8
- package/lib/provider.d.ts +3 -1
- package/lib/provider.js +7 -5
- package/lib/resources/multiRecordResource.js +2 -0
- package/lib/resources/singleRecordResource.js +1 -0
- 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 +183 -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 +161 -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-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/types.d.ts +28 -3
- package/lib/types.js +4 -3
- 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/index.d.ts +3 -2
- package/lib/utils/index.js +5 -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/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/variablesParams.d.ts +9 -5
- package/lib/utils/variablesParams.js +47 -36
- package/lib/views/PageComponent.js +2 -1
- 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 +8 -8
- package/lib/views/useDialog.js +8 -7
- package/lib/views/useDrawer.d.ts +8 -8
- package/lib/views/useDrawer.js +40 -26
- package/lib/views/usePage.d.ts +8 -8
- package/lib/views/usePage.js +8 -7
- package/package.json +5 -3
- package/src/BlockScopedFlowEngine.ts +86 -0
- package/src/FlowContextProvider.tsx +4 -2
- package/src/JSRunner.ts +3 -0
- package/src/ViewScopedFlowEngine.ts +1 -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__/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__/globalFlowRegistry.test.ts +1 -1
- 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 +449 -0
- package/src/__tests__/runjsSnippets.test.ts +140 -0
- package/src/__tests__/viewScopedFlowEngine.test.ts +3 -3
- package/src/components/DynamicFlowsEditor.tsx +3 -4
- package/src/components/FieldModelRenderer.tsx +16 -5
- package/src/components/FieldSkeleton.tsx +27 -0
- package/src/components/FlowContextSelector.tsx +6 -2
- package/src/components/FlowModelRenderer.tsx +30 -78
- package/src/components/FormItem.tsx +8 -1
- package/src/components/__tests__/flow-model-render-error-fallback.test.tsx +5 -5
- package/src/components/__tests__/gridDragPlanner.test.ts +494 -0
- package/src/components/dnd/README.md +149 -0
- package/src/components/dnd/findModelUidPosition.ts +26 -0
- package/src/components/dnd/gridDragPlanner.ts +659 -0
- package/src/components/dnd/index.tsx +3 -3
- 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/StepSettingsDialog.tsx +14 -1
- package/src/components/settings/wrappers/contextual/__tests__/DefaultSettingsIcon.test.tsx +424 -0
- package/src/components/subModel/__tests__/AddSubModelButton.test.tsx +5 -7
- package/src/components/variables/VariableInput.tsx +22 -2
- 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 +17 -11
- package/src/data-source/sortCollectionsByInherits.ts +61 -0
- package/src/executor/FlowExecutor.ts +178 -121
- package/src/executor/__tests__/ctx-defs-injection.test.ts +197 -0
- package/src/executor/__tests__/flowExecutor.test.ts +151 -5
- package/src/flowContext.ts +266 -97
- package/src/flowEngine.ts +21 -6
- package/src/flowSettings.ts +9 -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 +43 -4
- package/src/models/__tests__/flowModel.getFlows.sort.test.ts +4 -4
- package/src/models/__tests__/flowModel.test.ts +234 -111
- package/src/models/__tests__/forkFlowModel.test.ts +22 -7
- package/src/models/flowModel.tsx +149 -125
- package/src/models/forkFlowModel.ts +41 -8
- package/src/provider.tsx +10 -7
- package/src/resources/multiRecordResource.ts +2 -0
- package/src/resources/singleRecordResource.ts +1 -0
- 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 +171 -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 +177 -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-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/types.ts +34 -0
- package/src/utils/__tests__/jsxTransform.test.ts +38 -0
- package/src/utils/__tests__/safeGlobals.test.ts +22 -1
- package/src/utils/buildSettingsViewInputArgs.ts +72 -0
- package/src/utils/createEphemeralContext.ts +142 -0
- package/src/utils/index.ts +2 -2
- package/src/utils/jsxTransform.ts +39 -0
- package/src/utils/params-resolvers.ts +2 -2
- 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/variablesParams.ts +50 -38
- package/src/views/PageComponent.tsx +1 -1
- package/src/views/createViewMeta.ts +393 -70
- package/src/views/index.tsx +1 -0
- package/src/views/useDialog.tsx +12 -10
- package/src/views/useDrawer.tsx +60 -36
- package/src/views/usePage.tsx +13 -10
- package/lib/components/dnd/getMousePositionOnElement.d.ts +0 -50
- package/lib/components/dnd/getMousePositionOnElement.js +0 -95
- package/lib/components/dnd/moveBlock.d.ts +0 -33
- package/lib/components/dnd/moveBlock.js +0 -302
- 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/api-request-post.snippet.js +0 -42
- 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/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/global/try-catch-async.snippet.js +0 -44
- 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-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/components/dnd/getMousePositionOnElement.ts +0 -115
- package/src/components/dnd/moveBlock.ts +0 -379
- 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
|
@@ -0,0 +1,38 @@
|
|
|
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 type { SnippetModule } from '../../types';
|
|
11
|
+
import { JSBlockRunJSContext } from '../../../contexts/JSBlockRunJSContext';
|
|
12
|
+
|
|
13
|
+
const snippet: SnippetModule = {
|
|
14
|
+
contexts: [JSBlockRunJSContext],
|
|
15
|
+
prefix: 'sn-jsb-react',
|
|
16
|
+
label: 'Render React',
|
|
17
|
+
description: 'Render a React element inside the block container',
|
|
18
|
+
locales: {
|
|
19
|
+
'zh-CN': {
|
|
20
|
+
label: '渲染 React',
|
|
21
|
+
description: '在区块容器中渲染 React 组件',
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
content: `
|
|
25
|
+
// Render a React element into ctx.element via ReactDOM
|
|
26
|
+
const { Button } = ctx.antd;
|
|
27
|
+
|
|
28
|
+
ctx.render(
|
|
29
|
+
<div style={{ padding: 12 }}>
|
|
30
|
+
<Button type="primary" onClick={() => ctx.message.success(ctx.t('Clicked!'))}>
|
|
31
|
+
{ctx.t('Click')}
|
|
32
|
+
</Button>
|
|
33
|
+
</div>
|
|
34
|
+
);
|
|
35
|
+
`,
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export default snippet;
|
|
@@ -0,0 +1,76 @@
|
|
|
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 type { SnippetModule } from '../../types';
|
|
11
|
+
import { JSBlockRunJSContext } from '../../../contexts/JSBlockRunJSContext';
|
|
12
|
+
|
|
13
|
+
const snippet: SnippetModule = {
|
|
14
|
+
contexts: [JSBlockRunJSContext],
|
|
15
|
+
prefix: 'sn-jsb-stats',
|
|
16
|
+
label: 'Render statistics cards',
|
|
17
|
+
description: 'Display multiple statistic cards with numbers from API',
|
|
18
|
+
locales: {
|
|
19
|
+
'zh-CN': {
|
|
20
|
+
label: '渲染统计卡片',
|
|
21
|
+
description: '显示多个统计数字卡片(从 API 获取数据)',
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
content: `
|
|
25
|
+
const { Card, Statistic, Row, Col } = ctx.antd;
|
|
26
|
+
|
|
27
|
+
const res = await ctx.api.request({
|
|
28
|
+
url: 'users:list',
|
|
29
|
+
method: 'get',
|
|
30
|
+
params: {
|
|
31
|
+
pageSize: 100,
|
|
32
|
+
appends: ['roles'],
|
|
33
|
+
},
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
const users = res?.data?.data || [];
|
|
37
|
+
|
|
38
|
+
const total = users.length;
|
|
39
|
+
const adminCount = users.filter((user) =>
|
|
40
|
+
Array.isArray(user?.roles) && user.roles.some((role) => role?.name === 'admin')
|
|
41
|
+
).length;
|
|
42
|
+
const withEmail = users.filter((user) => !!user?.email).length;
|
|
43
|
+
const distinctRoles = new Set(
|
|
44
|
+
users
|
|
45
|
+
.flatMap((user) => (Array.isArray(user?.roles) ? user.roles.map((role) => role?.name) : []))
|
|
46
|
+
.filter(Boolean),
|
|
47
|
+
).size;
|
|
48
|
+
|
|
49
|
+
ctx.render(
|
|
50
|
+
<Row gutter={16}>
|
|
51
|
+
<Col span={6}>
|
|
52
|
+
<Card>
|
|
53
|
+
<Statistic title={ctx.t('Total users')} value={total} valueStyle={{ color: '#3f8600' }} />
|
|
54
|
+
</Card>
|
|
55
|
+
</Col>
|
|
56
|
+
<Col span={6}>
|
|
57
|
+
<Card>
|
|
58
|
+
<Statistic title={ctx.t('Administrators')} value={adminCount} valueStyle={{ color: '#1890ff' }} />
|
|
59
|
+
</Card>
|
|
60
|
+
</Col>
|
|
61
|
+
<Col span={6}>
|
|
62
|
+
<Card>
|
|
63
|
+
<Statistic title={ctx.t('Users with email')} value={withEmail} valueStyle={{ color: '#faad14' }} />
|
|
64
|
+
</Card>
|
|
65
|
+
</Col>
|
|
66
|
+
<Col span={6}>
|
|
67
|
+
<Card>
|
|
68
|
+
<Statistic title={ctx.t('Distinct roles')} value={distinctRoles} valueStyle={{ color: '#cf1322' }} />
|
|
69
|
+
</Card>
|
|
70
|
+
</Col>
|
|
71
|
+
</Row>
|
|
72
|
+
);
|
|
73
|
+
`,
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
export default snippet;
|
|
@@ -0,0 +1,65 @@
|
|
|
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 type { SnippetModule } from '../../types';
|
|
11
|
+
import { JSBlockRunJSContext } from '../../../contexts/JSBlockRunJSContext';
|
|
12
|
+
|
|
13
|
+
const snippet: SnippetModule = {
|
|
14
|
+
contexts: [JSBlockRunJSContext],
|
|
15
|
+
prefix: 'sn-jsb-timeline',
|
|
16
|
+
label: 'Render timeline from records',
|
|
17
|
+
description: 'Display records as a timeline using Ant Design Timeline',
|
|
18
|
+
locales: {
|
|
19
|
+
'zh-CN': {
|
|
20
|
+
label: '渲染时间轴',
|
|
21
|
+
description: '使用 Ant Design 时间轴组件显示记录历史',
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
content: `
|
|
25
|
+
const { Timeline, Card } = ctx.antd;
|
|
26
|
+
|
|
27
|
+
const res = await ctx.api.request({
|
|
28
|
+
url: 'users:list',
|
|
29
|
+
method: 'get',
|
|
30
|
+
params: {
|
|
31
|
+
pageSize: 20,
|
|
32
|
+
sort: ['-createdAt'],
|
|
33
|
+
},
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
const records = res?.data?.data || [];
|
|
37
|
+
|
|
38
|
+
if (!records.length) {
|
|
39
|
+
ctx.render('<div style="padding:16px;color:#999;">' + ctx.t('No data') + '</div>');
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
ctx.render(
|
|
44
|
+
<Card title={ctx.t('Activity Timeline')} bordered>
|
|
45
|
+
<Timeline mode="left">
|
|
46
|
+
{records.map((record) => (
|
|
47
|
+
<Timeline.Item
|
|
48
|
+
key={record.id}
|
|
49
|
+
label={record.createdAt ? new Date(record.createdAt).toLocaleString() : ''}
|
|
50
|
+
>
|
|
51
|
+
<div>
|
|
52
|
+
<strong>{record.nickname || record.username || ctx.t('Unnamed user')}</strong>
|
|
53
|
+
{record.email ? (
|
|
54
|
+
<div style={{ color: '#999', fontSize: '12px', marginTop: '4px' }}>{record.email}</div>
|
|
55
|
+
) : null}
|
|
56
|
+
</div>
|
|
57
|
+
</Timeline.Item>
|
|
58
|
+
))}
|
|
59
|
+
</Timeline>
|
|
60
|
+
</Card>
|
|
61
|
+
);
|
|
62
|
+
`,
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
export default snippet;
|
|
@@ -0,0 +1,46 @@
|
|
|
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 { JSBlockRunJSContext } from '../../../contexts/JSBlockRunJSContext';
|
|
11
|
+
import type { SnippetModule } from '../../types';
|
|
12
|
+
|
|
13
|
+
const snippet: SnippetModule = {
|
|
14
|
+
contexts: [JSBlockRunJSContext],
|
|
15
|
+
prefix: 'sn-resource-example',
|
|
16
|
+
label: 'Resource example',
|
|
17
|
+
description: 'Create a resource via ctx.createResource and render JSON output',
|
|
18
|
+
locales: {
|
|
19
|
+
'zh-CN': {
|
|
20
|
+
label: '资源示例',
|
|
21
|
+
description: '使用 ctx.useResource 加载数据并渲染 JSON 输出',
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
content:
|
|
25
|
+
`
|
|
26
|
+
// Create a resource and load a single record
|
|
27
|
+
const resource = ctx.createResource('SingleRecordResource');
|
|
28
|
+
resource.setDataSourceKey('main');
|
|
29
|
+
resource.setResourceName('users');
|
|
30
|
+
// Optionally set filterByTk to target a specific record:
|
|
31
|
+
// resource.setRequestOptions('params', { filterByTk: 1 });
|
|
32
|
+
await resource.refresh();
|
|
33
|
+
|
|
34
|
+
ctx.element.innerHTML = ` +
|
|
35
|
+
'`' +
|
|
36
|
+
`
|
|
37
|
+
<pre style="padding: 12px; background: #f5f5f5; border-radius: 6px;">
|
|
38
|
+
\${JSON.stringify(resource.getData(), null, 2)}
|
|
39
|
+
</pre>
|
|
40
|
+
` +
|
|
41
|
+
'`' +
|
|
42
|
+
`;
|
|
43
|
+
`,
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
export default snippet;
|
|
@@ -0,0 +1,264 @@
|
|
|
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 type { SnippetModule } from '../../types';
|
|
11
|
+
import { JSBlockRunJSContext } from '../../../contexts/JSBlockRunJSContext';
|
|
12
|
+
|
|
13
|
+
const snippet: SnippetModule = {
|
|
14
|
+
contexts: [JSBlockRunJSContext],
|
|
15
|
+
prefix: 'sn-three-users-orbit',
|
|
16
|
+
label: 'Users orbit (three.js)',
|
|
17
|
+
description: 'Fetch users:list and render a rotating 3D orbit of users with hover/click',
|
|
18
|
+
locales: {
|
|
19
|
+
'zh-CN': {
|
|
20
|
+
label: 'Three.js 用户轨道',
|
|
21
|
+
description: '从 users:list 加载用户,并以 3D 轨道方式展示(支持悬停高亮与点击提示)',
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
content: `
|
|
25
|
+
// Container
|
|
26
|
+
const container = document.createElement('div');
|
|
27
|
+
container.style.width = '100%';
|
|
28
|
+
container.style.height = '360px';
|
|
29
|
+
container.style.position = 'relative';
|
|
30
|
+
container.style.borderRadius = '10px';
|
|
31
|
+
container.style.overflow = 'hidden';
|
|
32
|
+
container.style.background = 'radial-gradient(700px 300px at 20% 25%, #172036, #0b0f19 60%), radial-gradient(600px 240px at 80% 70%, rgba(56,189,248,0.12), transparent 60%)';
|
|
33
|
+
ctx.element.replaceChildren(container);
|
|
34
|
+
|
|
35
|
+
// 不做显式清理逻辑;如需存储信息,统一挂在 ctx.model 上
|
|
36
|
+
|
|
37
|
+
// 使用 ctx.useResource 加载 users:list(真实数据)
|
|
38
|
+
ctx.useResource('MultiRecordResource');
|
|
39
|
+
const resource = ctx.resource;
|
|
40
|
+
resource.setDataSourceKey && resource.setDataSourceKey('main');
|
|
41
|
+
resource.setResourceName && resource.setResourceName('users');
|
|
42
|
+
resource.setPageSize && resource.setPageSize(50);
|
|
43
|
+
try {
|
|
44
|
+
await resource.refresh();
|
|
45
|
+
} catch (err) {
|
|
46
|
+
var msg = (err && err.message) ? err.message : 'users:list 请求失败';
|
|
47
|
+
ctx.element.innerHTML = '<div style="color:#cbd5e1; padding: 12px; text-align:center;">' + msg + '</div>';
|
|
48
|
+
throw err;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Helpers: generate avatar textures (emoji or initials)
|
|
52
|
+
function makeAvatarTexture(user, idx) {
|
|
53
|
+
const canvas = document.createElement('canvas');
|
|
54
|
+
const size = 128;
|
|
55
|
+
canvas.width = canvas.height = size;
|
|
56
|
+
const g = canvas.getContext('2d');
|
|
57
|
+
// background circle with subtle gradient
|
|
58
|
+
const palettes = ['#60a5fa','#34d399','#fbbf24','#f472b6','#a78bfa','#f87171','#22d3ee'];
|
|
59
|
+
const c1 = palettes[idx % palettes.length];
|
|
60
|
+
const grad = g.createRadialGradient(size*0.35, size*0.35, 10, size*0.5, size*0.5, size*0.6);
|
|
61
|
+
grad.addColorStop(0, c1);
|
|
62
|
+
grad.addColorStop(1, '#111827');
|
|
63
|
+
g.fillStyle = grad;
|
|
64
|
+
g.beginPath();
|
|
65
|
+
g.arc(size/2, size/2, size*0.48, 0, Math.PI*2);
|
|
66
|
+
g.fill();
|
|
67
|
+
// border
|
|
68
|
+
g.lineWidth = 4; g.strokeStyle = 'rgba(255,255,255,0.25)';
|
|
69
|
+
g.stroke();
|
|
70
|
+
// content: emoji if possible, else initials
|
|
71
|
+
const emojis = ['😀','😎','🚀','🌟','🎉','🧠','🐼','🦊','🐯','🦄','🍀','🍕','⚡️','🔥','❤️'];
|
|
72
|
+
const text = emojis[idx % emojis.length];
|
|
73
|
+
g.textAlign = 'center';
|
|
74
|
+
g.textBaseline = 'middle';
|
|
75
|
+
g.font = 'bold 68px system-ui, -apple-system, Segoe UI Emoji, Noto Color Emoji, Apple Color Emoji';
|
|
76
|
+
g.fillStyle = '#fff';
|
|
77
|
+
g.fillText(text, size/2, size/2 + 4);
|
|
78
|
+
const tex = new THREE.CanvasTexture(canvas);
|
|
79
|
+
tex.needsUpdate = true;
|
|
80
|
+
return tex;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const THREE = await ctx.importAsync('https://esm.sh/three@0.160.0');
|
|
84
|
+
const { Scene, PerspectiveCamera, WebGLRenderer, Color, AmbientLight, DirectionalLight, Group, Mesh, MeshStandardMaterial, SphereGeometry, Raycaster, Vector2 } = THREE;
|
|
85
|
+
|
|
86
|
+
const scene = new Scene();
|
|
87
|
+
scene.background = new Color(0x0b0f19);
|
|
88
|
+
|
|
89
|
+
const camera = new PerspectiveCamera(55, container.clientWidth / container.clientHeight, 0.1, 100);
|
|
90
|
+
camera.position.set(0, 1.2, 6.5);
|
|
91
|
+
|
|
92
|
+
const renderer = new WebGLRenderer({ antialias: true, alpha: false });
|
|
93
|
+
renderer.setSize(container.clientWidth, container.clientHeight);
|
|
94
|
+
renderer.setPixelRatio(1); // sandbox-friendly
|
|
95
|
+
container.appendChild(renderer.domElement);
|
|
96
|
+
|
|
97
|
+
scene.add(new AmbientLight(0xffffff, 0.8));
|
|
98
|
+
const dir = new DirectionalLight(0xffffff, 0.6);
|
|
99
|
+
dir.position.set(2.5, 3.0, 4.0);
|
|
100
|
+
scene.add(dir);
|
|
101
|
+
|
|
102
|
+
const orbit = new Group();
|
|
103
|
+
scene.add(orbit);
|
|
104
|
+
|
|
105
|
+
const users = (resource && resource.getData && Array.isArray(resource.getData())) ? resource.getData() : [];
|
|
106
|
+
if (!users.length) {
|
|
107
|
+
container.innerHTML = '<div style="color:#cbd5e1; padding: 12px; text-align:center;">users:list 接口无数据</div>';
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
const N = users.length;
|
|
111
|
+
const R = 2.8;
|
|
112
|
+
// background starfield
|
|
113
|
+
const starCount = 500;
|
|
114
|
+
const starPos = new Float32Array(starCount * 3);
|
|
115
|
+
for (let i = 0; i < starCount; i++) {
|
|
116
|
+
const r = 10 * Math.pow(Math.random(), 0.7) + 4;
|
|
117
|
+
const th = Math.random() * Math.PI * 2;
|
|
118
|
+
const ph = Math.acos(2 * Math.random() - 1);
|
|
119
|
+
starPos[i*3+0] = r * Math.sin(ph) * Math.cos(th);
|
|
120
|
+
starPos[i*3+1] = r * Math.cos(ph) * 0.5;
|
|
121
|
+
starPos[i*3+2] = r * Math.sin(ph) * Math.sin(th);
|
|
122
|
+
}
|
|
123
|
+
const starGeo = new THREE.BufferGeometry();
|
|
124
|
+
starGeo.setAttribute('position', new THREE.Float32BufferAttribute(starPos, 3));
|
|
125
|
+
const starMat = new THREE.PointsMaterial({ color: 0xffffff, size: 0.02, transparent: true, opacity: 0.8 });
|
|
126
|
+
const stars = new THREE.Points(starGeo, starMat);
|
|
127
|
+
scene.add(stars);
|
|
128
|
+
|
|
129
|
+
const items = [];
|
|
130
|
+
for (let i = 0; i < N; i++) {
|
|
131
|
+
const u = users[i];
|
|
132
|
+
const a = (i / N) * Math.PI * 2;
|
|
133
|
+
const y = (Math.sin(a * 2) * 0.6);
|
|
134
|
+
const tex = makeAvatarTexture(u, i);
|
|
135
|
+
const mat = new THREE.SpriteMaterial({ map: tex, transparent: true, depthWrite: false });
|
|
136
|
+
const sprite = new THREE.Sprite(mat);
|
|
137
|
+
sprite.scale.set(0.9, 0.9, 1);
|
|
138
|
+
sprite.position.set(Math.cos(a) * R, y, Math.sin(a) * R);
|
|
139
|
+
sprite.userData.user = u;
|
|
140
|
+
orbit.add(sprite);
|
|
141
|
+
items.push(sprite);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Simple ring wireframe for context
|
|
145
|
+
const ring = new Group();
|
|
146
|
+
scene.add(ring);
|
|
147
|
+
for (let k = 0; k < 64; k++) {
|
|
148
|
+
const a = (k / 64) * Math.PI * 2;
|
|
149
|
+
const seg = new Mesh(new SphereGeometry(0.01, 8, 8), new MeshStandardMaterial({ color: 0xffffff }));
|
|
150
|
+
seg.position.set(Math.cos(a) * R, 0, Math.sin(a) * R);
|
|
151
|
+
ring.add(seg);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// Hover + click via Raycaster
|
|
155
|
+
const raycaster = new Raycaster();
|
|
156
|
+
const mouse = new Vector2();
|
|
157
|
+
let over = null;
|
|
158
|
+
|
|
159
|
+
function updateMouse(e) {
|
|
160
|
+
const rect = container.getBoundingClientRect();
|
|
161
|
+
const x = (e.clientX - rect.left) / rect.width;
|
|
162
|
+
const y = (e.clientY - rect.top) / rect.height;
|
|
163
|
+
mouse.set(x * 2 - 1, -(y * 2 - 1));
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
function handleHover() {
|
|
167
|
+
raycaster.setFromCamera(mouse, camera);
|
|
168
|
+
const intersects = raycaster.intersectObjects(items, false);
|
|
169
|
+
const hit = (intersects && intersects[0] && intersects[0].object) ? intersects[0].object : null;
|
|
170
|
+
if (over && over !== hit) {
|
|
171
|
+
over.material.opacity = 1.0;
|
|
172
|
+
over.scale.set(0.9, 0.9, 1);
|
|
173
|
+
over = null;
|
|
174
|
+
}
|
|
175
|
+
if (hit && hit !== over) {
|
|
176
|
+
over = hit;
|
|
177
|
+
over.material.opacity = 1.0;
|
|
178
|
+
over.scale.set(1.15, 1.15, 1);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
const onMouseMove = (e) => { updateMouse(e); handleHover(); };
|
|
183
|
+
// resolve primary key field name from collection meta
|
|
184
|
+
let __pkField = null;
|
|
185
|
+
async function getPrimaryKeyField() {
|
|
186
|
+
if (__pkField) return __pkField;
|
|
187
|
+
const name = (resource && resource.getResourceName) ? resource.getResourceName() : 'users';
|
|
188
|
+
try {
|
|
189
|
+
const meta = await ctx.api.request({ url: 'collections:get', method: 'get', params: { filterByTk: name } });
|
|
190
|
+
const data = (meta && meta.data) ? meta.data : {};
|
|
191
|
+
// prefer filterTargetKey, fallback to fields.primaryKey
|
|
192
|
+
const ft = (data && data.filterTargetKey) ? data.filterTargetKey : (data && data.options && data.options.filterTargetKey);
|
|
193
|
+
if (ft && typeof ft === 'string') {
|
|
194
|
+
__pkField = ft;
|
|
195
|
+
return __pkField;
|
|
196
|
+
}
|
|
197
|
+
const fields = (data && data.fields) ? data.fields : (data && data.options && data.options.fields) ? data.options.fields : [];
|
|
198
|
+
const pk = Array.isArray(fields) && fields.find(function(f){ return f && (f.primaryKey || (f.uiSchema && f.uiSchema['x-component'] === 'ID')); });
|
|
199
|
+
if (pk && typeof pk.name === 'string') {
|
|
200
|
+
__pkField = pk.name;
|
|
201
|
+
return __pkField;
|
|
202
|
+
}
|
|
203
|
+
} catch (_) {}
|
|
204
|
+
__pkField = 'id';
|
|
205
|
+
return __pkField;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
const onClick = async (e) => {
|
|
209
|
+
updateMouse(e);
|
|
210
|
+
handleHover();
|
|
211
|
+
if (over && over.userData && over.userData.user) {
|
|
212
|
+
const u = over.userData.user;
|
|
213
|
+
const baseId = (ctx.model && ctx.model.uid) ? ctx.model.uid : String(ctx.model || 'runjs');
|
|
214
|
+
const popupUid = baseId + '-details';
|
|
215
|
+
const pkField = await getPrimaryKeyField();
|
|
216
|
+
var tk = (u && u[pkField]) ? u[pkField] : (u ? (u.id || u.userId || u.pk) : undefined);
|
|
217
|
+
await ctx.openView(popupUid, {
|
|
218
|
+
mode: 'dialog',
|
|
219
|
+
// 让弹窗自动定位当前记录:顶层 filterByTk + 数据源/集合信息
|
|
220
|
+
dataSourceKey: (resource && resource.getDataSourceKey) ? resource.getDataSourceKey() : 'main',
|
|
221
|
+
collectionName: (resource && resource.getResourceName) ? resource.getResourceName() : 'users',
|
|
222
|
+
filterByTk: tk,
|
|
223
|
+
params: { user: u, userId: tk },
|
|
224
|
+
title: (u.nickname || u.username || u.name || 'User') + ' details',
|
|
225
|
+
width: 720,
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
};
|
|
229
|
+
container.addEventListener('mousemove', onMouseMove);
|
|
230
|
+
container.addEventListener('click', onClick);
|
|
231
|
+
|
|
232
|
+
// Animation (no rAF/use setInterval)
|
|
233
|
+
let t = 0;
|
|
234
|
+
const tick = () => {
|
|
235
|
+
t += 0.016;
|
|
236
|
+
orbit.rotation.y += 0.005; // slow spin
|
|
237
|
+
stars.rotation.y = t * 0.02;
|
|
238
|
+
// subtle bobbing per item
|
|
239
|
+
for (let i = 0; i < items.length; i++) {
|
|
240
|
+
const m = items[i];
|
|
241
|
+
const a = (i / items.length) * Math.PI * 2;
|
|
242
|
+
m.position.y = Math.sin(a * 2 + t * 1.5) * 0.6;
|
|
243
|
+
}
|
|
244
|
+
renderer.render(scene, camera);
|
|
245
|
+
};
|
|
246
|
+
// 若上一次运行的动画仍在,清理之(仅使用 ctx.model 存储)
|
|
247
|
+
try { if (ctx.model && ctx.model.__usersOrbitTimer) clearInterval(ctx.model.__usersOrbitTimer); } catch (_) {}
|
|
248
|
+
var __timer = setInterval(tick, 16);
|
|
249
|
+
if (ctx.model) ctx.model.__usersOrbitTimer = __timer;
|
|
250
|
+
|
|
251
|
+
// Initial sizing
|
|
252
|
+
(() => {
|
|
253
|
+
const w = container.clientWidth;
|
|
254
|
+
const h = container.clientHeight;
|
|
255
|
+
camera.aspect = w / h;
|
|
256
|
+
camera.updateProjectionMatrix();
|
|
257
|
+
renderer.setSize(w, h);
|
|
258
|
+
})();
|
|
259
|
+
|
|
260
|
+
// 不额外挂载 cleanup;容器被替换后旧 DOM 将被 GC;定时器在下次运行前通过 ctx.model 清理
|
|
261
|
+
`,
|
|
262
|
+
};
|
|
263
|
+
|
|
264
|
+
export default snippet;
|
|
@@ -0,0 +1,105 @@
|
|
|
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 type { SnippetModule } from '../../types';
|
|
11
|
+
import { JSBlockRunJSContext } from '../../../contexts/JSBlockRunJSContext';
|
|
12
|
+
|
|
13
|
+
const snippet: SnippetModule = {
|
|
14
|
+
contexts: [JSBlockRunJSContext],
|
|
15
|
+
prefix: 'sn-jsb-vue',
|
|
16
|
+
label: 'Embed Vue component',
|
|
17
|
+
description: 'Use ctx.importAsync to load Vue 3 ESM build and render a reactive widget',
|
|
18
|
+
locales: {
|
|
19
|
+
'zh-CN': {
|
|
20
|
+
label: '嵌入 Vue 组件',
|
|
21
|
+
description: '通过 ctx.importAsync 加载 Vue 3 ESM 构建并渲染交互组件',
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
content: `
|
|
25
|
+
const mountNode = document.createElement('div');
|
|
26
|
+
mountNode.style.padding = '16px';
|
|
27
|
+
mountNode.style.background = '#fff';
|
|
28
|
+
mountNode.style.borderRadius = '8px';
|
|
29
|
+
const target = document.createElement('div');
|
|
30
|
+
target.className = 'nb-vue-counter';
|
|
31
|
+
mountNode.appendChild(target);
|
|
32
|
+
ctx.element.replaceChildren(mountNode);
|
|
33
|
+
|
|
34
|
+
async function bootstrap() {
|
|
35
|
+
const mod = await ctx.importAsync('https://esm.sh/vue@3.4.27/dist/vue.runtime.esm-browser.js');
|
|
36
|
+
const createApp = mod?.createApp;
|
|
37
|
+
const ref = mod?.ref;
|
|
38
|
+
const h = mod?.h;
|
|
39
|
+
if (typeof createApp !== 'function' || typeof ref !== 'function' || typeof h !== 'function') {
|
|
40
|
+
throw new Error('Vue ESM module not available');
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const Counter = {
|
|
44
|
+
setup() {
|
|
45
|
+
const count = ref(0);
|
|
46
|
+
const increase = () => {
|
|
47
|
+
count.value += 1;
|
|
48
|
+
};
|
|
49
|
+
const openPopup = async () => {
|
|
50
|
+
const popupUid = ctx.model?.uid ? ctx.model.uid + '-popup' : 'vue-popup';
|
|
51
|
+
await ctx.openView(popupUid, {
|
|
52
|
+
mode: 'drawer',
|
|
53
|
+
title: ctx.t('Hello from Vue'),
|
|
54
|
+
params: {
|
|
55
|
+
fromVue: true,
|
|
56
|
+
triggerCount: count.value,
|
|
57
|
+
},
|
|
58
|
+
});
|
|
59
|
+
};
|
|
60
|
+
return () =>
|
|
61
|
+
h(
|
|
62
|
+
'div',
|
|
63
|
+
{ style: 'display:flex;align-items:center;gap:12px;' },
|
|
64
|
+
[
|
|
65
|
+
h(
|
|
66
|
+
'button',
|
|
67
|
+
{
|
|
68
|
+
style:
|
|
69
|
+
'padding:6px 12px;border:1px solid #fa8c16;background:#fa8c16;color:#fff;border-radius:4px;cursor:pointer;',
|
|
70
|
+
onClick: increase,
|
|
71
|
+
},
|
|
72
|
+
ctx.t('Increase'),
|
|
73
|
+
),
|
|
74
|
+
h(
|
|
75
|
+
'button',
|
|
76
|
+
{
|
|
77
|
+
style:
|
|
78
|
+
'padding:6px 12px;border:1px solid #1677ff;background:#1677ff;color:#fff;border-radius:4px;cursor:pointer;',
|
|
79
|
+
onClick: openPopup,
|
|
80
|
+
},
|
|
81
|
+
ctx.t('Open popup'),
|
|
82
|
+
),
|
|
83
|
+
h(
|
|
84
|
+
'span',
|
|
85
|
+
null,
|
|
86
|
+
ctx.t('Current count') + ': ' + count.value,
|
|
87
|
+
),
|
|
88
|
+
],
|
|
89
|
+
);
|
|
90
|
+
},
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
const app = createApp(Counter);
|
|
94
|
+
const mountTarget = ctx.element.querySelector('.nb-vue-counter');
|
|
95
|
+
app.mount(mountTarget || ctx.element);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
bootstrap().catch((error) => {
|
|
99
|
+
console.error('[RunJS] failed to mount Vue counter', error);
|
|
100
|
+
mountNode.innerHTML = '<div style="color:#c00;">' + (error?.message || ctx.t('Vue initialization failed')) + '</div>';
|
|
101
|
+
});
|
|
102
|
+
`,
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
export default snippet;
|
|
@@ -0,0 +1,33 @@
|
|
|
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 type { SnippetModule } from '../../types';
|
|
11
|
+
import { JSFieldRunJSContext } from '../../../contexts/JSFieldRunJSContext';
|
|
12
|
+
import { FormJSFieldItemRunJSContext } from '../../../contexts/FormJSFieldItemRunJSContext';
|
|
13
|
+
|
|
14
|
+
const snippet: SnippetModule = {
|
|
15
|
+
contexts: [JSFieldRunJSContext, FormJSFieldItemRunJSContext],
|
|
16
|
+
prefix: 'sn-jsf-color',
|
|
17
|
+
label: 'Display number field as colored text',
|
|
18
|
+
description: 'Display numeric values using colors based on their sign',
|
|
19
|
+
locales: {
|
|
20
|
+
'zh-CN': {
|
|
21
|
+
label: '将数字字段显示为彩色文本',
|
|
22
|
+
description: '根据数值正负设置显示颜色',
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
content: `
|
|
26
|
+
// Colorize based on numeric sign
|
|
27
|
+
const n = Number(ctx.value ?? 0);
|
|
28
|
+
const color = Number.isFinite(n) ? (n > 0 ? 'green' : n < 0 ? 'red' : '#999') : '#555';
|
|
29
|
+
ctx.element.innerHTML = '<span style=' + JSON.stringify('color:' + color) + '>' + String(ctx.value ?? '') + '</span>';
|
|
30
|
+
`,
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export default snippet;
|
|
@@ -0,0 +1,45 @@
|
|
|
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 type { SnippetModule } from '../../types';
|
|
11
|
+
import { JSFieldRunJSContext } from '../../../contexts/JSFieldRunJSContext';
|
|
12
|
+
|
|
13
|
+
const snippet: SnippetModule = {
|
|
14
|
+
contexts: [JSFieldRunJSContext],
|
|
15
|
+
prefix: 'sn-jsf-copy',
|
|
16
|
+
label: 'Display text field with copy button',
|
|
17
|
+
description: 'Render the text field value with a copy-to-clipboard button',
|
|
18
|
+
locales: {
|
|
19
|
+
'zh-CN': {
|
|
20
|
+
label: '将文本字段显示为复制按钮',
|
|
21
|
+
description: '展示字段值并提供快捷复制到剪贴板的按钮',
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
content: `
|
|
25
|
+
const text = String(ctx.value ?? '');
|
|
26
|
+
ctx.element.innerHTML = '<a class="nb-copy" style="cursor:pointer;color:#1677ff">' +
|
|
27
|
+
ctx.t('Copy') + '</a>';
|
|
28
|
+
|
|
29
|
+
ctx.element.querySelector('.nb-copy')?.addEventListener('click', async () => {
|
|
30
|
+
if (navigator?.clipboard?.writeText) {
|
|
31
|
+
await navigator.clipboard.writeText(text);
|
|
32
|
+
} else {
|
|
33
|
+
const ta = document.createElement('textarea');
|
|
34
|
+
ta.value = text;
|
|
35
|
+
document.body.appendChild(ta);
|
|
36
|
+
ta.select();
|
|
37
|
+
document.execCommand('copy');
|
|
38
|
+
document.body.removeChild(ta);
|
|
39
|
+
}
|
|
40
|
+
ctx.message.success(ctx.t('Copied'));
|
|
41
|
+
});
|
|
42
|
+
`,
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export default snippet;
|