@jsonforms/core 3.0.0-beta.1 → 3.0.0-beta.4
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 +11 -0
- package/docs/assets/js/search.json +1 -1
- package/docs/enums/ruleeffect.html +4 -4
- package/docs/globals.html +357 -217
- package/docs/index.html +29 -4
- package/docs/interfaces/addcellrendereraction.html +3 -3
- package/docs/interfaces/addrendereraction.html +3 -3
- package/docs/interfaces/adduischemaaction.html +3 -3
- package/docs/interfaces/andcondition.html +2 -2
- package/docs/interfaces/arraycontrolprops.html +21 -21
- package/docs/interfaces/arraylayoutprops.html +21 -21
- package/docs/interfaces/categorization.html +5 -5
- package/docs/interfaces/category.html +5 -5
- package/docs/interfaces/cellprops.html +12 -12
- package/docs/interfaces/combinatorrendererprops.html +143 -36
- package/docs/interfaces/composablecondition.html +2 -2
- package/docs/interfaces/condition.html +1 -1
- package/docs/interfaces/controlelement.html +22 -4
- package/docs/interfaces/controlprops.html +16 -16
- package/docs/interfaces/controlstate.html +2 -2
- package/docs/interfaces/controlwithdetailprops.html +17 -17
- package/docs/interfaces/dispatchcellprops.html +10 -10
- package/docs/interfaces/dispatchcellstateprops.html +10 -10
- package/docs/interfaces/dispatchpropsofarraycontrol.html +4 -4
- package/docs/interfaces/dispatchpropsofcontrol.html +1 -1
- package/docs/interfaces/dispatchpropsofmultienumcontrol.html +2 -2
- package/docs/interfaces/enumcellprops.html +13 -13
- package/docs/interfaces/enumoption.html +2 -2
- package/docs/interfaces/grouplayout.html +5 -5
- package/docs/interfaces/horizontallayout.html +4 -4
- package/docs/interfaces/initactionoptions.html +14 -0
- package/docs/interfaces/internationalizable.html +167 -0
- package/docs/interfaces/jsonformscore.html +17 -3
- package/docs/interfaces/jsonformsprops.html +9 -9
- package/docs/interfaces/labeldescription.html +2 -2
- package/docs/interfaces/labelelement.html +4 -4
- package/docs/interfaces/layout.html +4 -4
- package/docs/interfaces/layoutprops.html +10 -10
- package/docs/interfaces/leafcondition.html +2 -2
- package/docs/interfaces/orcondition.html +2 -2
- package/docs/interfaces/ownpropsofcell.html +9 -9
- package/docs/interfaces/ownpropsofcontrol.html +9 -12
- package/docs/interfaces/ownpropsofenum.html +1 -1
- package/docs/interfaces/ownpropsofenumcell.html +10 -10
- package/docs/interfaces/ownpropsofjsonformsrenderer.html +8 -8
- package/docs/interfaces/ownpropsoflayout.html +9 -9
- package/docs/interfaces/ownpropsofmasterlistitem.html +6 -6
- package/docs/interfaces/ownpropsofrenderer.html +8 -8
- package/docs/interfaces/registerdefaultdataaction.html +3 -3
- package/docs/interfaces/removecellrendereraction.html +3 -3
- package/docs/interfaces/removerendereraction.html +3 -3
- package/docs/interfaces/removeuischemaaction.html +2 -2
- package/docs/interfaces/rendererprops.html +9 -9
- package/docs/interfaces/rule.html +2 -2
- package/docs/interfaces/schemabasedcondition.html +2 -2
- package/docs/interfaces/setajvaction.html +2 -2
- package/docs/interfaces/setconfigaction.html +2 -2
- package/docs/interfaces/setlocaleaction.html +2 -2
- package/docs/interfaces/setschemaaction.html +2 -2
- package/docs/interfaces/settranslatoraction.html +3 -3
- package/docs/interfaces/setuischemaaction.html +2 -2
- package/docs/interfaces/setvalidationmodeaction.html +2 -2
- package/docs/interfaces/statepropsofarraycontrol.html +17 -17
- package/docs/interfaces/statepropsofarraylayout.html +17 -17
- package/docs/interfaces/statepropsofcell.html +11 -11
- package/docs/interfaces/statepropsofcombinator.html +147 -40
- package/docs/interfaces/statepropsofcontrol.html +18 -15
- package/docs/interfaces/statepropsofcontrolwithdetail.html +16 -16
- package/docs/interfaces/statepropsofenumcell.html +12 -12
- package/docs/interfaces/statepropsofjsonformsrenderer.html +9 -9
- package/docs/interfaces/statepropsoflayout.html +10 -10
- package/docs/interfaces/statepropsofmasteritem.html +7 -7
- package/docs/interfaces/statepropsofrenderer.html +9 -9
- package/docs/interfaces/statepropsofscopedrenderer.html +12 -12
- package/docs/interfaces/uischemaelement.html +3 -3
- package/docs/interfaces/unregisterdefaultdataaction.html +2 -2
- package/docs/interfaces/updatei18naction.html +4 -4
- package/docs/interfaces/verticallayout.html +4 -4
- package/docs/interfaces/withclassname.html +1 -1
- package/lib/actions/actions.d.ts +1 -0
- package/lib/jsonforms-core.cjs.js +201 -179
- package/lib/jsonforms-core.cjs.js.map +1 -1
- package/lib/jsonforms-core.esm.js +182 -166
- package/lib/jsonforms-core.esm.js.map +1 -1
- package/lib/models/uischema.d.ts +10 -1
- package/lib/reducers/core.d.ts +1 -0
- package/lib/reducers/reducers.d.ts +2 -2
- package/lib/testers/testers.d.ts +8 -7
- package/lib/util/combinators.d.ts +0 -1
- package/lib/util/path.d.ts +10 -0
- package/lib/util/renderer.d.ts +2 -2
- package/lib/util/resolvers.d.ts +1 -1
- package/lib/util/util.d.ts +1 -1
- package/package.json +2 -2
- package/src/actions/actions.ts +1 -0
- package/src/generators/uischema.ts +4 -4
- package/src/i18n/i18nUtil.ts +10 -7
- package/src/models/uischema.ts +14 -1
- package/src/reducers/core.ts +30 -3
- package/src/reducers/reducers.ts +12 -4
- package/src/testers/testers.ts +61 -34
- package/src/util/combinators.ts +17 -32
- package/src/util/label.ts +2 -2
- package/src/util/path.ts +18 -6
- package/src/util/renderer.ts +20 -32
- package/src/util/resolvers.ts +57 -68
- package/src/util/util.ts +1 -1
- package/stats.html +1 -1
- package/test/generators/uischema.test.ts +18 -0
- package/test/i18n/i18nUtil.test.ts +41 -1
- package/test/reducers/core.test.ts +203 -1
- package/test/testers.test.ts +208 -120
- package/test/util/path.test.ts +37 -20
- package/test/util/renderer.test.ts +1 -1
- package/test/util/resolvers.test.ts +99 -8
package/lib/models/uischema.d.ts
CHANGED
|
@@ -9,6 +9,14 @@ export interface Scopable {
|
|
|
9
9
|
*/
|
|
10
10
|
scope: string;
|
|
11
11
|
}
|
|
12
|
+
/**
|
|
13
|
+
* Interface for describing an UI schema element that can provide an internationalization base key.
|
|
14
|
+
* If defined, this key is suffixed to derive applicable message keys for the UI schema element.
|
|
15
|
+
* For example, such suffixes are `.label` or `.description` to derive the corresponding message keys for a control element.
|
|
16
|
+
*/
|
|
17
|
+
export interface Internationalizable {
|
|
18
|
+
i18n?: string;
|
|
19
|
+
}
|
|
12
20
|
/**
|
|
13
21
|
* A rule that may be attached to any UI schema element.
|
|
14
22
|
*/
|
|
@@ -163,7 +171,7 @@ export interface LabelElement extends UISchemaElement {
|
|
|
163
171
|
* A control element. The scope property of the control determines
|
|
164
172
|
* to which part of the schema the control should be bound.
|
|
165
173
|
*/
|
|
166
|
-
export interface ControlElement extends UISchemaElement, Scopable {
|
|
174
|
+
export interface ControlElement extends UISchemaElement, Scopable, Internationalizable {
|
|
167
175
|
type: 'Control';
|
|
168
176
|
/**
|
|
169
177
|
* An optional label that will be associated with the control
|
|
@@ -197,5 +205,6 @@ export interface Categorization extends UISchemaElement {
|
|
|
197
205
|
*/
|
|
198
206
|
elements: (Category | Categorization)[];
|
|
199
207
|
}
|
|
208
|
+
export declare const isInternationalized: (element: unknown) => element is Required<Internationalizable>;
|
|
200
209
|
export declare const isGroup: (layout: Layout) => layout is GroupLayout;
|
|
201
210
|
export declare const isLayout: (uischema: UISchemaElement) => uischema is Layout;
|
package/lib/reducers/core.d.ts
CHANGED
|
@@ -17,10 +17,10 @@ export declare const jsonFormsReducerConfig: {
|
|
|
17
17
|
* @param schema the JSON schema describing the data to be rendered
|
|
18
18
|
* @param schemaPath the according schema path
|
|
19
19
|
* @param path the instance path
|
|
20
|
-
* @param
|
|
20
|
+
* @param fallback the type of the layout to use or a UI-schema-generator function
|
|
21
21
|
* @param control may be checked for embedded inline uischema options
|
|
22
22
|
*/
|
|
23
|
-
export declare const findUISchema: (uischemas: JsonFormsUISchemaRegistryEntry[], schema: JsonSchema, schemaPath: string, path: string,
|
|
23
|
+
export declare const findUISchema: (uischemas: JsonFormsUISchemaRegistryEntry[], schema: JsonSchema, schemaPath: string, path: string, fallback?: string | (() => UISchemaElement), control?: ControlElement, rootSchema?: JsonSchema) => UISchemaElement;
|
|
24
24
|
export declare const getErrorAt: (instancePath: string, schema: JsonSchema) => (state: JsonFormsState) => import("ajv").ErrorObject<string, Record<string, any>, unknown>[];
|
|
25
25
|
export declare const getSubErrorsAt: (instancePath: string, schema: JsonSchema) => (state: JsonFormsState) => import("ajv").ErrorObject<string, Record<string, any>, unknown>[];
|
|
26
26
|
export declare const getConfig: (state: JsonFormsState) => any;
|
package/lib/testers/testers.d.ts
CHANGED
|
@@ -7,12 +7,13 @@ import { Categorization, ControlElement, JsonSchema, UISchemaElement } from '../
|
|
|
7
7
|
export declare const NOT_APPLICABLE = -1;
|
|
8
8
|
/**
|
|
9
9
|
* A tester is a function that receives an UI schema and a JSON schema and returns a boolean.
|
|
10
|
+
* The rootSchema is handed over as context. Can be used to resolve references.
|
|
10
11
|
*/
|
|
11
|
-
export declare type Tester = (uischema: UISchemaElement, schema: JsonSchema) => boolean;
|
|
12
|
+
export declare type Tester = (uischema: UISchemaElement, schema: JsonSchema, rootSchema: JsonSchema) => boolean;
|
|
12
13
|
/**
|
|
13
14
|
* A ranked tester associates a tester with a number.
|
|
14
15
|
*/
|
|
15
|
-
export declare type RankedTester = (uischema: UISchemaElement, schema: JsonSchema) => number;
|
|
16
|
+
export declare type RankedTester = (uischema: UISchemaElement, schema: JsonSchema, rootSchema: JsonSchema) => number;
|
|
16
17
|
export declare const isControl: (uischema: any) => uischema is ControlElement;
|
|
17
18
|
/**
|
|
18
19
|
* Only applicable for Controls.
|
|
@@ -24,8 +25,8 @@ export declare const isControl: (uischema: any) => uischema is ControlElement;
|
|
|
24
25
|
* @param {(JsonSchema) => boolean} predicate the predicate that should be
|
|
25
26
|
* applied to the resolved sub-schema
|
|
26
27
|
*/
|
|
27
|
-
export declare const schemaMatches: (predicate: (schema: JsonSchema) => boolean) => Tester;
|
|
28
|
-
export declare const schemaSubPathMatches: (subPath: string, predicate: (schema: JsonSchema) => boolean) => Tester;
|
|
28
|
+
export declare const schemaMatches: (predicate: (schema: JsonSchema, rootSchema: JsonSchema) => boolean) => Tester;
|
|
29
|
+
export declare const schemaSubPathMatches: (subPath: string, predicate: (schema: JsonSchema, rootSchema: JsonSchema) => boolean) => Tester;
|
|
29
30
|
/**
|
|
30
31
|
* Only applicable for Controls.
|
|
31
32
|
*
|
|
@@ -96,8 +97,8 @@ export declare const or: (...testers: Tester[]) => Tester;
|
|
|
96
97
|
* @param {number} rank the rank to be returned in case the tester returns true
|
|
97
98
|
* @param {Tester} tester a tester
|
|
98
99
|
*/
|
|
99
|
-
export declare const rankWith: (rank: number, tester: Tester) => (uischema: UISchemaElement, schema: JsonSchema) => number;
|
|
100
|
-
export declare const withIncreasedRank: (by: number, rankedTester: RankedTester) => (uischema: UISchemaElement, schema: JsonSchema) => number;
|
|
100
|
+
export declare const rankWith: (rank: number, tester: Tester) => (uischema: UISchemaElement, schema: JsonSchema, rootSchema: JsonSchema) => number;
|
|
101
|
+
export declare const withIncreasedRank: (by: number, rankedTester: RankedTester) => (uischema: UISchemaElement, schema: JsonSchema, rootSchema: JsonSchema) => number;
|
|
101
102
|
/**
|
|
102
103
|
* Default tester for boolean.
|
|
103
104
|
* @type {RankedTester}
|
|
@@ -172,7 +173,7 @@ export declare const isObjectArray: Tester;
|
|
|
172
173
|
* @type {Tester}
|
|
173
174
|
*/
|
|
174
175
|
export declare const isObjectArrayControl: Tester;
|
|
175
|
-
export declare const isObjectArrayWithNesting: (uischema: UISchemaElement, schema: JsonSchema) => boolean;
|
|
176
|
+
export declare const isObjectArrayWithNesting: (uischema: UISchemaElement, schema: JsonSchema, rootSchema: JsonSchema) => boolean;
|
|
176
177
|
/**
|
|
177
178
|
* Synonym for isObjectArrayControl
|
|
178
179
|
*/
|
|
@@ -6,5 +6,4 @@ export interface CombinatorSubSchemaRenderInfo {
|
|
|
6
6
|
label: string;
|
|
7
7
|
}
|
|
8
8
|
export declare type CombinatorKeyword = 'anyOf' | 'oneOf' | 'allOf';
|
|
9
|
-
export declare const resolveSubSchemas: (schema: JsonSchema, rootSchema: JsonSchema, keyword: CombinatorKeyword) => JsonSchema;
|
|
10
9
|
export declare const createCombinatorRenderInfos: (combinatorSubSchemas: JsonSchema[], rootSchema: JsonSchema, keyword: CombinatorKeyword, control: ControlElement, path: string, uischemas: JsonFormsUISchemaRegistryEntry[]) => CombinatorSubSchemaRenderInfo[];
|
package/lib/util/path.d.ts
CHANGED
|
@@ -23,3 +23,13 @@ export declare const toDataPathSegments: (schemaPath: string) => string[];
|
|
|
23
23
|
*/
|
|
24
24
|
export declare const toDataPath: (schemaPath: string) => string;
|
|
25
25
|
export declare const composeWithUi: (scopableUi: Scopable, path: string) => string;
|
|
26
|
+
/**
|
|
27
|
+
* Encodes the given segment to be used as part of a JSON Pointer
|
|
28
|
+
*
|
|
29
|
+
* JSON Pointer has special meaning for "/" and "~", therefore these must be encoded
|
|
30
|
+
*/
|
|
31
|
+
export declare const encode: (segment: string) => string;
|
|
32
|
+
/**
|
|
33
|
+
* Decodes a given JSON Pointer segment to its "normal" representation
|
|
34
|
+
*/
|
|
35
|
+
export declare const decode: (pointerSegment: string) => string;
|
package/lib/util/renderer.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ControlElement, JsonSchema, UISchemaElement } from '../models';
|
|
2
|
-
import
|
|
2
|
+
import { JsonFormsCellRendererRegistryEntry, JsonFormsRendererRegistryEntry } from '../reducers';
|
|
3
3
|
import { JsonFormsUISchemaRegistryEntry } from '../reducers';
|
|
4
4
|
import { RankedTester } from '../testers';
|
|
5
5
|
import { CombinatorKeyword } from './combinators';
|
|
@@ -359,7 +359,7 @@ export declare const controlDefaultProps: {
|
|
|
359
359
|
path: string;
|
|
360
360
|
direction: 'row' | 'column';
|
|
361
361
|
};
|
|
362
|
-
export interface StatePropsOfCombinator extends
|
|
362
|
+
export interface StatePropsOfCombinator extends StatePropsOfControl {
|
|
363
363
|
rootSchema: JsonSchema;
|
|
364
364
|
path: string;
|
|
365
365
|
id: string;
|
package/lib/util/resolvers.d.ts
CHANGED
|
@@ -22,4 +22,4 @@ export declare const findAllRefs: (schema: JsonSchema, result?: ReferenceSchemaM
|
|
|
22
22
|
* @param {JsonSchema} rootSchema the actual root schema
|
|
23
23
|
* @returns {JsonSchema} the resolved sub-schema
|
|
24
24
|
*/
|
|
25
|
-
export declare const resolveSchema: (schema: JsonSchema, schemaPath: string, rootSchema
|
|
25
|
+
export declare const resolveSchema: (schema: JsonSchema, schemaPath: string, rootSchema: JsonSchema) => JsonSchema;
|
package/lib/util/util.d.ts
CHANGED
|
@@ -18,7 +18,7 @@ export declare const deriveTypes: (jsonSchema: JsonSchema) => string[];
|
|
|
18
18
|
* Convenience wrapper around resolveData and resolveSchema.
|
|
19
19
|
*/
|
|
20
20
|
export declare const Resolve: {
|
|
21
|
-
schema(schema: JsonSchema, schemaPath: string, rootSchema
|
|
21
|
+
schema(schema: JsonSchema, schemaPath: string, rootSchema: JsonSchema): JsonSchema;
|
|
22
22
|
data(data: any, path: string): any;
|
|
23
23
|
};
|
|
24
24
|
export declare const Paths: {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jsonforms/core",
|
|
3
|
-
"version": "3.0.0-beta.
|
|
3
|
+
"version": "3.0.0-beta.4",
|
|
4
4
|
"description": "Core module of JSON Forms",
|
|
5
5
|
"repository": "https://github.com/eclipsesource/jsonforms",
|
|
6
6
|
"bugs": "https://github.com/eclipsesource/jsonforms/issues",
|
|
@@ -88,5 +88,5 @@
|
|
|
88
88
|
"typedoc": "^0.19.2",
|
|
89
89
|
"typescript": "4.2.3"
|
|
90
90
|
},
|
|
91
|
-
"gitHead": "
|
|
91
|
+
"gitHead": "413b9767ea8e2c0b6adb3919f5e6b76263d4be31"
|
|
92
92
|
}
|
package/src/actions/actions.ts
CHANGED
|
@@ -35,7 +35,7 @@ import {
|
|
|
35
35
|
Layout,
|
|
36
36
|
UISchemaElement
|
|
37
37
|
} from '../models';
|
|
38
|
-
import { deriveTypes, resolveSchema } from '../util';
|
|
38
|
+
import { deriveTypes, encode, resolveSchema } from '../util';
|
|
39
39
|
|
|
40
40
|
/**
|
|
41
41
|
* Creates a new ILayout.
|
|
@@ -122,7 +122,7 @@ const generateUISchema = (
|
|
|
122
122
|
): UISchemaElement => {
|
|
123
123
|
if (!isEmpty(jsonSchema) && jsonSchema.$ref !== undefined) {
|
|
124
124
|
return generateUISchema(
|
|
125
|
-
resolveSchema(rootSchema, jsonSchema.$ref),
|
|
125
|
+
resolveSchema(rootSchema, jsonSchema.$ref, rootSchema),
|
|
126
126
|
schemaElements,
|
|
127
127
|
currentRef,
|
|
128
128
|
schemaName,
|
|
@@ -162,9 +162,9 @@ const generateUISchema = (
|
|
|
162
162
|
const nextRef: string = currentRef + '/properties';
|
|
163
163
|
Object.keys(jsonSchema.properties).map(propName => {
|
|
164
164
|
let value = jsonSchema.properties[propName];
|
|
165
|
-
const ref = `${nextRef}/${propName}`;
|
|
165
|
+
const ref = `${nextRef}/${encode(propName)}`;
|
|
166
166
|
if (value.$ref !== undefined) {
|
|
167
|
-
value = resolveSchema(rootSchema, value.$ref);
|
|
167
|
+
value = resolveSchema(rootSchema, value.$ref, rootSchema);
|
|
168
168
|
}
|
|
169
169
|
generateUISchema(
|
|
170
170
|
value,
|
package/src/i18n/i18nUtil.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ErrorObject } from 'ajv';
|
|
2
|
-
import { UISchemaElement } from '../models';
|
|
2
|
+
import { isInternationalized, UISchemaElement } from '../models';
|
|
3
3
|
import { getControlPath } from '../reducers';
|
|
4
4
|
import { formatErrorMessage } from '../util';
|
|
5
5
|
import { i18nJsonSchema, ErrorTranslator, Translator } from './i18nTypes';
|
|
@@ -8,7 +8,10 @@ export const getI18nKeyPrefixBySchema = (
|
|
|
8
8
|
schema: i18nJsonSchema | undefined,
|
|
9
9
|
uischema: UISchemaElement | undefined
|
|
10
10
|
): string | undefined => {
|
|
11
|
-
|
|
11
|
+
if (isInternationalized(uischema)) {
|
|
12
|
+
return uischema.i18n;
|
|
13
|
+
}
|
|
14
|
+
return schema?.i18n ?? undefined;
|
|
12
15
|
};
|
|
13
16
|
|
|
14
17
|
/**
|
|
@@ -54,26 +57,26 @@ export const defaultErrorTranslator: ErrorTranslator = (error, t, uischema) => {
|
|
|
54
57
|
getControlPath(error),
|
|
55
58
|
`error.${error.keyword}`
|
|
56
59
|
);
|
|
57
|
-
const specializedKeywordMessage = t(i18nKey, undefined);
|
|
60
|
+
const specializedKeywordMessage = t(i18nKey, undefined, { error } );
|
|
58
61
|
if (specializedKeywordMessage !== undefined) {
|
|
59
62
|
return specializedKeywordMessage;
|
|
60
63
|
}
|
|
61
64
|
|
|
62
65
|
// check whether there is a generic keyword message
|
|
63
|
-
const genericKeywordMessage = t(`error.${error.keyword}`, undefined);
|
|
66
|
+
const genericKeywordMessage = t(`error.${error.keyword}`, undefined, { error });
|
|
64
67
|
if (genericKeywordMessage !== undefined) {
|
|
65
68
|
return genericKeywordMessage;
|
|
66
69
|
}
|
|
67
70
|
|
|
68
71
|
// check whether there is a customization for the default message
|
|
69
|
-
const messageCustomization = t(error.message, undefined);
|
|
72
|
+
const messageCustomization = t(error.message, undefined, { error });
|
|
70
73
|
if (messageCustomization !== undefined) {
|
|
71
74
|
return messageCustomization;
|
|
72
75
|
}
|
|
73
76
|
|
|
74
77
|
// rewrite required property messages (if they were not customized) as we place them next to the respective input
|
|
75
78
|
if (error.keyword === 'required' && error.message?.startsWith('must have required property')) {
|
|
76
|
-
return t('is a required property', 'is a required property');
|
|
79
|
+
return t('is a required property', 'is a required property', { error });
|
|
77
80
|
}
|
|
78
81
|
|
|
79
82
|
return error.message;
|
|
@@ -94,7 +97,7 @@ export const getCombinedErrorMessage = (
|
|
|
94
97
|
if (errors.length > 0 && t) {
|
|
95
98
|
// check whether there is a special message which overwrites all others
|
|
96
99
|
const customErrorKey = getI18nKey(schema, uischema, path, 'error.custom');
|
|
97
|
-
const specializedErrorMessage = t(customErrorKey, undefined);
|
|
100
|
+
const specializedErrorMessage = t(customErrorKey, undefined, {schema, uischema, path, errors});
|
|
98
101
|
if (specializedErrorMessage !== undefined) {
|
|
99
102
|
return specializedErrorMessage;
|
|
100
103
|
}
|
package/src/models/uischema.ts
CHANGED
|
@@ -36,6 +36,15 @@ export interface Scopable {
|
|
|
36
36
|
scope: string;
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
+
/**
|
|
40
|
+
* Interface for describing an UI schema element that can provide an internationalization base key.
|
|
41
|
+
* If defined, this key is suffixed to derive applicable message keys for the UI schema element.
|
|
42
|
+
* For example, such suffixes are `.label` or `.description` to derive the corresponding message keys for a control element.
|
|
43
|
+
*/
|
|
44
|
+
export interface Internationalizable {
|
|
45
|
+
i18n?: string;
|
|
46
|
+
}
|
|
47
|
+
|
|
39
48
|
/**
|
|
40
49
|
* A rule that may be attached to any UI schema element.
|
|
41
50
|
*/
|
|
@@ -207,7 +216,7 @@ export interface LabelElement extends UISchemaElement {
|
|
|
207
216
|
* A control element. The scope property of the control determines
|
|
208
217
|
* to which part of the schema the control should be bound.
|
|
209
218
|
*/
|
|
210
|
-
export interface ControlElement extends UISchemaElement, Scopable {
|
|
219
|
+
export interface ControlElement extends UISchemaElement, Scopable, Internationalizable {
|
|
211
220
|
type: 'Control';
|
|
212
221
|
/**
|
|
213
222
|
* An optional label that will be associated with the control
|
|
@@ -244,6 +253,10 @@ export interface Categorization extends UISchemaElement {
|
|
|
244
253
|
elements: (Category | Categorization)[];
|
|
245
254
|
}
|
|
246
255
|
|
|
256
|
+
export const isInternationalized = (element: unknown): element is Required<Internationalizable> => {
|
|
257
|
+
return typeof element === 'object' && element !== null && typeof (element as Internationalizable).i18n === 'string';
|
|
258
|
+
}
|
|
259
|
+
|
|
247
260
|
export const isGroup = (layout: Layout): layout is GroupLayout =>
|
|
248
261
|
layout.type === 'Group';
|
|
249
262
|
|
package/src/reducers/core.ts
CHANGED
|
@@ -65,6 +65,7 @@ export interface JsonFormsCore {
|
|
|
65
65
|
schema: JsonSchema;
|
|
66
66
|
uischema: UISchemaElement;
|
|
67
67
|
errors?: ErrorObject[];
|
|
68
|
+
additionalErrors?: ErrorObject[];
|
|
68
69
|
validator?: ValidateFunction;
|
|
69
70
|
ajv?: Ajv;
|
|
70
71
|
validationMode?: ValidationMode;
|
|
@@ -78,6 +79,7 @@ const initState: JsonFormsCore = {
|
|
|
78
79
|
validator: undefined,
|
|
79
80
|
ajv: undefined,
|
|
80
81
|
validationMode: 'ValidateAndShow',
|
|
82
|
+
additionalErrors: []
|
|
81
83
|
};
|
|
82
84
|
|
|
83
85
|
const reuseAjvForSchema = (ajv: Ajv, schema: JsonSchema): Ajv => {
|
|
@@ -133,6 +135,23 @@ const hasValidationModeOption = (option: any): option is InitActionOptions => {
|
|
|
133
135
|
return false;
|
|
134
136
|
};
|
|
135
137
|
|
|
138
|
+
const hasAdditionalErrorsOption = (option: any): option is InitActionOptions => {
|
|
139
|
+
if (option) {
|
|
140
|
+
return option.additionalErrors !== undefined;
|
|
141
|
+
}
|
|
142
|
+
return false;
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
const getAdditionalErrors = (
|
|
146
|
+
state: JsonFormsCore,
|
|
147
|
+
action?: InitAction | UpdateCoreAction
|
|
148
|
+
): ErrorObject[] => {
|
|
149
|
+
if (action && hasAdditionalErrorsOption(action.options)) {
|
|
150
|
+
return action.options.additionalErrors;
|
|
151
|
+
}
|
|
152
|
+
return state.additionalErrors;
|
|
153
|
+
};
|
|
154
|
+
|
|
136
155
|
// tslint:disable-next-line: cyclomatic-complexity
|
|
137
156
|
export const coreReducer: Reducer<JsonFormsCore, CoreActions> = (
|
|
138
157
|
state = initState,
|
|
@@ -145,12 +164,14 @@ export const coreReducer: Reducer<JsonFormsCore, CoreActions> = (
|
|
|
145
164
|
const validationMode = getValidationMode(state, action);
|
|
146
165
|
const v = validationMode === 'NoValidation' ? undefined : thisAjv.compile(action.schema);
|
|
147
166
|
const e = validate(v, action.data);
|
|
167
|
+
const additionalErrors = getAdditionalErrors(state, action);
|
|
148
168
|
|
|
149
169
|
return {
|
|
150
170
|
...state,
|
|
151
171
|
data: action.data,
|
|
152
172
|
schema: action.schema,
|
|
153
173
|
uischema: action.uischema,
|
|
174
|
+
additionalErrors,
|
|
154
175
|
errors: e,
|
|
155
176
|
validator: v,
|
|
156
177
|
ajv: thisAjv,
|
|
@@ -176,6 +197,7 @@ export const coreReducer: Reducer<JsonFormsCore, CoreActions> = (
|
|
|
176
197
|
} else if (state.data !== action.data) {
|
|
177
198
|
errors = validate(validator, action.data);
|
|
178
199
|
}
|
|
200
|
+
const additionalErrors = getAdditionalErrors(state, action);
|
|
179
201
|
|
|
180
202
|
const stateChanged =
|
|
181
203
|
state.data !== action.data ||
|
|
@@ -184,7 +206,8 @@ export const coreReducer: Reducer<JsonFormsCore, CoreActions> = (
|
|
|
184
206
|
state.ajv !== thisAjv ||
|
|
185
207
|
state.errors !== errors ||
|
|
186
208
|
state.validator !== validator ||
|
|
187
|
-
state.validationMode !== validationMode
|
|
209
|
+
state.validationMode !== validationMode ||
|
|
210
|
+
state.additionalErrors !== additionalErrors
|
|
188
211
|
return stateChanged
|
|
189
212
|
? {
|
|
190
213
|
...state,
|
|
@@ -195,6 +218,7 @@ export const coreReducer: Reducer<JsonFormsCore, CoreActions> = (
|
|
|
195
218
|
errors: isEqual(errors, state.errors) ? state.errors : errors,
|
|
196
219
|
validator: validator,
|
|
197
220
|
validationMode: validationMode,
|
|
221
|
+
additionalErrors
|
|
198
222
|
}
|
|
199
223
|
: state;
|
|
200
224
|
}
|
|
@@ -391,8 +415,11 @@ const getErrorsAt = (
|
|
|
391
415
|
instancePath: string,
|
|
392
416
|
schema: JsonSchema,
|
|
393
417
|
matchPath: (path: string) => boolean
|
|
394
|
-
) => (state: JsonFormsCore): ErrorObject[] =>
|
|
395
|
-
|
|
418
|
+
) => (state: JsonFormsCore): ErrorObject[] => {
|
|
419
|
+
const errors = state.errors ?? [];
|
|
420
|
+
const additionalErrors = state.additionalErrors ?? [];
|
|
421
|
+
return errorsAt(instancePath, schema, matchPath)(state.validationMode === 'ValidateAndHide' ? additionalErrors : [...errors, ...additionalErrors]);
|
|
422
|
+
}
|
|
396
423
|
|
|
397
424
|
export const errorAt = (instancePath: string, schema: JsonSchema) =>
|
|
398
425
|
getErrorsAt(instancePath, schema, path => path === instancePath);
|
package/src/reducers/reducers.ts
CHANGED
|
@@ -67,7 +67,7 @@ export const jsonFormsReducerConfig = {
|
|
|
67
67
|
* @param schema the JSON schema describing the data to be rendered
|
|
68
68
|
* @param schemaPath the according schema path
|
|
69
69
|
* @param path the instance path
|
|
70
|
-
* @param
|
|
70
|
+
* @param fallback the type of the layout to use or a UI-schema-generator function
|
|
71
71
|
* @param control may be checked for embedded inline uischema options
|
|
72
72
|
*/
|
|
73
73
|
export const findUISchema = (
|
|
@@ -75,7 +75,7 @@ export const findUISchema = (
|
|
|
75
75
|
schema: JsonSchema,
|
|
76
76
|
schemaPath: string,
|
|
77
77
|
path: string,
|
|
78
|
-
|
|
78
|
+
fallback: string | (() => UISchemaElement) = 'VerticalLayout',
|
|
79
79
|
control?: ControlElement,
|
|
80
80
|
rootSchema?: JsonSchema
|
|
81
81
|
): UISchemaElement => {
|
|
@@ -83,8 +83,12 @@ export const findUISchema = (
|
|
|
83
83
|
if (control && control.options && control.options.detail) {
|
|
84
84
|
if (typeof control.options.detail === 'string') {
|
|
85
85
|
if (control.options.detail.toUpperCase() === 'GENERATE') {
|
|
86
|
+
//use fallback generation function
|
|
87
|
+
if(typeof fallback === "function"){
|
|
88
|
+
return fallback();
|
|
89
|
+
}
|
|
86
90
|
// force generation of uischema
|
|
87
|
-
return Generate.uiSchema(schema,
|
|
91
|
+
return Generate.uiSchema(schema, fallback);
|
|
88
92
|
}
|
|
89
93
|
} else if (typeof control.options.detail === 'object') {
|
|
90
94
|
// check if detail is a valid uischema
|
|
@@ -99,7 +103,11 @@ export const findUISchema = (
|
|
|
99
103
|
// default
|
|
100
104
|
const uiSchema = findMatchingUISchema(uischemas)(schema, schemaPath, path);
|
|
101
105
|
if (uiSchema === undefined) {
|
|
102
|
-
|
|
106
|
+
//use fallback generation function
|
|
107
|
+
if(typeof fallback === 'function'){
|
|
108
|
+
return fallback();
|
|
109
|
+
}
|
|
110
|
+
return Generate.uiSchema(schema, fallback, '#', rootSchema);
|
|
103
111
|
}
|
|
104
112
|
return uiSchema;
|
|
105
113
|
};
|