@nocobase/client-v2 2.1.0-alpha.38 → 2.1.0-alpha.39
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 +16 -0
- package/es/Application.d.ts +2 -1
- package/es/BaseApplication.d.ts +6 -0
- package/es/PluginManager.d.ts +2 -0
- package/es/authRedirect.d.ts +9 -16
- package/es/components/form/EnvVariableInput.d.ts +8 -6
- package/es/components/form/VariableInput.d.ts +73 -0
- package/es/components/form/index.d.ts +1 -0
- package/es/components/form/table/RowOverlayPreview.d.ts +27 -0
- package/es/components/form/table/SelectionCell.d.ts +36 -0
- package/es/components/form/table/Table.d.ts +82 -0
- package/es/components/form/table/constants.d.ts +15 -0
- package/es/components/form/table/dnd/SortableRow.d.ts +40 -0
- package/es/components/form/table/dnd/index.d.ts +9 -0
- package/es/components/form/table/index.d.ts +9 -0
- package/es/components/form/table/styles.d.ts +41 -0
- package/es/components/form/table/utils.d.ts +44 -0
- package/es/components/index.d.ts +2 -0
- package/es/flow/components/TextAreaWithContextSelector.d.ts +15 -0
- package/es/flow/models/blocks/filter-form/FilterFormBlockModel.d.ts +9 -1
- package/es/flow/models/blocks/table/dragSort/dragSortComponents.d.ts +1 -6
- package/es/flow/models/blocks/table/dragSort/dragSortHooks.d.ts +5 -1
- package/es/flow-compat/passwordUtils.d.ts +1 -1
- package/es/index.d.ts +1 -0
- package/es/index.mjs +164 -97
- package/es/json-logic/globalOperators.d.ts +11 -0
- package/es/theme/globalStyles.d.ts +9 -0
- package/es/theme/index.d.ts +1 -0
- package/es/utils/globalDeps.d.ts +7 -0
- package/lib/index.js +173 -106
- package/package.json +9 -6
- package/src/APIClient.ts +68 -0
- package/src/Application.tsx +6 -2
- package/src/BaseApplication.tsx +8 -0
- package/src/PluginManager.ts +2 -0
- package/src/__tests__/app.test.tsx +8 -0
- package/src/__tests__/authRedirect.test.ts +170 -64
- package/src/__tests__/globalDeps.test.ts +2 -0
- package/src/__tests__/nocobase-buildin-plugin-auth.test.tsx +6 -6
- package/src/__tests__/remotePlugins.test.ts +148 -0
- package/src/authRedirect.ts +23 -84
- package/src/components/form/EnvVariableInput.tsx +11 -46
- package/src/components/form/VariableInput.tsx +177 -0
- package/src/components/form/__tests__/EnvVariableInput.test.tsx +175 -0
- package/src/components/form/index.tsx +1 -0
- package/src/components/form/table/RowOverlayPreview.tsx +51 -0
- package/src/components/form/table/SelectionCell.tsx +72 -0
- package/src/components/form/table/Table.tsx +279 -0
- package/src/components/form/table/__tests__/Table.pagination.test.tsx +80 -0
- package/src/components/form/table/constants.ts +16 -0
- package/src/components/form/table/dnd/SortableRow.tsx +106 -0
- package/src/components/form/table/dnd/index.ts +10 -0
- package/src/components/form/table/index.tsx +13 -0
- package/src/components/form/table/styles.ts +110 -0
- package/src/components/form/table/utils.ts +75 -0
- package/src/components/index.ts +2 -0
- package/src/css-variable/CSSVariableProvider.tsx +1 -1
- package/src/flow/actions/filterFormDefaultValues.tsx +1 -2
- package/src/flow/admin-shell/admin-layout/resolveAdminRouteRuntimeTarget.test.ts +111 -0
- package/src/flow/admin-shell/admin-layout/resolveAdminRouteRuntimeTarget.ts +2 -1
- package/src/flow/components/TextAreaWithContextSelector.tsx +30 -6
- package/src/flow/models/blocks/filter-form/FilterFormBlockModel.tsx +329 -5
- package/src/flow/models/blocks/filter-form/__tests__/defaultValues.wiring.test.ts +337 -0
- package/src/flow/models/blocks/table/dragSort/dragSortComponents.tsx +1 -81
- package/src/index.ts +1 -0
- package/src/json-logic/globalOperators.js +731 -0
- package/src/nocobase-buildin-plugin/index.tsx +4 -4
- package/src/theme/globalStyles.ts +21 -0
- package/src/theme/index.tsx +1 -0
- package/src/utils/globalDeps.ts +50 -30
- package/src/utils/remotePlugins.ts +107 -6
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
import { SettingOutlined } from '@ant-design/icons';
|
|
11
11
|
import { FormButtonGroup } from '@formily/antd-v5';
|
|
12
|
+
import type { CollectionField, PropertyMeta, PropertyMetaFactory } from '@nocobase/flow-engine';
|
|
12
13
|
import {
|
|
13
14
|
AddSubModelButton,
|
|
14
15
|
DndProvider,
|
|
@@ -22,6 +23,7 @@ import {
|
|
|
22
23
|
FlowSettingsButton,
|
|
23
24
|
} from '@nocobase/flow-engine';
|
|
24
25
|
import { Form } from 'antd';
|
|
26
|
+
import { isEqual } from 'lodash';
|
|
25
27
|
import React from 'react';
|
|
26
28
|
import { commonConditionHandler, ConditionBuilder } from '../../../components/ConditionBuilder';
|
|
27
29
|
import {
|
|
@@ -31,6 +33,7 @@ import {
|
|
|
31
33
|
import { BlockSceneEnum } from '../../base/BlockModel';
|
|
32
34
|
import { FilterBlockModel } from '../../base/FilterBlockModel';
|
|
33
35
|
import { FormComponent } from '../form/FormBlockModel';
|
|
36
|
+
import { evaluateCondition } from '../form/value-runtime/conditions';
|
|
34
37
|
import { isEmptyValue } from '../form/value-runtime/utils';
|
|
35
38
|
import { FilterManager, type RefreshTargetsByFilterOptions } from '../filter-manager/FilterManager';
|
|
36
39
|
import { FilterFormItemModel } from './FilterFormItemModel';
|
|
@@ -40,6 +43,177 @@ import { FormItemModel } from '../form/FormItemModel';
|
|
|
40
43
|
import { getDefaultOperator } from '../filter-manager/utils';
|
|
41
44
|
import { normalizeFilterValueByOperator } from './valueNormalization';
|
|
42
45
|
|
|
46
|
+
const RELATION_FIELD_TYPES = ['belongsTo', 'hasOne', 'hasMany', 'belongsToMany', 'belongsToArray'];
|
|
47
|
+
const NUMERIC_FIELD_TYPES = ['integer', 'float', 'double', 'decimal'];
|
|
48
|
+
|
|
49
|
+
function getFilterFormFieldMetaType(field: CollectionField) {
|
|
50
|
+
if (RELATION_FIELD_TYPES.includes(field.type)) {
|
|
51
|
+
return 'object';
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (NUMERIC_FIELD_TYPES.includes(field.type)) {
|
|
55
|
+
return 'number';
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
switch (field.type) {
|
|
59
|
+
case 'boolean':
|
|
60
|
+
return 'boolean';
|
|
61
|
+
case 'json':
|
|
62
|
+
return 'object';
|
|
63
|
+
case 'array':
|
|
64
|
+
return 'array';
|
|
65
|
+
default:
|
|
66
|
+
return 'string';
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function shouldShowFilterFormFieldMeta(field: CollectionField) {
|
|
71
|
+
return Boolean(field?.interface);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function createFilterFormFieldMeta(field: CollectionField): PropertyMeta {
|
|
75
|
+
const baseMeta = {
|
|
76
|
+
title: field.title || field.name,
|
|
77
|
+
interface: field.interface,
|
|
78
|
+
options: field.options,
|
|
79
|
+
uiSchema: field.uiSchema || {},
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
if (!field.isAssociationField?.()) {
|
|
83
|
+
return {
|
|
84
|
+
type: getFilterFormFieldMetaType(field),
|
|
85
|
+
...baseMeta,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const targetCollection = field.targetCollection;
|
|
90
|
+
if (!targetCollection) {
|
|
91
|
+
return {
|
|
92
|
+
type: 'object',
|
|
93
|
+
...baseMeta,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return {
|
|
98
|
+
type: 'object',
|
|
99
|
+
...baseMeta,
|
|
100
|
+
properties: async () => {
|
|
101
|
+
const properties: Record<string, PropertyMeta> = {};
|
|
102
|
+
targetCollection.fields.forEach((subField) => {
|
|
103
|
+
if (shouldShowFilterFormFieldMeta(subField)) {
|
|
104
|
+
properties[subField.name] = createFilterFormFieldMeta(subField);
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
return properties;
|
|
108
|
+
},
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function getFilterFormItemFieldName(itemModel: any) {
|
|
113
|
+
const name = itemModel?.props?.name;
|
|
114
|
+
if (typeof name === 'string' && name) {
|
|
115
|
+
return name;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
return itemModel?.fieldPath && itemModel?.uid ? `${itemModel.fieldPath}_${itemModel.uid}` : undefined;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function toFilterByTk(value: any, primaryKey: string | string[] | undefined) {
|
|
122
|
+
if (value == null) return undefined;
|
|
123
|
+
if (Array.isArray(primaryKey)) {
|
|
124
|
+
if (typeof value !== 'object') return undefined;
|
|
125
|
+
const filterByTk: Record<string, any> = {};
|
|
126
|
+
for (const key of primaryKey) {
|
|
127
|
+
const item = value?.[key];
|
|
128
|
+
if (item == null) return undefined;
|
|
129
|
+
filterByTk[key] = item;
|
|
130
|
+
}
|
|
131
|
+
return filterByTk;
|
|
132
|
+
}
|
|
133
|
+
if (typeof value !== 'object') return value;
|
|
134
|
+
const key = Array.isArray(primaryKey) ? primaryKey[0] : primaryKey;
|
|
135
|
+
return key ? value?.[key] : value?.id;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
function setValueByPath(target: Record<string, any>, path: string, value: any) {
|
|
139
|
+
const segments = path.split('.').filter(Boolean);
|
|
140
|
+
if (!segments.length) return;
|
|
141
|
+
|
|
142
|
+
let cursor = target;
|
|
143
|
+
segments.forEach((segment, index) => {
|
|
144
|
+
if (index === segments.length - 1) {
|
|
145
|
+
cursor[segment] = value;
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
if (!cursor[segment] || typeof cursor[segment] !== 'object' || Array.isArray(cursor[segment])) {
|
|
150
|
+
cursor[segment] = {};
|
|
151
|
+
}
|
|
152
|
+
cursor = cursor[segment];
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
function setMetaByPath(target: Record<string, PropertyMeta>, path: string, meta: PropertyMeta) {
|
|
157
|
+
const segments = path.split('.').filter(Boolean);
|
|
158
|
+
if (!segments.length) return;
|
|
159
|
+
|
|
160
|
+
let cursor = target;
|
|
161
|
+
segments.forEach((segment, index) => {
|
|
162
|
+
if (index === segments.length - 1) {
|
|
163
|
+
cursor[segment] = meta;
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
const current = cursor[segment];
|
|
168
|
+
if (!current || typeof current !== 'object') {
|
|
169
|
+
cursor[segment] = {
|
|
170
|
+
type: 'object',
|
|
171
|
+
title: segment,
|
|
172
|
+
properties: {},
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
const properties = cursor[segment].properties;
|
|
176
|
+
if (!properties || typeof properties === 'function') {
|
|
177
|
+
cursor[segment].properties = {};
|
|
178
|
+
}
|
|
179
|
+
cursor = cursor[segment].properties as Record<string, PropertyMeta>;
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
function getFilterFormValues(form: any, items: any[]) {
|
|
184
|
+
const formValues = form?.getFieldsValue?.() || {};
|
|
185
|
+
const values = { ...formValues };
|
|
186
|
+
|
|
187
|
+
for (const itemModel of items) {
|
|
188
|
+
const fieldName = getFilterFormItemFieldName(itemModel);
|
|
189
|
+
if (!fieldName || !fieldName.includes('.') || !(fieldName in formValues)) {
|
|
190
|
+
continue;
|
|
191
|
+
}
|
|
192
|
+
setValueByPath(values, fieldName, formValues[fieldName]);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
return values;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
function isFilterFormFieldSubPath(fieldName: string, subPath: string) {
|
|
199
|
+
return subPath === fieldName || subPath.startsWith(`${fieldName}.`) || subPath.startsWith(`${fieldName}[`);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
function isFilterFormFieldDeepSubPath(fieldName: string, subPath: string) {
|
|
203
|
+
return subPath.startsWith(`${fieldName}.`) || subPath.startsWith(`${fieldName}[`);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
function findFilterFormItemByVariableSubPath(items: any[], subPath: string) {
|
|
207
|
+
if (!subPath) return null;
|
|
208
|
+
|
|
209
|
+
return (
|
|
210
|
+
items.find((itemModel) => {
|
|
211
|
+
const fieldName = getFilterFormItemFieldName(itemModel);
|
|
212
|
+
return fieldName && isFilterFormFieldSubPath(fieldName, subPath);
|
|
213
|
+
}) || null
|
|
214
|
+
);
|
|
215
|
+
}
|
|
216
|
+
|
|
43
217
|
export class FilterFormBlockModel extends FilterBlockModel<{
|
|
44
218
|
subModels: {
|
|
45
219
|
grid: any; // Replace with actual type if available
|
|
@@ -56,6 +230,8 @@ export class FilterFormBlockModel extends FilterBlockModel<{
|
|
|
56
230
|
private removeTargetBlockListener?: () => void;
|
|
57
231
|
private initialDefaultsPromise?: Promise<void>;
|
|
58
232
|
private initialRefreshHandledTargetIds = new Set<string>();
|
|
233
|
+
private lastDefaultValueByFieldName = new Map<string, any>();
|
|
234
|
+
private defaultValuesRefreshSeq = 0;
|
|
59
235
|
|
|
60
236
|
get form() {
|
|
61
237
|
return this.context.form;
|
|
@@ -65,10 +241,98 @@ export class FilterFormBlockModel extends FilterBlockModel<{
|
|
|
65
241
|
return 'Filter form';
|
|
66
242
|
}
|
|
67
243
|
|
|
244
|
+
protected createFormValuesMetaFactory(): PropertyMetaFactory {
|
|
245
|
+
const factory: PropertyMetaFactory = async () => ({
|
|
246
|
+
type: 'object',
|
|
247
|
+
title: this.translate('Current form'),
|
|
248
|
+
properties: async () => {
|
|
249
|
+
const properties: Record<string, PropertyMeta> = {};
|
|
250
|
+
const items = this.subModels?.grid?.subModels?.items || [];
|
|
251
|
+
|
|
252
|
+
for (const itemModel of items) {
|
|
253
|
+
const fieldName = getFilterFormItemFieldName(itemModel);
|
|
254
|
+
const collectionField = itemModel?.subModels?.field?.context?.collectionField || itemModel?.collectionField;
|
|
255
|
+
if (!fieldName || !collectionField || !shouldShowFilterFormFieldMeta(collectionField)) {
|
|
256
|
+
continue;
|
|
257
|
+
}
|
|
258
|
+
setMetaByPath(properties, fieldName, createFilterFormFieldMeta(collectionField));
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
return properties;
|
|
262
|
+
},
|
|
263
|
+
buildVariablesParams: () => {
|
|
264
|
+
const formValues = this.form?.getFieldsValue?.() || {};
|
|
265
|
+
const items = this.subModels?.grid?.subModels?.items || [];
|
|
266
|
+
const params: Record<string, any> = {};
|
|
267
|
+
|
|
268
|
+
for (const itemModel of items) {
|
|
269
|
+
const fieldName = getFilterFormItemFieldName(itemModel);
|
|
270
|
+
const collectionField = itemModel?.subModels?.field?.context?.collectionField || itemModel?.collectionField;
|
|
271
|
+
if (!fieldName || !collectionField?.isAssociationField?.()) {
|
|
272
|
+
continue;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
const targetCollection = collectionField.targetCollection;
|
|
276
|
+
const target = collectionField.target;
|
|
277
|
+
if (!targetCollection || !target) {
|
|
278
|
+
continue;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
const fieldValue = formValues[fieldName];
|
|
282
|
+
const primaryKey = targetCollection.filterTargetKey;
|
|
283
|
+
if (Array.isArray(fieldValue)) {
|
|
284
|
+
const filterByTk = fieldValue.map((item) => toFilterByTk(item, primaryKey)).filter((item) => item != null);
|
|
285
|
+
if (filterByTk.length) {
|
|
286
|
+
setValueByPath(params, fieldName, {
|
|
287
|
+
collection: target,
|
|
288
|
+
dataSourceKey: targetCollection.dataSourceKey,
|
|
289
|
+
filterByTk,
|
|
290
|
+
});
|
|
291
|
+
}
|
|
292
|
+
continue;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
const filterByTk = toFilterByTk(fieldValue, primaryKey);
|
|
296
|
+
if (filterByTk != null) {
|
|
297
|
+
setValueByPath(params, fieldName, {
|
|
298
|
+
collection: target,
|
|
299
|
+
dataSourceKey: targetCollection.dataSourceKey,
|
|
300
|
+
filterByTk,
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
return params;
|
|
306
|
+
},
|
|
307
|
+
});
|
|
308
|
+
factory.title = this.translate('Current form');
|
|
309
|
+
return factory;
|
|
310
|
+
}
|
|
311
|
+
|
|
68
312
|
useHooksBeforeRender() {
|
|
69
313
|
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
70
314
|
const [form] = Form.useForm();
|
|
71
315
|
this.context.defineProperty('form', { get: () => form, cache: false });
|
|
316
|
+
this.context.defineProperty('formValues', {
|
|
317
|
+
get: () => getFilterFormValues(this.form, this.subModels?.grid?.subModels?.items || []),
|
|
318
|
+
cache: false,
|
|
319
|
+
meta: this.createFormValuesMetaFactory(),
|
|
320
|
+
resolveOnServer: (subPath: string) => {
|
|
321
|
+
const items = this.subModels?.grid?.subModels?.items || [];
|
|
322
|
+
const itemModel = findFilterFormItemByVariableSubPath(items, subPath);
|
|
323
|
+
if (!itemModel) return false;
|
|
324
|
+
|
|
325
|
+
const fieldName = getFilterFormItemFieldName(itemModel);
|
|
326
|
+
const collectionField = itemModel?.subModels?.field?.context?.collectionField || itemModel?.collectionField;
|
|
327
|
+
return Boolean(
|
|
328
|
+
fieldName &&
|
|
329
|
+
isFilterFormFieldDeepSubPath(fieldName, subPath) &&
|
|
330
|
+
collectionField?.isAssociationField?.() &&
|
|
331
|
+
collectionField?.targetCollection,
|
|
332
|
+
);
|
|
333
|
+
},
|
|
334
|
+
serverOnlyWhenContextParams: true,
|
|
335
|
+
});
|
|
72
336
|
}
|
|
73
337
|
|
|
74
338
|
async saveStepParams() {
|
|
@@ -165,14 +429,38 @@ export class FilterFormBlockModel extends FilterBlockModel<{
|
|
|
165
429
|
}
|
|
166
430
|
}
|
|
167
431
|
|
|
168
|
-
|
|
432
|
+
private canApplyFormDefaultValue(name: string, current: any, force?: boolean) {
|
|
433
|
+
if (force) return true;
|
|
434
|
+
if (isEmptyValue(current)) return true;
|
|
435
|
+
if (!this.lastDefaultValueByFieldName.has(name)) return false;
|
|
436
|
+
return isEqual(current, this.lastDefaultValueByFieldName.get(name));
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
private async matchDefaultValueCondition(condition: any) {
|
|
440
|
+
if (!condition) return true;
|
|
441
|
+
|
|
442
|
+
let resolvedCondition = condition;
|
|
443
|
+
try {
|
|
444
|
+
const nextCondition = await (this.context as any).resolveJsonTemplate?.(condition);
|
|
445
|
+
if (typeof nextCondition !== 'undefined') {
|
|
446
|
+
resolvedCondition = nextCondition;
|
|
447
|
+
}
|
|
448
|
+
} catch {
|
|
449
|
+
resolvedCondition = condition;
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
return evaluateCondition(this.context, resolvedCondition);
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
async applyFormDefaultValues(options?: { force?: boolean; refreshSeq?: number }) {
|
|
456
|
+
const appliedValues: Record<string, any> = {};
|
|
169
457
|
const form = this.form;
|
|
170
|
-
if (!form) return;
|
|
458
|
+
if (!form) return appliedValues;
|
|
171
459
|
|
|
172
460
|
const force = options?.force === true;
|
|
173
461
|
const params = this.getStepParams?.('formFilterBlockModelSettings', 'defaultValues');
|
|
174
462
|
const rules = (params?.value || []) as any[];
|
|
175
|
-
if (!Array.isArray(rules) || rules.length === 0) return;
|
|
463
|
+
if (!Array.isArray(rules) || rules.length === 0) return appliedValues;
|
|
176
464
|
|
|
177
465
|
const resolveValue = async (raw: any) => {
|
|
178
466
|
// RunJS support
|
|
@@ -188,7 +476,8 @@ export class FilterFormBlockModel extends FilterBlockModel<{
|
|
|
188
476
|
for (const rule of rules) {
|
|
189
477
|
if (!rule || typeof rule !== 'object') continue;
|
|
190
478
|
if (rule.enable === false) continue;
|
|
191
|
-
if (
|
|
479
|
+
if (!(await this.matchDefaultValueCondition(rule.condition))) continue;
|
|
480
|
+
if (options?.refreshSeq && options.refreshSeq !== this.defaultValuesRefreshSeq) return appliedValues;
|
|
192
481
|
|
|
193
482
|
const targetPath = rule.targetPath ? String(rule.targetPath).trim() : '';
|
|
194
483
|
const fieldUid = rule.field ? String(rule.field).trim() : '';
|
|
@@ -203,20 +492,54 @@ export class FilterFormBlockModel extends FilterBlockModel<{
|
|
|
203
492
|
if (!name) continue;
|
|
204
493
|
|
|
205
494
|
const current = (form as any).getFieldValue?.(name);
|
|
206
|
-
if (!force && !isEmptyValue(current)) continue;
|
|
207
495
|
|
|
208
496
|
const resolved = await resolveValue(rule.value);
|
|
497
|
+
if (options?.refreshSeq && options.refreshSeq !== this.defaultValuesRefreshSeq) return appliedValues;
|
|
209
498
|
if (typeof resolved === 'undefined') continue;
|
|
210
499
|
|
|
211
500
|
const operator = getDefaultOperator(itemModel as any);
|
|
212
501
|
const normalized = normalizeFilterValueByOperator(operator, resolved);
|
|
502
|
+
const mode = String(rule.mode || 'default') === 'assign' ? 'assign' : 'default';
|
|
503
|
+
if (mode === 'default' && !this.canApplyFormDefaultValue(String(name), current, force)) continue;
|
|
504
|
+
if (isEqual(current, normalized)) {
|
|
505
|
+
if (mode === 'default') {
|
|
506
|
+
this.lastDefaultValueByFieldName.set(String(name), normalized);
|
|
507
|
+
} else {
|
|
508
|
+
this.lastDefaultValueByFieldName.delete(String(name));
|
|
509
|
+
}
|
|
510
|
+
continue;
|
|
511
|
+
}
|
|
213
512
|
|
|
214
513
|
if (typeof (form as any).setFieldValue === 'function') {
|
|
215
514
|
(form as any).setFieldValue(name, normalized);
|
|
216
515
|
} else {
|
|
217
516
|
(form as any).setFieldsValue?.({ [String(name)]: normalized });
|
|
218
517
|
}
|
|
518
|
+
if (mode === 'default') {
|
|
519
|
+
this.lastDefaultValueByFieldName.set(String(name), normalized);
|
|
520
|
+
} else {
|
|
521
|
+
this.lastDefaultValueByFieldName.delete(String(name));
|
|
522
|
+
}
|
|
523
|
+
appliedValues[String(name)] = normalized;
|
|
219
524
|
}
|
|
525
|
+
|
|
526
|
+
return appliedValues;
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
private handleFilterFormValuesChange(changedValues: any, allValues: any) {
|
|
530
|
+
const refreshSeq = ++this.defaultValuesRefreshSeq;
|
|
531
|
+
void (async () => {
|
|
532
|
+
const appliedValues = await this.applyFormDefaultValues({ refreshSeq });
|
|
533
|
+
if (refreshSeq !== this.defaultValuesRefreshSeq) return;
|
|
534
|
+
|
|
535
|
+
const finalChangedValues = { ...(changedValues || {}), ...(appliedValues || {}) };
|
|
536
|
+
const finalAllValues = this.form?.getFieldsValue?.() || allValues;
|
|
537
|
+
const payload = { changedValues: finalChangedValues, allValues: finalAllValues };
|
|
538
|
+
this.dispatchEvent('formValuesChange', payload, { debounce: true });
|
|
539
|
+
this.emitter.emit('formValuesChange', payload);
|
|
540
|
+
})().catch((error) => {
|
|
541
|
+
console.error('Failed to refresh filter form default values:', error);
|
|
542
|
+
});
|
|
220
543
|
}
|
|
221
544
|
|
|
222
545
|
private async handleTargetBlockRemoved(targetUid: string) {
|
|
@@ -264,6 +587,7 @@ export class FilterFormBlockModel extends FilterBlockModel<{
|
|
|
264
587
|
onFinish={() => {
|
|
265
588
|
this.context.refreshTargets();
|
|
266
589
|
}}
|
|
590
|
+
onValuesChange={(changedValues, allValues) => this.handleFilterFormValuesChange(changedValues, allValues)}
|
|
267
591
|
layoutProps={{ colon, labelAlign, labelWidth, labelWrap, layout }}
|
|
268
592
|
>
|
|
269
593
|
<FlowModelRenderer model={this.subModels.grid} showFlowSettings={false} />
|