@nocobase/client-v2 2.2.0-beta.8 → 2.2.0
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 +13 -3
- package/es/BaseApplication.d.ts +3 -0
- package/es/RouteRepository.d.ts +8 -0
- 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/ScanInput/useCodeScanner.d.ts +3 -2
- package/es/components/form/TypedVariableInput.d.ts +31 -5
- 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/index.d.ts +1 -0
- package/es/entry-actions/EntryActionManager.d.ts +24 -0
- package/es/entry-actions/index.d.ts +9 -0
- package/es/flow/actions/index.d.ts +1 -1
- package/es/flow/actions/linkageRules.d.ts +27 -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/AdminLayoutMenuModels.d.ts +1 -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/useApplications.d.ts +7 -2
- package/es/flow/components/FieldAssignExactDatePicker.d.ts +1 -0
- package/es/flow/components/FieldAssignValueInput.d.ts +7 -24
- package/es/flow/components/FlowRoute.d.ts +2 -2
- package/es/flow/components/RunJSValueEditor.d.ts +1 -0
- package/es/flow/components/field-value-variable/DateVariableEditor.d.ts +24 -0
- package/es/flow/components/field-value-variable/FieldValueVariableInput.d.ts +31 -0
- package/es/flow/components/field-value-variable/dateValue.d.ts +36 -0
- package/es/flow/components/field-value-variable/index.d.ts +11 -0
- package/es/flow/components/filter/FilterGroup.d.ts +1 -0
- package/es/flow/components/filter/VariableFilterItem.d.ts +6 -1
- package/es/flow/components/placeholders/BlockPlaceholder.d.ts +1 -0
- package/es/flow/index.d.ts +1 -0
- package/es/flow/internal/registerDeviceTypeContext.d.ts +10 -0
- package/es/flow/internal/utils/operatorSchemaHelper.d.ts +2 -2
- package/es/flow/models/actions/UpdateRecordActionUtils.d.ts +8 -2
- package/es/flow/models/base/ActionModelCore.d.ts +6 -2
- package/es/flow/models/base/BlockGridModel.d.ts +3 -0
- package/es/flow/models/base/CollectionBlockModel.d.ts +3 -0
- 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/details/DetailsBlockModel.d.ts +3 -0
- package/es/flow/models/blocks/filter-form/FilterFormGridModel.d.ts +1 -0
- package/es/flow/models/blocks/filter-form/FilterFormSubmitActionModel.d.ts +3 -1
- package/es/flow/models/blocks/form/FormBlockModel.d.ts +7 -0
- package/es/flow/models/blocks/form/FormGridModel.d.ts +6 -0
- package/es/flow/models/blocks/form/QuickEditFormModel.d.ts +17 -2
- package/es/flow/models/blocks/form/value-runtime/rules.d.ts +1 -0
- package/es/flow/models/blocks/table/JSColumnModel.d.ts +2 -0
- package/es/flow/models/blocks/table/TableBlockModel.d.ts +1 -0
- package/es/flow/models/blocks/table/TableColumnModel.d.ts +12 -0
- package/es/flow/models/blocks/table/utils.d.ts +1 -0
- package/es/flow/models/fields/AssociationFieldModel/RecordPickerFieldModel.d.ts +2 -1
- package/es/flow/models/fields/AssociationFieldModel/RecordSelectFieldModel.d.ts +0 -17
- package/es/flow/models/fields/AssociationFieldModel/recordSelectShared.d.ts +41 -0
- package/es/flow/models/fields/DateTimeFieldModel/dateLimit.d.ts +15 -7
- package/es/flow/routeTransientInputArgs.d.ts +14 -0
- package/es/flow-compat/fieldValidationConstants.d.ts +1 -1
- package/es/flow-compat/passwordUtils.d.ts +1 -1
- package/es/flow-compat/routeTypes.d.ts +1 -0
- package/es/index.d.ts +7 -0
- package/es/index.mjs +301 -177
- package/es/ui-operation/index.d.ts +15 -0
- package/es/ui-operation/ui-operation-codec.d.ts +10 -0
- 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 +313 -189
- package/lib/locale/languageCodes.js +3 -1
- package/package.json +9 -7
- package/src/APIClient.ts +90 -7
- package/src/Application.tsx +7 -1
- package/src/BaseApplication.tsx +13 -6
- package/src/RouteRepository.ts +25 -0
- package/src/RouterManager.tsx +142 -1
- package/src/__tests__/APIClient.test.tsx +58 -0
- package/src/__tests__/RouteRepository.test.ts +23 -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__/getRouteRuntimeVersion.test.ts +68 -0
- package/src/__tests__/nocobase-buildin-plugin-auth.test.tsx +35 -2
- package/src/__tests__/settings-center.test.tsx +270 -6
- package/src/acl/ACLProvider.tsx +2 -0
- package/src/acl/__tests__/ACLProvider.test.tsx +92 -0
- 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-validation.ts +1 -1
- 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 +4 -0
- 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/__tests__/TypedVariableInput.test.tsx +364 -12
- package/src/components/form/filter/CollectionFilter.tsx +4 -0
- package/src/components/form/filter/CollectionFilterItem.tsx +36 -9
- package/src/components/form/filter/CollectionFilterPanel.tsx +4 -0
- package/src/components/form/filter/__tests__/CollectionFilterItem.test.tsx +55 -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/table/Table.tsx +81 -6
- package/src/components/form/table/__tests__/Table.columnWidth.test.tsx +433 -0
- package/src/components/index.ts +1 -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 +675 -12
- package/src/flow/__tests__/PluginFlowEngine.test.ts +58 -0
- package/src/flow/actions/__tests__/actionLinkageRules.forkProps.test.ts +314 -0
- package/src/flow/actions/__tests__/dataScopeFilter.test.ts +62 -0
- package/src/flow/actions/__tests__/dataScopeFormValueClear.test.ts +102 -0
- package/src/flow/actions/__tests__/linkageRules.actionStates.test.ts +33 -0
- package/src/flow/actions/__tests__/linkageRules.subFormSetFieldProps.test.ts +72 -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 +80 -20
- package/src/flow/actions/dataScopeFilter.ts +10 -1
- package/src/flow/actions/dateTimeFormat.tsx +2 -2
- package/src/flow/actions/index.ts +2 -0
- package/src/flow/actions/linkageRules.tsx +144 -26
- package/src/flow/actions/linkageRulesRefresh.tsx +2 -6
- package/src/flow/actions/openView.tsx +21 -1
- package/src/flow/admin-shell/BaseLayoutModel.tsx +124 -0
- package/src/flow/admin-shell/BaseLayoutRouteCoordinator.ts +184 -42
- package/src/flow/admin-shell/__tests__/AdminLayoutRouteCoordinator.test.ts +1016 -119
- package/src/flow/admin-shell/admin-layout/AdminLayoutComponent.tsx +41 -5
- package/src/flow/admin-shell/admin-layout/AdminLayoutEntryGuard.test.tsx +177 -1
- package/src/flow/admin-shell/admin-layout/AdminLayoutEntryGuard.tsx +20 -0
- package/src/flow/admin-shell/admin-layout/AdminLayoutMenuUtils.tsx +78 -59
- 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/__tests__/AdminLayoutComponent.test.tsx +253 -6
- package/src/flow/admin-shell/admin-layout/__tests__/AdminLayoutMenuModels.test.ts +228 -0
- package/src/flow/admin-shell/admin-layout/__tests__/AdminLayoutModel.test.tsx +436 -2
- package/src/flow/admin-shell/admin-layout/__tests__/TopbarActionsBar.test.tsx +48 -0
- package/src/flow/admin-shell/admin-layout/index.ts +1 -0
- 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/FieldAssignExactDatePicker.tsx +25 -11
- package/src/flow/components/FieldAssignValueInput.tsx +72 -584
- package/src/flow/components/FlowRoute.tsx +204 -46
- package/src/flow/components/RunJSValueEditor.tsx +9 -1
- package/src/flow/components/__tests__/FieldAssignValueInput.context.test.tsx +216 -0
- package/src/flow/components/field-value-variable/DateVariableEditor.tsx +181 -0
- package/src/flow/components/field-value-variable/FieldValueVariableInput.tsx +326 -0
- package/src/flow/components/field-value-variable/__tests__/FieldValueVariableInput.test.tsx +380 -0
- package/src/flow/components/field-value-variable/dateValue.ts +223 -0
- package/src/flow/components/field-value-variable/index.ts +12 -0
- package/src/flow/components/filter/FilterGroup.tsx +33 -5
- package/src/flow/components/filter/VariableFilterItem.tsx +170 -13
- 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 +195 -1
- package/src/flow/components/placeholders/BlockPlaceholder.tsx +70 -23
- package/src/flow/components/placeholders/__tests__/BlockPlaceholder.test.tsx +57 -7
- package/src/flow/index.ts +3 -0
- 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 +3 -2
- package/src/flow/models/actions/UpdateRecordActionModel.tsx +18 -1
- package/src/flow/models/actions/UpdateRecordActionUtils.ts +18 -6
- package/src/flow/models/actions/__tests__/UpdateRecordActionModel.test.ts +76 -4
- package/src/flow/models/base/ActionModel.tsx +10 -8
- package/src/flow/models/base/ActionModelCore.tsx +16 -2
- package/src/flow/models/base/BlockGridModel.tsx +26 -0
- package/src/flow/models/base/CollectionBlockModel.tsx +38 -3
- package/src/flow/models/base/PageModel/PageModel.tsx +387 -53
- 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 +790 -10
- 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__/ActionModelCore.render.test.tsx +49 -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__/CollectionBlockModel.initialBeforeRenderRefresh.test.ts +125 -9
- package/src/flow/models/blocks/assign-form/AssignFormItemModel.tsx +28 -53
- package/src/flow/models/blocks/details/DetailsBlockModel.tsx +8 -3
- package/src/flow/models/blocks/details/__tests__/DetailsBlockModel.initialPaginationChangeRefresh.test.ts +32 -1
- package/src/flow/models/blocks/filter-form/FilterFormBlockModel.tsx +28 -3
- package/src/flow/models/blocks/filter-form/FilterFormGridModel.tsx +36 -5
- package/src/flow/models/blocks/filter-form/FilterFormItemModel.tsx +155 -25
- package/src/flow/models/blocks/filter-form/FilterFormSubmitActionModel.tsx +57 -4
- package/src/flow/models/blocks/filter-form/__tests__/FilterFormGridModel.onModelCreated.test.ts +174 -1
- package/src/flow/models/blocks/filter-form/__tests__/FilterFormItemModel.defineChildren.test.ts +395 -1
- package/src/flow/models/blocks/filter-form/__tests__/FilterFormItemModel.getFilterValue.test.ts +72 -0
- package/src/flow/models/blocks/filter-form/__tests__/FilterFormSubmitActionModel.lifecycle.test.ts +90 -0
- package/src/flow/models/blocks/filter-form/__tests__/defaultValues.wiring.test.ts +66 -4
- package/src/flow/models/blocks/filter-manager/FilterManager.ts +5 -0
- package/src/flow/models/blocks/filter-manager/__tests__/FilterManager.test.ts +40 -0
- package/src/flow/models/blocks/form/FormBlockModel.tsx +47 -0
- package/src/flow/models/blocks/form/FormGridModel.tsx +4 -0
- package/src/flow/models/blocks/form/QuickEditFormModel.tsx +189 -36
- package/src/flow/models/blocks/form/__tests__/FormBlockModel.test.tsx +8 -2
- package/src/flow/models/blocks/form/__tests__/QuickEditFormModel.quickEdit.test.ts +350 -2
- package/src/flow/models/blocks/form/__tests__/runJsFormSubmit.test.ts +131 -0
- package/src/flow/models/blocks/form/value-runtime/__tests__/runtime.test.ts +435 -0
- package/src/flow/models/blocks/form/value-runtime/rules.ts +67 -14
- package/src/flow/models/blocks/form/value-runtime/runtime.ts +43 -19
- package/src/flow/models/blocks/js-block/JSBlock.tsx +1 -1
- package/src/flow/models/blocks/table/JSColumnModel.tsx +10 -1
- package/src/flow/models/blocks/table/TableActionsColumnModel.tsx +2 -1
- package/src/flow/models/blocks/table/TableBlockModel.tsx +29 -3
- package/src/flow/models/blocks/table/TableColumnModel.tsx +54 -11
- package/src/flow/models/blocks/table/__tests__/JSColumnModel.test.tsx +52 -5
- package/src/flow/models/blocks/table/__tests__/TableBlockModel.filterReset.test.ts +78 -0
- package/src/flow/models/blocks/table/__tests__/TableBlockModel.quickEditRefresh.test.ts +12 -0
- package/src/flow/models/blocks/table/__tests__/TableColumnModel.test.tsx +84 -0
- package/src/flow/models/blocks/table/utils.ts +7 -0
- package/src/flow/models/fields/AssociationFieldModel/CascadeSelectFieldModel.tsx +33 -1
- package/src/flow/models/fields/AssociationFieldModel/PopupSubTableFieldModel/PopupSubTableFieldModel.tsx +10 -1
- package/src/flow/models/fields/AssociationFieldModel/PopupSubTableFieldModel/__tests__/popupContext.test.ts +120 -0
- package/src/flow/models/fields/AssociationFieldModel/PopupSubTableFieldModel/actions/PopupSubTableEditActionModel.tsx +10 -2
- package/src/flow/models/fields/AssociationFieldModel/RecordPickerFieldModel.tsx +24 -1
- package/src/flow/models/fields/AssociationFieldModel/RecordSelectFieldModel.tsx +54 -149
- package/src/flow/models/fields/AssociationFieldModel/__tests__/RecordPickerFieldModel.itemContext.test.ts +167 -3
- package/src/flow/models/fields/AssociationFieldModel/recordSelectShared.tsx +156 -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/DisplayNumberFieldModel.tsx +1 -1
- package/src/flow/models/fields/JsonFieldModel.tsx +31 -8
- package/src/flow/models/fields/NumberFieldModel.tsx +1 -1
- package/src/flow/models/fields/TextareaFieldModel.tsx +42 -19
- package/src/flow/models/fields/VariableFieldFormModel.tsx +3 -3
- package/src/flow/models/fields/__tests__/DisplayNumberFieldModel.test.ts +33 -0
- package/src/flow/models/fields/__tests__/JsonFieldModel.test.ts +82 -0
- package/src/flow/models/fields/__tests__/NumberFieldModel.test.tsx +47 -0
- package/src/flow/models/fields/__tests__/TextareaFieldModel.test.tsx +32 -1
- package/src/flow/models/fields/__tests__/VariableFieldFormModel.test.tsx +51 -0
- package/src/flow/models/fields/mobile-components/MobileLazySelect.tsx +26 -10
- package/src/flow/models/fields/mobile-components/MobileSelect.tsx +51 -14
- package/src/flow/models/fields/mobile-components/__tests__/MobileSelect.test.tsx +139 -13
- package/src/flow/models/topbar/TopbarActionModel.tsx +78 -3
- package/src/flow/routeTransientInputArgs.ts +27 -0
- package/src/flow/utils/__tests__/dateTimeFormat.test.ts +42 -0
- package/src/flow/utils/dataScopeFormValueClear.ts +4 -3
- package/src/flow-compat/fieldValidationConstants.ts +1 -1
- package/src/flow-compat/routeTypes.ts +1 -0
- package/src/index.ts +7 -0
- package/src/layout-manager/LayoutContentRoute.tsx +2 -1
- package/src/layout-manager/LayoutRoute.tsx +2 -1
- package/src/layout-manager/__tests__/LayoutRoute.test.tsx +87 -1
- package/src/locale/languageCodes.ts +3 -1
- package/src/nocobase-buildin-plugin/index.tsx +19 -1
- package/src/settings-center/AdminSettingsLayout.tsx +23 -2
- package/src/ui-operation/index.ts +33 -0
- package/src/ui-operation/ui-operation-codec.ts +54 -0
- package/src/utils/getRouteRuntimeVersion.ts +185 -0
- package/src/utils/index.tsx +1 -0
- package/src/utils/markdownSanitize.ts +88 -0
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of the NocoBase (R) project.
|
|
3
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
+
* Authors: NocoBase Team.
|
|
5
|
+
*
|
|
6
|
+
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
+
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { describe, expect, it, vi } from 'vitest';
|
|
11
|
+
import { TableBlockModel } from '../TableBlockModel';
|
|
12
|
+
|
|
13
|
+
describe('TableBlockModel filter reset', () => {
|
|
14
|
+
it('collapses the filtered tree when rows are not expanded by default', () => {
|
|
15
|
+
const setExpandFlag = vi.fn();
|
|
16
|
+
const setProps = vi.fn();
|
|
17
|
+
const model = {
|
|
18
|
+
props: { treeTable: true, defaultExpandAllRows: false, expandedRowKeys: [1, 2] },
|
|
19
|
+
resource: { getData: () => [{ id: 3, children: [{ id: 4 }] }] },
|
|
20
|
+
setProps,
|
|
21
|
+
mapSubModels: (_key, callback) => callback({ setExpandFlag }),
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
TableBlockModel.prototype.resetAfterFilterChange.call(model);
|
|
25
|
+
|
|
26
|
+
expect(setProps).toHaveBeenCalledWith('expandedRowKeys', []);
|
|
27
|
+
expect(setExpandFlag).toHaveBeenCalledWith(false);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it('expands the filtered tree when rows are expanded by default', () => {
|
|
31
|
+
const setExpandFlag = vi.fn();
|
|
32
|
+
const setProps = vi.fn();
|
|
33
|
+
const model = {
|
|
34
|
+
props: { treeTable: true, defaultExpandAllRows: true, expandedRowKeys: [1, 2] },
|
|
35
|
+
collection: { filterTargetKey: 'id' },
|
|
36
|
+
resource: { getData: () => [{ id: 3, children: [{ id: 4 }] }] },
|
|
37
|
+
setProps,
|
|
38
|
+
mapSubModels: (_key, callback) => callback({ setExpandFlag }),
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
TableBlockModel.prototype.resetAfterFilterChange.call(model);
|
|
42
|
+
|
|
43
|
+
expect(setProps).toHaveBeenCalledWith('expandedRowKeys', [3, 4]);
|
|
44
|
+
expect(setExpandFlag).toHaveBeenCalledWith(true);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it('uses the collection filter target key when expanding the filtered tree', () => {
|
|
48
|
+
const setProps = vi.fn();
|
|
49
|
+
const model = {
|
|
50
|
+
props: { treeTable: true, defaultExpandAllRows: true },
|
|
51
|
+
collection: { filterTargetKey: ['tenant', 'slug'] },
|
|
52
|
+
resource: {
|
|
53
|
+
getData: () => [{ tenant: 'acme', slug: 'root', children: [{ tenant: 'acme', slug: 'child' }] }],
|
|
54
|
+
},
|
|
55
|
+
setProps,
|
|
56
|
+
mapSubModels: vi.fn(),
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
TableBlockModel.prototype.resetAfterFilterChange.call(model);
|
|
60
|
+
|
|
61
|
+
expect(setProps).toHaveBeenCalledWith('expandedRowKeys', ['acme-root', 'acme-child']);
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
it('does not change expansion state for a regular table', () => {
|
|
65
|
+
const setProps = vi.fn();
|
|
66
|
+
const mapSubModels = vi.fn();
|
|
67
|
+
const model = {
|
|
68
|
+
props: { treeTable: false },
|
|
69
|
+
setProps,
|
|
70
|
+
mapSubModels,
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
TableBlockModel.prototype.resetAfterFilterChange.call(model);
|
|
74
|
+
|
|
75
|
+
expect(setProps).not.toHaveBeenCalled();
|
|
76
|
+
expect(mapSubModels).not.toHaveBeenCalled();
|
|
77
|
+
});
|
|
78
|
+
});
|
|
@@ -9,8 +9,20 @@
|
|
|
9
9
|
|
|
10
10
|
import { FlowEngine, MultiRecordResource } from '@nocobase/flow-engine';
|
|
11
11
|
import { describe, expect, it } from 'vitest';
|
|
12
|
+
import { TableBlockModel } from '../TableBlockModel';
|
|
12
13
|
|
|
13
14
|
describe('TableBlockModel quick edit refresh', () => {
|
|
15
|
+
it('requests record-level ACL metadata for table data', () => {
|
|
16
|
+
const engine = new FlowEngine();
|
|
17
|
+
const model = {
|
|
18
|
+
context: engine.context,
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const resource = TableBlockModel.prototype.createResource.call(model, {}, {});
|
|
22
|
+
|
|
23
|
+
expect(resource.getRequestOptions().headers['X-With-ACL-Meta']).toBe('true');
|
|
24
|
+
});
|
|
25
|
+
|
|
14
26
|
it('updates table data through a new array reference after quick editing a flat row', () => {
|
|
15
27
|
const engine = new FlowEngine();
|
|
16
28
|
const resource = engine.context.createResource(MultiRecordResource);
|
|
@@ -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);
|
|
@@ -327,6 +360,57 @@ describe('TableColumnModel sorter settings', () => {
|
|
|
327
360
|
);
|
|
328
361
|
});
|
|
329
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
|
+
);
|
|
412
|
+
});
|
|
413
|
+
|
|
330
414
|
it('does not update field component setting when title field refresh fails', async () => {
|
|
331
415
|
const engine = new FlowEngine();
|
|
332
416
|
const model = new TableColumnModel({ uid: 'table-column-title-field-component-failed', flowEngine: engine } as any);
|
|
@@ -67,6 +67,13 @@ export function extractIds(data) {
|
|
|
67
67
|
return ids;
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
+
export function extractRowKeys(data: Record<string, unknown>[], key: string | string[]) {
|
|
71
|
+
return data.flatMap((item) => {
|
|
72
|
+
const children = Array.isArray(item.children) ? extractRowKeys(item.children, key) : [];
|
|
73
|
+
return [getRowKey(item, key), ...children];
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
|
|
70
77
|
/**
|
|
71
78
|
* 生成表格行唯一 key
|
|
72
79
|
* @param record 当前行数据
|
|
@@ -8,7 +8,13 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import { Cascader, Space, Button } from 'antd';
|
|
11
|
-
import {
|
|
11
|
+
import {
|
|
12
|
+
CollectionField,
|
|
13
|
+
EditableItemModel,
|
|
14
|
+
FilterableItemModel,
|
|
15
|
+
MultiRecordResource,
|
|
16
|
+
tExpr,
|
|
17
|
+
} from '@nocobase/flow-engine';
|
|
12
18
|
import { DeleteOutlined } from '@ant-design/icons';
|
|
13
19
|
import { css, cx } from '@emotion/css';
|
|
14
20
|
import { debounce, castArray, omit, last, isEqual } from 'lodash';
|
|
@@ -31,6 +37,23 @@ function normalizeLabelKeys(labelKeyOrKeys?: string | string[]): string[] {
|
|
|
31
37
|
return Array.from(new Set(list.filter((item): item is string => !!item && typeof item === 'string')));
|
|
32
38
|
}
|
|
33
39
|
|
|
40
|
+
function normalizeCascadeFieldKey(key: unknown): string | undefined {
|
|
41
|
+
if (typeof key === 'string' && key) {
|
|
42
|
+
return key;
|
|
43
|
+
}
|
|
44
|
+
if (Array.isArray(key) && key.length === 1 && typeof key[0] === 'string') {
|
|
45
|
+
return key[0];
|
|
46
|
+
}
|
|
47
|
+
return undefined;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function getDefaultCascadeFieldNames(field: CollectionField) {
|
|
51
|
+
const targetCollection = field?.targetCollection;
|
|
52
|
+
const value = normalizeCascadeFieldKey(targetCollection?.filterTargetKey) || 'id';
|
|
53
|
+
const label = targetCollection?.titleCollectionField?.name || value;
|
|
54
|
+
return { label, value };
|
|
55
|
+
}
|
|
56
|
+
|
|
34
57
|
function getRecordDisplayLabel(item: any, labelKeyOrKeys?: string | string[]): string | null {
|
|
35
58
|
if (!isPlainRecord(item)) return null;
|
|
36
59
|
const labelKeys = normalizeLabelKeys(labelKeyOrKeys);
|
|
@@ -815,6 +838,15 @@ EditableItemModel.bindModelToInterface('CascadeSelectFieldModel', ['m2o', 'o2o',
|
|
|
815
838
|
order: 60,
|
|
816
839
|
});
|
|
817
840
|
|
|
841
|
+
FilterableItemModel.bindModelToInterface('CascadeSelectFieldModel', ['m2o', 'o2o', 'oho', 'obo'], {
|
|
842
|
+
when: (ctx, field) => field.targetCollection?.template === 'tree',
|
|
843
|
+
isDefault: true,
|
|
844
|
+
order: 60,
|
|
845
|
+
defaultProps: (ctx, field) => ({
|
|
846
|
+
fieldNames: getDefaultCascadeFieldNames(field),
|
|
847
|
+
}),
|
|
848
|
+
});
|
|
849
|
+
|
|
818
850
|
EditableItemModel.bindModelToInterface('CascadeSelectListFieldModel', ['m2m', 'o2m', 'mbm'], {
|
|
819
851
|
when: (ctx, field) => field.targetCollection?.template === 'tree',
|
|
820
852
|
isDefault: true,
|
|
@@ -28,6 +28,7 @@ import { observer } from '@formily/reactive-react';
|
|
|
28
28
|
import React, { useEffect, useMemo, useState, useRef } from 'react';
|
|
29
29
|
import { useTranslation } from 'react-i18next';
|
|
30
30
|
import { buildRecordPickerPopupContextInputArgs, RecordPickerContent } from '../RecordPickerFieldModel';
|
|
31
|
+
import { buildOpenerUids } from '../recordSelectShared';
|
|
31
32
|
import { AssociationFieldModel } from '../AssociationFieldModel';
|
|
32
33
|
import { adjustColumnOrder } from '../../../blocks/table/utils';
|
|
33
34
|
import { isSubTableColumnFieldComponentContext } from '../SubTableFieldModel/SubTableColumnModel';
|
|
@@ -102,7 +103,7 @@ const RenderCell = observer<any>((props) => {
|
|
|
102
103
|
transform: translateY(-50%);
|
|
103
104
|
}
|
|
104
105
|
&:hover {
|
|
105
|
-
|
|
106
|
+
box-shadow: inset 0 0 0 9999px rgba(24, 144, 255, 0.1);
|
|
106
107
|
}
|
|
107
108
|
&:hover .edit-icon {
|
|
108
109
|
display: inline-flex;
|
|
@@ -126,6 +127,7 @@ const RenderCell = observer<any>((props) => {
|
|
|
126
127
|
fieldPath: dataIndex,
|
|
127
128
|
record: record,
|
|
128
129
|
fieldProps: { ...columnModel.props, ...columnModel.subModels.field.props },
|
|
130
|
+
sourceFieldModelUid: columnModel.subModels.field.uid,
|
|
129
131
|
onOk: (values) => {
|
|
130
132
|
record[dataIndex] = values[dataIndex];
|
|
131
133
|
// 仅重渲染单元格
|
|
@@ -652,6 +654,11 @@ PopupSubTableFieldModel.registerFlow({
|
|
|
652
654
|
const parentItemOptions = ctx?.getPropertyOptions?.('item');
|
|
653
655
|
const itemIndex = Array.isArray(ctx.model?.props?.value) ? ctx.model.props.value.length : 0;
|
|
654
656
|
const itemLength = itemIndex + 1;
|
|
657
|
+
const associationName = ctx.collectionField?.resourceName;
|
|
658
|
+
const sourceId = parentItem?.value
|
|
659
|
+
? ctx.collectionField?.collection?.getFilterByTK?.(parentItem.value)
|
|
660
|
+
: undefined;
|
|
661
|
+
const openerUids = buildOpenerUids(ctx, ctx.inputArgs);
|
|
655
662
|
ctx.viewer.open({
|
|
656
663
|
type: openMode,
|
|
657
664
|
width: sizeToWidthMap[openMode][size],
|
|
@@ -662,12 +669,14 @@ PopupSubTableFieldModel.registerFlow({
|
|
|
662
669
|
scene: 'subForm',
|
|
663
670
|
dataSourceKey: ctx.collection.dataSourceKey,
|
|
664
671
|
collectionName: ctx.collectionField?.target,
|
|
672
|
+
...(associationName && sourceId != null ? { associationName, sourceId } : {}),
|
|
665
673
|
collectionField: ctx.collectionField,
|
|
666
674
|
parentItem,
|
|
667
675
|
parentItemMeta: parentItemOptions?.meta,
|
|
668
676
|
parentItemResolver: parentItemOptions?.resolveOnServer,
|
|
669
677
|
itemIndex,
|
|
670
678
|
itemLength,
|
|
679
|
+
openerUids,
|
|
671
680
|
},
|
|
672
681
|
content: () => <EditFormContent model={ctx.model} scene="create" />,
|
|
673
682
|
styles: {
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of the NocoBase (R) project.
|
|
3
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
+
* Authors: NocoBase Team.
|
|
5
|
+
*
|
|
6
|
+
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
+
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { describe, expect, it, vi } from 'vitest';
|
|
11
|
+
import { PopupSubTableFieldModel } from '../PopupSubTableFieldModel';
|
|
12
|
+
import { PopupSubTableEditActionModel } from '../actions/PopupSubTableEditActionModel';
|
|
13
|
+
|
|
14
|
+
function getOpenViewHandler(modelClass: typeof PopupSubTableFieldModel | typeof PopupSubTableEditActionModel) {
|
|
15
|
+
const flow = modelClass.globalFlowRegistry.getFlow('popupSettings');
|
|
16
|
+
const step = flow?.getStep('openView');
|
|
17
|
+
const handler = step?.serialize().handler;
|
|
18
|
+
|
|
19
|
+
if (!handler) {
|
|
20
|
+
throw new Error('popupSettings.openView handler is not registered');
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
return handler;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function createContext(record?: Record<string, unknown>, parentRecord: Record<string, unknown> = { id: 1 }) {
|
|
27
|
+
const open = vi.fn();
|
|
28
|
+
const sourceCollection = {
|
|
29
|
+
getFilterByTK: vi.fn((sourceRecord: Record<string, unknown>) => sourceRecord.id),
|
|
30
|
+
};
|
|
31
|
+
const model = {
|
|
32
|
+
uid: 'popup-subtable-uid',
|
|
33
|
+
props: {
|
|
34
|
+
value: record ? [record] : [],
|
|
35
|
+
},
|
|
36
|
+
context: {
|
|
37
|
+
inputArgs: {},
|
|
38
|
+
},
|
|
39
|
+
flowEngine: {
|
|
40
|
+
context: {
|
|
41
|
+
themeToken: {
|
|
42
|
+
colorBgLayout: '#fff',
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
return {
|
|
49
|
+
open,
|
|
50
|
+
context: {
|
|
51
|
+
inputArgs: {},
|
|
52
|
+
item: {
|
|
53
|
+
value: parentRecord,
|
|
54
|
+
},
|
|
55
|
+
view: {
|
|
56
|
+
inputArgs: {
|
|
57
|
+
viewUid: 'parent-popup-uid',
|
|
58
|
+
openerUids: ['root-page-uid'],
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
viewer: { open },
|
|
62
|
+
layoutContentElement: {},
|
|
63
|
+
model,
|
|
64
|
+
associationModel: model,
|
|
65
|
+
collection: {
|
|
66
|
+
dataSourceKey: 'main',
|
|
67
|
+
filterTargetKey: 'id',
|
|
68
|
+
},
|
|
69
|
+
collectionField: {
|
|
70
|
+
target: 'roles',
|
|
71
|
+
resourceName: 'users.roles',
|
|
72
|
+
collection: sourceCollection,
|
|
73
|
+
},
|
|
74
|
+
record,
|
|
75
|
+
getFormValues: () => ({ id: 1 }),
|
|
76
|
+
getPropertyOptions: () => undefined,
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
describe('PopupSubTable popup context', () => {
|
|
82
|
+
it('passes popup and parent record context to the add-new popup', () => {
|
|
83
|
+
const { context, open } = createContext();
|
|
84
|
+
const handler = getOpenViewHandler(PopupSubTableFieldModel);
|
|
85
|
+
|
|
86
|
+
handler(context, { mode: 'drawer', size: 'medium' });
|
|
87
|
+
|
|
88
|
+
expect(open).toHaveBeenCalledOnce();
|
|
89
|
+
expect(open.mock.calls[0][0].inputArgs).toMatchObject({
|
|
90
|
+
openerUids: ['root-page-uid', 'parent-popup-uid'],
|
|
91
|
+
associationName: 'users.roles',
|
|
92
|
+
sourceId: 1,
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
it('passes popup and parent record context to the edit popup', () => {
|
|
97
|
+
const { context, open } = createContext({ id: 2, name: 'Member' });
|
|
98
|
+
const handler = getOpenViewHandler(PopupSubTableEditActionModel);
|
|
99
|
+
|
|
100
|
+
handler(context, { mode: 'dialog', size: 'medium' });
|
|
101
|
+
|
|
102
|
+
expect(open).toHaveBeenCalledOnce();
|
|
103
|
+
expect(open.mock.calls[0][0].inputArgs).toMatchObject({
|
|
104
|
+
openerUids: ['root-page-uid', 'parent-popup-uid'],
|
|
105
|
+
associationName: 'users.roles',
|
|
106
|
+
sourceId: 1,
|
|
107
|
+
});
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
it('does not expose a parent record reference before the parent record is persisted', () => {
|
|
111
|
+
const { context, open } = createContext(undefined, { nickname: 'Draft user' });
|
|
112
|
+
const handler = getOpenViewHandler(PopupSubTableFieldModel);
|
|
113
|
+
|
|
114
|
+
handler(context, { mode: 'drawer', size: 'medium' });
|
|
115
|
+
|
|
116
|
+
expect(open).toHaveBeenCalledOnce();
|
|
117
|
+
expect(open.mock.calls[0][0].inputArgs).not.toHaveProperty('associationName');
|
|
118
|
+
expect(open.mock.calls[0][0].inputArgs).not.toHaveProperty('sourceId');
|
|
119
|
+
});
|
|
120
|
+
});
|
|
@@ -17,6 +17,7 @@ import { capitalize } from 'lodash';
|
|
|
17
17
|
import '../../../../base/ActionModel';
|
|
18
18
|
import { ActionModel, ActionWithoutPermission } from '../../../../base/ActionModelCore';
|
|
19
19
|
import { SkeletonFallback } from '../../../../../components/SkeletonFallback';
|
|
20
|
+
import { buildOpenerUids } from '../../recordSelectShared';
|
|
20
21
|
import { bindPopupSubTableBeforeClose } from './popupSubTableBeforeClose';
|
|
21
22
|
|
|
22
23
|
function FieldWithoutPermissionPlaceholder({ targetModel, children }) {
|
|
@@ -29,7 +30,7 @@ function FieldWithoutPermissionPlaceholder({ targetModel, children }) {
|
|
|
29
30
|
const dataSourcePrefix = `${t(dataSource.displayName || dataSource.key)} > `;
|
|
30
31
|
const collectionPrefix = collection ? `${t(collection.title) || collection.name || collection.tableName} > ` : '';
|
|
31
32
|
return `${dataSourcePrefix}${collectionPrefix}${name}`;
|
|
32
|
-
}, []);
|
|
33
|
+
}, [collection, dataSource.displayName, dataSource.key, name, t]);
|
|
33
34
|
const { actionName } = fieldModel.forbidden || {};
|
|
34
35
|
const messageValue = useMemo(() => {
|
|
35
36
|
return t(
|
|
@@ -39,7 +40,7 @@ function FieldWithoutPermissionPlaceholder({ targetModel, children }) {
|
|
|
39
40
|
actionName: t(capitalize(actionName)),
|
|
40
41
|
},
|
|
41
42
|
).replaceAll('>', '>');
|
|
42
|
-
}, [nameValue, t]);
|
|
43
|
+
}, [actionName, nameValue, t]);
|
|
43
44
|
return <Tooltip title={messageValue}>{children}</Tooltip>;
|
|
44
45
|
}
|
|
45
46
|
|
|
@@ -347,6 +348,11 @@ PopupSubTableEditActionModel.registerFlow({
|
|
|
347
348
|
return undefined;
|
|
348
349
|
}
|
|
349
350
|
})();
|
|
351
|
+
const associationName = ctx.collectionField?.resourceName;
|
|
352
|
+
const sourceId = parentItem?.value
|
|
353
|
+
? ctx.collectionField?.collection?.getFilterByTK?.(parentItem.value)
|
|
354
|
+
: undefined;
|
|
355
|
+
const openerUids = buildOpenerUids(ctx, ctx.inputArgs);
|
|
350
356
|
ctx.viewer.open({
|
|
351
357
|
type: openMode,
|
|
352
358
|
width: sizeToWidthMap[openMode][size],
|
|
@@ -357,6 +363,7 @@ PopupSubTableEditActionModel.registerFlow({
|
|
|
357
363
|
scene: 'subForm',
|
|
358
364
|
dataSourceKey: ctx.collection.dataSourceKey,
|
|
359
365
|
collectionName: ctx.collectionField?.target,
|
|
366
|
+
...(associationName && sourceId != null ? { associationName, sourceId } : {}),
|
|
360
367
|
collectionField: ctx.collectionField,
|
|
361
368
|
record: ctx.record,
|
|
362
369
|
parentItem,
|
|
@@ -364,6 +371,7 @@ PopupSubTableEditActionModel.registerFlow({
|
|
|
364
371
|
parentItemResolver: parentItemOptions?.resolveOnServer,
|
|
365
372
|
itemIndex,
|
|
366
373
|
itemLength,
|
|
374
|
+
openerUids,
|
|
367
375
|
},
|
|
368
376
|
content: () => <EditFormContent model={ctx.model} />,
|
|
369
377
|
styles: {
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
import {
|
|
11
11
|
CollectionField,
|
|
12
|
+
MultiRecordResource,
|
|
12
13
|
EditableItemModel,
|
|
13
14
|
tExpr,
|
|
14
15
|
FlowModel,
|
|
@@ -31,7 +32,12 @@ import {
|
|
|
31
32
|
createRootItemChain,
|
|
32
33
|
type ItemChain,
|
|
33
34
|
} from './itemChain';
|
|
34
|
-
import {
|
|
35
|
+
import {
|
|
36
|
+
buildOpenerUids,
|
|
37
|
+
LabelByField,
|
|
38
|
+
type AssociationFieldNames,
|
|
39
|
+
useAssociationValueHydration,
|
|
40
|
+
} from './recordSelectShared';
|
|
35
41
|
|
|
36
42
|
const MULTIPLE_ASSOCIATION_TYPES = ['belongsToMany', 'hasMany', 'belongsToArray'];
|
|
37
43
|
|
|
@@ -328,6 +334,13 @@ function RecordPickerField(props) {
|
|
|
328
334
|
useEffect(() => {
|
|
329
335
|
ctx.model.selectedRows.value = props.value;
|
|
330
336
|
}, [ctx.model.selectedRows, props.value]);
|
|
337
|
+
useAssociationValueHydration({
|
|
338
|
+
model: ctx.model,
|
|
339
|
+
value: props.value,
|
|
340
|
+
isMultiple: allowMultiple,
|
|
341
|
+
fieldNames,
|
|
342
|
+
onChange: props.onChange,
|
|
343
|
+
});
|
|
331
344
|
|
|
332
345
|
return (
|
|
333
346
|
<Select
|
|
@@ -400,6 +413,7 @@ function RecordPickerField(props) {
|
|
|
400
413
|
}
|
|
401
414
|
|
|
402
415
|
export class RecordPickerFieldModel extends FieldModel {
|
|
416
|
+
declare resource: MultiRecordResource;
|
|
403
417
|
selectedRows = observable.ref([]);
|
|
404
418
|
_closeView;
|
|
405
419
|
selectBlockModel;
|
|
@@ -564,6 +578,15 @@ RecordPickerFieldModel.registerFlow({
|
|
|
564
578
|
title: tExpr('RecordPicker settings'),
|
|
565
579
|
sort: 200,
|
|
566
580
|
steps: {
|
|
581
|
+
init: {
|
|
582
|
+
handler(ctx) {
|
|
583
|
+
const { target, dataSourceKey } = ctx.model.collectionField;
|
|
584
|
+
const resource = ctx.createResource(MultiRecordResource);
|
|
585
|
+
resource.setDataSourceKey(dataSourceKey);
|
|
586
|
+
resource.setResourceName(target);
|
|
587
|
+
ctx.model.resource = resource;
|
|
588
|
+
},
|
|
589
|
+
},
|
|
567
590
|
fieldNames: {
|
|
568
591
|
use: 'titleField',
|
|
569
592
|
},
|