@nocobase/client-v2 2.1.6 → 2.1.7
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/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/index.mjs +110 -90
- package/lib/index.js +89 -69
- package/package.json +7 -7
- 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/dateTimeFormat.tsx +42 -28
- package/src/flow/actions/linkageRules.tsx +45 -11
- package/src/flow/admin-shell/admin-layout/HelpLite.tsx +1 -3
- package/src/flow/components/DynamicFlowsIcon.tsx +447 -126
- package/src/flow/components/__tests__/DynamicFlowsIcon.test.tsx +148 -2
- 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/blocks/filter-manager/flow-actions/__tests__/customizeFilterRender.test.tsx +56 -1
- package/src/flow/models/blocks/table/TableColumnModel.tsx +36 -3
- 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/SelectFieldModel.tsx +6 -4
- package/src/flow/models/fields/__tests__/DisplayDateTimeFieldModel.test.tsx +96 -0
- package/src/flow/models/fields/__tests__/SelectFieldModel.test.tsx +43 -0
- package/src/flow/utils/__tests__/dateTimeFormat.test.ts +258 -0
- package/src/flow/utils/dateTimeDisplayProps.ts +135 -0
- package/src/settings-center/plugin-manager/index.tsx +3 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nocobase/client-v2",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.7",
|
|
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.7",
|
|
31
|
+
"@nocobase/flow-engine": "2.1.7",
|
|
32
|
+
"@nocobase/sdk": "2.1.7",
|
|
33
|
+
"@nocobase/shared": "2.1.7",
|
|
34
|
+
"@nocobase/utils": "2.1.7",
|
|
35
35
|
"ahooks": "^3.7.2",
|
|
36
36
|
"antd": "5.24.2",
|
|
37
37
|
"antd-style": "3.7.1",
|
|
@@ -46,5 +46,5 @@
|
|
|
46
46
|
"react-i18next": "^11.15.1",
|
|
47
47
|
"react-router-dom": "^6.30.1"
|
|
48
48
|
},
|
|
49
|
-
"gitHead": "
|
|
49
|
+
"gitHead": "fc3bc8bf6ef0c185a456cb5241abc4716af8c20c"
|
|
50
50
|
}
|
|
@@ -27,12 +27,12 @@ describe('linkageRules hidden state propagation', () => {
|
|
|
27
27
|
const hostModel: any = {
|
|
28
28
|
uid: 'host',
|
|
29
29
|
hidden: false,
|
|
30
|
-
context: { blockModel },
|
|
30
|
+
context: { blockModel, fieldPathArray: ['children'] },
|
|
31
31
|
__allModels: [],
|
|
32
32
|
setProps: vi.fn(),
|
|
33
33
|
getFlow: vi.fn(() => ({})),
|
|
34
34
|
getStepParams: vi.fn((_flowKey: string, stepKey: string) => {
|
|
35
|
-
if (stepKey === 'init') return { fieldPath: '
|
|
35
|
+
if (stepKey === 'init') return { fieldPath: 'children' };
|
|
36
36
|
return undefined;
|
|
37
37
|
}),
|
|
38
38
|
translate: (s: string) => s,
|
|
@@ -41,10 +41,22 @@ describe('linkageRules hidden state propagation', () => {
|
|
|
41
41
|
const sameTargetModel: any = {
|
|
42
42
|
uid: 'same-target',
|
|
43
43
|
hidden: false,
|
|
44
|
-
context: { blockModel },
|
|
44
|
+
context: { blockModel, fieldPathArray: ['children'] },
|
|
45
45
|
setProps: vi.fn(),
|
|
46
46
|
getStepParams: vi.fn((_flowKey: string, stepKey: string) => {
|
|
47
|
-
if (stepKey === 'init') return { fieldPath: '
|
|
47
|
+
if (stepKey === 'init') return { fieldPath: 'children' };
|
|
48
|
+
return undefined;
|
|
49
|
+
}),
|
|
50
|
+
translate: (s: string) => s,
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
const nestedColumnModel: any = {
|
|
54
|
+
uid: 'nested-column',
|
|
55
|
+
hidden: true,
|
|
56
|
+
context: { blockModel, fieldPathArray: ['children'] },
|
|
57
|
+
setProps: vi.fn(),
|
|
58
|
+
getStepParams: vi.fn((_flowKey: string, stepKey: string) => {
|
|
59
|
+
if (stepKey === 'init') return { fieldPath: 'children.children' };
|
|
48
60
|
return undefined;
|
|
49
61
|
}),
|
|
50
62
|
translate: (s: string) => s,
|
|
@@ -52,7 +64,7 @@ describe('linkageRules hidden state propagation', () => {
|
|
|
52
64
|
|
|
53
65
|
const engine = {
|
|
54
66
|
forEachModel: (visitor: (m: any) => void) => {
|
|
55
|
-
[hostModel, sameTargetModel].forEach(visitor);
|
|
67
|
+
[hostModel, sameTargetModel, nestedColumnModel].forEach(visitor);
|
|
56
68
|
},
|
|
57
69
|
};
|
|
58
70
|
|
|
@@ -92,9 +104,11 @@ describe('linkageRules hidden state propagation', () => {
|
|
|
92
104
|
});
|
|
93
105
|
expect(hostModel.hidden).toBe(true);
|
|
94
106
|
expect(sameTargetModel.hidden).toBe(true);
|
|
107
|
+
expect(nestedColumnModel.hidden).toBe(true);
|
|
95
108
|
|
|
96
109
|
await actionLinkageRules.handler(ctx, { value: [] });
|
|
97
110
|
expect(hostModel.hidden).toBe(false);
|
|
98
111
|
expect(sameTargetModel.hidden).toBe(false);
|
|
112
|
+
expect(nestedColumnModel.hidden).toBe(true);
|
|
99
113
|
});
|
|
100
114
|
});
|
|
@@ -728,6 +728,98 @@ describe('linkageSetFieldProps action', () => {
|
|
|
728
728
|
expect(form.setFieldValue).not.toHaveBeenCalled();
|
|
729
729
|
});
|
|
730
730
|
|
|
731
|
+
it('should not clear the parent field when a nested same-name field inherits the parent path', async () => {
|
|
732
|
+
const setFormValues = vi.fn(async () => undefined);
|
|
733
|
+
const form = {
|
|
734
|
+
getFieldValue: vi.fn((path: Array<string | number>) => {
|
|
735
|
+
if (JSON.stringify(path) === JSON.stringify(['children', 'children'])) {
|
|
736
|
+
return [{ title: 'nested' }];
|
|
737
|
+
}
|
|
738
|
+
if (JSON.stringify(path) === JSON.stringify(['children'])) {
|
|
739
|
+
return [{ title: 'parent' }];
|
|
740
|
+
}
|
|
741
|
+
return undefined;
|
|
742
|
+
}),
|
|
743
|
+
setFieldValue: vi.fn(),
|
|
744
|
+
};
|
|
745
|
+
const fieldModel: any = {
|
|
746
|
+
uid: 'nested-children-field',
|
|
747
|
+
hidden: false,
|
|
748
|
+
context: {
|
|
749
|
+
form,
|
|
750
|
+
fieldPathArray: ['children'],
|
|
751
|
+
},
|
|
752
|
+
props: {
|
|
753
|
+
label: 'Children',
|
|
754
|
+
},
|
|
755
|
+
getStepParams: vi.fn((flowKey: string, stepKey: string) => {
|
|
756
|
+
if (flowKey === 'fieldSettings' && stepKey === 'init') {
|
|
757
|
+
return { fieldPath: 'children.children' };
|
|
758
|
+
}
|
|
759
|
+
}),
|
|
760
|
+
setProps(key: any, value?: any) {
|
|
761
|
+
if (typeof key === 'string') {
|
|
762
|
+
this.props[key] = value;
|
|
763
|
+
} else {
|
|
764
|
+
this.props = { ...this.props, ...key };
|
|
765
|
+
}
|
|
766
|
+
},
|
|
767
|
+
};
|
|
768
|
+
const ctx: any = {
|
|
769
|
+
app: {
|
|
770
|
+
jsonLogic: {
|
|
771
|
+
apply: vi.fn(() => true),
|
|
772
|
+
},
|
|
773
|
+
},
|
|
774
|
+
model: {
|
|
775
|
+
context: { form },
|
|
776
|
+
subModels: {
|
|
777
|
+
grid: {
|
|
778
|
+
subModels: {
|
|
779
|
+
items: [fieldModel],
|
|
780
|
+
},
|
|
781
|
+
},
|
|
782
|
+
},
|
|
783
|
+
},
|
|
784
|
+
setFormValues,
|
|
785
|
+
getAction: (name: string) => (name === 'linkageSetFieldProps' ? linkageSetFieldProps : null),
|
|
786
|
+
resolveJsonTemplate: vi.fn(async (value) => value),
|
|
787
|
+
};
|
|
788
|
+
|
|
789
|
+
await fieldLinkageRules.handler(ctx, {
|
|
790
|
+
value: [
|
|
791
|
+
{
|
|
792
|
+
key: 'rule-1',
|
|
793
|
+
enable: true,
|
|
794
|
+
condition: { logic: '$and', items: [] },
|
|
795
|
+
actions: [
|
|
796
|
+
{
|
|
797
|
+
key: 'action-1',
|
|
798
|
+
name: 'linkageSetFieldProps',
|
|
799
|
+
params: {
|
|
800
|
+
value: {
|
|
801
|
+
fields: ['nested-children-field'],
|
|
802
|
+
state: 'hidden',
|
|
803
|
+
},
|
|
804
|
+
},
|
|
805
|
+
},
|
|
806
|
+
],
|
|
807
|
+
},
|
|
808
|
+
],
|
|
809
|
+
});
|
|
810
|
+
|
|
811
|
+
expect(fieldModel.hidden).toBe(true);
|
|
812
|
+
expect(setFormValues).toHaveBeenCalledWith(
|
|
813
|
+
[{ path: ['children', 'children'], value: undefined }],
|
|
814
|
+
expect.objectContaining({ source: 'linkage' }),
|
|
815
|
+
);
|
|
816
|
+
expect(setFormValues).not.toHaveBeenCalledWith(
|
|
817
|
+
[{ path: ['children'], value: undefined }],
|
|
818
|
+
expect.objectContaining({ source: 'linkage' }),
|
|
819
|
+
);
|
|
820
|
+
expect(form.setFieldValue).not.toHaveBeenCalled();
|
|
821
|
+
});
|
|
822
|
+
|
|
731
823
|
it('should keep hidden clear after same-round assignment for the same field', async () => {
|
|
732
824
|
const formValues: { name?: string } = {};
|
|
733
825
|
const setFormValues = vi.fn(async (patches: Array<{ path: Array<string | number>; value: string | undefined }>) => {
|
|
@@ -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
|
});
|
|
@@ -1948,6 +1948,21 @@ const commonLinkageRulesHandler = async (ctx: FlowContext, params: any) => {
|
|
|
1948
1948
|
>;
|
|
1949
1949
|
return normalized.length ? normalized : null;
|
|
1950
1950
|
};
|
|
1951
|
+
const pathKeysEqual = (
|
|
1952
|
+
a: Array<string | number> | null | undefined,
|
|
1953
|
+
b: Array<string | number> | null | undefined,
|
|
1954
|
+
) => {
|
|
1955
|
+
if (!a || !b) return false;
|
|
1956
|
+
return namePathToPathKey(a) === namePathToPathKey(b);
|
|
1957
|
+
};
|
|
1958
|
+
const namePathEndsWith = (
|
|
1959
|
+
namePath: Array<string | number> | null | undefined,
|
|
1960
|
+
suffix: Array<string | number> | null | undefined,
|
|
1961
|
+
) => {
|
|
1962
|
+
if (!namePath || !suffix || suffix.length > namePath.length) return false;
|
|
1963
|
+
const offset = namePath.length - suffix.length;
|
|
1964
|
+
return suffix.every((seg, index) => namePath[offset + index] === seg);
|
|
1965
|
+
};
|
|
1951
1966
|
const getFieldIndexEntries = (fieldIndex: any): Array<{ name: string; index: number }> => {
|
|
1952
1967
|
if (!Array.isArray(fieldIndex)) return [];
|
|
1953
1968
|
return fieldIndex
|
|
@@ -1996,17 +2011,35 @@ const commonLinkageRulesHandler = async (ctx: FlowContext, params: any) => {
|
|
|
1996
2011
|
|
|
1997
2012
|
return out;
|
|
1998
2013
|
};
|
|
2014
|
+
const getTrustedFieldPathArray = (
|
|
2015
|
+
fieldPathArray: Array<string | number> | null,
|
|
2016
|
+
targetPath: string | null,
|
|
2017
|
+
fieldIndex: unknown,
|
|
2018
|
+
): Array<string | number> | null => {
|
|
2019
|
+
if (!fieldPathArray || !targetPath) return null;
|
|
2020
|
+
|
|
2021
|
+
const targetNamePath = normalizeNamePathForKey(
|
|
2022
|
+
parsePathString(targetPath).filter((seg) => typeof seg === 'string' || typeof seg === 'number'),
|
|
2023
|
+
);
|
|
2024
|
+
const resolvedTargetPath = normalizeNamePathForKey(resolveDynamicNamePath(targetPath, fieldIndex));
|
|
2025
|
+
const indexedRelativePath = resolveIndexedRelativePath(targetPath, fieldIndex);
|
|
2026
|
+
|
|
2027
|
+
if (
|
|
2028
|
+
pathKeysEqual(fieldPathArray, resolvedTargetPath) ||
|
|
2029
|
+
pathKeysEqual(fieldPathArray, indexedRelativePath) ||
|
|
2030
|
+
namePathEndsWith(fieldPathArray, targetNamePath)
|
|
2031
|
+
) {
|
|
2032
|
+
return fieldPathArray;
|
|
2033
|
+
}
|
|
2034
|
+
|
|
2035
|
+
return null;
|
|
2036
|
+
};
|
|
1999
2037
|
const getModelTargetPathForHiddenClear = (model: any): string | Array<string | number> | null => {
|
|
2000
2038
|
const fieldPathArray = normalizeNamePathForKey(model?.context?.fieldPathArray);
|
|
2001
2039
|
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
|
-
}
|
|
2040
|
+
const trustedFieldPathArray = getTrustedFieldPathArray(fieldPathArray, targetPath, model?.context?.fieldIndex);
|
|
2041
|
+
if (trustedFieldPathArray) {
|
|
2042
|
+
return trustedFieldPathArray;
|
|
2010
2043
|
}
|
|
2011
2044
|
|
|
2012
2045
|
if (!targetPath) return null;
|
|
@@ -2016,12 +2049,13 @@ const commonLinkageRulesHandler = async (ctx: FlowContext, params: any) => {
|
|
|
2016
2049
|
const getModelTargetPathKeys = (model: any): Set<string> => {
|
|
2017
2050
|
const keys = new Set<string>();
|
|
2018
2051
|
const fieldPathArray = normalizeNamePathForKey(model?.context?.fieldPathArray);
|
|
2019
|
-
|
|
2020
|
-
|
|
2052
|
+
const targetPath = getModelTargetPathForPatch(model);
|
|
2053
|
+
const trustedFieldPathArray = getTrustedFieldPathArray(fieldPathArray, targetPath, model?.context?.fieldIndex);
|
|
2054
|
+
if (trustedFieldPathArray) {
|
|
2055
|
+
keys.add(namePathToPathKey(trustedFieldPathArray));
|
|
2021
2056
|
return keys;
|
|
2022
2057
|
}
|
|
2023
2058
|
|
|
2024
|
-
const targetPath = getModelTargetPathForPatch(model);
|
|
2025
2059
|
if (targetPath) {
|
|
2026
2060
|
const fieldIndexEntries = getFieldIndexEntries(model?.context?.fieldIndex);
|
|
2027
2061
|
if (!fieldIndexEntries.length) {
|
|
@@ -70,9 +70,7 @@ const SettingsMenu: React.FC = () => {
|
|
|
70
70
|
key: 'userManual',
|
|
71
71
|
label: (
|
|
72
72
|
<a
|
|
73
|
-
href={
|
|
74
|
-
isSimplifiedChinese ? 'https://v2.docs.nocobase.com/cn/guide/' : 'https://v2.docs.nocobase.com/guide/'
|
|
75
|
-
}
|
|
73
|
+
href={isSimplifiedChinese ? 'https://docs.nocobase.com/cn/guide/' : 'https://docs.nocobase.com/guide/'}
|
|
76
74
|
target="_blank"
|
|
77
75
|
rel="noreferrer"
|
|
78
76
|
>
|