@abgov/jsonforms-components 2.1.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
@@ -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
  }
@@ -5432,8 +5433,8 @@ let _$6 = t => t,
5432
5433
  _t13$1,
5433
5434
  _t14$1,
5434
5435
  _t15$1,
5435
- _t16,
5436
- _t17;
5436
+ _t16$1,
5437
+ _t17$1;
5437
5438
  const ReviewItem = styled.div(_t$6 || (_t$6 = _$6`
5438
5439
  display: flex;
5439
5440
  flex-direction: column;
@@ -5524,14 +5525,14 @@ const TableReviewItem = styled.div(_t15$1 || (_t15$1 = _$6`
5524
5525
  border-radius: 5px;
5525
5526
  padding: var(--goa-space-2xl);
5526
5527
  `));
5527
- const TableReviewPageTitleRow = styled.div(_t16 || (_t16 = _$6`
5528
+ const TableReviewPageTitleRow = styled.div(_t16$1 || (_t16$1 = _$6`
5528
5529
  margin-top: var(--goa-space-xl);
5529
5530
  display: flex;
5530
5531
  .right {
5531
5532
  margin-left: auto;
5532
5533
  }
5533
5534
  `));
5534
- const TableReviewCategoryLabel = styled.h3(_t17 || (_t17 = _$6`
5535
+ const TableReviewCategoryLabel = styled.h3(_t17$1 || (_t17$1 = _$6`
5535
5536
  color: var(--goa-color-text-secondary) !important;
5536
5537
  `));
5537
5538
 
@@ -7206,6 +7207,92 @@ $$8({ global: true, forced: parseInt !== $parseInt }, {
7206
7207
  parseInt: $parseInt
7207
7208
  });
7208
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
+
7209
7296
  let _$2 = t => t,
7210
7297
  _t$2,
7211
7298
  _t2$2,
@@ -7221,7 +7308,11 @@ let _$2 = t => t,
7221
7308
  _t12,
7222
7309
  _t13,
7223
7310
  _t14,
7224
- _t15;
7311
+ _t15,
7312
+ _t16,
7313
+ _t17,
7314
+ _t18,
7315
+ _t19;
7225
7316
  const DeleteDialogContent = styled.div(_t$2 || (_t$2 = _$2`
7226
7317
  margin-bottom: var(--goa-space-m);
7227
7318
  `));
@@ -7289,6 +7380,31 @@ const ListContainer = styled.div(_t14 || (_t14 = _$2`
7289
7380
  const TableTHHeader = styled.th(_t15 || (_t15 = _$2`
7290
7381
  background-color: var(--goa-color-greyscale-100) !important;
7291
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
+ `));
7292
7408
 
7293
7409
  const DeleteDialog = /*#__PURE__*/React.memo(function DeleteDialog({
7294
7410
  open,
@@ -7361,116 +7477,83 @@ const ObjectArrayToolBar = /*#__PURE__*/React.memo(function TableToolbar({
7361
7477
  "aria-label": translations.addAriaLabel,
7362
7478
  onClick: addItem(path, createDefaultValue(schema, rootSchema)),
7363
7479
  type: (_c = (_b = uischema.options) === null || _b === void 0 ? void 0 : _b.addButtonType) !== null && _c !== void 0 ? _c : 'primary',
7364
- 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}`)
7365
7481
  })
7366
7482
  })
7367
7483
  });
7368
7484
  });
7369
7485
 
7370
- const ADD_DATA_ACTION = 'jsonforms/register/add_data_action';
7371
- const SET_DATA_ACTION = 'jsonforms/register/set_data_action';
7372
- const INCREMENT_ACTION = 'jsonforms/register/increment_action';
7373
- const DELETE_ACTION = 'jsonforms/register/delete_action';
7374
- const initialState = {
7375
- categories: {}
7376
- };
7377
-
7378
- function objectListReducer(state, action) {
7379
- switch (action.type) {
7380
- case ADD_DATA_ACTION:
7381
- {
7382
- //ok so we're assuming we're already getting the updated category data
7383
- const {
7384
- categories
7385
- } = state;
7386
- const {
7387
- name,
7388
- category
7389
- } = action.payload;
7390
- const newCategories = Object.assign({}, categories);
7391
- if (!newCategories[name]) {
7392
- newCategories[name] = {
7393
- data: category
7394
- };
7395
- } else {
7396
- newCategories[name].data = category;
7397
- }
7398
- return Object.assign(Object.assign({}, state), {
7399
- categories: newCategories
7400
- });
7401
- }
7402
- case SET_DATA_ACTION:
7403
- {
7404
- const CategoriesStateData = action.payload;
7405
- return Object.assign(Object.assign({}, state), {
7406
- categories: CategoriesStateData
7407
- });
7408
- }
7409
- case INCREMENT_ACTION:
7410
- {
7411
- const {
7412
- categories
7413
- } = state;
7414
- const name = action.payload;
7415
- const newCategories = Object.assign({}, categories);
7416
- // Assuming you want to increment the count of a category:
7417
- if (newCategories[name]) {
7418
- const updatedCategory = Object.assign(Object.assign({}, categories[name]), {
7419
- count: (categories[name].count || 0) + 1
7420
- });
7421
- return Object.assign(Object.assign({}, state), {
7422
- categories: Object.assign(Object.assign({}, categories), {
7423
- [name]: updatedCategory
7424
- })
7425
- });
7426
- } else {
7427
- newCategories[name] = {
7428
- count: 1,
7429
- data: {}
7430
- };
7431
- }
7432
- return Object.assign(Object.assign({}, state), {
7433
- categories: newCategories
7434
- });
7435
- }
7436
- case DELETE_ACTION:
7437
- {
7438
- const {
7439
- name,
7440
- category
7441
- } = action.payload;
7442
- const {
7443
- categories
7444
- } = state;
7445
- const newCategories = Object.assign({}, categories);
7446
- newCategories[name] = category;
7447
- return Object.assign(Object.assign({}, state), {
7448
- categories: newCategories
7449
- });
7450
- }
7451
- default:
7452
- return state;
7453
- }
7454
- }
7455
-
7456
- 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 = {}) => {
7457
7493
  if (Array.isArray(obj)) {
7458
7494
  obj.forEach(item => extractNames(item, names));
7459
7495
  } else if (typeof obj === 'object' && obj !== null) {
7460
7496
  const typedObj = obj;
7461
- if (typeof typedObj.label === 'string') {
7462
- names.push(typedObj.label);
7463
- } else if (typeof typedObj.scope === 'string') {
7497
+ if (typeof typedObj.scope === 'string') {
7464
7498
  const parts = typedObj.scope.split('/');
7465
- 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
+ }
7466
7505
  }
7467
7506
  Object.values(typedObj).forEach(value => extractNames(value, names));
7468
7507
  }
7469
7508
  return names;
7470
- }
7471
- const GenerateRows$1 = (Cell, schema, rowPath, enabled, openDeleteDialog, handleChange, cells, uischema, isInReview, count, data,
7472
- // eslint-disable-next-line
7473
- 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) => {
7474
7557
  if ((schema === null || schema === void 0 ? void 0 : schema.type) === 'object') {
7475
7558
  const props = {
7476
7559
  schema,
@@ -7545,12 +7628,8 @@ const ctxToNonEmptyCellProps$1 = (ctx, ownProps) => {
7545
7628
  handleChange: ownProps.handleChange
7546
7629
  };
7547
7630
  };
7548
- function capitalizeFirstLetter(str) {
7549
- if (!str) return ''; // Handle empty strings
7550
- return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase();
7551
- }
7552
7631
  const NonEmptyCellComponent$1 = /*#__PURE__*/React.memo(function NonEmptyCellComponent(props) {
7553
- var _a, _b, _c;
7632
+ var _a, _b, _c, _d;
7554
7633
  const {
7555
7634
  schema,
7556
7635
  enabled,
@@ -7568,13 +7647,26 @@ const NonEmptyCellComponent$1 = /*#__PURE__*/React.memo(function NonEmptyCellCom
7568
7647
  const properties = (schema === null || schema === void 0 ? void 0 : schema.items) && 'properties' in schema.items && schema.items.properties || {};
7569
7648
  const required = (_a = schema.items) === null || _a === void 0 ? void 0 : _a.required;
7570
7649
  let tableKeys = extractNames((_b = uischema === null || uischema === void 0 ? void 0 : uischema.options) === null || _b === void 0 ? void 0 : _b.detail);
7571
- if (tableKeys.length === 0) {
7572
- tableKeys = Object.keys(properties);
7650
+ if (Object.keys(tableKeys).length === 0) {
7651
+ Object.keys(properties).forEach(item => {
7652
+ tableKeys[item] = item;
7653
+ });
7573
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;
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;
7574
7668
  return jsxs(NonEmptyCellStyle, {
7575
- children: [
7576
- // eslint-disable-next-line
7577
- (_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 => {
7578
7670
  return jsx(JsonFormsDispatch, {
7579
7671
  "data-testid": `jsonforms-object-list-defined-elements-dispatch`,
7580
7672
  schema: schema,
@@ -7584,99 +7676,114 @@ const NonEmptyCellComponent$1 = /*#__PURE__*/React.memo(function NonEmptyCellCom
7584
7676
  renderers: isInReview ? GoAReviewRenderers : renderers,
7585
7677
  cells: cells
7586
7678
  }, rowPath);
7587
- }), Object.keys(properties).length > 0 && jsxs(GoATable, {
7588
- width: "100%",
7589
- children: [jsx("thead", {
7590
- children: jsxs("tr", {
7591
- children: [tableKeys.map((key, index) => {
7592
- if (!isInReview) {
7593
- 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, {
7594
7695
  children: jsxs("p", {
7595
- children: [convertToSentenceCase(key), (required === null || required === void 0 ? void 0 : required.includes(key)) && jsx(RequiredSpan, {
7596
- children: "(required)"
7696
+ children: [`${convertToSentenceCase(index)}`, (required === null || required === void 0 ? void 0 : required.includes(value)) && jsxs(RequiredSpan, {
7697
+ children: [jsx("br", {}), " (required)"]
7597
7698
  })]
7598
7699
  })
7599
7700
  }, index);
7600
- }
7601
- return jsx(TableTHHeader, {
7701
+ }), isInReview !== true && jsx("th", {
7602
7702
  children: jsx("p", {
7603
- children: convertToSentenceCase(key)
7703
+ children: "Actions"
7604
7704
  })
7605
- }, index);
7606
- }), isInReview !== true && jsx("th", {
7607
- children: jsx("p", {
7608
- children: "Actions"
7609
- })
7610
- })]
7611
- }, 0)
7612
- }), jsx("tbody", {
7613
- children: range(count || 0).map((num, i) => {
7614
- // eslint-disable-next-line
7615
- const errorRow = errors === null || errors === void 0 ? void 0 : errors.find(error => error.instancePath.includes(`/${props.rowPath.replace(/\./g, '/')}/${i}`));
7616
- return jsxs("tr", {
7617
- children: [Object.keys(properties).map((element, ix) => {
7618
- var _a;
7619
- const dataObject = properties[element];
7620
- const schemaName = element;
7621
- const currentData = data && data[num] ? data[num][element] : '';
7622
- const error = errors === null || errors === void 0 ? void 0 : errors.find(
7623
- // eslint-disable-next-line
7624
- e => e.instancePath === `/${props.rowPath.replace(/\./g, '/')}/${i}/${element}`);
7625
- 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))) {
7626
- error.message = `${capitalizeFirstLetter(schemaName)} is required`;
7627
- }
7628
- return jsx("td", {
7629
- children: isInReview ? jsx("div", {
7630
- "data-testid": `#/properties/${schemaName}-input-${i}-review`,
7631
- children: typeof currentData === 'string' ? currentData : jsx("pre", {
7632
- 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
+ })
7633
7764
  })
7634
- }) : jsx(GoAFormItem, {
7635
- error: (_a = error === null || error === void 0 ? void 0 : error.message) !== null && _a !== void 0 ? _a : '',
7636
- mb: errorRow && !error && '2xl' || 'xs',
7637
- children: dataObject.type === 'number' || dataObject.type === 'string' && !dataObject.enum ? jsx(GoAInput, {
7638
- error: (error === null || error === void 0 ? void 0 : error.message.length) > 0,
7639
- type: dataObject.type === 'number' ? 'number' : 'text',
7640
- id: schemaName,
7641
- name: schemaName,
7642
- value: currentData,
7643
- testId: `#/properties/${schemaName}-input-${i}`,
7644
- onChange: (name, value) => {
7645
- handleChange(rowPath, {
7646
- [num]: {
7647
- [name]: dataObject.type === 'number' ? parseInt(value) : value
7648
- }
7649
- });
7650
- },
7651
- "aria-label": schemaName,
7652
- width: "100%"
7653
- }) : jsx(GoACallout, {
7654
- type: "important",
7655
- size: "medium",
7656
- testId: "form-support-callout",
7657
- heading: "Not supported",
7658
- 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)
7659
7779
  })
7660
7780
  })
7661
- }, ix);
7662
- }), jsx("td", {
7663
- style: {
7664
- alignContent: 'baseLine',
7665
- paddingTop: '18px'
7666
- },
7667
- children: jsx("div", {
7668
- "aria-hidden": "true",
7669
- children: !isInReview && jsx(GoAIconButton, {
7670
- icon: "trash",
7671
- title: "trash button",
7672
- testId: "trash-icon-button",
7673
- "aria-label": `remove-element-${num}`,
7674
- onClick: () => openDeleteDialog(num)
7675
- })
7676
- })
7677
- })]
7678
- }, i);
7679
- })
7781
+ })]
7782
+ }, `${i}-${num}`);
7783
+ })
7784
+ })]
7785
+ }), hasAnyErrors && isInReview && jsx(GoAFormItem, {
7786
+ error: `There are validation errors for '${capitalizeFirstLetter(rowPath)}'`
7680
7787
  })]
7681
7788
  })]
7682
7789
  });
@@ -7760,7 +7867,6 @@ const ObjectArrayList$1 = ({
7760
7867
  data: data
7761
7868
  }, 0);
7762
7869
  };
7763
- // eslint-disable-next-line
7764
7870
  const ObjectArrayControl = props => {
7765
7871
  var _a, _b, _c;
7766
7872
  const [registers, dispatch] = useReducer(objectListReducer, initialState);
@@ -7866,8 +7972,7 @@ const ObjectArrayControl = props => {
7866
7972
  }
7867
7973
  };
7868
7974
  useEffect(() => {
7869
- // eslint-disable-next-line
7870
- const updatedData = Array.isArray(parsedData) ? Object.fromEntries(parsedData.map((item, index) => [index, item])) : {};
7975
+ const updatedData = Object.fromEntries((parsedData || []).map((item, index) => [index, item]));
7871
7976
  const count = Object.keys(updatedData).length;
7872
7977
  const dispatchData = {
7873
7978
  [path]: {
@@ -7881,9 +7986,9 @@ const ObjectArrayControl = props => {
7881
7986
  payload: dispatchData
7882
7987
  });
7883
7988
  }
7989
+ // eslint-disable-next-line
7884
7990
  }, []);
7885
7991
  const controlElement = uischema;
7886
- // eslint-disable-next-line
7887
7992
  const listTitle = label || ((_a = uischema.options) === null || _a === void 0 ? void 0 : _a.title);
7888
7993
  const isInReview = isStepperReview === true;
7889
7994
  return jsxs(Visible, {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abgov/jsonforms-components",
3
- "version": "2.1.0",
3
+ "version": "2.1.1",
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",
@@ -1,50 +1,6 @@
1
1
  import React from 'react';
2
- import { ArrayLayoutProps, ControlElement, JsonSchema, JsonFormsRendererRegistryEntry, JsonFormsCellRendererRegistryEntry, ArrayTranslations, Layout, ControlProps } from '@jsonforms/core';
3
2
  import { WithBasicDeleteDialogSupport } from './DeleteDialog';
4
- import { StateData } from './arrayData';
5
- interface ArrayLayoutExtProps {
6
- isStepperReview?: boolean;
7
- }
8
- interface HandleChangeProps {
9
- handleChange(path: string, value: any): void;
10
- }
11
- export type ObjectArrayControlProps = ArrayLayoutProps & ArrayLayoutExtProps & ControlProps;
12
- export interface EmptyListProps {
13
- numColumns: number;
14
- translations: ArrayTranslations;
15
- }
16
- interface NonEmptyRowComponentProps {
17
- propName?: string;
18
- schema: JsonSchema;
19
- rootSchema?: JsonSchema;
20
- rowPath: string;
21
- errors?: Record<string, any>;
22
- enabled: boolean;
23
- renderers?: JsonFormsRendererRegistryEntry[];
24
- cells?: JsonFormsCellRendererRegistryEntry[];
25
- isValid: boolean;
26
- uischema?: ControlElement | Layout;
27
- isInReview?: boolean;
28
- count?: number;
29
- data: StateData | undefined;
30
- handleChange(path: string, value: string): void;
31
- openDeleteDialog(rowIndex: number): void;
32
- }
3
+ import { HandleChangeProps, NonEmptyRowComponentProps, NonEmptyRowProps, ObjectArrayControlProps } from './ObjectListControlTypes';
33
4
  export declare const NonEmptyCellComponent: React.NamedExoticComponent<NonEmptyRowComponentProps & HandleChangeProps>;
34
- interface NonEmptyRowProps {
35
- childPath: string;
36
- schema: JsonSchema;
37
- rowIndex: number;
38
- showSortButtons: boolean;
39
- enabled: boolean;
40
- cells?: JsonFormsCellRendererRegistryEntry[];
41
- path: string;
42
- translations: ArrayTranslations;
43
- uischema: ControlElement;
44
- isInReview?: boolean;
45
- data?: StateData;
46
- count: number;
47
- }
48
5
  export declare const NonEmptyList: React.MemoExoticComponent<({ childPath, schema, openDeleteDialog, enabled, cells, uischema, isInReview, data, count, handleChange, }: NonEmptyRowProps & WithBasicDeleteDialogSupport & HandleChangeProps) => import("react/jsx-runtime").JSX.Element>;
49
6
  export declare const ObjectArrayControl: (props: ObjectArrayControlProps) => JSX.Element;
50
- export {};
@@ -0,0 +1,99 @@
1
+ import { ArrayLayoutProps, ArrayTranslations, ControlElement, ControlProps, JsonFormsCellRendererRegistryEntry, JsonFormsRendererRegistryEntry, JsonSchema, Layout } from '@jsonforms/core';
2
+ import { StateData } from './arrayData';
3
+ import { ErrorObject } from 'ajv';
4
+ export type ObjectArrayControlProps = ArrayLayoutProps & ArrayLayoutExtProps & ControlProps;
5
+ export interface ArrayLayoutExtProps {
6
+ isStepperReview?: boolean;
7
+ }
8
+ export interface DataProperty {
9
+ type: string;
10
+ format?: string;
11
+ maxLength?: number;
12
+ required?: string[];
13
+ enum: string[];
14
+ }
15
+ export interface DataObject {
16
+ [key: string]: DataProperty;
17
+ }
18
+ export interface Items {
19
+ type: string;
20
+ properties: DataObject;
21
+ }
22
+ export interface HandleChangeProps {
23
+ handleChange(path: string, value: any): void;
24
+ }
25
+ export interface NonEmptyCellProps extends OwnPropsOfNonEmptyCell {
26
+ rootSchema?: JsonSchema;
27
+ errors?: ErrorObject[];
28
+ enabled: boolean;
29
+ }
30
+ export interface OwnPropsOfNonEmptyCell {
31
+ rowPath: string;
32
+ propName?: string;
33
+ schema: JsonSchema;
34
+ enabled: boolean;
35
+ renderers?: JsonFormsRendererRegistryEntry[];
36
+ cells?: JsonFormsCellRendererRegistryEntry[];
37
+ uischema?: ControlElement;
38
+ isInReview?: boolean;
39
+ data?: StateData;
40
+ count?: number;
41
+ handleChange(path: string, value: string): void;
42
+ }
43
+ export interface OwnPropsOfNonEmptyCellWithDialog extends OwnPropsOfNonEmptyCell {
44
+ openDeleteDialog: (rowIndex: number) => void;
45
+ }
46
+ export interface NonEmptyRowComponentProps {
47
+ propName?: string;
48
+ schema: JsonSchema;
49
+ rootSchema?: JsonSchema;
50
+ rowPath: string;
51
+ errors?: ErrorObject[];
52
+ enabled: boolean;
53
+ renderers?: JsonFormsRendererRegistryEntry[];
54
+ cells?: JsonFormsCellRendererRegistryEntry[];
55
+ isValid: boolean;
56
+ uischema?: ControlElement | Layout;
57
+ isInReview?: boolean;
58
+ count?: number;
59
+ data: StateData | undefined;
60
+ handleChange(path: string, value: string): void;
61
+ openDeleteDialog(rowIndex: number): void;
62
+ }
63
+ export interface NonEmptyRowProps {
64
+ childPath: string;
65
+ schema: JsonSchema;
66
+ rowIndex: number;
67
+ showSortButtons: boolean;
68
+ enabled: boolean;
69
+ cells?: JsonFormsCellRendererRegistryEntry[];
70
+ path: string;
71
+ translations: ArrayTranslations;
72
+ uischema: ControlElement;
73
+ isInReview?: boolean;
74
+ data?: StateData;
75
+ count: number;
76
+ }
77
+ export interface EmptyListProps {
78
+ numColumns: number;
79
+ translations: ArrayTranslations;
80
+ }
81
+ export interface TableRowsProp {
82
+ data: StateData;
83
+ path: string;
84
+ schema: JsonSchema;
85
+ uischema: ControlElement;
86
+ config?: any;
87
+ enabled: boolean;
88
+ cells?: JsonFormsCellRendererRegistryEntry[];
89
+ translations: ArrayTranslations;
90
+ count: number;
91
+ isInReview?: boolean;
92
+ handleChange: (path: string, value: any) => void;
93
+ }
94
+ export interface RenderCellColumnProps {
95
+ currentData: string | undefined;
96
+ error: string | undefined;
97
+ isRequired: boolean;
98
+ tableKeys?: string[];
99
+ }
@@ -0,0 +1,9 @@
1
+ import { RenderCellColumnProps } from './ObjectListControlTypes';
2
+ /**
3
+ * Extract Json data schema name attribute and the ui schema label name.
4
+ * @param obj
5
+ * @param names
6
+ * @returns A key value of the data attribute name and the uiSchema label value
7
+ */
8
+ export declare const extractNames: (obj: unknown, names?: Record<string, string>) => Record<string, string>;
9
+ export declare const renderCellColumn: ({ currentData, error, isRequired }: RenderCellColumnProps) => string | import("react/jsx-runtime").JSX.Element | null;
@@ -14,3 +14,7 @@ export declare const TabName: import("styled-components/dist/types").IStyledComp
14
14
  export declare const Trash: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
15
15
  export declare const ListContainer: 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 TableTHHeader: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").ThHTMLAttributes<HTMLTableHeaderCellElement>, HTMLTableHeaderCellElement>, never>> & string;
17
+ export declare const ObjectArrayWarningIconDiv: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
18
+ export declare const ObjectArrayRequiredTextLabel: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").LabelHTMLAttributes<HTMLLabelElement>, HTMLLabelElement>, never>> & string;
19
+ export declare const HasErrorLabel: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
20
+ export declare const HilightCellWarning: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;