@oneblink/apps-react 0.4.16 → 0.4.18-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/dist/OneBlinkFormBase.js +32 -1
  3. package/dist/OneBlinkFormBase.js.map +1 -1
  4. package/dist/components/OneBlinkFormElements.js +5 -0
  5. package/dist/components/OneBlinkFormElements.js.map +1 -1
  6. package/dist/form-elements/FormElementBSB.d.ts +18 -0
  7. package/dist/form-elements/FormElementBSB.js +94 -0
  8. package/dist/form-elements/FormElementBSB.js.map +1 -0
  9. package/dist/form-elements/FormElementDate.js +2 -1
  10. package/dist/form-elements/FormElementDate.js.map +1 -1
  11. package/dist/form-elements/FormElementLocation.d.ts +1 -1
  12. package/dist/form-elements/FormElementLocation.js +3 -1
  13. package/dist/form-elements/FormElementLocation.js.map +1 -1
  14. package/dist/form-elements/FormElementSummary.js +2 -1
  15. package/dist/form-elements/FormElementSummary.js.map +1 -1
  16. package/dist/services/checkBsbsAreInvalid.d.ts +3 -0
  17. package/dist/services/checkBsbsAreInvalid.js +41 -0
  18. package/dist/services/checkBsbsAreInvalid.js.map +1 -0
  19. package/dist/services/checkIfBsbsAreValidating.d.ts +3 -0
  20. package/dist/services/checkIfBsbsAreValidating.js +41 -0
  21. package/dist/services/checkIfBsbsAreValidating.js.map +1 -0
  22. package/dist/services/form-validation.js +14 -0
  23. package/dist/services/form-validation.js.map +1 -1
  24. package/dist/services/generate-default-data.js +8 -0
  25. package/dist/services/generate-default-data.js.map +1 -1
  26. package/dist/services/getCorrectDateFromDateOnlyString.d.ts +2 -0
  27. package/dist/services/getCorrectDateFromDateOnlyString.js +4 -0
  28. package/dist/services/getCorrectDateFromDateOnlyString.js.map +1 -0
  29. package/dist/styles/bsb.scss +10 -0
  30. package/dist/styles.css +11 -0
  31. package/dist/styles.css.map +1 -1
  32. package/dist/styles.scss +1 -0
  33. package/package.json +20 -17
@@ -0,0 +1,94 @@
1
+ import * as React from 'react';
2
+ import InputMask from 'react-input-mask';
3
+ import clsx from 'clsx';
4
+ import CopyToClipboardButton from '../components/CopyToClipboardButton';
5
+ import useBooleanState from '../hooks/useBooleanState';
6
+ import LookupButton from '../components/LookupButton';
7
+ import FormElementLabelContainer from '../components/FormElementLabelContainer';
8
+ import { formService } from '@oneblink/apps';
9
+ function FormElementBSB({ id, formId, element, value, onChange, validationMessage, displayValidationMessage, }) {
10
+ const [text, setText] = React.useState(typeof value === 'string' ? value : '');
11
+ const isValidFormat = /\d{3}-\d{3}/.test(text);
12
+ const [isDirty, setIsDirty] = useBooleanState(false);
13
+ const [{ isLoading, errorMessage, bsbRecord }, setState] = React.useState({
14
+ isLoading: false,
15
+ errorMessage: null,
16
+ bsbRecord: null,
17
+ });
18
+ React.useEffect(() => {
19
+ if (bsbRecord) {
20
+ onChange(element, bsbRecord.bsb);
21
+ }
22
+ }, [bsbRecord, element, onChange, value]);
23
+ React.useEffect(() => {
24
+ if (text === '') {
25
+ return;
26
+ }
27
+ if (!isValidFormat) {
28
+ setState({
29
+ isLoading: false,
30
+ errorMessage: null,
31
+ bsbRecord: null,
32
+ });
33
+ return;
34
+ }
35
+ setState({
36
+ isLoading: true,
37
+ errorMessage: null,
38
+ bsbRecord: null,
39
+ });
40
+ const abortController = new AbortController();
41
+ const getBSBRecord = async () => {
42
+ onChange(element, { isValidating: true, isInvalid: false });
43
+ try {
44
+ const bsbRecord = await formService.getBSBRecord(formId, text, abortController.signal);
45
+ if (!abortController.signal.aborted) {
46
+ setState({
47
+ isLoading: false,
48
+ errorMessage: null,
49
+ bsbRecord,
50
+ });
51
+ }
52
+ }
53
+ catch (error) {
54
+ console.warn('Error validating BSB number', error);
55
+ if (!abortController.signal.aborted) {
56
+ onChange(element, { isInvalid: true, isValidating: false });
57
+ setState({
58
+ isLoading: false,
59
+ errorMessage: `The BSB number "${text}" does not exist`,
60
+ bsbRecord: null,
61
+ });
62
+ }
63
+ }
64
+ };
65
+ getBSBRecord();
66
+ return () => {
67
+ abortController.abort();
68
+ };
69
+ }, [formId, isValidFormat, text, onChange, element]);
70
+ return (React.createElement("div", { className: "cypress-bsb-element" },
71
+ React.createElement(FormElementLabelContainer, { className: "ob-bsb", id: id, element: element, required: element.required },
72
+ React.createElement("div", { className: "field has-addons" },
73
+ React.createElement("div", { className: clsx('control is-expanded', {
74
+ 'is-loading': isLoading,
75
+ }) },
76
+ React.createElement(InputMask, { mask: "999-999",
77
+ // @ts-expect-error "maskChar" is not in the types, but it is in the docs
78
+ maskChar: "x", type: "text", placeholder: element.placeholderValue, id: id, name: element.name, className: "input ob-input cypress-bsb-control", value: text, onChange: (e) => setText(e.target.value), required: element.required, disabled: element.readOnly, onBlur: setIsDirty })),
79
+ bsbRecord && (React.createElement("div", { className: "control ob-bsb__record-control" },
80
+ React.createElement("a", { className: "button is-static ob-bsb__record-button" },
81
+ bsbRecord.financialInstitutionMnemonic,
82
+ " - ",
83
+ bsbRecord.name))),
84
+ !!element.readOnly && !!value && (React.createElement("div", { className: "control" },
85
+ React.createElement(CopyToClipboardButton, { className: "button is-input-addon cypress-copy-to-clipboard-button", isInputButton: true, text: text }))),
86
+ React.createElement(LookupButton, { isInputButton: true, value: value, validationMessage: validationMessage })),
87
+ (((isDirty || displayValidationMessage) &&
88
+ !!validationMessage &&
89
+ !isLoading) ||
90
+ errorMessage) && (React.createElement("div", { role: "alert", className: "has-margin-top-8" },
91
+ React.createElement("div", { className: "has-text-danger ob-error__text cypress-validation-message" }, errorMessage || validationMessage))))));
92
+ }
93
+ export default React.memo(FormElementBSB);
94
+ //# sourceMappingURL=FormElementBSB.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FormElementBSB.js","sourceRoot":"","sources":["../../src/form-elements/FormElementBSB.tsx"],"names":[],"mappings":"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","sourcesContent":["import * as React from 'react'\nimport InputMask from 'react-input-mask'\nimport clsx from 'clsx'\nimport CopyToClipboardButton from '../components/CopyToClipboardButton'\nimport useBooleanState from '../hooks/useBooleanState'\nimport LookupButton from '../components/LookupButton'\nimport { FormTypes, MiscTypes } from '@oneblink/types'\nimport FormElementLabelContainer from '../components/FormElementLabelContainer'\nimport { FormElementValueChangeHandler } from '../types/form'\nimport { formService } from '@oneblink/apps'\n\ntype Props = {\n id: string\n formId: number\n element: FormTypes.BSBElement\n value: unknown\n onChange: FormElementValueChangeHandler<\n string | { isInvalid: boolean; isValidating: boolean }\n >\n displayValidationMessage: boolean\n validationMessage: string | undefined\n}\n\nfunction FormElementBSB({\n id,\n formId,\n element,\n value,\n onChange,\n validationMessage,\n displayValidationMessage,\n}: Props) {\n const [text, setText] = React.useState(typeof value === 'string' ? value : '')\n const isValidFormat = /\\d{3}-\\d{3}/.test(text)\n\n const [isDirty, setIsDirty] = useBooleanState(false)\n const [{ isLoading, errorMessage, bsbRecord }, setState] = React.useState<{\n isLoading: boolean\n errorMessage: string | null\n bsbRecord: MiscTypes.BSBRecord | null\n }>({\n isLoading: false,\n errorMessage: null,\n bsbRecord: null,\n })\n\n React.useEffect(() => {\n if (bsbRecord) {\n onChange(element, bsbRecord.bsb)\n }\n }, [bsbRecord, element, onChange, value])\n\n React.useEffect(() => {\n if (text === '') {\n return\n }\n\n if (!isValidFormat) {\n setState({\n isLoading: false,\n errorMessage: null,\n bsbRecord: null,\n })\n return\n }\n\n setState({\n isLoading: true,\n errorMessage: null,\n bsbRecord: null,\n })\n\n const abortController = new AbortController()\n const getBSBRecord = async () => {\n onChange(element, { isValidating: true, isInvalid: false })\n try {\n const bsbRecord = await formService.getBSBRecord(\n formId,\n text,\n abortController.signal,\n )\n if (!abortController.signal.aborted) {\n setState({\n isLoading: false,\n errorMessage: null,\n bsbRecord,\n })\n }\n } catch (error) {\n console.warn('Error validating BSB number', error)\n if (!abortController.signal.aborted) {\n onChange(element, { isInvalid: true, isValidating: false })\n setState({\n isLoading: false,\n errorMessage: `The BSB number \"${text}\" does not exist`,\n bsbRecord: null,\n })\n }\n }\n }\n\n getBSBRecord()\n\n return () => {\n abortController.abort()\n }\n }, [formId, isValidFormat, text, onChange, element])\n\n return (\n <div className=\"cypress-bsb-element\">\n <FormElementLabelContainer\n className=\"ob-bsb\"\n id={id}\n element={element}\n required={element.required}\n >\n <div className=\"field has-addons\">\n <div\n className={clsx('control is-expanded', {\n 'is-loading': isLoading,\n })}\n >\n <InputMask\n mask=\"999-999\"\n // @ts-expect-error \"maskChar\" is not in the types, but it is in the docs\n maskChar=\"x\"\n type=\"text\"\n placeholder={element.placeholderValue}\n id={id}\n name={element.name}\n className=\"input ob-input cypress-bsb-control\"\n value={text}\n onChange={(e) => setText(e.target.value)}\n required={element.required}\n disabled={element.readOnly}\n onBlur={setIsDirty}\n />\n </div>\n {bsbRecord && (\n <div className=\"control ob-bsb__record-control\">\n <a className=\"button is-static ob-bsb__record-button\">\n {bsbRecord.financialInstitutionMnemonic} - {bsbRecord.name}\n </a>\n </div>\n )}\n {!!element.readOnly && !!value && (\n <div className=\"control\">\n <CopyToClipboardButton\n className=\"button is-input-addon cypress-copy-to-clipboard-button\"\n isInputButton\n text={text}\n />\n </div>\n )}\n <LookupButton\n isInputButton\n value={value}\n validationMessage={validationMessage}\n />\n </div>\n {(((isDirty || displayValidationMessage) &&\n !!validationMessage &&\n !isLoading) ||\n errorMessage) && (\n <div role=\"alert\" className=\"has-margin-top-8\">\n <div className=\"has-text-danger ob-error__text cypress-validation-message\">\n {errorMessage || validationMessage}\n </div>\n </div>\n )}\n </FormElementLabelContainer>\n </div>\n )\n}\n\nexport default React.memo(FormElementBSB)\n"]}
@@ -6,6 +6,7 @@ import useBooleanState from '../hooks/useBooleanState';
6
6
  import LookupButton from '../components/LookupButton';
7
7
  import FormElementLabelContainer from '../components/FormElementLabelContainer';
8
8
  import { parseDateValue } from '../services/generate-default-data';
9
+ import getCorrectDateFromDateOnlyString from '../services/getCorrectDateFromDateOnlyString';
9
10
  function FormElementDate({ id, element, value, onChange, validationMessage, displayValidationMessage, }) {
10
11
  const htmlDivElementRef = React.useRef(null);
11
12
  const [isDirty, setIsDirty] = useBooleanState(false);
@@ -49,7 +50,7 @@ function FormElementDate({ id, element, value, onChange, validationMessage, disp
49
50
  if (typeof value !== 'string') {
50
51
  return null;
51
52
  }
52
- return localisationService.formatDate(new Date(value));
53
+ return localisationService.formatDate(getCorrectDateFromDateOnlyString(value));
53
54
  }, [value]);
54
55
  return (React.createElement("div", { className: "cypress-date-element", ref: htmlDivElementRef },
55
56
  React.createElement(FormElementLabelContainer, { className: "ob-date", id: id, element: element, required: element.required },
@@ -1 +1 @@
1
- {"version":3,"file":"FormElementDate.js","sourceRoot":"","sources":["../../src/form-elements/FormElementDate.tsx"],"names":[],"mappings":"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","sourcesContent":["import * as React from 'react'\nimport { localisationService } from '@oneblink/apps'\n\nimport CopyToClipboardButton from '../components/CopyToClipboardButton'\nimport useFlatpickr, { FlatpickrOptions } from '../hooks/useFlatpickr'\nimport useBooleanState from '../hooks/useBooleanState'\nimport LookupButton from '../components/LookupButton'\nimport { FormTypes } from '@oneblink/types'\nimport FormElementLabelContainer from '../components/FormElementLabelContainer'\nimport { parseDateValue } from '../services/generate-default-data'\nimport { FormElementValueChangeHandler } from '../types/form'\n\ntype Props = {\n id: string\n element: FormTypes.DateElement\n value: unknown | undefined\n onChange: FormElementValueChangeHandler<string>\n displayValidationMessage: boolean\n validationMessage: string | undefined\n}\n\nfunction FormElementDate({\n id,\n element,\n value,\n onChange,\n validationMessage,\n displayValidationMessage,\n}: Props) {\n const htmlDivElementRef = React.useRef<HTMLDivElement>(null)\n\n const [isDirty, setIsDirty] = useBooleanState(false)\n\n const flatpickrOptions = React.useMemo(() => {\n const opts: FlatpickrOptions = {\n altInput: true,\n dateFormat: 'Y-m-d',\n altFormat: localisationService.flatpickrDateFormat,\n allowInput: true,\n altInputClass: 'input ob-input cypress-date-control',\n minDate: parseDateValue({\n dateOnly: false,\n daysOffset: element.fromDateDaysOffset,\n value: element.fromDate,\n }),\n maxDate: parseDateValue({\n dateOnly: false,\n daysOffset: element.toDateDaysOffset,\n value: element.toDate,\n }),\n defaultDate: undefined,\n allowInvalidPreload: true,\n onClose: setIsDirty,\n }\n\n return opts\n }, [\n element.fromDate,\n element.fromDateDaysOffset,\n element.toDate,\n element.toDateDaysOffset,\n setIsDirty,\n ])\n\n const handleChange = React.useCallback(\n (newValue) => onChange(element, newValue),\n [element, onChange],\n )\n\n useFlatpickr(\n {\n id,\n value,\n onChange: handleChange,\n dateOnly: true,\n },\n flatpickrOptions,\n htmlDivElementRef,\n )\n\n const text = React.useMemo(() => {\n if (typeof value !== 'string') {\n return null\n }\n return localisationService.formatDate(new Date(value))\n }, [value])\n\n return (\n <div className=\"cypress-date-element\" ref={htmlDivElementRef}>\n <FormElementLabelContainer\n className=\"ob-date\"\n id={id}\n element={element}\n required={element.required}\n >\n <div className=\"field has-addons\">\n <div className=\"control is-expanded has-icons-right\">\n <input\n type=\"date\"\n id={id}\n name={element.name}\n placeholder={element.placeholderValue}\n disabled={element.readOnly}\n className=\"input ob-input\"\n />\n <span className=\"ob-input-icon icon is-small is-right\">\n <i className=\"material-icons is-size-5\">event</i>\n </span>\n </div>\n {!!element.readOnly && !!text && (\n <div className=\"control\">\n <CopyToClipboardButton\n className=\"button is-input-addon cypress-copy-to-clipboard-button\"\n isInputButton\n text={text}\n />\n </div>\n )}\n <LookupButton\n isInputButton\n value={value}\n validationMessage={validationMessage}\n />\n </div>\n\n {(isDirty || displayValidationMessage) && !!validationMessage && (\n <div role=\"alert\" className=\"has-margin-top-8\">\n <div className=\"has-text-danger ob-error__text cypress-validation-message\">\n {validationMessage}\n </div>\n </div>\n )}\n </FormElementLabelContainer>\n </div>\n )\n}\n\nexport default React.memo(FormElementDate)\n"]}
1
+ {"version":3,"file":"FormElementDate.js","sourceRoot":"","sources":["../../src/form-elements/FormElementDate.tsx"],"names":[],"mappings":"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","sourcesContent":["import * as React from 'react'\nimport { localisationService } from '@oneblink/apps'\n\nimport CopyToClipboardButton from '../components/CopyToClipboardButton'\nimport useFlatpickr, { FlatpickrOptions } from '../hooks/useFlatpickr'\nimport useBooleanState from '../hooks/useBooleanState'\nimport LookupButton from '../components/LookupButton'\nimport { FormTypes } from '@oneblink/types'\nimport FormElementLabelContainer from '../components/FormElementLabelContainer'\nimport { parseDateValue } from '../services/generate-default-data'\nimport { FormElementValueChangeHandler } from '../types/form'\nimport getCorrectDateFromDateOnlyString from '../services/getCorrectDateFromDateOnlyString'\n\ntype Props = {\n id: string\n element: FormTypes.DateElement\n value: unknown | undefined\n onChange: FormElementValueChangeHandler<string>\n displayValidationMessage: boolean\n validationMessage: string | undefined\n}\n\nfunction FormElementDate({\n id,\n element,\n value,\n onChange,\n validationMessage,\n displayValidationMessage,\n}: Props) {\n const htmlDivElementRef = React.useRef<HTMLDivElement>(null)\n\n const [isDirty, setIsDirty] = useBooleanState(false)\n\n const flatpickrOptions = React.useMemo(() => {\n const opts: FlatpickrOptions = {\n altInput: true,\n dateFormat: 'Y-m-d',\n altFormat: localisationService.flatpickrDateFormat,\n allowInput: true,\n altInputClass: 'input ob-input cypress-date-control',\n minDate: parseDateValue({\n dateOnly: false,\n daysOffset: element.fromDateDaysOffset,\n value: element.fromDate,\n }),\n maxDate: parseDateValue({\n dateOnly: false,\n daysOffset: element.toDateDaysOffset,\n value: element.toDate,\n }),\n defaultDate: undefined,\n allowInvalidPreload: true,\n onClose: setIsDirty,\n }\n\n return opts\n }, [\n element.fromDate,\n element.fromDateDaysOffset,\n element.toDate,\n element.toDateDaysOffset,\n setIsDirty,\n ])\n\n const handleChange = React.useCallback(\n (newValue) => onChange(element, newValue),\n [element, onChange],\n )\n\n useFlatpickr(\n {\n id,\n value,\n onChange: handleChange,\n dateOnly: true,\n },\n flatpickrOptions,\n htmlDivElementRef,\n )\n\n const text = React.useMemo(() => {\n if (typeof value !== 'string') {\n return null\n }\n return localisationService.formatDate(\n getCorrectDateFromDateOnlyString(value),\n )\n }, [value])\n\n return (\n <div className=\"cypress-date-element\" ref={htmlDivElementRef}>\n <FormElementLabelContainer\n className=\"ob-date\"\n id={id}\n element={element}\n required={element.required}\n >\n <div className=\"field has-addons\">\n <div className=\"control is-expanded has-icons-right\">\n <input\n type=\"date\"\n id={id}\n name={element.name}\n placeholder={element.placeholderValue}\n disabled={element.readOnly}\n className=\"input ob-input\"\n />\n <span className=\"ob-input-icon icon is-small is-right\">\n <i className=\"material-icons is-size-5\">event</i>\n </span>\n </div>\n {!!element.readOnly && !!text && (\n <div className=\"control\">\n <CopyToClipboardButton\n className=\"button is-input-addon cypress-copy-to-clipboard-button\"\n isInputButton\n text={text}\n />\n </div>\n )}\n <LookupButton\n isInputButton\n value={value}\n validationMessage={validationMessage}\n />\n </div>\n\n {(isDirty || displayValidationMessage) && !!validationMessage && (\n <div role=\"alert\" className=\"has-margin-top-8\">\n <div className=\"has-text-danger ob-error__text cypress-validation-message\">\n {validationMessage}\n </div>\n </div>\n )}\n </FormElementLabelContainer>\n </div>\n )\n}\n\nexport default React.memo(FormElementDate)\n"]}
@@ -12,7 +12,7 @@ declare type Props = {
12
12
  declare type Coords = {
13
13
  latitude: number;
14
14
  longitude: number;
15
- zoom: number;
15
+ zoom?: number;
16
16
  };
17
17
  export declare const stringifyLocation: (location: Coords | undefined) => string | undefined;
18
18
  declare function FormElementLocation({ id, element, value, onChange, validationMessage, displayValidationMessage, }: Props): JSX.Element;
@@ -181,7 +181,6 @@ const LocationPicker = React.memo(function SummaryResult({ location, onChange, }
181
181
  onChange({
182
182
  latitude: location.latitude,
183
183
  longitude: location.longitude,
184
- // @ts-expect-error ???
185
184
  zoom: map.getZoom(),
186
185
  });
187
186
  }, [location.latitude, location.longitude, map, onChange]);
@@ -191,6 +190,9 @@ const LocationPicker = React.memo(function SummaryResult({ location, onChange, }
191
190
  height: 300,
192
191
  }, center: center, zoom: location.zoom, onZoomChanged: onZoomChanged },
193
192
  React.createElement(Marker, { animation: 2, position: center, draggable: true, onDragEnd: (e) => {
193
+ if (!e.latLng) {
194
+ return;
195
+ }
194
196
  const { lat, lng } = e.latLng.toJSON();
195
197
  onChange({
196
198
  latitude: lat,
@@ -1 +1 @@
1
- {"version":3,"file":"FormElementLocation.js","sourceRoot":"","sources":["../../src/form-elements/FormElementLocation.tsx"],"names":[],"mappings":"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","sourcesContent":["import * as React from 'react'\nimport useBooleanState from '../hooks/useBooleanState'\nimport useIsOffline from '../hooks/useIsOffline'\nimport { GoogleMap, LoadScript, Marker } from '@react-google-maps/api'\nimport geolocation from '@blinkmobile/geolocation'\nimport queryString from 'query-string'\nimport OnLoading from '../components/OnLoading'\nimport defaultCoords from '../services/defaultCoordinates'\nimport useGoogleMapsApiKeyKey from '../hooks/useGoogleMapsApiKey'\nimport { FormTypes } from '@oneblink/types'\nimport FormElementLabelContainer from '../components/FormElementLabelContainer'\nimport { Sentry } from '@oneblink/apps'\nimport { FormElementValueChangeHandler } from '../types/form'\n\ntype Props = {\n id: string\n element: FormTypes.LocationElement\n value: unknown | undefined\n onChange: FormElementValueChangeHandler<Coords>\n displayValidationMessage: boolean\n validationMessage: string | undefined\n}\n\ntype Coords = {\n latitude: number\n longitude: number\n zoom: number\n}\n\nexport const stringifyLocation = (location: Coords | undefined) => {\n if (location) {\n return `${location.latitude},${location.longitude}`\n }\n}\n\nfunction parseLocationValue(value: unknown): Coords | undefined {\n if (!value || typeof value !== 'object') {\n return\n }\n\n const { latitude, longitude, zoom } = value as Record<string, unknown>\n if (typeof latitude !== 'number' || typeof longitude !== 'number') {\n return\n }\n\n return {\n latitude,\n longitude,\n zoom: typeof zoom === 'number' ? zoom : initialMapZoom,\n }\n}\n\nconst mapHeight = 300\nconst initialMapZoom = 15\nconst apiUrl = 'https://maps.googleapis.com/maps/api/staticmap'\nfunction FormElementLocation({\n id,\n element,\n value,\n onChange,\n validationMessage,\n displayValidationMessage,\n}: Props) {\n const [isDirty, setIsDirty] = useBooleanState(false)\n const [isLocationPickerOpen, showLocationPicker, hideLocationPicker] =\n useBooleanState(false)\n\n const [location, setLocation] = React.useState<Coords | undefined>(undefined)\n const onClear = React.useCallback(() => {\n hideLocationPicker()\n onChange(element, undefined)\n setLocation(undefined)\n }, [element, hideLocationPicker, onChange])\n\n const onCancel = React.useCallback(() => {\n hideLocationPicker()\n setLocation(parseLocationValue(value))\n }, [hideLocationPicker, value])\n\n const onLocate = React.useCallback(async () => {\n showLocationPicker()\n\n if (location) {\n return\n }\n\n let currentLocation = null\n try {\n const result = await geolocation.getCurrentPosition()\n currentLocation = result.coords\n } catch (err) {\n console.error(\n 'Error while attempting to find the users current location',\n err,\n )\n Sentry.captureException(err)\n } finally {\n setLocation(parseLocationValue(currentLocation || defaultCoords()))\n }\n }, [location, showLocationPicker])\n\n const isLoadingLocation = !location && isLocationPickerOpen\n\n const onConfirm = React.useCallback(() => {\n setIsDirty()\n hideLocationPicker()\n onChange(element, location)\n }, [element, hideLocationPicker, location, onChange, setIsDirty])\n\n // SET DEFAULT/PREFILL DATA\n React.useEffect(() => {\n const newValue = parseLocationValue(value)\n if (newValue) {\n setLocation(newValue)\n }\n }, [value])\n\n return (\n <div className=\"cypress-location-element\">\n <FormElementLabelContainer\n className=\"ob-location\"\n id={id}\n element={element}\n required={element.required}\n >\n <div className=\"control\">\n <LocationDisplay\n isOpen={isLocationPickerOpen}\n isLoading={isLoadingLocation}\n location={location}\n onChange={setLocation}\n />\n\n <div className=\"buttons ob-buttons ob-location__buttons\">\n {isLocationPickerOpen ? (\n <>\n <button\n type=\"button\"\n className=\"is-light button ob-button ob-button__cancel ob-location__button ob-location__button-cancel cypress-cancel-location-button\"\n onClick={onCancel}\n disabled={element.readOnly}\n >\n Cancel\n </button>\n <button\n type=\"button\"\n className=\"is-primary button ob-button ob-button__confirm ob-location__button ob-location__button-confirm cypress-confirm-location-button\"\n onClick={onConfirm}\n disabled={element.readOnly || !location}\n >\n Confirm\n </button>\n </>\n ) : (\n <>\n <button\n type=\"button\"\n className=\"is-light button ob-button ob-button__clear ob-button-clear ob-location__button ob-location__button-clear cypress-clear-location-button\"\n onClick={onClear}\n disabled={element.readOnly}\n >\n Clear\n </button>\n <button\n type=\"button\"\n className=\"is-primary button ob-button ob-button__edit ob-location__button ob-location__button-edit cypress-locate-button\"\n onClick={onLocate}\n disabled={element.readOnly}\n >\n Locate\n </button>\n </>\n )}\n </div>\n </div>\n\n {(isDirty || displayValidationMessage) && !!validationMessage && (\n <div role=\"alert\" className=\"has-margin-top-8\">\n <div className=\"has-text-danger ob-error__text cypress-validation-message\">\n {validationMessage}\n </div>\n </div>\n )}\n </FormElementLabelContainer>\n </div>\n )\n}\n\nconst LocationDisplay = React.memo(function LocationDisplay({\n isLoading,\n isOpen,\n location,\n onChange,\n}: {\n isLoading: boolean\n isOpen: boolean\n location: Coords | undefined\n onChange: (location: Coords) => void\n}) {\n const isOffline = useIsOffline()\n\n if (isLoading) {\n return (\n <figure className=\"ob-figure\">\n <div className=\"figure-content\">\n <OnLoading small></OnLoading>\n </div>\n </figure>\n )\n }\n\n if (isOffline) {\n return <LocationIsOffline location={location} isOpen={isOpen} />\n }\n\n if (isOpen) {\n if (!location) {\n // There is no location to display while user is attempting to pick a location.\n // This should never happen, if loading has finished a default should be set.\n // Fail fast!!!\n // https://en.wikipedia.org/wiki/Fail-fast\n throw new Error(\n 'Default location was not set for \"location\" form element',\n )\n }\n\n return <LocationPicker location={location} onChange={onChange} />\n }\n\n if (location) {\n return <LocationImage location={location} />\n }\n\n return null\n})\n\nfunction LocationIsOfflineFigureContent({\n children,\n}: {\n children: React.ReactNode\n}) {\n return (\n <figure className=\"ob-figure\">\n <div className=\"figure-content has-text-centered\">\n <h4 className=\"title is-4\">You are currently offline</h4>\n {children}\n </div>\n </figure>\n )\n}\n\nconst LocationIsOffline = React.memo(function LocationIsOffline({\n location,\n isOpen,\n}: {\n location: Coords | undefined\n isOpen: boolean\n}) {\n if (isOpen) {\n if (location) {\n // If user is offline and attempting to pick a location and there is one set already\n return (\n <LocationIsOfflineFigureContent>\n <p>\n Click the <b>Confirm</b> button below to set the location to your\n current position.\n </p>\n </LocationIsOfflineFigureContent>\n )\n }\n\n // If user is offline and attempting to pick a location and there is one nothing set yet\n return (\n <LocationIsOfflineFigureContent>\n <p>\n We could not find your current location. Click the <b>Cancel</b>{' '}\n button below to try again.\n </p>\n </LocationIsOfflineFigureContent>\n )\n }\n\n // If user is offline and has confirmed a location\n if (location) {\n return (\n <LocationIsOfflineFigureContent>\n <h3 className=\"title is-3 ob-location__latitude\">Latitude</h3>\n <p>\n <b>{location.latitude}</b>\n </p>\n <h3 className=\"title is-3 ob-location__longitude\">Longitude</h3>\n <p>\n <b>{location.longitude}</b>\n </p>\n </LocationIsOfflineFigureContent>\n )\n }\n\n // User is offline with no location set and not attempting to pick a location\n return null\n})\n\nconst LocationImage = React.memo(function LocationImage({\n location,\n}: {\n location: Coords\n}) {\n const googleMapsApiKey = useGoogleMapsApiKeyKey()\n\n const staticUrl = React.useMemo(() => {\n const center = `${location.latitude},${location.longitude}`\n const queries = {\n key: googleMapsApiKey,\n size: `${mapHeight}x${mapHeight}`,\n zoom: location.zoom,\n center,\n markers: `color:red|${center}`,\n }\n return `${apiUrl}?${queryString.stringify(queries)}`\n }, [googleMapsApiKey, location])\n\n return (\n <figure className=\"ob-figure\">\n <img\n className=\"ob-location__map\"\n alt={`map with center at ${location.latitude} latitude, ${location.longitude} longitude`}\n src={staticUrl}\n height={mapHeight}\n width={mapHeight}\n />\n </figure>\n )\n})\n\nconst LocationPicker = React.memo(function SummaryResult({\n location,\n onChange,\n}: {\n location: Coords\n onChange: (newLocation: Coords) => void\n}) {\n const googleMapsApiKey = useGoogleMapsApiKeyKey()\n\n const [map, setMap] = React.useState(null)\n\n const center = React.useMemo(() => {\n return {\n lat: location.latitude,\n lng: location.longitude,\n }\n }, [location.latitude, location.longitude])\n\n const onZoomChanged = React.useCallback(() => {\n if (!map) {\n return\n }\n\n onChange({\n latitude: location.latitude,\n longitude: location.longitude,\n // @ts-expect-error ???\n zoom: map.getZoom(),\n })\n }, [location.latitude, location.longitude, map, onChange])\n\n return (\n <figure className=\"ob-figure\">\n <LoadScript googleMapsApiKey={googleMapsApiKey || ''}>\n <GoogleMap\n onLoad={(map) => setMap(map)}\n onUnmount={() => setMap(null)}\n mapContainerStyle={{\n height: 300,\n }}\n center={center}\n zoom={location.zoom}\n onZoomChanged={onZoomChanged}\n >\n <Marker\n animation={2} // DOCUMENTATION IS POOR, THIS IS DROP ANIMATION\n position={center}\n draggable\n onDragEnd={(e) => {\n const { lat, lng } = e.latLng.toJSON()\n onChange({\n latitude: lat,\n longitude: lng,\n zoom: location.zoom,\n })\n }}\n ></Marker>\n </GoogleMap>\n </LoadScript>\n </figure>\n )\n})\n\nexport default React.memo(FormElementLocation)\n"]}
1
+ {"version":3,"file":"FormElementLocation.js","sourceRoot":"","sources":["../../src/form-elements/FormElementLocation.tsx"],"names":[],"mappings":"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","sourcesContent":["import * as React from 'react'\nimport useBooleanState from '../hooks/useBooleanState'\nimport useIsOffline from '../hooks/useIsOffline'\nimport { GoogleMap, LoadScript, Marker } from '@react-google-maps/api'\nimport geolocation from '@blinkmobile/geolocation'\nimport queryString from 'query-string'\nimport OnLoading from '../components/OnLoading'\nimport defaultCoords from '../services/defaultCoordinates'\nimport useGoogleMapsApiKeyKey from '../hooks/useGoogleMapsApiKey'\nimport { FormTypes } from '@oneblink/types'\nimport FormElementLabelContainer from '../components/FormElementLabelContainer'\nimport { Sentry } from '@oneblink/apps'\nimport { FormElementValueChangeHandler } from '../types/form'\n\ntype Props = {\n id: string\n element: FormTypes.LocationElement\n value: unknown | undefined\n onChange: FormElementValueChangeHandler<Coords>\n displayValidationMessage: boolean\n validationMessage: string | undefined\n}\n\ntype Coords = {\n latitude: number\n longitude: number\n zoom?: number\n}\n\nexport const stringifyLocation = (location: Coords | undefined) => {\n if (location) {\n return `${location.latitude},${location.longitude}`\n }\n}\n\nfunction parseLocationValue(value: unknown): Coords | undefined {\n if (!value || typeof value !== 'object') {\n return\n }\n\n const { latitude, longitude, zoom } = value as Record<string, unknown>\n if (typeof latitude !== 'number' || typeof longitude !== 'number') {\n return\n }\n\n return {\n latitude,\n longitude,\n zoom: typeof zoom === 'number' ? zoom : initialMapZoom,\n }\n}\n\nconst mapHeight = 300\nconst initialMapZoom = 15\nconst apiUrl = 'https://maps.googleapis.com/maps/api/staticmap'\nfunction FormElementLocation({\n id,\n element,\n value,\n onChange,\n validationMessage,\n displayValidationMessage,\n}: Props) {\n const [isDirty, setIsDirty] = useBooleanState(false)\n const [isLocationPickerOpen, showLocationPicker, hideLocationPicker] =\n useBooleanState(false)\n\n const [location, setLocation] = React.useState<Coords | undefined>(undefined)\n const onClear = React.useCallback(() => {\n hideLocationPicker()\n onChange(element, undefined)\n setLocation(undefined)\n }, [element, hideLocationPicker, onChange])\n\n const onCancel = React.useCallback(() => {\n hideLocationPicker()\n setLocation(parseLocationValue(value))\n }, [hideLocationPicker, value])\n\n const onLocate = React.useCallback(async () => {\n showLocationPicker()\n\n if (location) {\n return\n }\n\n let currentLocation = null\n try {\n const result = await geolocation.getCurrentPosition()\n currentLocation = result.coords\n } catch (err) {\n console.error(\n 'Error while attempting to find the users current location',\n err,\n )\n Sentry.captureException(err)\n } finally {\n setLocation(parseLocationValue(currentLocation || defaultCoords()))\n }\n }, [location, showLocationPicker])\n\n const isLoadingLocation = !location && isLocationPickerOpen\n\n const onConfirm = React.useCallback(() => {\n setIsDirty()\n hideLocationPicker()\n onChange(element, location)\n }, [element, hideLocationPicker, location, onChange, setIsDirty])\n\n // SET DEFAULT/PREFILL DATA\n React.useEffect(() => {\n const newValue = parseLocationValue(value)\n if (newValue) {\n setLocation(newValue)\n }\n }, [value])\n\n return (\n <div className=\"cypress-location-element\">\n <FormElementLabelContainer\n className=\"ob-location\"\n id={id}\n element={element}\n required={element.required}\n >\n <div className=\"control\">\n <LocationDisplay\n isOpen={isLocationPickerOpen}\n isLoading={isLoadingLocation}\n location={location}\n onChange={setLocation}\n />\n\n <div className=\"buttons ob-buttons ob-location__buttons\">\n {isLocationPickerOpen ? (\n <>\n <button\n type=\"button\"\n className=\"is-light button ob-button ob-button__cancel ob-location__button ob-location__button-cancel cypress-cancel-location-button\"\n onClick={onCancel}\n disabled={element.readOnly}\n >\n Cancel\n </button>\n <button\n type=\"button\"\n className=\"is-primary button ob-button ob-button__confirm ob-location__button ob-location__button-confirm cypress-confirm-location-button\"\n onClick={onConfirm}\n disabled={element.readOnly || !location}\n >\n Confirm\n </button>\n </>\n ) : (\n <>\n <button\n type=\"button\"\n className=\"is-light button ob-button ob-button__clear ob-button-clear ob-location__button ob-location__button-clear cypress-clear-location-button\"\n onClick={onClear}\n disabled={element.readOnly}\n >\n Clear\n </button>\n <button\n type=\"button\"\n className=\"is-primary button ob-button ob-button__edit ob-location__button ob-location__button-edit cypress-locate-button\"\n onClick={onLocate}\n disabled={element.readOnly}\n >\n Locate\n </button>\n </>\n )}\n </div>\n </div>\n\n {(isDirty || displayValidationMessage) && !!validationMessage && (\n <div role=\"alert\" className=\"has-margin-top-8\">\n <div className=\"has-text-danger ob-error__text cypress-validation-message\">\n {validationMessage}\n </div>\n </div>\n )}\n </FormElementLabelContainer>\n </div>\n )\n}\n\nconst LocationDisplay = React.memo(function LocationDisplay({\n isLoading,\n isOpen,\n location,\n onChange,\n}: {\n isLoading: boolean\n isOpen: boolean\n location: Coords | undefined\n onChange: (location: Coords) => void\n}) {\n const isOffline = useIsOffline()\n\n if (isLoading) {\n return (\n <figure className=\"ob-figure\">\n <div className=\"figure-content\">\n <OnLoading small></OnLoading>\n </div>\n </figure>\n )\n }\n\n if (isOffline) {\n return <LocationIsOffline location={location} isOpen={isOpen} />\n }\n\n if (isOpen) {\n if (!location) {\n // There is no location to display while user is attempting to pick a location.\n // This should never happen, if loading has finished a default should be set.\n // Fail fast!!!\n // https://en.wikipedia.org/wiki/Fail-fast\n throw new Error(\n 'Default location was not set for \"location\" form element',\n )\n }\n\n return <LocationPicker location={location} onChange={onChange} />\n }\n\n if (location) {\n return <LocationImage location={location} />\n }\n\n return null\n})\n\nfunction LocationIsOfflineFigureContent({\n children,\n}: {\n children: React.ReactNode\n}) {\n return (\n <figure className=\"ob-figure\">\n <div className=\"figure-content has-text-centered\">\n <h4 className=\"title is-4\">You are currently offline</h4>\n {children}\n </div>\n </figure>\n )\n}\n\nconst LocationIsOffline = React.memo(function LocationIsOffline({\n location,\n isOpen,\n}: {\n location: Coords | undefined\n isOpen: boolean\n}) {\n if (isOpen) {\n if (location) {\n // If user is offline and attempting to pick a location and there is one set already\n return (\n <LocationIsOfflineFigureContent>\n <p>\n Click the <b>Confirm</b> button below to set the location to your\n current position.\n </p>\n </LocationIsOfflineFigureContent>\n )\n }\n\n // If user is offline and attempting to pick a location and there is one nothing set yet\n return (\n <LocationIsOfflineFigureContent>\n <p>\n We could not find your current location. Click the <b>Cancel</b>{' '}\n button below to try again.\n </p>\n </LocationIsOfflineFigureContent>\n )\n }\n\n // If user is offline and has confirmed a location\n if (location) {\n return (\n <LocationIsOfflineFigureContent>\n <h3 className=\"title is-3 ob-location__latitude\">Latitude</h3>\n <p>\n <b>{location.latitude}</b>\n </p>\n <h3 className=\"title is-3 ob-location__longitude\">Longitude</h3>\n <p>\n <b>{location.longitude}</b>\n </p>\n </LocationIsOfflineFigureContent>\n )\n }\n\n // User is offline with no location set and not attempting to pick a location\n return null\n})\n\nconst LocationImage = React.memo(function LocationImage({\n location,\n}: {\n location: Coords\n}) {\n const googleMapsApiKey = useGoogleMapsApiKeyKey()\n\n const staticUrl = React.useMemo(() => {\n const center = `${location.latitude},${location.longitude}`\n const queries = {\n key: googleMapsApiKey,\n size: `${mapHeight}x${mapHeight}`,\n zoom: location.zoom,\n center,\n markers: `color:red|${center}`,\n }\n return `${apiUrl}?${queryString.stringify(queries)}`\n }, [googleMapsApiKey, location])\n\n return (\n <figure className=\"ob-figure\">\n <img\n className=\"ob-location__map\"\n alt={`map with center at ${location.latitude} latitude, ${location.longitude} longitude`}\n src={staticUrl}\n height={mapHeight}\n width={mapHeight}\n />\n </figure>\n )\n})\n\nconst LocationPicker = React.memo(function SummaryResult({\n location,\n onChange,\n}: {\n location: Coords\n onChange: (newLocation: Coords) => void\n}) {\n const googleMapsApiKey = useGoogleMapsApiKeyKey()\n\n const [map, setMap] = React.useState<google.maps.Map | null>(null)\n\n const center = React.useMemo(() => {\n return {\n lat: location.latitude,\n lng: location.longitude,\n }\n }, [location.latitude, location.longitude])\n\n const onZoomChanged = React.useCallback(() => {\n if (!map) {\n return\n }\n\n onChange({\n latitude: location.latitude,\n longitude: location.longitude,\n zoom: map.getZoom(),\n })\n }, [location.latitude, location.longitude, map, onChange])\n\n return (\n <figure className=\"ob-figure\">\n <LoadScript googleMapsApiKey={googleMapsApiKey || ''}>\n <GoogleMap\n onLoad={(map) => setMap(map)}\n onUnmount={() => setMap(null)}\n mapContainerStyle={{\n height: 300,\n }}\n center={center}\n zoom={location.zoom}\n onZoomChanged={onZoomChanged}\n >\n <Marker\n animation={2} // DOCUMENTATION IS POOR, THIS IS DROP ANIMATION\n position={center}\n draggable\n onDragEnd={(e) => {\n if (!e.latLng) {\n return\n }\n const { lat, lng } = e.latLng.toJSON()\n onChange({\n latitude: lat,\n longitude: lng,\n zoom: location.zoom,\n })\n }}\n ></Marker>\n </GoogleMap>\n </LoadScript>\n </figure>\n )\n})\n\nexport default React.memo(FormElementLocation)\n"]}
@@ -2,6 +2,7 @@ import * as React from 'react';
2
2
  import { localisationService } from '@oneblink/apps';
3
3
  import useFormSubmissionModel from '../hooks/useFormSubmissionModelContext';
4
4
  import useFlattenElements from '../hooks/useFlattenElementsContext';
5
+ import getCorrectDateFromDateOnlyString from '../services/getCorrectDateFromDateOnlyString';
5
6
  const arraysAreEqual = (a, b) => {
6
7
  if (!Array.isArray(a) || !Array.isArray(b)) {
7
8
  if (a !== b)
@@ -88,7 +89,7 @@ function FormElementSummary({ element, onChange, value }) {
88
89
  case 'date': {
89
90
  if (typeof formElementValue !== 'string')
90
91
  return partialSummary;
91
- partialSummary.push(localisationService.formatDate(new Date(formElementValue)));
92
+ partialSummary.push(localisationService.formatDate(getCorrectDateFromDateOnlyString(formElementValue)));
92
93
  break;
93
94
  }
94
95
  case 'datetime': {
@@ -1 +1 @@
1
- {"version":3,"file":"FormElementSummary.js","sourceRoot":"","sources":["../../src/form-elements/FormElementSummary.tsx"],"names":[],"mappings":"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","sourcesContent":["import * as React from 'react'\nimport { localisationService } from '@oneblink/apps'\n\nimport useFormSubmissionModel from '../hooks/useFormSubmissionModelContext'\nimport useFlattenElements from '../hooks/useFlattenElementsContext'\nimport { FormTypes } from '@oneblink/types'\nimport { FormElementValueChangeHandler } from '../types/form'\n\ntype Props = {\n element: FormTypes.SummaryElement\n onChange: FormElementValueChangeHandler\n value: unknown\n}\n\nconst arraysAreEqual = (a: unknown[], b: unknown[]) => {\n if (!Array.isArray(a) || !Array.isArray(b)) {\n if (a !== b) return false\n return true\n }\n if (a.length !== b.length) return false\n\n for (let i = 0; i < a.length; i++) {\n if (Array.isArray(a[i]) && Array.isArray(b[i])) {\n const areEqual = arraysAreEqual(a[i], b[i])\n if (!areEqual) return false\n continue\n }\n if (a[i] !== b[i]) return false\n }\n return true\n}\nfunction FormElementSummary({ element, onChange, value }: Props) {\n const formSubmissionModel = useFormSubmissionModel()\n const flattenedElements = useFlattenElements()\n\n const reducer = React.useCallback(\n (partialSummary, formElement, submission) => {\n if (formElement.type === 'page') return partialSummary\n if (\n formElement.type !== 'repeatableSet' &&\n formElement.type !== 'form' &&\n !element.elementIds.some((elementId) => elementId === formElement.id)\n ) {\n return partialSummary\n }\n\n const formElementValue = submission[formElement.name]\n if (!formElementValue && formElementValue !== 0) {\n return partialSummary\n }\n\n switch (formElement.type) {\n case 'repeatableSet': {\n if (!Array.isArray(formElementValue)) return partialSummary\n // If we found a repeatable set, look through child elements\n // to find the summary elements. Need to start a new array for\n // this structure and look at each entry in the repeatable set\n for (const entry of formElementValue) {\n const repeatableSetSummaryValues = formElement.elements.reduce(\n (\n partialSummary: FormElementSummaryResults,\n formElement: FormTypes.FormElement,\n ) =>\n reducer(\n partialSummary,\n formElement,\n // Pleasing TypeScript\n entry instanceof Object ? entry : {},\n ),\n [],\n )\n if (repeatableSetSummaryValues.length) {\n partialSummary.push(repeatableSetSummaryValues)\n }\n }\n break\n }\n case 'form': {\n const formSummaryValues = (formElement.elements || []).reduce(\n (\n partialSummary: FormElementSummaryResults,\n formElement: FormTypes.FormElement,\n ) =>\n reducer(\n partialSummary,\n formElement,\n // Pleasing TypeScript\n formElementValue instanceof Object ? formElementValue : {},\n ),\n [],\n )\n if (formSummaryValues.length) {\n partialSummary.push(formSummaryValues)\n }\n\n break\n }\n case 'select':\n case 'autocomplete':\n case 'radio':\n case 'checkboxes': {\n const optionValues = []\n if (Array.isArray(formElementValue)) {\n optionValues.push(...formElementValue)\n } else {\n optionValues.push(formElementValue)\n }\n if (Array.isArray(formElement.options)) {\n partialSummary.push(\n ...optionValues.reduce((optionLabels, optionValue) => {\n const option = formElement.options.find(\n ({ value }: FormTypes.ChoiceElementOption) =>\n optionValue === value,\n )\n if (option) {\n optionLabels.push(option.label)\n }\n return optionLabels\n }, []),\n )\n }\n break\n }\n case 'date': {\n if (typeof formElementValue !== 'string') return partialSummary\n partialSummary.push(\n localisationService.formatDate(new Date(formElementValue)),\n )\n break\n }\n case 'datetime': {\n if (typeof formElementValue !== 'string') return partialSummary\n partialSummary.push(\n localisationService.formatDatetime(new Date(formElementValue)),\n )\n break\n }\n case 'time': {\n if (typeof formElementValue !== 'string') return partialSummary\n partialSummary.push(\n localisationService.formatTime(new Date(formElementValue)),\n )\n break\n }\n default: {\n // Pleasing TypeScript WHILE COVERING ALL BASES\n if (\n typeof formElementValue !== 'string' &&\n typeof formElementValue !== 'object' &&\n typeof formElementValue !== 'number' &&\n typeof formElementValue !== 'function' &&\n typeof formElementValue !== 'boolean'\n ) {\n return partialSummary\n }\n\n partialSummary.push(formElementValue.toString())\n }\n }\n return partialSummary\n },\n [element.elementIds],\n )\n\n // MODEL LISTENER\n React.useEffect(() => {\n const summary = flattenedElements.reduce(\n (partialSummary, formElement) => {\n return reducer(partialSummary, formElement, formSubmissionModel)\n },\n\n [],\n )\n\n if (value === undefined) {\n if (!summary.length) return\n }\n if (arraysAreEqual(value as FormElementSummaryResults, summary)) {\n return\n }\n if (summary.length) {\n onChange(element, summary)\n } else {\n onChange(element, undefined)\n }\n }, [\n element,\n flattenedElements,\n formSubmissionModel,\n onChange,\n reducer,\n value,\n ])\n\n return (\n <div className=\"ob-form__element ob-summary cypress-summary-result \">\n {!!value && Array.isArray(value) && (\n <SummaryResult results={value}></SummaryResult>\n )}\n </div>\n )\n}\n\ntype FormElementSummaryResults = Array<string | FormElementSummaryResults>\ntype FormElementSummaryResultProps = {\n results: FormElementSummaryResults\n}\n\nconst SummaryResult = React.memo<FormElementSummaryResultProps>(\n function SummaryResult({ results }) {\n return (\n <>\n {results.map((result, i) => {\n return (\n <div\n key={`${result.toString()}-${i}`}\n className=\"ob-summary__result-container\"\n >\n {typeof result === 'string' ? (\n <p className=\"ob-summary__result has-line-breaks cypress-summary-result-text\">\n {result}\n </p>\n ) : (\n <SummaryResult results={result}></SummaryResult>\n )}\n </div>\n )\n })}\n </>\n )\n },\n)\n\nexport default React.memo(FormElementSummary)\n"]}
1
+ {"version":3,"file":"FormElementSummary.js","sourceRoot":"","sources":["../../src/form-elements/FormElementSummary.tsx"],"names":[],"mappings":"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","sourcesContent":["import * as React from 'react'\nimport { localisationService } from '@oneblink/apps'\n\nimport useFormSubmissionModel from '../hooks/useFormSubmissionModelContext'\nimport useFlattenElements from '../hooks/useFlattenElementsContext'\nimport { FormTypes } from '@oneblink/types'\nimport { FormElementValueChangeHandler } from '../types/form'\nimport getCorrectDateFromDateOnlyString from '../services/getCorrectDateFromDateOnlyString'\ntype Props = {\n element: FormTypes.SummaryElement\n onChange: FormElementValueChangeHandler\n value: unknown\n}\n\nconst arraysAreEqual = (a: unknown[], b: unknown[]) => {\n if (!Array.isArray(a) || !Array.isArray(b)) {\n if (a !== b) return false\n return true\n }\n if (a.length !== b.length) return false\n\n for (let i = 0; i < a.length; i++) {\n if (Array.isArray(a[i]) && Array.isArray(b[i])) {\n const areEqual = arraysAreEqual(a[i], b[i])\n if (!areEqual) return false\n continue\n }\n if (a[i] !== b[i]) return false\n }\n return true\n}\nfunction FormElementSummary({ element, onChange, value }: Props) {\n const formSubmissionModel = useFormSubmissionModel()\n const flattenedElements = useFlattenElements()\n\n const reducer = React.useCallback(\n (partialSummary, formElement, submission) => {\n if (formElement.type === 'page') return partialSummary\n if (\n formElement.type !== 'repeatableSet' &&\n formElement.type !== 'form' &&\n !element.elementIds.some((elementId) => elementId === formElement.id)\n ) {\n return partialSummary\n }\n\n const formElementValue = submission[formElement.name]\n if (!formElementValue && formElementValue !== 0) {\n return partialSummary\n }\n\n switch (formElement.type) {\n case 'repeatableSet': {\n if (!Array.isArray(formElementValue)) return partialSummary\n // If we found a repeatable set, look through child elements\n // to find the summary elements. Need to start a new array for\n // this structure and look at each entry in the repeatable set\n for (const entry of formElementValue) {\n const repeatableSetSummaryValues = formElement.elements.reduce(\n (\n partialSummary: FormElementSummaryResults,\n formElement: FormTypes.FormElement,\n ) =>\n reducer(\n partialSummary,\n formElement,\n // Pleasing TypeScript\n entry instanceof Object ? entry : {},\n ),\n [],\n )\n if (repeatableSetSummaryValues.length) {\n partialSummary.push(repeatableSetSummaryValues)\n }\n }\n break\n }\n case 'form': {\n const formSummaryValues = (formElement.elements || []).reduce(\n (\n partialSummary: FormElementSummaryResults,\n formElement: FormTypes.FormElement,\n ) =>\n reducer(\n partialSummary,\n formElement,\n // Pleasing TypeScript\n formElementValue instanceof Object ? formElementValue : {},\n ),\n [],\n )\n if (formSummaryValues.length) {\n partialSummary.push(formSummaryValues)\n }\n\n break\n }\n case 'select':\n case 'autocomplete':\n case 'radio':\n case 'checkboxes': {\n const optionValues = []\n if (Array.isArray(formElementValue)) {\n optionValues.push(...formElementValue)\n } else {\n optionValues.push(formElementValue)\n }\n if (Array.isArray(formElement.options)) {\n partialSummary.push(\n ...optionValues.reduce((optionLabels, optionValue) => {\n const option = formElement.options.find(\n ({ value }: FormTypes.ChoiceElementOption) =>\n optionValue === value,\n )\n if (option) {\n optionLabels.push(option.label)\n }\n return optionLabels\n }, []),\n )\n }\n break\n }\n case 'date': {\n if (typeof formElementValue !== 'string') return partialSummary\n partialSummary.push(\n localisationService.formatDate(\n getCorrectDateFromDateOnlyString(formElementValue),\n ),\n )\n break\n }\n case 'datetime': {\n if (typeof formElementValue !== 'string') return partialSummary\n partialSummary.push(\n localisationService.formatDatetime(new Date(formElementValue)),\n )\n break\n }\n case 'time': {\n if (typeof formElementValue !== 'string') return partialSummary\n partialSummary.push(\n localisationService.formatTime(new Date(formElementValue)),\n )\n break\n }\n default: {\n // Pleasing TypeScript WHILE COVERING ALL BASES\n if (\n typeof formElementValue !== 'string' &&\n typeof formElementValue !== 'object' &&\n typeof formElementValue !== 'number' &&\n typeof formElementValue !== 'function' &&\n typeof formElementValue !== 'boolean'\n ) {\n return partialSummary\n }\n\n partialSummary.push(formElementValue.toString())\n }\n }\n return partialSummary\n },\n [element.elementIds],\n )\n\n // MODEL LISTENER\n React.useEffect(() => {\n const summary = flattenedElements.reduce(\n (partialSummary, formElement) => {\n return reducer(partialSummary, formElement, formSubmissionModel)\n },\n\n [],\n )\n\n if (value === undefined) {\n if (!summary.length) return\n }\n if (arraysAreEqual(value as FormElementSummaryResults, summary)) {\n return\n }\n if (summary.length) {\n onChange(element, summary)\n } else {\n onChange(element, undefined)\n }\n }, [\n element,\n flattenedElements,\n formSubmissionModel,\n onChange,\n reducer,\n value,\n ])\n\n return (\n <div className=\"ob-form__element ob-summary cypress-summary-result \">\n {!!value && Array.isArray(value) && (\n <SummaryResult results={value}></SummaryResult>\n )}\n </div>\n )\n}\n\ntype FormElementSummaryResults = Array<string | FormElementSummaryResults>\ntype FormElementSummaryResultProps = {\n results: FormElementSummaryResults\n}\n\nconst SummaryResult = React.memo<FormElementSummaryResultProps>(\n function SummaryResult({ results }) {\n return (\n <>\n {results.map((result, i) => {\n return (\n <div\n key={`${result.toString()}-${i}`}\n className=\"ob-summary__result-container\"\n >\n {typeof result === 'string' ? (\n <p className=\"ob-summary__result has-line-breaks cypress-summary-result-text\">\n {result}\n </p>\n ) : (\n <SummaryResult results={result}></SummaryResult>\n )}\n </div>\n )\n })}\n </>\n )\n },\n)\n\nexport default React.memo(FormElementSummary)\n"]}
@@ -0,0 +1,3 @@
1
+ import { FormTypes } from '@oneblink/types';
2
+ import { FormSubmissionModel } from '../types/form';
3
+ export default function checkBsbsAreInvalid(form: FormTypes.Form, submission: FormSubmissionModel): boolean;
@@ -0,0 +1,41 @@
1
+ function checkIfBsbsAreInvalidForFormElements(formElements, submission) {
2
+ return formElements.some((formElement) => {
3
+ switch (formElement.type) {
4
+ case 'section':
5
+ case 'page': {
6
+ return checkIfBsbsAreInvalidForFormElements(formElement.elements, submission);
7
+ }
8
+ case 'form': {
9
+ const nestedSubmission = submission[formElement.name];
10
+ if (!nestedSubmission || typeof nestedSubmission !== 'object') {
11
+ break;
12
+ }
13
+ return checkIfBsbsAreInvalidForFormElements(formElement.elements || [], nestedSubmission);
14
+ }
15
+ case 'repeatableSet': {
16
+ const entries = submission[formElement.name];
17
+ if (!Array.isArray(entries)) {
18
+ break;
19
+ }
20
+ return entries.some((entry) => {
21
+ return (typeof entry === 'object' &&
22
+ checkIfBsbsAreInvalidForFormElements(formElement.elements, entry));
23
+ });
24
+ }
25
+ case 'bsb': {
26
+ const value = submission[formElement.name];
27
+ if (!value) {
28
+ break;
29
+ }
30
+ const bsbValue = value;
31
+ if (typeof bsbValue === 'object') {
32
+ return bsbValue.isInvalid;
33
+ }
34
+ }
35
+ }
36
+ });
37
+ }
38
+ export default function checkBsbsAreInvalid(form, submission) {
39
+ return checkIfBsbsAreInvalidForFormElements(form.elements, submission);
40
+ }
41
+ //# sourceMappingURL=checkBsbsAreInvalid.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checkBsbsAreInvalid.js","sourceRoot":"","sources":["../../src/services/checkBsbsAreInvalid.ts"],"names":[],"mappings":"AAGA,SAAS,oCAAoC,CAC3C,YAAqC,EACrC,UAA+B;IAE/B,OAAO,YAAY,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,EAAE;QACvC,QAAQ,WAAW,CAAC,IAAI,EAAE;YACxB,KAAK,SAAS,CAAC;YACf,KAAK,MAAM,CAAC,CAAC;gBACX,OAAO,oCAAoC,CACzC,WAAW,CAAC,QAAQ,EACpB,UAAU,CACX,CAAA;aACF;YACD,KAAK,MAAM,CAAC,CAAC;gBACX,MAAM,gBAAgB,GAAG,UAAU,CAAC,WAAW,CAAC,IAAI,CAAC,CAAA;gBACrD,IAAI,CAAC,gBAAgB,IAAI,OAAO,gBAAgB,KAAK,QAAQ,EAAE;oBAC7D,MAAK;iBACN;gBACD,OAAO,oCAAoC,CACzC,WAAW,CAAC,QAAQ,IAAI,EAAE,EAC1B,gBAAuC,CACxC,CAAA;aACF;YACD,KAAK,eAAe,CAAC,CAAC;gBACpB,MAAM,OAAO,GAAG,UAAU,CAAC,WAAW,CAAC,IAAI,CAAC,CAAA;gBAC5C,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE;oBAC3B,MAAK;iBACN;gBACD,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE;oBAC5B,OAAO,CACL,OAAO,KAAK,KAAK,QAAQ;wBACzB,oCAAoC,CAAC,WAAW,CAAC,QAAQ,EAAE,KAAK,CAAC,CAClE,CAAA;gBACH,CAAC,CAAC,CAAA;aACH;YACD,KAAK,KAAK,CAAC,CAAC;gBACV,MAAM,KAAK,GAAG,UAAU,CAAC,WAAW,CAAC,IAAI,CAAC,CAAA;gBAC1C,IAAI,CAAC,KAAK,EAAE;oBACV,MAAK;iBACN;gBACD,MAAM,QAAQ,GAAG,KAAwC,CAAA;gBACzD,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE;oBAChC,OAAO,QAAQ,CAAC,SAAS,CAAA;iBAC1B;aACF;SACF;IACH,CAAC,CAAC,CAAA;AACJ,CAAC;AAED,MAAM,CAAC,OAAO,UAAU,mBAAmB,CACzC,IAAoB,EACpB,UAA+B;IAE/B,OAAO,oCAAoC,CAAC,IAAI,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAA;AACxE,CAAC","sourcesContent":["import { FormTypes } from '@oneblink/types'\nimport { FormSubmissionModel } from '../types/form'\n\nfunction checkIfBsbsAreInvalidForFormElements(\n formElements: FormTypes.FormElement[],\n submission: FormSubmissionModel,\n): boolean {\n return formElements.some((formElement) => {\n switch (formElement.type) {\n case 'section':\n case 'page': {\n return checkIfBsbsAreInvalidForFormElements(\n formElement.elements,\n submission,\n )\n }\n case 'form': {\n const nestedSubmission = submission[formElement.name]\n if (!nestedSubmission || typeof nestedSubmission !== 'object') {\n break\n }\n return checkIfBsbsAreInvalidForFormElements(\n formElement.elements || [],\n nestedSubmission as FormSubmissionModel,\n )\n }\n case 'repeatableSet': {\n const entries = submission[formElement.name]\n if (!Array.isArray(entries)) {\n break\n }\n return entries.some((entry) => {\n return (\n typeof entry === 'object' &&\n checkIfBsbsAreInvalidForFormElements(formElement.elements, entry)\n )\n })\n }\n case 'bsb': {\n const value = submission[formElement.name]\n if (!value) {\n break\n }\n const bsbValue = value as string | { isInvalid: boolean }\n if (typeof bsbValue === 'object') {\n return bsbValue.isInvalid\n }\n }\n }\n })\n}\n\nexport default function checkBsbsAreInvalid(\n form: FormTypes.Form,\n submission: FormSubmissionModel,\n): boolean {\n return checkIfBsbsAreInvalidForFormElements(form.elements, submission)\n}\n"]}
@@ -0,0 +1,3 @@
1
+ import { FormTypes } from '@oneblink/types';
2
+ import { FormSubmissionModel } from '../types/form';
3
+ export default function checkIfBsbsAreValidating(form: FormTypes.Form, submission: FormSubmissionModel): boolean;
@@ -0,0 +1,41 @@
1
+ function checkIfBsbsAreValidatingForFormElements(formElements, submission) {
2
+ return formElements.some((formElement) => {
3
+ switch (formElement.type) {
4
+ case 'section':
5
+ case 'page': {
6
+ return checkIfBsbsAreValidatingForFormElements(formElement.elements, submission);
7
+ }
8
+ case 'form': {
9
+ const nestedSubmission = submission[formElement.name];
10
+ if (!nestedSubmission || typeof nestedSubmission !== 'object') {
11
+ break;
12
+ }
13
+ return checkIfBsbsAreValidatingForFormElements(formElement.elements || [], nestedSubmission);
14
+ }
15
+ case 'repeatableSet': {
16
+ const entries = submission[formElement.name];
17
+ if (!Array.isArray(entries)) {
18
+ break;
19
+ }
20
+ return entries.some((entry) => {
21
+ return (typeof entry === 'object' &&
22
+ checkIfBsbsAreValidatingForFormElements(formElement.elements, entry));
23
+ });
24
+ }
25
+ case 'bsb': {
26
+ const value = submission[formElement.name];
27
+ if (!value) {
28
+ break;
29
+ }
30
+ const bsbValue = value;
31
+ if (typeof bsbValue === 'object') {
32
+ return bsbValue.isValidating;
33
+ }
34
+ }
35
+ }
36
+ });
37
+ }
38
+ export default function checkIfBsbsAreValidating(form, submission) {
39
+ return checkIfBsbsAreValidatingForFormElements(form.elements, submission);
40
+ }
41
+ //# sourceMappingURL=checkIfBsbsAreValidating.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checkIfBsbsAreValidating.js","sourceRoot":"","sources":["../../src/services/checkIfBsbsAreValidating.ts"],"names":[],"mappings":"AAGA,SAAS,uCAAuC,CAC9C,YAAqC,EACrC,UAA+B;IAE/B,OAAO,YAAY,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,EAAE;QACvC,QAAQ,WAAW,CAAC,IAAI,EAAE;YACxB,KAAK,SAAS,CAAC;YACf,KAAK,MAAM,CAAC,CAAC;gBACX,OAAO,uCAAuC,CAC5C,WAAW,CAAC,QAAQ,EACpB,UAAU,CACX,CAAA;aACF;YACD,KAAK,MAAM,CAAC,CAAC;gBACX,MAAM,gBAAgB,GAAG,UAAU,CAAC,WAAW,CAAC,IAAI,CAAC,CAAA;gBACrD,IAAI,CAAC,gBAAgB,IAAI,OAAO,gBAAgB,KAAK,QAAQ,EAAE;oBAC7D,MAAK;iBACN;gBACD,OAAO,uCAAuC,CAC5C,WAAW,CAAC,QAAQ,IAAI,EAAE,EAC1B,gBAAuC,CACxC,CAAA;aACF;YACD,KAAK,eAAe,CAAC,CAAC;gBACpB,MAAM,OAAO,GAAG,UAAU,CAAC,WAAW,CAAC,IAAI,CAAC,CAAA;gBAC5C,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE;oBAC3B,MAAK;iBACN;gBACD,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE;oBAC5B,OAAO,CACL,OAAO,KAAK,KAAK,QAAQ;wBACzB,uCAAuC,CAAC,WAAW,CAAC,QAAQ,EAAE,KAAK,CAAC,CACrE,CAAA;gBACH,CAAC,CAAC,CAAA;aACH;YACD,KAAK,KAAK,CAAC,CAAC;gBACV,MAAM,KAAK,GAAG,UAAU,CAAC,WAAW,CAAC,IAAI,CAAC,CAAA;gBAC1C,IAAI,CAAC,KAAK,EAAE;oBACV,MAAK;iBACN;gBACD,MAAM,QAAQ,GAAG,KAA2C,CAAA;gBAC5D,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE;oBAChC,OAAO,QAAQ,CAAC,YAAY,CAAA;iBAC7B;aACF;SACF;IACH,CAAC,CAAC,CAAA;AACJ,CAAC;AAED,MAAM,CAAC,OAAO,UAAU,wBAAwB,CAC9C,IAAoB,EACpB,UAA+B;IAE/B,OAAO,uCAAuC,CAAC,IAAI,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAA;AAC3E,CAAC","sourcesContent":["import { FormTypes } from '@oneblink/types'\nimport { FormSubmissionModel } from '../types/form'\n\nfunction checkIfBsbsAreValidatingForFormElements(\n formElements: FormTypes.FormElement[],\n submission: FormSubmissionModel,\n): boolean {\n return formElements.some((formElement) => {\n switch (formElement.type) {\n case 'section':\n case 'page': {\n return checkIfBsbsAreValidatingForFormElements(\n formElement.elements,\n submission,\n )\n }\n case 'form': {\n const nestedSubmission = submission[formElement.name]\n if (!nestedSubmission || typeof nestedSubmission !== 'object') {\n break\n }\n return checkIfBsbsAreValidatingForFormElements(\n formElement.elements || [],\n nestedSubmission as FormSubmissionModel,\n )\n }\n case 'repeatableSet': {\n const entries = submission[formElement.name]\n if (!Array.isArray(entries)) {\n break\n }\n return entries.some((entry) => {\n return (\n typeof entry === 'object' &&\n checkIfBsbsAreValidatingForFormElements(formElement.elements, entry)\n )\n })\n }\n case 'bsb': {\n const value = submission[formElement.name]\n if (!value) {\n break\n }\n const bsbValue = value as string | { isValidating: boolean }\n if (typeof bsbValue === 'object') {\n return bsbValue.isValidating\n }\n }\n }\n })\n}\n\nexport default function checkIfBsbsAreValidating(\n form: FormTypes.Form,\n submission: FormSubmissionModel,\n): boolean {\n return checkIfBsbsAreValidatingForFormElements(form.elements, submission)\n}\n"]}
@@ -270,6 +270,20 @@ export function generateValidationSchema(elements, elementIdsWithLookupsExecuted
270
270
  };
271
271
  break;
272
272
  }
273
+ case 'bsb': {
274
+ partialSchema[escapeElementName(formElement.name)] = {
275
+ presence: presence(formElement.required, 'Please enter a BSB number'),
276
+ lookups: {
277
+ formElement,
278
+ elementIdsWithLookupsExecuted,
279
+ },
280
+ format: {
281
+ pattern: /\d{3}-\d{3}/,
282
+ message: 'Please enter a valid BSB number',
283
+ },
284
+ };
285
+ break;
286
+ }
273
287
  case 'barcodeScanner': {
274
288
  partialSchema[escapeElementName(formElement.name)] = {
275
289
  presence: presence(formElement.required, 'Please scan a barcode or enter a value'),