@nocobase/client-v2 2.2.0-alpha.1 → 2.2.0-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/es/PluginSettingsManager.d.ts +33 -0
- package/es/RouteRepository.d.ts +21 -6
- 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/TypedVariableInput.d.ts +22 -4
- package/es/components/form/VariableJsonTextArea.d.ts +19 -0
- package/es/components/form/filter/CollectionFilterItem.d.ts +11 -1
- package/es/components/form/filter/index.d.ts +2 -0
- package/es/components/form/index.d.ts +1 -0
- package/es/components/index.d.ts +2 -0
- package/es/flow/actions/afterSuccess.d.ts +8 -1
- package/es/flow/actions/index.d.ts +1 -1
- 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 +2 -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/resolveAdminRouteRuntimeTarget.d.ts +6 -0
- package/es/flow/components/FieldAssignRulesEditor.d.ts +3 -1
- package/es/flow/components/FieldAssignValueInput.d.ts +2 -0
- package/es/flow/index.d.ts +1 -0
- package/es/flow/models/base/GridModel.d.ts +1 -1
- 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/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 +21 -0
- package/es/flow/models/blocks/form/value-runtime/types.d.ts +2 -2
- 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/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/resolveViewParamsToViewList.d.ts +1 -1
- 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/index.d.ts +2 -1
- package/es/index.mjs +233 -137
- package/lib/index.js +234 -138
- package/package.json +7 -7
- package/src/PluginSettingsManager.ts +53 -0
- package/src/RouteRepository.ts +126 -24
- package/src/__tests__/PluginSettingsManager.test.ts +13 -0
- package/src/__tests__/RouteRepository.test.ts +216 -0
- package/src/__tests__/browserChecker.test.ts +61 -0
- package/src/__tests__/exports.test.ts +16 -0
- package/src/__tests__/nocobase-buildin-plugin-auth.test.tsx +199 -0
- package/src/__tests__/plugin-manager.test.tsx +44 -2
- package/src/__tests__/settings-center.test.tsx +40 -1
- package/src/collection-manager/field-configure.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 +21 -11
- package/src/components/form/TypedVariableInput.tsx +416 -93
- 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 +266 -9
- package/src/components/form/__tests__/VariableJsonTextArea.test.tsx +86 -0
- package/src/components/form/filter/CollectionFilterItem.tsx +32 -7
- package/src/components/form/filter/__tests__/CollectionFilterItem.test.tsx +38 -0
- package/src/components/form/filter/index.ts +2 -0
- package/src/components/form/index.tsx +1 -0
- package/src/components/index.ts +2 -0
- package/src/flow/__tests__/FlowRoute.test.tsx +443 -5
- package/src/flow/__tests__/getKey.test.ts +7 -0
- package/src/flow/__tests__/resolveViewParamsToViewList.test.ts +34 -0
- package/src/flow/actions/__tests__/afterSuccess.test.ts +73 -0
- package/src/flow/actions/__tests__/dataScopeFilter.test.ts +58 -0
- package/src/flow/actions/__tests__/dataScopeFormValueClear.test.ts +1022 -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__/openView.defineProps.route.test.tsx +104 -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 +10 -0
- package/src/flow/actions/dateTimeFormat.tsx +42 -28
- package/src/flow/actions/index.ts +1 -1
- package/src/flow/actions/linkageRules.tsx +123 -35
- package/src/flow/actions/linkageRulesFormValueRefresh.ts +22 -130
- package/src/flow/actions/openView.tsx +38 -4
- package/src/flow/actions/runjs.tsx +2 -14
- package/src/flow/actions/validation.tsx +62 -30
- package/src/flow/admin-shell/BaseLayoutModel.tsx +25 -3
- package/src/flow/admin-shell/BaseLayoutRouteCoordinator.ts +5 -2
- package/src/flow/admin-shell/__tests__/AdminLayoutRouteCoordinator.test.ts +13 -0
- package/src/flow/admin-shell/admin-layout/AdminLayoutComponent.tsx +34 -10
- package/src/flow/admin-shell/admin-layout/AdminLayoutEntryGuard.test.tsx +310 -0
- package/src/flow/admin-shell/admin-layout/AdminLayoutEntryGuard.tsx +44 -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/HelpLite.tsx +1 -3
- package/src/flow/admin-shell/admin-layout/__tests__/AdminLayoutComponent.test.tsx +188 -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 +82 -0
- package/src/flow/admin-shell/admin-layout/__tests__/TopbarActionsBar.test.tsx +166 -2
- 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/components/DefaultValue.tsx +1 -2
- package/src/flow/components/DynamicFlowsIcon.tsx +447 -126
- package/src/flow/components/FieldAssignRulesEditor.tsx +128 -21
- package/src/flow/components/FieldAssignValueInput.tsx +10 -5
- package/src/flow/components/FlowRoute.tsx +56 -11
- 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__/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/flows/editMarkdownFlow.tsx +1 -1
- package/src/flow/getViewDiffAndUpdateHidden.tsx +1 -0
- package/src/flow/index.ts +2 -1
- 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 +12 -1
- package/src/flow/models/base/GridModel.tsx +38 -7
- package/src/flow/models/base/PageModel/PageModel.tsx +4 -1
- package/src/flow/models/base/PageModel/__tests__/PageModel.test.ts +28 -4
- package/src/flow/models/base/__tests__/ActionModel.test.ts +83 -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 +31 -3
- package/src/flow/models/blocks/filter-form/FilterFormJSActionModel.tsx +2 -7
- package/src/flow/models/blocks/filter-form/__tests__/defaultValues.wiring.test.ts +77 -0
- 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/__tests__/FormBlockModel.test.tsx +17 -0
- 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 +880 -102
- package/src/flow/models/blocks/form/value-runtime/rules.ts +445 -13
- package/src/flow/models/blocks/form/value-runtime/runtime.ts +257 -13
- package/src/flow/models/blocks/form/value-runtime/types.ts +2 -2
- package/src/flow/models/blocks/js-block/JSBlock.tsx +2 -7
- package/src/flow/models/blocks/table/JSColumnModel.tsx +1 -9
- package/src/flow/models/blocks/table/TableActionsColumnModel.tsx +36 -13
- package/src/flow/models/blocks/table/TableBlockModel.tsx +38 -17
- package/src/flow/models/blocks/table/TableColumnModel.tsx +36 -3
- 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.rowSelection.test.tsx +1 -0
- package/src/flow/models/blocks/table/__tests__/TableColumnModel.test.tsx +159 -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 +29 -6
- package/src/flow/models/fields/AssociationFieldModel/RecordSelectFieldModel.tsx +16 -4
- 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/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 +49 -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 +100 -0
- package/src/flow/models/topbar/TopbarActionModel.tsx +93 -10
- package/src/flow/resolveViewParamsToViewList.tsx +11 -3
- package/src/flow/utils/__tests__/dateTimeFormat.test.ts +258 -0
- package/src/flow/utils/dataScopeFormValueClear.ts +218 -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/index.ts +8 -1
- package/src/layout-manager/__tests__/LayoutRoute.test.tsx +41 -1
- package/src/nocobase-buildin-plugin/index.tsx +44 -14
- 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
|
@@ -7,13 +7,152 @@
|
|
|
7
7
|
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
import {
|
|
10
|
+
import {
|
|
11
|
+
FlowContext,
|
|
12
|
+
createRecordMetaFactory,
|
|
13
|
+
createRecordResolveOnServerWithLocal,
|
|
14
|
+
defineAction,
|
|
15
|
+
tExpr,
|
|
16
|
+
useFlowSettingsContext,
|
|
17
|
+
type Collection,
|
|
18
|
+
type FlowRuntimeContext,
|
|
19
|
+
type MetaTreeNode,
|
|
20
|
+
type PropertyMetaFactory,
|
|
21
|
+
} from '@nocobase/flow-engine';
|
|
11
22
|
import { isURL } from '@nocobase/utils/client';
|
|
12
|
-
import {
|
|
23
|
+
import React, { useMemo } from 'react';
|
|
24
|
+
import {
|
|
25
|
+
TextAreaWithContextSelector,
|
|
26
|
+
type TextAreaWithContextSelectorProps,
|
|
27
|
+
} from '../components/TextAreaWithContextSelector';
|
|
28
|
+
|
|
29
|
+
type ResponseRecordPlainStepContext = {
|
|
30
|
+
steps?: FlowRuntimeContext['steps'];
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
type ResponseRecordFlowDefinitionContext = {
|
|
34
|
+
flowKey?: string;
|
|
35
|
+
model?: {
|
|
36
|
+
getFlow?: (flowKey: string) => { steps?: Record<string, unknown> } | undefined;
|
|
37
|
+
};
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
type ResponseRecordContext = FlowContext &
|
|
41
|
+
ResponseRecordPlainStepContext & {
|
|
42
|
+
blockModel?: { collection?: Collection };
|
|
43
|
+
collection?: Collection;
|
|
44
|
+
model?: FlowRuntimeContext['model'] & { collection?: Collection };
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
function getResponseRecordSteps(ctx: FlowContext | ResponseRecordPlainStepContext): FlowRuntimeContext['steps'] {
|
|
48
|
+
return 'steps' in ctx ? ctx.steps || {} : {};
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export function getAfterSuccessResponseRecord(ctx: FlowContext | ResponseRecordPlainStepContext) {
|
|
52
|
+
const steps = getResponseRecordSteps(ctx);
|
|
53
|
+
const preferredStepKeys = ['saveResource', 'submit', 'request', 'apply', 'save'];
|
|
54
|
+
|
|
55
|
+
for (const stepKey of preferredStepKeys) {
|
|
56
|
+
if (Object.prototype.hasOwnProperty.call(steps, stepKey) && steps[stepKey]?.result != null) {
|
|
57
|
+
return steps[stepKey].result;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const results = Object.entries(steps)
|
|
62
|
+
.filter(([stepKey, step]) => stepKey !== 'afterSuccess' && step?.result != null)
|
|
63
|
+
.map(([, step]) => step.result);
|
|
64
|
+
return results[results.length - 1];
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function getResponseRecordMeta(ctx: ResponseRecordContext): PropertyMetaFactory | undefined {
|
|
68
|
+
if (!hasResponseRecordSource(ctx)) {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
const collectionAccessor = getResponseRecordCollectionAccessor(ctx);
|
|
72
|
+
if (!collectionAccessor()) {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
return createRecordMetaFactory(collectionAccessor, ctx.t('Response record'), () => {
|
|
76
|
+
const collection = collectionAccessor();
|
|
77
|
+
const record = getAfterSuccessResponseRecord(ctx);
|
|
78
|
+
if (!collection || !record) {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
try {
|
|
82
|
+
const filterByTk = collection.getFilterByTK(record);
|
|
83
|
+
if (filterByTk == null) {
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
return {
|
|
87
|
+
collection: collection.name,
|
|
88
|
+
dataSourceKey: collection.dataSourceKey || 'main',
|
|
89
|
+
filterByTk,
|
|
90
|
+
};
|
|
91
|
+
} catch (error) {
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function hasResponseRecordSource(ctx: FlowContext | ResponseRecordPlainStepContext) {
|
|
98
|
+
if (Object.prototype.hasOwnProperty.call(getResponseRecordSteps(ctx), 'saveResource')) {
|
|
99
|
+
return true;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const { model, flowKey } = ctx as ResponseRecordFlowDefinitionContext;
|
|
103
|
+
if (!model || typeof model.getFlow !== 'function' || !flowKey) {
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return Object.prototype.hasOwnProperty.call(model.getFlow(flowKey)?.steps || {}, 'saveResource');
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function getResponseRecordCollectionAccessor(ctx: ResponseRecordContext) {
|
|
111
|
+
return () => ctx.blockModel?.collection || ctx.collection || ctx.model?.collection || null;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export function getMetaTreeWithResponseRecord(ctx: FlowRuntimeContext): MetaTreeNode[] {
|
|
115
|
+
const responseRecordMeta = getResponseRecordMeta(ctx);
|
|
116
|
+
if (!responseRecordMeta) {
|
|
117
|
+
return ctx.getPropertyMetaTree?.() || [];
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const scoped = new FlowContext();
|
|
121
|
+
scoped.addDelegate(ctx);
|
|
122
|
+
scoped.defineProperty('responseRecord', {
|
|
123
|
+
get: () => getAfterSuccessResponseRecord(ctx),
|
|
124
|
+
cache: false,
|
|
125
|
+
resolveOnServer: createRecordResolveOnServerWithLocal(getResponseRecordCollectionAccessor(ctx), () =>
|
|
126
|
+
getAfterSuccessResponseRecord(ctx),
|
|
127
|
+
),
|
|
128
|
+
meta: responseRecordMeta,
|
|
129
|
+
});
|
|
130
|
+
return scoped.getPropertyMetaTree();
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function AfterSuccessRedirectTextArea(props: TextAreaWithContextSelectorProps) {
|
|
134
|
+
const flowCtx = useFlowSettingsContext();
|
|
135
|
+
const metaTree = useMemo(() => () => getMetaTreeWithResponseRecord(flowCtx), [flowCtx]);
|
|
136
|
+
|
|
137
|
+
return <TextAreaWithContextSelector {...props} metaTree={metaTree} />;
|
|
138
|
+
}
|
|
13
139
|
|
|
14
140
|
export const afterSuccess = defineAction({
|
|
15
141
|
name: 'afterSuccess',
|
|
16
142
|
title: tExpr('After successful submission'),
|
|
143
|
+
defineProperties(ctx) {
|
|
144
|
+
const responseRecordMeta = getResponseRecordMeta(ctx);
|
|
145
|
+
return {
|
|
146
|
+
responseRecord: {
|
|
147
|
+
get: () => getAfterSuccessResponseRecord(ctx),
|
|
148
|
+
cache: false,
|
|
149
|
+
resolveOnServer: createRecordResolveOnServerWithLocal(getResponseRecordCollectionAccessor(ctx), () =>
|
|
150
|
+
getAfterSuccessResponseRecord(ctx),
|
|
151
|
+
),
|
|
152
|
+
...(responseRecordMeta ? { meta: responseRecordMeta } : {}),
|
|
153
|
+
},
|
|
154
|
+
};
|
|
155
|
+
},
|
|
17
156
|
uiSchema: {
|
|
18
157
|
successMessage: {
|
|
19
158
|
type: 'string',
|
|
@@ -46,7 +185,7 @@ export const afterSuccess = defineAction({
|
|
|
46
185
|
type: 'string',
|
|
47
186
|
title: tExpr('Link'),
|
|
48
187
|
'x-decorator': 'FormItem',
|
|
49
|
-
'x-component':
|
|
188
|
+
'x-component': AfterSuccessRedirectTextArea,
|
|
50
189
|
'x-reactions': {
|
|
51
190
|
dependencies: ['actionAfterSuccess'],
|
|
52
191
|
fulfill: {
|
|
@@ -12,7 +12,6 @@ import {
|
|
|
12
12
|
defineAction,
|
|
13
13
|
isRunJSValue,
|
|
14
14
|
normalizeRunJSValue,
|
|
15
|
-
runjsWithSafeGlobals,
|
|
16
15
|
tExpr,
|
|
17
16
|
type RunJSValue,
|
|
18
17
|
useFlowContext,
|
|
@@ -43,7 +42,7 @@ export const customVariable = defineAction({
|
|
|
43
42
|
if (variable.type === 'runjs') {
|
|
44
43
|
const getFunction = async () => {
|
|
45
44
|
const { code, version } = normalizeRunJSValue(variable.runjs);
|
|
46
|
-
return
|
|
45
|
+
return ctx.runjs(code, undefined, { version });
|
|
47
46
|
};
|
|
48
47
|
const metaFunction = () => ({
|
|
49
48
|
title: variable.title,
|
|
@@ -12,6 +12,12 @@ import { transformFilter } from '@nocobase/utils/client';
|
|
|
12
12
|
import _ from 'lodash';
|
|
13
13
|
|
|
14
14
|
const PRESERVE_NULL = { __nocobaseDataScopeNull__: true };
|
|
15
|
+
const SERVER_CURRENT_ROLE_VARIABLE = '{{$nRole}}';
|
|
16
|
+
const CURRENT_ROLE_EXPRESSION_RE = /^\s*\{\{\s*ctx\.role\s*\}\}\s*$/;
|
|
17
|
+
|
|
18
|
+
function isCurrentRoleExpression(value: unknown) {
|
|
19
|
+
return typeof value === 'string' && CURRENT_ROLE_EXPRESSION_RE.test(value);
|
|
20
|
+
}
|
|
15
21
|
|
|
16
22
|
function isPreserveNull(value: any) {
|
|
17
23
|
return (
|
|
@@ -45,6 +51,10 @@ function markEmptyVariableValues(rawNode: any, resolvedNode: any) {
|
|
|
45
51
|
}
|
|
46
52
|
|
|
47
53
|
if ('path' in rawNode && 'operator' in rawNode) {
|
|
54
|
+
if (isCurrentRoleExpression(rawNode.value)) {
|
|
55
|
+
resolvedNode.value = SERVER_CURRENT_ROLE_VARIABLE;
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
48
58
|
if (
|
|
49
59
|
isVariableExpression(rawNode.value) &&
|
|
50
60
|
(resolvedNode.value === undefined || resolvedNode.value === null || resolvedNode.value === '')
|
|
@@ -11,13 +11,36 @@ import { css } from '@emotion/css';
|
|
|
11
11
|
import { defineAction, tExpr } from '@nocobase/flow-engine';
|
|
12
12
|
import { getPickerFormat } from '@nocobase/utils/client';
|
|
13
13
|
import { DateFormatCom, ExpiresRadio } from '../components';
|
|
14
|
+
import {
|
|
15
|
+
getDateTimeFormatCollectionField,
|
|
16
|
+
isDateOnlyCollectionField,
|
|
17
|
+
isTimeCollectionField,
|
|
18
|
+
resolveDateTimeDisplayProps,
|
|
19
|
+
} from '../utils/dateTimeDisplayProps';
|
|
20
|
+
|
|
21
|
+
const isTableColumnFieldSubModel = (model) => {
|
|
22
|
+
const parent = model?.parent;
|
|
23
|
+
return (
|
|
24
|
+
parent?.subModels?.field === model &&
|
|
25
|
+
(parent?.use === 'TableColumnModel' || parent?.constructor?.name === 'TableColumnModel')
|
|
26
|
+
);
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const syncTableColumnDateTimeFormatProps = (ctx, props) => {
|
|
30
|
+
const model = ctx.model;
|
|
31
|
+
if (!isTableColumnFieldSubModel(model) || !model?.parent?.collectionField?.isAssociationField?.()) {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
model.parent.setProps(props);
|
|
36
|
+
};
|
|
14
37
|
|
|
15
38
|
export const dateTimeFormat = defineAction({
|
|
16
39
|
title: tExpr('Date display format'),
|
|
17
40
|
name: 'dateDisplayFormat',
|
|
18
41
|
uiSchema: (ctx) => {
|
|
19
|
-
const
|
|
20
|
-
const isTimeField = collectionField
|
|
42
|
+
const collectionField = getDateTimeFormatCollectionField({ model: ctx.model });
|
|
43
|
+
const isTimeField = isTimeCollectionField(collectionField);
|
|
21
44
|
const timeFormatField = {
|
|
22
45
|
type: 'string',
|
|
23
46
|
title: '{{t("Time format")}}',
|
|
@@ -43,7 +66,7 @@ export const dateTimeFormat = defineAction({
|
|
|
43
66
|
(field) => {
|
|
44
67
|
if (!isTimeField) {
|
|
45
68
|
const { showTime, picker } = field.form.values || {};
|
|
46
|
-
field.hidden = !showTime || picker !== 'date';
|
|
69
|
+
field.hidden = isDateOnlyCollectionField(collectionField) || !showTime || picker !== 'date';
|
|
47
70
|
}
|
|
48
71
|
},
|
|
49
72
|
],
|
|
@@ -146,10 +169,11 @@ export const dateTimeFormat = defineAction({
|
|
|
146
169
|
},
|
|
147
170
|
},
|
|
148
171
|
(field) => {
|
|
149
|
-
const
|
|
172
|
+
const collectionField = getDateTimeFormatCollectionField({ model: ctx.model });
|
|
150
173
|
const { picker } = field.form.values || {};
|
|
151
|
-
|
|
152
|
-
|
|
174
|
+
const isDateOnlyField = isDateOnlyCollectionField(collectionField);
|
|
175
|
+
field.hidden = isDateOnlyField || picker !== 'date';
|
|
176
|
+
if (isDateOnlyField || picker !== 'date') {
|
|
153
177
|
field.value = false;
|
|
154
178
|
}
|
|
155
179
|
},
|
|
@@ -159,34 +183,24 @@ export const dateTimeFormat = defineAction({
|
|
|
159
183
|
};
|
|
160
184
|
},
|
|
161
185
|
defaultParams: (ctx: any) => {
|
|
162
|
-
const { showTime, dateFormat,
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
};
|
|
166
|
-
const collectionField = ctx.model.context.collectionField;
|
|
167
|
-
const isTimeField = collectionField.type === 'time' || collectionField.interface === 'time';
|
|
186
|
+
const { showTime, dateFormat, timeFormat, picker } = resolveDateTimeDisplayProps({
|
|
187
|
+
model: ctx.model,
|
|
188
|
+
withDefaults: true,
|
|
189
|
+
});
|
|
168
190
|
return {
|
|
169
191
|
picker: picker || 'date',
|
|
170
192
|
dateFormat: dateFormat || 'YYYY-MM-DD',
|
|
171
|
-
timeFormat: timeFormat ||
|
|
193
|
+
timeFormat: timeFormat || 'HH:mm:ss',
|
|
172
194
|
showTime,
|
|
173
195
|
};
|
|
174
196
|
},
|
|
197
|
+
async beforeParamsSave(ctx: any, params) {
|
|
198
|
+
const props = resolveDateTimeDisplayProps({ model: ctx.model, params });
|
|
199
|
+
ctx.model.setProps(props);
|
|
200
|
+
syncTableColumnDateTimeFormatProps(ctx, props);
|
|
201
|
+
await ctx.model.save?.();
|
|
202
|
+
},
|
|
175
203
|
handler(ctx: any, params) {
|
|
176
|
-
|
|
177
|
-
const isTimeField = collectionField.type === 'time' || collectionField.interface === 'time';
|
|
178
|
-
if (isTimeField) {
|
|
179
|
-
const timeFormat = params?.timeFormat || params?.format || 'HH:mm:ss';
|
|
180
|
-
ctx.model.setProps({
|
|
181
|
-
...params,
|
|
182
|
-
timeFormat,
|
|
183
|
-
format: timeFormat,
|
|
184
|
-
});
|
|
185
|
-
} else {
|
|
186
|
-
ctx.model.setProps({
|
|
187
|
-
...params,
|
|
188
|
-
format: params?.showTime ? `${params.dateFormat} ${params.timeFormat}` : params.dateFormat,
|
|
189
|
-
});
|
|
190
|
-
}
|
|
204
|
+
ctx.model.setProps(resolveDateTimeDisplayProps({ model: ctx.model, params }));
|
|
191
205
|
},
|
|
192
206
|
});
|
|
@@ -16,13 +16,9 @@ import {
|
|
|
16
16
|
FlowRuntimeContext,
|
|
17
17
|
useFlowContext,
|
|
18
18
|
useFlowEngine,
|
|
19
|
-
createSafeWindow,
|
|
20
|
-
createSafeDocument,
|
|
21
|
-
createSafeNavigator,
|
|
22
19
|
observer,
|
|
23
20
|
isRunJSValue,
|
|
24
21
|
normalizeRunJSValue,
|
|
25
|
-
runjsWithSafeGlobals,
|
|
26
22
|
} from '@nocobase/flow-engine';
|
|
27
23
|
import { evaluateConditions, FilterGroupType, removeInvalidFilterItems } from '@nocobase/utils/client';
|
|
28
24
|
import React from 'react';
|
|
@@ -40,7 +36,7 @@ import { FilterGroup } from '../components/filter/FilterGroup';
|
|
|
40
36
|
import { LinkageFilterItem } from '../components/filter';
|
|
41
37
|
import { CodeEditor } from '../components/code-editor';
|
|
42
38
|
import { FieldAssignRulesEditor } from '../components/FieldAssignRulesEditor';
|
|
43
|
-
import type { FieldAssignRuleItem } from '../components/FieldAssignRulesEditor';
|
|
39
|
+
import type { AssignMode, FieldAssignRuleItem } from '../components/FieldAssignRulesEditor';
|
|
44
40
|
import { collectFieldAssignCascaderOptions } from '../components/fieldAssignOptions';
|
|
45
41
|
import { useAssociationTitleFieldSync } from '../components/useAssociationTitleFieldSync';
|
|
46
42
|
import _ from 'lodash';
|
|
@@ -492,7 +488,7 @@ async function resolveLinkageAssignRuntimeValue(ctx: FlowContext, rawValue: any)
|
|
|
492
488
|
|
|
493
489
|
try {
|
|
494
490
|
const { code, version } = normalizeRunJSValue(rawValue);
|
|
495
|
-
const ret = await
|
|
491
|
+
const ret = await ctx.runjs(code, undefined, { version });
|
|
496
492
|
if (!ret?.success) {
|
|
497
493
|
return SKIP_RUNJS_ASSIGN_VALUE;
|
|
498
494
|
}
|
|
@@ -888,6 +884,20 @@ type ArrayFieldComponentProps = {
|
|
|
888
884
|
|
|
889
885
|
const LEGACY_ASSIGN_RULE = { mode: 'assign', valueKey: 'assignValue' } as const;
|
|
890
886
|
const LEGACY_DEFAULT_RULE = { mode: 'default', valueKey: 'initialValue' } as const;
|
|
887
|
+
const LINKAGE_ASSIGN_MODE_PROP = '__linkageAssignMode';
|
|
888
|
+
|
|
889
|
+
function normalizeLinkageAssignMode(mode: unknown): AssignMode {
|
|
890
|
+
if (mode === 'default') return 'default';
|
|
891
|
+
if (mode === 'override') return 'override';
|
|
892
|
+
return 'assign';
|
|
893
|
+
}
|
|
894
|
+
|
|
895
|
+
type LinkageValuePatch = {
|
|
896
|
+
path: Array<string | number>;
|
|
897
|
+
value: unknown;
|
|
898
|
+
whenEmpty?: boolean;
|
|
899
|
+
mode?: AssignMode;
|
|
900
|
+
};
|
|
891
901
|
|
|
892
902
|
const FieldAssignRulesActionComponent: React.FC<
|
|
893
903
|
ArrayFieldComponentProps & {
|
|
@@ -1002,16 +1012,24 @@ export const linkageAssignField = defineAction({
|
|
|
1002
1012
|
continue;
|
|
1003
1013
|
}
|
|
1004
1014
|
|
|
1005
|
-
const mode = it?.mode
|
|
1015
|
+
const mode = normalizeLinkageAssignMode(it?.mode);
|
|
1006
1016
|
if (fieldModel) {
|
|
1007
1017
|
if (mode === 'default') {
|
|
1008
1018
|
setProps(fieldModel as FlowModel, { initialValue: finalValue });
|
|
1009
1019
|
} else {
|
|
1010
|
-
setProps(fieldModel as FlowModel, {
|
|
1020
|
+
setProps(fieldModel as FlowModel, {
|
|
1021
|
+
value: finalValue,
|
|
1022
|
+
...(mode === 'override' ? { [LINKAGE_ASSIGN_MODE_PROP]: mode } : {}),
|
|
1023
|
+
});
|
|
1011
1024
|
}
|
|
1012
1025
|
} else if (typeof addFormValuePatch === 'function') {
|
|
1013
1026
|
// 对关联字段子属性(如 user.name)等没有独立 FormItemModel 的目标,直接写入表单值
|
|
1014
|
-
addFormValuePatch({
|
|
1027
|
+
addFormValuePatch({
|
|
1028
|
+
path: targetPath,
|
|
1029
|
+
value: finalValue,
|
|
1030
|
+
whenEmpty: mode === 'default',
|
|
1031
|
+
...(mode === 'override' ? { mode } : {}),
|
|
1032
|
+
});
|
|
1015
1033
|
}
|
|
1016
1034
|
}
|
|
1017
1035
|
} catch (error) {
|
|
@@ -1177,7 +1195,7 @@ export const subFormLinkageAssignField = defineAction({
|
|
|
1177
1195
|
continue;
|
|
1178
1196
|
}
|
|
1179
1197
|
|
|
1180
|
-
const mode = it?.mode
|
|
1198
|
+
const mode = normalizeLinkageAssignMode(it?.mode);
|
|
1181
1199
|
const actionName = (ctx.model as any)?.getAclActionName?.() ?? (ctx.model as any)?.context?.actionName;
|
|
1182
1200
|
const isEditForm = actionName === 'update';
|
|
1183
1201
|
const isNewItem = (ctx as any)?.item?.__is_new__ === true;
|
|
@@ -1207,12 +1225,21 @@ export const subFormLinkageAssignField = defineAction({
|
|
|
1207
1225
|
continue;
|
|
1208
1226
|
}
|
|
1209
1227
|
|
|
1228
|
+
if (mode === 'override' && hasExplicitPathHit(targetPath)) {
|
|
1229
|
+
continue;
|
|
1230
|
+
}
|
|
1231
|
+
|
|
1210
1232
|
if (!fieldUid) {
|
|
1211
1233
|
if (mode === 'default' && hasExplicitPathHit(targetPath)) {
|
|
1212
1234
|
continue;
|
|
1213
1235
|
}
|
|
1214
1236
|
if (typeof addFormValuePatch === 'function') {
|
|
1215
|
-
addFormValuePatch({
|
|
1237
|
+
addFormValuePatch({
|
|
1238
|
+
path: targetPath,
|
|
1239
|
+
value: finalValue,
|
|
1240
|
+
whenEmpty: mode === 'default',
|
|
1241
|
+
...(mode === 'override' ? { mode } : {}),
|
|
1242
|
+
});
|
|
1216
1243
|
}
|
|
1217
1244
|
continue;
|
|
1218
1245
|
}
|
|
@@ -1223,7 +1250,10 @@ export const subFormLinkageAssignField = defineAction({
|
|
|
1223
1250
|
if (mode === 'default') {
|
|
1224
1251
|
setProps(model, { initialValue: finalValue });
|
|
1225
1252
|
} else {
|
|
1226
|
-
setProps(model, {
|
|
1253
|
+
setProps(model, {
|
|
1254
|
+
value: finalValue,
|
|
1255
|
+
...(mode === 'override' ? { [LINKAGE_ASSIGN_MODE_PROP]: mode } : {}),
|
|
1256
|
+
});
|
|
1227
1257
|
}
|
|
1228
1258
|
}
|
|
1229
1259
|
} catch (error) {
|
|
@@ -1363,8 +1393,7 @@ export const linkageRunjs = defineAction({
|
|
|
1363
1393
|
}
|
|
1364
1394
|
|
|
1365
1395
|
try {
|
|
1366
|
-
|
|
1367
|
-
await ctx.runjs(script, { window: createSafeWindow({ navigator }), document: createSafeDocument(), navigator });
|
|
1396
|
+
await ctx.runjs(script);
|
|
1368
1397
|
} catch (error) {
|
|
1369
1398
|
console.error('Script execution error:', error);
|
|
1370
1399
|
// 可以选择显示错误信息给用户
|
|
@@ -1781,7 +1810,7 @@ const commonLinkageRulesHandler = async (ctx: FlowContext, params: any) => {
|
|
|
1781
1810
|
const modelsToApply = new Set<FlowModel>(allModels);
|
|
1782
1811
|
const patchPropsByModel = new Map<FlowModel, any>();
|
|
1783
1812
|
const clearValueOnHiddenModelUids = new Set<string>();
|
|
1784
|
-
const directValuePatches:
|
|
1813
|
+
const directValuePatches: LinkageValuePatch[] = [];
|
|
1785
1814
|
const rootCollection = getCollectionFromModel((ctx.model as any)?.context?.blockModel ?? ctx.model);
|
|
1786
1815
|
const isSafeToWriteAssociationSubpath = (namePath: any): boolean => {
|
|
1787
1816
|
if (!Array.isArray(namePath) || !namePath.length) return true;
|
|
@@ -1836,13 +1865,18 @@ const commonLinkageRulesHandler = async (ctx: FlowContext, params: any) => {
|
|
|
1836
1865
|
}
|
|
1837
1866
|
|
|
1838
1867
|
for (const patch of lastPatchByPathKey.values()) {
|
|
1839
|
-
if (!patch.whenEmpty) continue;
|
|
1868
|
+
if (!patch.whenEmpty && patch.mode !== 'default') continue;
|
|
1840
1869
|
runtime.recordDefaultValuePatch(patch.path, patch.value);
|
|
1841
1870
|
}
|
|
1842
1871
|
};
|
|
1843
|
-
const
|
|
1872
|
+
const getPatchMode = (patch: { mode?: unknown; whenEmpty?: boolean }): AssignMode => {
|
|
1873
|
+
if (patch?.mode === 'default') return 'default';
|
|
1874
|
+
if (patch?.mode === 'override') return 'override';
|
|
1875
|
+
return patch?.whenEmpty ? 'default' : 'assign';
|
|
1876
|
+
};
|
|
1877
|
+
const addFormValuePatch = (patch: { path: unknown; value: unknown; whenEmpty?: boolean; mode?: AssignMode }) => {
|
|
1844
1878
|
if (!patch) return;
|
|
1845
|
-
const path =
|
|
1879
|
+
const path = patch.path;
|
|
1846
1880
|
if (!path) return;
|
|
1847
1881
|
const resolvedPath = resolveNamePathForPatch(path);
|
|
1848
1882
|
if (!resolvedPath) {
|
|
@@ -1862,8 +1896,9 @@ const commonLinkageRulesHandler = async (ctx: FlowContext, params: any) => {
|
|
|
1862
1896
|
});
|
|
1863
1897
|
return;
|
|
1864
1898
|
}
|
|
1865
|
-
const
|
|
1866
|
-
const
|
|
1899
|
+
const mode = getPatchMode(patch);
|
|
1900
|
+
const whenEmpty = mode === 'default';
|
|
1901
|
+
const value = patch.value;
|
|
1867
1902
|
try {
|
|
1868
1903
|
const form = ctx.model?.context?.form;
|
|
1869
1904
|
const current = form?.getFieldValue?.(resolvedPath);
|
|
@@ -1878,6 +1913,15 @@ const commonLinkageRulesHandler = async (ctx: FlowContext, params: any) => {
|
|
|
1878
1913
|
return;
|
|
1879
1914
|
}
|
|
1880
1915
|
}
|
|
1916
|
+
if (mode === 'override') {
|
|
1917
|
+
const runtime = getDefaultPatchRuntime();
|
|
1918
|
+
if (
|
|
1919
|
+
typeof runtime?.canApplyOverrideValuePatch === 'function' &&
|
|
1920
|
+
!runtime.canApplyOverrideValuePatch(resolvedPath)
|
|
1921
|
+
) {
|
|
1922
|
+
return;
|
|
1923
|
+
}
|
|
1924
|
+
}
|
|
1881
1925
|
if (_.isEqual(current, value)) {
|
|
1882
1926
|
return;
|
|
1883
1927
|
}
|
|
@@ -1889,6 +1933,7 @@ const commonLinkageRulesHandler = async (ctx: FlowContext, params: any) => {
|
|
|
1889
1933
|
path: resolvedPath,
|
|
1890
1934
|
value,
|
|
1891
1935
|
...(whenEmpty ? { whenEmpty: true } : {}),
|
|
1936
|
+
...(mode === 'override' ? { mode } : {}),
|
|
1892
1937
|
});
|
|
1893
1938
|
};
|
|
1894
1939
|
const removePendingFormValuePatches = (path: any) => {
|
|
@@ -1948,6 +1993,21 @@ const commonLinkageRulesHandler = async (ctx: FlowContext, params: any) => {
|
|
|
1948
1993
|
>;
|
|
1949
1994
|
return normalized.length ? normalized : null;
|
|
1950
1995
|
};
|
|
1996
|
+
const pathKeysEqual = (
|
|
1997
|
+
a: Array<string | number> | null | undefined,
|
|
1998
|
+
b: Array<string | number> | null | undefined,
|
|
1999
|
+
) => {
|
|
2000
|
+
if (!a || !b) return false;
|
|
2001
|
+
return namePathToPathKey(a) === namePathToPathKey(b);
|
|
2002
|
+
};
|
|
2003
|
+
const namePathEndsWith = (
|
|
2004
|
+
namePath: Array<string | number> | null | undefined,
|
|
2005
|
+
suffix: Array<string | number> | null | undefined,
|
|
2006
|
+
) => {
|
|
2007
|
+
if (!namePath || !suffix || suffix.length > namePath.length) return false;
|
|
2008
|
+
const offset = namePath.length - suffix.length;
|
|
2009
|
+
return suffix.every((seg, index) => namePath[offset + index] === seg);
|
|
2010
|
+
};
|
|
1951
2011
|
const getFieldIndexEntries = (fieldIndex: any): Array<{ name: string; index: number }> => {
|
|
1952
2012
|
if (!Array.isArray(fieldIndex)) return [];
|
|
1953
2013
|
return fieldIndex
|
|
@@ -1996,17 +2056,35 @@ const commonLinkageRulesHandler = async (ctx: FlowContext, params: any) => {
|
|
|
1996
2056
|
|
|
1997
2057
|
return out;
|
|
1998
2058
|
};
|
|
2059
|
+
const getTrustedFieldPathArray = (
|
|
2060
|
+
fieldPathArray: Array<string | number> | null,
|
|
2061
|
+
targetPath: string | null,
|
|
2062
|
+
fieldIndex: unknown,
|
|
2063
|
+
): Array<string | number> | null => {
|
|
2064
|
+
if (!fieldPathArray || !targetPath) return null;
|
|
2065
|
+
|
|
2066
|
+
const targetNamePath = normalizeNamePathForKey(
|
|
2067
|
+
parsePathString(targetPath).filter((seg) => typeof seg === 'string' || typeof seg === 'number'),
|
|
2068
|
+
);
|
|
2069
|
+
const resolvedTargetPath = normalizeNamePathForKey(resolveDynamicNamePath(targetPath, fieldIndex));
|
|
2070
|
+
const indexedRelativePath = resolveIndexedRelativePath(targetPath, fieldIndex);
|
|
2071
|
+
|
|
2072
|
+
if (
|
|
2073
|
+
pathKeysEqual(fieldPathArray, resolvedTargetPath) ||
|
|
2074
|
+
pathKeysEqual(fieldPathArray, indexedRelativePath) ||
|
|
2075
|
+
namePathEndsWith(fieldPathArray, targetNamePath)
|
|
2076
|
+
) {
|
|
2077
|
+
return fieldPathArray;
|
|
2078
|
+
}
|
|
2079
|
+
|
|
2080
|
+
return null;
|
|
2081
|
+
};
|
|
1999
2082
|
const getModelTargetPathForHiddenClear = (model: any): string | Array<string | number> | null => {
|
|
2000
2083
|
const fieldPathArray = normalizeNamePathForKey(model?.context?.fieldPathArray);
|
|
2001
2084
|
const targetPath = getModelTargetPathForPatch(model);
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
: undefined;
|
|
2006
|
-
const fieldPathArrayLastString = [...fieldPathArray].reverse().find((seg) => typeof seg === 'string');
|
|
2007
|
-
if (!targetPathLastString || targetPathLastString === fieldPathArrayLastString) {
|
|
2008
|
-
return fieldPathArray;
|
|
2009
|
-
}
|
|
2085
|
+
const trustedFieldPathArray = getTrustedFieldPathArray(fieldPathArray, targetPath, model?.context?.fieldIndex);
|
|
2086
|
+
if (trustedFieldPathArray) {
|
|
2087
|
+
return trustedFieldPathArray;
|
|
2010
2088
|
}
|
|
2011
2089
|
|
|
2012
2090
|
if (!targetPath) return null;
|
|
@@ -2016,12 +2094,13 @@ const commonLinkageRulesHandler = async (ctx: FlowContext, params: any) => {
|
|
|
2016
2094
|
const getModelTargetPathKeys = (model: any): Set<string> => {
|
|
2017
2095
|
const keys = new Set<string>();
|
|
2018
2096
|
const fieldPathArray = normalizeNamePathForKey(model?.context?.fieldPathArray);
|
|
2019
|
-
|
|
2020
|
-
|
|
2097
|
+
const targetPath = getModelTargetPathForPatch(model);
|
|
2098
|
+
const trustedFieldPathArray = getTrustedFieldPathArray(fieldPathArray, targetPath, model?.context?.fieldIndex);
|
|
2099
|
+
if (trustedFieldPathArray) {
|
|
2100
|
+
keys.add(namePathToPathKey(trustedFieldPathArray));
|
|
2021
2101
|
return keys;
|
|
2022
2102
|
}
|
|
2023
2103
|
|
|
2024
|
-
const targetPath = getModelTargetPathForPatch(model);
|
|
2025
2104
|
if (targetPath) {
|
|
2026
2105
|
const fieldIndexEntries = getFieldIndexEntries(model?.context?.fieldIndex);
|
|
2027
2106
|
if (!fieldIndexEntries.length) {
|
|
@@ -2082,6 +2161,14 @@ const commonLinkageRulesHandler = async (ctx: FlowContext, params: any) => {
|
|
|
2082
2161
|
|
|
2083
2162
|
for (const action of actions) {
|
|
2084
2163
|
const setProps = (model: FlowModel & { __originalProps?: any; __shouldReset?: boolean }, props: any) => {
|
|
2164
|
+
const normalizedProps =
|
|
2165
|
+
props && typeof props === 'object' && Object.prototype.hasOwnProperty.call(props, 'value')
|
|
2166
|
+
? {
|
|
2167
|
+
...props,
|
|
2168
|
+
[LINKAGE_ASSIGN_MODE_PROP]: normalizeLinkageAssignMode(props?.[LINKAGE_ASSIGN_MODE_PROP]),
|
|
2169
|
+
}
|
|
2170
|
+
: props;
|
|
2171
|
+
|
|
2085
2172
|
// 存储原始值,用于恢复
|
|
2086
2173
|
if (!model.__originalProps) {
|
|
2087
2174
|
model.__originalProps = {
|
|
@@ -2097,7 +2184,7 @@ const commonLinkageRulesHandler = async (ctx: FlowContext, params: any) => {
|
|
|
2097
2184
|
// 临时存起来,遍历完所有规则后,再统一处理
|
|
2098
2185
|
patchPropsByModel.set(model, {
|
|
2099
2186
|
...(patchPropsByModel.get(model) || {}),
|
|
2100
|
-
...
|
|
2187
|
+
...normalizedProps,
|
|
2101
2188
|
});
|
|
2102
2189
|
|
|
2103
2190
|
if (
|
|
@@ -2151,7 +2238,7 @@ const commonLinkageRulesHandler = async (ctx: FlowContext, params: any) => {
|
|
|
2151
2238
|
const prevHidden = !!model.hidden;
|
|
2152
2239
|
const nextHidden = !!newProps.hiddenModel;
|
|
2153
2240
|
|
|
2154
|
-
model.setProps(_.omit(newProps, ['hiddenModel', 'value', 'hiddenText']));
|
|
2241
|
+
model.setProps(_.omit(newProps, ['hiddenModel', 'value', 'hiddenText', LINKAGE_ASSIGN_MODE_PROP]));
|
|
2155
2242
|
syncFieldOptionsToForks(model, patchProps);
|
|
2156
2243
|
if (typeof model.setHidden === 'function') {
|
|
2157
2244
|
model.setHidden(nextHidden);
|
|
@@ -2190,7 +2277,8 @@ const commonLinkageRulesHandler = async (ctx: FlowContext, params: any) => {
|
|
|
2190
2277
|
targetUid: model?.uid,
|
|
2191
2278
|
});
|
|
2192
2279
|
} else {
|
|
2193
|
-
|
|
2280
|
+
const mode = normalizeLinkageAssignMode(patchProps?.[LINKAGE_ASSIGN_MODE_PROP]);
|
|
2281
|
+
addFormValuePatch({ path: targetPath, value: newProps.value, ...(mode === 'override' ? { mode } : {}) });
|
|
2194
2282
|
}
|
|
2195
2283
|
}
|
|
2196
2284
|
|
|
@@ -2842,7 +2930,7 @@ export const subFormFieldLinkageRules = defineAction({
|
|
|
2842
2930
|
}
|
|
2843
2931
|
} else {
|
|
2844
2932
|
await Promise.all(
|
|
2845
|
-
(grid.forks || []).map(async (forkModel: FlowModel) => {
|
|
2933
|
+
Array.from(grid.forks || []).map(async (forkModel: FlowModel) => {
|
|
2846
2934
|
if (forkModel.hidden) {
|
|
2847
2935
|
return;
|
|
2848
2936
|
}
|