@jsonforms/core 3.1.0-alpha.1 → 3.1.0-alpha.3
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/README.md +3 -3
- package/lib/actions/actions.d.ts +21 -21
- package/lib/i18n/arrayTranslations.d.ts +24 -0
- package/lib/i18n/i18nUtil.d.ts +3 -0
- package/lib/i18n/index.d.ts +1 -0
- package/lib/jsonforms-core.cjs.js +436 -262
- package/lib/jsonforms-core.cjs.js.map +1 -1
- package/lib/jsonforms-core.esm.js +318 -201
- package/lib/jsonforms-core.esm.js.map +1 -1
- package/lib/util/cell.d.ts +0 -1
- package/lib/util/renderer.d.ts +6 -2
- package/lib/util/schema.d.ts +5 -0
- package/package.json +11 -4
- package/src/Helpers.ts +1 -1
- package/src/actions/actions.ts +52 -55
- package/src/configDefault.ts +1 -1
- package/src/generators/Generate.ts +3 -1
- package/src/generators/schema.ts +29 -25
- package/src/generators/uischema.ts +7 -6
- package/src/i18n/arrayTranslations.ts +54 -0
- package/src/i18n/i18nTypes.ts +10 -6
- package/src/i18n/i18nUtil.ts +64 -14
- package/src/i18n/index.ts +1 -0
- package/src/models/draft4.ts +33 -33
- package/src/models/uischema.ts +17 -6
- package/src/reducers/cells.ts +8 -7
- package/src/reducers/core.ts +119 -75
- package/src/reducers/default-data.ts +7 -7
- package/src/reducers/i18n.ts +21 -9
- package/src/reducers/reducers.ts +20 -30
- package/src/reducers/renderers.ts +7 -7
- package/src/reducers/selectors.ts +4 -5
- package/src/reducers/uischemas.ts +25 -24
- package/src/store.ts +1 -1
- package/src/testers/testers.ts +202 -148
- package/src/util/cell.ts +24 -26
- package/src/util/combinators.ts +5 -3
- package/src/util/label.ts +1 -1
- package/src/util/path.ts +11 -7
- package/src/util/renderer.ts +118 -67
- package/src/util/resolvers.ts +15 -13
- package/src/util/runtime.ts +2 -2
- package/src/util/schema.ts +10 -1
- package/src/util/type.ts +5 -3
- package/src/util/uischema.ts +9 -9
- package/src/util/util.ts +52 -52
- package/src/util/validator.ts +1 -1
package/src/store.ts
CHANGED
package/src/testers/testers.ts
CHANGED
|
@@ -35,9 +35,14 @@ import type {
|
|
|
35
35
|
Categorization,
|
|
36
36
|
ControlElement,
|
|
37
37
|
JsonSchema,
|
|
38
|
-
UISchemaElement
|
|
38
|
+
UISchemaElement,
|
|
39
39
|
} from '../models';
|
|
40
|
-
import {
|
|
40
|
+
import {
|
|
41
|
+
deriveTypes,
|
|
42
|
+
hasType,
|
|
43
|
+
isOneOfEnumSchema,
|
|
44
|
+
resolveSchema,
|
|
45
|
+
} from '../util';
|
|
41
46
|
|
|
42
47
|
/**
|
|
43
48
|
* Constant that indicates that a tester is not capable of handling
|
|
@@ -49,7 +54,11 @@ export const NOT_APPLICABLE = -1;
|
|
|
49
54
|
* A tester is a function that receives an UI schema and a JSON schema and returns a boolean.
|
|
50
55
|
* The rootSchema is handed over as context. Can be used to resolve references.
|
|
51
56
|
*/
|
|
52
|
-
export type Tester = (
|
|
57
|
+
export type Tester = (
|
|
58
|
+
uischema: UISchemaElement,
|
|
59
|
+
schema: JsonSchema,
|
|
60
|
+
context: TesterContext
|
|
61
|
+
) => boolean;
|
|
53
62
|
|
|
54
63
|
/**
|
|
55
64
|
* A ranked tester associates a tester with a number.
|
|
@@ -83,50 +92,70 @@ export const isControl = (uischema: any): uischema is ControlElement =>
|
|
|
83
92
|
* @param {(JsonSchema) => boolean} predicate the predicate that should be
|
|
84
93
|
* applied to the resolved sub-schema
|
|
85
94
|
*/
|
|
86
|
-
export const schemaMatches =
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
95
|
+
export const schemaMatches =
|
|
96
|
+
(
|
|
97
|
+
predicate: (schema: JsonSchema, rootSchema: JsonSchema) => boolean
|
|
98
|
+
): Tester =>
|
|
99
|
+
(
|
|
100
|
+
uischema: UISchemaElement,
|
|
101
|
+
schema: JsonSchema,
|
|
102
|
+
context: TesterContext
|
|
103
|
+
): boolean => {
|
|
104
|
+
if (isEmpty(uischema) || !isControl(uischema)) {
|
|
105
|
+
return false;
|
|
106
|
+
}
|
|
107
|
+
if (isEmpty(schema)) {
|
|
108
|
+
return false;
|
|
109
|
+
}
|
|
110
|
+
const schemaPath = uischema.scope;
|
|
111
|
+
if (isEmpty(schemaPath)) {
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
let currentDataSchema = schema;
|
|
115
|
+
if (hasType(schema, 'object')) {
|
|
116
|
+
currentDataSchema = resolveSchema(
|
|
117
|
+
schema,
|
|
118
|
+
schemaPath,
|
|
119
|
+
context?.rootSchema
|
|
120
|
+
);
|
|
121
|
+
}
|
|
122
|
+
if (currentDataSchema === undefined) {
|
|
123
|
+
return false;
|
|
124
|
+
}
|
|
109
125
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
126
|
+
return predicate(currentDataSchema, context?.rootSchema);
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
export const schemaSubPathMatches =
|
|
130
|
+
(
|
|
131
|
+
subPath: string,
|
|
132
|
+
predicate: (schema: JsonSchema, rootSchema: JsonSchema) => boolean
|
|
133
|
+
): Tester =>
|
|
134
|
+
(
|
|
135
|
+
uischema: UISchemaElement,
|
|
136
|
+
schema: JsonSchema,
|
|
137
|
+
context: TesterContext
|
|
138
|
+
): boolean => {
|
|
139
|
+
if (isEmpty(uischema) || !isControl(uischema)) {
|
|
140
|
+
return false;
|
|
141
|
+
}
|
|
142
|
+
const schemaPath = uischema.scope;
|
|
143
|
+
let currentDataSchema: JsonSchema = schema;
|
|
144
|
+
if (hasType(schema, 'object')) {
|
|
145
|
+
currentDataSchema = resolveSchema(
|
|
146
|
+
schema,
|
|
147
|
+
schemaPath,
|
|
148
|
+
context?.rootSchema
|
|
149
|
+
);
|
|
150
|
+
}
|
|
151
|
+
currentDataSchema = get(currentDataSchema, subPath);
|
|
123
152
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
153
|
+
if (currentDataSchema === undefined) {
|
|
154
|
+
return false;
|
|
155
|
+
}
|
|
127
156
|
|
|
128
|
-
|
|
129
|
-
};
|
|
157
|
+
return predicate(currentDataSchema, context?.rootSchema);
|
|
158
|
+
};
|
|
130
159
|
|
|
131
160
|
/**
|
|
132
161
|
* Only applicable for Controls.
|
|
@@ -138,7 +167,7 @@ export const schemaSubPathMatches = (
|
|
|
138
167
|
* @param {string} expectedType the expected type of the resolved sub-schema
|
|
139
168
|
*/
|
|
140
169
|
export const schemaTypeIs = (expectedType: string): Tester =>
|
|
141
|
-
schemaMatches(schema => !isEmpty(schema) && hasType(schema, expectedType));
|
|
170
|
+
schemaMatches((schema) => !isEmpty(schema) && hasType(schema, expectedType));
|
|
142
171
|
|
|
143
172
|
/**
|
|
144
173
|
* Only applicable for Controls.
|
|
@@ -151,7 +180,7 @@ export const schemaTypeIs = (expectedType: string): Tester =>
|
|
|
151
180
|
*/
|
|
152
181
|
export const formatIs = (expectedFormat: string): Tester =>
|
|
153
182
|
schemaMatches(
|
|
154
|
-
schema =>
|
|
183
|
+
(schema) =>
|
|
155
184
|
!isEmpty(schema) &&
|
|
156
185
|
schema.format === expectedFormat &&
|
|
157
186
|
hasType(schema, 'string')
|
|
@@ -162,9 +191,10 @@ export const formatIs = (expectedFormat: string): Tester =>
|
|
|
162
191
|
*
|
|
163
192
|
* @param {string} expected the expected UI schema type
|
|
164
193
|
*/
|
|
165
|
-
export const uiTypeIs =
|
|
166
|
-
|
|
167
|
-
): boolean =>
|
|
194
|
+
export const uiTypeIs =
|
|
195
|
+
(expected: string): Tester =>
|
|
196
|
+
(uischema: UISchemaElement): boolean =>
|
|
197
|
+
!isEmpty(uischema) && uischema.type === expected;
|
|
168
198
|
|
|
169
199
|
/**
|
|
170
200
|
* Checks whether the given UI schema has an option with the given
|
|
@@ -174,16 +204,16 @@ export const uiTypeIs = (expected: string): Tester => (
|
|
|
174
204
|
* @param {string} optionName the name of the option to check
|
|
175
205
|
* @param {any} optionValue the expected value of the option
|
|
176
206
|
*/
|
|
177
|
-
export const optionIs =
|
|
178
|
-
|
|
179
|
-
): boolean => {
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
207
|
+
export const optionIs =
|
|
208
|
+
(optionName: string, optionValue: any): Tester =>
|
|
209
|
+
(uischema: UISchemaElement): boolean => {
|
|
210
|
+
if (isEmpty(uischema)) {
|
|
211
|
+
return false;
|
|
212
|
+
}
|
|
183
213
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
};
|
|
214
|
+
const options = uischema.options;
|
|
215
|
+
return !isEmpty(options) && options[optionName] === optionValue;
|
|
216
|
+
};
|
|
187
217
|
|
|
188
218
|
/**
|
|
189
219
|
* Only applicable for Controls.
|
|
@@ -192,15 +222,15 @@ export const optionIs = (optionName: string, optionValue: any): Tester => (
|
|
|
192
222
|
*
|
|
193
223
|
* @param {string} expected the expected ending of the reference
|
|
194
224
|
*/
|
|
195
|
-
export const scopeEndsWith =
|
|
196
|
-
|
|
197
|
-
): boolean => {
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
225
|
+
export const scopeEndsWith =
|
|
226
|
+
(expected: string): Tester =>
|
|
227
|
+
(uischema: UISchemaElement): boolean => {
|
|
228
|
+
if (isEmpty(expected) || !isControl(uischema)) {
|
|
229
|
+
return false;
|
|
230
|
+
}
|
|
201
231
|
|
|
202
|
-
|
|
203
|
-
};
|
|
232
|
+
return endsWith(uischema.scope, expected);
|
|
233
|
+
};
|
|
204
234
|
|
|
205
235
|
/**
|
|
206
236
|
* Only applicable for Controls.
|
|
@@ -209,38 +239,42 @@ export const scopeEndsWith = (expected: string): Tester => (
|
|
|
209
239
|
*
|
|
210
240
|
* @param {string} expected the expected ending of the reference
|
|
211
241
|
*/
|
|
212
|
-
export const scopeEndIs =
|
|
213
|
-
|
|
214
|
-
): boolean => {
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
242
|
+
export const scopeEndIs =
|
|
243
|
+
(expected: string): Tester =>
|
|
244
|
+
(uischema: UISchemaElement): boolean => {
|
|
245
|
+
if (isEmpty(expected) || !isControl(uischema)) {
|
|
246
|
+
return false;
|
|
247
|
+
}
|
|
248
|
+
const schemaPath = uischema.scope;
|
|
219
249
|
|
|
220
|
-
|
|
221
|
-
};
|
|
250
|
+
return !isEmpty(schemaPath) && last(schemaPath.split('/')) === expected;
|
|
251
|
+
};
|
|
222
252
|
|
|
223
253
|
/**
|
|
224
254
|
* A tester that allow composing other testers by && them.
|
|
225
255
|
*
|
|
226
256
|
* @param {Array<Tester>} testers the testers to be composed
|
|
227
257
|
*/
|
|
228
|
-
export const and =
|
|
229
|
-
|
|
230
|
-
schema: JsonSchema,
|
|
231
|
-
|
|
232
|
-
|
|
258
|
+
export const and =
|
|
259
|
+
(...testers: Tester[]): Tester =>
|
|
260
|
+
(uischema: UISchemaElement, schema: JsonSchema, context: TesterContext) =>
|
|
261
|
+
testers.reduce(
|
|
262
|
+
(acc, tester) => acc && tester(uischema, schema, context),
|
|
263
|
+
true
|
|
264
|
+
);
|
|
233
265
|
|
|
234
266
|
/**
|
|
235
267
|
* A tester that allow composing other testers by || them.
|
|
236
268
|
*
|
|
237
269
|
* @param {Array<Tester>} testers the testers to be composed
|
|
238
270
|
*/
|
|
239
|
-
export const or =
|
|
240
|
-
|
|
241
|
-
schema: JsonSchema,
|
|
242
|
-
|
|
243
|
-
|
|
271
|
+
export const or =
|
|
272
|
+
(...testers: Tester[]): Tester =>
|
|
273
|
+
(uischema: UISchemaElement, schema: JsonSchema, context: TesterContext) =>
|
|
274
|
+
testers.reduce(
|
|
275
|
+
(acc, tester) => acc || tester(uischema, schema, context),
|
|
276
|
+
false
|
|
277
|
+
);
|
|
244
278
|
/**
|
|
245
279
|
* Create a ranked tester that will associate a number with a given tester, if the
|
|
246
280
|
* latter returns true.
|
|
@@ -248,30 +282,34 @@ export const or = (...testers: Tester[]): Tester => (
|
|
|
248
282
|
* @param {number} rank the rank to be returned in case the tester returns true
|
|
249
283
|
* @param {Tester} tester a tester
|
|
250
284
|
*/
|
|
251
|
-
export const rankWith =
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
};
|
|
285
|
+
export const rankWith =
|
|
286
|
+
(rank: number, tester: Tester) =>
|
|
287
|
+
(
|
|
288
|
+
uischema: UISchemaElement,
|
|
289
|
+
schema: JsonSchema,
|
|
290
|
+
context: TesterContext
|
|
291
|
+
): number => {
|
|
292
|
+
if (tester(uischema, schema, context)) {
|
|
293
|
+
return rank;
|
|
294
|
+
}
|
|
262
295
|
|
|
263
|
-
export const withIncreasedRank = (by: number, rankedTester: RankedTester) => (
|
|
264
|
-
uischema: UISchemaElement,
|
|
265
|
-
schema: JsonSchema,
|
|
266
|
-
context: TesterContext
|
|
267
|
-
): number => {
|
|
268
|
-
const rank = rankedTester(uischema, schema, context);
|
|
269
|
-
if (rank === NOT_APPLICABLE) {
|
|
270
296
|
return NOT_APPLICABLE;
|
|
271
|
-
}
|
|
297
|
+
};
|
|
298
|
+
|
|
299
|
+
export const withIncreasedRank =
|
|
300
|
+
(by: number, rankedTester: RankedTester) =>
|
|
301
|
+
(
|
|
302
|
+
uischema: UISchemaElement,
|
|
303
|
+
schema: JsonSchema,
|
|
304
|
+
context: TesterContext
|
|
305
|
+
): number => {
|
|
306
|
+
const rank = rankedTester(uischema, schema, context);
|
|
307
|
+
if (rank === NOT_APPLICABLE) {
|
|
308
|
+
return NOT_APPLICABLE;
|
|
309
|
+
}
|
|
272
310
|
|
|
273
|
-
|
|
274
|
-
};
|
|
311
|
+
return rank + by;
|
|
312
|
+
};
|
|
275
313
|
|
|
276
314
|
/**
|
|
277
315
|
* Default tester for boolean.
|
|
@@ -287,17 +325,17 @@ export const isObjectControl = and(uiTypeIs('Control'), schemaTypeIs('object'));
|
|
|
287
325
|
|
|
288
326
|
export const isAllOfControl = and(
|
|
289
327
|
uiTypeIs('Control'),
|
|
290
|
-
schemaMatches(schema => schema.hasOwnProperty('allOf'))
|
|
328
|
+
schemaMatches((schema) => schema.hasOwnProperty('allOf'))
|
|
291
329
|
);
|
|
292
330
|
|
|
293
331
|
export const isAnyOfControl = and(
|
|
294
332
|
uiTypeIs('Control'),
|
|
295
|
-
schemaMatches(schema => schema.hasOwnProperty('anyOf'))
|
|
333
|
+
schemaMatches((schema) => schema.hasOwnProperty('anyOf'))
|
|
296
334
|
);
|
|
297
335
|
|
|
298
336
|
export const isOneOfControl = and(
|
|
299
337
|
uiTypeIs('Control'),
|
|
300
|
-
schemaMatches(schema => schema.hasOwnProperty('oneOf'))
|
|
338
|
+
schemaMatches((schema) => schema.hasOwnProperty('oneOf'))
|
|
301
339
|
);
|
|
302
340
|
|
|
303
341
|
/**
|
|
@@ -308,8 +346,8 @@ export const isOneOfControl = and(
|
|
|
308
346
|
export const isEnumControl = and(
|
|
309
347
|
uiTypeIs('Control'),
|
|
310
348
|
or(
|
|
311
|
-
schemaMatches(schema => schema.hasOwnProperty('enum')),
|
|
312
|
-
schemaMatches(schema => schema.hasOwnProperty('const'))
|
|
349
|
+
schemaMatches((schema) => schema.hasOwnProperty('enum')),
|
|
350
|
+
schemaMatches((schema) => schema.hasOwnProperty('const'))
|
|
313
351
|
)
|
|
314
352
|
);
|
|
315
353
|
|
|
@@ -320,10 +358,7 @@ export const isEnumControl = and(
|
|
|
320
358
|
*/
|
|
321
359
|
export const isOneOfEnumControl = and(
|
|
322
360
|
uiTypeIs('Control'),
|
|
323
|
-
schemaMatches(schema =>
|
|
324
|
-
schema.hasOwnProperty('oneOf') &&
|
|
325
|
-
(schema.oneOf as JsonSchema[]).every(s => s.const !== undefined)
|
|
326
|
-
)
|
|
361
|
+
schemaMatches((schema) => isOneOfEnumSchema(schema))
|
|
327
362
|
);
|
|
328
363
|
|
|
329
364
|
/**
|
|
@@ -396,11 +431,15 @@ export const isDateTimeControl = and(
|
|
|
396
431
|
*/
|
|
397
432
|
export const isObjectArray = and(
|
|
398
433
|
schemaMatches(
|
|
399
|
-
(schema, rootSchema) =>
|
|
434
|
+
(schema, rootSchema) =>
|
|
435
|
+
hasType(schema, 'array') &&
|
|
436
|
+
!Array.isArray(resolveSchema(schema, 'items', rootSchema)) // we don't care about tuples
|
|
400
437
|
),
|
|
401
438
|
schemaSubPathMatches('items', (schema, rootSchema) => {
|
|
402
|
-
const resolvedSchema = schema.$ref
|
|
403
|
-
|
|
439
|
+
const resolvedSchema = schema.$ref
|
|
440
|
+
? resolveSchema(rootSchema, schema.$ref, rootSchema)
|
|
441
|
+
: schema;
|
|
442
|
+
return hasType(resolvedSchema, 'object');
|
|
404
443
|
})
|
|
405
444
|
);
|
|
406
445
|
|
|
@@ -417,7 +456,11 @@ const traverse = (
|
|
|
417
456
|
rootSchema: JsonSchema
|
|
418
457
|
): boolean => {
|
|
419
458
|
if (isArray(any)) {
|
|
420
|
-
return reduce(
|
|
459
|
+
return reduce(
|
|
460
|
+
any,
|
|
461
|
+
(acc, el) => acc || traverse(el, pred, rootSchema),
|
|
462
|
+
false
|
|
463
|
+
);
|
|
421
464
|
}
|
|
422
465
|
|
|
423
466
|
if (pred(any)) {
|
|
@@ -454,32 +497,43 @@ export const isObjectArrayWithNesting = (
|
|
|
454
497
|
return false;
|
|
455
498
|
}
|
|
456
499
|
const schemaPath = (uischema as ControlElement).scope;
|
|
457
|
-
const resolvedSchema = resolveSchema(
|
|
500
|
+
const resolvedSchema = resolveSchema(
|
|
501
|
+
schema,
|
|
502
|
+
schemaPath,
|
|
503
|
+
context?.rootSchema ?? schema
|
|
504
|
+
);
|
|
458
505
|
let objectDepth = 0;
|
|
459
506
|
if (resolvedSchema !== undefined && resolvedSchema.items !== undefined) {
|
|
460
507
|
// check if nested arrays
|
|
461
508
|
if (
|
|
462
|
-
traverse(
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
if (hasType(val, 'object')) {
|
|
473
|
-
objectDepth++;
|
|
474
|
-
if (objectDepth === 2) {
|
|
509
|
+
traverse(
|
|
510
|
+
resolvedSchema.items,
|
|
511
|
+
(val) => {
|
|
512
|
+
if (val === schema) {
|
|
513
|
+
return false;
|
|
514
|
+
}
|
|
515
|
+
if (val.$ref !== undefined) {
|
|
516
|
+
return false;
|
|
517
|
+
}
|
|
518
|
+
if (val.anyOf || val.allOf) {
|
|
475
519
|
return true;
|
|
476
520
|
}
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
521
|
+
if (val.oneOf && !isOneOfEnumSchema(val)) {
|
|
522
|
+
return true;
|
|
523
|
+
}
|
|
524
|
+
if (hasType(val, 'object')) {
|
|
525
|
+
objectDepth++;
|
|
526
|
+
if (objectDepth === 2) {
|
|
527
|
+
return true;
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
if (hasType(val, 'array')) {
|
|
531
|
+
return true;
|
|
532
|
+
}
|
|
533
|
+
return false;
|
|
534
|
+
},
|
|
535
|
+
context?.rootSchema
|
|
536
|
+
)
|
|
483
537
|
) {
|
|
484
538
|
return true;
|
|
485
539
|
}
|
|
@@ -516,7 +570,9 @@ export const isPrimitiveArrayControl = and(
|
|
|
516
570
|
!Array.isArray(resolveSchema(schema, 'items', rootSchema)) // we don't care about tuples
|
|
517
571
|
),
|
|
518
572
|
schemaSubPathMatches('items', (schema, rootSchema) => {
|
|
519
|
-
const resolvedSchema = schema.$ref
|
|
573
|
+
const resolvedSchema = schema.$ref
|
|
574
|
+
? resolveSchema(rootSchema, schema.$ref, rootSchema)
|
|
575
|
+
: schema;
|
|
520
576
|
const types = deriveTypes(resolvedSchema);
|
|
521
577
|
return (
|
|
522
578
|
types.length === 1 &&
|
|
@@ -535,7 +591,7 @@ export const isRangeControl = and(
|
|
|
535
591
|
uiTypeIs('Control'),
|
|
536
592
|
or(schemaTypeIs('number'), schemaTypeIs('integer')),
|
|
537
593
|
schemaMatches(
|
|
538
|
-
schema =>
|
|
594
|
+
(schema) =>
|
|
539
595
|
schema.hasOwnProperty('maximum') &&
|
|
540
596
|
schema.hasOwnProperty('minimum') &&
|
|
541
597
|
schema.hasOwnProperty('default')
|
|
@@ -567,7 +623,7 @@ export const hasCategory = (categorization: Categorization): boolean => {
|
|
|
567
623
|
}
|
|
568
624
|
// all children of the categorization have to be categories
|
|
569
625
|
return categorization.elements
|
|
570
|
-
.map(elem =>
|
|
626
|
+
.map((elem) =>
|
|
571
627
|
isCategorization(elem) ? hasCategory(elem) : isCategory(elem)
|
|
572
628
|
)
|
|
573
629
|
.reduce((prev, curr) => prev && curr, true);
|
|
@@ -576,9 +632,7 @@ export const hasCategory = (categorization: Categorization): boolean => {
|
|
|
576
632
|
export const categorizationHasCategory = (uischema: UISchemaElement) =>
|
|
577
633
|
hasCategory(uischema as Categorization);
|
|
578
634
|
|
|
579
|
-
export const not =
|
|
580
|
-
|
|
581
|
-
schema: JsonSchema,
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
) => !tester(uischema, schema, context);
|
|
635
|
+
export const not =
|
|
636
|
+
(tester: Tester): Tester =>
|
|
637
|
+
(uischema: UISchemaElement, schema: JsonSchema, context: TesterContext) =>
|
|
638
|
+
!tester(uischema, schema, context);
|
package/src/util/cell.ts
CHANGED
|
@@ -24,9 +24,8 @@
|
|
|
24
24
|
*/
|
|
25
25
|
|
|
26
26
|
import isEmpty from 'lodash/isEmpty';
|
|
27
|
-
import union from 'lodash/union';
|
|
28
|
-
import type { JsonFormsCellRendererRegistryEntry } from '../reducers';
|
|
29
27
|
import {
|
|
28
|
+
getErrorTranslator,
|
|
30
29
|
getAjv,
|
|
31
30
|
getConfig,
|
|
32
31
|
getData,
|
|
@@ -34,15 +33,10 @@ import {
|
|
|
34
33
|
getSchema,
|
|
35
34
|
getTranslator,
|
|
36
35
|
} from '../reducers';
|
|
36
|
+
import type { JsonFormsCellRendererRegistryEntry } from '../reducers';
|
|
37
37
|
import type { AnyAction, Dispatch } from './type';
|
|
38
|
-
import {
|
|
39
|
-
|
|
40
|
-
Resolve,
|
|
41
|
-
} from './util';
|
|
42
|
-
import {
|
|
43
|
-
isInherentlyEnabled,
|
|
44
|
-
isVisible,
|
|
45
|
-
} from './runtime';
|
|
38
|
+
import { Resolve } from './util';
|
|
39
|
+
import { isInherentlyEnabled, isVisible } from './runtime';
|
|
46
40
|
import {
|
|
47
41
|
DispatchPropsOfControl,
|
|
48
42
|
EnumOption,
|
|
@@ -53,11 +47,9 @@ import {
|
|
|
53
47
|
OwnPropsOfEnum,
|
|
54
48
|
StatePropsOfScopedRenderer,
|
|
55
49
|
} from './renderer';
|
|
50
|
+
import { getCombinedErrorMessage, getI18nKeyPrefix } from '../i18n';
|
|
56
51
|
import type { JsonFormsState } from '../store';
|
|
57
52
|
import type { JsonSchema } from '../models';
|
|
58
|
-
import { getI18nKeyPrefix } from '../i18n';
|
|
59
|
-
|
|
60
|
-
export type { JsonFormsCellRendererRegistryEntry };
|
|
61
53
|
|
|
62
54
|
export interface OwnPropsOfCell extends OwnPropsOfControl {
|
|
63
55
|
data?: any;
|
|
@@ -126,7 +118,7 @@ export const mapStateToCellProps = (
|
|
|
126
118
|
|
|
127
119
|
/* When determining the enabled state of cells we take a shortcut: At the
|
|
128
120
|
* moment it's only possible to configure enablement and disablement at the
|
|
129
|
-
* control level. Therefore the renderer using the cell, for example a
|
|
121
|
+
* control level. Therefore the renderer using the cell, for example a
|
|
130
122
|
* table renderer, determines whether a cell is enabled and should hand
|
|
131
123
|
* over the prop themselves. If that prop was given, we prefer it over
|
|
132
124
|
* anything else to save evaluation effort (except for the global readonly
|
|
@@ -148,8 +140,15 @@ export const mapStateToCellProps = (
|
|
|
148
140
|
);
|
|
149
141
|
}
|
|
150
142
|
|
|
151
|
-
const
|
|
152
|
-
|
|
143
|
+
const t = getTranslator()(state);
|
|
144
|
+
const te = getErrorTranslator()(state);
|
|
145
|
+
const errors = getCombinedErrorMessage(
|
|
146
|
+
getErrorAt(path, schema)(state),
|
|
147
|
+
te,
|
|
148
|
+
t,
|
|
149
|
+
schema,
|
|
150
|
+
uischema,
|
|
151
|
+
path
|
|
153
152
|
);
|
|
154
153
|
const isValid = isEmpty(errors);
|
|
155
154
|
|
|
@@ -166,7 +165,7 @@ export const mapStateToCellProps = (
|
|
|
166
165
|
config: getConfig(state),
|
|
167
166
|
rootSchema,
|
|
168
167
|
renderers,
|
|
169
|
-
cells
|
|
168
|
+
cells,
|
|
170
169
|
};
|
|
171
170
|
};
|
|
172
171
|
|
|
@@ -175,11 +174,11 @@ export const mapStateToDispatchCellProps = (
|
|
|
175
174
|
ownProps: OwnPropsOfCell
|
|
176
175
|
): DispatchCellStateProps => {
|
|
177
176
|
const props: StatePropsOfCell = mapStateToCellProps(state, ownProps);
|
|
178
|
-
const { renderers, cells, ...otherOwnProps } = ownProps;
|
|
177
|
+
const { renderers: _renderers, cells, ...otherOwnProps } = ownProps;
|
|
179
178
|
return {
|
|
180
179
|
...props,
|
|
181
180
|
...otherOwnProps,
|
|
182
|
-
cells: cells || state.jsonforms.cells || []
|
|
181
|
+
cells: cells || state.jsonforms.cells || [],
|
|
183
182
|
};
|
|
184
183
|
};
|
|
185
184
|
|
|
@@ -198,7 +197,7 @@ export const defaultMapStateToEnumCellProps = (
|
|
|
198
197
|
const props: StatePropsOfCell = mapStateToCellProps(state, ownProps);
|
|
199
198
|
const options: EnumOption[] =
|
|
200
199
|
ownProps.options ||
|
|
201
|
-
props.schema.enum?.map(e =>
|
|
200
|
+
props.schema.enum?.map((e) =>
|
|
202
201
|
enumToEnumOptionMapper(
|
|
203
202
|
e,
|
|
204
203
|
getTranslator()(state),
|
|
@@ -210,11 +209,11 @@ export const defaultMapStateToEnumCellProps = (
|
|
|
210
209
|
props.schema.const,
|
|
211
210
|
getTranslator()(state),
|
|
212
211
|
getI18nKeyPrefix(props.schema, props.uischema, props.path)
|
|
213
|
-
)
|
|
212
|
+
),
|
|
214
213
|
]);
|
|
215
214
|
return {
|
|
216
215
|
...props,
|
|
217
|
-
options
|
|
216
|
+
options,
|
|
218
217
|
};
|
|
219
218
|
};
|
|
220
219
|
|
|
@@ -231,7 +230,7 @@ export const mapStateToOneOfEnumCellProps = (
|
|
|
231
230
|
const props: StatePropsOfCell = mapStateToCellProps(state, ownProps);
|
|
232
231
|
const options: EnumOption[] =
|
|
233
232
|
ownProps.options ||
|
|
234
|
-
(props.schema.oneOf as JsonSchema[])?.map(oneOfSubSchema =>
|
|
233
|
+
(props.schema.oneOf as JsonSchema[])?.map((oneOfSubSchema) =>
|
|
235
234
|
oneOfToEnumOptionMapper(
|
|
236
235
|
oneOfSubSchema,
|
|
237
236
|
getTranslator()(state),
|
|
@@ -240,11 +239,10 @@ export const mapStateToOneOfEnumCellProps = (
|
|
|
240
239
|
);
|
|
241
240
|
return {
|
|
242
241
|
...props,
|
|
243
|
-
options
|
|
242
|
+
options,
|
|
244
243
|
};
|
|
245
244
|
};
|
|
246
245
|
|
|
247
|
-
|
|
248
246
|
/**
|
|
249
247
|
* Synonym for mapDispatchToControlProps.
|
|
250
248
|
*
|
|
@@ -264,6 +262,6 @@ export const defaultMapDispatchToControlProps =
|
|
|
264
262
|
const { handleChange } = mapDispatchToCellProps(dispatch);
|
|
265
263
|
|
|
266
264
|
return {
|
|
267
|
-
handleChange: ownProps.handleChange || handleChange
|
|
265
|
+
handleChange: ownProps.handleChange || handleChange,
|
|
268
266
|
};
|
|
269
267
|
};
|