@wise/dynamic-flow-client 5.9.0 → 5.9.1

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 (28) hide show
  1. package/build/domain/components/step/StepDomainComponent.js +6 -1
  2. package/build/domain/mappers/mapStepSchemas.js +2 -4
  3. package/build/domain/mappers/mapStepToComponent.js +4 -3
  4. package/build/domain/mappers/schema/oneOfSchemaToComponent/oneOfSchemaToComponent.js +0 -10
  5. package/build/domain/mappers/schema/oneOfSchemaToComponent/oneOfSchemaToComponent.test.js +0 -40
  6. package/build/main.js +34 -43
  7. package/build/main.mjs +34 -43
  8. package/build/renderers/mappers/selectInputComponentToProps.js +9 -1
  9. package/build/stories/spec/schemas/features/PersistAsync.story.js +35 -0
  10. package/build/stories/spec/schemas/oneOf/OneOfWithSingleOption.story.js +114 -0
  11. package/build/tests/PersistAsync.test.js +33 -0
  12. package/build/tests/SchemaReferences.test.js +88 -0
  13. package/build/tests/Submission.test.js +80 -0
  14. package/build/tests/renderers/SelectInputRendererProps.test.js +1 -0
  15. package/build/types/domain/components/step/StepDomainComponent.d.ts +2 -1
  16. package/build/types/domain/components/step/StepDomainComponent.d.ts.map +1 -1
  17. package/build/types/domain/mappers/mapStepSchemas.d.ts +1 -1
  18. package/build/types/domain/mappers/mapStepSchemas.d.ts.map +1 -1
  19. package/build/types/domain/mappers/mapStepToComponent.d.ts.map +1 -1
  20. package/build/types/domain/mappers/schema/oneOfSchemaToComponent/oneOfSchemaToComponent.d.ts +1 -531
  21. package/build/types/domain/mappers/schema/oneOfSchemaToComponent/oneOfSchemaToComponent.d.ts.map +1 -1
  22. package/build/types/domain/mappers/schema/persistAsyncSchemaToComponent.d.ts +0 -16
  23. package/build/types/domain/mappers/schema/persistAsyncSchemaToComponent.d.ts.map +1 -1
  24. package/build/types/domain/types.d.ts +0 -1
  25. package/build/types/domain/types.d.ts.map +1 -1
  26. package/build/types/renderers/mappers/selectInputComponentToProps.d.ts +2 -2
  27. package/build/types/renderers/mappers/selectInputComponentToProps.d.ts.map +1 -1
  28. package/package.json +13 -13
@@ -49,7 +49,12 @@ export const createStepComponent = (stepProps) => {
49
49
  return getLocalValues(this.schemaComponents);
50
50
  },
51
51
  validate() {
52
- return this.schemaComponents.every((inputComponent) => inputComponent.isSchemaReferencedInStep ? inputComponent.validate() : true);
52
+ return this.schemaComponents.every((inputComponent) => {
53
+ var _a;
54
+ return this.referencedSchemaIds.includes((_a = inputComponent.schemaId) !== null && _a !== void 0 ? _a : '')
55
+ ? inputComponent.validate()
56
+ : true;
57
+ });
53
58
  },
54
59
  setLoadingState(loadingState) {
55
60
  this._update((draft) => {
@@ -1,9 +1,8 @@
1
1
  import { mapSchemaToComponent } from './mapSchemaToComponent';
2
- export const mapStepSchemas = (uid, step, stepLocalValue, mapperProps, referencedSchemaIds) => {
3
- const isReferenced = (schemaId) => schemaId != null && referencedSchemaIds.includes(schemaId);
2
+ export const mapStepSchemas = (uid, step, stepLocalValue, mapperProps) => {
4
3
  return step.schemas.map((schema, i) => {
5
4
  var _a, _b;
6
- const schemaComponent = mapSchemaToComponent({
5
+ return mapSchemaToComponent({
7
6
  uid: `${uid}.schemas-${i}.${schema.$id}`,
8
7
  schemaId: schema.$id,
9
8
  schema,
@@ -12,6 +11,5 @@ export const mapStepSchemas = (uid, step, stepLocalValue, mapperProps, reference
12
11
  validationErrors: (_b = step.errors) === null || _b === void 0 ? void 0 : _b.validation,
13
12
  required: true,
14
13
  }, mapperProps);
15
- return Object.assign(Object.assign({}, schemaComponent), { isSchemaReferencedInStep: isReferenced(schema.$id) });
16
14
  });
17
15
  };
@@ -64,7 +64,7 @@ export const mapStepToComponent = (_a) => {
64
64
  onBehavior,
65
65
  registerSubmissionBehavior });
66
66
  const referencedSchemaIds = getReferencedSchemaId(step);
67
- const schemaComponents = mapStepSchemas(uid, step, stepLocalValue, mapperProps, referencedSchemaIds);
67
+ const schemaComponents = mapStepSchemas(uid, step, stepLocalValue, mapperProps);
68
68
  const { layout, footer } = getLayoutAndFooter(step, features);
69
69
  const layoutComponents = layout.map((layoutComponent, index) => mapLayoutToComponent(`${uid}.layout-${index}`, layoutComponent, mapperProps, schemaComponents));
70
70
  const footerComponents = normaliseMarginInLastComponent(footer).map((footerComponent, index) => mapLayoutToComponent(`${uid}.footer-${index}`, footerComponent, mapperProps, schemaComponents));
@@ -89,6 +89,7 @@ export const mapStepToComponent = (_a) => {
89
89
  stackBehavior: (_b = navigation === null || navigation === void 0 ? void 0 : navigation.stackBehavior) !== null && _b !== void 0 ? _b : 'default',
90
90
  stepPrefetch,
91
91
  step,
92
+ referencedSchemaIds,
92
93
  onComponentUpdate,
93
94
  trackEvent,
94
95
  onBehavior,
@@ -96,8 +97,8 @@ export const mapStepToComponent = (_a) => {
96
97
  return stepComponent;
97
98
  };
98
99
  const getReferencedSchemaId = (step) => {
99
- const { schemas, layout } = step;
100
- const stringifiedLayout = JSON.stringify(layout);
100
+ const { schemas, layout, footer } = step;
101
+ const stringifiedLayout = JSON.stringify({ layout, footer });
101
102
  return schemas
102
103
  .filter((schema) => stringifiedLayout.includes(`"schemaId":"${schema.$id}"`) ||
103
104
  stringifiedLayout.includes(`"schema":{"$ref":"${schema.$id}"`))
@@ -22,16 +22,6 @@ export const oneOfSchemaToComponent = (schemaMapperProps, mapperProps) => {
22
22
  var _a;
23
23
  const { uid, localValue, schema, model, validationErrors: initialError, required = false, } = schemaMapperProps;
24
24
  const initialModel = (_a = model !== null && model !== void 0 ? model : schema.default) !== null && _a !== void 0 ? _a : null;
25
- if (schema.oneOf.length === 1 && isFormSectionSchema(schema.oneOf[0])) {
26
- return mapSchemaToComponent({
27
- uid,
28
- schema: supressSchemaTitleAndDescription(schema.oneOf[0]),
29
- model: initialModel,
30
- localValue,
31
- validationErrors: initialError,
32
- required,
33
- }, mapperProps);
34
- }
35
25
  const options = schema.oneOf.map((childSchema, index) => {
36
26
  var _a;
37
27
  const { title = '', description, image, icon, media, keywords = [], tags, additionalText, inlineAlert, supportingValues, } = childSchema;
@@ -222,44 +222,4 @@ describe('oneOfSchemaToComponent', () => {
222
222
  });
223
223
  });
224
224
  });
225
- describe('number of elements', () => {
226
- describe('when the oneOf contains only more than one element', () => {
227
- it('returns an SelectComponent', () => {
228
- const schemaMapperProps = getMockSchemaMapperProps({
229
- schema: {
230
- oneOf: [
231
- { type: 'object', displayOrder: ['name'], properties: { name: { type: 'string' } } },
232
- { type: 'object', displayOrder: ['name'], properties: { name: { type: 'string' } } },
233
- ],
234
- },
235
- });
236
- const component = oneOfSchemaToComponent(schemaMapperProps, getMockMapperProps());
237
- expect(component.type).toBe('select');
238
- });
239
- });
240
- describe('when the oneOf contains only one element, and its an object schema', () => {
241
- it('returns an ObjectComponent', () => {
242
- const schemaMapperProps = getMockSchemaMapperProps({
243
- schema: {
244
- oneOf: [
245
- { type: 'object', displayOrder: ['name'], properties: { name: { type: 'string' } } },
246
- ],
247
- },
248
- });
249
- const component = oneOfSchemaToComponent(schemaMapperProps, getMockMapperProps());
250
- expect(component.type).toBe('object');
251
- });
252
- });
253
- describe('when the oneOf contains only one element, and its a const schema', () => {
254
- it('returns an SelectComponent', () => {
255
- const schemaMapperProps = getMockSchemaMapperProps({
256
- schema: {
257
- oneOf: [{ const: 'EUR' }],
258
- },
259
- });
260
- const component = oneOfSchemaToComponent(schemaMapperProps, getMockMapperProps());
261
- expect(component.type).toBe('select');
262
- });
263
- });
264
- });
265
225
  });
package/build/main.js CHANGED
@@ -2615,7 +2615,10 @@ var createStepComponent = (stepProps) => {
2615
2615
  },
2616
2616
  validate() {
2617
2617
  return this.schemaComponents.every(
2618
- (inputComponent) => inputComponent.isSchemaReferencedInStep ? inputComponent.validate() : true
2618
+ (inputComponent) => {
2619
+ var _a2;
2620
+ return this.referencedSchemaIds.includes((_a2 = inputComponent.schemaId) != null ? _a2 : "") ? inputComponent.validate() : true;
2621
+ }
2619
2622
  );
2620
2623
  },
2621
2624
  setLoadingState(loadingState) {
@@ -5268,19 +5271,6 @@ var oneOfSchemaToComponent = (schemaMapperProps, mapperProps) => {
5268
5271
  required = false
5269
5272
  } = schemaMapperProps;
5270
5273
  const initialModel = (_a = model != null ? model : schema.default) != null ? _a : null;
5271
- if (schema.oneOf.length === 1 && isFormSectionSchema(schema.oneOf[0])) {
5272
- return mapSchemaToComponent(
5273
- {
5274
- uid,
5275
- schema: supressSchemaTitleAndDescription(schema.oneOf[0]),
5276
- model: initialModel,
5277
- localValue,
5278
- validationErrors: initialError,
5279
- required
5280
- },
5281
- mapperProps
5282
- );
5283
- }
5284
5274
  const options = schema.oneOf.map((childSchema, index) => {
5285
5275
  var _a2;
5286
5276
  const {
@@ -5891,26 +5881,24 @@ var mapSchemaToComponent = (schemaMapperProps, mapperProps) => {
5891
5881
  };
5892
5882
 
5893
5883
  // src/domain/mappers/mapStepSchemas.ts
5894
- var mapStepSchemas = (uid, step, stepLocalValue, mapperProps, referencedSchemaIds) => {
5895
- const isReferenced = (schemaId) => schemaId != null && referencedSchemaIds.includes(schemaId);
5896
- return step.schemas.map((schema, i) => {
5897
- var _a, _b;
5898
- const schemaComponent = mapSchemaToComponent(
5899
- {
5900
- uid: `${uid}.schemas-${i}.${schema.$id}`,
5901
- schemaId: schema.$id,
5902
- schema,
5903
- model: (_a = step.model) != null ? _a : null,
5904
- localValue: stepLocalValue,
5905
- validationErrors: (_b = step.errors) == null ? void 0 : _b.validation,
5906
- required: true
5907
- },
5908
- mapperProps
5909
- );
5910
- return __spreadProps(__spreadValues({}, schemaComponent), {
5911
- isSchemaReferencedInStep: isReferenced(schema.$id)
5912
- });
5913
- });
5884
+ var mapStepSchemas = (uid, step, stepLocalValue, mapperProps) => {
5885
+ return step.schemas.map(
5886
+ (schema, i) => {
5887
+ var _a, _b;
5888
+ return mapSchemaToComponent(
5889
+ {
5890
+ uid: `${uid}.schemas-${i}.${schema.$id}`,
5891
+ schemaId: schema.$id,
5892
+ schema,
5893
+ model: (_a = step.model) != null ? _a : null,
5894
+ localValue: stepLocalValue,
5895
+ validationErrors: (_b = step.errors) == null ? void 0 : _b.validation,
5896
+ required: true
5897
+ },
5898
+ mapperProps
5899
+ );
5900
+ }
5901
+ );
5914
5902
  };
5915
5903
 
5916
5904
  // src/domain/mappers/mapToolbarToComponent.ts
@@ -6311,13 +6299,7 @@ var mapStepToComponent = (_a) => {
6311
6299
  registerSubmissionBehavior
6312
6300
  });
6313
6301
  const referencedSchemaIds = getReferencedSchemaId(step);
6314
- const schemaComponents = mapStepSchemas(
6315
- uid,
6316
- step,
6317
- stepLocalValue,
6318
- mapperProps,
6319
- referencedSchemaIds
6320
- );
6302
+ const schemaComponents = mapStepSchemas(uid, step, stepLocalValue, mapperProps);
6321
6303
  const { layout, footer } = getLayoutAndFooter(step, features);
6322
6304
  const layoutComponents = layout.map(
6323
6305
  (layoutComponent, index) => mapLayoutToComponent(`${uid}.layout-${index}`, layoutComponent, mapperProps, schemaComponents)
@@ -6346,6 +6328,7 @@ var mapStepToComponent = (_a) => {
6346
6328
  stackBehavior: (_a2 = navigation == null ? void 0 : navigation.stackBehavior) != null ? _a2 : "default",
6347
6329
  stepPrefetch,
6348
6330
  step,
6331
+ referencedSchemaIds,
6349
6332
  onComponentUpdate,
6350
6333
  trackEvent,
6351
6334
  onBehavior
@@ -6353,8 +6336,8 @@ var mapStepToComponent = (_a) => {
6353
6336
  return stepComponent;
6354
6337
  };
6355
6338
  var getReferencedSchemaId = (step) => {
6356
- const { schemas, layout } = step;
6357
- const stringifiedLayout = JSON.stringify(layout);
6339
+ const { schemas, layout, footer } = step;
6340
+ const stringifiedLayout = JSON.stringify({ layout, footer });
6358
6341
  return schemas.filter(
6359
6342
  (schema) => stringifiedLayout.includes(`"schemaId":"${schema.$id}"`) || stringifiedLayout.includes(`"schema":{"$ref":"${schema.$id}"`)
6360
6343
  ).map((schema) => schema.$id).filter((schemaId) => schemaId !== void 0);
@@ -8094,6 +8077,7 @@ var sectionComponentToProps = (component, rendererMapperProps) => {
8094
8077
 
8095
8078
  // src/renderers/mappers/selectInputComponentToProps.ts
8096
8079
  var selectInputComponentToProps = (component, rendererMapperProps) => {
8080
+ var _b;
8097
8081
  const { autoComplete, selectedIndex, onSelect } = component;
8098
8082
  const selectedChild = component.getSelectedChild();
8099
8083
  const childrenProps = selectedChild ? componentToRendererProps(selectedChild, rendererMapperProps) : null;
@@ -8103,6 +8087,13 @@ var selectInputComponentToProps = (component, rendererMapperProps) => {
8103
8087
  component.getChildren(),
8104
8088
  rendererMapperProps
8105
8089
  );
8090
+ if (options.length === 1 && ((_b = options[0].childrenProps) == null ? void 0 : _b.type) === "form-section") {
8091
+ if (selectedIndex == null) {
8092
+ rendererMapperProps.trackEvent("OneOf Option Selected - Auto-select single-option", {});
8093
+ onSelect.bind(component)(0);
8094
+ }
8095
+ return options[0].childrenProps;
8096
+ }
8106
8097
  return __spreadProps(__spreadValues(__spreadValues({}, props), rendererMapperProps), {
8107
8098
  autoComplete,
8108
8099
  options,
package/build/main.mjs CHANGED
@@ -2585,7 +2585,10 @@ var createStepComponent = (stepProps) => {
2585
2585
  },
2586
2586
  validate() {
2587
2587
  return this.schemaComponents.every(
2588
- (inputComponent) => inputComponent.isSchemaReferencedInStep ? inputComponent.validate() : true
2588
+ (inputComponent) => {
2589
+ var _a2;
2590
+ return this.referencedSchemaIds.includes((_a2 = inputComponent.schemaId) != null ? _a2 : "") ? inputComponent.validate() : true;
2591
+ }
2589
2592
  );
2590
2593
  },
2591
2594
  setLoadingState(loadingState) {
@@ -5238,19 +5241,6 @@ var oneOfSchemaToComponent = (schemaMapperProps, mapperProps) => {
5238
5241
  required = false
5239
5242
  } = schemaMapperProps;
5240
5243
  const initialModel = (_a = model != null ? model : schema.default) != null ? _a : null;
5241
- if (schema.oneOf.length === 1 && isFormSectionSchema(schema.oneOf[0])) {
5242
- return mapSchemaToComponent(
5243
- {
5244
- uid,
5245
- schema: supressSchemaTitleAndDescription(schema.oneOf[0]),
5246
- model: initialModel,
5247
- localValue,
5248
- validationErrors: initialError,
5249
- required
5250
- },
5251
- mapperProps
5252
- );
5253
- }
5254
5244
  const options = schema.oneOf.map((childSchema, index) => {
5255
5245
  var _a2;
5256
5246
  const {
@@ -5861,26 +5851,24 @@ var mapSchemaToComponent = (schemaMapperProps, mapperProps) => {
5861
5851
  };
5862
5852
 
5863
5853
  // src/domain/mappers/mapStepSchemas.ts
5864
- var mapStepSchemas = (uid, step, stepLocalValue, mapperProps, referencedSchemaIds) => {
5865
- const isReferenced = (schemaId) => schemaId != null && referencedSchemaIds.includes(schemaId);
5866
- return step.schemas.map((schema, i) => {
5867
- var _a, _b;
5868
- const schemaComponent = mapSchemaToComponent(
5869
- {
5870
- uid: `${uid}.schemas-${i}.${schema.$id}`,
5871
- schemaId: schema.$id,
5872
- schema,
5873
- model: (_a = step.model) != null ? _a : null,
5874
- localValue: stepLocalValue,
5875
- validationErrors: (_b = step.errors) == null ? void 0 : _b.validation,
5876
- required: true
5877
- },
5878
- mapperProps
5879
- );
5880
- return __spreadProps(__spreadValues({}, schemaComponent), {
5881
- isSchemaReferencedInStep: isReferenced(schema.$id)
5882
- });
5883
- });
5854
+ var mapStepSchemas = (uid, step, stepLocalValue, mapperProps) => {
5855
+ return step.schemas.map(
5856
+ (schema, i) => {
5857
+ var _a, _b;
5858
+ return mapSchemaToComponent(
5859
+ {
5860
+ uid: `${uid}.schemas-${i}.${schema.$id}`,
5861
+ schemaId: schema.$id,
5862
+ schema,
5863
+ model: (_a = step.model) != null ? _a : null,
5864
+ localValue: stepLocalValue,
5865
+ validationErrors: (_b = step.errors) == null ? void 0 : _b.validation,
5866
+ required: true
5867
+ },
5868
+ mapperProps
5869
+ );
5870
+ }
5871
+ );
5884
5872
  };
5885
5873
 
5886
5874
  // src/domain/mappers/mapToolbarToComponent.ts
@@ -6281,13 +6269,7 @@ var mapStepToComponent = (_a) => {
6281
6269
  registerSubmissionBehavior
6282
6270
  });
6283
6271
  const referencedSchemaIds = getReferencedSchemaId(step);
6284
- const schemaComponents = mapStepSchemas(
6285
- uid,
6286
- step,
6287
- stepLocalValue,
6288
- mapperProps,
6289
- referencedSchemaIds
6290
- );
6272
+ const schemaComponents = mapStepSchemas(uid, step, stepLocalValue, mapperProps);
6291
6273
  const { layout, footer } = getLayoutAndFooter(step, features);
6292
6274
  const layoutComponents = layout.map(
6293
6275
  (layoutComponent, index) => mapLayoutToComponent(`${uid}.layout-${index}`, layoutComponent, mapperProps, schemaComponents)
@@ -6316,6 +6298,7 @@ var mapStepToComponent = (_a) => {
6316
6298
  stackBehavior: (_a2 = navigation == null ? void 0 : navigation.stackBehavior) != null ? _a2 : "default",
6317
6299
  stepPrefetch,
6318
6300
  step,
6301
+ referencedSchemaIds,
6319
6302
  onComponentUpdate,
6320
6303
  trackEvent,
6321
6304
  onBehavior
@@ -6323,8 +6306,8 @@ var mapStepToComponent = (_a) => {
6323
6306
  return stepComponent;
6324
6307
  };
6325
6308
  var getReferencedSchemaId = (step) => {
6326
- const { schemas, layout } = step;
6327
- const stringifiedLayout = JSON.stringify(layout);
6309
+ const { schemas, layout, footer } = step;
6310
+ const stringifiedLayout = JSON.stringify({ layout, footer });
6328
6311
  return schemas.filter(
6329
6312
  (schema) => stringifiedLayout.includes(`"schemaId":"${schema.$id}"`) || stringifiedLayout.includes(`"schema":{"$ref":"${schema.$id}"`)
6330
6313
  ).map((schema) => schema.$id).filter((schemaId) => schemaId !== void 0);
@@ -8064,6 +8047,7 @@ var sectionComponentToProps = (component, rendererMapperProps) => {
8064
8047
 
8065
8048
  // src/renderers/mappers/selectInputComponentToProps.ts
8066
8049
  var selectInputComponentToProps = (component, rendererMapperProps) => {
8050
+ var _b;
8067
8051
  const { autoComplete, selectedIndex, onSelect } = component;
8068
8052
  const selectedChild = component.getSelectedChild();
8069
8053
  const childrenProps = selectedChild ? componentToRendererProps(selectedChild, rendererMapperProps) : null;
@@ -8073,6 +8057,13 @@ var selectInputComponentToProps = (component, rendererMapperProps) => {
8073
8057
  component.getChildren(),
8074
8058
  rendererMapperProps
8075
8059
  );
8060
+ if (options.length === 1 && ((_b = options[0].childrenProps) == null ? void 0 : _b.type) === "form-section") {
8061
+ if (selectedIndex == null) {
8062
+ rendererMapperProps.trackEvent("OneOf Option Selected - Auto-select single-option", {});
8063
+ onSelect.bind(component)(0);
8064
+ }
8065
+ return options[0].childrenProps;
8066
+ }
8076
8067
  return __spreadProps(__spreadValues(__spreadValues({}, props), rendererMapperProps), {
8077
8068
  autoComplete,
8078
8069
  options,
@@ -13,13 +13,21 @@ import { componentToRendererProps } from './componentToRendererProps';
13
13
  import { inputComponentToProps } from './utils/inputComponentToProps';
14
14
  import { selectInputOptionsToProps } from './utils/selectInputOptionsToProps';
15
15
  export const selectInputComponentToProps = (component, rendererMapperProps) => {
16
+ var _a;
16
17
  const { autoComplete, selectedIndex, onSelect } = component;
17
18
  const selectedChild = component.getSelectedChild();
18
19
  const childrenProps = selectedChild
19
20
  ? componentToRendererProps(selectedChild, rendererMapperProps)
20
21
  : null;
21
- const _a = inputComponentToProps(component, 'input-select'), { value } = _a, props = __rest(_a, ["value"]);
22
+ const _b = inputComponentToProps(component, 'input-select'), { value } = _b, props = __rest(_b, ["value"]);
22
23
  const options = selectInputOptionsToProps(component.options, component.getChildren(), rendererMapperProps);
24
+ if (options.length === 1 && ((_a = options[0].childrenProps) === null || _a === void 0 ? void 0 : _a.type) === 'form-section') {
25
+ if (selectedIndex == null) {
26
+ rendererMapperProps.trackEvent('OneOf Option Selected - Auto-select single-option', {});
27
+ onSelect.bind(component)(0);
28
+ }
29
+ return options[0].childrenProps;
30
+ }
23
31
  return Object.assign(Object.assign(Object.assign({}, props), rendererMapperProps), { autoComplete,
24
32
  options,
25
33
  selectedIndex, onSelect: onSelect.bind(component), children: rendererMapperProps.render(childrenProps), childrenProps });
@@ -43,6 +43,9 @@ export function PersistAsyncGenericFailure() {
43
43
  export function PersistAsyncValidationFailure() {
44
44
  return renderWithStep(getBasicStep('/persist-async-validation-failure'), httpClient);
45
45
  }
46
+ export function PersistAsyncValidationFailureWithObjectSchemaWrapper() {
47
+ return renderWithStep(getBasicStepWithObjectWrapper('/persist-async-validation-failure'), httpClient);
48
+ }
46
49
  export function PersistAsyncFileUpload() {
47
50
  return renderWithStep(getFileUploadStep(), httpClient);
48
51
  }
@@ -75,6 +78,38 @@ const getBasicStep = (url) => ({
75
78
  ],
76
79
  model: 'the-token',
77
80
  });
81
+ const getBasicStepWithObjectWrapper = (url) => ({
82
+ id: 'step-id',
83
+ title: 'Persist async on text input',
84
+ schemas: [
85
+ {
86
+ $id: '#schema',
87
+ type: 'object',
88
+ displayOrder: ['field'],
89
+ properties: {
90
+ field: {
91
+ type: 'string',
92
+ persistAsync: {
93
+ method: 'POST',
94
+ url,
95
+ param: 'param',
96
+ idProperty: 'token',
97
+ schema: { title: 'Card number', type: 'number' },
98
+ },
99
+ },
100
+ },
101
+ },
102
+ ],
103
+ layout: [
104
+ { type: 'form', schemaId: '#schema' },
105
+ {
106
+ type: 'button',
107
+ title: 'Submit',
108
+ action: { url: '/submit', method: 'POST' },
109
+ },
110
+ ],
111
+ model: 'the-token',
112
+ });
78
113
  const getComplexStepWithDelay = () => ({
79
114
  id: 'step-id',
80
115
  title: 'Persist async on text input',
@@ -0,0 +1,114 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { getMockHttpClient, respondWith } from '../../../../test-utils';
3
+ import DynamicFlowWise from '../../../../test-utils/DynamicFlowWise';
4
+ import { renderWithStepAndOverrides } from '../../../utils/render-utils';
5
+ export default {
6
+ component: DynamicFlowWise,
7
+ title: 'Spec/Schemas/OneOf',
8
+ parameters: {
9
+ chromatic: { disableSnapshot: true },
10
+ },
11
+ };
12
+ const httpClient = getMockHttpClient({
13
+ '/submit': async () => respondWith({}, { status: 404 }),
14
+ });
15
+ export function SingleOptionOneOfs() {
16
+ const optionSchemasByType = {
17
+ object: {
18
+ type: 'object',
19
+ title: 'Object Schema Option',
20
+ displayOrder: ['accountId'],
21
+ properties: {
22
+ accountId: {
23
+ title: 'Account Number',
24
+ type: 'string',
25
+ placeholder: '12345678',
26
+ },
27
+ },
28
+ },
29
+ const: {
30
+ title: 'Const Schema Option',
31
+ const: 'fixedValue',
32
+ layout: [
33
+ {
34
+ type: 'alert',
35
+ markdown: 'This is a const schema with a fixed value of "fixedValue"',
36
+ },
37
+ ],
38
+ },
39
+ };
40
+ const rootLevel = [true, false];
41
+ const withId = [true, false];
42
+ const required = [true, false];
43
+ const optionSchemaType = Object.keys(optionSchemasByType);
44
+ const examples = [];
45
+ rootLevel.forEach((isRootLevel) => {
46
+ withId.forEach((hasId) => {
47
+ required.forEach((isRequired) => {
48
+ optionSchemaType.forEach((optionType) => {
49
+ const step = getStep(isRootLevel, isRequired, hasId, optionSchemasByType[optionType]);
50
+ if (!isRequired && isRootLevel) {
51
+ return null;
52
+ }
53
+ if (!hasId && isRootLevel) {
54
+ return null;
55
+ }
56
+ examples.push(_jsx("div", { className: "m-b-3", children: _jsx(BeforeAndAfter, { step: step, configuration: _jsx(ConfigurationTable, { ordinal: examples.length + 1, step: step, configuration: {
57
+ isRootLevel,
58
+ isRequired,
59
+ withId: hasId,
60
+ optionType,
61
+ } }) }) }, `${isRootLevel}-${isRequired}-${hasId}-${optionType}`));
62
+ });
63
+ });
64
+ });
65
+ });
66
+ return examples;
67
+ }
68
+ const getStep = (rootLevel, required, withId, singleOption) => {
69
+ const oneOfSchema = {
70
+ $id: withId && rootLevel ? '#oneOfSchemaId' : undefined,
71
+ title: 'One Of Schema Title',
72
+ placeholder: 'Select an option',
73
+ oneOf: [singleOption],
74
+ // control: 'tab',
75
+ };
76
+ const objectSchemaWrapper = {
77
+ type: 'object',
78
+ $id: '#objectSchemaWrapper',
79
+ title: 'Object Schema Wrapper Title',
80
+ displayOrder: ['childSchema'],
81
+ properties: {
82
+ childSchema: oneOfSchema,
83
+ },
84
+ required: required ? ['childSchema'] : [],
85
+ };
86
+ return {
87
+ id: 'step-id',
88
+ title: 'Step Title',
89
+ schemas: [rootLevel ? oneOfSchema : objectSchemaWrapper],
90
+ layout: [
91
+ {
92
+ type: 'form',
93
+ schemaId: rootLevel ? '#oneOfSchemaId' : '#objectSchemaWrapper',
94
+ },
95
+ {
96
+ type: 'button',
97
+ title: 'Submit',
98
+ behavior: { type: 'action', action: { url: '/submit' } },
99
+ },
100
+ ],
101
+ };
102
+ };
103
+ function ConfigurationTable({ configuration, ordinal, step, }) {
104
+ return (_jsxs(_Fragment, { children: [_jsxs("h4", { children: ["Configuration ", String(ordinal)] }), _jsxs("ul", { style: { paddingLeft: '16px', marginBottom: '4px' }, children: [_jsxs("li", { children: ["OneOf is at ", _jsxs("strong", { children: ["root level: ", configuration.isRootLevel ? 'Yes' : 'No'] })] }), _jsxs("li", { children: ["OneOf is ", _jsxs("strong", { children: ["required: ", configuration.isRequired ? 'Yes' : 'No'] })] }), _jsxs("li", { children: ["OneOf has ", _jsxs("strong", { children: ["$id: ", configuration.withId ? 'Yes' : 'No'] })] }), _jsxs("li", { children: ["Option Schema Type: ", _jsx("strong", { children: configuration.optionType })] })] }), _jsxs("details", { children: [_jsx("summary", { children: "Step JSON" }), _jsx("pre", { children: JSON.stringify(step, null, 2) })] })] }));
105
+ }
106
+ function BeforeAndAfter({ configuration, step }) {
107
+ return (_jsxs("div", { style: { display: 'flex', gap: '16px' }, children: [_jsx("div", { style: { flex: 1, padding: '8px' }, children: configuration }), _jsxs("div", { style: { flex: 2, border: '1px dashed #999', borderRadius: '8px', padding: '8px' }, children: [_jsx("strong", { children: "Before" }), _jsx("br", {}), renderWithStepAndOverrides(step, {
108
+ httpClient,
109
+ features: { bugfix: false },
110
+ })] }), _jsxs("div", { style: { flex: 2, border: '1px dashed #999', borderRadius: '8px', padding: '8px' }, children: [_jsx("strong", { children: "After" }), _jsx("br", {}), renderWithStepAndOverrides(step, {
111
+ httpClient,
112
+ features: { bugfix: true },
113
+ })] })] }));
114
+ }
@@ -37,6 +37,24 @@ describe('Persist Async', () => {
37
37
  ],
38
38
  layout: [{ type: 'form', schemaId: '#persist-async-schema' }, submitButtonComponent],
39
39
  });
40
+ const getStepWithPersistAsyncNoObject = (childSchema) => ({
41
+ id: 'step-1',
42
+ title: 'Persist Async Step',
43
+ schemas: [
44
+ {
45
+ $id: '#persist-async-schema',
46
+ type: 'string',
47
+ persistAsync: {
48
+ idProperty: 'id',
49
+ url: '/persist-async',
50
+ method: 'POST',
51
+ param: 'value',
52
+ schema: childSchema,
53
+ },
54
+ },
55
+ ],
56
+ layout: [{ type: 'form', schemaId: '#persist-async-schema' }, submitButtonComponent],
57
+ });
40
58
  const renderDF = (httpClient, initialStep, onError = vi.fn()) => renderWithProviders(_jsx(DynamicFlowWise, { flowId: "persist-async-test-flow", httpClient: httpClient, initialStep: initialStep, onError: onError, onCompletion: () => { } }));
41
59
  describe('with a string schema', () => {
42
60
  const getStepWithStringSchema = () => getStepWithPersisAsync({ type: 'string', title: 'Credit Card Number' });
@@ -199,6 +217,21 @@ describe('Persist Async', () => {
199
217
  await waitFor(() => expect(mockHttpClient).toHaveBeenCalledTimes(1));
200
218
  expect(screen.getByText('Server-side error')).toBeInTheDocument();
201
219
  });
220
+ it('should set component errors if persist async fails (server error message) (schema not wrapped in object)', async () => {
221
+ const mockHttpClient = vi
222
+ .fn()
223
+ .mockResolvedValue(respondWith({ validation: { value: 'Server-side error' } }, { status: 422 }));
224
+ const step = getStepWithPersistAsyncNoObject({
225
+ type: 'string',
226
+ title: 'Credit Card Number',
227
+ });
228
+ renderDF(mockHttpClient, step);
229
+ const input = screen.getByRole('textbox', { name: 'Credit Card Number' });
230
+ await user.type(input, '1111-1111-1111-1111');
231
+ await user.tab();
232
+ await waitFor(() => expect(mockHttpClient).toHaveBeenCalledTimes(1));
233
+ expect(screen.getByText('Server-side error')).toBeInTheDocument();
234
+ });
202
235
  test.each([
203
236
  ['null, 404', new Response(null, { status: 404 })],
204
237
  ['wrong, 200', new Response(JSON.stringify({ wrongId: 'wishful-token' }), { status: 200 })],