@abgov/jsonforms-components 2.0.0 → 2.1.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.
package/index.esm.js CHANGED
@@ -1,11 +1,11 @@
1
1
  import * as runtime from 'react/jsx-runtime';
2
2
  import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
3
3
  import React, { createContext, useContext, useReducer, useMemo, useEffect, useState, useRef, useCallback } from 'react';
4
- import { GoAFormItem, GoAInput, GoATextArea, GoACallout, GoAInputDate, GoAInputDateTime, GoAInputTime, GoARadioGroup, GoARadioItem, GoACheckbox, GoAIcon, GoAButton, GoAGrid, GoAFormStepper, GoAFormStep, GoAPages, GoAModal, GoAButtonGroup, GoATable, GoAIconButton, GoAFileUploadInput, GoACircularProgress, GoAContainer, GoADropdown, GoADropdownItem, GoADetails, GoASpinner } from '@abgov/react-components';
4
+ import { GoAFormItem, GoAInput, GoATextArea, GoACallout, GoAInputDate, GoAInputDateTime, GoAInputTime, GoARadioGroup, GoARadioItem, GoACheckbox, GoAIcon, GoAGrid, GoAFormStepper, GoAFormStep, GoAPages, GoAButton, GoAModal, GoAButtonGroup, GoATable, GoAIconButton, GoAFileUploadInput, GoACircularProgress, GoAContainer, GoADropdown, GoADropdownItem, GoADetails, GoASpinner } from '@abgov/react-components';
5
5
  import styled from 'styled-components';
6
6
  import axios from 'axios';
7
7
  import get$1 from 'lodash/get';
8
- import { rankWith, isStringControl, and, optionIs, uiTypeIs, isDateControl, isNumberControl, isIntegerControl, isDateTimeControl, isTimeControl, isEnumControl, isBooleanControl, getControlPath, toDataPath, deriveLabelForUISchemaElement, isEnabled, getAjv, isVisible, schemaTypeIs, formatIs, createDefaultValue, or, isObjectArrayControl, isPrimitiveArrayControl, Paths, schemaMatches, hasType, isControl, isCategorization, isLayout } from '@jsonforms/core';
8
+ import { rankWith, isStringControl, and, optionIs, uiTypeIs, isDateControl, isNumberControl, isIntegerControl, isDateTimeControl, isTimeControl, isEnumControl, isBooleanControl, getAjv, isVisible, getControlPath, toDataPath, deriveLabelForUISchemaElement, isEnabled, schemaTypeIs, formatIs, createDefaultValue, or, isObjectArrayControl, isPrimitiveArrayControl, Paths, schemaMatches, hasType, isControl, isCategorization, isLayout } from '@jsonforms/core';
9
9
  import { withJsonFormsControlProps, withJsonFormsRendererProps, withJsonFormsEnumProps, withTranslateProps, useJsonForms, JsonFormsDispatch, withJsonFormsLayoutProps, withJsonFormsArrayLayoutProps, withJsonFormsCellProps } from '@jsonforms/react';
10
10
  import * as _$c from 'lodash';
11
11
  import { isEqual, isObject as isObject$f } from 'lodash';
@@ -2635,7 +2635,8 @@ const invalidSin = 'Social insurance number is invalid';
2635
2635
  * @param words
2636
2636
  * @returns sentence word string.
2637
2637
  */
2638
- const capitalizeFirstLetter$1 = words => {
2638
+ const capitalizeFirstLetter = words => {
2639
+ if (!words) return ''; // Handle empty strings
2639
2640
  const value = words.charAt(0).toUpperCase() + words.slice(1).toLowerCase();
2640
2641
  return value;
2641
2642
  };
@@ -2661,7 +2662,7 @@ const controlScopeMatchesLabel = (scope, label) => {
2661
2662
  const getLabelText = (scope, label) => {
2662
2663
  let labelToUpdate = '';
2663
2664
  if (controlScopeMatchesLabel(scope, label || '') && !areAllUppercase(label)) {
2664
- labelToUpdate = capitalizeFirstLetter$1(label || '');
2665
+ labelToUpdate = capitalizeFirstLetter(label || '');
2665
2666
  } else {
2666
2667
  labelToUpdate = label || '';
2667
2668
  }
@@ -3803,8 +3804,7 @@ let _$a = t => t,
3803
3804
  _t3$5,
3804
3805
  _t4$5,
3805
3806
  _t5$3,
3806
- _t6$3,
3807
- _t7$2;
3807
+ _t6$3;
3808
3808
  const FormFieldWrapper = styled.div(_t$a || (_t$a = _$a`
3809
3809
  margin-bottom: var(--goa-space-l);
3810
3810
  `));
@@ -3823,7 +3823,7 @@ const RequiredTextLabel = styled.label(_t3$5 || (_t3$5 = _$a`
3823
3823
  font-style: normal;
3824
3824
  `));
3825
3825
  const PageReviewNameCol = styled.td(_t4$5 || (_t4$5 = _$a`
3826
- width: 70%;
3826
+ width: 80%;
3827
3827
  padding-top: var(--goa-space-s);
3828
3828
  padding-bottom: var(--goa-space-s);
3829
3829
  padding-right: var(--goa-space-m);
@@ -3832,11 +3832,8 @@ const PageReviewValueCol = styled.td(_t5$3 || (_t5$3 = _$a`
3832
3832
  width: 20%;
3833
3833
  text-align: left;
3834
3834
  `));
3835
- const PageReviewActionCol = styled.td(_t6$3 || (_t6$3 = _$a`
3836
- width: 10%;
3837
- `));
3838
3835
  //Check and unchecked are different heights otherwise
3839
- const CheckboxWrapper = styled.div(_t7$2 || (_t7$2 = _$a`
3836
+ const CheckboxWrapper = styled.div(_t6$3 || (_t6$3 = _$a`
3840
3837
  height: 28px;
3841
3838
  `));
3842
3839
 
@@ -5297,470 +5294,128 @@ const GoInputBaseReview = props => jsx(GoAInputBaseControl, Object.assign({}, pr
5297
5294
  }));
5298
5295
  const GoInputBaseReviewControl = withJsonFormsControlProps(GoInputBaseReview);
5299
5296
 
5300
- // eslint-disable-next-line
5301
- const getProperty = (obj, propName) => {
5302
- if (obj[propName] !== undefined) return obj[propName];
5303
- for (const key in obj) {
5304
- if (typeof obj[key] === 'object' && obj[key] !== null) {
5305
- const result = getProperty(obj[key], propName);
5306
- if (result !== undefined) return result;
5307
- }
5308
- }
5309
- };
5310
- // eslint-disable-next-line
5311
- const pickPropertyValues = (obj, property, endWithType) => {
5312
- let values = [];
5313
- Object.keys(obj).forEach(function (key) {
5314
- var _a;
5315
- if (key === property) {
5316
- values.push(obj[key]);
5317
- } else if (_$c.isObject(obj[key])) {
5318
- // if the object type is equal to end type, we are not going to continue the recursive approach
5319
- if (endWithType && ((_a = obj[key]) === null || _a === void 0 ? void 0 : _a.type) === endWithType) {
5320
- if (property in obj[key]) {
5321
- values.push(obj[key][property]);
5322
- }
5297
+ const GoAInputBaseTableReview = props => {
5298
+ var _a, _b, _c;
5299
+ const {
5300
+ data,
5301
+ uischema,
5302
+ label
5303
+ } = props;
5304
+ const labelToUpdate = convertToSentenceCase(getLabelText(uischema.scope, label || ''));
5305
+ let reviewText = data;
5306
+ const isBoolean = typeof data === 'boolean';
5307
+ if (isBoolean) {
5308
+ const checkboxLabel = ((_b = (_a = uischema.options) === null || _a === void 0 ? void 0 : _a.text) === null || _b === void 0 ? void 0 : _b.trim()) || convertToSentenceCase(getLastSegmentFromPointer(uischema.scope));
5309
+ if (((_c = uischema.options) === null || _c === void 0 ? void 0 : _c.radio) === true) {
5310
+ reviewText = data ? `Yes` : `No`;
5311
+ } else {
5312
+ if (label !== '' || typeof label === 'boolean') {
5313
+ reviewText = data ? `Yes` : `No`;
5323
5314
  } else {
5324
- values = [...values, ...pickPropertyValues(obj[key], property, endWithType)];
5315
+ reviewText = data ? `Yes (${checkboxLabel.trim()})` : `No (${checkboxLabel.trim()})`;
5325
5316
  }
5326
- } else if (_$c.isArray(obj[key])) {
5327
- const nextValues = obj[key].map(function (arrayObj) {
5328
- return pickPropertyValues(arrayObj, property, endWithType);
5329
- });
5330
- values = [...values, ...nextValues];
5331
5317
  }
5318
+ }
5319
+ return jsxs("tr", {
5320
+ "data-testid": `input-base-table-${label}-row`,
5321
+ children: [jsx(PageReviewNameCol, {
5322
+ children: jsx("strong", {
5323
+ children: labelToUpdate
5324
+ })
5325
+ }), jsx(PageReviewValueCol, {
5326
+ children: reviewText
5327
+ })]
5332
5328
  });
5333
- return values;
5334
5329
  };
5330
+ const GoAInputBaseTableReviewControl = withJsonFormsControlProps(GoAInputBaseTableReview);
5335
5331
 
5336
- const isErrorPathIncluded = (errorPaths, path) => {
5337
- return errorPaths.some(ePath => {
5338
- /**
5339
- * case A: errorPaths: [name] path: [name]
5340
- *
5341
- * case B: errorPath: [name] path: [name.firstName]
5342
- * */
5343
- return ePath === path || path.startsWith(ePath + '.');
5344
- });
5332
+ let _$7 = t => t,
5333
+ _t$7;
5334
+ const renderLayoutElements = (elements, schema, path, enabled, renderers, cells) => {
5335
+ return elements.map((child, index) => jsx("div", {
5336
+ children: jsx(JsonFormsDispatch, {
5337
+ uischema: child,
5338
+ schema: schema,
5339
+ path: path,
5340
+ enabled: enabled,
5341
+ renderers: renderers,
5342
+ cells: cells
5343
+ }, path)
5344
+ }, index));
5345
5345
  };
5346
- function isNumber(value) {
5347
- return value != null && value !== '' && !isNaN(Number(value.toString()));
5348
- }
5349
- const getIncompletePaths = (ajv, scopes) => {
5350
- var _a;
5351
- const requiredErrorPaths = (_a = ajv === null || ajv === void 0 ? void 0 : ajv.errors) === null || _a === void 0 ? void 0 : _a.filter(e => e.keyword === 'required' || e.keyword === 'minLength').map(e => {
5352
- return getControlPath(e);
5346
+ const withAjvProps = Component => function WithAjvProps(props) {
5347
+ const ctx = useJsonForms();
5348
+ const ajv = getAjv({
5349
+ jsonforms: Object.assign({}, ctx)
5353
5350
  });
5354
- const _scopes = scopes.map(scope => toDataPath(scope)).filter(path => requiredErrorPaths && isErrorPathIncluded(requiredErrorPaths, path));
5355
- return _scopes;
5351
+ return jsx(Component, Object.assign({}, props, {
5352
+ ajv: ajv
5353
+ }));
5356
5354
  };
5357
- const subErrorInParent = (error, paths) => {
5358
- /*
5359
- Detect is there sub error in an object array.
5360
- For example: error with instance path /roadmap/0/when belongs to /roadmap
5361
- */
5362
- const errorPaths = error.instancePath.split('/');
5363
- if (errorPaths.length < 2) return false;
5364
- // For case /roadmap/0
5365
- if (errorPaths.length > 1 && isNumber(errorPaths[errorPaths.length - 1])) {
5366
- const parentPath = errorPaths.slice(0, errorPaths.length - 1).join('/');
5367
- return paths.includes(parentPath);
5368
- }
5369
- // For case /roadmap/0/when
5370
- if (errorPaths.length > 2 && isNumber(errorPaths[errorPaths.length - 2])) {
5371
- const parentPath = errorPaths.slice(0, errorPaths.length - 2).join('/');
5372
- return paths.includes(parentPath);
5355
+ const LayoutRenderer = ({
5356
+ elements,
5357
+ schema,
5358
+ path,
5359
+ enabled,
5360
+ direction,
5361
+ renderers,
5362
+ cells,
5363
+ visible,
5364
+ width
5365
+ }) => {
5366
+ if (isEmpty(elements)) {
5367
+ return null;
5368
+ } else {
5369
+ if (direction === 'row') {
5370
+ return jsx(Visible, {
5371
+ visible: visible,
5372
+ children: jsx(GoAGrid, {
5373
+ minChildWidth: width || '10ch',
5374
+ children: renderLayoutElements(elements, schema, path, enabled, renderers, cells)
5375
+ })
5376
+ });
5377
+ } else {
5378
+ return jsx(Visible, {
5379
+ visible: visible,
5380
+ children: renderLayoutElements(elements, schema, path, enabled, renderers, cells)
5381
+ });
5382
+ }
5373
5383
  }
5374
- return false;
5375
5384
  };
5376
- const getErrorsInScopes = (errors, scopes) => {
5377
- return errors.filter(e => {
5378
- // transfer scope #properties/value to data path /value
5379
- const dataPaths = scopes.map(s => '/' + toDataPath(s));
5380
- return dataPaths.includes(e.instancePath) || subErrorInParent(e, dataPaths);
5381
- });
5385
+ const ReviewLayoutRenderer = ({
5386
+ elements,
5387
+ schema,
5388
+ path,
5389
+ enabled,
5390
+ direction,
5391
+ renderers,
5392
+ cells,
5393
+ visible,
5394
+ width
5395
+ }) => {
5396
+ if (isEmpty(elements)) {
5397
+ return null;
5398
+ } else {
5399
+ if (direction === 'row') {
5400
+ return jsx(Visible, {
5401
+ visible: visible,
5402
+ children: jsx(ReviewGrid, {
5403
+ children: renderLayoutElements(elements, schema, path, enabled, renderers, cells)
5404
+ })
5405
+ });
5406
+ } else {
5407
+ return jsx(Visible, {
5408
+ visible: visible,
5409
+ children: renderLayoutElements(elements, schema, path, enabled, renderers, cells)
5410
+ });
5411
+ }
5412
+ }
5382
5413
  };
5383
-
5384
- const stepperReducer = (state, action) => {
5385
- var _a, _b;
5386
- const {
5387
- activeId,
5388
- categories
5389
- } = state;
5390
- const lastId = categories[categories.length - 1].id;
5391
- switch (action.type) {
5392
- case 'update/uischema':
5393
- {
5394
- return Object.assign({}, action.payload.state);
5395
- }
5396
- case 'page/next':
5397
- {
5398
- state.activeId += 1;
5399
- if (activeId === lastId) {
5400
- state.isOnReview = true;
5401
- state.hasNextButton = false;
5402
- state.hasPrevButton = false;
5403
- } else {
5404
- state.hasNextButton = true;
5405
- state.hasPrevButton = true;
5406
- state.isOnReview = false;
5407
- }
5408
- state.categories[activeId].isVisited = true;
5409
- return Object.assign({}, state);
5410
- }
5411
- case 'page/prev':
5412
- {
5413
- state.categories[activeId].isVisited = true;
5414
- if (activeId > 0) {
5415
- state.activeId -= 1;
5416
- state.hasPrevButton = state.activeId !== 0;
5417
- state.hasNextButton = true;
5418
- state.isOnReview = false;
5419
- }
5420
- return Object.assign({}, state);
5421
- }
5422
- case 'page/to/index':
5423
- {
5424
- const {
5425
- id
5426
- } = action.payload;
5427
- state.activeId = id;
5428
- if (id > lastId) {
5429
- state.isOnReview = true;
5430
- state.hasNextButton = false;
5431
- state.hasPrevButton = true;
5432
- return Object.assign({}, state);
5433
- } else {
5434
- state.categories[id].isVisited = true;
5435
- state.hasNextButton = id <= lastId;
5436
- state.hasPrevButton = id !== 0;
5437
- state.isOnReview = false;
5438
- state.maxReachedStep = Math.max(state.maxReachedStep, activeId);
5439
- return Object.assign({}, state);
5440
- }
5441
- }
5442
- case 'update/category':
5443
- {
5444
- const {
5445
- id,
5446
- ajv,
5447
- errors
5448
- } = action.payload;
5449
- if (id === state.categories.length) {
5450
- return Object.assign({}, state);
5451
- }
5452
- /*
5453
- ctx.core.errors only includes required errors when the fields are touched. In this case, we still ajv to figure out the required errors at the very beginning.
5454
- */
5455
- const incompletePaths = getIncompletePaths(ajv, ((_a = state.categories[id]) === null || _a === void 0 ? void 0 : _a.scopes) || []);
5456
- const errorsInCategory = getErrorsInScopes(errors, ((_b = state.categories[id]) === null || _b === void 0 ? void 0 : _b.scopes) || []);
5457
- state.categories[id].isCompleted = (incompletePaths === null || incompletePaths === void 0 ? void 0 : incompletePaths.length) === 0;
5458
- state.categories[id].isValid = errorsInCategory.length === 0;
5459
- state.categories[id].isVisited = true;
5460
- return Object.assign({}, state);
5461
- }
5462
- case 'validate/form':
5463
- {
5464
- const {
5465
- errors
5466
- } = action.payload;
5467
- state.isValid = errors.length === 0;
5468
- return Object.assign({}, state);
5469
- }
5470
- case 'toggle/category/review-link':
5471
- {
5472
- const {
5473
- id
5474
- } = action.payload;
5475
- state.categories[id].showReviewPageLink = !state.categories[id].showReviewPageLink;
5476
- return Object.assign({}, state);
5477
- }
5478
- default:
5479
- return state;
5480
- }
5481
- };
5482
-
5483
- const createStepperContextInitData = props => {
5484
- var _a;
5485
- const {
5486
- uischema,
5487
- data,
5488
- schema,
5489
- ajv,
5490
- t,
5491
- visible,
5492
- path
5493
- } = props;
5494
- const categorization = uischema;
5495
- const valid = ajv.validate(schema, data || {});
5496
- const categories = (_a = categorization.elements) === null || _a === void 0 ? void 0 : _a.map((c, id) => {
5497
- const scopes = pickPropertyValues(c, 'scope', 'ListWithDetail');
5498
- const incompletePaths = getIncompletePaths(ajv, scopes);
5499
- return {
5500
- id,
5501
- label: deriveLabelForUISchemaElement(c, t),
5502
- scopes,
5503
- isVisited: false,
5504
- isCompleted: (incompletePaths === null || incompletePaths === void 0 ? void 0 : incompletePaths.length) === 0,
5505
- isValid: (incompletePaths === null || incompletePaths === void 0 ? void 0 : incompletePaths.length) === 0,
5506
- uischema: c,
5507
- showReviewPageLink: props.withBackReviewBtn || false,
5508
- isEnabled: isEnabled(c, data, '', ajv),
5509
- visible
5510
- };
5511
- });
5512
- const activeId = (props === null || props === void 0 ? void 0 : props.activeId) || 0;
5513
- return {
5514
- categories: categories,
5515
- activeId,
5516
- hasNextButton: activeId !== (categories === null || categories === void 0 ? void 0 : categories.length),
5517
- hasPrevButton: activeId > 0 && activeId !== (categories === null || categories === void 0 ? void 0 : categories.length),
5518
- path,
5519
- isOnReview: activeId === (categories === null || categories === void 0 ? void 0 : categories.length),
5520
- isValid: valid === true,
5521
- maxReachedStep: 0
5522
- };
5523
- };
5524
- const JsonFormsStepperContext = /*#__PURE__*/createContext(undefined);
5525
- const JsonFormsStepperContextProvider = ({
5526
- children,
5527
- StepperProps
5528
- }) => {
5529
- var _a;
5530
- const ctx = useJsonForms();
5531
- const {
5532
- schema,
5533
- ajv
5534
- } = StepperProps;
5535
- const [stepperState, dispatch] = useReducer(stepperReducer, createStepperContextInitData(StepperProps));
5536
- const stepperDispatch = (StepperProps === null || StepperProps === void 0 ? void 0 : StepperProps.customDispatch) || dispatch;
5537
- const context = useMemo(() => {
5538
- return {
5539
- isProvided: true,
5540
- stepperDispatch,
5541
- selectStepperState: () => {
5542
- return stepperState;
5543
- },
5544
- selectIsDisabled: () => {
5545
- var _a;
5546
- const category = (_a = stepperState.categories) === null || _a === void 0 ? void 0 : _a[stepperState.activeId];
5547
- return category === undefined ? false : !(category === null || category === void 0 ? void 0 : category.isEnabled);
5548
- },
5549
- selectIsActive: id => {
5550
- return id === stepperState.activeId;
5551
- },
5552
- selectPath: () => {
5553
- return stepperState.path;
5554
- },
5555
- selectCategory: id => {
5556
- return stepperState.categories[id];
5557
- },
5558
- validatePage: id => {
5559
- var _a;
5560
- stepperDispatch({
5561
- type: 'update/category',
5562
- payload: {
5563
- errors: (_a = ctx === null || ctx === void 0 ? void 0 : ctx.core) === null || _a === void 0 ? void 0 : _a.errors,
5564
- id,
5565
- ajv
5566
- }
5567
- });
5568
- },
5569
- goToPage: (id, updateCategoryId) => {
5570
- var _a, _b, _c;
5571
- ajv.validate(schema, ((_a = ctx.core) === null || _a === void 0 ? void 0 : _a.data) || {});
5572
- if (stepperState.isOnReview !== true) {
5573
- for (let i = 0; i < id; i++) {
5574
- stepperDispatch({
5575
- type: 'update/category',
5576
- payload: {
5577
- errors: (_b = ctx === null || ctx === void 0 ? void 0 : ctx.core) === null || _b === void 0 ? void 0 : _b.errors,
5578
- id: i,
5579
- ajv
5580
- }
5581
- });
5582
- }
5583
- }
5584
- stepperDispatch({
5585
- type: 'validate/form',
5586
- payload: {
5587
- errors: (_c = ctx === null || ctx === void 0 ? void 0 : ctx.core) === null || _c === void 0 ? void 0 : _c.errors
5588
- }
5589
- });
5590
- stepperDispatch({
5591
- type: 'page/to/index',
5592
- payload: {
5593
- id
5594
- }
5595
- });
5596
- },
5597
- toggleShowReviewLink: id => {
5598
- stepperDispatch({
5599
- type: 'toggle/category/review-link',
5600
- payload: {
5601
- id
5602
- }
5603
- });
5604
- }
5605
- };
5606
- }, [stepperDispatch, stepperState, (_a = ctx.core) === null || _a === void 0 ? void 0 : _a.errors]);
5607
- useEffect(() => {
5608
- if ((context === null || context === void 0 ? void 0 : context.isProvided) === true) {
5609
- /* The block is used to cache the state for the tenant web app review editor */
5610
- stepperDispatch({
5611
- type: 'update/uischema',
5612
- payload: {
5613
- state: createStepperContextInitData(Object.assign(Object.assign({}, StepperProps), {
5614
- activeId: stepperState === null || stepperState === void 0 ? void 0 : stepperState.activeId
5615
- }))
5616
- }
5617
- });
5618
- context.goToPage(stepperState.maxReachedStep);
5619
- context.goToPage(stepperState.activeId);
5620
- }
5621
- }, [JSON.stringify(StepperProps.uischema), JSON.stringify(StepperProps.schema)]);
5622
- return jsx(JsonFormsStepperContext.Provider, {
5623
- value: context,
5624
- children: children
5625
- });
5626
- };
5627
-
5628
- const GoAInputBaseTableReview = props => {
5629
- var _a, _b, _c, _d;
5630
- const {
5631
- data,
5632
- uischema,
5633
- label
5634
- } = props;
5635
- const labelToUpdate = convertToSentenceCase(getLabelText(uischema.scope, label || ''));
5636
- const categoryIndex = (_a = uischema.options) === null || _a === void 0 ? void 0 : _a.categoryIndex;
5637
- const formStepperCtx = useContext(JsonFormsStepperContext);
5638
- let reviewText = data;
5639
- const isBoolean = typeof data === 'boolean';
5640
- if (isBoolean) {
5641
- const checkboxLabel = ((_c = (_b = uischema.options) === null || _b === void 0 ? void 0 : _b.text) === null || _c === void 0 ? void 0 : _c.trim()) || convertToSentenceCase(getLastSegmentFromPointer(uischema.scope));
5642
- if (((_d = uischema.options) === null || _d === void 0 ? void 0 : _d.radio) === true) {
5643
- reviewText = data ? `Yes` : `No`;
5644
- } else {
5645
- if (label !== '' || typeof label === 'boolean') {
5646
- reviewText = data ? `Yes` : `No`;
5647
- } else {
5648
- reviewText = data ? `Yes (${checkboxLabel.trim()})` : `No (${checkboxLabel.trim()})`;
5649
- }
5650
- }
5651
- }
5652
- return jsxs("tr", {
5653
- "data-testid": `input-base-table-${label}-row`,
5654
- children: [jsx(PageReviewNameCol, {
5655
- children: jsx("strong", {
5656
- children: labelToUpdate
5657
- })
5658
- }), jsx(PageReviewValueCol, {
5659
- children: reviewText
5660
- }), jsx(PageReviewActionCol, {
5661
- children: jsx(GoAButton, {
5662
- type: "tertiary",
5663
- testId: `page-review-change-${label}-btn`,
5664
- onClick: () => {
5665
- if (formStepperCtx) {
5666
- formStepperCtx.toggleShowReviewLink(categoryIndex);
5667
- formStepperCtx.goToPage(categoryIndex);
5668
- }
5669
- },
5670
- children: "Change"
5671
- })
5672
- })]
5673
- });
5674
- };
5675
- const GoAInputBaseTableReviewControl = withJsonFormsControlProps(GoAInputBaseTableReview);
5676
-
5677
- let _$7 = t => t,
5678
- _t$7;
5679
- const renderLayoutElements = (elements, schema, path, enabled, renderers, cells) => {
5680
- return elements.map((child, index) => jsx("div", {
5681
- children: jsx(JsonFormsDispatch, {
5682
- uischema: child,
5683
- schema: schema,
5684
- path: path,
5685
- enabled: enabled,
5686
- renderers: renderers,
5687
- cells: cells
5688
- }, path)
5689
- }, index));
5690
- };
5691
- const withAjvProps = Component => function WithAjvProps(props) {
5692
- const ctx = useJsonForms();
5693
- const ajv = getAjv({
5694
- jsonforms: Object.assign({}, ctx)
5695
- });
5696
- return jsx(Component, Object.assign({}, props, {
5697
- ajv: ajv
5698
- }));
5699
- };
5700
- const LayoutRenderer = ({
5701
- elements,
5702
- schema,
5703
- path,
5704
- enabled,
5705
- direction,
5706
- renderers,
5707
- cells,
5708
- visible,
5709
- width
5710
- }) => {
5711
- if (isEmpty(elements)) {
5712
- return null;
5713
- } else {
5714
- if (direction === 'row') {
5715
- return jsx(Visible, {
5716
- visible: visible,
5717
- children: jsx(GoAGrid, {
5718
- minChildWidth: width || '10ch',
5719
- children: renderLayoutElements(elements, schema, path, enabled, renderers, cells)
5720
- })
5721
- });
5722
- } else {
5723
- return jsx(Visible, {
5724
- visible: visible,
5725
- children: renderLayoutElements(elements, schema, path, enabled, renderers, cells)
5726
- });
5727
- }
5728
- }
5729
- };
5730
- const ReviewLayoutRenderer = ({
5731
- elements,
5732
- schema,
5733
- path,
5734
- enabled,
5735
- direction,
5736
- renderers,
5737
- cells,
5738
- visible,
5739
- width
5740
- }) => {
5741
- if (isEmpty(elements)) {
5742
- return null;
5743
- } else {
5744
- if (direction === 'row') {
5745
- return jsx(Visible, {
5746
- visible: visible,
5747
- children: jsx(ReviewGrid, {
5748
- children: renderLayoutElements(elements, schema, path, enabled, renderers, cells)
5749
- })
5750
- });
5751
- } else {
5752
- return jsx(Visible, {
5753
- visible: visible,
5754
- children: renderLayoutElements(elements, schema, path, enabled, renderers, cells)
5755
- });
5756
- }
5757
- }
5758
- };
5759
- const ReviewGrid = styled.div(_t$7 || (_t$7 = _$7`
5760
- display: grid;
5761
- grid-template-columns: repeat(auto-fit, minmax(250px, calc(50% - 8px)));
5762
- gap: 16px;
5763
- `));
5414
+ const ReviewGrid = styled.div(_t$7 || (_t$7 = _$7`
5415
+ display: grid;
5416
+ grid-template-columns: repeat(auto-fit, minmax(250px, calc(50% - 8px)));
5417
+ gap: 16px;
5418
+ `));
5764
5419
 
5765
5420
  let _$6 = t => t,
5766
5421
  _t$6,
@@ -5778,7 +5433,8 @@ let _$6 = t => t,
5778
5433
  _t13$1,
5779
5434
  _t14$1,
5780
5435
  _t15$1,
5781
- _t16;
5436
+ _t16$1,
5437
+ _t17$1;
5782
5438
  const ReviewItem = styled.div(_t$6 || (_t$6 = _$6`
5783
5439
  display: flex;
5784
5440
  flex-direction: column;
@@ -5869,7 +5525,14 @@ const TableReviewItem = styled.div(_t15$1 || (_t15$1 = _$6`
5869
5525
  border-radius: 5px;
5870
5526
  padding: var(--goa-space-2xl);
5871
5527
  `));
5872
- const TableReviewCategoryLabel = styled.h3(_t16 || (_t16 = _$6`
5528
+ const TableReviewPageTitleRow = styled.div(_t16$1 || (_t16$1 = _$6`
5529
+ margin-top: var(--goa-space-xl);
5530
+ display: flex;
5531
+ .right {
5532
+ margin-left: auto;
5533
+ }
5534
+ `));
5535
+ const TableReviewCategoryLabel = styled.h3(_t17$1 || (_t17$1 = _$6`
5873
5536
  color: var(--goa-color-text-secondary) !important;
5874
5537
  `));
5875
5538
 
@@ -6170,101 +5833,429 @@ $$a({ target: 'Array', proto: true }, {
6170
5833
  A.length = flattenIntoArray(A, O, O, sourceLen, 0, depthArg === undefined ? 1 : toIntegerOrInfinity(depthArg));
6171
5834
  return A;
6172
5835
  }
6173
- });
6174
-
6175
- // this method was added to unscopables after implementation
6176
- // in popular engines, so it's moved to a separate module
6177
- var addToUnscopables = addToUnscopables$4;
6178
-
6179
- // https://tc39.es/ecma262/#sec-array.prototype-@@unscopables
6180
- addToUnscopables('flat');
5836
+ });
5837
+
5838
+ // this method was added to unscopables after implementation
5839
+ // in popular engines, so it's moved to a separate module
5840
+ var addToUnscopables = addToUnscopables$4;
5841
+
5842
+ // https://tc39.es/ecma262/#sec-array.prototype-@@unscopables
5843
+ addToUnscopables('flat');
5844
+
5845
+ // eslint-disable-next-line
5846
+ const getProperty = (obj, propName) => {
5847
+ if (obj[propName] !== undefined) return obj[propName];
5848
+ for (const key in obj) {
5849
+ if (typeof obj[key] === 'object' && obj[key] !== null) {
5850
+ const result = getProperty(obj[key], propName);
5851
+ if (result !== undefined) return result;
5852
+ }
5853
+ }
5854
+ };
5855
+ // eslint-disable-next-line
5856
+ const pickPropertyValues = (obj, property, endWithType) => {
5857
+ let values = [];
5858
+ Object.keys(obj).forEach(function (key) {
5859
+ var _a;
5860
+ if (key === property) {
5861
+ values.push(obj[key]);
5862
+ } else if (_$c.isObject(obj[key])) {
5863
+ // if the object type is equal to end type, we are not going to continue the recursive approach
5864
+ if (endWithType && ((_a = obj[key]) === null || _a === void 0 ? void 0 : _a.type) === endWithType) {
5865
+ if (property in obj[key]) {
5866
+ values.push(obj[key][property]);
5867
+ }
5868
+ } else {
5869
+ values = [...values, ...pickPropertyValues(obj[key], property, endWithType)];
5870
+ }
5871
+ } else if (_$c.isArray(obj[key])) {
5872
+ const nextValues = obj[key].map(function (arrayObj) {
5873
+ return pickPropertyValues(arrayObj, property, endWithType);
5874
+ });
5875
+ values = [...values, ...nextValues];
5876
+ }
5877
+ });
5878
+ return values;
5879
+ };
5880
+
5881
+ const FormStepperReviewer = props => {
5882
+ var _a, _b, _c;
5883
+ const {
5884
+ uischema,
5885
+ data,
5886
+ schema,
5887
+ ajv,
5888
+ cells,
5889
+ enabled,
5890
+ navigationFunc
5891
+ } = props;
5892
+ const componentProps = (_b = (_a = uischema.options) === null || _a === void 0 ? void 0 : _a.componentProps) !== null && _b !== void 0 ? _b : {};
5893
+ const readOnly = (_c = componentProps === null || componentProps === void 0 ? void 0 : componentProps.readOnly) !== null && _c !== void 0 ? _c : false;
5894
+ const categorization = uischema;
5895
+ const categories = categorization.elements.filter(category => isVisible(category, data, '', ajv));
5896
+ const rescopeMaps = ['#/properties/albertaAddress', '#/properties/canadianAddress', '#/properties/sin'];
5897
+ return jsx(ReviewItem, {
5898
+ children: categories.map((category, index) => {
5899
+ const categoryLabel = category.label || category.i18n || 'Unknown Category';
5900
+ const testId = `${categoryLabel}-review-link`;
5901
+ return jsxs(ReviewItemSection, {
5902
+ children: [jsxs(ReviewItemHeader, {
5903
+ children: [jsx(ReviewItemTitle, {
5904
+ children: categoryLabel
5905
+ }), navigationFunc && jsx(Anchor, {
5906
+ onClick: () => {
5907
+ navigationFunc(index);
5908
+ },
5909
+ "data-testid": testId,
5910
+ onKeyDown: e => {
5911
+ if (!readOnly && (e.key === ' ' || e.key === 'Enter')) {
5912
+ e.preventDefault();
5913
+ navigationFunc(index);
5914
+ }
5915
+ },
5916
+ children: readOnly ? 'View' : 'Edit'
5917
+ })]
5918
+ }), jsx(GoAGrid, {
5919
+ minChildWidth: "100%",
5920
+ children: category.elements.filter(field => {
5921
+ var _a, _b;
5922
+ // [TODO] we need to double check why we cannot hide the elements at the element level
5923
+ const conditionProps = (_a = field.rule) === null || _a === void 0 ? void 0 : _a.condition;
5924
+ /* istanbul ignore next */
5925
+ if (conditionProps && data) {
5926
+ const canHideControlParts = (_b = conditionProps === null || conditionProps === void 0 ? void 0 : conditionProps.scope) === null || _b === void 0 ? void 0 : _b.split('/');
5927
+ const canHideControl = canHideControlParts && canHideControlParts[(canHideControlParts === null || canHideControlParts === void 0 ? void 0 : canHideControlParts.length) - 1];
5928
+ const isHidden = getProperty(data, canHideControl);
5929
+ if (!isHidden) {
5930
+ return field;
5931
+ }
5932
+ } else {
5933
+ return field;
5934
+ }
5935
+ }).map(e => {
5936
+ const layout = e;
5937
+ if (rescopeMaps.some(scope => {
5938
+ var _a;
5939
+ return (_a = layout.elements) === null || _a === void 0 ? void 0 : _a.map(el => {
5940
+ const element = el;
5941
+ return element.scope;
5942
+ }).includes(scope);
5943
+ })) {
5944
+ return layout.elements;
5945
+ } else {
5946
+ return e;
5947
+ }
5948
+ }).flat().map((element, index) => {
5949
+ return jsx("div", {
5950
+ className: "element-style",
5951
+ children: jsx(JsonFormsDispatch, {
5952
+ "data-testid": `jsonforms-object-list-defined-elements-dispatch`,
5953
+ schema: schema,
5954
+ uischema: element,
5955
+ enabled: enabled,
5956
+ renderers: GoAReviewRenderers,
5957
+ cells: cells
5958
+ })
5959
+ }, `form-stepper-category-${index}`);
5960
+ })
5961
+ })]
5962
+ }, index);
5963
+ })
5964
+ });
5965
+ };
5966
+ const FormStepperReviewControl = withAjvProps(withTranslateProps(withJsonFormsLayoutProps(FormStepperReviewer)));
5967
+
5968
+ const isErrorPathIncluded = (errorPaths, path) => {
5969
+ return errorPaths.some(ePath => {
5970
+ /**
5971
+ * case A: errorPaths: [name] path: [name]
5972
+ *
5973
+ * case B: errorPath: [name] path: [name.firstName]
5974
+ * */
5975
+ return ePath === path || path.startsWith(ePath + '.');
5976
+ });
5977
+ };
5978
+ function isNumber(value) {
5979
+ return value != null && value !== '' && !isNaN(Number(value.toString()));
5980
+ }
5981
+ const getIncompletePaths = (ajv, scopes) => {
5982
+ var _a;
5983
+ const requiredErrorPaths = (_a = ajv === null || ajv === void 0 ? void 0 : ajv.errors) === null || _a === void 0 ? void 0 : _a.filter(e => e.keyword === 'required' || e.keyword === 'minLength').map(e => {
5984
+ return getControlPath(e);
5985
+ });
5986
+ const _scopes = scopes.map(scope => toDataPath(scope)).filter(path => requiredErrorPaths && isErrorPathIncluded(requiredErrorPaths, path));
5987
+ return _scopes;
5988
+ };
5989
+ const subErrorInParent = (error, paths) => {
5990
+ /*
5991
+ Detect is there sub error in an object array.
5992
+ For example: error with instance path /roadmap/0/when belongs to /roadmap
5993
+ */
5994
+ const errorPaths = error.instancePath.split('/');
5995
+ if (errorPaths.length < 2) return false;
5996
+ // For case /roadmap/0
5997
+ if (errorPaths.length > 1 && isNumber(errorPaths[errorPaths.length - 1])) {
5998
+ const parentPath = errorPaths.slice(0, errorPaths.length - 1).join('/');
5999
+ return paths.includes(parentPath);
6000
+ }
6001
+ // For case /roadmap/0/when
6002
+ if (errorPaths.length > 2 && isNumber(errorPaths[errorPaths.length - 2])) {
6003
+ const parentPath = errorPaths.slice(0, errorPaths.length - 2).join('/');
6004
+ return paths.includes(parentPath);
6005
+ }
6006
+ return false;
6007
+ };
6008
+ const getErrorsInScopes = (errors, scopes) => {
6009
+ return errors.filter(e => {
6010
+ // transfer scope #properties/value to data path /value
6011
+ const dataPaths = scopes.map(s => '/' + toDataPath(s));
6012
+ return dataPaths.includes(e.instancePath) || subErrorInParent(e, dataPaths);
6013
+ });
6014
+ };
6015
+
6016
+ const stepperReducer = (state, action) => {
6017
+ var _a, _b;
6018
+ const {
6019
+ activeId,
6020
+ categories
6021
+ } = state;
6022
+ const lastId = categories[categories.length - 1].id;
6023
+ switch (action.type) {
6024
+ case 'update/uischema':
6025
+ {
6026
+ return Object.assign({}, action.payload.state);
6027
+ }
6028
+ case 'page/next':
6029
+ {
6030
+ state.activeId += 1;
6031
+ if (activeId === lastId) {
6032
+ state.isOnReview = true;
6033
+ state.hasNextButton = false;
6034
+ state.hasPrevButton = false;
6035
+ } else {
6036
+ state.hasNextButton = true;
6037
+ state.hasPrevButton = true;
6038
+ state.isOnReview = false;
6039
+ }
6040
+ state.categories[activeId].isVisited = true;
6041
+ return Object.assign({}, state);
6042
+ }
6043
+ case 'page/prev':
6044
+ {
6045
+ state.categories[activeId].isVisited = true;
6046
+ if (activeId > 0) {
6047
+ state.activeId -= 1;
6048
+ state.hasPrevButton = state.activeId !== 0;
6049
+ state.hasNextButton = true;
6050
+ state.isOnReview = false;
6051
+ }
6052
+ return Object.assign({}, state);
6053
+ }
6054
+ case 'page/to/index':
6055
+ {
6056
+ const {
6057
+ id
6058
+ } = action.payload;
6059
+ state.activeId = id;
6060
+ if (id > lastId) {
6061
+ state.isOnReview = true;
6062
+ state.hasNextButton = false;
6063
+ state.hasPrevButton = true;
6064
+ return Object.assign({}, state);
6065
+ } else {
6066
+ state.categories[id].isVisited = true;
6067
+ state.hasNextButton = id <= lastId;
6068
+ state.hasPrevButton = id !== 0;
6069
+ state.isOnReview = false;
6070
+ state.maxReachedStep = Math.max(state.maxReachedStep, activeId);
6071
+ return Object.assign({}, state);
6072
+ }
6073
+ }
6074
+ case 'update/category':
6075
+ {
6076
+ const {
6077
+ id,
6078
+ ajv,
6079
+ errors
6080
+ } = action.payload;
6081
+ if (id === state.categories.length) {
6082
+ return Object.assign({}, state);
6083
+ }
6084
+ /*
6085
+ ctx.core.errors only includes required errors when the fields are touched. In this case, we still ajv to figure out the required errors at the very beginning.
6086
+ */
6087
+ const incompletePaths = getIncompletePaths(ajv, ((_a = state.categories[id]) === null || _a === void 0 ? void 0 : _a.scopes) || []);
6088
+ const errorsInCategory = getErrorsInScopes(errors, ((_b = state.categories[id]) === null || _b === void 0 ? void 0 : _b.scopes) || []);
6089
+ state.categories[id].isCompleted = (incompletePaths === null || incompletePaths === void 0 ? void 0 : incompletePaths.length) === 0;
6090
+ state.categories[id].isValid = errorsInCategory.length === 0;
6091
+ state.categories[id].isVisited = true;
6092
+ return Object.assign({}, state);
6093
+ }
6094
+ case 'validate/form':
6095
+ {
6096
+ const {
6097
+ errors
6098
+ } = action.payload;
6099
+ state.isValid = errors.length === 0;
6100
+ return Object.assign({}, state);
6101
+ }
6102
+ case 'toggle/category/review-link':
6103
+ {
6104
+ const {
6105
+ id
6106
+ } = action.payload;
6107
+ state.categories[id].showReviewPageLink = !state.categories[id].showReviewPageLink;
6108
+ return Object.assign({}, state);
6109
+ }
6110
+ default:
6111
+ return state;
6112
+ }
6113
+ };
6181
6114
 
6182
- const FormStepperReviewer = props => {
6183
- var _a, _b, _c;
6115
+ const createStepperContextInitData = props => {
6116
+ var _a;
6184
6117
  const {
6185
6118
  uischema,
6186
6119
  data,
6187
6120
  schema,
6188
6121
  ajv,
6189
- cells,
6190
- enabled,
6191
- navigationFunc
6122
+ t,
6123
+ visible,
6124
+ path
6192
6125
  } = props;
6193
- const componentProps = (_b = (_a = uischema.options) === null || _a === void 0 ? void 0 : _a.componentProps) !== null && _b !== void 0 ? _b : {};
6194
- const readOnly = (_c = componentProps === null || componentProps === void 0 ? void 0 : componentProps.readOnly) !== null && _c !== void 0 ? _c : false;
6195
6126
  const categorization = uischema;
6196
- const categories = categorization.elements.filter(category => isVisible(category, data, '', ajv));
6197
- const rescopeMaps = ['#/properties/albertaAddress', '#/properties/canadianAddress', '#/properties/sin'];
6198
- return jsx(ReviewItem, {
6199
- children: categories.map((category, index) => {
6200
- const categoryLabel = category.label || category.i18n || 'Unknown Category';
6201
- const testId = `${categoryLabel}-review-link`;
6202
- return jsxs(ReviewItemSection, {
6203
- children: [jsxs(ReviewItemHeader, {
6204
- children: [jsx(ReviewItemTitle, {
6205
- children: categoryLabel
6206
- }), navigationFunc && jsx(Anchor, {
6207
- onClick: () => {
6208
- navigationFunc(index);
6209
- },
6210
- "data-testid": testId,
6211
- onKeyDown: e => {
6212
- if (!readOnly && (e.key === ' ' || e.key === 'Enter')) {
6213
- e.preventDefault();
6214
- navigationFunc(index);
6215
- }
6216
- },
6217
- children: readOnly ? 'View' : 'Edit'
6218
- })]
6219
- }), jsx(GoAGrid, {
6220
- minChildWidth: "100%",
6221
- children: category.elements.filter(field => {
6222
- var _a, _b;
6223
- // [TODO] we need to double check why we cannot hide the elements at the element level
6224
- const conditionProps = (_a = field.rule) === null || _a === void 0 ? void 0 : _a.condition;
6225
- /* istanbul ignore next */
6226
- if (conditionProps && data) {
6227
- const canHideControlParts = (_b = conditionProps === null || conditionProps === void 0 ? void 0 : conditionProps.scope) === null || _b === void 0 ? void 0 : _b.split('/');
6228
- const canHideControl = canHideControlParts && canHideControlParts[(canHideControlParts === null || canHideControlParts === void 0 ? void 0 : canHideControlParts.length) - 1];
6229
- const isHidden = getProperty(data, canHideControl);
6230
- if (!isHidden) {
6231
- return field;
6127
+ const valid = ajv.validate(schema, data || {});
6128
+ const categories = (_a = categorization.elements) === null || _a === void 0 ? void 0 : _a.map((c, id) => {
6129
+ const scopes = pickPropertyValues(c, 'scope', 'ListWithDetail');
6130
+ const incompletePaths = getIncompletePaths(ajv, scopes);
6131
+ return {
6132
+ id,
6133
+ label: deriveLabelForUISchemaElement(c, t),
6134
+ scopes,
6135
+ isVisited: false,
6136
+ isCompleted: (incompletePaths === null || incompletePaths === void 0 ? void 0 : incompletePaths.length) === 0,
6137
+ isValid: (incompletePaths === null || incompletePaths === void 0 ? void 0 : incompletePaths.length) === 0,
6138
+ uischema: c,
6139
+ showReviewPageLink: props.withBackReviewBtn || false,
6140
+ isEnabled: isEnabled(c, data, '', ajv),
6141
+ visible
6142
+ };
6143
+ });
6144
+ const activeId = (props === null || props === void 0 ? void 0 : props.activeId) || 0;
6145
+ return {
6146
+ categories: categories,
6147
+ activeId,
6148
+ hasNextButton: activeId !== (categories === null || categories === void 0 ? void 0 : categories.length),
6149
+ hasPrevButton: activeId > 0 && activeId !== (categories === null || categories === void 0 ? void 0 : categories.length),
6150
+ path,
6151
+ isOnReview: activeId === (categories === null || categories === void 0 ? void 0 : categories.length),
6152
+ isValid: valid === true,
6153
+ maxReachedStep: 0
6154
+ };
6155
+ };
6156
+ const JsonFormsStepperContext = /*#__PURE__*/createContext(undefined);
6157
+ const JsonFormsStepperContextProvider = ({
6158
+ children,
6159
+ StepperProps
6160
+ }) => {
6161
+ var _a;
6162
+ const ctx = useJsonForms();
6163
+ const {
6164
+ schema,
6165
+ ajv
6166
+ } = StepperProps;
6167
+ const [stepperState, dispatch] = useReducer(stepperReducer, createStepperContextInitData(StepperProps));
6168
+ const stepperDispatch = (StepperProps === null || StepperProps === void 0 ? void 0 : StepperProps.customDispatch) || dispatch;
6169
+ const context = useMemo(() => {
6170
+ return {
6171
+ isProvided: true,
6172
+ stepperDispatch,
6173
+ selectStepperState: () => {
6174
+ return stepperState;
6175
+ },
6176
+ selectIsDisabled: () => {
6177
+ var _a;
6178
+ const category = (_a = stepperState.categories) === null || _a === void 0 ? void 0 : _a[stepperState.activeId];
6179
+ return category === undefined ? false : !(category === null || category === void 0 ? void 0 : category.isEnabled);
6180
+ },
6181
+ selectIsActive: id => {
6182
+ return id === stepperState.activeId;
6183
+ },
6184
+ selectPath: () => {
6185
+ return stepperState.path;
6186
+ },
6187
+ selectCategory: id => {
6188
+ return stepperState.categories[id];
6189
+ },
6190
+ validatePage: id => {
6191
+ var _a;
6192
+ stepperDispatch({
6193
+ type: 'update/category',
6194
+ payload: {
6195
+ errors: (_a = ctx === null || ctx === void 0 ? void 0 : ctx.core) === null || _a === void 0 ? void 0 : _a.errors,
6196
+ id,
6197
+ ajv
6198
+ }
6199
+ });
6200
+ },
6201
+ goToPage: (id, updateCategoryId) => {
6202
+ var _a, _b, _c;
6203
+ ajv.validate(schema, ((_a = ctx.core) === null || _a === void 0 ? void 0 : _a.data) || {});
6204
+ if (stepperState.isOnReview !== true) {
6205
+ for (let i = 0; i < id; i++) {
6206
+ stepperDispatch({
6207
+ type: 'update/category',
6208
+ payload: {
6209
+ errors: (_b = ctx === null || ctx === void 0 ? void 0 : ctx.core) === null || _b === void 0 ? void 0 : _b.errors,
6210
+ id: i,
6211
+ ajv
6232
6212
  }
6233
- } else {
6234
- return field;
6235
- }
6236
- }).map(e => {
6237
- const layout = e;
6238
- if (rescopeMaps.some(scope => {
6239
- var _a;
6240
- return (_a = layout.elements) === null || _a === void 0 ? void 0 : _a.map(el => {
6241
- const element = el;
6242
- return element.scope;
6243
- }).includes(scope);
6244
- })) {
6245
- return layout.elements;
6246
- } else {
6247
- return e;
6248
- }
6249
- }).flat().map((element, index) => {
6250
- return jsx("div", {
6251
- className: "element-style",
6252
- children: jsx(JsonFormsDispatch, {
6253
- "data-testid": `jsonforms-object-list-defined-elements-dispatch`,
6254
- schema: schema,
6255
- uischema: element,
6256
- enabled: enabled,
6257
- renderers: GoAReviewRenderers,
6258
- cells: cells
6259
- })
6260
- }, `form-stepper-category-${index}`);
6261
- })
6262
- })]
6263
- }, index);
6264
- })
6213
+ });
6214
+ }
6215
+ }
6216
+ stepperDispatch({
6217
+ type: 'validate/form',
6218
+ payload: {
6219
+ errors: (_c = ctx === null || ctx === void 0 ? void 0 : ctx.core) === null || _c === void 0 ? void 0 : _c.errors
6220
+ }
6221
+ });
6222
+ stepperDispatch({
6223
+ type: 'page/to/index',
6224
+ payload: {
6225
+ id
6226
+ }
6227
+ });
6228
+ },
6229
+ toggleShowReviewLink: id => {
6230
+ stepperDispatch({
6231
+ type: 'toggle/category/review-link',
6232
+ payload: {
6233
+ id
6234
+ }
6235
+ });
6236
+ }
6237
+ };
6238
+ }, [stepperDispatch, stepperState, (_a = ctx.core) === null || _a === void 0 ? void 0 : _a.errors]);
6239
+ useEffect(() => {
6240
+ if ((context === null || context === void 0 ? void 0 : context.isProvided) === true) {
6241
+ /* The block is used to cache the state for the tenant web app review editor */
6242
+ stepperDispatch({
6243
+ type: 'update/uischema',
6244
+ payload: {
6245
+ state: createStepperContextInitData(Object.assign(Object.assign({}, StepperProps), {
6246
+ activeId: stepperState === null || stepperState === void 0 ? void 0 : stepperState.activeId
6247
+ }))
6248
+ }
6249
+ });
6250
+ context.goToPage(stepperState.maxReachedStep);
6251
+ context.goToPage(stepperState.activeId);
6252
+ }
6253
+ }, [JSON.stringify(StepperProps.uischema), JSON.stringify(StepperProps.schema)]);
6254
+ return jsx(JsonFormsStepperContext.Provider, {
6255
+ value: context,
6256
+ children: children
6265
6257
  });
6266
6258
  };
6267
- const FormStepperReviewControl = withAjvProps(withTranslateProps(withJsonFormsLayoutProps(FormStepperReviewer)));
6268
6259
 
6269
6260
  const summaryLabel = 'Summary';
6270
6261
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -6494,7 +6485,6 @@ const BackButton = ({
6494
6485
  };
6495
6486
 
6496
6487
  const FormStepperPageReviewer = props => {
6497
- var _a, _b;
6498
6488
  const {
6499
6489
  uischema,
6500
6490
  data,
@@ -6504,18 +6494,35 @@ const FormStepperPageReviewer = props => {
6504
6494
  enabled,
6505
6495
  navigationFunc
6506
6496
  } = props;
6507
- (_b = (_a = uischema.options) === null || _a === void 0 ? void 0 : _a.componentProps) !== null && _b !== void 0 ? _b : {};
6508
6497
  const categorization = uischema;
6509
6498
  const categories = categorization.elements.filter(category => isVisible(category, data, '', ajv));
6510
6499
  const rescopeMaps = ['#/properties/albertaAddress', '#/properties/canadianAddress', '#/properties/sin'];
6500
+ const formStepperCtx = useContext(JsonFormsStepperContext);
6511
6501
  return jsxs(TableReviewItem, {
6512
6502
  children: [jsx("h2", {
6513
6503
  children: "Review your answers"
6514
6504
  }), categories.map((category, index) => {
6515
6505
  const categoryLabel = category.label || category.i18n || 'Unknown Category';
6516
6506
  return jsxs(Fragment, {
6517
- children: [jsx(TableReviewCategoryLabel, {
6518
- children: categoryLabel
6507
+ children: [jsx("div", {
6508
+ children: jsxs(TableReviewPageTitleRow, {
6509
+ children: [jsx(TableReviewCategoryLabel, {
6510
+ children: categoryLabel
6511
+ }), jsx("div", {
6512
+ className: "right",
6513
+ children: jsx(GoAButton, {
6514
+ type: "tertiary",
6515
+ testId: `page-review-change-${category.label}-btn`,
6516
+ onClick: () => {
6517
+ if (formStepperCtx) {
6518
+ formStepperCtx.toggleShowReviewLink(index);
6519
+ formStepperCtx.goToPage(index);
6520
+ }
6521
+ },
6522
+ children: "Change"
6523
+ })
6524
+ })]
6525
+ })
6519
6526
  }), jsx(TableReviewItemSection, {
6520
6527
  children: category.elements.filter(field => {
6521
6528
  var _a, _b;
@@ -7200,6 +7207,92 @@ $$8({ global: true, forced: parseInt !== $parseInt }, {
7200
7207
  parseInt: $parseInt
7201
7208
  });
7202
7209
 
7210
+ const ADD_DATA_ACTION = 'jsonforms/register/add_data_action';
7211
+ const SET_DATA_ACTION = 'jsonforms/register/set_data_action';
7212
+ const INCREMENT_ACTION = 'jsonforms/register/increment_action';
7213
+ const DELETE_ACTION = 'jsonforms/register/delete_action';
7214
+ const initialState = {
7215
+ categories: {}
7216
+ };
7217
+
7218
+ function objectListReducer(state, action) {
7219
+ switch (action.type) {
7220
+ case ADD_DATA_ACTION:
7221
+ {
7222
+ //ok so we're assuming we're already getting the updated category data
7223
+ const {
7224
+ categories
7225
+ } = state;
7226
+ const {
7227
+ name,
7228
+ category
7229
+ } = action.payload;
7230
+ const newCategories = Object.assign({}, categories);
7231
+ if (!newCategories[name]) {
7232
+ newCategories[name] = {
7233
+ data: category
7234
+ };
7235
+ } else {
7236
+ newCategories[name].data = category;
7237
+ }
7238
+ return Object.assign(Object.assign({}, state), {
7239
+ categories: newCategories
7240
+ });
7241
+ }
7242
+ case SET_DATA_ACTION:
7243
+ {
7244
+ const CategoriesStateData = action.payload;
7245
+ return Object.assign(Object.assign({}, state), {
7246
+ categories: CategoriesStateData
7247
+ });
7248
+ }
7249
+ case INCREMENT_ACTION:
7250
+ {
7251
+ const {
7252
+ categories
7253
+ } = state;
7254
+ const name = action.payload;
7255
+ const newCategories = Object.assign({}, categories);
7256
+ // Assuming you want to increment the count of a category:
7257
+ if (newCategories[name]) {
7258
+ const updatedCategory = Object.assign(Object.assign({}, categories[name]), {
7259
+ count: (categories[name].count || 0) + 1
7260
+ });
7261
+ return Object.assign(Object.assign({}, state), {
7262
+ categories: Object.assign(Object.assign({}, categories), {
7263
+ [name]: updatedCategory
7264
+ })
7265
+ });
7266
+ } else {
7267
+ newCategories[name] = {
7268
+ count: 1,
7269
+ data: {}
7270
+ };
7271
+ }
7272
+ return Object.assign(Object.assign({}, state), {
7273
+ categories: newCategories
7274
+ });
7275
+ }
7276
+ case DELETE_ACTION:
7277
+ {
7278
+ const {
7279
+ name,
7280
+ category
7281
+ } = action.payload;
7282
+ const {
7283
+ categories
7284
+ } = state;
7285
+ const newCategories = Object.assign({}, categories);
7286
+ newCategories[name] = category;
7287
+ return Object.assign(Object.assign({}, state), {
7288
+ categories: newCategories
7289
+ });
7290
+ }
7291
+ default:
7292
+ return state;
7293
+ }
7294
+ }
7295
+
7203
7296
  let _$2 = t => t,
7204
7297
  _t$2,
7205
7298
  _t2$2,
@@ -7215,7 +7308,11 @@ let _$2 = t => t,
7215
7308
  _t12,
7216
7309
  _t13,
7217
7310
  _t14,
7218
- _t15;
7311
+ _t15,
7312
+ _t16,
7313
+ _t17,
7314
+ _t18,
7315
+ _t19;
7219
7316
  const DeleteDialogContent = styled.div(_t$2 || (_t$2 = _$2`
7220
7317
  margin-bottom: var(--goa-space-m);
7221
7318
  `));
@@ -7283,6 +7380,31 @@ const ListContainer = styled.div(_t14 || (_t14 = _$2`
7283
7380
  const TableTHHeader = styled.th(_t15 || (_t15 = _$2`
7284
7381
  background-color: var(--goa-color-greyscale-100) !important;
7285
7382
  `));
7383
+ const ObjectArrayWarningIconDiv = styled.div(_t16 || (_t16 = _$2`
7384
+ display: inline-flex;
7385
+ align-items: flex-start;
7386
+ gap: 0.25rem;
7387
+ font-size: var(--goa-font-size-2);
7388
+ color: var(--goa-color-interactive-error);
7389
+ `));
7390
+ styled.label(_t17 || (_t17 = _$2`
7391
+ color: var(--goa-color-interactive-error);
7392
+ font-weight: var(--goa-font-weight-regular);
7393
+ font-size: var(--goa-font-size-3);
7394
+ line-height: var(--goa-line-height-1);
7395
+ font-style: normal;
7396
+ `));
7397
+ styled.div(_t18 || (_t18 = _$2`
7398
+ margin-top: var(--goa-space-m);
7399
+ color: var(--goa-color-interactive-error);
7400
+ font-weight: var(--goa-font-weight-regular);
7401
+ font-size: var(--goa-font-size-2);
7402
+ line-height: var(--goa-line-height-1);
7403
+ font-style: normal;
7404
+ `));
7405
+ const HilightCellWarning = styled.div(_t19 || (_t19 = _$2`
7406
+ background-color: var(--goa-color-warning-default);
7407
+ `));
7286
7408
 
7287
7409
  const DeleteDialog = /*#__PURE__*/React.memo(function DeleteDialog({
7288
7410
  open,
@@ -7355,116 +7477,83 @@ const ObjectArrayToolBar = /*#__PURE__*/React.memo(function TableToolbar({
7355
7477
  "aria-label": translations.addAriaLabel,
7356
7478
  onClick: addItem(path, createDefaultValue(schema, rootSchema)),
7357
7479
  type: (_c = (_b = uischema.options) === null || _b === void 0 ? void 0 : _b.addButtonType) !== null && _c !== void 0 ? _c : 'primary',
7358
- children: ((_d = uischema === null || uischema === void 0 ? void 0 : uischema.options) === null || _d === void 0 ? void 0 : _d.addButtonText) || capitalizeFirstLetter$1(`Add ${arrayLabel}`)
7480
+ children: ((_d = uischema === null || uischema === void 0 ? void 0 : uischema.options) === null || _d === void 0 ? void 0 : _d.addButtonText) || capitalizeFirstLetter(`Add ${arrayLabel}`)
7359
7481
  })
7360
7482
  })
7361
7483
  });
7362
7484
  });
7363
7485
 
7364
- const ADD_DATA_ACTION = 'jsonforms/register/add_data_action';
7365
- const SET_DATA_ACTION = 'jsonforms/register/set_data_action';
7366
- const INCREMENT_ACTION = 'jsonforms/register/increment_action';
7367
- const DELETE_ACTION = 'jsonforms/register/delete_action';
7368
- const initialState = {
7369
- categories: {}
7370
- };
7371
-
7372
- function objectListReducer(state, action) {
7373
- switch (action.type) {
7374
- case ADD_DATA_ACTION:
7375
- {
7376
- //ok so we're assuming we're already getting the updated category data
7377
- const {
7378
- categories
7379
- } = state;
7380
- const {
7381
- name,
7382
- category
7383
- } = action.payload;
7384
- const newCategories = Object.assign({}, categories);
7385
- if (!newCategories[name]) {
7386
- newCategories[name] = {
7387
- data: category
7388
- };
7389
- } else {
7390
- newCategories[name].data = category;
7391
- }
7392
- return Object.assign(Object.assign({}, state), {
7393
- categories: newCategories
7394
- });
7395
- }
7396
- case SET_DATA_ACTION:
7397
- {
7398
- const CategoriesStateData = action.payload;
7399
- return Object.assign(Object.assign({}, state), {
7400
- categories: CategoriesStateData
7401
- });
7402
- }
7403
- case INCREMENT_ACTION:
7404
- {
7405
- const {
7406
- categories
7407
- } = state;
7408
- const name = action.payload;
7409
- const newCategories = Object.assign({}, categories);
7410
- // Assuming you want to increment the count of a category:
7411
- if (newCategories[name]) {
7412
- const updatedCategory = Object.assign(Object.assign({}, categories[name]), {
7413
- count: (categories[name].count || 0) + 1
7414
- });
7415
- return Object.assign(Object.assign({}, state), {
7416
- categories: Object.assign(Object.assign({}, categories), {
7417
- [name]: updatedCategory
7418
- })
7419
- });
7420
- } else {
7421
- newCategories[name] = {
7422
- count: 1,
7423
- data: {}
7424
- };
7425
- }
7426
- return Object.assign(Object.assign({}, state), {
7427
- categories: newCategories
7428
- });
7429
- }
7430
- case DELETE_ACTION:
7431
- {
7432
- const {
7433
- name,
7434
- category
7435
- } = action.payload;
7436
- const {
7437
- categories
7438
- } = state;
7439
- const newCategories = Object.assign({}, categories);
7440
- newCategories[name] = category;
7441
- return Object.assign(Object.assign({}, state), {
7442
- categories: newCategories
7443
- });
7444
- }
7445
- default:
7446
- return state;
7447
- }
7448
- }
7449
-
7450
- function extractNames(obj, names = []) {
7486
+ /**
7487
+ * Extract Json data schema name attribute and the ui schema label name.
7488
+ * @param obj
7489
+ * @param names
7490
+ * @returns A key value of the data attribute name and the uiSchema label value
7491
+ */
7492
+ const extractNames = (obj, names = {}) => {
7451
7493
  if (Array.isArray(obj)) {
7452
7494
  obj.forEach(item => extractNames(item, names));
7453
7495
  } else if (typeof obj === 'object' && obj !== null) {
7454
7496
  const typedObj = obj;
7455
- if (typeof typedObj.label === 'string') {
7456
- names.push(typedObj.label);
7457
- } else if (typeof typedObj.scope === 'string') {
7497
+ if (typeof typedObj.scope === 'string') {
7458
7498
  const parts = typedObj.scope.split('/');
7459
- names.push(parts[parts.length - 1]);
7499
+ if (typeof typedObj.label === 'string') {
7500
+ names[parts[parts.length - 1]] = typedObj.label;
7501
+ } else if (typeof typedObj.scope === 'string') {
7502
+ const _parts = typedObj.scope.split('/');
7503
+ names[_parts[_parts.length - 1]] = _parts[_parts.length - 1];
7504
+ }
7460
7505
  }
7461
7506
  Object.values(typedObj).forEach(value => extractNames(value, names));
7462
7507
  }
7463
7508
  return names;
7464
- }
7465
- const GenerateRows$1 = (Cell, schema, rowPath, enabled, openDeleteDialog, handleChange, cells, uischema, isInReview, count, data,
7466
- // eslint-disable-next-line
7467
- errors) => {
7509
+ };
7510
+ const renderCellColumn = ({
7511
+ currentData,
7512
+ error,
7513
+ isRequired
7514
+ }) => {
7515
+ const renderWarningCell = data => {
7516
+ return jsx(HilightCellWarning, {
7517
+ children: jsxs(ObjectArrayWarningIconDiv, {
7518
+ children: [jsx(GoAIcon, {
7519
+ type: "warning",
7520
+ title: "warning",
7521
+ size: "small",
7522
+ theme: "filled",
7523
+ ml: "2xs",
7524
+ mt: "2xs"
7525
+ }), data]
7526
+ })
7527
+ });
7528
+ };
7529
+ if (currentData === undefined && isRequired || error !== '' && error !== undefined) {
7530
+ return renderWarningCell(currentData);
7531
+ } else if (currentData !== undefined && isRequired && error) {
7532
+ return renderWarningCell(currentData);
7533
+ }
7534
+ if (typeof currentData === 'string') {
7535
+ return currentData;
7536
+ } else if (typeof currentData === 'object' || Array.isArray(currentData)) {
7537
+ const result = Object.keys(currentData);
7538
+ if (result.length === 0) {
7539
+ return renderWarningCell();
7540
+ } else if (currentData !== undefined && result.length > 0 && error !== '' && error !== undefined) {
7541
+ const values = Object.values(currentData);
7542
+ if (values && values.length > 0) {
7543
+ return jsx("pre", {
7544
+ children: renderWarningCell(JSON.stringify(values.at(0), null, 2))
7545
+ });
7546
+ }
7547
+ } else {
7548
+ return jsx("pre", {
7549
+ children: JSON.stringify(currentData, null, 2)
7550
+ });
7551
+ }
7552
+ }
7553
+ return null;
7554
+ };
7555
+
7556
+ const GenerateRows$1 = (Cell, schema, rowPath, enabled, openDeleteDialog, handleChange, cells, uischema, isInReview, count, data, errors) => {
7468
7557
  if ((schema === null || schema === void 0 ? void 0 : schema.type) === 'object') {
7469
7558
  const props = {
7470
7559
  schema,
@@ -7539,12 +7628,8 @@ const ctxToNonEmptyCellProps$1 = (ctx, ownProps) => {
7539
7628
  handleChange: ownProps.handleChange
7540
7629
  };
7541
7630
  };
7542
- function capitalizeFirstLetter(str) {
7543
- if (!str) return ''; // Handle empty strings
7544
- return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase();
7545
- }
7546
7631
  const NonEmptyCellComponent$1 = /*#__PURE__*/React.memo(function NonEmptyCellComponent(props) {
7547
- var _a, _b, _c;
7632
+ var _a, _b, _c, _d;
7548
7633
  const {
7549
7634
  schema,
7550
7635
  enabled,
@@ -7562,13 +7647,26 @@ const NonEmptyCellComponent$1 = /*#__PURE__*/React.memo(function NonEmptyCellCom
7562
7647
  const properties = (schema === null || schema === void 0 ? void 0 : schema.items) && 'properties' in schema.items && schema.items.properties || {};
7563
7648
  const required = (_a = schema.items) === null || _a === void 0 ? void 0 : _a.required;
7564
7649
  let tableKeys = extractNames((_b = uischema === null || uischema === void 0 ? void 0 : uischema.options) === null || _b === void 0 ? void 0 : _b.detail);
7565
- if (tableKeys.length === 0) {
7566
- tableKeys = Object.keys(properties);
7650
+ if (Object.keys(tableKeys).length === 0) {
7651
+ Object.keys(properties).forEach(item => {
7652
+ tableKeys[item] = item;
7653
+ });
7654
+ }
7655
+ if (Object.keys(properties).length !== Object.keys(tableKeys).length) {
7656
+ const tempTableKeys = {};
7657
+ //For nested objects to display only the top level column.
7658
+ Object.keys(properties).forEach(item => {
7659
+ if (Object.keys(tableKeys).includes(item)) {
7660
+ tempTableKeys[item] = tableKeys[item];
7661
+ }
7662
+ });
7663
+ tableKeys = tempTableKeys;
7567
7664
  }
7665
+ const hasAnyErrors = Array.isArray(errors) ? ((_c = errors === null || errors === void 0 ? void 0 : errors.filter(err => {
7666
+ return err.instancePath.includes(rowPath);
7667
+ })) === null || _c === void 0 ? void 0 : _c.length) > 0 : false;
7568
7668
  return jsxs(NonEmptyCellStyle, {
7569
- children: [
7570
- // eslint-disable-next-line
7571
- (_c = uischema === null || uischema === void 0 ? void 0 : uischema.elements) === null || _c === void 0 ? void 0 : _c.map(element => {
7669
+ children: [(_d = uischema === null || uischema === void 0 ? void 0 : uischema.elements) === null || _d === void 0 ? void 0 : _d.map(element => {
7572
7670
  return jsx(JsonFormsDispatch, {
7573
7671
  "data-testid": `jsonforms-object-list-defined-elements-dispatch`,
7574
7672
  schema: schema,
@@ -7578,99 +7676,114 @@ const NonEmptyCellComponent$1 = /*#__PURE__*/React.memo(function NonEmptyCellCom
7578
7676
  renderers: isInReview ? GoAReviewRenderers : renderers,
7579
7677
  cells: cells
7580
7678
  }, rowPath);
7581
- }), Object.keys(properties).length > 0 && jsxs(GoATable, {
7582
- width: "100%",
7583
- children: [jsx("thead", {
7584
- children: jsxs("tr", {
7585
- children: [tableKeys.map((key, index) => {
7586
- if (!isInReview) {
7587
- return jsx("th", {
7679
+ }), Object.keys(properties).length > 0 && jsxs(Fragment, {
7680
+ children: [jsxs(GoATable, {
7681
+ width: "100%",
7682
+ children: [jsx("thead", {
7683
+ children: jsxs("tr", {
7684
+ children: [Object.entries(tableKeys).map(([value, index]) => {
7685
+ if (!isInReview) {
7686
+ return jsx("th", {
7687
+ children: jsxs("p", {
7688
+ children: [convertToSentenceCase(index), (required === null || required === void 0 ? void 0 : required.includes(value)) && jsx(RequiredSpan, {
7689
+ children: "(required)"
7690
+ })]
7691
+ })
7692
+ }, index);
7693
+ }
7694
+ return jsx(TableTHHeader, {
7588
7695
  children: jsxs("p", {
7589
- children: [convertToSentenceCase(key), (required === null || required === void 0 ? void 0 : required.includes(key)) && jsx(RequiredSpan, {
7590
- children: "(required)"
7696
+ children: [`${convertToSentenceCase(index)}`, (required === null || required === void 0 ? void 0 : required.includes(value)) && jsxs(RequiredSpan, {
7697
+ children: [jsx("br", {}), " (required)"]
7591
7698
  })]
7592
7699
  })
7593
7700
  }, index);
7594
- }
7595
- return jsx(TableTHHeader, {
7701
+ }), isInReview !== true && jsx("th", {
7596
7702
  children: jsx("p", {
7597
- children: convertToSentenceCase(key)
7703
+ children: "Actions"
7598
7704
  })
7599
- }, index);
7600
- }), isInReview !== true && jsx("th", {
7601
- children: jsx("p", {
7602
- children: "Actions"
7603
- })
7604
- })]
7605
- }, 0)
7606
- }), jsx("tbody", {
7607
- children: range(count || 0).map((num, i) => {
7608
- // eslint-disable-next-line
7609
- const errorRow = errors === null || errors === void 0 ? void 0 : errors.find(error => error.instancePath.includes(`/${props.rowPath.replace(/\./g, '/')}/${i}`));
7610
- return jsxs("tr", {
7611
- children: [Object.keys(properties).map((element, ix) => {
7612
- var _a;
7613
- const dataObject = properties[element];
7614
- const schemaName = element;
7615
- const currentData = data && data[num] ? data[num][element] : '';
7616
- const error = errors === null || errors === void 0 ? void 0 : errors.find(
7617
- // eslint-disable-next-line
7618
- e => e.instancePath === `/${props.rowPath.replace(/\./g, '/')}/${i}/${element}`);
7619
- if ((error === null || error === void 0 ? void 0 : error.message.includes('must NOT have fewer')) && required.find(r => r === schemaName) && (isEmptyBoolean(schema, currentData) || isEmptyNumber(schema, currentData))) {
7620
- error.message = `${capitalizeFirstLetter(schemaName)} is required`;
7621
- }
7622
- return jsx("td", {
7623
- children: isInReview ? jsx("div", {
7624
- "data-testid": `#/properties/${schemaName}-input-${i}-review`,
7625
- children: typeof currentData === 'string' ? currentData : jsx("pre", {
7626
- children: JSON.stringify(currentData, null, 2)
7705
+ })]
7706
+ }, 0)
7707
+ }), jsx("tbody", {
7708
+ children: range(count || 0).map((num, i) => {
7709
+ const errorRow = errors === null || errors === void 0 ? void 0 : errors.find(error => error.instancePath.includes(`/${props.rowPath.replace(/\./g, '/')}/${i}`));
7710
+ return jsxs("tr", {
7711
+ children: [Object.keys(properties).map((element, ix) => {
7712
+ var _a;
7713
+ const dataObject = properties[element];
7714
+ const schemaName = element;
7715
+ const currentData = data && data[num] ? data[num][element] : '';
7716
+ //Get out of the loop to not render extra blank columns at the end of the table
7717
+ if (ix > 1 && Object.keys(tableKeys).length === ix) return null;
7718
+ const error = (errors === null || errors === void 0 ? void 0 : errors.filter(e => e.instancePath === `/${props.rowPath.replace(/\./g, '/')}/${i}/${element}` || e.instancePath === `/${props.rowPath.replace(/\./g, '/')}/${i}`)).find(y => {
7719
+ var _a;
7720
+ return ((_a = y === null || y === void 0 ? void 0 : y.message) === null || _a === void 0 ? void 0 : _a.includes(element)) || y.instancePath.includes(element);
7721
+ });
7722
+ if ((error === null || error === void 0 ? void 0 : error.message.includes('must NOT have fewer')) && required.find(r => r === schemaName) && (isEmptyBoolean(schema, currentData) || isEmptyNumber(schema, currentData))) {
7723
+ error.message = `${capitalizeFirstLetter(schemaName)} is required`;
7724
+ }
7725
+ if (isInReview === true) {
7726
+ return jsx("td", {
7727
+ children: jsx("div", {
7728
+ "data-testid": `#/properties/${schemaName}-input-${i}-review`,
7729
+ children: renderCellColumn({
7730
+ currentData,
7731
+ error: error === null || error === void 0 ? void 0 : error.message,
7732
+ isRequired: required === null || required === void 0 ? void 0 : required.includes(tableKeys[element])
7733
+ })
7734
+ })
7735
+ }, ix);
7736
+ }
7737
+ return jsx("td", {
7738
+ children: jsx(GoAFormItem, {
7739
+ error: (_a = error === null || error === void 0 ? void 0 : error.message) !== null && _a !== void 0 ? _a : '',
7740
+ mb: errorRow && !error && '2xl' || 'xs',
7741
+ children: dataObject.type === 'number' || dataObject.type === 'string' && !dataObject.enum ? jsx(GoAInput, {
7742
+ error: (error === null || error === void 0 ? void 0 : error.message.length) > 0,
7743
+ type: dataObject.type === 'number' ? 'number' : 'text',
7744
+ id: schemaName,
7745
+ name: schemaName,
7746
+ value: currentData,
7747
+ testId: `#/properties/${schemaName}-input-${i}`,
7748
+ onChange: (name, value) => {
7749
+ handleChange(rowPath, {
7750
+ [num]: {
7751
+ [name]: dataObject.type === 'number' ? parseInt(value) : value
7752
+ }
7753
+ });
7754
+ },
7755
+ "aria-label": schemaName,
7756
+ width: "100%"
7757
+ }) : jsx(GoACallout, {
7758
+ type: "important",
7759
+ size: "medium",
7760
+ testId: "form-support-callout",
7761
+ heading: "Not supported",
7762
+ children: "Only string and number are supported inside arrays"
7763
+ })
7627
7764
  })
7628
- }) : jsx(GoAFormItem, {
7629
- error: (_a = error === null || error === void 0 ? void 0 : error.message) !== null && _a !== void 0 ? _a : '',
7630
- mb: errorRow && !error && '2xl' || 'xs',
7631
- children: dataObject.type === 'number' || dataObject.type === 'string' && !dataObject.enum ? jsx(GoAInput, {
7632
- error: (error === null || error === void 0 ? void 0 : error.message.length) > 0,
7633
- type: dataObject.type === 'number' ? 'number' : 'text',
7634
- id: schemaName,
7635
- name: schemaName,
7636
- value: currentData,
7637
- testId: `#/properties/${schemaName}-input-${i}`,
7638
- onChange: (name, value) => {
7639
- handleChange(rowPath, {
7640
- [num]: {
7641
- [name]: dataObject.type === 'number' ? parseInt(value) : value
7642
- }
7643
- });
7644
- },
7645
- "aria-label": schemaName,
7646
- width: "100%"
7647
- }) : jsx(GoACallout, {
7648
- type: "important",
7649
- size: "medium",
7650
- testId: "form-support-callout",
7651
- heading: "Not supported",
7652
- children: "Only string and number are supported inside arrays"
7765
+ }, ix);
7766
+ }), !isInReview && jsx("td", {
7767
+ style: {
7768
+ alignContent: 'baseLine',
7769
+ paddingTop: '18px'
7770
+ },
7771
+ children: jsx("div", {
7772
+ "aria-hidden": "true",
7773
+ children: jsx(GoAIconButton, {
7774
+ icon: "trash",
7775
+ title: "trash button",
7776
+ testId: "trash-icon-button",
7777
+ "aria-label": `remove-element-${num}`,
7778
+ onClick: () => openDeleteDialog(num)
7653
7779
  })
7654
7780
  })
7655
- }, ix);
7656
- }), jsx("td", {
7657
- style: {
7658
- alignContent: 'baseLine',
7659
- paddingTop: '18px'
7660
- },
7661
- children: jsx("div", {
7662
- "aria-hidden": "true",
7663
- children: !isInReview && jsx(GoAIconButton, {
7664
- icon: "trash",
7665
- title: "trash button",
7666
- testId: "trash-icon-button",
7667
- "aria-label": `remove-element-${num}`,
7668
- onClick: () => openDeleteDialog(num)
7669
- })
7670
- })
7671
- })]
7672
- }, i);
7673
- })
7781
+ })]
7782
+ }, `${i}-${num}`);
7783
+ })
7784
+ })]
7785
+ }), hasAnyErrors && isInReview && jsx(GoAFormItem, {
7786
+ error: `There are validation errors for '${capitalizeFirstLetter(rowPath)}'`
7674
7787
  })]
7675
7788
  })]
7676
7789
  });
@@ -7754,7 +7867,6 @@ const ObjectArrayList$1 = ({
7754
7867
  data: data
7755
7868
  }, 0);
7756
7869
  };
7757
- // eslint-disable-next-line
7758
7870
  const ObjectArrayControl = props => {
7759
7871
  var _a, _b, _c;
7760
7872
  const [registers, dispatch] = useReducer(objectListReducer, initialState);
@@ -7860,8 +7972,7 @@ const ObjectArrayControl = props => {
7860
7972
  }
7861
7973
  };
7862
7974
  useEffect(() => {
7863
- // eslint-disable-next-line
7864
- const updatedData = Array.isArray(parsedData) ? Object.fromEntries(parsedData.map((item, index) => [index, item])) : {};
7975
+ const updatedData = Object.fromEntries((parsedData || []).map((item, index) => [index, item]));
7865
7976
  const count = Object.keys(updatedData).length;
7866
7977
  const dispatchData = {
7867
7978
  [path]: {
@@ -7875,9 +7986,9 @@ const ObjectArrayControl = props => {
7875
7986
  payload: dispatchData
7876
7987
  });
7877
7988
  }
7989
+ // eslint-disable-next-line
7878
7990
  }, []);
7879
7991
  const controlElement = uischema;
7880
- // eslint-disable-next-line
7881
7992
  const listTitle = label || ((_a = uischema.options) === null || _a === void 0 ? void 0 : _a.title);
7882
7993
  const isInReview = isStepperReview === true;
7883
7994
  return jsxs(Visible, {
@@ -9321,29 +9432,17 @@ const AddressLoopUpControlTableReview = props => {
9321
9432
  schema,
9322
9433
  uischema
9323
9434
  } = props;
9324
- const categoryIndex = (_a = uischema.options) === null || _a === void 0 ? void 0 : _a.categoryIndex;
9325
- const formStepperCtx = useContext(JsonFormsStepperContext);
9435
+ (_a = uischema.options) === null || _a === void 0 ? void 0 : _a.categoryIndex;
9436
+ useContext(JsonFormsStepperContext);
9326
9437
  const isAlbertaAddress = ((_c = (_b = schema === null || schema === void 0 ? void 0 : schema.properties) === null || _b === void 0 ? void 0 : _b.subdivisionCode) === null || _c === void 0 ? void 0 : _c.const) === 'AB';
9327
9438
  return jsxs(Fragment, {
9328
- children: [jsxs("tr", {
9439
+ children: [jsx("tr", {
9329
9440
  "data-testid": "address-lookup-table-review",
9330
- children: [jsx(PageReviewNameCol, {
9441
+ children: jsx(PageReviewNameCol, {
9331
9442
  children: jsx("strong", {
9332
9443
  children: `${isAlbertaAddress ? 'Alberta' : 'Canada'} postal address`
9333
9444
  })
9334
- }), jsx(PageReviewValueCol, {}), jsx(PageReviewActionCol, {
9335
- children: jsx(GoAButton, {
9336
- type: "tertiary",
9337
- testId: `page-review-change-address-btn`,
9338
- onClick: () => {
9339
- if (formStepperCtx) {
9340
- formStepperCtx.toggleShowReviewLink(categoryIndex);
9341
- formStepperCtx.goToPage(categoryIndex);
9342
- }
9343
- },
9344
- children: "Change"
9345
- })
9346
- })]
9445
+ })
9347
9446
  }), jsx("tr", {
9348
9447
  children: jsx("td", {
9349
9448
  colSpan: 3,