@abgov/jsonforms-components 1.14.0 → 1.14.2

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
@@ -3263,6 +3263,48 @@ $({ target: 'String', proto: true, forced: !correctIsRegExpLogic('includes') },
3263
3263
  }
3264
3264
  });
3265
3265
 
3266
+ /******************************************************************************
3267
+ Copyright (c) Microsoft Corporation.
3268
+
3269
+ Permission to use, copy, modify, and/or distribute this software for any
3270
+ purpose with or without fee is hereby granted.
3271
+
3272
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
3273
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
3274
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
3275
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
3276
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
3277
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
3278
+ PERFORMANCE OF THIS SOFTWARE.
3279
+ ***************************************************************************** */
3280
+
3281
+ function __rest(s, e) {
3282
+ var t = {};
3283
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
3284
+ t[p] = s[p];
3285
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
3286
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
3287
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
3288
+ t[p[i]] = s[p[i]];
3289
+ }
3290
+ return t;
3291
+ }
3292
+
3293
+ function __awaiter(thisArg, _arguments, P, generator) {
3294
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3295
+ return new (P || (P = Promise))(function (resolve, reject) {
3296
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
3297
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
3298
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
3299
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
3300
+ });
3301
+ }
3302
+
3303
+ typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
3304
+ var e = new Error(message);
3305
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
3306
+ };
3307
+
3266
3308
  const getAxiosInterceptorConfig = axios => {
3267
3309
  const requestId = axios.interceptors.request.use(req => {
3268
3310
  if (req.data === undefined) {
@@ -3272,7 +3314,7 @@ const getAxiosInterceptorConfig = axios => {
3272
3314
  });
3273
3315
  return [requestId, axios];
3274
3316
  };
3275
- function addDataByUrl(key, url, processDataFunction, token) {
3317
+ const addDataByUrl = (key, url, processDataFunction, token) => __awaiter(void 0, void 0, void 0, function* () {
3276
3318
  let header = {};
3277
3319
  const [requestId, axiosWithConfig] = getAxiosInterceptorConfig(axios);
3278
3320
  if (token) {
@@ -3280,7 +3322,7 @@ function addDataByUrl(key, url, processDataFunction, token) {
3280
3322
  Authorization: `Bearer ${token}`
3281
3323
  });
3282
3324
  }
3283
- axiosWithConfig.get(url, header).then(response => {
3325
+ yield axiosWithConfig.get(url, header).then(response => {
3284
3326
  const processedData = processDataFunction(response.data);
3285
3327
  enumValues.set(key, () => processedData);
3286
3328
  }).catch(err => {
@@ -3291,14 +3333,15 @@ function addDataByUrl(key, url, processDataFunction, token) {
3291
3333
  }
3292
3334
  });
3293
3335
  axiosWithConfig.interceptors.request.eject(requestId);
3294
- }
3295
- function addDataByOptions(key, url, location, type, values) {
3336
+ });
3337
+ function addDataByOptions(key, url, location, type, values = ['']) {
3296
3338
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
3297
3339
  const dataFunction = data => {
3298
3340
  let dataLink = data;
3299
3341
  let returnData = [''];
3300
- const locationArray = location && !Array.isArray(location) ? [location] : location;
3301
- locationArray === null || locationArray === void 0 ? void 0 : locationArray.forEach(attribute => {
3342
+ const locationArray = location && Array.isArray(location) ? location : [location];
3343
+ const locationArrayTyped = locationArray;
3344
+ locationArrayTyped === null || locationArrayTyped === void 0 ? void 0 : locationArrayTyped.forEach(attribute => {
3302
3345
  dataLink = dataLink[attribute];
3303
3346
  });
3304
3347
  const valuesArray = Array.isArray(values) ? values : [values];
@@ -3341,20 +3384,16 @@ function ContextProvider(props) {
3341
3384
  downloadFile,
3342
3385
  deleteFile
3343
3386
  } = props.fileManagement;
3344
- /* eslint-disable @typescript-eslint/no-empty-function */
3345
- const uploadFileFunction = uploadFile ? uploadFile : () => {};
3346
- const downloadFileFunction = downloadFile ? downloadFile : () => {};
3347
- const deleteFileFunction = deleteFile ? deleteFile : () => {};
3348
3387
  enumValues.set('file-list', () => fileList);
3349
- enumFunctions.set('upload-file', () => uploadFileFunction);
3350
- enumFunctions.set('download-file', () => downloadFileFunction);
3351
- enumFunctions.set('delete-file', () => deleteFileFunction);
3388
+ enumFunctions.set('upload-file', () => uploadFile);
3389
+ enumFunctions.set('download-file', () => downloadFile);
3390
+ enumFunctions.set('delete-file', () => deleteFile);
3352
3391
  }
3353
3392
  if (props.submit) {
3354
3393
  const {
3355
3394
  submitForm
3356
3395
  } = props.submit;
3357
- const submitFunction = submitForm ? submitForm : () => {};
3396
+ const submitFunction = submitForm;
3358
3397
  enumSubmitFunctions.set('submit-form', () => submitFunction);
3359
3398
  }
3360
3399
  if (props.data) {
@@ -3936,46 +3975,82 @@ const getFormFieldValue = (scope, data) => {
3936
3975
  return '';
3937
3976
  }
3938
3977
  };
3939
- const renderFormFields = (elements, data,
3940
- // eslint-disable-line @typescript-eslint/no-explicit-any
3941
- requiredFields) => elements.map((element, index) => {
3942
- var _a;
3943
- const clonedElement = JSON.parse(JSON.stringify(element));
3944
- const lastSegment = (_a = clonedElement.scope) === null || _a === void 0 ? void 0 : _a.split('/').pop();
3945
- if (clonedElement.type === 'Control' && clonedElement.scope) {
3946
- const label = clonedElement.label ? clonedElement.label : resolveLabelFromScope(clonedElement.scope);
3947
- if (!label) return null;
3948
- const value = getFormFieldValue(clonedElement.scope, data ? data : {}).toString();
3949
- const asterisk = requiredFields.indexOf(lastSegment) !== -1 ? ' *' : '';
3950
- return jsxs(GridItem, {
3951
- md: 6,
3952
- vSpacing: 1,
3953
- hSpacing: 0.5,
3954
- children: [jsxs("strong", {
3955
- children: [label, " ", asterisk + ':']
3956
- }), ' ', value]
3957
- }, index);
3958
- } else if (clonedElement.type !== 'ListWithDetail' && (clonedElement === null || clonedElement === void 0 ? void 0 : clonedElement.elements)) {
3959
- return jsx(React.Fragment, {
3960
- children: renderFormFields(clonedElement.elements, data, requiredFields)
3961
- }, index);
3962
- } else if (clonedElement.type === 'ListWithDetail' && data && data[lastSegment] && data[lastSegment].length > 0) {
3963
- const listData = data[lastSegment];
3964
- return jsxs(ListWithDetail, {
3965
- children: [jsxs(ListWithDetailHeading, {
3966
- children: [lastSegment, listData.length > 1 && 's']
3967
- }), jsx(Grid, {
3968
- children: listData.map((childData,
3969
- // eslint-disable-line @typescript-eslint/no-explicit-any
3970
- childIndex // eslint-disable-line @typescript-eslint/no-explicit-any
3971
- ) => jsx(React.Fragment, {
3972
- children: renderFormFields(clonedElement.elements, childData, requiredFields)
3973
- }, `${index}-${childIndex}`))
3974
- })]
3975
- });
3976
- }
3977
- return null;
3978
- });
3978
+ const RenderFormFields = ({
3979
+ elements,
3980
+ data,
3981
+ requiredFields
3982
+ }) => {
3983
+ var _a, _b;
3984
+ const enumerators = useContext(JsonFormContext);
3985
+ const downloadTriggerFunction = (_a = enumerators === null || enumerators === void 0 ? void 0 : enumerators.functions) === null || _a === void 0 ? void 0 : _a.get('download-file');
3986
+ const downloadTrigger = downloadTriggerFunction && downloadTriggerFunction();
3987
+ const fileListValue = (_b = enumerators === null || enumerators === void 0 ? void 0 : enumerators.data) === null || _b === void 0 ? void 0 : _b.get('file-list');
3988
+ // eslint-disable-next-line
3989
+ const fileList = fileListValue && fileListValue();
3990
+ const toCamelCase = input => {
3991
+ const words = input.split(' ');
3992
+ const firstWord = words[0].toLowerCase();
3993
+ const capitalizedWords = words.slice(1).map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase());
3994
+ return [firstWord, ...capitalizedWords].join('');
3995
+ };
3996
+ const downloadFile = (file, propertyId) => {
3997
+ if (downloadTrigger) {
3998
+ downloadTrigger(file, propertyId);
3999
+ }
4000
+ };
4001
+ return elements.map((element, index) => {
4002
+ var _a;
4003
+ const clonedElement = JSON.parse(JSON.stringify(element));
4004
+ const lastSegment = (_a = clonedElement.scope) === null || _a === void 0 ? void 0 : _a.split('/').pop();
4005
+ if (clonedElement.type === 'Control' && clonedElement.scope) {
4006
+ const label = clonedElement.label ? clonedElement.label : resolveLabelFromScope(clonedElement.scope);
4007
+ if (!label) return null;
4008
+ const isFileUploader = label.toLowerCase().includes('file uploader');
4009
+ const fileUploaderElement = isFileUploader ? fileList && fileList[toCamelCase(label)] : null;
4010
+ const value = getFormFieldValue(clonedElement.scope, data ? data : {}).toString();
4011
+ const isRequired = requiredFields.includes(lastSegment);
4012
+ const asterisk = isRequired ? ' *' : '';
4013
+ return jsxs(GridItem, {
4014
+ md: 6,
4015
+ vSpacing: 1,
4016
+ hSpacing: 0.5,
4017
+ children: [jsxs("strong", {
4018
+ children: [label, " ", asterisk + ': ']
4019
+ }), fileUploaderElement ? jsx("a", {
4020
+ onClick: () => downloadFile(fileUploaderElement, fileUploaderElement === null || fileUploaderElement === void 0 ? void 0 : fileUploaderElement.propertyId),
4021
+ children: fileUploaderElement === null || fileUploaderElement === void 0 ? void 0 : fileUploaderElement.filename
4022
+ }) : value]
4023
+ }, index);
4024
+ } else if (clonedElement.type !== 'ListWithDetail' && (clonedElement === null || clonedElement === void 0 ? void 0 : clonedElement.elements)) {
4025
+ return jsx(React.Fragment, {
4026
+ children: jsx(RenderFormFields, {
4027
+ elements: clonedElement.elements,
4028
+ data: data,
4029
+ requiredFields: requiredFields
4030
+ })
4031
+ }, index);
4032
+ } else if (clonedElement.type === 'ListWithDetail' && data && data[lastSegment] && data[lastSegment].length > 0) {
4033
+ const listData = data[lastSegment];
4034
+ return jsxs(ListWithDetail, {
4035
+ children: [jsxs(ListWithDetailHeading, {
4036
+ children: [lastSegment, listData.length > 1 && 's']
4037
+ }), jsx(Grid, {
4038
+ children: listData.map((childData,
4039
+ // eslint-disable-line @typescript-eslint/no-explicit-any
4040
+ childIndex // eslint-disable-line @typescript-eslint/no-explicit-any
4041
+ ) => jsx(React.Fragment, {
4042
+ children: jsx(RenderFormFields, {
4043
+ elements: clonedElement.elements,
4044
+ data: childData,
4045
+ requiredFields: requiredFields
4046
+ })
4047
+ }, `${index}-${childIndex}`))
4048
+ })]
4049
+ });
4050
+ }
4051
+ return null;
4052
+ });
4053
+ };
3979
4054
 
3980
4055
  const RenderStepElements = props => {
3981
4056
  return (
@@ -3999,6 +4074,24 @@ const RenderStepElements = props => {
3999
4074
  );
4000
4075
  };
4001
4076
 
4077
+ const validateData = (jsonSchema, data, ajv) => {
4078
+ const newSchema = JSON.parse(JSON.stringify(jsonSchema));
4079
+ Object.keys(newSchema.properties || {}).forEach(propertyName => {
4080
+ var _a;
4081
+ const property = newSchema.properties || {};
4082
+ property[propertyName].enum = getData(propertyName);
4083
+ if (((_a = property[propertyName]) === null || _a === void 0 ? void 0 : _a.format) === 'file-urn') {
4084
+ delete property[propertyName].format;
4085
+ }
4086
+ });
4087
+ try {
4088
+ const validate = ajv.compile(newSchema);
4089
+ return validate(data).valueOf();
4090
+ } catch (e) {
4091
+ return false;
4092
+ }
4093
+ };
4094
+
4002
4095
  const FormStepper = props => {
4003
4096
  var _a, _b, _c, _d;
4004
4097
  const {
@@ -4052,17 +4145,8 @@ const FormStepper = props => {
4052
4145
  setStepStatuses(statuses);
4053
4146
  }, [inputStatuses, categories]);
4054
4147
  useEffect(() => {
4055
- const newSchema = JSON.parse(JSON.stringify(schema));
4056
- Object.keys(newSchema.properties || {}).forEach(propertyName => {
4057
- var _a;
4058
- const property = newSchema.properties || {};
4059
- property[propertyName].enum = getData(propertyName);
4060
- if (((_a = property[propertyName]) === null || _a === void 0 ? void 0 : _a.format) === 'file-urn') {
4061
- delete property[propertyName].format;
4062
- }
4063
- });
4064
- const validate = ajv.compile(newSchema);
4065
- setIsFormValid(validate(data));
4148
+ const isValid = validateData(schema, data, ajv);
4149
+ setIsFormValid(isValid);
4066
4150
  }, [ajv, data, schema]);
4067
4151
  useEffect(() => {
4068
4152
  var _a, _b;
@@ -4198,7 +4282,11 @@ const FormStepper = props => {
4198
4282
  children: readOnly ? 'View' : 'Edit'
4199
4283
  })]
4200
4284
  }), jsx(Grid, {
4201
- children: renderFormFields(category.elements, data, requiredFields)
4285
+ children: jsx(RenderFormFields, {
4286
+ elements: category.elements,
4287
+ data: data,
4288
+ requiredFields: requiredFields
4289
+ })
4202
4290
  })]
4203
4291
  }, index);
4204
4292
  })
@@ -4226,6 +4314,7 @@ const FormStepper = props => {
4226
4314
  type: "primary",
4227
4315
  onClick: handleSubmit,
4228
4316
  disabled: !isFormValid || !enabled,
4317
+ testId: "stepper-submit-btn",
4229
4318
  children: "Submit"
4230
4319
  })
4231
4320
  })]
@@ -4273,38 +4362,6 @@ const categoriesAreValid = uischema => {
4273
4362
  };
4274
4363
  const CategorizationRendererTester = rankWith(2, and(uiTypeIs('Categorization'), categoriesAreValid, optionIs('variant', 'stepper')));
4275
4364
 
4276
- /******************************************************************************
4277
- Copyright (c) Microsoft Corporation.
4278
-
4279
- Permission to use, copy, modify, and/or distribute this software for any
4280
- purpose with or without fee is hereby granted.
4281
-
4282
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
4283
- REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
4284
- AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
4285
- INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
4286
- LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
4287
- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
4288
- PERFORMANCE OF THIS SOFTWARE.
4289
- ***************************************************************************** */
4290
-
4291
- function __rest(s, e) {
4292
- var t = {};
4293
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
4294
- t[p] = s[p];
4295
- if (s != null && typeof Object.getOwnPropertySymbols === "function")
4296
- for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
4297
- if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
4298
- t[p[i]] = s[p[i]];
4299
- }
4300
- return t;
4301
- }
4302
-
4303
- typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
4304
- var e = new Error(message);
4305
- return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
4306
- };
4307
-
4308
4365
  let _$3 = t => t,
4309
4366
  _t$3;
4310
4367
  const GoAContextMenuIcon = props => {
@@ -5422,4 +5479,4 @@ const GoARenderers = [...GoABaseRenderers, {
5422
5479
  }];
5423
5480
  const GoACells = [...InputCells];
5424
5481
 
5425
- export { ContextProvider, GoABaseRenderers, GoACells, GoARenderers, JsonFormContext, addData, addDataByOptions, addDataByUrl, ajv, getAllData, getData };
5482
+ export { ContextProvider, GoABaseRenderers, GoACells, GoARenderers, JsonFormContext, addData, addDataByOptions, addDataByUrl, ajv, getAllData, getAxiosInterceptorConfig, getData };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abgov/jsonforms-components",
3
- "version": "1.14.0",
3
+ "version": "1.14.2",
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,9 +1,11 @@
1
1
  import React from 'react';
2
+ import { AxiosStatic } from 'axios';
2
3
  export interface AllData {
3
4
  [x: string]: any;
4
5
  }
5
- export declare function addDataByUrl(key: string, url: string, processDataFunction: (url: string) => string[], token?: string): void;
6
- export declare function addDataByOptions(key: string, url: string, location: string[], type: string, values: string[]): void;
6
+ export declare const getAxiosInterceptorConfig: (axios: AxiosStatic) => [number, AxiosStatic];
7
+ export declare const addDataByUrl: (key: string, url: string, processDataFunction: (data: object) => string[], token?: string) => Promise<void>;
8
+ export declare function addDataByOptions(key: string, url: string, location: string[] | string, type: string, values?: string[] | string): void;
7
9
  interface FileManagement {
8
10
  fileList?: any;
9
11
  uploadFile?: (file: File, propertyId: string) => void;
@@ -20,16 +22,16 @@ type Props = {
20
22
  data?: any;
21
23
  };
22
24
  export declare const JsonFormContext: React.Context<{
23
- data: Map<string, () => Record<string, any> | string[]>;
24
- functions: Map<string, () => (file: File, propertyId: string) => void>;
25
- submitFunction: Map<string, () => (data: any) => void>;
25
+ data: Map<string, () => Record<string, any>>;
26
+ functions: Map<string, () => ((file: File, propertyId: string) => void) | undefined>;
27
+ submitFunction: Map<string, () => ((data: any) => void) | undefined>;
26
28
  }>;
27
29
  export declare function ContextProvider(props: Props): JSX.Element | null;
28
30
  /**
29
31
  * Grabs data stored under a given key
30
32
  *
31
33
  */
32
- export declare function getData(key: string): string[] | Record<string, any> | undefined;
34
+ export declare function getData(key: string): Record<string, any> | undefined;
33
35
  /**
34
36
  * Grabs all data
35
37
  *
@@ -5,6 +5,5 @@ export interface CategorizationStepperLayoutRendererProps extends StatePropsOfLa
5
5
  data: unknown;
6
6
  }
7
7
  export declare const FormStepper: (props: CategorizationStepperLayoutRendererProps) => JSX.Element;
8
- export declare const flattenObject: (obj: Record<string, string>) => Record<string, string>;
9
8
  export declare const FormStepperControl: (props: CategorizationStepperLayoutRendererProps & import("@jsonforms/core").OwnPropsOfLayout) => import("react/jsx-runtime").JSX.Element;
10
9
  export default FormStepper;
@@ -1,4 +1,11 @@
1
1
  import { UISchemaElement, Category, Categorization } from '@jsonforms/core';
2
+ import React from 'react';
3
+ interface RenderFormFieldsProps {
4
+ elements: UISchemaElement[] | (Category | Categorization)[];
5
+ data: any;
6
+ requiredFields: string[];
7
+ }
2
8
  export declare const resolveLabelFromScope: (scope: string) => string | null;
3
9
  export declare const getFormFieldValue: (scope: string, data: object) => any;
4
- export declare const renderFormFields: (elements: UISchemaElement[] | (Category | Categorization)[], data: any, requiredFields: string[]) => (import("react/jsx-runtime").JSX.Element | null)[];
10
+ export declare const RenderFormFields: React.FC<RenderFormFieldsProps>;
11
+ export {};
@@ -0,0 +1,3 @@
1
+ import { JsonSchema } from '@jsonforms/core';
2
+ import Ajv from 'ajv8';
3
+ export declare const validateData: (jsonSchema: JsonSchema, data: unknown, ajv: Ajv) => boolean;