@nocobase/client-v2 2.1.28 → 2.1.29
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/index.mjs +58 -58
- package/lib/index.js +67 -67
- package/package.json +7 -7
- package/src/flow/components/BlockItemCard.tsx +2 -2
- package/src/flow/models/blocks/filter-form/FilterFormBlockModel.tsx +27 -3
- package/src/flow/models/blocks/filter-form/__tests__/defaultValues.wiring.test.ts +32 -4
- package/src/flow/models/blocks/js-block/JSBlock.tsx +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nocobase/client-v2",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.29",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"module": "es/index.mjs",
|
|
@@ -27,11 +27,11 @@
|
|
|
27
27
|
"@formily/antd-v5": "1.2.3",
|
|
28
28
|
"@formily/react": "^2.2.27",
|
|
29
29
|
"@formily/shared": "^2.2.27",
|
|
30
|
-
"@nocobase/evaluators": "2.1.
|
|
31
|
-
"@nocobase/flow-engine": "2.1.
|
|
32
|
-
"@nocobase/sdk": "2.1.
|
|
33
|
-
"@nocobase/shared": "2.1.
|
|
34
|
-
"@nocobase/utils": "2.1.
|
|
30
|
+
"@nocobase/evaluators": "2.1.29",
|
|
31
|
+
"@nocobase/flow-engine": "2.1.29",
|
|
32
|
+
"@nocobase/sdk": "2.1.29",
|
|
33
|
+
"@nocobase/shared": "2.1.29",
|
|
34
|
+
"@nocobase/utils": "2.1.29",
|
|
35
35
|
"ahooks": "^3.7.2",
|
|
36
36
|
"antd": "5.24.2",
|
|
37
37
|
"antd-style": "3.7.1",
|
|
@@ -48,5 +48,5 @@
|
|
|
48
48
|
"react-i18next": "^11.15.1",
|
|
49
49
|
"react-router-dom": "^6.30.1"
|
|
50
50
|
},
|
|
51
|
-
"gitHead": "
|
|
51
|
+
"gitHead": "d9848c5df07cef806cb938bb14b3f4ef5f3d0129"
|
|
52
52
|
}
|
|
@@ -150,7 +150,7 @@ export const BlockItemCard = React.forwardRef(
|
|
|
150
150
|
) => {
|
|
151
151
|
const { t } = useTranslation();
|
|
152
152
|
const { token } = theme.useToken();
|
|
153
|
-
const { title: blockTitle, description, children, className, heightMode, ...rest } = props;
|
|
153
|
+
const { title: blockTitle, description, children, className, heightMode, style, ...rest } = props;
|
|
154
154
|
const cardRef = useRef<HTMLDivElement | null>(null);
|
|
155
155
|
const setCardRef = useCallback(
|
|
156
156
|
(node: HTMLDivElement | null) => {
|
|
@@ -185,7 +185,7 @@ export const BlockItemCard = React.forwardRef(
|
|
|
185
185
|
<Card
|
|
186
186
|
ref={setCardRef as any}
|
|
187
187
|
title={title}
|
|
188
|
-
style={{ display: 'flex', flexDirection: 'column', height: height }}
|
|
188
|
+
style={{ display: 'flex', flexDirection: 'column', ...style, height: height ?? style?.height }}
|
|
189
189
|
styles={{
|
|
190
190
|
body: { flex: 1, display: 'flex', flexDirection: 'column', overflow: 'auto' },
|
|
191
191
|
header: {
|
|
@@ -15,8 +15,10 @@ import {
|
|
|
15
15
|
DndProvider,
|
|
16
16
|
DragHandler,
|
|
17
17
|
Droppable,
|
|
18
|
+
isCtxDateExpression,
|
|
18
19
|
isRunJSValue,
|
|
19
20
|
normalizeRunJSValue,
|
|
21
|
+
parseCtxDateExpression,
|
|
20
22
|
runjsWithSafeGlobals,
|
|
21
23
|
tExpr,
|
|
22
24
|
FlowModelRenderer,
|
|
@@ -45,6 +47,15 @@ import { normalizeFilterValueByOperator } from './valueNormalization';
|
|
|
45
47
|
|
|
46
48
|
const RELATION_FIELD_TYPES = ['belongsTo', 'hasOne', 'hasMany', 'belongsToMany', 'belongsToArray'];
|
|
47
49
|
const NUMERIC_FIELD_TYPES = ['integer', 'float', 'double', 'decimal'];
|
|
50
|
+
const DATE_FILTER_OPERATORS = new Set([
|
|
51
|
+
'$dateOn',
|
|
52
|
+
'$dateNotOn',
|
|
53
|
+
'$dateBefore',
|
|
54
|
+
'$dateAfter',
|
|
55
|
+
'$dateNotBefore',
|
|
56
|
+
'$dateNotAfter',
|
|
57
|
+
'$dateBetween',
|
|
58
|
+
]);
|
|
48
59
|
|
|
49
60
|
function getFilterFormFieldMetaType(field: CollectionField) {
|
|
50
61
|
if (RELATION_FIELD_TYPES.includes(field.type)) {
|
|
@@ -67,6 +78,14 @@ function getFilterFormFieldMetaType(field: CollectionField) {
|
|
|
67
78
|
}
|
|
68
79
|
}
|
|
69
80
|
|
|
81
|
+
function parseDateFilterDefaultValue(operator: string | undefined, rawValue: unknown) {
|
|
82
|
+
if (!operator || !DATE_FILTER_OPERATORS.has(operator) || !isCtxDateExpression(rawValue)) {
|
|
83
|
+
return undefined;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return parseCtxDateExpression(rawValue);
|
|
87
|
+
}
|
|
88
|
+
|
|
70
89
|
function shouldShowFilterFormFieldMeta(field: CollectionField) {
|
|
71
90
|
return Boolean(field?.interface);
|
|
72
91
|
}
|
|
@@ -490,7 +509,7 @@ export class FilterFormBlockModel extends FilterBlockModel<{
|
|
|
490
509
|
const rules = (params?.value || []) as any[];
|
|
491
510
|
if (!Array.isArray(rules) || rules.length === 0) return appliedValues;
|
|
492
511
|
|
|
493
|
-
const resolveValue = async (raw: any) => {
|
|
512
|
+
const resolveValue = async (raw: any, operator?: string) => {
|
|
494
513
|
// RunJS support
|
|
495
514
|
if (isRunJSValue(raw)) {
|
|
496
515
|
const { code, version } = normalizeRunJSValue(raw);
|
|
@@ -498,6 +517,11 @@ export class FilterFormBlockModel extends FilterBlockModel<{
|
|
|
498
517
|
return ret?.success ? ret.value : undefined;
|
|
499
518
|
}
|
|
500
519
|
|
|
520
|
+
const parsedDateFilterValue = parseDateFilterDefaultValue(operator, raw);
|
|
521
|
+
if (typeof parsedDateFilterValue !== 'undefined') {
|
|
522
|
+
return parsedDateFilterValue;
|
|
523
|
+
}
|
|
524
|
+
|
|
501
525
|
return await (this.context as any).resolveJsonTemplate?.(raw);
|
|
502
526
|
};
|
|
503
527
|
|
|
@@ -521,11 +545,11 @@ export class FilterFormBlockModel extends FilterBlockModel<{
|
|
|
521
545
|
|
|
522
546
|
const current = (form as any).getFieldValue?.(name);
|
|
523
547
|
|
|
524
|
-
const
|
|
548
|
+
const operator = getDefaultOperator(itemModel as any);
|
|
549
|
+
const resolved = await resolveValue(rule.value, operator);
|
|
525
550
|
if (options?.refreshSeq && options.refreshSeq !== this.defaultValuesRefreshSeq) return appliedValues;
|
|
526
551
|
if (typeof resolved === 'undefined') continue;
|
|
527
552
|
|
|
528
|
-
const operator = getDefaultOperator(itemModel as any);
|
|
529
553
|
const normalized = normalizeFilterValueByOperator(operator, resolved);
|
|
530
554
|
const mode = this.normalizeFieldValueMode(rule.mode);
|
|
531
555
|
if (mode === 'default' && !this.canApplyFormDefaultValue(String(name), current, force)) continue;
|
|
@@ -17,7 +17,15 @@ import { FilterFormBlockModel } from '../FilterFormBlockModel';
|
|
|
17
17
|
function resolveTemplateValue(raw: any, values: Record<string, any>): any {
|
|
18
18
|
if (typeof raw === 'string') {
|
|
19
19
|
const matched = raw.match(/^\{\{\s*ctx\.formValues\.([^}]+?)\s*\}\}$/);
|
|
20
|
-
|
|
20
|
+
if (matched) {
|
|
21
|
+
return values[matched[1]];
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (/^\{\{\s*ctx\.date\.relative\.past\.day\.n7\s*\}\}$/.test(raw)) {
|
|
25
|
+
return '2026-06-15';
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return raw;
|
|
21
29
|
}
|
|
22
30
|
if (Array.isArray(raw)) {
|
|
23
31
|
return raw.map((item) => resolveTemplateValue(item, values));
|
|
@@ -30,7 +38,7 @@ function resolveTemplateValue(raw: any, values: Record<string, any>): any {
|
|
|
30
38
|
|
|
31
39
|
function createFilterFormDefaultValuesModel(rules: any[], initialValues: Record<string, any> = {}) {
|
|
32
40
|
const values = { ...initialValues };
|
|
33
|
-
const createItem = (fieldPath: string, uid: string) => ({
|
|
41
|
+
const createItem = (fieldPath: string, uid: string, operator?: string) => ({
|
|
34
42
|
uid,
|
|
35
43
|
fieldPath,
|
|
36
44
|
props: { name: `${fieldPath}_${uid}` },
|
|
@@ -44,7 +52,7 @@ function createFilterFormDefaultValuesModel(rules: any[], initialValues: Record<
|
|
|
44
52
|
return undefined;
|
|
45
53
|
},
|
|
46
54
|
subModels: {
|
|
47
|
-
field: {},
|
|
55
|
+
field: operator ? { operator } : {},
|
|
48
56
|
},
|
|
49
57
|
});
|
|
50
58
|
const model = {
|
|
@@ -76,7 +84,11 @@ function createFilterFormDefaultValuesModel(rules: any[], initialValues: Record<
|
|
|
76
84
|
subModels: {
|
|
77
85
|
grid: {
|
|
78
86
|
subModels: {
|
|
79
|
-
items: [
|
|
87
|
+
items: [
|
|
88
|
+
createItem('nickname', 'nick'),
|
|
89
|
+
createItem('username', 'user'),
|
|
90
|
+
createItem('birthdate_tz', 'birthdate', '$dateOn'),
|
|
91
|
+
],
|
|
80
92
|
},
|
|
81
93
|
},
|
|
82
94
|
},
|
|
@@ -354,6 +366,22 @@ describe('filter-form defaultValues wiring', () => {
|
|
|
354
366
|
expect(values.username_user).toBe('Bob');
|
|
355
367
|
});
|
|
356
368
|
|
|
369
|
+
it('preserves relative date descriptors for date filter default values', async () => {
|
|
370
|
+
const { model, values } = createFilterFormDefaultValuesModel([
|
|
371
|
+
{
|
|
372
|
+
key: 'birthdate-default',
|
|
373
|
+
enable: true,
|
|
374
|
+
targetPath: 'birthdate_tz',
|
|
375
|
+
mode: 'assign',
|
|
376
|
+
value: '{{ ctx.date.relative.past.day.n7 }}',
|
|
377
|
+
},
|
|
378
|
+
]);
|
|
379
|
+
|
|
380
|
+
await FilterFormBlockModel.prototype.applyFormDefaultValues.call(model as any);
|
|
381
|
+
|
|
382
|
+
expect(values.birthdate_tz_birthdate).toEqual({ type: 'past', unit: 'day', number: 7 });
|
|
383
|
+
});
|
|
384
|
+
|
|
357
385
|
it('applies override values until the target filter field is changed by user', async () => {
|
|
358
386
|
const { model, values } = createFilterFormDefaultValuesModel(
|
|
359
387
|
[
|
|
@@ -235,7 +235,7 @@ export class JSBlockModel extends BlockModel {
|
|
|
235
235
|
const cardProps = {
|
|
236
236
|
...rest,
|
|
237
237
|
height,
|
|
238
|
-
style,
|
|
238
|
+
...(style === undefined ? {} : { style }),
|
|
239
239
|
...(beforeContent === undefined ? {} : { beforeContent }),
|
|
240
240
|
...(afterContent === undefined ? {} : { afterContent }),
|
|
241
241
|
};
|