@jsonforms/core 2.5.2 → 3.0.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.
Files changed (274) hide show
  1. package/README.md +1 -1
  2. package/docs/assets/js/search.json +1 -1
  3. package/docs/enums/ruleeffect.html +4 -4
  4. package/docs/globals.html +1124 -1081
  5. package/docs/index.html +70 -88
  6. package/docs/interfaces/addcellrendereraction.html +3 -3
  7. package/docs/interfaces/addrendereraction.html +3 -3
  8. package/docs/interfaces/adduischemaaction.html +3 -3
  9. package/docs/interfaces/andcondition.html +2 -2
  10. package/docs/interfaces/arraycontrolprops.html +22 -22
  11. package/docs/interfaces/arraylayoutprops.html +22 -22
  12. package/docs/interfaces/categorization.html +5 -5
  13. package/docs/interfaces/category.html +5 -5
  14. package/docs/interfaces/cellprops.html +14 -14
  15. package/docs/interfaces/combinatorrendererprops.html +13 -13
  16. package/docs/interfaces/combinatorsubschemarenderinfo.html +3 -3
  17. package/docs/interfaces/composablecondition.html +2 -2
  18. package/docs/interfaces/condition.html +1 -1
  19. package/docs/interfaces/controlelement.html +5 -5
  20. package/docs/interfaces/controlprops.html +17 -17
  21. package/docs/interfaces/controlstate.html +2 -2
  22. package/docs/interfaces/controlwithdetailprops.html +18 -18
  23. package/docs/interfaces/dispatchcellprops.html +13 -13
  24. package/docs/interfaces/dispatchcellstateprops.html +13 -13
  25. package/docs/interfaces/dispatchpropsofarraycontrol.html +4 -4
  26. package/docs/interfaces/dispatchpropsofcontrol.html +1 -1
  27. package/docs/interfaces/dispatchpropsofmultienumcontrol.html +2 -2
  28. package/docs/interfaces/enumcellprops.html +15 -15
  29. package/docs/interfaces/enumoption.html +2 -2
  30. package/docs/interfaces/formatted.html +2 -2
  31. package/docs/interfaces/grouplayout.html +5 -5
  32. package/docs/interfaces/horizontallayout.html +4 -4
  33. package/docs/interfaces/initaction.html +6 -6
  34. package/docs/interfaces/initactionoptions.html +3 -17
  35. package/docs/interfaces/jsonformscellrendererregistryentry.html +2 -2
  36. package/docs/interfaces/jsonformscore.html +7 -21
  37. package/docs/interfaces/jsonformsdefaultdataregistryentry.html +2 -2
  38. package/docs/interfaces/jsonformsextendedstate.html +1 -1
  39. package/docs/interfaces/{jsonformslocalestate.html → jsonformsi18nstate.html} +20 -20
  40. package/docs/interfaces/jsonformsprops.html +9 -24
  41. package/docs/interfaces/jsonformsrendererregistryentry.html +2 -2
  42. package/docs/interfaces/jsonformsstate.html +1 -1
  43. package/docs/interfaces/jsonformsstore.html +5 -5
  44. package/docs/interfaces/jsonformssubstates.html +18 -8
  45. package/docs/interfaces/jsonformsuischemaregistryentry.html +2 -2
  46. package/docs/interfaces/labeldescription.html +2 -2
  47. package/docs/interfaces/labelelement.html +4 -4
  48. package/docs/interfaces/layout.html +4 -4
  49. package/docs/interfaces/layoutprops.html +10 -10
  50. package/docs/interfaces/leafcondition.html +3 -3
  51. package/docs/interfaces/orcondition.html +2 -2
  52. package/docs/interfaces/ownpropsofcell.html +10 -10
  53. package/docs/interfaces/ownpropsofcontrol.html +9 -9
  54. package/docs/interfaces/ownpropsofenum.html +1 -1
  55. package/docs/interfaces/ownpropsofenumcell.html +11 -11
  56. package/docs/interfaces/ownpropsofjsonformsrenderer.html +8 -8
  57. package/docs/interfaces/ownpropsoflayout.html +9 -9
  58. package/docs/interfaces/ownpropsofmasterlistitem.html +6 -6
  59. package/docs/interfaces/ownpropsofrenderer.html +8 -8
  60. package/docs/interfaces/registerdefaultdataaction.html +3 -3
  61. package/docs/interfaces/removecellrendereraction.html +3 -3
  62. package/docs/interfaces/removerendereraction.html +3 -3
  63. package/docs/interfaces/removeuischemaaction.html +2 -2
  64. package/docs/interfaces/rendererprops.html +9 -9
  65. package/docs/interfaces/rule.html +2 -2
  66. package/docs/interfaces/schemabasedcondition.html +3 -3
  67. package/docs/interfaces/scopable.html +1 -1
  68. package/docs/interfaces/setajvaction.html +3 -3
  69. package/docs/interfaces/setconfigaction.html +2 -2
  70. package/docs/interfaces/setlocaleaction.html +3 -3
  71. package/docs/interfaces/setschemaaction.html +2 -2
  72. package/docs/interfaces/{setlocalizeduischemasaction.html → settranslatoraction.html} +29 -15
  73. package/docs/interfaces/setuischemaaction.html +2 -2
  74. package/docs/interfaces/setvalidationmodeaction.html +2 -2
  75. package/docs/interfaces/statepropsofarraycontrol.html +18 -18
  76. package/docs/interfaces/statepropsofarraylayout.html +18 -18
  77. package/docs/interfaces/statepropsofcell.html +13 -13
  78. package/docs/interfaces/statepropsofcombinator.html +12 -12
  79. package/docs/interfaces/statepropsofcontrol.html +16 -16
  80. package/docs/interfaces/statepropsofcontrolwithdetail.html +17 -17
  81. package/docs/interfaces/statepropsofenumcell.html +14 -14
  82. package/docs/interfaces/statepropsofjsonformsrenderer.html +9 -23
  83. package/docs/interfaces/statepropsoflayout.html +10 -10
  84. package/docs/interfaces/statepropsofmasteritem.html +7 -7
  85. package/docs/interfaces/statepropsofrenderer.html +9 -9
  86. package/docs/interfaces/statepropsofscopedrenderer.html +12 -12
  87. package/docs/interfaces/uischemaelement.html +3 -3
  88. package/docs/interfaces/unregisterdefaultdataaction.html +2 -2
  89. package/docs/interfaces/updateaction.html +3 -3
  90. package/docs/interfaces/updatecoreaction.html +6 -6
  91. package/docs/interfaces/updateerrorsaction.html +2 -2
  92. package/docs/interfaces/{setlocalizedschemasaction.html → updatei18naction.html} +43 -15
  93. package/docs/interfaces/verticallayout.html +4 -4
  94. package/docs/interfaces/withclassname.html +1 -1
  95. package/lib/Helpers.d.ts +5 -0
  96. package/lib/Helpers.js +33 -0
  97. package/lib/Helpers.js.map +1 -0
  98. package/lib/actions/actions.d.ts +181 -0
  99. package/lib/actions/actions.js +173 -0
  100. package/lib/actions/actions.js.map +1 -0
  101. package/lib/actions/index.d.ts +1 -180
  102. package/lib/actions/index.js +26 -122
  103. package/lib/actions/index.js.map +1 -1
  104. package/lib/configDefault.js +2 -1
  105. package/lib/configDefault.js.map +1 -1
  106. package/lib/generators/Generate.d.ts +6 -0
  107. package/lib/generators/Generate.js +35 -0
  108. package/lib/generators/Generate.js.map +1 -0
  109. package/lib/generators/index.d.ts +3 -10
  110. package/lib/generators/index.js +28 -9
  111. package/lib/generators/index.js.map +1 -1
  112. package/lib/generators/schema.d.ts +1 -1
  113. package/lib/generators/schema.js +3 -1
  114. package/lib/generators/schema.js.map +1 -1
  115. package/lib/generators/uischema.d.ts +1 -2
  116. package/lib/generators/uischema.js +12 -10
  117. package/lib/generators/uischema.js.map +1 -1
  118. package/lib/i18n/i18nTypes.d.ts +15 -0
  119. package/lib/i18n/i18nTypes.js +3 -0
  120. package/lib/i18n/i18nTypes.js.map +1 -0
  121. package/lib/i18n/i18nUtil.d.ts +18 -0
  122. package/lib/i18n/i18nUtil.js +71 -0
  123. package/lib/i18n/i18nUtil.js.map +1 -0
  124. package/lib/i18n/index.d.ts +2 -0
  125. package/lib/i18n/index.js +6 -0
  126. package/lib/i18n/index.js.map +1 -0
  127. package/lib/index.d.ts +6 -18
  128. package/lib/index.js +10 -15
  129. package/lib/index.js.map +1 -1
  130. package/lib/jsonforms-core.js +9 -12
  131. package/lib/jsonforms-core.js.map +1 -1
  132. package/lib/models/draft4.js +2 -1
  133. package/lib/models/draft4.js.map +1 -1
  134. package/lib/models/index.d.ts +5 -0
  135. package/lib/models/index.js +33 -0
  136. package/lib/models/index.js.map +1 -0
  137. package/lib/models/jsonSchema.js +24 -0
  138. package/lib/models/jsonSchema.js.map +1 -1
  139. package/lib/models/uischema.js +29 -2
  140. package/lib/models/uischema.js.map +1 -1
  141. package/lib/reducers/cells.d.ts +1 -1
  142. package/lib/reducers/cells.js +27 -1
  143. package/lib/reducers/cells.js.map +1 -1
  144. package/lib/reducers/config.d.ts +1 -1
  145. package/lib/reducers/config.js +5 -3
  146. package/lib/reducers/config.js.map +1 -1
  147. package/lib/reducers/core.d.ts +5 -7
  148. package/lib/reducers/core.js +78 -63
  149. package/lib/reducers/core.js.map +1 -1
  150. package/lib/reducers/default-data.d.ts +1 -1
  151. package/lib/reducers/default-data.js +6 -3
  152. package/lib/reducers/default-data.js.map +1 -1
  153. package/lib/reducers/i18n.d.ts +8 -11
  154. package/lib/reducers/i18n.js +40 -23
  155. package/lib/reducers/i18n.js.map +1 -1
  156. package/lib/reducers/index.d.ts +9 -49
  157. package/lib/reducers/index.js +33 -91
  158. package/lib/reducers/index.js.map +1 -1
  159. package/lib/reducers/reducers.d.ts +29 -0
  160. package/lib/reducers/reducers.js +98 -0
  161. package/lib/reducers/reducers.js.map +1 -0
  162. package/lib/reducers/renderers.d.ts +1 -1
  163. package/lib/reducers/renderers.js +27 -1
  164. package/lib/reducers/renderers.js.map +1 -1
  165. package/lib/reducers/selectors.d.ts +15 -0
  166. package/lib/reducers/selectors.js +56 -0
  167. package/lib/reducers/selectors.js.map +1 -0
  168. package/lib/reducers/uischemas.d.ts +2 -2
  169. package/lib/reducers/uischemas.js +9 -6
  170. package/lib/reducers/uischemas.js.map +1 -1
  171. package/lib/store.d.ts +5 -8
  172. package/lib/store.js +24 -0
  173. package/lib/store.js.map +1 -1
  174. package/lib/testers/index.d.ts +1 -204
  175. package/lib/testers/index.js +3 -376
  176. package/lib/testers/index.js.map +1 -1
  177. package/lib/testers/testers.d.ts +203 -0
  178. package/lib/testers/testers.js +421 -0
  179. package/lib/testers/testers.js.map +1 -0
  180. package/lib/util/Formatted.js +24 -0
  181. package/lib/util/Formatted.js.map +1 -1
  182. package/lib/util/array.js +25 -0
  183. package/lib/util/array.js.map +1 -1
  184. package/lib/util/cell.d.ts +11 -4
  185. package/lib/util/cell.js +60 -17
  186. package/lib/util/cell.js.map +1 -1
  187. package/lib/util/combinators.d.ts +2 -3
  188. package/lib/util/combinators.js +5 -2
  189. package/lib/util/combinators.js.map +1 -1
  190. package/lib/util/ids.js +8 -4
  191. package/lib/util/ids.js.map +1 -1
  192. package/lib/util/index.d.ts +11 -45
  193. package/lib/util/index.js +14 -104
  194. package/lib/util/index.js.map +1 -1
  195. package/lib/util/label.d.ts +1 -2
  196. package/lib/util/label.js +7 -4
  197. package/lib/util/label.js.map +1 -1
  198. package/lib/util/path.d.ts +2 -1
  199. package/lib/util/path.js +12 -6
  200. package/lib/util/path.js.map +1 -1
  201. package/lib/util/renderer.d.ts +19 -18
  202. package/lib/util/renderer.js +163 -78
  203. package/lib/util/renderer.js.map +1 -1
  204. package/lib/util/resolvers.d.ts +1 -14
  205. package/lib/util/resolvers.js +9 -215
  206. package/lib/util/resolvers.js.map +1 -1
  207. package/lib/util/runtime.d.ts +12 -2
  208. package/lib/util/runtime.js +59 -17
  209. package/lib/util/runtime.js.map +1 -1
  210. package/lib/util/schema.js +27 -1
  211. package/lib/util/schema.js.map +1 -1
  212. package/lib/util/uischema.d.ts +1 -1
  213. package/lib/util/uischema.js +11 -7
  214. package/lib/util/uischema.js.map +1 -1
  215. package/lib/util/util.d.ts +31 -0
  216. package/lib/util/util.js +112 -0
  217. package/lib/util/util.js.map +1 -0
  218. package/lib/util/validator.d.ts +3 -2
  219. package/lib/util/validator.js +6 -5
  220. package/lib/util/validator.js.map +1 -1
  221. package/package.json +6 -8
  222. package/src/Helpers.ts +38 -0
  223. package/src/actions/actions.ts +345 -0
  224. package/src/actions/index.ts +1 -312
  225. package/src/configDefault.ts +1 -0
  226. package/src/generators/Generate.ts +43 -0
  227. package/src/generators/index.ts +3 -21
  228. package/src/generators/schema.ts +1 -1
  229. package/src/generators/uischema.ts +4 -4
  230. package/src/i18n/i18nTypes.ts +17 -0
  231. package/src/i18n/i18nUtil.ts +105 -0
  232. package/src/i18n/index.ts +2 -0
  233. package/src/index.ts +7 -31
  234. package/src/models/draft4.ts +1 -0
  235. package/src/models/index.ts +30 -0
  236. package/src/models/jsonSchema.ts +1 -0
  237. package/src/models/uischema.ts +1 -0
  238. package/src/reducers/cells.ts +2 -1
  239. package/src/reducers/config.ts +2 -1
  240. package/src/reducers/core.ts +74 -81
  241. package/src/reducers/default-data.ts +2 -1
  242. package/src/reducers/i18n.ts +42 -35
  243. package/src/reducers/index.ts +9 -158
  244. package/src/reducers/reducers.ts +128 -0
  245. package/src/reducers/renderers.ts +2 -1
  246. package/src/reducers/selectors.ts +65 -0
  247. package/src/reducers/uischemas.ts +4 -2
  248. package/src/store.ts +11 -8
  249. package/src/testers/index.ts +1 -516
  250. package/src/testers/testers.ts +547 -0
  251. package/src/util/Formatted.ts +1 -0
  252. package/src/util/array.ts +25 -0
  253. package/src/util/cell.ts +91 -19
  254. package/src/util/combinators.ts +2 -4
  255. package/src/util/ids.ts +1 -0
  256. package/src/util/index.ts +11 -126
  257. package/src/util/label.ts +2 -2
  258. package/src/util/path.ts +4 -1
  259. package/src/util/renderer.ts +170 -88
  260. package/src/util/resolvers.ts +2 -261
  261. package/src/util/runtime.ts +46 -2
  262. package/src/util/schema.ts +26 -1
  263. package/src/util/uischema.ts +2 -1
  264. package/src/util/util.ts +127 -0
  265. package/src/util/validator.ts +5 -8
  266. package/test/i18n/i18nUtil.test.ts +48 -0
  267. package/test/reducers/core.test.ts +33 -226
  268. package/test/util/cell.test.ts +33 -2
  269. package/test/util/renderer.test.ts +543 -31
  270. package/test/util/resolvers.test.ts +1 -59
  271. package/test/util/runtime.test.ts +264 -4
  272. package/docs/interfaces/labels.html +0 -157
  273. package/docs/interfaces/schemaref.html +0 -160
  274. package/docs/interfaces/schemarefs.html +0 -138
@@ -22,11 +22,10 @@
22
22
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
23
  THE SOFTWARE.
24
24
  */
25
+
25
26
  import get from 'lodash/get';
26
- import { ControlElement, UISchemaElement } from '../models/uischema';
27
- import union from 'lodash/union';
27
+ import { ControlElement, JsonSchema, UISchemaElement } from '../models';
28
28
  import find from 'lodash/find';
29
- import RefParser from 'json-schema-ref-parser';
30
29
  import {
31
30
  findUISchema,
32
31
  getAjv,
@@ -34,48 +33,29 @@ import {
34
33
  getConfig,
35
34
  getData,
36
35
  getErrorAt,
37
- getRefParserOptions,
36
+ getErrorTranslator,
38
37
  getRenderers,
39
38
  getSchema,
40
39
  getSubErrorsAt,
41
- getUiSchema
40
+ getTranslator,
41
+ getUiSchema,
42
+ JsonFormsCellRendererRegistryEntry,
43
+ JsonFormsRendererRegistryEntry,
44
+ JsonFormsUISchemaRegistryEntry,
42
45
  } from '../reducers';
43
46
  import { RankedTester } from '../testers';
44
- import { JsonSchema } from '../models/jsonSchema';
45
- import {
46
- AnyAction,
47
- CombinatorKeyword,
48
- composePaths,
49
- composeWithUi,
50
- createLabelDescriptionFrom,
51
- Dispatch,
52
- formatErrorMessage,
53
- hasEnableRule,
54
- hasShowRule,
55
- isEnabled,
56
- isVisible,
57
- moveDown,
58
- moveUp,
59
- Resolve,
60
- resolveSubSchemas
61
- } from '../util';
47
+ import { isInherentlyEnabled, hasShowRule } from './runtime';
48
+ import { createLabelDescriptionFrom } from './label';
49
+ import { CombinatorKeyword, resolveSubSchemas } from './combinators';
50
+ import { moveDown, moveUp } from './array';
51
+ import { AnyAction, Dispatch } from './type';
52
+ import { Resolve } from './util';
53
+ import { composePaths, composeWithUi } from './path';
54
+ import { isVisible } from './runtime';
62
55
  import { CoreActions, update } from '../actions';
63
56
  import { ErrorObject } from 'ajv';
64
57
  import { JsonFormsState } from '../store';
65
- import { JsonFormsRendererRegistryEntry } from '../reducers/renderers';
66
- import { JsonFormsCellRendererRegistryEntry } from '../reducers/cells';
67
- import { JsonFormsUISchemaRegistryEntry } from '../reducers/uischemas';
68
-
69
- export { JsonFormsRendererRegistryEntry, JsonFormsCellRendererRegistryEntry };
70
-
71
- export interface Labels {
72
- default: string;
73
- [additionalLabels: string]: string;
74
- }
75
-
76
- export const isPlainLabel = (label: string | Labels): label is string => {
77
- return typeof label === 'string';
78
- };
58
+ import { getCombinedErrorMessage, getI18nKey, getI18nKeyPrefix, Translator } from '../i18n';
79
59
 
80
60
  const isRequired = (
81
61
  schema: JsonSchema,
@@ -108,6 +88,7 @@ const isRequired = (
108
88
  *
109
89
  * @param {string} label the label string
110
90
  * @param {boolean} required whether the label belongs to a control which is required
91
+ * @param {boolean} hideRequiredAsterisk applied UI Schema option
111
92
  * @returns {string} the label string
112
93
  */
113
94
  export const computeLabel = (
@@ -118,6 +99,20 @@ export const computeLabel = (
118
99
  return required && !hideRequiredAsterisk ? label + '*' : label;
119
100
  };
120
101
 
102
+ /**
103
+ * Indicates whether to mark a field as required.
104
+ *
105
+ * @param {boolean} required whether the label belongs to a control which is required
106
+ * @param {boolean} hideRequiredAsterisk applied UI Schema option
107
+ * @returns {boolean} should the field be marked as required
108
+ */
109
+ export const showAsRequired = (
110
+ required: boolean,
111
+ hideRequiredAsterisk: boolean
112
+ ): boolean => {
113
+ return required && !hideRequiredAsterisk;
114
+ };
115
+
121
116
  /**
122
117
  * Create a default value based on the given scheam.
123
118
  * @param schema the schema for which to create a default value.
@@ -179,16 +174,45 @@ export interface EnumOption {
179
174
  value: any;
180
175
  }
181
176
 
182
- export const enumToEnumOptionMapper = (e: any): EnumOption => {
183
- const stringifiedEnum = typeof e === 'string' ? e : JSON.stringify(e);
184
- return { label: stringifiedEnum, value: e };
177
+ export const enumToEnumOptionMapper = (
178
+ e: any,
179
+ t?: Translator,
180
+ i18nKey?: string
181
+ ): EnumOption => {
182
+ let label = typeof e === 'string' ? e : JSON.stringify(e);
183
+ if (t) {
184
+ if (i18nKey) {
185
+ label = t(`${i18nKey}.${label}`, label);
186
+ } else {
187
+ label = t(label, label);
188
+ }
189
+ }
190
+ return { label, value: e };
185
191
  };
186
192
 
187
- export const oneOfToEnumOptionMapper = (e: any): EnumOption => ({
188
- value: e.const,
189
- label:
190
- e.title ?? (typeof e.const === 'string' ? e.const : JSON.stringify(e.const))
191
- });
193
+ export const oneOfToEnumOptionMapper = (
194
+ e: any,
195
+ t?: Translator,
196
+ fallbackI18nKey?: string
197
+ ): EnumOption => {
198
+ let label =
199
+ e.title ??
200
+ (typeof e.const === 'string' ? e.const : JSON.stringify(e.const));
201
+ if (t) {
202
+ // prefer schema keys as they can be more specialized
203
+ if (e.i18n) {
204
+ label = t(e.i18n, label);
205
+ } else if (fallbackI18nKey) {
206
+ label = t(`${fallbackI18nKey}.${label}`, label);
207
+ } else {
208
+ label = t(label, label);
209
+ }
210
+ }
211
+ return {
212
+ label,
213
+ value: e.const,
214
+ };
215
+ };
192
216
 
193
217
  export interface OwnPropsOfRenderer {
194
218
  /**
@@ -328,7 +352,7 @@ export interface StatePropsOfControl extends StatePropsOfScopedRenderer {
328
352
  /**
329
353
  * The label for the rendered element.
330
354
  */
331
- label: string | Labels;
355
+ label: string;
332
356
 
333
357
  /**
334
358
  * Description of input cell
@@ -407,11 +431,6 @@ export const mapStateToControlProps = (
407
431
  ownProps.visible === undefined || hasShowRule(uischema)
408
432
  ? isVisible(uischema, rootData, ownProps.path, getAjv(state))
409
433
  : ownProps.visible;
410
- const readonly = state.jsonforms.readonly;
411
- const enabled: boolean =
412
- !readonly && (ownProps.enabled === undefined || hasEnableRule(uischema)
413
- ? isEnabled(uischema, rootData, ownProps.path, getAjv(state) )
414
- : ownProps.enabled);
415
434
  const controlElement = uischema as ControlElement;
416
435
  const id = ownProps.id;
417
436
  const rootSchema = getSchema(state);
@@ -423,26 +442,42 @@ export const mapStateToControlProps = (
423
442
  controlElement.scope,
424
443
  rootSchema
425
444
  );
426
- const errors = formatErrorMessage(
427
- union(getErrorAt(path, resolvedSchema)(state).map(error => error.message))
428
- );
445
+ const errors = getErrorAt(path, resolvedSchema)(state);
446
+
429
447
  const description =
430
448
  resolvedSchema !== undefined ? resolvedSchema.description : '';
431
449
  const data = Resolve.data(rootData, path);
432
450
  const labelDesc = createLabelDescriptionFrom(uischema, resolvedSchema);
433
451
  const label = labelDesc.show ? labelDesc.text : '';
452
+ const config = getConfig(state);
453
+ const enabled: boolean = isInherentlyEnabled(
454
+ state,
455
+ ownProps,
456
+ uischema,
457
+ resolvedSchema || rootSchema,
458
+ rootData,
459
+ config
460
+ );
461
+
462
+ const schema = resolvedSchema ?? rootSchema;
463
+ const t = getTranslator()(state);
464
+ const te = getErrorTranslator()(state);
465
+ const i18nLabel = t(getI18nKey(schema, uischema, path, 'label'), label);
466
+ const i18nDescription = t(getI18nKey(schema, uischema, path, 'description'), description);
467
+ const i18nErrorMessage = getCombinedErrorMessage(errors, te, t, schema, uischema, path);
468
+
434
469
  return {
435
470
  data,
436
- description,
437
- errors,
438
- label,
471
+ description: i18nDescription,
472
+ errors: i18nErrorMessage,
473
+ label: i18nLabel,
439
474
  visible,
440
475
  enabled,
441
476
  id,
442
477
  path,
443
478
  required,
444
- uischema: ownProps.uischema,
445
- schema: resolvedSchema || rootSchema,
479
+ uischema,
480
+ schema,
446
481
  config: getConfig(state),
447
482
  cells: ownProps.cells || state.jsonforms.cells,
448
483
  rootSchema
@@ -476,9 +511,21 @@ export const mapStateToEnumControlProps = (
476
511
  ): StatePropsOfControl & OwnPropsOfEnum => {
477
512
  const props: StatePropsOfControl = mapStateToControlProps(state, ownProps);
478
513
  const options: EnumOption[] =
479
- ownProps.options ||
480
- props.schema.enum?.map(enumToEnumOptionMapper) ||
481
- props.schema.const && [enumToEnumOptionMapper(props.schema.const)];
514
+ ownProps.options ||
515
+ props.schema.enum?.map(e =>
516
+ enumToEnumOptionMapper(
517
+ e,
518
+ getTranslator()(state),
519
+ getI18nKeyPrefix(props.schema, props.uischema, props.path)
520
+ )
521
+ ) ||
522
+ (props.schema.const && [
523
+ enumToEnumOptionMapper(
524
+ props.schema.const,
525
+ getTranslator()(state),
526
+ getI18nKeyPrefix(props.schema, props.uischema, props.path)
527
+ )
528
+ ]);
482
529
  return {
483
530
  ...props,
484
531
  options
@@ -498,7 +545,13 @@ export const mapStateToOneOfEnumControlProps = (
498
545
  const props: StatePropsOfControl = mapStateToControlProps(state, ownProps);
499
546
  const options: EnumOption[] =
500
547
  ownProps.options ||
501
- (props.schema.oneOf as JsonSchema[])?.map(oneOfToEnumOptionMapper);
548
+ (props.schema.oneOf as JsonSchema[])?.map(oneOfSubSchema =>
549
+ oneOfToEnumOptionMapper(
550
+ oneOfSubSchema,
551
+ getTranslator()(state),
552
+ getI18nKeyPrefix(props.schema, props.uischema, props.path)
553
+ )
554
+ );
502
555
  return {
503
556
  ...props,
504
557
  options
@@ -519,8 +572,21 @@ export const mapStateToMultiEnumControlProps = (
519
572
  const items = props.schema.items as JsonSchema;
520
573
  const options: EnumOption[] =
521
574
  ownProps.options ||
522
- (items?.oneOf && (items.oneOf as JsonSchema[]).map(oneOfToEnumOptionMapper)) ||
523
- items?.enum?.map(enumToEnumOptionMapper);
575
+ (items?.oneOf &&
576
+ (items.oneOf as JsonSchema[]).map(oneOfSubSchema =>
577
+ oneOfToEnumOptionMapper(
578
+ oneOfSubSchema,
579
+ state.jsonforms.i18n?.translate,
580
+ getI18nKeyPrefix(props.schema, props.uischema, props.path)
581
+ )
582
+ )) ||
583
+ items?.enum?.map(e =>
584
+ enumToEnumOptionMapper(
585
+ e,
586
+ state.jsonforms.i18n?.translate,
587
+ getI18nKeyPrefix(props.schema, props.uischema, props.path)
588
+ )
589
+ );
524
590
  return {
525
591
  ...props,
526
592
  options
@@ -702,14 +768,14 @@ export const mapDispatchToArrayControlProps = (
702
768
  });
703
769
 
704
770
  export interface DispatchPropsOfMultiEnumControl {
705
- addItem: (path:string, value: any) => void;
706
- removeItem? :(path:string, toDelete: any) => void;
771
+ addItem: (path: string, value: any) => void;
772
+ removeItem?: (path: string, toDelete: any) => void;
707
773
  }
708
774
 
709
775
  export const mapDispatchToMultiEnumProps = (
710
776
  dispatch: Dispatch<CoreActions>
711
777
  ): DispatchPropsOfMultiEnumControl => ({
712
- addItem: (path:string, value: any) => {
778
+ addItem: (path: string, value: any) => {
713
779
  dispatch(
714
780
  update(path, data => {
715
781
  if (data === undefined || data === null) {
@@ -720,7 +786,7 @@ export const mapDispatchToMultiEnumProps = (
720
786
  })
721
787
  );
722
788
  },
723
- removeItem: (path:string, toDelete: any) => {
789
+ removeItem: (path: string, toDelete: any) => {
724
790
  dispatch(
725
791
  update(path, data => {
726
792
  const indexInData = data.indexOf(toDelete);
@@ -776,13 +842,17 @@ export const mapStateToLayoutProps = (
776
842
  ownProps.visible === undefined || hasShowRule(uischema)
777
843
  ? isVisible(ownProps.uischema, rootData, ownProps.path, getAjv(state))
778
844
  : ownProps.visible;
779
- const readonly = state.jsonforms.readonly;
780
- const enabled: boolean =
781
- !readonly && (ownProps.enabled === undefined || hasEnableRule(uischema)
782
- ? isEnabled(ownProps.uischema, rootData, ownProps.path, getAjv(state))
783
- : ownProps.enabled);
784
845
 
785
846
  const data = Resolve.data(rootData, ownProps.path);
847
+ const config = getConfig(state);
848
+ const enabled: boolean = isInherentlyEnabled(
849
+ state,
850
+ ownProps,
851
+ uischema,
852
+ undefined, // layouts have no associated schema
853
+ rootData,
854
+ config
855
+ );
786
856
 
787
857
  return {
788
858
  ...layoutDefaultProps,
@@ -805,7 +875,6 @@ export interface OwnPropsOfJsonFormsRenderer extends OwnPropsOfRenderer {}
805
875
  export interface StatePropsOfJsonFormsRenderer
806
876
  extends OwnPropsOfJsonFormsRenderer {
807
877
  rootSchema: JsonSchema;
808
- refResolver: any;
809
878
  }
810
879
 
811
880
  export interface JsonFormsProps extends StatePropsOfJsonFormsRenderer {}
@@ -834,8 +903,6 @@ export const mapStateToJsonFormsRendererProps = (
834
903
  schema: ownProps.schema || getSchema(state),
835
904
  rootSchema: getSchema(state),
836
905
  uischema: uischema,
837
- refResolver: (schema: any) =>
838
- RefParser.dereference(schema, getRefParserOptions(state)),
839
906
  path: ownProps.path
840
907
  };
841
908
  };
@@ -854,7 +921,7 @@ export interface StatePropsOfCombinator extends OwnPropsOfControl {
854
921
  data: any;
855
922
  }
856
923
 
857
- const mapStateToCombinatorRendererProps = (
924
+ export const mapStateToCombinatorRendererProps = (
858
925
  state: JsonFormsState,
859
926
  ownProps: OwnPropsOfControl,
860
927
  keyword: CombinatorKeyword
@@ -882,7 +949,8 @@ const mapStateToCombinatorRendererProps = (
882
949
  'required',
883
950
  'additionalProperties',
884
951
  'type',
885
- 'enum'
952
+ 'enum',
953
+ 'const'
886
954
  ];
887
955
  const dataIsValid = (errors: ErrorObject[]): boolean => {
888
956
  return (
@@ -892,12 +960,19 @@ const mapStateToCombinatorRendererProps = (
892
960
  );
893
961
  };
894
962
  let indexOfFittingSchema: number;
963
+ // TODO instead of compiling the combinator subschemas we can compile the original schema
964
+ // without the combinator alternatives and then revalidate and check the errors for the
965
+ // element
895
966
  for (let i = 0; i < _schema[keyword].length; i++) {
896
- const valFn = ajv.compile(_schema[keyword][i]);
897
- valFn(data);
898
- if (dataIsValid(valFn.errors)) {
899
- indexOfFittingSchema = i;
900
- break;
967
+ try {
968
+ const valFn = ajv.compile(_schema[keyword][i]);
969
+ valFn(data);
970
+ if (dataIsValid(valFn.errors)) {
971
+ indexOfFittingSchema = i;
972
+ break;
973
+ }
974
+ } catch (error) {
975
+ console.debug("Combinator subschema is not self contained, can't hand it over to AJV");
901
976
  }
902
977
  }
903
978
 
@@ -967,9 +1042,18 @@ export const mapStateToArrayLayoutProps = (
967
1042
  } = mapStateToControlWithDetailProps(state, ownProps);
968
1043
 
969
1044
  const resolvedSchema = Resolve.schema(schema, 'items', props.rootSchema);
970
- const childErrors = formatErrorMessage(
971
- getSubErrorsAt(path, resolvedSchema)(state).map(error => error.message)
1045
+
1046
+ // TODO Does not consider a specialized '.custom' error message overriding all other error messages
1047
+ // TODO Does not consider 'i18n' keys which are specified in the ui schemas of the sub errors
1048
+ const childErrors = getCombinedErrorMessage(
1049
+ getSubErrorsAt(path, resolvedSchema)(state),
1050
+ getErrorTranslator()(state),
1051
+ getTranslator()(state),
1052
+ undefined,
1053
+ undefined,
1054
+ undefined
972
1055
  );
1056
+
973
1057
  const allErrors =
974
1058
  errors +
975
1059
  (errors.length > 0 && childErrors.length > 0 ? '\n' : '') +
@@ -985,8 +1069,6 @@ export const mapStateToArrayLayoutProps = (
985
1069
  };
986
1070
  };
987
1071
 
988
- export type CombinatorProps = StatePropsOfCombinator & DispatchPropsOfControl;
989
-
990
1072
  /**
991
1073
  * Props of an array control.
992
1074
  */
@@ -22,17 +22,10 @@
22
22
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
23
  THE SOFTWARE.
24
24
  */
25
+
25
26
  import isEmpty from 'lodash/isEmpty';
26
27
  import get from 'lodash/get';
27
- import isArray from 'lodash/isArray';
28
- import isObject from 'lodash/isObject';
29
- import isFunction from 'lodash/isFunction';
30
- import isUndefined from 'lodash/isUndefined';
31
- import forOwn from 'lodash/forOwn';
32
- import isString from 'lodash/isString';
33
- import isPlainObject from 'lodash/isPlainObject';
34
- import { parse } from 'uri-js';
35
- import { JsonSchema } from '..';
28
+ import { JsonSchema } from '../models';
36
29
 
37
30
  /**
38
31
  * Map for storing refs and the respective schemas they are pointing to.
@@ -194,255 +187,3 @@ function retrieveResolvableSchema(
194
187
 
195
188
  return child;
196
189
  }
197
-
198
- // copied and adapted from JsonRefs
199
-
200
- /**
201
- * Interface for describing result of an extracted schema ref
202
- */
203
- export interface SchemaRef {
204
- uri: string;
205
- }
206
-
207
- /**
208
- * Interface wraps SchemaRef
209
- */
210
- export interface SchemaRefs {
211
- [id: string]: SchemaRef;
212
- }
213
-
214
- export const findRefs = (obj: JsonSchema): SchemaRefs => {
215
- const refs: SchemaRefs = {};
216
-
217
- // Walk the document (or sub document) and find all JSON References
218
- walk([], obj, [], ({}, node: any, path: any) => {
219
- let processChildren = true;
220
- let refDetails;
221
- let refPtr;
222
-
223
- if (isRefLike(node, false)) {
224
- refDetails = getRefDetails(node);
225
-
226
- if (refDetails.type !== 'invalid') {
227
- refPtr = pathToPtr(path, undefined);
228
-
229
- refs[refPtr] = refDetails;
230
- }
231
-
232
- // Whenever a JSON Reference has extra children, its children should not be processed.
233
- // See: http://tools.ietf.org/html/draft-pbryan-zyp-json-ref-03#section-3
234
- if (getExtraRefKeys(node).length > 0) {
235
- processChildren = false;
236
- }
237
- }
238
-
239
- return processChildren;
240
- });
241
-
242
- return refs;
243
- };
244
-
245
- // pure copy of JsonRefs (added types)
246
-
247
- const walk = (ancestors: any, node: any, path: any, fn: any) => {
248
- let processChildren = true;
249
-
250
- const walkItem = (item: any, segment: any) => {
251
- path.push(segment);
252
- walk(ancestors, item, path, fn);
253
- path.pop();
254
- };
255
-
256
- // Call the iteratee
257
- if (isFunction(fn)) {
258
- processChildren = fn(ancestors, node, path);
259
- }
260
-
261
- // We do not process circular objects again
262
- if (ancestors.indexOf(node) === -1) {
263
- ancestors.push(node);
264
-
265
- if (processChildren !== false) {
266
- if (isArray(node)) {
267
- node.forEach((member, index) => {
268
- walkItem(member, index.toString());
269
- });
270
- } else if (isObject(node)) {
271
- forOwn(node, (cNode, key) => {
272
- walkItem(cNode, key);
273
- });
274
- }
275
- }
276
-
277
- ancestors.pop();
278
- }
279
- };
280
-
281
- const pathToPtr = (path: any, hashPrefix: any) => {
282
- if (!isArray(path)) {
283
- throw new Error('path must be an Array');
284
- }
285
-
286
- // Encode each segment and return
287
- return (
288
- (hashPrefix !== false ? '#' : '') +
289
- (path.length > 0 ? '/' : '') +
290
- encodePath(path).join('/')
291
- );
292
- };
293
-
294
- const encodePath = (path: any) => {
295
- if (!isArray(path)) {
296
- throw new TypeError('path must be an array');
297
- }
298
-
299
- return path.map(seg => {
300
- if (!isString(seg)) {
301
- seg = JSON.stringify(seg);
302
- }
303
-
304
- return seg.replace(/~/g, '~0').replace(/\//g, '~1');
305
- });
306
- };
307
-
308
- const uriDetailsCache = {} as any;
309
- const badPtrTokenRegex = /~(?:[^01]|$)/g;
310
-
311
- const getRefDetails = (obj: any) => {
312
- const details = {
313
- def: obj
314
- } as any;
315
- let cacheKey;
316
- let extraKeys;
317
- let uriDetails;
318
-
319
- try {
320
- if (isRefLike(obj, true)) {
321
- cacheKey = obj.$ref;
322
- uriDetails = uriDetailsCache[cacheKey];
323
-
324
- if (isUndefined(uriDetails)) {
325
- uriDetails = uriDetailsCache[cacheKey] = parseURI(cacheKey);
326
- }
327
-
328
- details.uri = cacheKey;
329
- details.uriDetails = uriDetails;
330
-
331
- if (isUndefined(uriDetails.error)) {
332
- details.type = getRefType(details);
333
-
334
- // Validate the JSON Pointer
335
- try {
336
- if (['#', '/'].indexOf(cacheKey[0]) > -1) {
337
- isPtr(cacheKey, true);
338
- } else if (cacheKey.indexOf('#') > -1) {
339
- isPtr(uriDetails.fragment, true);
340
- }
341
- } catch (err) {
342
- details.error = err.message;
343
- details.type = 'invalid';
344
- }
345
- } else {
346
- details.error = details.uriDetails.error;
347
- details.type = 'invalid';
348
- }
349
-
350
- // Identify warning
351
- extraKeys = getExtraRefKeys(obj);
352
-
353
- if (extraKeys.length > 0) {
354
- details.warning =
355
- 'Extra JSON Reference properties will be ignored: ' +
356
- extraKeys.join(', ');
357
- }
358
- } else {
359
- details.type = 'invalid';
360
- }
361
- } catch (err) {
362
- details.error = err.message;
363
- details.type = 'invalid';
364
- }
365
-
366
- return details;
367
- };
368
-
369
- const getRefType = (refDetails: any) => {
370
- let type;
371
-
372
- // Convert the URI reference to one of our types
373
- switch (refDetails.uriDetails.reference) {
374
- case 'absolute':
375
- case 'uri':
376
- type = 'remote';
377
- break;
378
- case 'same-document':
379
- type = 'local';
380
- break;
381
- default:
382
- type = refDetails.uriDetails.reference;
383
- }
384
-
385
- return type;
386
- };
387
-
388
- const getExtraRefKeys = (ref: any) => {
389
- return Object.keys(ref).filter(key => {
390
- return key !== '$ref';
391
- });
392
- };
393
-
394
- const parseURI = (uri: string) => {
395
- // We decode first to avoid doubly encoding
396
- return parse(uri);
397
- };
398
-
399
- const isPtr = (ptr: any, throwWithDetails: boolean) => {
400
- let valid = true;
401
- let firstChar;
402
-
403
- try {
404
- if (isString(ptr)) {
405
- if (ptr !== '') {
406
- firstChar = ptr.charAt(0);
407
-
408
- if (['#', '/'].indexOf(firstChar) === -1) {
409
- throw new Error('ptr must start with a / or #/');
410
- } else if (firstChar === '#' && ptr !== '#' && ptr.charAt(1) !== '/') {
411
- throw new Error('ptr must start with a / or #/');
412
- } else if (ptr.match(badPtrTokenRegex)) {
413
- throw new Error('ptr has invalid token(s)');
414
- }
415
- }
416
- } else {
417
- throw new Error('ptr is not a String');
418
- }
419
- } catch (err) {
420
- if (throwWithDetails === true) {
421
- throw err;
422
- }
423
-
424
- valid = false;
425
- }
426
-
427
- return valid;
428
- };
429
-
430
- const isRefLike = (obj: any, throwWithDetails: boolean) => {
431
- let refLike = true;
432
-
433
- try {
434
- if (!isPlainObject(obj)) {
435
- throw new Error('obj is not an Object');
436
- } else if (!isString(obj.$ref)) {
437
- throw new Error('obj.$ref is not a String');
438
- }
439
- } catch (err) {
440
- if (throwWithDetails) {
441
- throw err;
442
- }
443
-
444
- refLike = false;
445
- }
446
-
447
- return refLike;
448
- };