@abgov/jsonforms-components 2.0.0 → 2.1.0

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';
@@ -3803,8 +3803,7 @@ let _$a = t => t,
3803
3803
  _t3$5,
3804
3804
  _t4$5,
3805
3805
  _t5$3,
3806
- _t6$3,
3807
- _t7$2;
3806
+ _t6$3;
3808
3807
  const FormFieldWrapper = styled.div(_t$a || (_t$a = _$a`
3809
3808
  margin-bottom: var(--goa-space-l);
3810
3809
  `));
@@ -3823,7 +3822,7 @@ const RequiredTextLabel = styled.label(_t3$5 || (_t3$5 = _$a`
3823
3822
  font-style: normal;
3824
3823
  `));
3825
3824
  const PageReviewNameCol = styled.td(_t4$5 || (_t4$5 = _$a`
3826
- width: 70%;
3825
+ width: 80%;
3827
3826
  padding-top: var(--goa-space-s);
3828
3827
  padding-bottom: var(--goa-space-s);
3829
3828
  padding-right: var(--goa-space-m);
@@ -3832,11 +3831,8 @@ const PageReviewValueCol = styled.td(_t5$3 || (_t5$3 = _$a`
3832
3831
  width: 20%;
3833
3832
  text-align: left;
3834
3833
  `));
3835
- const PageReviewActionCol = styled.td(_t6$3 || (_t6$3 = _$a`
3836
- width: 10%;
3837
- `));
3838
3834
  //Check and unchecked are different heights otherwise
3839
- const CheckboxWrapper = styled.div(_t7$2 || (_t7$2 = _$a`
3835
+ const CheckboxWrapper = styled.div(_t6$3 || (_t6$3 = _$a`
3840
3836
  height: 28px;
3841
3837
  `));
3842
3838
 
@@ -5297,470 +5293,128 @@ const GoInputBaseReview = props => jsx(GoAInputBaseControl, Object.assign({}, pr
5297
5293
  }));
5298
5294
  const GoInputBaseReviewControl = withJsonFormsControlProps(GoInputBaseReview);
5299
5295
 
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
- }
5296
+ const GoAInputBaseTableReview = props => {
5297
+ var _a, _b, _c;
5298
+ const {
5299
+ data,
5300
+ uischema,
5301
+ label
5302
+ } = props;
5303
+ const labelToUpdate = convertToSentenceCase(getLabelText(uischema.scope, label || ''));
5304
+ let reviewText = data;
5305
+ const isBoolean = typeof data === 'boolean';
5306
+ if (isBoolean) {
5307
+ 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));
5308
+ if (((_c = uischema.options) === null || _c === void 0 ? void 0 : _c.radio) === true) {
5309
+ reviewText = data ? `Yes` : `No`;
5310
+ } else {
5311
+ if (label !== '' || typeof label === 'boolean') {
5312
+ reviewText = data ? `Yes` : `No`;
5323
5313
  } else {
5324
- values = [...values, ...pickPropertyValues(obj[key], property, endWithType)];
5314
+ reviewText = data ? `Yes (${checkboxLabel.trim()})` : `No (${checkboxLabel.trim()})`;
5325
5315
  }
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
5316
  }
5317
+ }
5318
+ return jsxs("tr", {
5319
+ "data-testid": `input-base-table-${label}-row`,
5320
+ children: [jsx(PageReviewNameCol, {
5321
+ children: jsx("strong", {
5322
+ children: labelToUpdate
5323
+ })
5324
+ }), jsx(PageReviewValueCol, {
5325
+ children: reviewText
5326
+ })]
5332
5327
  });
5333
- return values;
5334
5328
  };
5329
+ const GoAInputBaseTableReviewControl = withJsonFormsControlProps(GoAInputBaseTableReview);
5335
5330
 
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
- });
5331
+ let _$7 = t => t,
5332
+ _t$7;
5333
+ const renderLayoutElements = (elements, schema, path, enabled, renderers, cells) => {
5334
+ return elements.map((child, index) => jsx("div", {
5335
+ children: jsx(JsonFormsDispatch, {
5336
+ uischema: child,
5337
+ schema: schema,
5338
+ path: path,
5339
+ enabled: enabled,
5340
+ renderers: renderers,
5341
+ cells: cells
5342
+ }, path)
5343
+ }, index));
5345
5344
  };
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);
5345
+ const withAjvProps = Component => function WithAjvProps(props) {
5346
+ const ctx = useJsonForms();
5347
+ const ajv = getAjv({
5348
+ jsonforms: Object.assign({}, ctx)
5353
5349
  });
5354
- const _scopes = scopes.map(scope => toDataPath(scope)).filter(path => requiredErrorPaths && isErrorPathIncluded(requiredErrorPaths, path));
5355
- return _scopes;
5350
+ return jsx(Component, Object.assign({}, props, {
5351
+ ajv: ajv
5352
+ }));
5356
5353
  };
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);
5354
+ const LayoutRenderer = ({
5355
+ elements,
5356
+ schema,
5357
+ path,
5358
+ enabled,
5359
+ direction,
5360
+ renderers,
5361
+ cells,
5362
+ visible,
5363
+ width
5364
+ }) => {
5365
+ if (isEmpty(elements)) {
5366
+ return null;
5367
+ } else {
5368
+ if (direction === 'row') {
5369
+ return jsx(Visible, {
5370
+ visible: visible,
5371
+ children: jsx(GoAGrid, {
5372
+ minChildWidth: width || '10ch',
5373
+ children: renderLayoutElements(elements, schema, path, enabled, renderers, cells)
5374
+ })
5375
+ });
5376
+ } else {
5377
+ return jsx(Visible, {
5378
+ visible: visible,
5379
+ children: renderLayoutElements(elements, schema, path, enabled, renderers, cells)
5380
+ });
5381
+ }
5373
5382
  }
5374
- return false;
5375
5383
  };
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
- });
5384
+ const ReviewLayoutRenderer = ({
5385
+ elements,
5386
+ schema,
5387
+ path,
5388
+ enabled,
5389
+ direction,
5390
+ renderers,
5391
+ cells,
5392
+ visible,
5393
+ width
5394
+ }) => {
5395
+ if (isEmpty(elements)) {
5396
+ return null;
5397
+ } else {
5398
+ if (direction === 'row') {
5399
+ return jsx(Visible, {
5400
+ visible: visible,
5401
+ children: jsx(ReviewGrid, {
5402
+ children: renderLayoutElements(elements, schema, path, enabled, renderers, cells)
5403
+ })
5404
+ });
5405
+ } else {
5406
+ return jsx(Visible, {
5407
+ visible: visible,
5408
+ children: renderLayoutElements(elements, schema, path, enabled, renderers, cells)
5409
+ });
5410
+ }
5411
+ }
5382
5412
  };
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
- `));
5413
+ const ReviewGrid = styled.div(_t$7 || (_t$7 = _$7`
5414
+ display: grid;
5415
+ grid-template-columns: repeat(auto-fit, minmax(250px, calc(50% - 8px)));
5416
+ gap: 16px;
5417
+ `));
5764
5418
 
5765
5419
  let _$6 = t => t,
5766
5420
  _t$6,
@@ -5778,7 +5432,8 @@ let _$6 = t => t,
5778
5432
  _t13$1,
5779
5433
  _t14$1,
5780
5434
  _t15$1,
5781
- _t16;
5435
+ _t16,
5436
+ _t17;
5782
5437
  const ReviewItem = styled.div(_t$6 || (_t$6 = _$6`
5783
5438
  display: flex;
5784
5439
  flex-direction: column;
@@ -5869,7 +5524,14 @@ const TableReviewItem = styled.div(_t15$1 || (_t15$1 = _$6`
5869
5524
  border-radius: 5px;
5870
5525
  padding: var(--goa-space-2xl);
5871
5526
  `));
5872
- const TableReviewCategoryLabel = styled.h3(_t16 || (_t16 = _$6`
5527
+ const TableReviewPageTitleRow = styled.div(_t16 || (_t16 = _$6`
5528
+ margin-top: var(--goa-space-xl);
5529
+ display: flex;
5530
+ .right {
5531
+ margin-left: auto;
5532
+ }
5533
+ `));
5534
+ const TableReviewCategoryLabel = styled.h3(_t17 || (_t17 = _$6`
5873
5535
  color: var(--goa-color-text-secondary) !important;
5874
5536
  `));
5875
5537
 
@@ -6170,101 +5832,429 @@ $$a({ target: 'Array', proto: true }, {
6170
5832
  A.length = flattenIntoArray(A, O, O, sourceLen, 0, depthArg === undefined ? 1 : toIntegerOrInfinity(depthArg));
6171
5833
  return A;
6172
5834
  }
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');
5835
+ });
5836
+
5837
+ // this method was added to unscopables after implementation
5838
+ // in popular engines, so it's moved to a separate module
5839
+ var addToUnscopables = addToUnscopables$4;
5840
+
5841
+ // https://tc39.es/ecma262/#sec-array.prototype-@@unscopables
5842
+ addToUnscopables('flat');
5843
+
5844
+ // eslint-disable-next-line
5845
+ const getProperty = (obj, propName) => {
5846
+ if (obj[propName] !== undefined) return obj[propName];
5847
+ for (const key in obj) {
5848
+ if (typeof obj[key] === 'object' && obj[key] !== null) {
5849
+ const result = getProperty(obj[key], propName);
5850
+ if (result !== undefined) return result;
5851
+ }
5852
+ }
5853
+ };
5854
+ // eslint-disable-next-line
5855
+ const pickPropertyValues = (obj, property, endWithType) => {
5856
+ let values = [];
5857
+ Object.keys(obj).forEach(function (key) {
5858
+ var _a;
5859
+ if (key === property) {
5860
+ values.push(obj[key]);
5861
+ } else if (_$c.isObject(obj[key])) {
5862
+ // if the object type is equal to end type, we are not going to continue the recursive approach
5863
+ if (endWithType && ((_a = obj[key]) === null || _a === void 0 ? void 0 : _a.type) === endWithType) {
5864
+ if (property in obj[key]) {
5865
+ values.push(obj[key][property]);
5866
+ }
5867
+ } else {
5868
+ values = [...values, ...pickPropertyValues(obj[key], property, endWithType)];
5869
+ }
5870
+ } else if (_$c.isArray(obj[key])) {
5871
+ const nextValues = obj[key].map(function (arrayObj) {
5872
+ return pickPropertyValues(arrayObj, property, endWithType);
5873
+ });
5874
+ values = [...values, ...nextValues];
5875
+ }
5876
+ });
5877
+ return values;
5878
+ };
5879
+
5880
+ const FormStepperReviewer = props => {
5881
+ var _a, _b, _c;
5882
+ const {
5883
+ uischema,
5884
+ data,
5885
+ schema,
5886
+ ajv,
5887
+ cells,
5888
+ enabled,
5889
+ navigationFunc
5890
+ } = props;
5891
+ const componentProps = (_b = (_a = uischema.options) === null || _a === void 0 ? void 0 : _a.componentProps) !== null && _b !== void 0 ? _b : {};
5892
+ const readOnly = (_c = componentProps === null || componentProps === void 0 ? void 0 : componentProps.readOnly) !== null && _c !== void 0 ? _c : false;
5893
+ const categorization = uischema;
5894
+ const categories = categorization.elements.filter(category => isVisible(category, data, '', ajv));
5895
+ const rescopeMaps = ['#/properties/albertaAddress', '#/properties/canadianAddress', '#/properties/sin'];
5896
+ return jsx(ReviewItem, {
5897
+ children: categories.map((category, index) => {
5898
+ const categoryLabel = category.label || category.i18n || 'Unknown Category';
5899
+ const testId = `${categoryLabel}-review-link`;
5900
+ return jsxs(ReviewItemSection, {
5901
+ children: [jsxs(ReviewItemHeader, {
5902
+ children: [jsx(ReviewItemTitle, {
5903
+ children: categoryLabel
5904
+ }), navigationFunc && jsx(Anchor, {
5905
+ onClick: () => {
5906
+ navigationFunc(index);
5907
+ },
5908
+ "data-testid": testId,
5909
+ onKeyDown: e => {
5910
+ if (!readOnly && (e.key === ' ' || e.key === 'Enter')) {
5911
+ e.preventDefault();
5912
+ navigationFunc(index);
5913
+ }
5914
+ },
5915
+ children: readOnly ? 'View' : 'Edit'
5916
+ })]
5917
+ }), jsx(GoAGrid, {
5918
+ minChildWidth: "100%",
5919
+ children: category.elements.filter(field => {
5920
+ var _a, _b;
5921
+ // [TODO] we need to double check why we cannot hide the elements at the element level
5922
+ const conditionProps = (_a = field.rule) === null || _a === void 0 ? void 0 : _a.condition;
5923
+ /* istanbul ignore next */
5924
+ if (conditionProps && data) {
5925
+ const canHideControlParts = (_b = conditionProps === null || conditionProps === void 0 ? void 0 : conditionProps.scope) === null || _b === void 0 ? void 0 : _b.split('/');
5926
+ const canHideControl = canHideControlParts && canHideControlParts[(canHideControlParts === null || canHideControlParts === void 0 ? void 0 : canHideControlParts.length) - 1];
5927
+ const isHidden = getProperty(data, canHideControl);
5928
+ if (!isHidden) {
5929
+ return field;
5930
+ }
5931
+ } else {
5932
+ return field;
5933
+ }
5934
+ }).map(e => {
5935
+ const layout = e;
5936
+ if (rescopeMaps.some(scope => {
5937
+ var _a;
5938
+ return (_a = layout.elements) === null || _a === void 0 ? void 0 : _a.map(el => {
5939
+ const element = el;
5940
+ return element.scope;
5941
+ }).includes(scope);
5942
+ })) {
5943
+ return layout.elements;
5944
+ } else {
5945
+ return e;
5946
+ }
5947
+ }).flat().map((element, index) => {
5948
+ return jsx("div", {
5949
+ className: "element-style",
5950
+ children: jsx(JsonFormsDispatch, {
5951
+ "data-testid": `jsonforms-object-list-defined-elements-dispatch`,
5952
+ schema: schema,
5953
+ uischema: element,
5954
+ enabled: enabled,
5955
+ renderers: GoAReviewRenderers,
5956
+ cells: cells
5957
+ })
5958
+ }, `form-stepper-category-${index}`);
5959
+ })
5960
+ })]
5961
+ }, index);
5962
+ })
5963
+ });
5964
+ };
5965
+ const FormStepperReviewControl = withAjvProps(withTranslateProps(withJsonFormsLayoutProps(FormStepperReviewer)));
5966
+
5967
+ const isErrorPathIncluded = (errorPaths, path) => {
5968
+ return errorPaths.some(ePath => {
5969
+ /**
5970
+ * case A: errorPaths: [name] path: [name]
5971
+ *
5972
+ * case B: errorPath: [name] path: [name.firstName]
5973
+ * */
5974
+ return ePath === path || path.startsWith(ePath + '.');
5975
+ });
5976
+ };
5977
+ function isNumber(value) {
5978
+ return value != null && value !== '' && !isNaN(Number(value.toString()));
5979
+ }
5980
+ const getIncompletePaths = (ajv, scopes) => {
5981
+ var _a;
5982
+ 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 => {
5983
+ return getControlPath(e);
5984
+ });
5985
+ const _scopes = scopes.map(scope => toDataPath(scope)).filter(path => requiredErrorPaths && isErrorPathIncluded(requiredErrorPaths, path));
5986
+ return _scopes;
5987
+ };
5988
+ const subErrorInParent = (error, paths) => {
5989
+ /*
5990
+ Detect is there sub error in an object array.
5991
+ For example: error with instance path /roadmap/0/when belongs to /roadmap
5992
+ */
5993
+ const errorPaths = error.instancePath.split('/');
5994
+ if (errorPaths.length < 2) return false;
5995
+ // For case /roadmap/0
5996
+ if (errorPaths.length > 1 && isNumber(errorPaths[errorPaths.length - 1])) {
5997
+ const parentPath = errorPaths.slice(0, errorPaths.length - 1).join('/');
5998
+ return paths.includes(parentPath);
5999
+ }
6000
+ // For case /roadmap/0/when
6001
+ if (errorPaths.length > 2 && isNumber(errorPaths[errorPaths.length - 2])) {
6002
+ const parentPath = errorPaths.slice(0, errorPaths.length - 2).join('/');
6003
+ return paths.includes(parentPath);
6004
+ }
6005
+ return false;
6006
+ };
6007
+ const getErrorsInScopes = (errors, scopes) => {
6008
+ return errors.filter(e => {
6009
+ // transfer scope #properties/value to data path /value
6010
+ const dataPaths = scopes.map(s => '/' + toDataPath(s));
6011
+ return dataPaths.includes(e.instancePath) || subErrorInParent(e, dataPaths);
6012
+ });
6013
+ };
6014
+
6015
+ const stepperReducer = (state, action) => {
6016
+ var _a, _b;
6017
+ const {
6018
+ activeId,
6019
+ categories
6020
+ } = state;
6021
+ const lastId = categories[categories.length - 1].id;
6022
+ switch (action.type) {
6023
+ case 'update/uischema':
6024
+ {
6025
+ return Object.assign({}, action.payload.state);
6026
+ }
6027
+ case 'page/next':
6028
+ {
6029
+ state.activeId += 1;
6030
+ if (activeId === lastId) {
6031
+ state.isOnReview = true;
6032
+ state.hasNextButton = false;
6033
+ state.hasPrevButton = false;
6034
+ } else {
6035
+ state.hasNextButton = true;
6036
+ state.hasPrevButton = true;
6037
+ state.isOnReview = false;
6038
+ }
6039
+ state.categories[activeId].isVisited = true;
6040
+ return Object.assign({}, state);
6041
+ }
6042
+ case 'page/prev':
6043
+ {
6044
+ state.categories[activeId].isVisited = true;
6045
+ if (activeId > 0) {
6046
+ state.activeId -= 1;
6047
+ state.hasPrevButton = state.activeId !== 0;
6048
+ state.hasNextButton = true;
6049
+ state.isOnReview = false;
6050
+ }
6051
+ return Object.assign({}, state);
6052
+ }
6053
+ case 'page/to/index':
6054
+ {
6055
+ const {
6056
+ id
6057
+ } = action.payload;
6058
+ state.activeId = id;
6059
+ if (id > lastId) {
6060
+ state.isOnReview = true;
6061
+ state.hasNextButton = false;
6062
+ state.hasPrevButton = true;
6063
+ return Object.assign({}, state);
6064
+ } else {
6065
+ state.categories[id].isVisited = true;
6066
+ state.hasNextButton = id <= lastId;
6067
+ state.hasPrevButton = id !== 0;
6068
+ state.isOnReview = false;
6069
+ state.maxReachedStep = Math.max(state.maxReachedStep, activeId);
6070
+ return Object.assign({}, state);
6071
+ }
6072
+ }
6073
+ case 'update/category':
6074
+ {
6075
+ const {
6076
+ id,
6077
+ ajv,
6078
+ errors
6079
+ } = action.payload;
6080
+ if (id === state.categories.length) {
6081
+ return Object.assign({}, state);
6082
+ }
6083
+ /*
6084
+ 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.
6085
+ */
6086
+ const incompletePaths = getIncompletePaths(ajv, ((_a = state.categories[id]) === null || _a === void 0 ? void 0 : _a.scopes) || []);
6087
+ const errorsInCategory = getErrorsInScopes(errors, ((_b = state.categories[id]) === null || _b === void 0 ? void 0 : _b.scopes) || []);
6088
+ state.categories[id].isCompleted = (incompletePaths === null || incompletePaths === void 0 ? void 0 : incompletePaths.length) === 0;
6089
+ state.categories[id].isValid = errorsInCategory.length === 0;
6090
+ state.categories[id].isVisited = true;
6091
+ return Object.assign({}, state);
6092
+ }
6093
+ case 'validate/form':
6094
+ {
6095
+ const {
6096
+ errors
6097
+ } = action.payload;
6098
+ state.isValid = errors.length === 0;
6099
+ return Object.assign({}, state);
6100
+ }
6101
+ case 'toggle/category/review-link':
6102
+ {
6103
+ const {
6104
+ id
6105
+ } = action.payload;
6106
+ state.categories[id].showReviewPageLink = !state.categories[id].showReviewPageLink;
6107
+ return Object.assign({}, state);
6108
+ }
6109
+ default:
6110
+ return state;
6111
+ }
6112
+ };
6181
6113
 
6182
- const FormStepperReviewer = props => {
6183
- var _a, _b, _c;
6114
+ const createStepperContextInitData = props => {
6115
+ var _a;
6184
6116
  const {
6185
6117
  uischema,
6186
6118
  data,
6187
6119
  schema,
6188
6120
  ajv,
6189
- cells,
6190
- enabled,
6191
- navigationFunc
6121
+ t,
6122
+ visible,
6123
+ path
6192
6124
  } = 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
6125
  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;
6126
+ const valid = ajv.validate(schema, data || {});
6127
+ const categories = (_a = categorization.elements) === null || _a === void 0 ? void 0 : _a.map((c, id) => {
6128
+ const scopes = pickPropertyValues(c, 'scope', 'ListWithDetail');
6129
+ const incompletePaths = getIncompletePaths(ajv, scopes);
6130
+ return {
6131
+ id,
6132
+ label: deriveLabelForUISchemaElement(c, t),
6133
+ scopes,
6134
+ isVisited: false,
6135
+ isCompleted: (incompletePaths === null || incompletePaths === void 0 ? void 0 : incompletePaths.length) === 0,
6136
+ isValid: (incompletePaths === null || incompletePaths === void 0 ? void 0 : incompletePaths.length) === 0,
6137
+ uischema: c,
6138
+ showReviewPageLink: props.withBackReviewBtn || false,
6139
+ isEnabled: isEnabled(c, data, '', ajv),
6140
+ visible
6141
+ };
6142
+ });
6143
+ const activeId = (props === null || props === void 0 ? void 0 : props.activeId) || 0;
6144
+ return {
6145
+ categories: categories,
6146
+ activeId,
6147
+ hasNextButton: activeId !== (categories === null || categories === void 0 ? void 0 : categories.length),
6148
+ hasPrevButton: activeId > 0 && activeId !== (categories === null || categories === void 0 ? void 0 : categories.length),
6149
+ path,
6150
+ isOnReview: activeId === (categories === null || categories === void 0 ? void 0 : categories.length),
6151
+ isValid: valid === true,
6152
+ maxReachedStep: 0
6153
+ };
6154
+ };
6155
+ const JsonFormsStepperContext = /*#__PURE__*/createContext(undefined);
6156
+ const JsonFormsStepperContextProvider = ({
6157
+ children,
6158
+ StepperProps
6159
+ }) => {
6160
+ var _a;
6161
+ const ctx = useJsonForms();
6162
+ const {
6163
+ schema,
6164
+ ajv
6165
+ } = StepperProps;
6166
+ const [stepperState, dispatch] = useReducer(stepperReducer, createStepperContextInitData(StepperProps));
6167
+ const stepperDispatch = (StepperProps === null || StepperProps === void 0 ? void 0 : StepperProps.customDispatch) || dispatch;
6168
+ const context = useMemo(() => {
6169
+ return {
6170
+ isProvided: true,
6171
+ stepperDispatch,
6172
+ selectStepperState: () => {
6173
+ return stepperState;
6174
+ },
6175
+ selectIsDisabled: () => {
6176
+ var _a;
6177
+ const category = (_a = stepperState.categories) === null || _a === void 0 ? void 0 : _a[stepperState.activeId];
6178
+ return category === undefined ? false : !(category === null || category === void 0 ? void 0 : category.isEnabled);
6179
+ },
6180
+ selectIsActive: id => {
6181
+ return id === stepperState.activeId;
6182
+ },
6183
+ selectPath: () => {
6184
+ return stepperState.path;
6185
+ },
6186
+ selectCategory: id => {
6187
+ return stepperState.categories[id];
6188
+ },
6189
+ validatePage: id => {
6190
+ var _a;
6191
+ stepperDispatch({
6192
+ type: 'update/category',
6193
+ payload: {
6194
+ errors: (_a = ctx === null || ctx === void 0 ? void 0 : ctx.core) === null || _a === void 0 ? void 0 : _a.errors,
6195
+ id,
6196
+ ajv
6197
+ }
6198
+ });
6199
+ },
6200
+ goToPage: (id, updateCategoryId) => {
6201
+ var _a, _b, _c;
6202
+ ajv.validate(schema, ((_a = ctx.core) === null || _a === void 0 ? void 0 : _a.data) || {});
6203
+ if (stepperState.isOnReview !== true) {
6204
+ for (let i = 0; i < id; i++) {
6205
+ stepperDispatch({
6206
+ type: 'update/category',
6207
+ payload: {
6208
+ errors: (_b = ctx === null || ctx === void 0 ? void 0 : ctx.core) === null || _b === void 0 ? void 0 : _b.errors,
6209
+ id: i,
6210
+ ajv
6232
6211
  }
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
- })
6212
+ });
6213
+ }
6214
+ }
6215
+ stepperDispatch({
6216
+ type: 'validate/form',
6217
+ payload: {
6218
+ errors: (_c = ctx === null || ctx === void 0 ? void 0 : ctx.core) === null || _c === void 0 ? void 0 : _c.errors
6219
+ }
6220
+ });
6221
+ stepperDispatch({
6222
+ type: 'page/to/index',
6223
+ payload: {
6224
+ id
6225
+ }
6226
+ });
6227
+ },
6228
+ toggleShowReviewLink: id => {
6229
+ stepperDispatch({
6230
+ type: 'toggle/category/review-link',
6231
+ payload: {
6232
+ id
6233
+ }
6234
+ });
6235
+ }
6236
+ };
6237
+ }, [stepperDispatch, stepperState, (_a = ctx.core) === null || _a === void 0 ? void 0 : _a.errors]);
6238
+ useEffect(() => {
6239
+ if ((context === null || context === void 0 ? void 0 : context.isProvided) === true) {
6240
+ /* The block is used to cache the state for the tenant web app review editor */
6241
+ stepperDispatch({
6242
+ type: 'update/uischema',
6243
+ payload: {
6244
+ state: createStepperContextInitData(Object.assign(Object.assign({}, StepperProps), {
6245
+ activeId: stepperState === null || stepperState === void 0 ? void 0 : stepperState.activeId
6246
+ }))
6247
+ }
6248
+ });
6249
+ context.goToPage(stepperState.maxReachedStep);
6250
+ context.goToPage(stepperState.activeId);
6251
+ }
6252
+ }, [JSON.stringify(StepperProps.uischema), JSON.stringify(StepperProps.schema)]);
6253
+ return jsx(JsonFormsStepperContext.Provider, {
6254
+ value: context,
6255
+ children: children
6265
6256
  });
6266
6257
  };
6267
- const FormStepperReviewControl = withAjvProps(withTranslateProps(withJsonFormsLayoutProps(FormStepperReviewer)));
6268
6258
 
6269
6259
  const summaryLabel = 'Summary';
6270
6260
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -6494,7 +6484,6 @@ const BackButton = ({
6494
6484
  };
6495
6485
 
6496
6486
  const FormStepperPageReviewer = props => {
6497
- var _a, _b;
6498
6487
  const {
6499
6488
  uischema,
6500
6489
  data,
@@ -6504,18 +6493,35 @@ const FormStepperPageReviewer = props => {
6504
6493
  enabled,
6505
6494
  navigationFunc
6506
6495
  } = props;
6507
- (_b = (_a = uischema.options) === null || _a === void 0 ? void 0 : _a.componentProps) !== null && _b !== void 0 ? _b : {};
6508
6496
  const categorization = uischema;
6509
6497
  const categories = categorization.elements.filter(category => isVisible(category, data, '', ajv));
6510
6498
  const rescopeMaps = ['#/properties/albertaAddress', '#/properties/canadianAddress', '#/properties/sin'];
6499
+ const formStepperCtx = useContext(JsonFormsStepperContext);
6511
6500
  return jsxs(TableReviewItem, {
6512
6501
  children: [jsx("h2", {
6513
6502
  children: "Review your answers"
6514
6503
  }), categories.map((category, index) => {
6515
6504
  const categoryLabel = category.label || category.i18n || 'Unknown Category';
6516
6505
  return jsxs(Fragment, {
6517
- children: [jsx(TableReviewCategoryLabel, {
6518
- children: categoryLabel
6506
+ children: [jsx("div", {
6507
+ children: jsxs(TableReviewPageTitleRow, {
6508
+ children: [jsx(TableReviewCategoryLabel, {
6509
+ children: categoryLabel
6510
+ }), jsx("div", {
6511
+ className: "right",
6512
+ children: jsx(GoAButton, {
6513
+ type: "tertiary",
6514
+ testId: `page-review-change-${category.label}-btn`,
6515
+ onClick: () => {
6516
+ if (formStepperCtx) {
6517
+ formStepperCtx.toggleShowReviewLink(index);
6518
+ formStepperCtx.goToPage(index);
6519
+ }
6520
+ },
6521
+ children: "Change"
6522
+ })
6523
+ })]
6524
+ })
6519
6525
  }), jsx(TableReviewItemSection, {
6520
6526
  children: category.elements.filter(field => {
6521
6527
  var _a, _b;
@@ -9321,29 +9327,17 @@ const AddressLoopUpControlTableReview = props => {
9321
9327
  schema,
9322
9328
  uischema
9323
9329
  } = props;
9324
- const categoryIndex = (_a = uischema.options) === null || _a === void 0 ? void 0 : _a.categoryIndex;
9325
- const formStepperCtx = useContext(JsonFormsStepperContext);
9330
+ (_a = uischema.options) === null || _a === void 0 ? void 0 : _a.categoryIndex;
9331
+ useContext(JsonFormsStepperContext);
9326
9332
  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
9333
  return jsxs(Fragment, {
9328
- children: [jsxs("tr", {
9334
+ children: [jsx("tr", {
9329
9335
  "data-testid": "address-lookup-table-review",
9330
- children: [jsx(PageReviewNameCol, {
9336
+ children: jsx(PageReviewNameCol, {
9331
9337
  children: jsx("strong", {
9332
9338
  children: `${isAlbertaAddress ? 'Alberta' : 'Canada'} postal address`
9333
9339
  })
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
- })]
9340
+ })
9347
9341
  }), jsx("tr", {
9348
9342
  children: jsx("td", {
9349
9343
  colSpan: 3,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abgov/jsonforms-components",
3
- "version": "2.0.0",
3
+ "version": "2.1.0",
4
4
  "license": "Apache-2.0",
5
5
  "description": "Government of Alberta - React renderers for JSON Forms based on the design system.",
6
6
  "repository": "https://github.com/GovAlta/adsp-monorepo",
@@ -14,4 +14,5 @@ export declare const PageRenderPadding: import("styled-components/dist/types").I
14
14
  export declare const PageBorder: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLHeadingElement>, HTMLHeadingElement>, never>> & string;
15
15
  export declare const TableReviewItemSection: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
16
16
  export declare const TableReviewItem: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
17
+ export declare const TableReviewPageTitleRow: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
17
18
  export declare const TableReviewCategoryLabel: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLHeadingElement>, HTMLHeadingElement>, never>> & string;
@@ -4,5 +4,4 @@ export declare const WarningIconDiv: import("styled-components/dist/types").ISty
4
4
  export declare const RequiredTextLabel: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").LabelHTMLAttributes<HTMLLabelElement>, HTMLLabelElement>, never>> & string;
5
5
  export declare const PageReviewNameCol: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").TdHTMLAttributes<HTMLTableDataCellElement>, HTMLTableDataCellElement>, never>> & string;
6
6
  export declare const PageReviewValueCol: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").TdHTMLAttributes<HTMLTableDataCellElement>, HTMLTableDataCellElement>, never>> & string;
7
- export declare const PageReviewActionCol: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").TdHTMLAttributes<HTMLTableDataCellElement>, HTMLTableDataCellElement>, never>> & string;
8
7
  export declare const CheckboxWrapper: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;