@nocobase/client-v2 2.2.0-beta.3 → 2.2.0-beta.6
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/RouteRepository.d.ts +21 -6
- package/es/components/form/JsonTextArea.d.ts +2 -1
- package/es/components/form/VariableJsonTextArea.d.ts +19 -0
- package/es/components/form/index.d.ts +1 -0
- package/es/components/index.d.ts +1 -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 +2 -0
- package/es/flow/admin-shell/admin-layout/AdminLayoutMenuUtils.d.ts +3 -2
- package/es/flow/admin-shell/admin-layout/AdminLayoutSlotModels.d.ts +4 -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/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/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/fields/AssociationFieldModel/RecordSelectFieldModel.d.ts +2 -0
- package/es/flow/models/fields/AssociationFieldModel/SubTableFieldModel/SubTableColumnModel.d.ts +1 -0
- package/es/flow/utils/dateTimeDisplayProps.d.ts +49 -0
- package/es/flow-compat/FieldValidation.d.ts +2 -1
- package/es/index.d.ts +2 -1
- package/es/index.mjs +167 -121
- package/lib/index.js +167 -121
- package/package.json +7 -7
- package/src/RouteRepository.ts +126 -24
- package/src/__tests__/RouteRepository.test.ts +216 -0
- package/src/__tests__/exports.test.ts +16 -0
- package/src/__tests__/settings-center.test.tsx +33 -0
- package/src/components/form/JsonTextArea.tsx +21 -11
- package/src/components/form/VariableJsonTextArea.tsx +175 -0
- package/src/components/form/__tests__/JsonTextArea.test.tsx +43 -0
- package/src/components/form/__tests__/VariableJsonTextArea.test.tsx +86 -0
- package/src/components/form/index.tsx +1 -0
- package/src/components/index.ts +1 -0
- package/src/flow/__tests__/FlowRoute.test.tsx +443 -5
- 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/customVariable.tsx +1 -2
- package/src/flow/actions/dateTimeFormat.tsx +42 -28
- package/src/flow/actions/linkageRules.tsx +122 -34
- package/src/flow/actions/runjs.tsx +2 -14
- package/src/flow/actions/validation.tsx +62 -30
- package/src/flow/admin-shell/admin-layout/AdminLayoutComponent.tsx +33 -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 +21 -8
- 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__/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 +62 -12
- 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 +81 -4
- 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/flows/editMarkdownFlow.tsx +1 -1
- package/src/flow/index.ts +1 -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-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/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/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 +1 -1
- package/src/flow/models/blocks/table/TableBlockModel.tsx +13 -3
- package/src/flow/models/blocks/table/TableColumnModel.tsx +36 -3
- package/src/flow/models/blocks/table/__tests__/TableActionsColumnModel.test.tsx +54 -0
- package/src/flow/models/blocks/table/__tests__/TableBlockModel.mobileSettingsButtons.test.tsx +78 -0
- package/src/flow/models/blocks/table/__tests__/TableColumnModel.test.tsx +159 -1
- 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 +24 -1
- package/src/flow/models/fields/AssociationFieldModel/SubTableFieldModel/SubTableField.tsx +13 -1
- package/src/flow/models/fields/AssociationFieldModel/SubTableFieldModel/__tests__/SubTableColumnModel.rowRecord.test.ts +12 -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 +14 -22
- 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/__tests__/DisplayDateTimeFieldModel.test.tsx +96 -0
- package/src/flow/models/fields/__tests__/InputFieldModel.test.tsx +17 -0
- package/src/flow/models/fields/__tests__/SelectFieldModel.test.tsx +43 -0
- package/src/flow/models/topbar/TopbarActionModel.tsx +93 -10
- package/src/flow/utils/__tests__/dateTimeFormat.test.ts +258 -0
- package/src/flow/utils/dateTimeDisplayProps.ts +135 -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/settings-center/AdminSettingsLayout.tsx +3 -0
- package/src/settings-center/plugin-manager/index.tsx +3 -0
|
@@ -44,6 +44,7 @@ export class FormValueRuntime {
|
|
|
44
44
|
|
|
45
45
|
private readonly valuesMirror = observable({});
|
|
46
46
|
private readonly explicitSet = new Set<string>();
|
|
47
|
+
private readonly userEditedSet = new Set<string>();
|
|
47
48
|
private readonly lastDefaultValueByPathKey = new Map<string, any>();
|
|
48
49
|
private readonly lastWriteMetaByPathKey = new Map<string, FormValueWriteMeta>();
|
|
49
50
|
private readonly observableBindings = new Map<string, ObservableBinding>();
|
|
@@ -59,6 +60,8 @@ export class FormValueRuntime {
|
|
|
59
60
|
private lastObservedToken = 0;
|
|
60
61
|
|
|
61
62
|
private readonly formValuesProxy: any;
|
|
63
|
+
private readonly mountedFieldModelsByPathKey = new Map<string, Set<FlowModel>>();
|
|
64
|
+
private readonly mountedFieldModelPathKeys = new WeakMap<FlowModel, Set<string>>();
|
|
62
65
|
|
|
63
66
|
private mountedListener?: (payload: { model: FlowModel }) => void;
|
|
64
67
|
private unmountedListener?: (payload: { model: FlowModel }) => void;
|
|
@@ -99,6 +102,7 @@ export class FormValueRuntime {
|
|
|
99
102
|
getFormValueAtPath: (namePath) => this.getFormValueAtPath(namePath),
|
|
100
103
|
setFormValues: (callerCtx, patch, ruleOptions) => this.setFormValues(callerCtx, patch, ruleOptions),
|
|
101
104
|
findExplicitHit: (pathKey) => this.findExplicitHit(pathKey),
|
|
105
|
+
findUserEditedHit: (pathKey) => this.findUserEditedHit(pathKey),
|
|
102
106
|
lastDefaultValueByPathKey: this.lastDefaultValueByPathKey,
|
|
103
107
|
lastWriteMetaByPathKey: this.lastWriteMetaByPathKey,
|
|
104
108
|
observableBindings: this.observableBindings,
|
|
@@ -117,6 +121,7 @@ export class FormValueRuntime {
|
|
|
117
121
|
*
|
|
118
122
|
* - mode=default → source=default(遵循 explicit/空值覆盖语义)
|
|
119
123
|
* - mode=assign → source=system(不受 explicit 影响,依赖变化时持续生效)
|
|
124
|
+
* - mode=override → source=override(首次覆盖已有值,用户修改后停止)
|
|
120
125
|
*/
|
|
121
126
|
syncAssignRules(items: FormAssignRuleItem[]) {
|
|
122
127
|
this.ruleEngine.syncAssignRules(items);
|
|
@@ -137,6 +142,15 @@ export class FormValueRuntime {
|
|
|
137
142
|
return this.getForm().getFieldsValue(true);
|
|
138
143
|
}
|
|
139
144
|
|
|
145
|
+
private toMirrorSnapshot(value: any) {
|
|
146
|
+
const raw = isObservable(value) ? toJS(value) : value;
|
|
147
|
+
return _.cloneDeepWith(raw, (item) => {
|
|
148
|
+
if (!item || typeof item !== 'object') return undefined;
|
|
149
|
+
if (Array.isArray(item) || _.isPlainObject(item)) return undefined;
|
|
150
|
+
return item;
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
|
|
140
154
|
canApplyDefaultValuePatch(namePath: NamePath, resolved: any) {
|
|
141
155
|
if (!namePath?.length) return false;
|
|
142
156
|
if (typeof resolved === 'undefined') return false;
|
|
@@ -153,19 +167,24 @@ export class FormValueRuntime {
|
|
|
153
167
|
|
|
154
168
|
const canOverwrite = isEmptyValue(current) || currentEqualsLastDefault;
|
|
155
169
|
if (!canOverwrite && _.isEqual(current, nextSnapshot)) {
|
|
156
|
-
this.lastDefaultValueByPathKey.set(pathKey, nextSnapshot);
|
|
170
|
+
this.lastDefaultValueByPathKey.set(pathKey, this.toMirrorSnapshot(nextSnapshot));
|
|
157
171
|
return false;
|
|
158
172
|
}
|
|
159
173
|
|
|
160
174
|
return canOverwrite;
|
|
161
175
|
}
|
|
162
176
|
|
|
177
|
+
canApplyOverrideValuePatch(namePath: NamePath) {
|
|
178
|
+
if (!namePath?.length) return false;
|
|
179
|
+
return !this.findUserEditedHit(namePathToPathKey(namePath));
|
|
180
|
+
}
|
|
181
|
+
|
|
163
182
|
recordDefaultValuePatch(namePath: NamePath, value?: any) {
|
|
164
183
|
if (!namePath?.length) return;
|
|
165
184
|
const pathKey = namePathToPathKey(namePath);
|
|
166
185
|
const snapshot =
|
|
167
186
|
arguments.length >= 2 ? (isObservable(value) ? toJS(value) : value) : this.getFormValueAtPath(namePath);
|
|
168
|
-
this.lastDefaultValueByPathKey.set(pathKey, snapshot);
|
|
187
|
+
this.lastDefaultValueByPathKey.set(pathKey, this.toMirrorSnapshot(snapshot));
|
|
169
188
|
const current = this.getFormValueAtPath(namePath);
|
|
170
189
|
const currentSnapshot = isObservable(current) ? toJS(current) : current;
|
|
171
190
|
if (_.isEqual(currentSnapshot, snapshot)) {
|
|
@@ -195,9 +214,11 @@ export class FormValueRuntime {
|
|
|
195
214
|
|
|
196
215
|
if (!this.mountedListener && !this.unmountedListener) {
|
|
197
216
|
this.mountedListener = ({ model }: { model: FlowModel }) => {
|
|
217
|
+
this.indexMountedFieldModelTree(model);
|
|
198
218
|
this.ruleEngine.onModelMounted(model);
|
|
199
219
|
};
|
|
200
220
|
this.unmountedListener = ({ model }: { model: FlowModel }) => {
|
|
221
|
+
this.unindexMountedFieldModelTree(model);
|
|
201
222
|
this.ruleEngine.onModelUnmounted(model);
|
|
202
223
|
};
|
|
203
224
|
|
|
@@ -205,10 +226,12 @@ export class FormValueRuntime {
|
|
|
205
226
|
engineEmitter.on('model:unmounted', this.unmountedListener);
|
|
206
227
|
}
|
|
207
228
|
|
|
229
|
+
this.rebuildMountedFieldModelIndex();
|
|
230
|
+
|
|
208
231
|
if (options?.sync) {
|
|
209
232
|
const snapshot = this.getFormValuesSnapshot();
|
|
210
233
|
if (snapshot && typeof snapshot === 'object') {
|
|
211
|
-
_.merge(this.valuesMirror, snapshot);
|
|
234
|
+
_.merge(this.valuesMirror, this.toMirrorSnapshot(snapshot));
|
|
212
235
|
this.bumpChangeTick();
|
|
213
236
|
}
|
|
214
237
|
this.ruleEngine.enable();
|
|
@@ -228,6 +251,7 @@ export class FormValueRuntime {
|
|
|
228
251
|
}
|
|
229
252
|
|
|
230
253
|
this.ruleEngine.dispose();
|
|
254
|
+
this.mountedFieldModelsByPathKey.clear();
|
|
231
255
|
|
|
232
256
|
for (const binding of this.observableBindings.values()) {
|
|
233
257
|
binding.dispose();
|
|
@@ -241,6 +265,7 @@ export class FormValueRuntime {
|
|
|
241
265
|
if (this.disposed) return;
|
|
242
266
|
|
|
243
267
|
this.explicitSet.clear();
|
|
268
|
+
this.userEditedSet.clear();
|
|
244
269
|
this.lastDefaultValueByPathKey.clear();
|
|
245
270
|
this.lastWriteMetaByPathKey.clear();
|
|
246
271
|
this.txWriteCounts.clear();
|
|
@@ -258,7 +283,7 @@ export class FormValueRuntime {
|
|
|
258
283
|
delete (this.valuesMirror as Record<string, any>)[key];
|
|
259
284
|
}
|
|
260
285
|
if (snapshot && typeof snapshot === 'object') {
|
|
261
|
-
_.merge(this.valuesMirror, snapshot);
|
|
286
|
+
_.merge(this.valuesMirror, this.toMirrorSnapshot(snapshot));
|
|
262
287
|
}
|
|
263
288
|
|
|
264
289
|
this.writeSeq += 1;
|
|
@@ -266,6 +291,13 @@ export class FormValueRuntime {
|
|
|
266
291
|
this.ruleEngine.rescheduleAllRules();
|
|
267
292
|
}
|
|
268
293
|
|
|
294
|
+
resetUserEditedState() {
|
|
295
|
+
if (this.disposed) return;
|
|
296
|
+
|
|
297
|
+
this.userEditedSet.clear();
|
|
298
|
+
this.ruleEngine.rescheduleAllRules();
|
|
299
|
+
}
|
|
300
|
+
|
|
269
301
|
isSuppressed() {
|
|
270
302
|
return this.suppressFormCallbackDepth > 0;
|
|
271
303
|
}
|
|
@@ -292,7 +324,7 @@ export class FormValueRuntime {
|
|
|
292
324
|
this.writeSeq += 1;
|
|
293
325
|
bumpedWriteSeq = true;
|
|
294
326
|
}
|
|
295
|
-
_.set(this.valuesMirror, namePath, nextValue);
|
|
327
|
+
_.set(this.valuesMirror, namePath, this.toMirrorSnapshot(nextValue));
|
|
296
328
|
changedPaths.push(namePath);
|
|
297
329
|
const isMeaningfulTouched =
|
|
298
330
|
field?.touched === true && !this.shouldIgnoreSyntheticTouchedInit(namePath, prevValue, nextValue);
|
|
@@ -311,6 +343,7 @@ export class FormValueRuntime {
|
|
|
311
343
|
if (!suppressed && touchedChangedPathKeys.size) {
|
|
312
344
|
for (const key of touchedChangedPathKeys) {
|
|
313
345
|
this.markExplicit(key);
|
|
346
|
+
this.markUserEdited(key);
|
|
314
347
|
}
|
|
315
348
|
}
|
|
316
349
|
|
|
@@ -374,6 +407,11 @@ export class FormValueRuntime {
|
|
|
374
407
|
this.explicitSet.delete(key);
|
|
375
408
|
}
|
|
376
409
|
|
|
410
|
+
for (const key of Array.from(this.userEditedSet)) {
|
|
411
|
+
if (!this.isDeletedArrayItemPath(key, snapshot)) continue;
|
|
412
|
+
this.userEditedSet.delete(key);
|
|
413
|
+
}
|
|
414
|
+
|
|
377
415
|
for (const key of Array.from(this.lastDefaultValueByPathKey.keys())) {
|
|
378
416
|
if (!this.isDeletedArrayItemPath(key, snapshot)) continue;
|
|
379
417
|
this.lastDefaultValueByPathKey.delete(key);
|
|
@@ -444,6 +482,7 @@ export class FormValueRuntime {
|
|
|
444
482
|
if (!nextIndexByIdentity.size) continue;
|
|
445
483
|
|
|
446
484
|
this.reconcileArrayItemSet(this.explicitSet, path, prevValue, nextIndexByIdentity);
|
|
485
|
+
this.reconcileArrayItemSet(this.userEditedSet, path, prevValue, nextIndexByIdentity);
|
|
447
486
|
this.reconcileArrayItemMap(this.lastDefaultValueByPathKey, path, prevValue, nextIndexByIdentity);
|
|
448
487
|
this.reconcileArrayItemMap(this.lastWriteMetaByPathKey, path, prevValue, nextIndexByIdentity);
|
|
449
488
|
this.reconcileObservableBindings(path, prevValue, nextIndexByIdentity);
|
|
@@ -647,7 +686,7 @@ export class FormValueRuntime {
|
|
|
647
686
|
this.writeSeq += 1;
|
|
648
687
|
bumpedWriteSeq = true;
|
|
649
688
|
}
|
|
650
|
-
_.set(this.valuesMirror, p, nextValue);
|
|
689
|
+
_.set(this.valuesMirror, p, this.toMirrorSnapshot(nextValue));
|
|
651
690
|
hasMirrorChange = true;
|
|
652
691
|
actuallyChangedPaths.push(p);
|
|
653
692
|
}
|
|
@@ -665,7 +704,11 @@ export class FormValueRuntime {
|
|
|
665
704
|
|
|
666
705
|
// 非 default 来源写入:需要使默认值永久失效(explicit)
|
|
667
706
|
for (const p of explicitPathsToMark) {
|
|
668
|
-
|
|
707
|
+
const pathKey = namePathToPathKey(p);
|
|
708
|
+
this.markExplicit(pathKey);
|
|
709
|
+
if (source === 'user') {
|
|
710
|
+
this.markUserEdited(pathKey);
|
|
711
|
+
}
|
|
669
712
|
}
|
|
670
713
|
|
|
671
714
|
if (hasMirrorChange) {
|
|
@@ -726,6 +769,9 @@ export class FormValueRuntime {
|
|
|
726
769
|
seen,
|
|
727
770
|
);
|
|
728
771
|
}
|
|
772
|
+
if (prevValue.length !== nextValue.length) {
|
|
773
|
+
return nestedCount + (this.pushExplicitPath(basePath, explicitPaths, seen) ? 1 : 0);
|
|
774
|
+
}
|
|
729
775
|
return nestedCount;
|
|
730
776
|
}
|
|
731
777
|
|
|
@@ -870,7 +916,8 @@ export class FormValueRuntime {
|
|
|
870
916
|
} else {
|
|
871
917
|
form.setFieldsValue?.({ [pathKey]: value });
|
|
872
918
|
}
|
|
873
|
-
_.set(this.valuesMirror, [pathKey], value);
|
|
919
|
+
_.set(this.valuesMirror, [pathKey], this.toMirrorSnapshot(value));
|
|
920
|
+
this.syncMountedFieldModelValue([pathKey], value);
|
|
874
921
|
}
|
|
875
922
|
this.bumpChangeTick();
|
|
876
923
|
} finally {
|
|
@@ -885,6 +932,9 @@ export class FormValueRuntime {
|
|
|
885
932
|
if (markExplicit) {
|
|
886
933
|
for (const k of patchKeys) {
|
|
887
934
|
this.markExplicit(k);
|
|
935
|
+
if (source === 'user') {
|
|
936
|
+
this.markUserEdited(k);
|
|
937
|
+
}
|
|
888
938
|
}
|
|
889
939
|
}
|
|
890
940
|
|
|
@@ -969,7 +1019,8 @@ export class FormValueRuntime {
|
|
|
969
1019
|
try {
|
|
970
1020
|
for (const { namePath, value } of filteredToWrite) {
|
|
971
1021
|
form.setFieldValue?.(namePath, value);
|
|
972
|
-
_.set(this.valuesMirror, namePath, value);
|
|
1022
|
+
_.set(this.valuesMirror, namePath, this.toMirrorSnapshot(value));
|
|
1023
|
+
this.syncMountedFieldModelValue(namePath, value);
|
|
973
1024
|
changedPaths.push(namePath);
|
|
974
1025
|
}
|
|
975
1026
|
this.bumpChangeTick();
|
|
@@ -984,13 +1035,16 @@ export class FormValueRuntime {
|
|
|
984
1035
|
if (markExplicit) {
|
|
985
1036
|
for (const { pathKey } of filteredToWrite) {
|
|
986
1037
|
this.markExplicit(pathKey);
|
|
1038
|
+
if (source === 'user') {
|
|
1039
|
+
this.markUserEdited(pathKey);
|
|
1040
|
+
}
|
|
987
1041
|
}
|
|
988
1042
|
}
|
|
989
1043
|
|
|
990
1044
|
if (source === 'default') {
|
|
991
1045
|
for (const { namePath, pathKey } of filteredToWrite) {
|
|
992
1046
|
const current = this.getFormValueAtPath(namePath);
|
|
993
|
-
this.lastDefaultValueByPathKey.set(pathKey, current);
|
|
1047
|
+
this.lastDefaultValueByPathKey.set(pathKey, this.toMirrorSnapshot(current));
|
|
994
1048
|
}
|
|
995
1049
|
}
|
|
996
1050
|
|
|
@@ -1052,6 +1106,7 @@ export class FormValueRuntime {
|
|
|
1052
1106
|
if (this.disposed) return;
|
|
1053
1107
|
const form = this.getForm?.();
|
|
1054
1108
|
if (!form) return;
|
|
1109
|
+
if (source === 'override' && this.findUserEditedHit(pathKey)) return;
|
|
1055
1110
|
|
|
1056
1111
|
const prevValue = _.get(this.valuesMirror, namePath);
|
|
1057
1112
|
if (_.isEqual(prevValue, nextValue)) return;
|
|
@@ -1062,7 +1117,8 @@ export class FormValueRuntime {
|
|
|
1062
1117
|
this.suppressFormCallbackDepth++;
|
|
1063
1118
|
try {
|
|
1064
1119
|
form.setFieldValue?.(namePath, nextValue);
|
|
1065
|
-
_.set(this.valuesMirror, namePath, nextValue);
|
|
1120
|
+
_.set(this.valuesMirror, namePath, this.toMirrorSnapshot(nextValue));
|
|
1121
|
+
this.syncMountedFieldModelValue(namePath, nextValue);
|
|
1066
1122
|
this.bumpChangeTick();
|
|
1067
1123
|
} finally {
|
|
1068
1124
|
this.suppressFormCallbackDepth--;
|
|
@@ -1098,7 +1154,10 @@ export class FormValueRuntime {
|
|
|
1098
1154
|
}
|
|
1099
1155
|
this.emitFormValuesChange(payload);
|
|
1100
1156
|
|
|
1101
|
-
if (
|
|
1157
|
+
if (
|
|
1158
|
+
(source === 'default' && this.isExplicit(pathKey)) ||
|
|
1159
|
+
(source === 'override' && this.findUserEditedHit(pathKey))
|
|
1160
|
+
) {
|
|
1102
1161
|
const existing = this.observableBindings.get(pathKey);
|
|
1103
1162
|
if (existing) {
|
|
1104
1163
|
existing.dispose();
|
|
@@ -1107,7 +1166,7 @@ export class FormValueRuntime {
|
|
|
1107
1166
|
}
|
|
1108
1167
|
|
|
1109
1168
|
if (source === 'default') {
|
|
1110
|
-
this.lastDefaultValueByPathKey.set(pathKey, this.getFormValueAtPath(namePath));
|
|
1169
|
+
this.lastDefaultValueByPathKey.set(pathKey, this.toMirrorSnapshot(this.getFormValueAtPath(namePath)));
|
|
1111
1170
|
}
|
|
1112
1171
|
}
|
|
1113
1172
|
|
|
@@ -1133,6 +1192,148 @@ export class FormValueRuntime {
|
|
|
1133
1192
|
this.model.emitter?.emit?.('formValuesChange', payload);
|
|
1134
1193
|
}
|
|
1135
1194
|
|
|
1195
|
+
private syncMountedFieldModelValue(namePath: NamePath, value: unknown) {
|
|
1196
|
+
const targetKey = namePathToPathKey(namePath);
|
|
1197
|
+
if (!targetKey) return;
|
|
1198
|
+
|
|
1199
|
+
const models = this.mountedFieldModelsByPathKey.get(targetKey);
|
|
1200
|
+
if (!models?.size) return;
|
|
1201
|
+
|
|
1202
|
+
const visited = new Set<FlowModel>();
|
|
1203
|
+
for (const model of Array.from(models)) {
|
|
1204
|
+
this.syncMountedFieldModelValueForModel(model, value, visited);
|
|
1205
|
+
}
|
|
1206
|
+
}
|
|
1207
|
+
|
|
1208
|
+
private syncMountedFieldModelValueForModel(
|
|
1209
|
+
model: FlowModel | null | undefined,
|
|
1210
|
+
value: unknown,
|
|
1211
|
+
visited: Set<FlowModel>,
|
|
1212
|
+
) {
|
|
1213
|
+
if (!model || visited.has(model)) return;
|
|
1214
|
+
visited.add(model);
|
|
1215
|
+
if (!this.isMountedModelInThisForm(model)) return;
|
|
1216
|
+
|
|
1217
|
+
const nextProps = { value };
|
|
1218
|
+
model.setProps?.(nextProps);
|
|
1219
|
+
const fieldModel = (model as FlowModel & { subModels?: { field?: FlowModel } }).subModels?.field;
|
|
1220
|
+
fieldModel?.setProps?.(nextProps);
|
|
1221
|
+
}
|
|
1222
|
+
|
|
1223
|
+
private rebuildMountedFieldModelIndex() {
|
|
1224
|
+
this.mountedFieldModelsByPathKey.clear();
|
|
1225
|
+
const engine = this.model?.context?.engine;
|
|
1226
|
+
if (!engine || typeof engine.forEachModel !== 'function') return;
|
|
1227
|
+
|
|
1228
|
+
engine.forEachModel((model: FlowModel) => {
|
|
1229
|
+
this.indexMountedFieldModelTree(model);
|
|
1230
|
+
});
|
|
1231
|
+
}
|
|
1232
|
+
|
|
1233
|
+
private indexMountedFieldModelTree(model: FlowModel | null | undefined) {
|
|
1234
|
+
this.visitModelAndForks(model, (item) => this.indexMountedFieldModel(item));
|
|
1235
|
+
}
|
|
1236
|
+
|
|
1237
|
+
private unindexMountedFieldModelTree(model: FlowModel | null | undefined) {
|
|
1238
|
+
this.visitModelAndForks(model, (item) => this.unindexMountedFieldModel(item));
|
|
1239
|
+
}
|
|
1240
|
+
|
|
1241
|
+
private visitModelAndForks(model: FlowModel | null | undefined, visit: (model: FlowModel) => void) {
|
|
1242
|
+
if (!model) return;
|
|
1243
|
+
const visited = new Set<FlowModel>();
|
|
1244
|
+
const walk = (item: FlowModel | null | undefined) => {
|
|
1245
|
+
if (!item || visited.has(item)) return;
|
|
1246
|
+
visited.add(item);
|
|
1247
|
+
visit(item);
|
|
1248
|
+
const forks = (item as FlowModel & { forks?: { forEach?: (cb: (fork: FlowModel) => void) => void } }).forks;
|
|
1249
|
+
forks?.forEach?.((fork) => walk(fork));
|
|
1250
|
+
};
|
|
1251
|
+
walk(model);
|
|
1252
|
+
}
|
|
1253
|
+
|
|
1254
|
+
private indexMountedFieldModel(model: FlowModel) {
|
|
1255
|
+
if (!this.isMountedModelInThisForm(model)) return;
|
|
1256
|
+
|
|
1257
|
+
const pathKeys = new Set<string>();
|
|
1258
|
+
for (const path of this.getMountedModelNamePaths(model)) {
|
|
1259
|
+
const key = namePathToPathKey(path);
|
|
1260
|
+
if (key) pathKeys.add(key);
|
|
1261
|
+
}
|
|
1262
|
+
if (!pathKeys.size) return;
|
|
1263
|
+
|
|
1264
|
+
this.unindexMountedFieldModel(model);
|
|
1265
|
+
this.mountedFieldModelPathKeys.set(model, pathKeys);
|
|
1266
|
+
|
|
1267
|
+
for (const key of pathKeys) {
|
|
1268
|
+
const models = this.mountedFieldModelsByPathKey.get(key) || new Set<FlowModel>();
|
|
1269
|
+
models.add(model);
|
|
1270
|
+
this.mountedFieldModelsByPathKey.set(key, models);
|
|
1271
|
+
}
|
|
1272
|
+
}
|
|
1273
|
+
|
|
1274
|
+
private unindexMountedFieldModel(model: FlowModel) {
|
|
1275
|
+
const pathKeys = this.mountedFieldModelPathKeys.get(model);
|
|
1276
|
+
if (!pathKeys) return;
|
|
1277
|
+
|
|
1278
|
+
for (const key of pathKeys) {
|
|
1279
|
+
const models = this.mountedFieldModelsByPathKey.get(key);
|
|
1280
|
+
if (!models) continue;
|
|
1281
|
+
models.delete(model);
|
|
1282
|
+
if (!models.size) {
|
|
1283
|
+
this.mountedFieldModelsByPathKey.delete(key);
|
|
1284
|
+
}
|
|
1285
|
+
}
|
|
1286
|
+
|
|
1287
|
+
this.mountedFieldModelPathKeys.delete(model);
|
|
1288
|
+
}
|
|
1289
|
+
|
|
1290
|
+
private isMountedModelInThisForm(model: FlowModel) {
|
|
1291
|
+
const blockModel = (model.context as { blockModel?: FlowModel } | undefined)?.blockModel;
|
|
1292
|
+
return !!blockModel && String(blockModel.uid) === String(this.model.uid);
|
|
1293
|
+
}
|
|
1294
|
+
|
|
1295
|
+
private getMountedModelNamePaths(model: FlowModel): NamePath[] {
|
|
1296
|
+
const paths: NamePath[] = [];
|
|
1297
|
+
const push = (value: unknown) => {
|
|
1298
|
+
const path = this.normalizeNamePathValue(value);
|
|
1299
|
+
if (path?.length) paths.push(path);
|
|
1300
|
+
};
|
|
1301
|
+
|
|
1302
|
+
push((model.context as { fieldPathArray?: unknown } | undefined)?.fieldPathArray);
|
|
1303
|
+
|
|
1304
|
+
const props = typeof model.getProps === 'function' ? model.getProps() : (model as { props?: unknown }).props;
|
|
1305
|
+
if (props && typeof props === 'object') {
|
|
1306
|
+
push((props as { name?: unknown }).name);
|
|
1307
|
+
}
|
|
1308
|
+
|
|
1309
|
+
try {
|
|
1310
|
+
const init = model.getStepParams?.('fieldSettings', 'init');
|
|
1311
|
+
if (init && typeof init === 'object') {
|
|
1312
|
+
push((init as { fieldPath?: unknown }).fieldPath);
|
|
1313
|
+
}
|
|
1314
|
+
} catch {
|
|
1315
|
+
// ignore models without field settings
|
|
1316
|
+
}
|
|
1317
|
+
|
|
1318
|
+
const seen = new Set<string>();
|
|
1319
|
+
return paths.filter((path) => {
|
|
1320
|
+
const key = namePathToPathKey(path);
|
|
1321
|
+
if (!key || seen.has(key)) return false;
|
|
1322
|
+
seen.add(key);
|
|
1323
|
+
return true;
|
|
1324
|
+
});
|
|
1325
|
+
}
|
|
1326
|
+
|
|
1327
|
+
private normalizeNamePathValue(value: unknown): NamePath | null {
|
|
1328
|
+
if (Array.isArray(value)) {
|
|
1329
|
+
const path = value.filter((seg): seg is string | number => typeof seg === 'string' || typeof seg === 'number');
|
|
1330
|
+
return path.length === value.length ? path : null;
|
|
1331
|
+
}
|
|
1332
|
+
if (typeof value === 'number') return [value];
|
|
1333
|
+
if (typeof value === 'string' && value) return pathKeyToNamePath(value);
|
|
1334
|
+
return null;
|
|
1335
|
+
}
|
|
1336
|
+
|
|
1136
1337
|
private markExplicit(pathKey: string) {
|
|
1137
1338
|
if (this.explicitSet.has(pathKey)) return;
|
|
1138
1339
|
this.explicitSet.add(pathKey);
|
|
@@ -1154,6 +1355,18 @@ export class FormValueRuntime {
|
|
|
1154
1355
|
}
|
|
1155
1356
|
}
|
|
1156
1357
|
|
|
1358
|
+
private markUserEdited(pathKey: string) {
|
|
1359
|
+
if (this.userEditedSet.has(pathKey)) return;
|
|
1360
|
+
this.userEditedSet.add(pathKey);
|
|
1361
|
+
|
|
1362
|
+
for (const [k, binding] of Array.from(this.observableBindings.entries())) {
|
|
1363
|
+
if (binding.source !== 'override') continue;
|
|
1364
|
+
if (!this.findUserEditedHit(k)) continue;
|
|
1365
|
+
binding.dispose();
|
|
1366
|
+
this.observableBindings.delete(k);
|
|
1367
|
+
}
|
|
1368
|
+
}
|
|
1369
|
+
|
|
1157
1370
|
private normalizeObservedNamePath(name: NamePath | string | number | undefined): NamePath | null {
|
|
1158
1371
|
if (Array.isArray(name)) return name as NamePath;
|
|
1159
1372
|
if (typeof name === 'number') return [name];
|
|
@@ -1216,4 +1429,35 @@ export class FormValueRuntime {
|
|
|
1216
1429
|
}
|
|
1217
1430
|
return null;
|
|
1218
1431
|
}
|
|
1432
|
+
|
|
1433
|
+
private findUserEditedHit(pathKey: string): string | null {
|
|
1434
|
+
if (this.userEditedSet.has(pathKey)) return pathKey;
|
|
1435
|
+
const namePath = pathKeyToNamePath(pathKey);
|
|
1436
|
+
const prefix: NamePath = [];
|
|
1437
|
+
|
|
1438
|
+
for (let i = 0; i < namePath.length; i++) {
|
|
1439
|
+
prefix.push(namePath[i]);
|
|
1440
|
+
const key = namePathToPathKey(prefix as any);
|
|
1441
|
+
if (!this.userEditedSet.has(key)) continue;
|
|
1442
|
+
|
|
1443
|
+
const nextSeg = namePath[i + 1];
|
|
1444
|
+
if (typeof nextSeg === 'number') {
|
|
1445
|
+
continue;
|
|
1446
|
+
}
|
|
1447
|
+
return key;
|
|
1448
|
+
}
|
|
1449
|
+
for (const key of this.userEditedSet) {
|
|
1450
|
+
if (!this.isDescendantPathKey(key, pathKey)) continue;
|
|
1451
|
+
return key;
|
|
1452
|
+
}
|
|
1453
|
+
return null;
|
|
1454
|
+
}
|
|
1455
|
+
|
|
1456
|
+
private isDescendantPathKey(candidateKey: string, parentKey: string) {
|
|
1457
|
+
if (!candidateKey || !parentKey || candidateKey === parentKey) return false;
|
|
1458
|
+
const candidatePath = pathKeyToNamePath(candidateKey);
|
|
1459
|
+
const parentPath = pathKeyToNamePath(parentKey);
|
|
1460
|
+
if (candidatePath.length <= parentPath.length) return false;
|
|
1461
|
+
return parentPath.every((seg, index) => candidatePath[index] === seg);
|
|
1462
|
+
}
|
|
1219
1463
|
}
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
export type NamePath = Array<string | number>;
|
|
11
11
|
|
|
12
|
-
export type ValueSource = 'default' | 'linkage' | 'user' | 'system';
|
|
12
|
+
export type ValueSource = 'default' | 'linkage' | 'user' | 'system' | 'override';
|
|
13
13
|
|
|
14
14
|
export type Patch =
|
|
15
15
|
| Record<string, any>
|
|
@@ -57,7 +57,7 @@ export interface FormValuesChangePayload {
|
|
|
57
57
|
allValuesSnapshot?: any;
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
-
export type AssignMode = 'default' | 'assign';
|
|
60
|
+
export type AssignMode = 'default' | 'assign' | 'override';
|
|
61
61
|
|
|
62
62
|
export type FormAssignRuleItem = {
|
|
63
63
|
key?: string;
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
import { ElementProxy, tExpr
|
|
10
|
+
import { ElementProxy, tExpr } from '@nocobase/flow-engine';
|
|
11
11
|
import React from 'react';
|
|
12
12
|
import { BlockModel } from '../../base';
|
|
13
13
|
import { BlockItemCard } from '../../../components';
|
|
@@ -167,12 +167,7 @@ ctx.render(\`
|
|
|
167
167
|
},
|
|
168
168
|
},
|
|
169
169
|
});
|
|
170
|
-
|
|
171
|
-
await ctx.runjs(
|
|
172
|
-
code,
|
|
173
|
-
{ window: createSafeWindow({ navigator }), document: createSafeDocument(), navigator },
|
|
174
|
-
{ version },
|
|
175
|
-
);
|
|
170
|
+
await ctx.runjs(code, undefined, { version });
|
|
176
171
|
});
|
|
177
172
|
},
|
|
178
173
|
},
|
|
@@ -19,9 +19,6 @@ import {
|
|
|
19
19
|
createRecordMetaFactory,
|
|
20
20
|
createRecordResolveOnServerWithLocal,
|
|
21
21
|
ElementProxy,
|
|
22
|
-
createSafeDocument,
|
|
23
|
-
createSafeWindow,
|
|
24
|
-
createSafeNavigator,
|
|
25
22
|
observer,
|
|
26
23
|
} from '@nocobase/flow-engine';
|
|
27
24
|
import { Tooltip } from 'antd';
|
|
@@ -294,12 +291,7 @@ JSColumnModel.registerFlow({
|
|
|
294
291
|
get: () => new ElementProxy((ctx.ref?.current as HTMLElement | null) || element),
|
|
295
292
|
cache: false,
|
|
296
293
|
});
|
|
297
|
-
|
|
298
|
-
await ctx.runjs(
|
|
299
|
-
code,
|
|
300
|
-
{ window: createSafeWindow({ navigator }), document: createSafeDocument(), navigator },
|
|
301
|
-
{ version },
|
|
302
|
-
);
|
|
294
|
+
await ctx.runjs(code, undefined, { version });
|
|
303
295
|
});
|
|
304
296
|
},
|
|
305
297
|
},
|
|
@@ -140,7 +140,7 @@ const AddActionToolbarComponent = observer(({ model }: any) => {
|
|
|
140
140
|
subModelBaseClass={model.context.getModelClassName('RecordActionGroupModel')}
|
|
141
141
|
subModelKey="actions"
|
|
142
142
|
afterSubModelInit={async (actionModel) => {
|
|
143
|
-
actionModel.setStepParams('buttonSettings', 'general', { type: 'link', icon: null });
|
|
143
|
+
actionModel.setStepParams('buttonSettings', 'general', { type: 'link', icon: null, iconOnly: false });
|
|
144
144
|
}}
|
|
145
145
|
>
|
|
146
146
|
<PlusOutlined />
|
|
@@ -179,11 +179,21 @@ const AddFieldColumn = ({ model }: { model: TableBlockModel }) => {
|
|
|
179
179
|
].filter(Boolean)}
|
|
180
180
|
keepDropdownOpen
|
|
181
181
|
>
|
|
182
|
-
|
|
182
|
+
{renderTableSettingsButton(model, 'Fields')}
|
|
183
183
|
</AddSubModelButton>
|
|
184
184
|
);
|
|
185
185
|
};
|
|
186
186
|
|
|
187
|
+
function renderTableSettingsButton(model: TableBlockModel, title: string) {
|
|
188
|
+
const label = model.translate(title);
|
|
189
|
+
|
|
190
|
+
return (
|
|
191
|
+
<FlowSettingsButton aria-label={label} icon={<SettingOutlined />}>
|
|
192
|
+
{model.context.isMobileLayout ? null : label}
|
|
193
|
+
</FlowSettingsButton>
|
|
194
|
+
);
|
|
195
|
+
}
|
|
196
|
+
|
|
187
197
|
type CustomTableBlockModelClassesEnum = {
|
|
188
198
|
CollectionActionGroupModel?: string;
|
|
189
199
|
RecordActionGroupModel?: string;
|
|
@@ -265,7 +275,7 @@ export class TableBlockModel extends CollectionBlockModel<TableBlockModelStructu
|
|
|
265
275
|
cols.push({
|
|
266
276
|
key: 'addColumn',
|
|
267
277
|
fixed: 'right',
|
|
268
|
-
width: 100,
|
|
278
|
+
...(this.context.isMobileLayout ? {} : { width: 100 }),
|
|
269
279
|
title: <AddFieldColumn model={this} />,
|
|
270
280
|
} as any);
|
|
271
281
|
}
|
|
@@ -508,7 +518,7 @@ export class TableBlockModel extends CollectionBlockModel<TableBlockModelStructu
|
|
|
508
518
|
subModelBaseClass={this.getModelClassName('CollectionActionGroupModel')}
|
|
509
519
|
subModelKey="actions"
|
|
510
520
|
>
|
|
511
|
-
|
|
521
|
+
{renderTableSettingsButton(this, 'Actions')}
|
|
512
522
|
</AddSubModelButton>
|
|
513
523
|
);
|
|
514
524
|
}
|
|
@@ -35,6 +35,7 @@ import { ErrorBoundary } from 'react-error-boundary';
|
|
|
35
35
|
import { getRowKey } from './utils';
|
|
36
36
|
import { getSavedAssociationTitleField, getTableColumnSortField } from './sortUtils';
|
|
37
37
|
import { getFieldBindingUse, rebuildFieldSubModel } from '../../../internal/utils/rebuildFieldSubModel';
|
|
38
|
+
import { getSavedDateTimeFormatParams, resolveDateTimeDisplayProps } from '../../../utils/dateTimeDisplayProps';
|
|
38
39
|
|
|
39
40
|
export function FieldDeletePlaceholder(props: any) {
|
|
40
41
|
const { t } = useTranslation();
|
|
@@ -128,6 +129,15 @@ export const CustomWidth = ({ setOpen, t, handleChange, defaultValue }) => {
|
|
|
128
129
|
);
|
|
129
130
|
};
|
|
130
131
|
|
|
132
|
+
const resetDateTimeDisplayProps = {
|
|
133
|
+
dateOnly: undefined,
|
|
134
|
+
dateFormat: undefined,
|
|
135
|
+
format: undefined,
|
|
136
|
+
picker: undefined,
|
|
137
|
+
showTime: undefined,
|
|
138
|
+
timeFormat: undefined,
|
|
139
|
+
};
|
|
140
|
+
|
|
131
141
|
export class TableColumnModel extends DisplayItemModel {
|
|
132
142
|
// 标记:该类的 render 返回函数, 避免错误的reactive封装
|
|
133
143
|
static renderMode: ModelRenderMode = ModelRenderMode.RenderFunction;
|
|
@@ -353,11 +363,22 @@ TableColumnModel.registerFlow({
|
|
|
353
363
|
return;
|
|
354
364
|
}
|
|
355
365
|
const titleField = getSavedAssociationTitleField(ctx.model);
|
|
366
|
+
const fieldModel = Array.isArray(ctx.model.subModels.field) ? undefined : ctx.model.subModels.field;
|
|
367
|
+
const targetCollectionField = collectionField.targetCollection?.getField?.(titleField);
|
|
368
|
+
const savedDateTimeDisplayProps = getSavedDateTimeFormatParams(fieldModel)
|
|
369
|
+
? resolveDateTimeDisplayProps({
|
|
370
|
+
model: fieldModel,
|
|
371
|
+
collectionField,
|
|
372
|
+
titleField,
|
|
373
|
+
currentProps: ctx.model.props,
|
|
374
|
+
})
|
|
375
|
+
: undefined;
|
|
356
376
|
const componentProps =
|
|
357
377
|
collectionField.isAssociationField() && titleField
|
|
358
378
|
? {
|
|
359
379
|
...collectionField.getComponentProps(),
|
|
360
|
-
...
|
|
380
|
+
...targetCollectionField?.getComponentProps?.(),
|
|
381
|
+
...savedDateTimeDisplayProps,
|
|
361
382
|
}
|
|
362
383
|
: collectionField.getComponentProps();
|
|
363
384
|
ctx.model.setProps('title', collectionField.title);
|
|
@@ -539,21 +560,33 @@ TableColumnModel.registerFlow({
|
|
|
539
560
|
typeof binding?.defaultProps === 'function'
|
|
540
561
|
? binding.defaultProps(ctx, targetCollectionField)
|
|
541
562
|
: binding?.defaultProps;
|
|
563
|
+
const componentProps = targetCollectionField.getComponentProps?.() || {};
|
|
564
|
+
const nextFieldProps = {
|
|
565
|
+
...(defaultProps || {}),
|
|
566
|
+
...componentProps,
|
|
567
|
+
titleField: params.label,
|
|
568
|
+
};
|
|
569
|
+
const nextColumnProps = {
|
|
570
|
+
...resetDateTimeDisplayProps,
|
|
571
|
+
...nextFieldProps,
|
|
572
|
+
};
|
|
542
573
|
if (targetUse && targetUse !== currentUse) {
|
|
543
574
|
await rebuildFieldSubModel({
|
|
544
575
|
parentModel: ctx.model as any,
|
|
545
576
|
targetUse,
|
|
546
|
-
defaultProps,
|
|
577
|
+
defaultProps: nextFieldProps,
|
|
547
578
|
fieldSettingsInit,
|
|
548
579
|
});
|
|
549
580
|
} else if (fieldModel) {
|
|
581
|
+
fieldModel.setProps(nextColumnProps);
|
|
550
582
|
fieldModel.setStepParams('fieldSettings', 'init', fieldSettingsInit);
|
|
551
583
|
await fieldModel.dispatchEvent('beforeRender', undefined, { useCache: false });
|
|
584
|
+
await fieldModel.save();
|
|
552
585
|
}
|
|
553
586
|
if (targetUse) {
|
|
554
587
|
ctx.model.setStepParams('tableColumnSettings', 'model', { use: targetUse });
|
|
555
588
|
}
|
|
556
|
-
ctx.model.setProps(
|
|
589
|
+
ctx.model.setProps(nextColumnProps);
|
|
557
590
|
},
|
|
558
591
|
defaultParams: (ctx: any) => {
|
|
559
592
|
const titleField = ctx.model?.context?.collectionField?.targetCollectionTitleFieldName;
|