@nocobase/client-v2 2.2.0-alpha.1 → 2.2.0-alpha.10
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/es/APIClient.d.ts +1 -3
- package/es/BaseApplication.d.ts +3 -0
- package/es/PluginSettingsManager.d.ts +33 -0
- package/es/RouteRepository.d.ts +29 -6
- package/es/RouterManager.d.ts +15 -0
- package/es/authRedirect.d.ts +1 -0
- package/es/collection-field-interface/CollectionFieldInterface.d.ts +1 -0
- package/es/collection-field-interface/CollectionFieldInterfaceManager.d.ts +1 -0
- package/es/components/category-tabs/SortableCategoryTabs.d.ts +55 -0
- package/es/components/category-tabs/index.d.ts +9 -0
- package/es/components/form/JsonTextArea.d.ts +2 -1
- package/es/components/form/ScanInput/useCodeScanner.d.ts +3 -2
- package/es/components/form/TypedVariableInput.d.ts +31 -5
- package/es/components/form/VariableJsonTextArea.d.ts +19 -0
- package/es/components/form/filter/CollectionFilter.d.ts +2 -0
- package/es/components/form/filter/CollectionFilterItem.d.ts +11 -1
- package/es/components/form/filter/CollectionFilterPanel.d.ts +2 -0
- package/es/components/form/filter/index.d.ts +2 -0
- package/es/components/form/filter/useFilterActionProps.d.ts +2 -0
- package/es/components/form/index.d.ts +1 -0
- package/es/components/index.d.ts +2 -0
- package/es/entry-actions/EntryActionManager.d.ts +24 -0
- package/es/entry-actions/index.d.ts +9 -0
- package/es/flow/actions/afterSuccess.d.ts +8 -1
- package/es/flow/actions/index.d.ts +2 -2
- package/es/flow/actions/linkageRules.d.ts +2 -0
- package/es/flow/admin-shell/BaseLayoutModel.d.ts +6 -0
- package/es/flow/admin-shell/BaseLayoutRouteCoordinator.d.ts +7 -0
- package/es/flow/admin-shell/admin-layout/AdminLayoutEntryGuard.d.ts +2 -0
- package/es/flow/admin-shell/admin-layout/AdminLayoutMenuFlowUtils.d.ts +2 -1
- package/es/flow/admin-shell/admin-layout/AdminLayoutMenuModels.d.ts +3 -0
- package/es/flow/admin-shell/admin-layout/AdminLayoutMenuUtils.d.ts +3 -2
- package/es/flow/admin-shell/admin-layout/AdminLayoutSlotModels.d.ts +5 -0
- package/es/flow/admin-shell/admin-layout/AppListRender.d.ts +2 -1
- package/es/flow/admin-shell/admin-layout/AppSwitcherActionPanelModel.d.ts +24 -0
- package/es/flow/admin-shell/admin-layout/index.d.ts +1 -0
- package/es/flow/admin-shell/admin-layout/resolveAdminRouteRuntimeTarget.d.ts +6 -0
- package/es/flow/admin-shell/admin-layout/useApplications.d.ts +7 -2
- package/es/flow/components/FieldAssignExactDatePicker.d.ts +1 -0
- package/es/flow/components/FieldAssignRulesEditor.d.ts +3 -1
- package/es/flow/components/FieldAssignValueInput.d.ts +9 -0
- package/es/flow/components/FlowRoute.d.ts +2 -2
- package/es/flow/components/RunJSValueEditor.d.ts +1 -0
- package/es/flow/components/filter/FilterGroup.d.ts +1 -0
- package/es/flow/components/filter/VariableFilterItem.d.ts +6 -1
- package/es/flow/index.d.ts +1 -0
- package/es/flow/internal/registerDeviceTypeContext.d.ts +10 -0
- package/es/flow/models/base/ActionModelCore.d.ts +2 -0
- package/es/flow/models/base/BlockGridModel.d.ts +3 -0
- package/es/flow/models/base/GridModel.d.ts +1 -1
- package/es/flow/models/base/PageModel/PageModel.d.ts +12 -0
- package/es/flow/models/base/PageModel/PageModelTabBar.d.ts +22 -0
- package/es/flow/models/base/PageModel/PageTabModel.d.ts +12 -0
- package/es/flow/models/blocks/filter-form/FilterFormBlockModel.d.ts +5 -0
- package/es/flow/models/blocks/form/FormBlockModel.d.ts +4 -0
- package/es/flow/models/blocks/form/QuickEditFormModel.d.ts +17 -2
- package/es/flow/models/blocks/form/submitHandler.d.ts +1 -1
- package/es/flow/models/blocks/form/value-runtime/rules.d.ts +21 -0
- package/es/flow/models/blocks/form/value-runtime/runtime.d.ts +30 -0
- package/es/flow/models/blocks/form/value-runtime/types.d.ts +2 -2
- package/es/flow/models/blocks/js-block/JSBlock.d.ts +1 -0
- package/es/flow/models/blocks/table/TableActionsColumnModel.d.ts +1 -0
- package/es/flow/models/blocks/table/TableBlockModel.d.ts +1 -0
- package/es/flow/models/blocks/table/TableColumnModel.d.ts +1 -0
- package/es/flow/models/blocks/table/dragSort/dragSortHooks.d.ts +1 -1
- package/es/flow/models/blocks/table/dragSort/dragSortSettings.d.ts +2 -1
- package/es/flow/models/blocks/table/dragSort/dragSortUtils.d.ts +6 -4
- package/es/flow/models/fields/AssociationFieldModel/RecordSelectFieldModel.d.ts +2 -0
- package/es/flow/models/fields/AssociationFieldModel/SubTableFieldModel/SubTableColumnModel.d.ts +6 -0
- package/es/flow/models/fields/DateTimeFieldModel/dateLimit.d.ts +15 -7
- package/es/flow/resolveViewParamsToViewList.d.ts +1 -1
- package/es/flow/routeTransientInputArgs.d.ts +14 -0
- package/es/flow/utils/dataScopeRowSnapshot.d.ts +59 -0
- package/es/flow/utils/dateTimeDisplayProps.d.ts +49 -0
- package/es/flow/utils/formValueDeps.d.ts +32 -0
- package/es/flow-compat/FieldValidation.d.ts +2 -1
- package/es/flow-compat/fieldValidationConstants.d.ts +1 -1
- package/es/flow-compat/routeTypes.d.ts +1 -0
- package/es/index.d.ts +8 -1
- package/es/index.mjs +367 -181
- package/es/utils/getRouteRuntimeVersion.d.ts +23 -0
- package/es/utils/index.d.ts +1 -0
- package/es/utils/markdownSanitize.d.ts +11 -0
- package/lib/index.js +367 -181
- package/lib/locale/languageCodes.js +3 -1
- package/package.json +9 -7
- package/src/APIClient.ts +1 -10
- package/src/Application.tsx +4 -0
- package/src/BaseApplication.tsx +13 -6
- package/src/PluginSettingsManager.ts +53 -0
- package/src/RouteRepository.ts +151 -24
- package/src/RouterManager.tsx +142 -1
- package/src/__tests__/PluginSettingsManager.test.ts +13 -0
- package/src/__tests__/RouteRepository.test.ts +239 -0
- package/src/__tests__/RouterManager.test.ts +125 -0
- package/src/__tests__/app.test.tsx +73 -0
- package/src/__tests__/authRedirect.test.ts +17 -0
- package/src/__tests__/browserChecker.test.ts +61 -0
- package/src/__tests__/exports.test.ts +16 -0
- package/src/__tests__/getRouteRuntimeVersion.test.ts +68 -0
- package/src/__tests__/nocobase-buildin-plugin-auth.test.tsx +234 -2
- package/src/__tests__/plugin-manager.test.tsx +44 -2
- package/src/__tests__/settings-center.test.tsx +40 -1
- package/src/authRedirect.ts +38 -0
- package/src/collection-field-interface/CollectionFieldInterface.ts +1 -0
- package/src/collection-field-interface/CollectionFieldInterfaceManager.ts +1 -0
- package/src/collection-manager/field-configure.ts +1 -1
- package/src/collection-manager/field-validation.ts +1 -1
- package/src/collection-manager/interfaces/id.ts +1 -1
- package/src/collection-manager/interfaces/m2m.tsx +2 -2
- package/src/collection-manager/interfaces/m2o.tsx +2 -2
- package/src/collection-manager/interfaces/nanoid.ts +1 -1
- package/src/collection-manager/interfaces/o2m.tsx +2 -2
- package/src/collection-manager/interfaces/obo.tsx +2 -2
- package/src/collection-manager/interfaces/oho.tsx +2 -2
- package/src/collection-manager/interfaces/properties/index.ts +2 -2
- package/src/collection-manager/interfaces/uuid.ts +1 -1
- package/src/components/AppComponents.tsx +19 -3
- package/src/components/README.md +7 -1
- package/src/components/README.zh-CN.md +6 -1
- package/src/components/category-tabs/SortableCategoryTabs.tsx +210 -0
- package/src/components/category-tabs/index.ts +10 -0
- package/src/components/form/JsonTextArea.tsx +25 -11
- package/src/components/form/ScanInput/CodeScanner.tsx +79 -35
- package/src/components/form/ScanInput/__tests__/CodeScanner.test.tsx +101 -0
- package/src/components/form/ScanInput/__tests__/useCodeScanner.test.tsx +284 -11
- package/src/components/form/ScanInput/useCodeScanner.ts +332 -24
- package/src/components/form/TypedVariableInput.tsx +452 -101
- package/src/components/form/VariableJsonTextArea.tsx +175 -0
- package/src/components/form/__tests__/JsonTextArea.test.tsx +43 -0
- package/src/components/form/__tests__/TypedVariableInput.test.tsx +364 -12
- package/src/components/form/__tests__/VariableJsonTextArea.test.tsx +86 -0
- package/src/components/form/filter/CollectionFilter.tsx +4 -0
- package/src/components/form/filter/CollectionFilterItem.tsx +32 -7
- package/src/components/form/filter/CollectionFilterPanel.tsx +4 -0
- package/src/components/form/filter/__tests__/CollectionFilterItem.test.tsx +38 -0
- package/src/components/form/filter/__tests__/useFilterActionProps.test.tsx +95 -0
- package/src/components/form/filter/index.ts +2 -0
- package/src/components/form/filter/useFilterActionProps.ts +37 -6
- package/src/components/form/index.tsx +1 -0
- package/src/components/index.ts +2 -0
- package/src/entry-actions/EntryActionManager.ts +76 -0
- package/src/entry-actions/index.ts +10 -0
- package/src/flow/FlowPage.tsx +38 -3
- package/src/flow/__tests__/FlowPage.test.tsx +201 -27
- package/src/flow/__tests__/FlowRoute.test.tsx +1181 -80
- package/src/flow/__tests__/PluginFlowEngine.test.ts +58 -0
- package/src/flow/__tests__/getKey.test.ts +7 -0
- package/src/flow/__tests__/resolveViewParamsToViewList.test.ts +34 -0
- package/src/flow/actions/__tests__/actionLinkageRules.forkProps.test.ts +115 -0
- package/src/flow/actions/__tests__/afterSuccess.test.ts +73 -0
- package/src/flow/actions/__tests__/dataScopeFilter.test.ts +120 -0
- package/src/flow/actions/__tests__/dataScopeFormValueClear.test.ts +1124 -0
- package/src/flow/actions/__tests__/fieldLinkageRules.scopeDepth.test.ts +150 -1
- package/src/flow/actions/__tests__/linkageAssignField.legacy.test.ts +135 -0
- package/src/flow/actions/__tests__/linkageRules.hiddenSync.restore.test.ts +19 -5
- package/src/flow/actions/__tests__/linkageRules.subFormSetFieldProps.test.ts +92 -0
- package/src/flow/actions/__tests__/linkageRules.tab.test.ts +171 -0
- package/src/flow/actions/__tests__/linkageRulesRefresh.test.ts +7 -3
- package/src/flow/actions/__tests__/openView.defineProps.route.test.tsx +164 -0
- package/src/flow/actions/__tests__/subFormFieldLinkageRules.inputArgs.test.ts +2 -2
- package/src/flow/actions/afterSuccess.tsx +142 -3
- package/src/flow/actions/customVariable.tsx +1 -2
- package/src/flow/actions/dataScopeFilter.ts +20 -1
- package/src/flow/actions/dateTimeFormat.tsx +42 -28
- package/src/flow/actions/index.ts +3 -1
- package/src/flow/actions/linkageRules.tsx +209 -47
- package/src/flow/actions/linkageRulesFormValueRefresh.ts +22 -130
- package/src/flow/actions/linkageRulesRefresh.tsx +2 -6
- package/src/flow/actions/openView.tsx +59 -5
- package/src/flow/actions/runjs.tsx +2 -14
- package/src/flow/actions/validation.tsx +62 -30
- package/src/flow/admin-shell/BaseLayoutModel.tsx +149 -3
- package/src/flow/admin-shell/BaseLayoutRouteCoordinator.ts +187 -42
- package/src/flow/admin-shell/__tests__/AdminLayoutRouteCoordinator.test.ts +1020 -110
- package/src/flow/admin-shell/admin-layout/AdminLayoutComponent.tsx +74 -14
- package/src/flow/admin-shell/admin-layout/AdminLayoutEntryGuard.test.tsx +486 -0
- package/src/flow/admin-shell/admin-layout/AdminLayoutEntryGuard.tsx +64 -8
- package/src/flow/admin-shell/admin-layout/AdminLayoutMenuFlowUtils.ts +5 -3
- package/src/flow/admin-shell/admin-layout/AdminLayoutMenuModels.tsx +61 -9
- package/src/flow/admin-shell/admin-layout/AdminLayoutMenuUtils.tsx +71 -8
- package/src/flow/admin-shell/admin-layout/AdminLayoutModel.tsx +1 -1
- package/src/flow/admin-shell/admin-layout/AdminLayoutSlotModels.tsx +23 -9
- package/src/flow/admin-shell/admin-layout/AppListRender.tsx +13 -2
- package/src/flow/admin-shell/admin-layout/AppSwitcherActionPanelModel.tsx +289 -0
- package/src/flow/admin-shell/admin-layout/HelpLite.tsx +1 -3
- package/src/flow/admin-shell/admin-layout/__tests__/AdminLayoutComponent.test.tsx +435 -0
- package/src/flow/admin-shell/admin-layout/__tests__/AdminLayoutMenuModels.test.ts +99 -0
- package/src/flow/admin-shell/admin-layout/__tests__/AdminLayoutModel.test.tsx +518 -2
- package/src/flow/admin-shell/admin-layout/__tests__/TopbarActionsBar.test.tsx +214 -2
- package/src/flow/admin-shell/admin-layout/index.ts +1 -0
- package/src/flow/admin-shell/admin-layout/resolveAdminRouteRuntimeTarget.test.ts +20 -0
- package/src/flow/admin-shell/admin-layout/resolveAdminRouteRuntimeTarget.ts +33 -5
- package/src/flow/admin-shell/admin-layout/useApplications.tsx +81 -12
- package/src/flow/common/Markdown/Display.tsx +14 -3
- package/src/flow/common/Markdown/Edit.tsx +19 -7
- package/src/flow/common/Markdown/style.ts +4 -0
- package/src/flow/components/BlockItemCard.tsx +2 -2
- package/src/flow/components/DefaultValue.tsx +1 -2
- package/src/flow/components/DynamicFlowsIcon.tsx +447 -126
- package/src/flow/components/FieldAssignExactDatePicker.tsx +25 -11
- package/src/flow/components/FieldAssignRulesEditor.tsx +128 -21
- package/src/flow/components/FieldAssignValueInput.tsx +91 -20
- package/src/flow/components/FlowRoute.tsx +256 -53
- package/src/flow/components/RunJSValueEditor.tsx +9 -1
- package/src/flow/components/__tests__/DynamicFlowsIcon.test.tsx +148 -2
- package/src/flow/components/__tests__/FieldAssignRulesEditor.test.tsx +508 -4
- package/src/flow/components/__tests__/FieldAssignValueInput.context.test.tsx +216 -0
- package/src/flow/components/__tests__/fieldAssignOptions.test.ts +151 -3
- package/src/flow/components/code-editor/__tests__/useCodeRunner.test.tsx +2 -17
- package/src/flow/components/code-editor/hooks/useCodeRunner.ts +2 -14
- package/src/flow/components/code-editor/runjsDiagnostics.ts +8 -45
- package/src/flow/components/fieldAssignOptions.ts +155 -27
- package/src/flow/components/filter/FilterGroup.tsx +33 -5
- package/src/flow/components/filter/VariableFilterItem.tsx +158 -10
- package/src/flow/components/filter/__tests__/FilterGroup.test.tsx +45 -0
- package/src/flow/components/filter/__tests__/VariableFilterItem.leftMetaTree.test.tsx +9 -0
- package/src/flow/components/filter/__tests__/VariableFilterItem.test.tsx +70 -1
- package/src/flow/flows/editMarkdownFlow.tsx +1 -1
- package/src/flow/getViewDiffAndUpdateHidden.tsx +1 -0
- package/src/flow/index.ts +4 -1
- package/src/flow/internal/components/Markdown/util.ts +2 -1
- package/src/flow/internal/registerDeviceTypeContext.ts +39 -0
- package/src/flow/internal/utils/operatorSchemaHelper.ts +15 -1
- package/src/flow/models/actions/JSActionModel.tsx +2 -7
- package/src/flow/models/actions/JSCollectionActionModel.tsx +2 -7
- package/src/flow/models/actions/JSItemActionModel.tsx +2 -7
- package/src/flow/models/actions/JSRecordActionModel.tsx +2 -7
- package/src/flow/models/base/ActionModel.tsx +21 -8
- package/src/flow/models/base/ActionModelCore.tsx +11 -4
- package/src/flow/models/base/BlockGridModel.tsx +26 -0
- package/src/flow/models/base/CollectionBlockModel.tsx +6 -2
- package/src/flow/models/base/GridModel.tsx +38 -7
- package/src/flow/models/base/PageModel/PageModel.tsx +387 -50
- package/src/flow/models/base/PageModel/PageModelTabBar.tsx +114 -0
- package/src/flow/models/base/PageModel/PageTabModel.tsx +249 -18
- package/src/flow/models/base/PageModel/__tests__/PageModel.test.ts +817 -13
- package/src/flow/models/base/PageModel/__tests__/PageModelTabBar.module-isolation.test.tsx +130 -0
- package/src/flow/models/base/PageModel/__tests__/PageModelTabBar.test.tsx +118 -0
- package/src/flow/models/base/PageModel/__tests__/PageTabModel.test.ts +1075 -7
- package/src/flow/models/base/__tests__/ActionModel.test.ts +83 -0
- package/src/flow/models/base/__tests__/ActionModelCore.render.test.tsx +37 -0
- package/src/flow/models/base/__tests__/BlockGridModel.selectSceneActivation.test.ts +124 -0
- package/src/flow/models/base/__tests__/CollectionBlockModel.addAppends.test.ts +41 -0
- package/src/flow/models/base/__tests__/GridModel.dragSnapshotContainer.test.ts +239 -1
- package/src/flow/models/base/__tests__/transformRowsToSingleColumn.test.ts +48 -0
- package/src/flow/models/blocks/filter-form/FilterFormBlockModel.tsx +59 -6
- package/src/flow/models/blocks/filter-form/FilterFormItemModel.tsx +27 -12
- package/src/flow/models/blocks/filter-form/FilterFormJSActionModel.tsx +2 -7
- package/src/flow/models/blocks/filter-form/__tests__/FilterFormItemModel.defineChildren.test.ts +36 -0
- package/src/flow/models/blocks/filter-form/__tests__/defaultValues.wiring.test.ts +143 -4
- package/src/flow/models/blocks/filter-form/fields/FilterFormCustomFieldModel.tsx +1 -1
- package/src/flow/models/blocks/filter-manager/flow-actions/__tests__/customizeFilterRender.test.tsx +56 -1
- package/src/flow/models/blocks/form/EditFormModel.tsx +1 -0
- package/src/flow/models/blocks/form/FormActionModel.tsx +1 -1
- package/src/flow/models/blocks/form/FormBlockModel.tsx +7 -0
- package/src/flow/models/blocks/form/JSFormActionModel.tsx +2 -7
- package/src/flow/models/blocks/form/QuickEditFormModel.tsx +189 -36
- package/src/flow/models/blocks/form/__tests__/FormBlockModel.test.tsx +17 -0
- package/src/flow/models/blocks/form/__tests__/QuickEditFormModel.quickEdit.test.ts +350 -2
- package/src/flow/models/blocks/form/__tests__/submitHandler.test.ts +54 -1
- package/src/flow/models/blocks/form/submitHandler.ts +17 -3
- package/src/flow/models/blocks/form/value-runtime/__tests__/runtime.test.ts +940 -75
- package/src/flow/models/blocks/form/value-runtime/rules.ts +445 -13
- package/src/flow/models/blocks/form/value-runtime/runtime.ts +348 -13
- package/src/flow/models/blocks/form/value-runtime/types.ts +2 -2
- package/src/flow/models/blocks/js-block/JSBlock.tsx +225 -9
- package/src/flow/models/blocks/js-block/__tests__/JSBlockModel.test.tsx +150 -0
- package/src/flow/models/blocks/table/JSColumnModel.tsx +1 -9
- package/src/flow/models/blocks/table/TableActionsColumnModel.tsx +38 -14
- package/src/flow/models/blocks/table/TableBlockModel.tsx +42 -19
- package/src/flow/models/blocks/table/TableColumnModel.tsx +72 -6
- package/src/flow/models/blocks/table/__tests__/TableActionsColumnModel.test.tsx +111 -1
- package/src/flow/models/blocks/table/__tests__/TableBlockModel.dragSort.test.ts +127 -0
- package/src/flow/models/blocks/table/__tests__/TableBlockModel.mobileSettingsButtons.test.tsx +78 -0
- package/src/flow/models/blocks/table/__tests__/TableBlockModel.quickEditRefresh.test.ts +12 -0
- package/src/flow/models/blocks/table/__tests__/TableBlockModel.rowSelection.test.tsx +1 -0
- package/src/flow/models/blocks/table/__tests__/TableColumnModel.test.tsx +243 -1
- package/src/flow/models/blocks/table/dragSort/dragSortHooks.tsx +28 -17
- package/src/flow/models/blocks/table/dragSort/dragSortSettings.ts +13 -6
- package/src/flow/models/blocks/table/dragSort/dragSortUtils.ts +15 -2
- package/src/flow/models/fields/AssociationFieldModel/AssociationFieldModel.tsx +1 -1
- package/src/flow/models/fields/AssociationFieldModel/PopupSubTableFieldModel/PopupSubTableFieldModel.tsx +31 -7
- package/src/flow/models/fields/AssociationFieldModel/RecordSelectFieldModel.tsx +61 -17
- package/src/flow/models/fields/AssociationFieldModel/SubTableFieldModel/SubTableColumnModel.tsx +141 -19
- package/src/flow/models/fields/AssociationFieldModel/SubTableFieldModel/SubTableField.tsx +13 -1
- package/src/flow/models/fields/AssociationFieldModel/SubTableFieldModel/__tests__/SubTableColumnModel.rowRecord.test.ts +197 -0
- package/src/flow/models/fields/AssociationFieldModel/SubTableFieldModel/__tests__/SubTableFieldModel.reset.test.ts +180 -0
- package/src/flow/models/fields/AssociationFieldModel/SubTableFieldModel/index.tsx +6 -4
- package/src/flow/models/fields/AssociationFieldModel/__tests__/AssociationFieldModel.updateAssociation.test.ts +72 -0
- package/src/flow/models/fields/AssociationFieldModel/__tests__/RecordPickerFieldModel.itemContext.test.ts +23 -0
- package/src/flow/models/fields/ClickableFieldModel.tsx +5 -0
- package/src/flow/models/fields/DateTimeFieldModel/__tests__/DateTimeNoTzFieldModel.dateLimit.test.tsx +149 -0
- package/src/flow/models/fields/DateTimeFieldModel/dateLimit.ts +149 -113
- package/src/flow/models/fields/DisplayDateTimeFieldModel.tsx +29 -1
- package/src/flow/models/fields/InputFieldModel.tsx +40 -2
- package/src/flow/models/fields/JSEditableFieldModel.tsx +2 -11
- package/src/flow/models/fields/JSFieldModel.tsx +2 -7
- package/src/flow/models/fields/JSItemModel.tsx +2 -14
- package/src/flow/models/fields/SelectFieldModel.tsx +6 -4
- package/src/flow/models/fields/TextareaFieldModel.tsx +72 -3
- package/src/flow/models/fields/VariableFieldFormModel.tsx +3 -3
- package/src/flow/models/fields/__tests__/DisplayDateTimeFieldModel.test.tsx +96 -0
- package/src/flow/models/fields/__tests__/InputFieldModel.test.tsx +117 -1
- package/src/flow/models/fields/__tests__/SelectFieldModel.test.tsx +43 -0
- package/src/flow/models/fields/__tests__/TextareaFieldModel.test.tsx +131 -0
- package/src/flow/models/fields/__tests__/VariableFieldFormModel.test.tsx +51 -0
- package/src/flow/models/fields/mobile-components/MobileLazySelect.tsx +20 -10
- package/src/flow/models/fields/mobile-components/MobileSelect.tsx +24 -12
- package/src/flow/models/topbar/TopbarActionModel.tsx +168 -10
- package/src/flow/resolveViewParamsToViewList.tsx +11 -3
- package/src/flow/routeTransientInputArgs.ts +27 -0
- package/src/flow/utils/__tests__/dateTimeFormat.test.ts +300 -0
- package/src/flow/utils/dataScopeFormValueClear.ts +219 -81
- package/src/flow/utils/dataScopeRowSnapshot.ts +616 -0
- package/src/flow/utils/dateTimeDisplayProps.ts +135 -0
- package/src/flow/utils/formValueDeps.ts +170 -0
- package/src/flow-compat/FieldValidation.tsx +122 -60
- package/src/flow-compat/Popover.tsx +43 -4
- package/src/flow-compat/__tests__/Popover.test.tsx +34 -0
- package/src/flow-compat/fieldValidationConstants.ts +1 -1
- package/src/flow-compat/routeTypes.ts +1 -0
- package/src/index.ts +14 -1
- package/src/layout-manager/__tests__/LayoutRoute.test.tsx +41 -1
- package/src/locale/languageCodes.ts +3 -1
- package/src/nocobase-buildin-plugin/index.tsx +63 -15
- package/src/settings-center/AdminSettingsLayout.tsx +10 -2
- package/src/settings-center/SystemSettingsPage.tsx +1 -2
- package/src/settings-center/plugin-manager/PluginCard.tsx +2 -2
- package/src/settings-center/plugin-manager/index.tsx +3 -0
- package/src/settings-center/utils.tsx +0 -6
- package/src/utils/getRouteRuntimeVersion.ts +185 -0
- package/src/utils/index.tsx +1 -0
- package/src/utils/markdownSanitize.ts +88 -0
|
@@ -66,6 +66,39 @@ describe('TableColumnModel sorter settings', () => {
|
|
|
66
66
|
expect(setProps).toHaveBeenCalledWith('editable', false);
|
|
67
67
|
});
|
|
68
68
|
|
|
69
|
+
it('checks record update scope and field permission before enabling quick edit', () => {
|
|
70
|
+
const can = vi.fn(() => false);
|
|
71
|
+
const model = {
|
|
72
|
+
props: { editable: true },
|
|
73
|
+
collectionField: { name: 'title' },
|
|
74
|
+
context: {
|
|
75
|
+
skipAclCheck: false,
|
|
76
|
+
acl: { can },
|
|
77
|
+
blockModel: {
|
|
78
|
+
collection: {
|
|
79
|
+
dataSourceKey: 'main',
|
|
80
|
+
name: 'posts',
|
|
81
|
+
getFilterByTK: () => 2,
|
|
82
|
+
},
|
|
83
|
+
resource: {
|
|
84
|
+
getResourceName: () => 'posts',
|
|
85
|
+
getMeta: () => ({ update: [1] }),
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
expect(TableColumnModel.prototype.canQuickEdit.call(model, { id: 2 })).toBe(false);
|
|
92
|
+
expect(can).toHaveBeenCalledWith({
|
|
93
|
+
dataSourceKey: 'main',
|
|
94
|
+
resourceName: 'posts',
|
|
95
|
+
actionName: 'update',
|
|
96
|
+
recordPkValue: 2,
|
|
97
|
+
allowedActions: { update: [1] },
|
|
98
|
+
fields: ['title'],
|
|
99
|
+
});
|
|
100
|
+
});
|
|
101
|
+
|
|
69
102
|
it('hides sortable setting for association fields', async () => {
|
|
70
103
|
const engine = new FlowEngine();
|
|
71
104
|
const model = new TableColumnModel({ uid: 'table-column-association-sorter', flowEngine: engine } as any);
|
|
@@ -130,9 +163,14 @@ describe('TableColumnModel sorter settings', () => {
|
|
|
130
163
|
const titleFieldStep = model.getFlow('tableColumnSettings')?.steps?.fieldNames as any;
|
|
131
164
|
const setStepParams = vi.fn();
|
|
132
165
|
const setProps = vi.fn();
|
|
166
|
+
const setFieldProps = vi.fn();
|
|
133
167
|
const dispatchEvent = vi.fn();
|
|
168
|
+
const saveFieldModel = vi.fn();
|
|
134
169
|
const targetCollectionField = {
|
|
135
|
-
getComponentProps: () => ({
|
|
170
|
+
getComponentProps: () => ({
|
|
171
|
+
format: 'hh:mm:ss a',
|
|
172
|
+
timeFormat: 'hh:mm:ss a',
|
|
173
|
+
}),
|
|
136
174
|
};
|
|
137
175
|
|
|
138
176
|
await titleFieldStep.beforeParamsSave(
|
|
@@ -156,8 +194,10 @@ describe('TableColumnModel sorter settings', () => {
|
|
|
156
194
|
subModels: {
|
|
157
195
|
field: {
|
|
158
196
|
use: 'DisplayTextFieldModel',
|
|
197
|
+
setProps: setFieldProps,
|
|
159
198
|
setStepParams,
|
|
160
199
|
dispatchEvent,
|
|
200
|
+
save: saveFieldModel,
|
|
161
201
|
},
|
|
162
202
|
},
|
|
163
203
|
setStepParams,
|
|
@@ -169,6 +209,206 @@ describe('TableColumnModel sorter settings', () => {
|
|
|
169
209
|
);
|
|
170
210
|
|
|
171
211
|
expect(setStepParams).toHaveBeenCalledWith('tableColumnSettings', 'model', { use: 'DisplayTextFieldModel' });
|
|
212
|
+
expect(setFieldProps).toHaveBeenCalledWith(
|
|
213
|
+
expect.objectContaining({
|
|
214
|
+
format: 'hh:mm:ss a',
|
|
215
|
+
timeFormat: 'hh:mm:ss a',
|
|
216
|
+
titleField: 'code',
|
|
217
|
+
}),
|
|
218
|
+
);
|
|
219
|
+
expect(setProps).toHaveBeenCalledWith(
|
|
220
|
+
expect.objectContaining({
|
|
221
|
+
format: 'hh:mm:ss a',
|
|
222
|
+
timeFormat: 'hh:mm:ss a',
|
|
223
|
+
titleField: 'code',
|
|
224
|
+
}),
|
|
225
|
+
);
|
|
226
|
+
expect(saveFieldModel).toHaveBeenCalled();
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
it('clears stale datetime display props when association title field changes to date only', async () => {
|
|
230
|
+
const engine = new FlowEngine();
|
|
231
|
+
const model = new TableColumnModel({ uid: 'table-column-title-field-date-only', flowEngine: engine } as any);
|
|
232
|
+
const titleFieldStep = model.getFlow('tableColumnSettings')?.steps?.fieldNames as any;
|
|
233
|
+
const setStepParams = vi.fn();
|
|
234
|
+
const setProps = vi.fn();
|
|
235
|
+
const setFieldProps = vi.fn();
|
|
236
|
+
const targetCollectionField = {
|
|
237
|
+
getComponentProps: () => ({
|
|
238
|
+
dateOnly: true,
|
|
239
|
+
showTime: false,
|
|
240
|
+
}),
|
|
241
|
+
};
|
|
242
|
+
|
|
243
|
+
await titleFieldStep.beforeParamsSave(
|
|
244
|
+
{
|
|
245
|
+
collectionField: {
|
|
246
|
+
isAssociationField: () => true,
|
|
247
|
+
targetCollection: {
|
|
248
|
+
name: 'departments',
|
|
249
|
+
getField: () => targetCollectionField,
|
|
250
|
+
},
|
|
251
|
+
},
|
|
252
|
+
model: {
|
|
253
|
+
collectionField: {
|
|
254
|
+
dataSourceKey: 'main',
|
|
255
|
+
},
|
|
256
|
+
constructor: {
|
|
257
|
+
getDefaultBindingByField: () => ({
|
|
258
|
+
modelName: 'DisplayDateTimeFieldModel',
|
|
259
|
+
}),
|
|
260
|
+
},
|
|
261
|
+
subModels: {
|
|
262
|
+
field: {
|
|
263
|
+
use: 'DisplayDateTimeFieldModel',
|
|
264
|
+
setProps: setFieldProps,
|
|
265
|
+
setStepParams,
|
|
266
|
+
dispatchEvent: vi.fn(),
|
|
267
|
+
save: vi.fn(),
|
|
268
|
+
},
|
|
269
|
+
},
|
|
270
|
+
setStepParams,
|
|
271
|
+
setProps,
|
|
272
|
+
},
|
|
273
|
+
},
|
|
274
|
+
{ label: 'dateOnly' },
|
|
275
|
+
{ label: 'time' },
|
|
276
|
+
);
|
|
277
|
+
|
|
278
|
+
expect(setFieldProps).toHaveBeenCalledWith(
|
|
279
|
+
expect.objectContaining({
|
|
280
|
+
dateOnly: true,
|
|
281
|
+
format: undefined,
|
|
282
|
+
showTime: false,
|
|
283
|
+
timeFormat: undefined,
|
|
284
|
+
titleField: 'dateOnly',
|
|
285
|
+
}),
|
|
286
|
+
);
|
|
287
|
+
expect(setProps).toHaveBeenCalledWith(
|
|
288
|
+
expect.objectContaining({
|
|
289
|
+
dateOnly: true,
|
|
290
|
+
format: undefined,
|
|
291
|
+
showTime: false,
|
|
292
|
+
timeFormat: undefined,
|
|
293
|
+
titleField: 'dateOnly',
|
|
294
|
+
}),
|
|
295
|
+
);
|
|
296
|
+
});
|
|
297
|
+
|
|
298
|
+
it('keeps saved association title datetime format when table column initializes again', async () => {
|
|
299
|
+
const engine = new FlowEngine();
|
|
300
|
+
const model = new TableColumnModel({
|
|
301
|
+
uid: 'table-column-title-field-saved-datetime-format',
|
|
302
|
+
flowEngine: engine,
|
|
303
|
+
} as any);
|
|
304
|
+
const initStep = model.getFlow('tableColumnSettings')?.steps?.init as any;
|
|
305
|
+
const setProps = vi.fn();
|
|
306
|
+
const targetCollectionField = {
|
|
307
|
+
getComponentProps: () => ({
|
|
308
|
+
dateFormat: 'YYYY-MM-DD',
|
|
309
|
+
format: 'YYYY-MM-DD HH:mm:ss',
|
|
310
|
+
showTime: true,
|
|
311
|
+
timeFormat: 'HH:mm:ss',
|
|
312
|
+
}),
|
|
313
|
+
};
|
|
314
|
+
|
|
315
|
+
await initStep.handler({
|
|
316
|
+
model: {
|
|
317
|
+
context: {
|
|
318
|
+
collectionField: {
|
|
319
|
+
title: 'Shipments',
|
|
320
|
+
name: 'shipments',
|
|
321
|
+
isAssociationField: () => true,
|
|
322
|
+
getComponentProps: () => ({
|
|
323
|
+
fieldNames: {
|
|
324
|
+
label: 'shipmentsDatetime',
|
|
325
|
+
},
|
|
326
|
+
}),
|
|
327
|
+
targetCollection: {
|
|
328
|
+
getField: () => targetCollectionField,
|
|
329
|
+
},
|
|
330
|
+
},
|
|
331
|
+
},
|
|
332
|
+
props: {
|
|
333
|
+
titleField: 'shipmentsDatetime',
|
|
334
|
+
},
|
|
335
|
+
subModels: {
|
|
336
|
+
field: {
|
|
337
|
+
getStepParams: (flowKey, stepKey) =>
|
|
338
|
+
flowKey === 'datetimeSettings' && stepKey === 'dateFormat'
|
|
339
|
+
? {
|
|
340
|
+
picker: 'date',
|
|
341
|
+
dateFormat: 'YYYY-MM-DD',
|
|
342
|
+
showTime: true,
|
|
343
|
+
timeFormat: 'h:mm a',
|
|
344
|
+
}
|
|
345
|
+
: undefined,
|
|
346
|
+
},
|
|
347
|
+
},
|
|
348
|
+
applySubModelsBeforeRenderFlows: vi.fn(),
|
|
349
|
+
setProps,
|
|
350
|
+
},
|
|
351
|
+
});
|
|
352
|
+
|
|
353
|
+
expect(setProps).toHaveBeenCalledWith(
|
|
354
|
+
expect.objectContaining({
|
|
355
|
+
dateFormat: 'YYYY-MM-DD',
|
|
356
|
+
format: 'YYYY-MM-DD h:mm a',
|
|
357
|
+
showTime: true,
|
|
358
|
+
timeFormat: 'h:mm a',
|
|
359
|
+
}),
|
|
360
|
+
);
|
|
361
|
+
});
|
|
362
|
+
|
|
363
|
+
it('keeps saved ordinary datetime format when table column initializes again', async () => {
|
|
364
|
+
const engine = new FlowEngine();
|
|
365
|
+
const model = new TableColumnModel({
|
|
366
|
+
uid: 'table-column-saved-datetime-format',
|
|
367
|
+
flowEngine: engine,
|
|
368
|
+
} as any);
|
|
369
|
+
const initStep = model.getFlow('tableColumnSettings')?.steps?.init as any;
|
|
370
|
+
const setProps = vi.fn();
|
|
371
|
+
|
|
372
|
+
await initStep.handler({
|
|
373
|
+
model: {
|
|
374
|
+
context: {
|
|
375
|
+
collectionField: {
|
|
376
|
+
title: 'Datetime',
|
|
377
|
+
name: 'datetime',
|
|
378
|
+
isAssociationField: () => false,
|
|
379
|
+
getComponentProps: () => ({
|
|
380
|
+
dateFormat: 'YYYY-MM-DD',
|
|
381
|
+
showTime: false,
|
|
382
|
+
}),
|
|
383
|
+
},
|
|
384
|
+
},
|
|
385
|
+
props: {},
|
|
386
|
+
subModels: {
|
|
387
|
+
field: {
|
|
388
|
+
getStepParams: (flowKey, stepKey) =>
|
|
389
|
+
flowKey === 'datetimeSettings' && stepKey === 'dateFormat'
|
|
390
|
+
? {
|
|
391
|
+
picker: 'date',
|
|
392
|
+
dateFormat: 'YYYY-MM-DD',
|
|
393
|
+
showTime: true,
|
|
394
|
+
timeFormat: 'HH:mm:ss',
|
|
395
|
+
}
|
|
396
|
+
: undefined,
|
|
397
|
+
},
|
|
398
|
+
},
|
|
399
|
+
applySubModelsBeforeRenderFlows: vi.fn(),
|
|
400
|
+
setProps,
|
|
401
|
+
},
|
|
402
|
+
});
|
|
403
|
+
|
|
404
|
+
expect(setProps).toHaveBeenCalledWith(
|
|
405
|
+
expect.objectContaining({
|
|
406
|
+
dateFormat: 'YYYY-MM-DD',
|
|
407
|
+
format: 'YYYY-MM-DD HH:mm:ss',
|
|
408
|
+
showTime: true,
|
|
409
|
+
timeFormat: 'HH:mm:ss',
|
|
410
|
+
}),
|
|
411
|
+
);
|
|
172
412
|
});
|
|
173
413
|
|
|
174
414
|
it('does not update field component setting when title field refresh fails', async () => {
|
|
@@ -203,8 +443,10 @@ describe('TableColumnModel sorter settings', () => {
|
|
|
203
443
|
subModels: {
|
|
204
444
|
field: {
|
|
205
445
|
use: 'DisplayTextFieldModel',
|
|
446
|
+
setProps: vi.fn(),
|
|
206
447
|
setStepParams: vi.fn(),
|
|
207
448
|
dispatchEvent: vi.fn().mockRejectedValue(new Error('beforeRender failed')),
|
|
449
|
+
save: vi.fn(),
|
|
208
450
|
},
|
|
209
451
|
},
|
|
210
452
|
setStepParams,
|
|
@@ -19,16 +19,23 @@ export function useDragSortBodyWrapper(
|
|
|
19
19
|
model: TableBlockModel,
|
|
20
20
|
dataSourceRef: React.MutableRefObject<any>,
|
|
21
21
|
getRowKeyFunc: (record: any) => string | number,
|
|
22
|
+
dragSortFieldName?: string,
|
|
22
23
|
) {
|
|
24
|
+
const expandedRowKeys = model.props.expandedRowKeys;
|
|
25
|
+
const defaultExpandAllRows = model.props.defaultExpandAllRows;
|
|
26
|
+
const resource = model.resource;
|
|
27
|
+
const filterTargetKey = model.collection.filterTargetKey;
|
|
28
|
+
const message = (model as { ctx?: { message?: { error?: (content: string) => void } } }).ctx?.message;
|
|
29
|
+
|
|
23
30
|
return useMemo(() => {
|
|
24
|
-
if (!
|
|
31
|
+
if (!dragSortFieldName) {
|
|
25
32
|
return (props) => <tbody {...props} />;
|
|
26
33
|
}
|
|
27
34
|
|
|
28
35
|
const flattenTreeData = (data: any[]) => {
|
|
29
36
|
const result: any[] = [];
|
|
30
|
-
const expandedKeys = new Set((
|
|
31
|
-
const includeAll = !!
|
|
37
|
+
const expandedKeys = new Set((expandedRowKeys || []).map((key) => (key == null ? key : String(key))));
|
|
38
|
+
const includeAll = !!defaultExpandAllRows;
|
|
32
39
|
|
|
33
40
|
const walk = (nodes: any[]) => {
|
|
34
41
|
if (!nodes?.length) return;
|
|
@@ -73,22 +80,22 @@ export function useDragSortBodyWrapper(
|
|
|
73
80
|
}
|
|
74
81
|
|
|
75
82
|
if (from && to) {
|
|
76
|
-
|
|
83
|
+
resource
|
|
77
84
|
.runAction('move', {
|
|
78
85
|
method: 'post',
|
|
79
86
|
params: {
|
|
80
|
-
sourceId: getRowKey(from,
|
|
81
|
-
targetId: getRowKey(to,
|
|
82
|
-
sortField:
|
|
87
|
+
sourceId: getRowKey(from, filterTargetKey),
|
|
88
|
+
targetId: getRowKey(to, filterTargetKey),
|
|
89
|
+
sortField: dragSortFieldName,
|
|
83
90
|
},
|
|
84
91
|
})
|
|
85
92
|
.then(() => {
|
|
86
|
-
|
|
93
|
+
resource.refresh();
|
|
87
94
|
})
|
|
88
95
|
.catch((error) => {
|
|
89
96
|
console.error('Move failed:', error);
|
|
90
97
|
// Show a user-facing error message if the message system is available
|
|
91
|
-
|
|
98
|
+
message?.error?.(error?.message || 'Move failed');
|
|
92
99
|
});
|
|
93
100
|
}
|
|
94
101
|
};
|
|
@@ -104,13 +111,14 @@ export function useDragSortBodyWrapper(
|
|
|
104
111
|
);
|
|
105
112
|
};
|
|
106
113
|
}, [
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
model.collection.filterTargetKey,
|
|
114
|
+
dataSourceRef,
|
|
115
|
+
defaultExpandAllRows,
|
|
116
|
+
dragSortFieldName,
|
|
117
|
+
expandedRowKeys,
|
|
118
|
+
filterTargetKey,
|
|
113
119
|
getRowKeyFunc,
|
|
120
|
+
message,
|
|
121
|
+
resource,
|
|
114
122
|
]);
|
|
115
123
|
}
|
|
116
124
|
|
|
@@ -124,7 +132,10 @@ export function useDragSortRowComponent(dragSort: boolean) {
|
|
|
124
132
|
}
|
|
125
133
|
|
|
126
134
|
export function initDragSortParams(model: TableBlockModel) {
|
|
127
|
-
|
|
128
|
-
|
|
135
|
+
const dragSortFieldName = model.getDragSortFieldName();
|
|
136
|
+
if (dragSortFieldName) {
|
|
137
|
+
model.resource.setSort([dragSortFieldName]);
|
|
138
|
+
} else if (model.props.dragSort && model.props.dragSortBy) {
|
|
139
|
+
model.resource.setSort(Array.isArray(model.props.globalSort) ? model.props.globalSort : []);
|
|
129
140
|
}
|
|
130
141
|
}
|
|
@@ -9,7 +9,11 @@
|
|
|
9
9
|
|
|
10
10
|
import { tExpr } from '@nocobase/flow-engine';
|
|
11
11
|
import type { TableBlockModel } from '../TableBlockModel';
|
|
12
|
-
import { convertFieldsToOptions, getSortFields } from './dragSortUtils';
|
|
12
|
+
import { convertFieldsToOptions, getSortFields, hasSortField } from './dragSortUtils';
|
|
13
|
+
|
|
14
|
+
function getFallbackSort(model: TableBlockModel): string[] {
|
|
15
|
+
return Array.isArray(model.props.globalSort) ? model.props.globalSort : [];
|
|
16
|
+
}
|
|
13
17
|
|
|
14
18
|
export const dragSortSettings = {
|
|
15
19
|
title: tExpr('Enable drag and drop sorting'),
|
|
@@ -17,9 +21,12 @@ export const dragSortSettings = {
|
|
|
17
21
|
defaultParams: {
|
|
18
22
|
dragSort: false,
|
|
19
23
|
},
|
|
20
|
-
|
|
24
|
+
handler(ctx, params) {
|
|
21
25
|
const model = ctx.model as TableBlockModel;
|
|
22
26
|
model.setProps('dragSort', params.dragSort);
|
|
27
|
+
if (!params.dragSort) {
|
|
28
|
+
model.resource.setSort(getFallbackSort(model));
|
|
29
|
+
}
|
|
23
30
|
|
|
24
31
|
// Note: automatic configuration of the drag sort field has been removed;
|
|
25
32
|
// users now configure `dragSortBy` explicitly via `dragSortBySettings`.
|
|
@@ -45,6 +52,7 @@ export const dragSortBySettings = {
|
|
|
45
52
|
key: 'dragSortBy',
|
|
46
53
|
props: {
|
|
47
54
|
options,
|
|
55
|
+
allowClear: true,
|
|
48
56
|
placeholder: ctx.t('Select field'),
|
|
49
57
|
},
|
|
50
58
|
};
|
|
@@ -54,9 +62,8 @@ export const dragSortBySettings = {
|
|
|
54
62
|
},
|
|
55
63
|
handler(ctx, params) {
|
|
56
64
|
const model = ctx.model as TableBlockModel;
|
|
57
|
-
model.
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
}
|
|
65
|
+
const dragSortBy = hasSortField(model.collection, params.dragSortBy) ? params.dragSortBy : null;
|
|
66
|
+
model.setProps('dragSortBy', dragSortBy);
|
|
67
|
+
model.resource.setSort(dragSortBy ? [dragSortBy] : getFallbackSort(model));
|
|
61
68
|
},
|
|
62
69
|
};
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
import type { Collection } from '@nocobase/flow-engine';
|
|
10
|
+
import type { Collection, CollectionField } from '@nocobase/flow-engine';
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* 从 collection 中获取所有 sort 类型的字段
|
|
@@ -24,6 +24,19 @@ export function getSortFields(collection: Collection | undefined) {
|
|
|
24
24
|
});
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
+
export function getSortField(
|
|
28
|
+
collection: Collection | undefined,
|
|
29
|
+
fieldName?: string | null,
|
|
30
|
+
): CollectionField | undefined {
|
|
31
|
+
if (!collection || !fieldName) return undefined;
|
|
32
|
+
|
|
33
|
+
return getSortFields(collection).find((field) => field.name === fieldName);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export function hasSortField(collection: Collection | undefined, fieldName?: string | null): boolean {
|
|
37
|
+
return !!getSortField(collection, fieldName);
|
|
38
|
+
}
|
|
39
|
+
|
|
27
40
|
/**
|
|
28
41
|
* 获取 collection 中第一个可用的 sort 字段
|
|
29
42
|
* @param collection - 集合对象
|
|
@@ -39,7 +52,7 @@ export function getFirstSortField(collection: Collection | undefined) {
|
|
|
39
52
|
* @param fields - 字段数组
|
|
40
53
|
* @returns 选项数组
|
|
41
54
|
*/
|
|
42
|
-
export function convertFieldsToOptions(fields:
|
|
55
|
+
export function convertFieldsToOptions(fields: CollectionField[]) {
|
|
43
56
|
return fields.map((field) => ({
|
|
44
57
|
label: field?.uiSchema?.title || field?.name,
|
|
45
58
|
value: field?.name,
|
|
@@ -11,7 +11,7 @@ import { FormItemModel } from '../../blocks/form/FormItemModel';
|
|
|
11
11
|
import { FieldModel } from '../../base/FieldModel';
|
|
12
12
|
export class AssociationFieldModel extends FieldModel {
|
|
13
13
|
operator = '$eq';
|
|
14
|
-
updateAssociation =
|
|
14
|
+
updateAssociation = false;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
AssociationFieldModel.registerFlow({
|
|
@@ -102,7 +102,7 @@ const RenderCell = observer<any>((props) => {
|
|
|
102
102
|
transform: translateY(-50%);
|
|
103
103
|
}
|
|
104
104
|
&:hover {
|
|
105
|
-
|
|
105
|
+
box-shadow: inset 0 0 0 9999px rgba(24, 144, 255, 0.1);
|
|
106
106
|
}
|
|
107
107
|
&:hover .edit-icon {
|
|
108
108
|
display: inline-flex;
|
|
@@ -126,6 +126,7 @@ const RenderCell = observer<any>((props) => {
|
|
|
126
126
|
fieldPath: dataIndex,
|
|
127
127
|
record: record,
|
|
128
128
|
fieldProps: { ...columnModel.props, ...columnModel.subModels.field.props },
|
|
129
|
+
sourceFieldModelUid: columnModel.subModels.field.uid,
|
|
129
130
|
onOk: (values) => {
|
|
130
131
|
record[dataIndex] = values[dataIndex];
|
|
131
132
|
// 仅重渲染单元格
|
|
@@ -203,6 +204,8 @@ const DisplayTable = (props) => {
|
|
|
203
204
|
onSelectExitRecordClick,
|
|
204
205
|
resetPage,
|
|
205
206
|
allowCreate,
|
|
207
|
+
formValuesChangeEmitter,
|
|
208
|
+
onResetFieldValue,
|
|
206
209
|
} = props;
|
|
207
210
|
const [currentPage, setCurrentPage] = useState(1);
|
|
208
211
|
const [currentPageSize, setCurrentPageSize] = useState(pageSize);
|
|
@@ -223,6 +226,18 @@ const DisplayTable = (props) => {
|
|
|
223
226
|
resetPage && setCurrentPage(1);
|
|
224
227
|
}, [resetPage]);
|
|
225
228
|
|
|
229
|
+
useEffect(() => {
|
|
230
|
+
if (!formValuesChangeEmitter?.on || !formValuesChangeEmitter?.off || !onResetFieldValue) return;
|
|
231
|
+
const listener = () => {
|
|
232
|
+
onResetFieldValue();
|
|
233
|
+
setTableData([]);
|
|
234
|
+
};
|
|
235
|
+
formValuesChangeEmitter.on('onFieldReset', listener);
|
|
236
|
+
return () => {
|
|
237
|
+
formValuesChangeEmitter.off('onFieldReset', listener);
|
|
238
|
+
};
|
|
239
|
+
}, [formValuesChangeEmitter, onResetFieldValue]);
|
|
240
|
+
|
|
226
241
|
const pagination = useMemo(() => {
|
|
227
242
|
return {
|
|
228
243
|
current: currentPage, // 当前页码
|
|
@@ -237,7 +252,7 @@ const DisplayTable = (props) => {
|
|
|
237
252
|
return t('Total {{count}} items', { count: total });
|
|
238
253
|
},
|
|
239
254
|
} as any;
|
|
240
|
-
}, [currentPage, currentPageSize, tableData]);
|
|
255
|
+
}, [currentPage, currentPageSize, tableData, t]);
|
|
241
256
|
|
|
242
257
|
const columns = useMemo(() => {
|
|
243
258
|
const cols = adjustColumnOrder(
|
|
@@ -421,10 +436,6 @@ export class PopupSubTableFieldModel extends AssociationFieldModel {
|
|
|
421
436
|
currentPageSize,
|
|
422
437
|
});
|
|
423
438
|
};
|
|
424
|
-
// 监听表单reset
|
|
425
|
-
this.context.blockModel.emitter.on('onFieldReset', () => {
|
|
426
|
-
this.props?.onChange([]);
|
|
427
|
-
});
|
|
428
439
|
}
|
|
429
440
|
}
|
|
430
441
|
|
|
@@ -457,8 +468,21 @@ export class PopupSubTableFieldModel extends AssociationFieldModel {
|
|
|
457
468
|
}
|
|
458
469
|
|
|
459
470
|
public render() {
|
|
471
|
+
const fieldPathArray = this.context.fieldPathArray ?? this.parent?.context?.fieldPathArray;
|
|
472
|
+
const onResetFieldValue = () => {
|
|
473
|
+
const value = [];
|
|
474
|
+
this.setProps({ value });
|
|
475
|
+
this.context.blockModel?.setFieldValue?.(fieldPathArray, value);
|
|
476
|
+
};
|
|
460
477
|
return (
|
|
461
|
-
<DisplayTable
|
|
478
|
+
<DisplayTable
|
|
479
|
+
{...this.props}
|
|
480
|
+
collection={this.collection}
|
|
481
|
+
baseColumns={this.getBaseColumns(this)}
|
|
482
|
+
model={this}
|
|
483
|
+
formValuesChangeEmitter={this.context.blockModel?.emitter}
|
|
484
|
+
onResetFieldValue={onResetFieldValue}
|
|
485
|
+
/>
|
|
462
486
|
);
|
|
463
487
|
}
|
|
464
488
|
}
|
|
@@ -99,6 +99,18 @@ export function collectAssociationHydrationCandidates(options: {
|
|
|
99
99
|
return candidates;
|
|
100
100
|
}
|
|
101
101
|
|
|
102
|
+
export function getAssociationHydrationNamePath(model: any) {
|
|
103
|
+
return model?.context?.fieldPathArray ?? model?.context?.fieldPath ?? model?.props?.name;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export function getAssociationHydrationSetterContext(model: any) {
|
|
107
|
+
if (typeof model?.context?.setFormValue === 'function') {
|
|
108
|
+
return model.context;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return model?.context?.blockModel?.context;
|
|
112
|
+
}
|
|
113
|
+
|
|
102
114
|
function markAssociationHydrationDone(statusMap: Map<string, HydrateStatus>, tkKey: string | null | undefined) {
|
|
103
115
|
if (!tkKey) return;
|
|
104
116
|
statusMap.set(tkKey, 'done');
|
|
@@ -186,6 +198,48 @@ const useFieldPermissionMessage = (model, allowEdit) => {
|
|
|
186
198
|
return messageValue;
|
|
187
199
|
};
|
|
188
200
|
|
|
201
|
+
const recordSelectClassName = css`
|
|
202
|
+
min-width: 0;
|
|
203
|
+
|
|
204
|
+
.ant-select-selector {
|
|
205
|
+
min-width: 0;
|
|
206
|
+
overflow: hidden;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
.ant-select-selection-search,
|
|
210
|
+
.ant-select-selection-item,
|
|
211
|
+
.ant-select-selection-placeholder,
|
|
212
|
+
.ant-select-selection-overflow,
|
|
213
|
+
.ant-select-selection-overflow-item {
|
|
214
|
+
min-width: 0;
|
|
215
|
+
max-width: 100%;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
.ant-select-selection-item,
|
|
219
|
+
.ant-select-selection-item-content {
|
|
220
|
+
overflow: hidden;
|
|
221
|
+
text-overflow: ellipsis;
|
|
222
|
+
white-space: nowrap;
|
|
223
|
+
}
|
|
224
|
+
`;
|
|
225
|
+
|
|
226
|
+
const recordSelectLabelClassName = css`
|
|
227
|
+
display: block;
|
|
228
|
+
min-width: 0;
|
|
229
|
+
max-width: 100%;
|
|
230
|
+
overflow: hidden;
|
|
231
|
+
text-overflow: ellipsis;
|
|
232
|
+
white-space: nowrap;
|
|
233
|
+
|
|
234
|
+
* {
|
|
235
|
+
min-width: 0;
|
|
236
|
+
max-width: 100%;
|
|
237
|
+
overflow: hidden;
|
|
238
|
+
text-overflow: ellipsis;
|
|
239
|
+
white-space: nowrap !important;
|
|
240
|
+
}
|
|
241
|
+
`;
|
|
242
|
+
|
|
189
243
|
const LazySelect = (props: Readonly<LazySelectProps>) => {
|
|
190
244
|
const {
|
|
191
245
|
fieldNames,
|
|
@@ -198,6 +252,7 @@ const LazySelect = (props: Readonly<LazySelectProps>) => {
|
|
|
198
252
|
onChange,
|
|
199
253
|
allowCreate = true,
|
|
200
254
|
allowEdit = true,
|
|
255
|
+
className,
|
|
201
256
|
...others
|
|
202
257
|
} = props;
|
|
203
258
|
const model: any = useFlowModel();
|
|
@@ -245,8 +300,8 @@ const LazySelect = (props: Readonly<LazySelectProps>) => {
|
|
|
245
300
|
});
|
|
246
301
|
if (!candidates.length) return;
|
|
247
302
|
|
|
248
|
-
const namePath = model
|
|
249
|
-
const
|
|
303
|
+
const namePath = getAssociationHydrationNamePath(model);
|
|
304
|
+
const setterCtx: any = getAssociationHydrationSetterContext(model);
|
|
250
305
|
|
|
251
306
|
candidates.forEach(({ item, tk, tkKey }) => {
|
|
252
307
|
void (async () => {
|
|
@@ -268,8 +323,8 @@ const LazySelect = (props: Readonly<LazySelectProps>) => {
|
|
|
268
323
|
})
|
|
269
324
|
: merge;
|
|
270
325
|
|
|
271
|
-
if (
|
|
272
|
-
await
|
|
326
|
+
if (setterCtx && typeof setterCtx.setFormValue === 'function' && namePath != null) {
|
|
327
|
+
await setterCtx.setFormValue(namePath, nextValue, {
|
|
273
328
|
source: 'default',
|
|
274
329
|
markExplicit: false,
|
|
275
330
|
triggerEvent: false,
|
|
@@ -305,6 +360,7 @@ const LazySelect = (props: Readonly<LazySelectProps>) => {
|
|
|
305
360
|
<Select
|
|
306
361
|
style={{ width: '100%' }}
|
|
307
362
|
{...others}
|
|
363
|
+
className={[recordSelectClassName, className].filter(Boolean).join(' ')}
|
|
308
364
|
allowClear
|
|
309
365
|
showSearch
|
|
310
366
|
maxTagCount="responsive"
|
|
@@ -397,19 +453,7 @@ const LazySelect = (props: Readonly<LazySelectProps>) => {
|
|
|
397
453
|
}}
|
|
398
454
|
popupMatchSelectWidth
|
|
399
455
|
labelRender={(data) => {
|
|
400
|
-
return
|
|
401
|
-
<div
|
|
402
|
-
className={css`
|
|
403
|
-
div {
|
|
404
|
-
white-space: nowrap !important;
|
|
405
|
-
overflow: hidden;
|
|
406
|
-
text-overflow: ellipsis;
|
|
407
|
-
}
|
|
408
|
-
`}
|
|
409
|
-
>
|
|
410
|
-
{data.label}
|
|
411
|
-
</div>
|
|
412
|
-
);
|
|
456
|
+
return <div className={recordSelectLabelClassName}>{data.label}</div>;
|
|
413
457
|
}}
|
|
414
458
|
dropdownRender={(menu) => {
|
|
415
459
|
const isFullMatch = realOptions.some((v) => v[normalizedFieldNames.label] === others.searchText);
|