@oneblink/apps-react 4.2.0 → 4.3.0-beta.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/dist/OneBlinkFormBase.js +121 -134
  2. package/dist/OneBlinkFormBase.js.map +1 -1
  3. package/dist/components/CustomAccordion.d.ts +1 -1
  4. package/dist/components/Lists.d.ts +2 -2
  5. package/dist/components/renderer/AutocompleteDropdown.js +23 -14
  6. package/dist/components/renderer/AutocompleteDropdown.js.map +1 -1
  7. package/dist/components/renderer/LookupButton.d.ts +2 -1
  8. package/dist/components/renderer/LookupButton.js +2 -2
  9. package/dist/components/renderer/LookupButton.js.map +1 -1
  10. package/dist/components/renderer/LookupNotification.js +7 -6
  11. package/dist/components/renderer/LookupNotification.js.map +1 -1
  12. package/dist/components/renderer/OneBlinkFormElements.d.ts +3 -2
  13. package/dist/components/renderer/OneBlinkFormElements.js +13 -13
  14. package/dist/components/renderer/OneBlinkFormElements.js.map +1 -1
  15. package/dist/components/renderer/PageFormElements.js +29 -1
  16. package/dist/components/renderer/PageFormElements.js.map +1 -1
  17. package/dist/form-elements/FormElementABN.js +1 -1
  18. package/dist/form-elements/FormElementABN.js.map +1 -1
  19. package/dist/form-elements/FormElementAutocomplete.d.ts +2 -1
  20. package/dist/form-elements/FormElementAutocomplete.js +3 -2
  21. package/dist/form-elements/FormElementAutocomplete.js.map +1 -1
  22. package/dist/form-elements/FormElementBSB.js +1 -1
  23. package/dist/form-elements/FormElementBSB.js.map +1 -1
  24. package/dist/form-elements/FormElementBarcodeScanner.js +1 -1
  25. package/dist/form-elements/FormElementBarcodeScanner.js.map +1 -1
  26. package/dist/form-elements/FormElementCheckBoxes.d.ts +3 -2
  27. package/dist/form-elements/FormElementCheckBoxes.js +3 -2
  28. package/dist/form-elements/FormElementCheckBoxes.js.map +1 -1
  29. package/dist/form-elements/FormElementCompliance.d.ts +3 -2
  30. package/dist/form-elements/FormElementCompliance.js +2 -1
  31. package/dist/form-elements/FormElementCompliance.js.map +1 -1
  32. package/dist/form-elements/FormElementDate.js +1 -1
  33. package/dist/form-elements/FormElementDate.js.map +1 -1
  34. package/dist/form-elements/FormElementDateTime.js +1 -1
  35. package/dist/form-elements/FormElementDateTime.js.map +1 -1
  36. package/dist/form-elements/FormElementEmail.js +1 -1
  37. package/dist/form-elements/FormElementEmail.js.map +1 -1
  38. package/dist/form-elements/FormElementForm.d.ts +3 -2
  39. package/dist/form-elements/FormElementForm.js +17 -2
  40. package/dist/form-elements/FormElementForm.js.map +1 -1
  41. package/dist/form-elements/FormElementFreshdeskDependentField.d.ts +1 -1
  42. package/dist/form-elements/FormElementFreshdeskDependentField.js +27 -3
  43. package/dist/form-elements/FormElementFreshdeskDependentField.js.map +1 -1
  44. package/dist/form-elements/FormElementNumber.js +13 -19
  45. package/dist/form-elements/FormElementNumber.js.map +1 -1
  46. package/dist/form-elements/FormElementRadio.d.ts +3 -2
  47. package/dist/form-elements/FormElementRadio.js +2 -1
  48. package/dist/form-elements/FormElementRadio.js.map +1 -1
  49. package/dist/form-elements/FormElementRepeatableSet.d.ts +3 -2
  50. package/dist/form-elements/FormElementRepeatableSet.js +18 -4
  51. package/dist/form-elements/FormElementRepeatableSet.js.map +1 -1
  52. package/dist/form-elements/FormElementSection.d.ts +1 -1
  53. package/dist/form-elements/FormElementSection.js +16 -2
  54. package/dist/form-elements/FormElementSection.js.map +1 -1
  55. package/dist/form-elements/FormElementSelect.d.ts +3 -2
  56. package/dist/form-elements/FormElementSelect.js +3 -2
  57. package/dist/form-elements/FormElementSelect.js.map +1 -1
  58. package/dist/form-elements/FormElementTelephone.js +1 -1
  59. package/dist/form-elements/FormElementTelephone.js.map +1 -1
  60. package/dist/form-elements/FormElementText.js +1 -1
  61. package/dist/form-elements/FormElementText.js.map +1 -1
  62. package/dist/form-elements/FormElementTextarea.js +1 -1
  63. package/dist/form-elements/FormElementTextarea.js.map +1 -1
  64. package/dist/form-elements/FormElementTime.js +1 -1
  65. package/dist/form-elements/FormElementTime.js.map +1 -1
  66. package/dist/hooks/useDynamicOptionsLoaderState.d.ts +16 -7
  67. package/dist/hooks/useDynamicOptionsLoaderState.js +205 -45
  68. package/dist/hooks/useDynamicOptionsLoaderState.js.map +1 -1
  69. package/dist/hooks/useFormElementOptions.d.ts +3 -2
  70. package/dist/hooks/useFormElementOptions.js +3 -1
  71. package/dist/hooks/useFormElementOptions.js.map +1 -1
  72. package/dist/services/form-validation.js +1 -1
  73. package/dist/services/form-validation.js.map +1 -1
  74. package/dist/services/generateFreshdeskDependentFieldElements.js +2 -0
  75. package/dist/services/generateFreshdeskDependentFieldElements.js.map +1 -1
  76. package/dist/types/form.d.ts +1 -0
  77. package/dist/types/form.js.map +1 -1
  78. package/package.json +3 -3
@@ -1,60 +1,220 @@
1
1
  import * as React from 'react';
2
- import _cloneDeep from 'lodash.clonedeep';
3
- import { formElementsService } from '@oneblink/sdk-core';
4
- import { formService } from '@oneblink/apps';
5
- export default function useDynamicOptionsLoaderState(form, setFormSubmission) {
6
- const [state, setState] = React.useState(null);
2
+ import { formElementsService, typeCastService } from '@oneblink/sdk-core';
3
+ import { formService, localisationService, OneBlinkAppsError, } from '@oneblink/apps';
4
+ import useLoadDataState from './useLoadDataState';
5
+ import OneBlinkAppsErrorOriginalMessage from '../components/renderer/OneBlinkAppsErrorOriginalMessage';
6
+ import useFormDefinition from './useFormDefinition';
7
+ export const FormElementOptionsContext = React.createContext([]);
8
+ export const FreshdeskFieldsStateContext = React.createContext(undefined);
9
+ export function FormElementOptionsContextProvider({ children, }) {
10
+ const form = useFormDefinition();
11
+ const hasFreshdeskFields = React.useMemo(() => {
12
+ return !!formElementsService.findFormElement(form.elements, (formElement) => {
13
+ const formElementWithOptions = typeCastService.formElements.toOptionsElement(formElement);
14
+ return ((formElementWithOptions === null || formElementWithOptions === void 0 ? void 0 : formElementWithOptions.optionsType) === 'FRESHDESK_FIELD' &&
15
+ !!formElementWithOptions.freshdeskFieldName);
16
+ });
17
+ }, [form.elements]);
18
+ const loadFreshdeskFields = React.useCallback(async (abortSignal) => {
19
+ if (hasFreshdeskFields) {
20
+ return await formService.getFreshdeskFields(form.id, abortSignal);
21
+ }
22
+ return [];
23
+ }, [form.id, hasFreshdeskFields]);
24
+ const [freshdeskFieldsState] = useLoadDataState(loadFreshdeskFields);
25
+ const hasOptionsSets = React.useMemo(() => {
26
+ return !!formElementsService.findFormElement(form.elements, (formElement) => {
27
+ const formElementWithOptions = typeCastService.formElements.toOptionsElement(formElement);
28
+ return ((formElementWithOptions === null || formElementWithOptions === void 0 ? void 0 : formElementWithOptions.optionsType) === 'DYNAMIC' &&
29
+ !!formElementWithOptions.dynamicOptionSetId);
30
+ });
31
+ }, [form.elements]);
32
+ const loadFormElementOptionsSets = React.useCallback(async (abortSignal) => {
33
+ if (!hasOptionsSets) {
34
+ return [];
35
+ }
36
+ const formElementOptionsSets = await formService.getFormElementOptionsSets(form.organisationId, abortSignal);
37
+ return formElementOptionsSets.map((formElementOptionsSet) => ({
38
+ formElementOptionsSet,
39
+ }));
40
+ }, [form.organisationId, hasOptionsSets]);
41
+ const [optionsSetResultsState, , setOptionsSetResults] = useLoadDataState(loadFormElementOptionsSets);
42
+ const optionsSetResults = React.useMemo(() => {
43
+ if (optionsSetResultsState.status === 'SUCCESS') {
44
+ return optionsSetResultsState.result;
45
+ }
46
+ return [];
47
+ }, [optionsSetResultsState]);
48
+ const error = React.useMemo(() => {
49
+ var _a;
50
+ if (freshdeskFieldsState.status === 'ERROR') {
51
+ return freshdeskFieldsState.error instanceof OneBlinkAppsError
52
+ ? freshdeskFieldsState.error
53
+ : new OneBlinkAppsError('An unknown error has occurred', {
54
+ originalError: freshdeskFieldsState.error,
55
+ });
56
+ }
57
+ if (optionsSetResultsState.status === 'ERROR') {
58
+ return optionsSetResultsState.error instanceof OneBlinkAppsError
59
+ ? optionsSetResultsState.error
60
+ : new OneBlinkAppsError('An unknown error has occurred', {
61
+ originalError: optionsSetResultsState.error,
62
+ });
63
+ }
64
+ for (const optionsSetResult of optionsSetResults) {
65
+ if (((_a = optionsSetResult.result) === null || _a === void 0 ? void 0 : _a.type) === 'ERROR') {
66
+ return optionsSetResult.result.error;
67
+ }
68
+ }
69
+ }, [freshdeskFieldsState, optionsSetResults, optionsSetResultsState]);
70
+ if (error) {
71
+ return (React.createElement(React.Fragment, null,
72
+ React.createElement("div", { className: "has-text-centered" },
73
+ React.createElement("i", { className: "material-icons has-text-warning icon-x-large" }, "error"),
74
+ React.createElement("h3", { className: "title is-3" }, error.title),
75
+ React.createElement("p", null, error.message),
76
+ React.createElement("p", { className: "has-text-grey" }, localisationService.formatDatetimeLong(new Date()))),
77
+ React.createElement(OneBlinkAppsErrorOriginalMessage, { error: error.originalError })));
78
+ }
79
+ return (React.createElement(React.Fragment, null,
80
+ optionsSetResults.map((optionsSetResult) => (React.createElement(React.Fragment, { key: optionsSetResult.formElementOptionsSet.id },
81
+ React.createElement(LoadOptionsSet, { optionsSetResult: optionsSetResult, form: form, setOptionsSetResults: setOptionsSetResults })))),
82
+ React.createElement(FormElementOptionsContext.Provider, { value: optionsSetResults },
83
+ React.createElement(FreshdeskFieldsStateContext.Provider, { value: freshdeskFieldsState }, children))));
84
+ }
85
+ const LoadOptionsSet = React.memo(function LoadOptionsSet({ form, optionsSetResult, setOptionsSetResults, }) {
86
+ const hasOptionsSet = React.useMemo(() => {
87
+ return !!formElementsService.findFormElement(form.elements, (formElement) => {
88
+ const formElementWithOptions = typeCastService.formElements.toOptionsElement(formElement);
89
+ return ((formElementWithOptions === null || formElementWithOptions === void 0 ? void 0 : formElementWithOptions.optionsType) === 'DYNAMIC' &&
90
+ formElementWithOptions.dynamicOptionSetId ===
91
+ optionsSetResult.formElementOptionsSet.id);
92
+ });
93
+ }, [form.elements, optionsSetResult.formElementOptionsSet.id]);
94
+ const setOptionsSetResult = React.useCallback((result) => {
95
+ setOptionsSetResults((currentOptionsSetResults) => {
96
+ return currentOptionsSetResults.map((currentOptionsSetResult) => {
97
+ if (currentOptionsSetResult.formElementOptionsSet.id ===
98
+ optionsSetResult.formElementOptionsSet.id) {
99
+ return {
100
+ ...optionsSetResult,
101
+ result,
102
+ };
103
+ }
104
+ else {
105
+ return currentOptionsSetResult;
106
+ }
107
+ });
108
+ });
109
+ }, [optionsSetResult, setOptionsSetResults]);
7
110
  React.useEffect(() => {
8
- if (state) {
111
+ if (!hasOptionsSet || optionsSetResult.result) {
9
112
  return;
10
113
  }
11
114
  const abortController = new AbortController();
12
115
  (async () => {
13
- const optionsByElementId = await formService.getFormElementDynamicOptions(form);
14
- if (abortController.signal.aborted || !optionsByElementId.length) {
15
- return;
16
- }
17
- const nonOkResponse = optionsByElementId.find((optionsForElementId) => optionsForElementId.type === 'ERROR');
18
- if (nonOkResponse && nonOkResponse.type === 'ERROR') {
19
- setState({
20
- elementId: nonOkResponse.elementId,
21
- error: nonOkResponse.error,
22
- });
23
- return;
116
+ try {
117
+ const result = await formService.getFormElementOptionsSetOptions(optionsSetResult.formElementOptionsSet, form.formsAppEnvironmentId, abortController.signal);
118
+ if (!abortController.signal.aborted) {
119
+ setOptionsSetResult(result);
120
+ }
24
121
  }
25
- setFormSubmission((currentFormSubmission) => {
26
- const clonedForm = _cloneDeep(currentFormSubmission.definition);
27
- for (const optionsForElementId of optionsByElementId) {
28
- formElementsService.forEachFormElementWithOptions(clonedForm.elements, (formElement) => {
29
- if (formElement.id === optionsForElementId.elementId) {
30
- switch (optionsForElementId.type) {
31
- case 'OPTIONS': {
32
- formElement.options = optionsForElementId.options;
33
- break;
34
- }
35
- case 'SEARCH': {
36
- if (formElement.type === 'autocomplete') {
37
- formElement.optionsType = 'SEARCH';
38
- formElement.searchUrl = optionsForElementId.url;
39
- formElement.searchQuerystringParameter =
40
- optionsForElementId.searchQuerystringParameter;
41
- }
42
- break;
43
- }
44
- }
45
- }
122
+ catch (error) {
123
+ if (!abortController.signal.aborted) {
124
+ setOptionsSetResult({
125
+ type: 'ERROR',
126
+ error: new OneBlinkAppsError(error instanceof Error
127
+ ? error.message
128
+ : 'An unknown error has occurred', {
129
+ originalError: error instanceof Error ? error : undefined,
130
+ }),
46
131
  });
47
132
  }
48
- return {
49
- ...currentFormSubmission,
50
- definition: clonedForm,
51
- };
52
- });
133
+ }
53
134
  })();
54
135
  return () => {
55
136
  abortController.abort();
56
137
  };
57
- }, [form, setFormSubmission, state]);
58
- return state;
138
+ }, [
139
+ form.formsAppEnvironmentId,
140
+ hasOptionsSet,
141
+ optionsSetResult.formElementOptionsSet,
142
+ optionsSetResult.result,
143
+ setOptionsSetResult,
144
+ ]);
145
+ return React.createElement(React.Fragment, null);
146
+ });
147
+ export function useLoadDynamicOptionsEffect(formElement, onUpdateFormElements) {
148
+ const form = useFormDefinition();
149
+ const optionsSetResults = React.useContext(FormElementOptionsContext);
150
+ const freshdeskFieldsState = React.useContext(FreshdeskFieldsStateContext);
151
+ const freshdeskFieldOptionsResult = React.useMemo(() => {
152
+ if ((freshdeskFieldsState === null || freshdeskFieldsState === void 0 ? void 0 : freshdeskFieldsState.status) === 'SUCCESS' &&
153
+ // We can stop here if the options are not coming from freshdesk
154
+ formElement.optionsType === 'FRESHDESK_FIELD' &&
155
+ // If the element already has options, we don't need to set them again
156
+ !Array.isArray(formElement.options)) {
157
+ return formService.parseFreshdeskFieldOptions(freshdeskFieldsState.result, formElement);
158
+ }
159
+ }, [formElement, freshdeskFieldsState]);
160
+ const optionsSetResult = React.useMemo(() => {
161
+ if (
162
+ // We can stop here if the options are not dynamic
163
+ formElement.optionsType !== 'DYNAMIC' ||
164
+ // If the element already has options, we don't need to set them again
165
+ Array.isArray(formElement.options)) {
166
+ return;
167
+ }
168
+ return optionsSetResults.find((optionsSetResult) => optionsSetResult.formElementOptionsSet.id ===
169
+ formElement.dynamicOptionSetId && optionsSetResult.result);
170
+ }, [
171
+ formElement.dynamicOptionSetId,
172
+ formElement.options,
173
+ formElement.optionsType,
174
+ optionsSetResults,
175
+ ]);
176
+ React.useEffect(() => {
177
+ if (!optionsSetResult && !freshdeskFieldOptionsResult) {
178
+ return;
179
+ }
180
+ onUpdateFormElements((formElements) => {
181
+ return formElements.map((existingFormElement) => {
182
+ var _a;
183
+ if (existingFormElement.id === formElement.id) {
184
+ switch ((_a = optionsSetResult === null || optionsSetResult === void 0 ? void 0 : optionsSetResult.result) === null || _a === void 0 ? void 0 : _a.type) {
185
+ case 'SEARCH': {
186
+ if (formElement.type === 'autocomplete') {
187
+ return {
188
+ ...existingFormElement,
189
+ optionsType: 'SEARCH',
190
+ searchUrl: optionsSetResult.result.url,
191
+ searchQuerystringParameter: optionsSetResult.result.searchQuerystringParameter,
192
+ };
193
+ }
194
+ break;
195
+ }
196
+ case 'OPTIONS': {
197
+ return formService.parseFormElementOptions(form, formElement, optionsSetResult.result.options);
198
+ }
199
+ }
200
+ if (freshdeskFieldOptionsResult) {
201
+ return {
202
+ ...existingFormElement,
203
+ options: freshdeskFieldOptionsResult.type === 'OPTIONS'
204
+ ? freshdeskFieldOptionsResult.options
205
+ : [],
206
+ };
207
+ }
208
+ }
209
+ return existingFormElement;
210
+ });
211
+ });
212
+ }, [
213
+ form,
214
+ formElement,
215
+ freshdeskFieldOptionsResult,
216
+ onUpdateFormElements,
217
+ optionsSetResult,
218
+ ]);
59
219
  }
60
220
  //# sourceMappingURL=useDynamicOptionsLoaderState.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"useDynamicOptionsLoaderState.js","sourceRoot":"","sources":["../../src/hooks/useDynamicOptionsLoaderState.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,UAAU,MAAM,kBAAkB,CAAA;AACzC,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAA;AACxD,OAAO,EAAE,WAAW,EAAqB,MAAM,gBAAgB,CAAA;AAI/D,MAAM,CAAC,OAAO,UAAU,4BAA4B,CAClD,IAAoB,EACpB,iBAAoC;IAEpC,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,KAAK,CAAC,QAAQ,CAG9B,IAAI,CAAC,CAAA;IACf,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACnB,IAAI,KAAK,EAAE;YACT,OAAM;SACP;QAED,MAAM,eAAe,GAAG,IAAI,eAAe,EAAE,CAE5C;QAAA,CAAC,KAAK,IAAI,EAAE;YACX,MAAM,kBAAkB,GAAG,MAAM,WAAW,CAAC,4BAA4B,CACvE,IAAI,CACL,CAAA;YAED,IAAI,eAAe,CAAC,MAAM,CAAC,OAAO,IAAI,CAAC,kBAAkB,CAAC,MAAM,EAAE;gBAChE,OAAM;aACP;YAED,MAAM,aAAa,GAAG,kBAAkB,CAAC,IAAI,CAC3C,CAAC,mBAAmB,EAAE,EAAE,CAAC,mBAAmB,CAAC,IAAI,KAAK,OAAO,CAC9D,CAAA;YACD,IAAI,aAAa,IAAI,aAAa,CAAC,IAAI,KAAK,OAAO,EAAE;gBACnD,QAAQ,CAAC;oBACP,SAAS,EAAE,aAAa,CAAC,SAAS;oBAClC,KAAK,EAAE,aAAa,CAAC,KAAK;iBAC3B,CAAC,CAAA;gBACF,OAAM;aACP;YAED,iBAAiB,CAAC,CAAC,qBAAqB,EAAE,EAAE;gBAC1C,MAAM,UAAU,GAAmB,UAAU,CAC3C,qBAAqB,CAAC,UAAU,CACjC,CAAA;gBACD,KAAK,MAAM,mBAAmB,IAAI,kBAAkB,EAAE;oBACpD,mBAAmB,CAAC,6BAA6B,CAC/C,UAAU,CAAC,QAAQ,EACnB,CAAC,WAAW,EAAE,EAAE;wBACd,IAAI,WAAW,CAAC,EAAE,KAAK,mBAAmB,CAAC,SAAS,EAAE;4BACpD,QAAQ,mBAAmB,CAAC,IAAI,EAAE;gCAChC,KAAK,SAAS,CAAC,CAAC;oCACd,WAAW,CAAC,OAAO,GAAG,mBAAmB,CAAC,OAAO,CAAA;oCACjD,MAAK;iCACN;gCACD,KAAK,QAAQ,CAAC,CAAC;oCACb,IAAI,WAAW,CAAC,IAAI,KAAK,cAAc,EAAE;wCACvC,WAAW,CAAC,WAAW,GAAG,QAAQ,CAAA;wCAClC,WAAW,CAAC,SAAS,GAAG,mBAAmB,CAAC,GAAG,CAAA;wCAC/C,WAAW,CAAC,0BAA0B;4CACpC,mBAAmB,CAAC,0BAA0B,CAAA;qCACjD;oCACD,MAAK;iCACN;6BACF;yBACF;oBACH,CAAC,CACF,CAAA;iBACF;gBACD,OAAO;oBACL,GAAG,qBAAqB;oBACxB,UAAU,EAAE,UAAU;iBACvB,CAAA;YACH,CAAC,CAAC,CAAA;QACJ,CAAC,CAAC,EAAE,CAAA;QAEJ,OAAO,GAAG,EAAE;YACV,eAAe,CAAC,KAAK,EAAE,CAAA;QACzB,CAAC,CAAA;IACH,CAAC,EAAE,CAAC,IAAI,EAAE,iBAAiB,EAAE,KAAK,CAAC,CAAC,CAAA;IAEpC,OAAO,KAAK,CAAA;AACd,CAAC","sourcesContent":["import * as React from 'react'\nimport _cloneDeep from 'lodash.clonedeep'\nimport { formElementsService } from '@oneblink/sdk-core'\nimport { formService, OneBlinkAppsError } from '@oneblink/apps'\nimport { FormTypes } from '@oneblink/types'\nimport { SetFormSubmission } from '../types/form'\n\nexport default function useDynamicOptionsLoaderState(\n form: FormTypes.Form,\n setFormSubmission: SetFormSubmission,\n) {\n const [state, setState] = React.useState<{\n elementId: string\n error: OneBlinkAppsError\n } | null>(null)\n React.useEffect(() => {\n if (state) {\n return\n }\n\n const abortController = new AbortController()\n\n ;(async () => {\n const optionsByElementId = await formService.getFormElementDynamicOptions(\n form,\n )\n\n if (abortController.signal.aborted || !optionsByElementId.length) {\n return\n }\n\n const nonOkResponse = optionsByElementId.find(\n (optionsForElementId) => optionsForElementId.type === 'ERROR',\n )\n if (nonOkResponse && nonOkResponse.type === 'ERROR') {\n setState({\n elementId: nonOkResponse.elementId,\n error: nonOkResponse.error,\n })\n return\n }\n\n setFormSubmission((currentFormSubmission) => {\n const clonedForm: FormTypes.Form = _cloneDeep(\n currentFormSubmission.definition,\n )\n for (const optionsForElementId of optionsByElementId) {\n formElementsService.forEachFormElementWithOptions(\n clonedForm.elements,\n (formElement) => {\n if (formElement.id === optionsForElementId.elementId) {\n switch (optionsForElementId.type) {\n case 'OPTIONS': {\n formElement.options = optionsForElementId.options\n break\n }\n case 'SEARCH': {\n if (formElement.type === 'autocomplete') {\n formElement.optionsType = 'SEARCH'\n formElement.searchUrl = optionsForElementId.url\n formElement.searchQuerystringParameter =\n optionsForElementId.searchQuerystringParameter\n }\n break\n }\n }\n }\n },\n )\n }\n return {\n ...currentFormSubmission,\n definition: clonedForm,\n }\n })\n })()\n\n return () => {\n abortController.abort()\n }\n }, [form, setFormSubmission, state])\n\n return state\n}\n"]}
1
+ {"version":3,"file":"useDynamicOptionsLoaderState.js","sourceRoot":"","sources":["../../src/hooks/useDynamicOptionsLoaderState.tsx"],"names":[],"mappings":"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","sourcesContent":["import * as React from 'react'\nimport { formElementsService, typeCastService } from '@oneblink/sdk-core'\nimport {\n formService,\n localisationService,\n OneBlinkAppsError,\n} from '@oneblink/apps'\nimport { FormTypes, FreshdeskTypes } from '@oneblink/types'\nimport useLoadDataState, { LoadDataState } from './useLoadDataState'\nimport OneBlinkAppsErrorOriginalMessage from '../components/renderer/OneBlinkAppsErrorOriginalMessage'\nimport useFormDefinition from './useFormDefinition'\nimport { UpdateFormElementsHandler } from '../typedoc'\n\ntype OptionsSetResult = {\n formElementOptionsSet: FormTypes.FormElementOptionSet\n result?: formService.FormElementOptionsSetResult\n}\n\nexport const FormElementOptionsContext = React.createContext<\n OptionsSetResult[]\n>([])\nexport const FreshdeskFieldsStateContext = React.createContext<\n LoadDataState<FreshdeskTypes.FreshdeskField[]> | undefined\n>(undefined)\n\nexport function FormElementOptionsContextProvider({\n children,\n}: {\n children: React.ReactNode\n}) {\n const form = useFormDefinition()\n\n const hasFreshdeskFields = React.useMemo<boolean>(() => {\n return !!formElementsService.findFormElement(\n form.elements,\n (formElement) => {\n const formElementWithOptions =\n typeCastService.formElements.toOptionsElement(formElement)\n return (\n formElementWithOptions?.optionsType === 'FRESHDESK_FIELD' &&\n !!formElementWithOptions.freshdeskFieldName\n )\n },\n )\n }, [form.elements])\n\n const loadFreshdeskFields = React.useCallback(\n async (abortSignal): Promise<FreshdeskTypes.FreshdeskField[]> => {\n if (hasFreshdeskFields) {\n return await formService.getFreshdeskFields(form.id, abortSignal)\n }\n return []\n },\n [form.id, hasFreshdeskFields],\n )\n\n const [freshdeskFieldsState] = useLoadDataState(loadFreshdeskFields)\n\n const hasOptionsSets = React.useMemo<boolean>(() => {\n return !!formElementsService.findFormElement(\n form.elements,\n (formElement) => {\n const formElementWithOptions =\n typeCastService.formElements.toOptionsElement(formElement)\n return (\n formElementWithOptions?.optionsType === 'DYNAMIC' &&\n !!formElementWithOptions.dynamicOptionSetId\n )\n },\n )\n }, [form.elements])\n\n const loadFormElementOptionsSets = React.useCallback(\n async (abortSignal): Promise<OptionsSetResult[]> => {\n if (!hasOptionsSets) {\n return []\n }\n const formElementOptionsSets =\n await formService.getFormElementOptionsSets(\n form.organisationId,\n abortSignal,\n )\n return formElementOptionsSets.map<OptionsSetResult>(\n (formElementOptionsSet) => ({\n formElementOptionsSet,\n }),\n )\n },\n [form.organisationId, hasOptionsSets],\n )\n\n const [optionsSetResultsState, , setOptionsSetResults] = useLoadDataState(\n loadFormElementOptionsSets,\n )\n\n const optionsSetResults = React.useMemo(() => {\n if (optionsSetResultsState.status === 'SUCCESS') {\n return optionsSetResultsState.result\n }\n return []\n }, [optionsSetResultsState])\n\n const error = React.useMemo<OneBlinkAppsError | undefined>(() => {\n if (freshdeskFieldsState.status === 'ERROR') {\n return freshdeskFieldsState.error instanceof OneBlinkAppsError\n ? freshdeskFieldsState.error\n : new OneBlinkAppsError('An unknown error has occurred', {\n originalError: freshdeskFieldsState.error,\n })\n }\n if (optionsSetResultsState.status === 'ERROR') {\n return optionsSetResultsState.error instanceof OneBlinkAppsError\n ? optionsSetResultsState.error\n : new OneBlinkAppsError('An unknown error has occurred', {\n originalError: optionsSetResultsState.error,\n })\n }\n for (const optionsSetResult of optionsSetResults) {\n if (optionsSetResult.result?.type === 'ERROR') {\n return optionsSetResult.result.error\n }\n }\n }, [freshdeskFieldsState, optionsSetResults, optionsSetResultsState])\n\n if (error) {\n return (\n <>\n <div className=\"has-text-centered\">\n <i className=\"material-icons has-text-warning icon-x-large\">error</i>\n <h3 className=\"title is-3\">{error.title}</h3>\n <p>{error.message}</p>\n <p className=\"has-text-grey\">\n {localisationService.formatDatetimeLong(new Date())}\n </p>\n </div>\n\n <OneBlinkAppsErrorOriginalMessage error={error.originalError} />\n </>\n )\n }\n\n return (\n <>\n {optionsSetResults.map((optionsSetResult) => (\n <React.Fragment key={optionsSetResult.formElementOptionsSet.id}>\n <LoadOptionsSet\n optionsSetResult={optionsSetResult}\n form={form}\n setOptionsSetResults={setOptionsSetResults}\n />\n </React.Fragment>\n ))}\n <FormElementOptionsContext.Provider value={optionsSetResults}>\n <FreshdeskFieldsStateContext.Provider value={freshdeskFieldsState}>\n {children}\n </FreshdeskFieldsStateContext.Provider>\n </FormElementOptionsContext.Provider>\n </>\n )\n}\n\nconst LoadOptionsSet = React.memo(function LoadOptionsSet({\n form,\n optionsSetResult,\n setOptionsSetResults,\n}: {\n form: FormTypes.Form\n optionsSetResult: OptionsSetResult\n setOptionsSetResults: React.Dispatch<React.SetStateAction<OptionsSetResult[]>>\n}) {\n const hasOptionsSet = React.useMemo<boolean>(() => {\n return !!formElementsService.findFormElement(\n form.elements,\n (formElement) => {\n const formElementWithOptions =\n typeCastService.formElements.toOptionsElement(formElement)\n return (\n formElementWithOptions?.optionsType === 'DYNAMIC' &&\n formElementWithOptions.dynamicOptionSetId ===\n optionsSetResult.formElementOptionsSet.id\n )\n },\n )\n }, [form.elements, optionsSetResult.formElementOptionsSet.id])\n\n const setOptionsSetResult = React.useCallback(\n (result: OptionsSetResult['result']) => {\n setOptionsSetResults((currentOptionsSetResults) => {\n return currentOptionsSetResults.map((currentOptionsSetResult) => {\n if (\n currentOptionsSetResult.formElementOptionsSet.id ===\n optionsSetResult.formElementOptionsSet.id\n ) {\n return {\n ...optionsSetResult,\n result,\n }\n } else {\n return currentOptionsSetResult\n }\n })\n })\n },\n [optionsSetResult, setOptionsSetResults],\n )\n\n React.useEffect(() => {\n if (!hasOptionsSet || optionsSetResult.result) {\n return\n }\n\n const abortController = new AbortController()\n\n ;(async () => {\n try {\n const result = await formService.getFormElementOptionsSetOptions(\n optionsSetResult.formElementOptionsSet,\n form.formsAppEnvironmentId,\n abortController.signal,\n )\n if (!abortController.signal.aborted) {\n setOptionsSetResult(result)\n }\n } catch (error) {\n if (!abortController.signal.aborted) {\n setOptionsSetResult({\n type: 'ERROR',\n error: new OneBlinkAppsError(\n error instanceof Error\n ? error.message\n : 'An unknown error has occurred',\n {\n originalError: error instanceof Error ? error : undefined,\n },\n ),\n })\n }\n }\n })()\n\n return () => {\n abortController.abort()\n }\n }, [\n form.formsAppEnvironmentId,\n hasOptionsSet,\n optionsSetResult.formElementOptionsSet,\n optionsSetResult.result,\n setOptionsSetResult,\n ])\n\n return <></>\n})\n\nexport function useLoadDynamicOptionsEffect(\n formElement: FormTypes.FormElementWithOptions,\n onUpdateFormElements: UpdateFormElementsHandler,\n) {\n const form = useFormDefinition()\n const optionsSetResults = React.useContext(FormElementOptionsContext)\n const freshdeskFieldsState = React.useContext(FreshdeskFieldsStateContext)\n\n const freshdeskFieldOptionsResult = React.useMemo(() => {\n if (\n freshdeskFieldsState?.status === 'SUCCESS' &&\n // We can stop here if the options are not coming from freshdesk\n formElement.optionsType === 'FRESHDESK_FIELD' &&\n // If the element already has options, we don't need to set them again\n !Array.isArray(formElement.options)\n ) {\n return formService.parseFreshdeskFieldOptions(\n freshdeskFieldsState.result,\n formElement,\n )\n }\n }, [formElement, freshdeskFieldsState])\n\n const optionsSetResult = React.useMemo<OptionsSetResult | undefined>(() => {\n if (\n // We can stop here if the options are not dynamic\n formElement.optionsType !== 'DYNAMIC' ||\n // If the element already has options, we don't need to set them again\n Array.isArray(formElement.options)\n ) {\n return\n }\n return optionsSetResults.find(\n (optionsSetResult) =>\n optionsSetResult.formElementOptionsSet.id ===\n formElement.dynamicOptionSetId && optionsSetResult.result,\n )\n }, [\n formElement.dynamicOptionSetId,\n formElement.options,\n formElement.optionsType,\n optionsSetResults,\n ])\n\n React.useEffect(() => {\n if (!optionsSetResult && !freshdeskFieldOptionsResult) {\n return\n }\n\n onUpdateFormElements((formElements) => {\n return formElements.map((existingFormElement) => {\n if (existingFormElement.id === formElement.id) {\n switch (optionsSetResult?.result?.type) {\n case 'SEARCH': {\n if (formElement.type === 'autocomplete') {\n return {\n ...existingFormElement,\n optionsType: 'SEARCH',\n searchUrl: optionsSetResult.result.url,\n searchQuerystringParameter:\n optionsSetResult.result.searchQuerystringParameter,\n }\n }\n break\n }\n case 'OPTIONS': {\n return formService.parseFormElementOptions(\n form,\n formElement,\n optionsSetResult.result.options,\n )\n }\n }\n\n if (freshdeskFieldOptionsResult) {\n return {\n ...existingFormElement,\n options:\n freshdeskFieldOptionsResult.type === 'OPTIONS'\n ? freshdeskFieldOptionsResult.options\n : [],\n }\n }\n }\n\n return existingFormElement\n })\n })\n }, [\n form,\n formElement,\n freshdeskFieldOptionsResult,\n onUpdateFormElements,\n optionsSetResult,\n ])\n}\n"]}
@@ -1,9 +1,10 @@
1
1
  import { FormTypes } from '@oneblink/types';
2
- import { FormElementValueChangeHandler, FormElementConditionallyShownElement } from '../types/form';
3
- export default function useFormElementOptions<T>({ element, value, onChange, conditionallyShownOptionsElement, onFilter, }: {
2
+ import { FormElementValueChangeHandler, FormElementConditionallyShownElement, UpdateFormElementsHandler } from '../types/form';
3
+ export default function useFormElementOptions<T>({ element, value, onChange, conditionallyShownOptionsElement, onFilter, onUpdateFormElements, }: {
4
4
  element: FormTypes.FormElementWithOptions;
5
5
  value: unknown | undefined;
6
6
  onChange: FormElementValueChangeHandler<T>;
7
7
  conditionallyShownOptionsElement: FormElementConditionallyShownElement | undefined;
8
8
  onFilter?: (choiceElementOption: FormTypes.ChoiceElementOption) => boolean;
9
+ onUpdateFormElements: UpdateFormElementsHandler;
9
10
  }): FormTypes.ChoiceElementOption[];
@@ -1,5 +1,6 @@
1
1
  import * as React from 'react';
2
- export default function useFormElementOptions({ element, value, onChange, conditionallyShownOptionsElement, onFilter, }) {
2
+ import { useLoadDynamicOptionsEffect } from './useDynamicOptionsLoaderState';
3
+ export default function useFormElementOptions({ element, value, onChange, conditionallyShownOptionsElement, onFilter, onUpdateFormElements, }) {
3
4
  const conditionallyShownOptions = conditionallyShownOptionsElement === null || conditionallyShownOptionsElement === void 0 ? void 0 : conditionallyShownOptionsElement.options;
4
5
  //options that are shown due to conditional logic
5
6
  const shownOptions = React.useMemo(() => {
@@ -48,6 +49,7 @@ export default function useFormElementOptions({ element, value, onChange, condit
48
49
  value,
49
50
  conditionallyShownOptionsElement === null || conditionallyShownOptionsElement === void 0 ? void 0 : conditionallyShownOptionsElement.dependencyIsLoading,
50
51
  ]);
52
+ useLoadDynamicOptionsEffect(element, onUpdateFormElements);
51
53
  return filteredOptions;
52
54
  }
53
55
  //# sourceMappingURL=useFormElementOptions.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"useFormElementOptions.js","sourceRoot":"","sources":["../../src/hooks/useFormElementOptions.ts"],"names":[],"mappings":"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","sourcesContent":["import { FormTypes } from '@oneblink/types'\nimport * as React from 'react'\nimport {\n FormElementValueChangeHandler,\n FormElementConditionallyShownElement,\n} from '../types/form'\n\nexport default function useFormElementOptions<T>({\n element,\n value,\n onChange,\n conditionallyShownOptionsElement,\n onFilter,\n}: {\n element: FormTypes.FormElementWithOptions\n value: unknown | undefined\n onChange: FormElementValueChangeHandler<T>\n conditionallyShownOptionsElement:\n | FormElementConditionallyShownElement\n | undefined\n onFilter?: (choiceElementOption: FormTypes.ChoiceElementOption) => boolean\n}) {\n const conditionallyShownOptions = conditionallyShownOptionsElement?.options\n //options that are shown due to conditional logic\n const shownOptions = React.useMemo<FormTypes.ChoiceElementOption[]>(() => {\n if (!element.options) {\n return []\n }\n if (!conditionallyShownOptions && !onFilter) {\n return element.options\n }\n return element.options.filter((option) => {\n return (\n !conditionallyShownOptions ||\n conditionallyShownOptions.some(({ id }) => id === option.id)\n )\n })\n }, [conditionallyShownOptions, element.options, onFilter])\n\n //options that are shown based on conditional logic and user input\n const filteredOptions = React.useMemo<FormTypes.ChoiceElementOption[]>(() => {\n const reducedOptions = shownOptions.filter(\n (option) => !onFilter || (onFilter(option) && !option.displayAlways),\n )\n if (element.type === 'autocomplete') {\n const alwaysShownOptions = shownOptions.filter(\n (option) => option.displayAlways,\n )\n reducedOptions.push(...alwaysShownOptions)\n }\n return reducedOptions\n }, [shownOptions, element.type, onFilter])\n\n React.useEffect(() => {\n if (\n !element.options ||\n conditionallyShownOptionsElement?.dependencyIsLoading\n ) {\n return\n }\n\n if (\n typeof value === 'string' &&\n value &&\n !shownOptions.some((option) => value === option.value)\n ) {\n onChange(element, undefined)\n return\n }\n\n if (Array.isArray(value)) {\n const newValue = value.filter((selectedValue) =>\n shownOptions.some((option) => selectedValue === option.value),\n )\n if (newValue.length !== value.length) {\n const newValueArray = newValue.length ? newValue : undefined\n onChange(element, newValueArray as T | undefined)\n }\n }\n }, [\n element,\n shownOptions,\n onChange,\n value,\n conditionallyShownOptionsElement?.dependencyIsLoading,\n ])\n\n return filteredOptions\n}\n"]}
1
+ {"version":3,"file":"useFormElementOptions.js","sourceRoot":"","sources":["../../src/hooks/useFormElementOptions.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAM9B,OAAO,EAAE,2BAA2B,EAAE,MAAM,gCAAgC,CAAA;AAE5E,MAAM,CAAC,OAAO,UAAU,qBAAqB,CAAI,EAC/C,OAAO,EACP,KAAK,EACL,QAAQ,EACR,gCAAgC,EAChC,QAAQ,EACR,oBAAoB,GAUrB;IACC,MAAM,yBAAyB,GAAG,gCAAgC,aAAhC,gCAAgC,uBAAhC,gCAAgC,CAAE,OAAO,CAAA;IAC3E,iDAAiD;IACjD,MAAM,YAAY,GAAG,KAAK,CAAC,OAAO,CAAkC,GAAG,EAAE;QACvE,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE;YACpB,OAAO,EAAE,CAAA;SACV;QACD,IAAI,CAAC,yBAAyB,IAAI,CAAC,QAAQ,EAAE;YAC3C,OAAO,OAAO,CAAC,OAAO,CAAA;SACvB;QACD,OAAO,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE;YACvC,OAAO,CACL,CAAC,yBAAyB;gBAC1B,yBAAyB,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,KAAK,MAAM,CAAC,EAAE,CAAC,CAC7D,CAAA;QACH,CAAC,CAAC,CAAA;IACJ,CAAC,EAAE,CAAC,yBAAyB,EAAE,OAAO,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAA;IAE1D,kEAAkE;IAClE,MAAM,eAAe,GAAG,KAAK,CAAC,OAAO,CAAkC,GAAG,EAAE;QAC1E,MAAM,cAAc,GAAG,YAAY,CAAC,MAAM,CACxC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,QAAQ,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,CACrE,CAAA;QACD,IAAI,OAAO,CAAC,IAAI,KAAK,cAAc,EAAE;YACnC,MAAM,kBAAkB,GAAG,YAAY,CAAC,MAAM,CAC5C,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,aAAa,CACjC,CAAA;YACD,cAAc,CAAC,IAAI,CAAC,GAAG,kBAAkB,CAAC,CAAA;SAC3C;QACD,OAAO,cAAc,CAAA;IACvB,CAAC,EAAE,CAAC,YAAY,EAAE,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAA;IAE1C,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACnB,IACE,CAAC,OAAO,CAAC,OAAO;aAChB,gCAAgC,aAAhC,gCAAgC,uBAAhC,gCAAgC,CAAE,mBAAmB,CAAA,EACrD;YACA,OAAM;SACP;QAED,IACE,OAAO,KAAK,KAAK,QAAQ;YACzB,KAAK;YACL,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,KAAK,KAAK,MAAM,CAAC,KAAK,CAAC,EACtD;YACA,QAAQ,CAAC,OAAO,EAAE,SAAS,CAAC,CAAA;YAC5B,OAAM;SACP;QAED,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;YACxB,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,aAAa,EAAE,EAAE,CAC9C,YAAY,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,aAAa,KAAK,MAAM,CAAC,KAAK,CAAC,CAC9D,CAAA;YACD,IAAI,QAAQ,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM,EAAE;gBACpC,MAAM,aAAa,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAA;gBAC5D,QAAQ,CAAC,OAAO,EAAE,aAA8B,CAAC,CAAA;aAClD;SACF;IACH,CAAC,EAAE;QACD,OAAO;QACP,YAAY;QACZ,QAAQ;QACR,KAAK;QACL,gCAAgC,aAAhC,gCAAgC,uBAAhC,gCAAgC,CAAE,mBAAmB;KACtD,CAAC,CAAA;IAEF,2BAA2B,CAAC,OAAO,EAAE,oBAAoB,CAAC,CAAA;IAE1D,OAAO,eAAe,CAAA;AACxB,CAAC","sourcesContent":["import { FormTypes } from '@oneblink/types'\nimport * as React from 'react'\nimport {\n FormElementValueChangeHandler,\n FormElementConditionallyShownElement,\n UpdateFormElementsHandler,\n} from '../types/form'\nimport { useLoadDynamicOptionsEffect } from './useDynamicOptionsLoaderState'\n\nexport default function useFormElementOptions<T>({\n element,\n value,\n onChange,\n conditionallyShownOptionsElement,\n onFilter,\n onUpdateFormElements,\n}: {\n element: FormTypes.FormElementWithOptions\n value: unknown | undefined\n onChange: FormElementValueChangeHandler<T>\n conditionallyShownOptionsElement:\n | FormElementConditionallyShownElement\n | undefined\n onFilter?: (choiceElementOption: FormTypes.ChoiceElementOption) => boolean\n onUpdateFormElements: UpdateFormElementsHandler\n}) {\n const conditionallyShownOptions = conditionallyShownOptionsElement?.options\n //options that are shown due to conditional logic\n const shownOptions = React.useMemo<FormTypes.ChoiceElementOption[]>(() => {\n if (!element.options) {\n return []\n }\n if (!conditionallyShownOptions && !onFilter) {\n return element.options\n }\n return element.options.filter((option) => {\n return (\n !conditionallyShownOptions ||\n conditionallyShownOptions.some(({ id }) => id === option.id)\n )\n })\n }, [conditionallyShownOptions, element.options, onFilter])\n\n //options that are shown based on conditional logic and user input\n const filteredOptions = React.useMemo<FormTypes.ChoiceElementOption[]>(() => {\n const reducedOptions = shownOptions.filter(\n (option) => !onFilter || (onFilter(option) && !option.displayAlways),\n )\n if (element.type === 'autocomplete') {\n const alwaysShownOptions = shownOptions.filter(\n (option) => option.displayAlways,\n )\n reducedOptions.push(...alwaysShownOptions)\n }\n return reducedOptions\n }, [shownOptions, element.type, onFilter])\n\n React.useEffect(() => {\n if (\n !element.options ||\n conditionallyShownOptionsElement?.dependencyIsLoading\n ) {\n return\n }\n\n if (\n typeof value === 'string' &&\n value &&\n !shownOptions.some((option) => value === option.value)\n ) {\n onChange(element, undefined)\n return\n }\n\n if (Array.isArray(value)) {\n const newValue = value.filter((selectedValue) =>\n shownOptions.some((option) => selectedValue === option.value),\n )\n if (newValue.length !== value.length) {\n const newValueArray = newValue.length ? newValue : undefined\n onChange(element, newValueArray as T | undefined)\n }\n }\n }, [\n element,\n shownOptions,\n onChange,\n value,\n conditionallyShownOptionsElement?.dependencyIsLoading,\n ])\n\n useLoadDynamicOptionsEffect(element, onUpdateFormElements)\n\n return filteredOptions\n}\n"]}
@@ -158,7 +158,6 @@ export function generateValidationSchema(elements, elementIdsWithLookupsExecuted
158
158
  case 'calculation':
159
159
  case 'image':
160
160
  case 'html':
161
- case 'infoPage':
162
161
  case 'heading': {
163
162
  return partialSchema;
164
163
  }
@@ -478,6 +477,7 @@ export function generateValidationSchema(elements, elementIdsWithLookupsExecuted
478
477
  },
479
478
  };
480
479
  }
480
+ case 'infoPage':
481
481
  case 'form': {
482
482
  if (formElement.elements) {
483
483
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"form-validation.js","sourceRoot":"","sources":["../../src/services/form-validation.ts"],"names":[],"mappings":"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","sourcesContent":["import validate, { ValidatorConstraintFn } from 'validate.js'\nimport { attachmentsService, localisationService } from '@oneblink/apps'\nimport { FormTypes, SubmissionTypes } from '@oneblink/types'\nimport { FormElementBinaryStorageValue } from '../types/attachments'\nimport { Value as FormElementComplianceValue } from '../form-elements/FormElementCompliance'\nimport { parseDateValue } from './generate-default-data'\nimport generateCivicaNameRecordElements from './generateCivicaNameRecordElements'\nimport {\n FormElementConditionallyShown,\n FormElementsConditionallyShown,\n FormElementsValidation,\n} from '../types/form'\nimport generateFreshdeskDependentFieldElements from './generateFreshdeskDependentFieldElements'\nimport cleanFormSubmissionModel from './cleanFormSubmissionModel'\nimport getDateRangeConfiguration, {\n DateRangeConfigurationOptions,\n} from './getDateRangeConfiguration'\nimport getRepeatableSetEntriesConfiguration from './getRepeatableSetEntriesConfiguration'\n\ntype NestedValidateJSSchema = {\n schema: ValidateJSSchema\n formElementConditionallyShown: FormElementConditionallyShown | undefined\n}\n\nexport const lookupValidationMessage = 'Lookup is required'\n// https://validatejs.org/#validators-datetime\n// Before using it we must add the parse and format functions\n// Here is a sample implementation using moment.js\nvalidate.extend(validate.validators.datetime, {\n // The value is guaranteed not to be null or undefined but otherwise it\n // could be anything.\n parse: function (value: string) {\n return Date.parse(value)\n },\n // Input is a unix timestamp\n format: function (\n value: string,\n options: { format: (date: Date) => string },\n ) {\n const dateValue = new Date(value)\n return options.format(dateValue)\n },\n})\n\nvalidate.validators.entries = function (\n value: unknown,\n {\n setSchema,\n entrySchema: { schema: entrySchema, formElementConditionallyShown },\n }: {\n setSchema: ValidateJSSchema\n entrySchema: NestedValidateJSSchema\n },\n) {\n const entries = Array.isArray(value) ? value : []\n\n const entryErrors = entries.reduce((errorsByIndex, entry, index) => {\n const entryValidation = validateSubmission(\n entrySchema,\n entry,\n formElementConditionallyShown?.type === 'repeatableSet'\n ? formElementConditionallyShown.entries[index.toString()]\n : undefined,\n )\n if (entryValidation) {\n errorsByIndex[index] = entryValidation\n }\n return errorsByIndex\n }, {})\n\n const setErrorMessages = validate.single(value, setSchema)\n\n if (!setErrorMessages && validate.isEmpty(entryErrors)) {\n return\n }\n\n return {\n type: 'repeatableSet',\n set: setErrorMessages && setErrorMessages[0],\n entries: entryErrors,\n }\n}\n\nvalidate.validators.nestedElements = function (\n value: SubmissionTypes.S3SubmissionData['submission'] | undefined,\n { schema, formElementConditionallyShown }: NestedValidateJSSchema,\n) {\n const errors = validateSubmission(\n schema,\n value,\n formElementConditionallyShown?.type === 'formElements'\n ? formElementConditionallyShown.formElements\n : undefined,\n )\n if (!errors) {\n return\n }\n return {\n type: 'formElements',\n formElements: errors,\n }\n}\n\nfunction getInvalidAttachment(value: FormElementBinaryStorageValue) {\n if (\n value &&\n typeof value === 'object' &&\n value.type &&\n value.type === 'ERROR'\n ) {\n return value\n }\n}\nfunction validateAttachments(\n value: FormElementBinaryStorageValue[] | undefined,\n) {\n const invalidAttachmentNames = value?.reduce(\n (invalidAttachmentNames: string[], att) => {\n const attachmentName = getInvalidAttachment(att)?.fileName\n if (attachmentName) {\n invalidAttachmentNames.push(attachmentName)\n }\n return invalidAttachmentNames\n },\n [],\n )\n if (invalidAttachmentNames?.length) {\n return `${invalidAttachmentNames.join(', ')} could not be uploaded.`\n }\n}\nvalidate.validators.attachment = function (\n value: FormElementBinaryStorageValue,\n) {\n return getInvalidAttachment(value)?.errorMessage\n}\nvalidate.validators.attachments = function (\n value:\n | FormElementBinaryStorageValue[]\n | FormElementComplianceValue\n | undefined,\n) {\n if (Array.isArray(value)) {\n return validateAttachments(value)\n }\n return validateAttachments(\n value?.files as FormElementBinaryStorageValue[] | undefined,\n )\n}\n\n// Extend validator for lookups\nvalidate.validators.lookups = function (\n value: unknown,\n {\n elementIdsWithLookupsExecuted,\n formElement,\n }: {\n formElement: FormTypes.LookupFormElement & FormTypes.FormElementRequired\n elementIdsWithLookupsExecuted: string[]\n },\n) {\n if (!formElement.isDataLookup && !formElement.isElementLookup) {\n return\n }\n\n // Lookups must only be executed on required form elements\n if (formElement && !formElement.required) {\n return\n }\n\n if (elementIdsWithLookupsExecuted.includes(formElement.id)) {\n return\n }\n\n return lookupValidationMessage\n}\n\nvalidate.validators.numberRegex = function (value: unknown, format: unknown) {\n if (!format) {\n return\n }\n if (typeof value === 'number' && !Number.isNaN(value)) {\n value = value.toString()\n }\n const errorMessages = validate.single(value, { format })\n return errorMessages && errorMessages[0]\n}\n\nvalidate.validators.isTrue = function (value: unknown, message?: string) {\n if (!value) {\n return message || 'Must be set to true'\n }\n}\n\nvalidate.validators.needsExtension = function (\n value: attachmentsService.Attachment[] | undefined,\n formElement: FormTypes.FilesElement,\n) {\n const isValid =\n !Array.isArray(value) ||\n value.every((file) => {\n return checkFileNameExtensionIsValid(formElement, file.fileName)\n })\n if (!isValid) return 'All files must have extensions'\n}\n\nfunction getCustomRegexFormatConfig<DefaultValue>(\n formElement: FormTypes.FormElementWithInput<DefaultValue>,\n) {\n return formElement.regexPattern\n ? {\n pattern: formElement.regexPattern,\n flags: formElement.regexFlags,\n message: formElement.regexMessage,\n }\n : undefined\n}\n\ntype ValidateJSSchema = Record<string, unknown>\n\nconst presence = (\n { required, requiredMessage }: FormTypes.FormElementRequired,\n message: string,\n) => (required ? { message: requiredMessage || message } : false)\n\nconst escapeElementName = (elementName: string) => {\n const escapedName = elementName.replace(/\\./g, '\\\\.')\n return escapedName\n}\n\nfunction getCleanDateRangeConfiguration(\n options: DateRangeConfigurationOptions,\n elements: FormTypes.FormElement[],\n submission: SubmissionTypes.S3SubmissionData['submission'] | undefined,\n formElementsConditionallyShown: FormElementsConditionallyShown | undefined,\n): ReturnType<typeof getDateRangeConfiguration> {\n if (options.referenceFormElementId && submission) {\n const { model } = cleanFormSubmissionModel(\n submission,\n elements,\n formElementsConditionallyShown,\n true,\n )\n return getDateRangeConfiguration(options, elements, model)\n }\n return [options.date, options.daysOffset]\n}\n\nfunction getCleanRepeatableSetConfiguration(\n setEntries: FormTypes.RepeatableSetElement['minSetEntries'],\n elements: FormTypes.FormElement[],\n submission: SubmissionTypes.S3SubmissionData['submission'] | undefined,\n formElementsConditionallyShown: FormElementsConditionallyShown | undefined,\n) {\n if (submission) {\n const { model } = cleanFormSubmissionModel(\n submission,\n elements,\n formElementsConditionallyShown,\n true,\n )\n return getRepeatableSetEntriesConfiguration(setEntries, elements, model)\n }\n}\n\nexport function generateValidationSchema(\n elements: FormTypes.FormElementWithName[],\n elementIdsWithLookupsExecuted: string[],\n): ValidateJSSchema {\n return elements.reduce<ValidateJSSchema>((partialSchema, formElement) => {\n switch (formElement.type) {\n // Elements that do not need to be validated\n case 'summary':\n case 'calculation':\n case 'image':\n case 'html':\n case 'infoPage':\n case 'heading': {\n return partialSchema\n }\n }\n\n const constraint: ValidatorConstraintFn<\n SubmissionTypes.S3SubmissionData['submission']\n > = (\n value,\n submission,\n propertyName,\n { formElementsConditionallyShown },\n ) => {\n // If the element is current hidden, we do not need to apply validation\n const formElementConditionallyShown =\n formElementsConditionallyShown?.[formElement.name]\n if (formElementConditionallyShown?.isHidden) {\n return\n }\n\n switch (formElement.type) {\n case 'draw': {\n return {\n attachment: true,\n presence: presence(formElement, 'A saved signature is required'),\n }\n }\n case 'camera': {\n return {\n attachment: true,\n presence: presence(formElement, 'A photo is required'),\n }\n }\n case 'captcha': {\n return {\n presence: presence(\n { ...formElement, required: true },\n 'Please complete the CAPTCHA successfully',\n ),\n }\n }\n case 'location': {\n return {\n presence: presence(formElement, 'Please select a location'),\n lookups: {\n formElement,\n elementIdsWithLookupsExecuted,\n },\n }\n }\n case 'compliance': {\n return {\n presence: presence(formElement, 'Required'),\n lookups: {\n formElement,\n elementIdsWithLookupsExecuted,\n },\n attachments: true,\n }\n }\n case 'checkboxes': {\n const requiredAllDefaultMessage = 'All options are required'\n return {\n presence: presence(\n {\n ...formElement,\n required: formElement.required || !!formElement.requiredAll,\n },\n formElement.requiredAll ? requiredAllDefaultMessage : 'Required',\n ),\n length: formElement.requiredAll\n ? {\n is: formElement.options?.length,\n message:\n formElement.requiredMessage || requiredAllDefaultMessage,\n }\n : undefined,\n lookups: {\n formElement,\n elementIdsWithLookupsExecuted,\n },\n }\n }\n case 'abn':\n case 'geoscapeAddress':\n case 'pointAddress':\n case 'civicaStreetName':\n case 'autocomplete':\n case 'radio':\n case 'select': {\n return {\n presence: presence(formElement, 'Required'),\n lookups: {\n formElement,\n elementIdsWithLookupsExecuted,\n },\n }\n }\n case 'boolean': {\n return {\n isTrue: formElement.required && 'Required',\n lookups: {\n formElement,\n elementIdsWithLookupsExecuted,\n },\n }\n }\n case 'bsb': {\n return {\n presence: presence(formElement, 'Please enter a BSB number'),\n lookups: {\n formElement,\n elementIdsWithLookupsExecuted,\n },\n format: {\n pattern: /\\d{3}-\\d{3}/,\n message: 'Please enter a valid BSB number',\n },\n }\n }\n case 'barcodeScanner': {\n return {\n presence: presence(\n formElement,\n 'Please scan a barcode or enter a value',\n ),\n lookups: {\n formElement,\n elementIdsWithLookupsExecuted,\n },\n format: getCustomRegexFormatConfig(formElement),\n }\n }\n case 'text':\n case 'textarea': {\n return {\n presence: presence(formElement, 'Please enter a value'),\n lookups: {\n formElement,\n elementIdsWithLookupsExecuted,\n },\n length: {\n minimum: formElement.minLength,\n tooShort:\n 'Please enter a value with at least %{count} character(s)',\n maximum: formElement.maxLength,\n tooLong:\n 'Please enter a value with %{count} character(s) or less',\n },\n format: getCustomRegexFormatConfig(formElement),\n }\n }\n case 'telephone': {\n return {\n presence: presence(formElement, 'Please enter a phone number'),\n lookups: {\n formElement,\n elementIdsWithLookupsExecuted,\n },\n format: getCustomRegexFormatConfig(formElement),\n }\n }\n case 'email': {\n return {\n presence: presence(formElement, 'Please enter an email address'),\n email: {\n message: 'Please enter a valid email for this field',\n },\n lookups: {\n formElement,\n elementIdsWithLookupsExecuted,\n },\n format: getCustomRegexFormatConfig(formElement),\n }\n }\n case 'time': {\n return {\n presence: presence(formElement, 'Please select a time'),\n lookups: {\n formElement,\n elementIdsWithLookupsExecuted,\n },\n }\n }\n case 'date': {\n const [fromDate, fromDateDaysOffset] = getCleanDateRangeConfiguration(\n {\n date: formElement.fromDate,\n daysOffset: formElement.fromDateDaysOffset,\n referenceFormElementId: formElement.fromDateElementId,\n },\n elements,\n submission,\n formElementsConditionallyShown,\n )\n const [toDate, toDateDaysOffset] = getCleanDateRangeConfiguration(\n {\n date: formElement.toDate,\n daysOffset: formElement.toDateDaysOffset,\n referenceFormElementId: formElement.toDateElementId,\n },\n elements,\n submission,\n formElementsConditionallyShown,\n )\n return {\n presence: presence(formElement, 'Please select a date'),\n date: {\n format: (v: Date) => localisationService.formatDate(v),\n earliest: parseDateValue({\n dateOnly: true,\n daysOffset: fromDateDaysOffset,\n value: fromDate,\n }),\n latest: parseDateValue({\n dateOnly: true,\n daysOffset: toDateDaysOffset,\n value: toDate,\n }),\n notValid: 'Please select a valid date',\n tooEarly: 'Date cannot be before %{date}',\n tooLate: 'Date cannot be after %{date}',\n },\n lookups: {\n formElement,\n elementIdsWithLookupsExecuted,\n },\n }\n }\n case 'datetime': {\n const [fromDate, fromDateDaysOffset] = getCleanDateRangeConfiguration(\n {\n date: formElement.fromDate,\n daysOffset: formElement.fromDateDaysOffset,\n referenceFormElementId: formElement.fromDateElementId,\n },\n elements,\n submission,\n formElementsConditionallyShown,\n )\n const [toDate, toDateDaysOffset] = getCleanDateRangeConfiguration(\n {\n date: formElement.toDate,\n daysOffset: formElement.toDateDaysOffset,\n referenceFormElementId: formElement.toDateElementId,\n },\n elements,\n submission,\n formElementsConditionallyShown,\n )\n return {\n presence: presence(formElement, 'Please select a date and time'),\n datetime: {\n format: (v: Date) => localisationService.formatDatetime(v),\n earliest: parseDateValue({\n dateOnly: false,\n daysOffset: fromDateDaysOffset,\n value: fromDate,\n }),\n latest: parseDateValue({\n dateOnly: false,\n daysOffset: toDateDaysOffset,\n value: toDate,\n }),\n notValid: 'Please select a valid date and time',\n tooEarly: 'Date and time cannot be before %{date}',\n tooLate: 'Date and time cannot be after %{date}',\n },\n lookups: {\n formElement,\n elementIdsWithLookupsExecuted,\n },\n }\n }\n case 'number': {\n let minErrorMessage =\n 'Please enter a number greater than or equal to %{count}'\n let maxErrorMessage =\n 'Please enter a number less than or equal to %{count}'\n if (\n typeof formElement.minNumber === 'number' &&\n typeof formElement.maxNumber === 'number'\n ) {\n minErrorMessage =\n maxErrorMessage = `Please enter a number between ${formElement.minNumber} and ${formElement.maxNumber}`\n }\n\n return {\n type: 'number',\n presence: presence(formElement, 'Please enter a number'),\n numericality: {\n greaterThanOrEqualTo: formElement.minNumber,\n notGreaterThanOrEqualTo: minErrorMessage,\n lessThanOrEqualTo: formElement.maxNumber,\n notLessThanOrEqualTo: maxErrorMessage,\n onlyInteger: formElement.isInteger,\n notInteger: 'Please enter a whole number',\n },\n lookups: {\n formElement,\n elementIdsWithLookupsExecuted,\n },\n numberRegex: getCustomRegexFormatConfig(formElement),\n }\n }\n case 'files': {\n return {\n presence: formElement.minEntries\n ? {\n message: `Please upload at least ${\n formElement.minEntries\n } file${formElement.minEntries === 1 ? '' : 's'}`,\n }\n : false,\n length: {\n minimum: formElement.minEntries,\n maximum: formElement.maxEntries,\n tooLong: 'Cannot upload more than %{count} file(s)',\n tooShort: 'Please upload at least %{count} file(s)',\n },\n type: {\n type: (files: attachmentsService.Attachment[] | undefined) => {\n return (\n !Array.isArray(files) ||\n files.every((file) => {\n return checkFileNameIsValid(formElement, file.fileName)\n })\n )\n },\n message: `Only the following file types are accepted: ${(\n formElement.restrictedFileTypes || []\n ).join(', ')}`,\n },\n needsExtension: formElement,\n attachments: true,\n }\n }\n case 'repeatableSet': {\n const minSetEntries = getCleanRepeatableSetConfiguration(\n formElement.minSetEntries,\n elements,\n submission,\n formElementsConditionallyShown,\n )\n const maxSetEntries = getCleanRepeatableSetConfiguration(\n formElement.maxSetEntries,\n elements,\n submission,\n formElementsConditionallyShown,\n )\n return {\n entries: {\n setSchema: {\n presence: minSetEntries\n ? {\n message: `Must have at least ${minSetEntries} ${\n minSetEntries === 1 ? 'entry' : 'entries'\n }`,\n }\n : false,\n length: {\n minimum: minSetEntries,\n maximum: maxSetEntries,\n tooLong: 'Cannot have more than %{count} entry/entries',\n tooShort: 'Must have at least %{count} entry/entries',\n },\n },\n entrySchema: {\n schema: generateValidationSchema(\n formElement.elements as FormTypes.FormElementWithName[],\n elementIdsWithLookupsExecuted,\n ),\n formElementConditionallyShown:\n formElementsConditionallyShown?.[formElement.name],\n },\n },\n }\n }\n case 'civicaNameRecord': {\n const nestedElements = generateCivicaNameRecordElements(\n formElement,\n [],\n )\n return {\n nestedElements: {\n schema: generateValidationSchema(\n nestedElements as FormTypes.FormElementWithName[],\n elementIdsWithLookupsExecuted,\n ),\n formElementConditionallyShown:\n formElementsConditionallyShown?.[formElement.name],\n },\n }\n }\n case 'form': {\n if (formElement.elements) {\n return {\n nestedElements: {\n schema: generateValidationSchema(\n formElement.elements as FormTypes.FormElementWithName[],\n elementIdsWithLookupsExecuted,\n ),\n formElementConditionallyShown:\n formElementsConditionallyShown?.[formElement.name],\n },\n }\n }\n break\n }\n case 'freshdeskDependentField': {\n const nestedElements =\n generateFreshdeskDependentFieldElements(formElement)\n return {\n nestedElements: {\n schema: generateValidationSchema(\n nestedElements as FormTypes.FormElementWithName[],\n elementIdsWithLookupsExecuted,\n ),\n formElementConditionallyShown:\n formElementsConditionallyShown?.[formElement.name],\n },\n }\n }\n default: {\n console.info('Unsupported form element with validation', formElement)\n }\n }\n }\n partialSchema[escapeElementName(formElement.name)] = constraint\n return partialSchema\n }, {})\n}\n\nexport function validateSubmission(\n schema: ValidateJSSchema,\n submission: SubmissionTypes.S3SubmissionData['submission'] | undefined,\n formElementsConditionallyShown: FormElementsConditionallyShown | undefined,\n): FormElementsValidation | undefined {\n const errorsAsArray = validate(submission, schema, {\n format: 'grouped',\n fullMessages: false,\n formElementsConditionallyShown,\n })\n if (!errorsAsArray || validate.isEmpty(errorsAsArray)) {\n return\n }\n\n const errors = Object.keys(errorsAsArray || {}).reduce(\n (messagesByFormElementName: FormElementsValidation, key) => {\n const validationMessage = errorsAsArray[key][0]\n if (validationMessage) {\n messagesByFormElementName[key.replace(/\\\\./g, '.')] = validationMessage\n }\n return messagesByFormElementName\n },\n {},\n )\n if (validate.isEmpty(errors)) {\n return\n }\n\n return errors\n}\n\nexport function checkFileNameIsValid(\n formElement: FormTypes.FilesElement,\n fileName: string,\n) {\n const extension = fileName.split('.').pop()\n return (\n !formElement.restrictedFileTypes ||\n formElement.restrictedFileTypes.some(\n (fileType) => fileType.toLowerCase() === extension?.toLowerCase(),\n )\n )\n}\n\nexport function checkFileNameExtensionIsValid(\n formElement: FormTypes.FilesElement,\n fileName: string,\n) {\n return (\n formElement.allowExtensionlessAttachments || fileName.split('.').length >= 2\n )\n}\n\nexport function checkSectionValidity(\n element: FormTypes.PageElement | FormTypes.SectionElement,\n formElementsValidation: FormElementsValidation | undefined,\n): boolean {\n // If everything is valid, no need to check elements\n if (!formElementsValidation) {\n return false\n }\n\n // If there is no elements on the page that are invalid, we will treat as valid\n return element.elements.some((formElement) => {\n switch (formElement.type) {\n case 'page':\n case 'section': {\n return checkSectionValidity(formElement, formElementsValidation)\n }\n default: {\n return formElementsValidation[formElement.name]\n }\n }\n })\n}\n"]}
1
+ {"version":3,"file":"form-validation.js","sourceRoot":"","sources":["../../src/services/form-validation.ts"],"names":[],"mappings":"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","sourcesContent":["import validate, { ValidatorConstraintFn } from 'validate.js'\nimport { attachmentsService, localisationService } from '@oneblink/apps'\nimport { FormTypes, SubmissionTypes } from '@oneblink/types'\nimport { FormElementBinaryStorageValue } from '../types/attachments'\nimport { Value as FormElementComplianceValue } from '../form-elements/FormElementCompliance'\nimport { parseDateValue } from './generate-default-data'\nimport generateCivicaNameRecordElements from './generateCivicaNameRecordElements'\nimport {\n FormElementConditionallyShown,\n FormElementsConditionallyShown,\n FormElementsValidation,\n} from '../types/form'\nimport generateFreshdeskDependentFieldElements from './generateFreshdeskDependentFieldElements'\nimport cleanFormSubmissionModel from './cleanFormSubmissionModel'\nimport getDateRangeConfiguration, {\n DateRangeConfigurationOptions,\n} from './getDateRangeConfiguration'\nimport getRepeatableSetEntriesConfiguration from './getRepeatableSetEntriesConfiguration'\n\ntype NestedValidateJSSchema = {\n schema: ValidateJSSchema\n formElementConditionallyShown: FormElementConditionallyShown | undefined\n}\n\nexport const lookupValidationMessage = 'Lookup is required'\n// https://validatejs.org/#validators-datetime\n// Before using it we must add the parse and format functions\n// Here is a sample implementation using moment.js\nvalidate.extend(validate.validators.datetime, {\n // The value is guaranteed not to be null or undefined but otherwise it\n // could be anything.\n parse: function (value: string) {\n return Date.parse(value)\n },\n // Input is a unix timestamp\n format: function (\n value: string,\n options: { format: (date: Date) => string },\n ) {\n const dateValue = new Date(value)\n return options.format(dateValue)\n },\n})\n\nvalidate.validators.entries = function (\n value: unknown,\n {\n setSchema,\n entrySchema: { schema: entrySchema, formElementConditionallyShown },\n }: {\n setSchema: ValidateJSSchema\n entrySchema: NestedValidateJSSchema\n },\n) {\n const entries = Array.isArray(value) ? value : []\n\n const entryErrors = entries.reduce((errorsByIndex, entry, index) => {\n const entryValidation = validateSubmission(\n entrySchema,\n entry,\n formElementConditionallyShown?.type === 'repeatableSet'\n ? formElementConditionallyShown.entries[index.toString()]\n : undefined,\n )\n if (entryValidation) {\n errorsByIndex[index] = entryValidation\n }\n return errorsByIndex\n }, {})\n\n const setErrorMessages = validate.single(value, setSchema)\n\n if (!setErrorMessages && validate.isEmpty(entryErrors)) {\n return\n }\n\n return {\n type: 'repeatableSet',\n set: setErrorMessages && setErrorMessages[0],\n entries: entryErrors,\n }\n}\n\nvalidate.validators.nestedElements = function (\n value: SubmissionTypes.S3SubmissionData['submission'] | undefined,\n { schema, formElementConditionallyShown }: NestedValidateJSSchema,\n) {\n const errors = validateSubmission(\n schema,\n value,\n formElementConditionallyShown?.type === 'formElements'\n ? formElementConditionallyShown.formElements\n : undefined,\n )\n if (!errors) {\n return\n }\n return {\n type: 'formElements',\n formElements: errors,\n }\n}\n\nfunction getInvalidAttachment(value: FormElementBinaryStorageValue) {\n if (\n value &&\n typeof value === 'object' &&\n value.type &&\n value.type === 'ERROR'\n ) {\n return value\n }\n}\nfunction validateAttachments(\n value: FormElementBinaryStorageValue[] | undefined,\n) {\n const invalidAttachmentNames = value?.reduce(\n (invalidAttachmentNames: string[], att) => {\n const attachmentName = getInvalidAttachment(att)?.fileName\n if (attachmentName) {\n invalidAttachmentNames.push(attachmentName)\n }\n return invalidAttachmentNames\n },\n [],\n )\n if (invalidAttachmentNames?.length) {\n return `${invalidAttachmentNames.join(', ')} could not be uploaded.`\n }\n}\nvalidate.validators.attachment = function (\n value: FormElementBinaryStorageValue,\n) {\n return getInvalidAttachment(value)?.errorMessage\n}\nvalidate.validators.attachments = function (\n value:\n | FormElementBinaryStorageValue[]\n | FormElementComplianceValue\n | undefined,\n) {\n if (Array.isArray(value)) {\n return validateAttachments(value)\n }\n return validateAttachments(\n value?.files as FormElementBinaryStorageValue[] | undefined,\n )\n}\n\n// Extend validator for lookups\nvalidate.validators.lookups = function (\n value: unknown,\n {\n elementIdsWithLookupsExecuted,\n formElement,\n }: {\n formElement: FormTypes.LookupFormElement & FormTypes.FormElementRequired\n elementIdsWithLookupsExecuted: string[]\n },\n) {\n if (!formElement.isDataLookup && !formElement.isElementLookup) {\n return\n }\n\n // Lookups must only be executed on required form elements\n if (formElement && !formElement.required) {\n return\n }\n\n if (elementIdsWithLookupsExecuted.includes(formElement.id)) {\n return\n }\n\n return lookupValidationMessage\n}\n\nvalidate.validators.numberRegex = function (value: unknown, format: unknown) {\n if (!format) {\n return\n }\n if (typeof value === 'number' && !Number.isNaN(value)) {\n value = value.toString()\n }\n const errorMessages = validate.single(value, { format })\n return errorMessages && errorMessages[0]\n}\n\nvalidate.validators.isTrue = function (value: unknown, message?: string) {\n if (!value) {\n return message || 'Must be set to true'\n }\n}\n\nvalidate.validators.needsExtension = function (\n value: attachmentsService.Attachment[] | undefined,\n formElement: FormTypes.FilesElement,\n) {\n const isValid =\n !Array.isArray(value) ||\n value.every((file) => {\n return checkFileNameExtensionIsValid(formElement, file.fileName)\n })\n if (!isValid) return 'All files must have extensions'\n}\n\nfunction getCustomRegexFormatConfig<DefaultValue>(\n formElement: FormTypes.FormElementWithInput<DefaultValue>,\n) {\n return formElement.regexPattern\n ? {\n pattern: formElement.regexPattern,\n flags: formElement.regexFlags,\n message: formElement.regexMessage,\n }\n : undefined\n}\n\ntype ValidateJSSchema = Record<string, unknown>\n\nconst presence = (\n { required, requiredMessage }: FormTypes.FormElementRequired,\n message: string,\n) => (required ? { message: requiredMessage || message } : false)\n\nconst escapeElementName = (elementName: string) => {\n const escapedName = elementName.replace(/\\./g, '\\\\.')\n return escapedName\n}\n\nfunction getCleanDateRangeConfiguration(\n options: DateRangeConfigurationOptions,\n elements: FormTypes.FormElement[],\n submission: SubmissionTypes.S3SubmissionData['submission'] | undefined,\n formElementsConditionallyShown: FormElementsConditionallyShown | undefined,\n): ReturnType<typeof getDateRangeConfiguration> {\n if (options.referenceFormElementId && submission) {\n const { model } = cleanFormSubmissionModel(\n submission,\n elements,\n formElementsConditionallyShown,\n true,\n )\n return getDateRangeConfiguration(options, elements, model)\n }\n return [options.date, options.daysOffset]\n}\n\nfunction getCleanRepeatableSetConfiguration(\n setEntries: FormTypes.RepeatableSetElement['minSetEntries'],\n elements: FormTypes.FormElement[],\n submission: SubmissionTypes.S3SubmissionData['submission'] | undefined,\n formElementsConditionallyShown: FormElementsConditionallyShown | undefined,\n) {\n if (submission) {\n const { model } = cleanFormSubmissionModel(\n submission,\n elements,\n formElementsConditionallyShown,\n true,\n )\n return getRepeatableSetEntriesConfiguration(setEntries, elements, model)\n }\n}\n\nexport function generateValidationSchema(\n elements: FormTypes.FormElementWithName[],\n elementIdsWithLookupsExecuted: string[],\n): ValidateJSSchema {\n return elements.reduce<ValidateJSSchema>((partialSchema, formElement) => {\n switch (formElement.type) {\n // Elements that do not need to be validated\n case 'summary':\n case 'calculation':\n case 'image':\n case 'html':\n case 'heading': {\n return partialSchema\n }\n }\n\n const constraint: ValidatorConstraintFn<\n SubmissionTypes.S3SubmissionData['submission']\n > = (\n value,\n submission,\n propertyName,\n { formElementsConditionallyShown },\n ) => {\n // If the element is current hidden, we do not need to apply validation\n const formElementConditionallyShown =\n formElementsConditionallyShown?.[formElement.name]\n if (formElementConditionallyShown?.isHidden) {\n return\n }\n\n switch (formElement.type) {\n case 'draw': {\n return {\n attachment: true,\n presence: presence(formElement, 'A saved signature is required'),\n }\n }\n case 'camera': {\n return {\n attachment: true,\n presence: presence(formElement, 'A photo is required'),\n }\n }\n case 'captcha': {\n return {\n presence: presence(\n { ...formElement, required: true },\n 'Please complete the CAPTCHA successfully',\n ),\n }\n }\n case 'location': {\n return {\n presence: presence(formElement, 'Please select a location'),\n lookups: {\n formElement,\n elementIdsWithLookupsExecuted,\n },\n }\n }\n case 'compliance': {\n return {\n presence: presence(formElement, 'Required'),\n lookups: {\n formElement,\n elementIdsWithLookupsExecuted,\n },\n attachments: true,\n }\n }\n case 'checkboxes': {\n const requiredAllDefaultMessage = 'All options are required'\n return {\n presence: presence(\n {\n ...formElement,\n required: formElement.required || !!formElement.requiredAll,\n },\n formElement.requiredAll ? requiredAllDefaultMessage : 'Required',\n ),\n length: formElement.requiredAll\n ? {\n is: formElement.options?.length,\n message:\n formElement.requiredMessage || requiredAllDefaultMessage,\n }\n : undefined,\n lookups: {\n formElement,\n elementIdsWithLookupsExecuted,\n },\n }\n }\n case 'abn':\n case 'geoscapeAddress':\n case 'pointAddress':\n case 'civicaStreetName':\n case 'autocomplete':\n case 'radio':\n case 'select': {\n return {\n presence: presence(formElement, 'Required'),\n lookups: {\n formElement,\n elementIdsWithLookupsExecuted,\n },\n }\n }\n case 'boolean': {\n return {\n isTrue: formElement.required && 'Required',\n lookups: {\n formElement,\n elementIdsWithLookupsExecuted,\n },\n }\n }\n case 'bsb': {\n return {\n presence: presence(formElement, 'Please enter a BSB number'),\n lookups: {\n formElement,\n elementIdsWithLookupsExecuted,\n },\n format: {\n pattern: /\\d{3}-\\d{3}/,\n message: 'Please enter a valid BSB number',\n },\n }\n }\n case 'barcodeScanner': {\n return {\n presence: presence(\n formElement,\n 'Please scan a barcode or enter a value',\n ),\n lookups: {\n formElement,\n elementIdsWithLookupsExecuted,\n },\n format: getCustomRegexFormatConfig(formElement),\n }\n }\n case 'text':\n case 'textarea': {\n return {\n presence: presence(formElement, 'Please enter a value'),\n lookups: {\n formElement,\n elementIdsWithLookupsExecuted,\n },\n length: {\n minimum: formElement.minLength,\n tooShort:\n 'Please enter a value with at least %{count} character(s)',\n maximum: formElement.maxLength,\n tooLong:\n 'Please enter a value with %{count} character(s) or less',\n },\n format: getCustomRegexFormatConfig(formElement),\n }\n }\n case 'telephone': {\n return {\n presence: presence(formElement, 'Please enter a phone number'),\n lookups: {\n formElement,\n elementIdsWithLookupsExecuted,\n },\n format: getCustomRegexFormatConfig(formElement),\n }\n }\n case 'email': {\n return {\n presence: presence(formElement, 'Please enter an email address'),\n email: {\n message: 'Please enter a valid email for this field',\n },\n lookups: {\n formElement,\n elementIdsWithLookupsExecuted,\n },\n format: getCustomRegexFormatConfig(formElement),\n }\n }\n case 'time': {\n return {\n presence: presence(formElement, 'Please select a time'),\n lookups: {\n formElement,\n elementIdsWithLookupsExecuted,\n },\n }\n }\n case 'date': {\n const [fromDate, fromDateDaysOffset] = getCleanDateRangeConfiguration(\n {\n date: formElement.fromDate,\n daysOffset: formElement.fromDateDaysOffset,\n referenceFormElementId: formElement.fromDateElementId,\n },\n elements,\n submission,\n formElementsConditionallyShown,\n )\n const [toDate, toDateDaysOffset] = getCleanDateRangeConfiguration(\n {\n date: formElement.toDate,\n daysOffset: formElement.toDateDaysOffset,\n referenceFormElementId: formElement.toDateElementId,\n },\n elements,\n submission,\n formElementsConditionallyShown,\n )\n return {\n presence: presence(formElement, 'Please select a date'),\n date: {\n format: (v: Date) => localisationService.formatDate(v),\n earliest: parseDateValue({\n dateOnly: true,\n daysOffset: fromDateDaysOffset,\n value: fromDate,\n }),\n latest: parseDateValue({\n dateOnly: true,\n daysOffset: toDateDaysOffset,\n value: toDate,\n }),\n notValid: 'Please select a valid date',\n tooEarly: 'Date cannot be before %{date}',\n tooLate: 'Date cannot be after %{date}',\n },\n lookups: {\n formElement,\n elementIdsWithLookupsExecuted,\n },\n }\n }\n case 'datetime': {\n const [fromDate, fromDateDaysOffset] = getCleanDateRangeConfiguration(\n {\n date: formElement.fromDate,\n daysOffset: formElement.fromDateDaysOffset,\n referenceFormElementId: formElement.fromDateElementId,\n },\n elements,\n submission,\n formElementsConditionallyShown,\n )\n const [toDate, toDateDaysOffset] = getCleanDateRangeConfiguration(\n {\n date: formElement.toDate,\n daysOffset: formElement.toDateDaysOffset,\n referenceFormElementId: formElement.toDateElementId,\n },\n elements,\n submission,\n formElementsConditionallyShown,\n )\n return {\n presence: presence(formElement, 'Please select a date and time'),\n datetime: {\n format: (v: Date) => localisationService.formatDatetime(v),\n earliest: parseDateValue({\n dateOnly: false,\n daysOffset: fromDateDaysOffset,\n value: fromDate,\n }),\n latest: parseDateValue({\n dateOnly: false,\n daysOffset: toDateDaysOffset,\n value: toDate,\n }),\n notValid: 'Please select a valid date and time',\n tooEarly: 'Date and time cannot be before %{date}',\n tooLate: 'Date and time cannot be after %{date}',\n },\n lookups: {\n formElement,\n elementIdsWithLookupsExecuted,\n },\n }\n }\n case 'number': {\n let minErrorMessage =\n 'Please enter a number greater than or equal to %{count}'\n let maxErrorMessage =\n 'Please enter a number less than or equal to %{count}'\n if (\n typeof formElement.minNumber === 'number' &&\n typeof formElement.maxNumber === 'number'\n ) {\n minErrorMessage =\n maxErrorMessage = `Please enter a number between ${formElement.minNumber} and ${formElement.maxNumber}`\n }\n\n return {\n type: 'number',\n presence: presence(formElement, 'Please enter a number'),\n numericality: {\n greaterThanOrEqualTo: formElement.minNumber,\n notGreaterThanOrEqualTo: minErrorMessage,\n lessThanOrEqualTo: formElement.maxNumber,\n notLessThanOrEqualTo: maxErrorMessage,\n onlyInteger: formElement.isInteger,\n notInteger: 'Please enter a whole number',\n },\n lookups: {\n formElement,\n elementIdsWithLookupsExecuted,\n },\n numberRegex: getCustomRegexFormatConfig(formElement),\n }\n }\n case 'files': {\n return {\n presence: formElement.minEntries\n ? {\n message: `Please upload at least ${\n formElement.minEntries\n } file${formElement.minEntries === 1 ? '' : 's'}`,\n }\n : false,\n length: {\n minimum: formElement.minEntries,\n maximum: formElement.maxEntries,\n tooLong: 'Cannot upload more than %{count} file(s)',\n tooShort: 'Please upload at least %{count} file(s)',\n },\n type: {\n type: (files: attachmentsService.Attachment[] | undefined) => {\n return (\n !Array.isArray(files) ||\n files.every((file) => {\n return checkFileNameIsValid(formElement, file.fileName)\n })\n )\n },\n message: `Only the following file types are accepted: ${(\n formElement.restrictedFileTypes || []\n ).join(', ')}`,\n },\n needsExtension: formElement,\n attachments: true,\n }\n }\n case 'repeatableSet': {\n const minSetEntries = getCleanRepeatableSetConfiguration(\n formElement.minSetEntries,\n elements,\n submission,\n formElementsConditionallyShown,\n )\n const maxSetEntries = getCleanRepeatableSetConfiguration(\n formElement.maxSetEntries,\n elements,\n submission,\n formElementsConditionallyShown,\n )\n return {\n entries: {\n setSchema: {\n presence: minSetEntries\n ? {\n message: `Must have at least ${minSetEntries} ${\n minSetEntries === 1 ? 'entry' : 'entries'\n }`,\n }\n : false,\n length: {\n minimum: minSetEntries,\n maximum: maxSetEntries,\n tooLong: 'Cannot have more than %{count} entry/entries',\n tooShort: 'Must have at least %{count} entry/entries',\n },\n },\n entrySchema: {\n schema: generateValidationSchema(\n formElement.elements as FormTypes.FormElementWithName[],\n elementIdsWithLookupsExecuted,\n ),\n formElementConditionallyShown:\n formElementsConditionallyShown?.[formElement.name],\n },\n },\n }\n }\n case 'civicaNameRecord': {\n const nestedElements = generateCivicaNameRecordElements(\n formElement,\n [],\n )\n return {\n nestedElements: {\n schema: generateValidationSchema(\n nestedElements as FormTypes.FormElementWithName[],\n elementIdsWithLookupsExecuted,\n ),\n formElementConditionallyShown:\n formElementsConditionallyShown?.[formElement.name],\n },\n }\n }\n case 'infoPage':\n case 'form': {\n if (formElement.elements) {\n return {\n nestedElements: {\n schema: generateValidationSchema(\n formElement.elements as FormTypes.FormElementWithName[],\n elementIdsWithLookupsExecuted,\n ),\n formElementConditionallyShown:\n formElementsConditionallyShown?.[formElement.name],\n },\n }\n }\n break\n }\n case 'freshdeskDependentField': {\n const nestedElements =\n generateFreshdeskDependentFieldElements(formElement)\n return {\n nestedElements: {\n schema: generateValidationSchema(\n nestedElements as FormTypes.FormElementWithName[],\n elementIdsWithLookupsExecuted,\n ),\n formElementConditionallyShown:\n formElementsConditionallyShown?.[formElement.name],\n },\n }\n }\n default: {\n console.info('Unsupported form element with validation', formElement)\n }\n }\n }\n partialSchema[escapeElementName(formElement.name)] = constraint\n return partialSchema\n }, {})\n}\n\nexport function validateSubmission(\n schema: ValidateJSSchema,\n submission: SubmissionTypes.S3SubmissionData['submission'] | undefined,\n formElementsConditionallyShown: FormElementsConditionallyShown | undefined,\n): FormElementsValidation | undefined {\n const errorsAsArray = validate(submission, schema, {\n format: 'grouped',\n fullMessages: false,\n formElementsConditionallyShown,\n })\n if (!errorsAsArray || validate.isEmpty(errorsAsArray)) {\n return\n }\n\n const errors = Object.keys(errorsAsArray || {}).reduce(\n (messagesByFormElementName: FormElementsValidation, key) => {\n const validationMessage = errorsAsArray[key][0]\n if (validationMessage) {\n messagesByFormElementName[key.replace(/\\\\./g, '.')] = validationMessage\n }\n return messagesByFormElementName\n },\n {},\n )\n if (validate.isEmpty(errors)) {\n return\n }\n\n return errors\n}\n\nexport function checkFileNameIsValid(\n formElement: FormTypes.FilesElement,\n fileName: string,\n) {\n const extension = fileName.split('.').pop()\n return (\n !formElement.restrictedFileTypes ||\n formElement.restrictedFileTypes.some(\n (fileType) => fileType.toLowerCase() === extension?.toLowerCase(),\n )\n )\n}\n\nexport function checkFileNameExtensionIsValid(\n formElement: FormTypes.FilesElement,\n fileName: string,\n) {\n return (\n formElement.allowExtensionlessAttachments || fileName.split('.').length >= 2\n )\n}\n\nexport function checkSectionValidity(\n element: FormTypes.PageElement | FormTypes.SectionElement,\n formElementsValidation: FormElementsValidation | undefined,\n): boolean {\n // If everything is valid, no need to check elements\n if (!formElementsValidation) {\n return false\n }\n\n // If there is no elements on the page that are invalid, we will treat as valid\n return element.elements.some((formElement) => {\n switch (formElement.type) {\n case 'page':\n case 'section': {\n return checkSectionValidity(formElement, formElementsValidation)\n }\n default: {\n return formElementsValidation[formElement.name]\n }\n }\n })\n}\n"]}
@@ -36,6 +36,8 @@ export default function generateFreshdeskDependentFieldElements(element) {
36
36
  hint: element.hint,
37
37
  defaultValue: (_a = element.defaultValue) === null || _a === void 0 ? void 0 : _a.category,
38
38
  options: element.options,
39
+ freshdeskFieldName: element.freshdeskFieldName,
40
+ optionsType: 'FRESHDESK_FIELD',
39
41
  };
40
42
  const formElements = [categoryElement];
41
43
  const subCategoryElement = {