@oneblink/apps-react 8.6.0-beta.8 → 8.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/dist/OneBlinkFormBase.js +10 -2
  2. package/dist/OneBlinkFormBase.js.map +1 -1
  3. package/dist/components/renderer/AutocompleteDropdown.js +1 -1
  4. package/dist/components/renderer/AutocompleteDropdown.js.map +1 -1
  5. package/dist/form-elements/FormElementABN.js +1 -1
  6. package/dist/form-elements/FormElementABN.js.map +1 -1
  7. package/dist/form-elements/FormElementBSB.js +1 -1
  8. package/dist/form-elements/FormElementBSB.js.map +1 -1
  9. package/dist/form-elements/FormElementBarcodeScanner.js +1 -1
  10. package/dist/form-elements/FormElementBarcodeScanner.js.map +1 -1
  11. package/dist/form-elements/FormElementBoolean.js +1 -0
  12. package/dist/form-elements/FormElementBoolean.js.map +1 -1
  13. package/dist/form-elements/FormElementCamera.js +1 -1
  14. package/dist/form-elements/FormElementCamera.js.map +1 -1
  15. package/dist/form-elements/FormElementDate.js +1 -0
  16. package/dist/form-elements/FormElementDate.js.map +1 -1
  17. package/dist/form-elements/FormElementDateTime.js +1 -0
  18. package/dist/form-elements/FormElementDateTime.js.map +1 -1
  19. package/dist/form-elements/FormElementEmail.js +1 -1
  20. package/dist/form-elements/FormElementEmail.js.map +1 -1
  21. package/dist/form-elements/FormElementForm.js +3 -2
  22. package/dist/form-elements/FormElementForm.js.map +1 -1
  23. package/dist/form-elements/FormElementLocation.js +3 -1
  24. package/dist/form-elements/FormElementLocation.js.map +1 -1
  25. package/dist/form-elements/FormElementNumber.js +4 -4
  26. package/dist/form-elements/FormElementNumber.js.map +1 -1
  27. package/dist/form-elements/FormElementPointCadastralParcel.js +1 -1
  28. package/dist/form-elements/FormElementPointCadastralParcel.js.map +1 -1
  29. package/dist/form-elements/FormElementRepeatableSet.js +60 -12
  30. package/dist/form-elements/FormElementRepeatableSet.js.map +1 -1
  31. package/dist/form-elements/FormElementSection.js +2 -1
  32. package/dist/form-elements/FormElementSection.js.map +1 -1
  33. package/dist/form-elements/FormElementSelect.js +2 -2
  34. package/dist/form-elements/FormElementSelect.js.map +1 -1
  35. package/dist/form-elements/FormElementTelephone.js +1 -1
  36. package/dist/form-elements/FormElementTelephone.js.map +1 -1
  37. package/dist/form-elements/FormElementText.js +1 -1
  38. package/dist/form-elements/FormElementText.js.map +1 -1
  39. package/dist/form-elements/FormElementTextarea.js +1 -1
  40. package/dist/form-elements/FormElementTextarea.js.map +1 -1
  41. package/dist/form-elements/FormElementTime.js +1 -0
  42. package/dist/form-elements/FormElementTime.js.map +1 -1
  43. package/dist/hooks/form-date-picker/useFormDatePickerProps.d.ts +2 -1
  44. package/dist/hooks/form-date-picker/useFormDatePickerProps.js +2 -1
  45. package/dist/hooks/form-date-picker/useFormDatePickerProps.js.map +1 -1
  46. package/dist/types/form.d.ts +3 -1
  47. package/dist/types/form.js.map +1 -1
  48. package/package.json +3 -3
@@ -1 +1 @@
1
- {"version":3,"file":"FormElementEmail.js","sourceRoot":"","sources":["../../src/form-elements/FormElementEmail.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,OAAO,qBAAqB,MAAM,8CAA8C,CAAA;AAChF,OAAO,YAAY,MAAM,qCAAqC,CAAA;AAE9D,OAAO,yBAAyB,MAAM,kDAAkD,CAAA;AAExF,OAAO,EAAE,yBAAyB,EAAE,MAAM,gCAAgC,CAAA;AAC1E,OAAO,yBAAyB,MAAM,oCAAoC,CAAA;AAC1E,OAAO,YAAY,MAAM,4BAA4B,CAAA;AAYrD,SAAS,gBAAgB,CAAC,EACxB,EAAE,EACF,OAAO,EACP,KAAK,EACL,QAAQ,EACR,iBAAiB,EACjB,wBAAwB,EACxB,OAAO,EACP,UAAU,EACV,sBAAsB,GAChB;IACN,MAAM,eAAe,GAAG,yBAAyB,CAAC,EAAE,EAAE,OAAO,CAAC,CAAA;IAC9D,MAAM,EAAE,WAAW,EAAE,GAAG,KAAK,CAAC,UAAU,CAAC,yBAAyB,CAAC,CAAA;IACnE,MAAM,6BAA6B,GACjC,CAAC,OAAO,IAAI,wBAAwB,CAAC,IAAI,CAAC,CAAC,iBAAiB,IAAI,CAAC,WAAW,CAAA;IAE9E,MAAM,IAAI,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAA;IACnD,OAAO,CACL,6BAAK,SAAS,EAAC,uBAAuB;QACpC,oBAAC,yBAAyB,IACxB,SAAS,EAAC,UAAU,EACpB,EAAE,EAAE,EAAE,EACN,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAE1B,6BAAK,SAAS,EAAC,kBAAkB;gBAC/B,6BAAK,SAAS,EAAC,qCAAqC;oBAClD,+BACE,IAAI,EAAC,OAAO,EACZ,WAAW,EAAE,OAAO,CAAC,gBAAgB,EACrC,EAAE,EAAE,EAAE,EACN,IAAI,EAAE,OAAO,CAAC,IAAI,EAClB,SAAS,EAAC,sCAAsC,EAChD,KAAK,EAAE,IAAI,EACX,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CACd,QAAQ,CAAC,OAAO,EAAE;4BAChB,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,KAAK,IAAI,SAAS;yBACnC,CAAC,EAEJ,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAC1B,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAC1B,MAAM,EAAE,UAAU,sBACA,eAAe,EACjC,YAAY,EAAE,sBAAsB,GACpC;oBACF,8BAAM,SAAS,EAAC,sCAAsC;wBACpD,oBAAC,YAAY,IAAC,SAAS,EAAC,WAAW,YAAqB,CACnD,CACH;gBACL,CAAC,CAAC,OAAO,CAAC,QAAQ,IAAI,CAAC,CAAC,KAAK,IAAI,CAChC,6BAAK,SAAS,EAAC,SAAS;oBACtB,oBAAC,qBAAqB,IACpB,SAAS,EAAC,oEAAoE,EAC9E,IAAI,EAAE,IAAI,GACV,CACE,CACP;gBACD,oBAAC,YAAY,IACX,aAAa,QACb,KAAK,EAAE,KAAK,EACZ,iBAAiB,EAAE,iBAAiB,EACpC,kBAAkB,EAAE,OAAO,CAAC,YAAY,GACxC,CACE;YAEL,6BAA6B,IAAI,CAChC,6BAAK,IAAI,EAAC,OAAO,EAAC,SAAS,EAAC,kBAAkB;gBAC5C,6BAAK,SAAS,EAAC,2DAA2D,IACvE,iBAAiB,CACd,CACF,CACP,CACyB,CACxB,CACP,CAAA;AACH,CAAC;AAED,eAAe,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAA","sourcesContent":["import * as React from 'react'\n\nimport CopyToClipboardButton from '../components/renderer/CopyToClipboardButton'\nimport LookupButton from '../components/renderer/LookupButton'\nimport { FormTypes } from '@oneblink/types'\nimport FormElementLabelContainer from '../components/renderer/FormElementLabelContainer'\nimport { FormElementValueChangeHandler, IsDirtyProps } from '../types/form'\nimport { LookupNotificationContext } from '../hooks/useLookupNotification'\nimport useElementAriaDescribedby from '../hooks/useElementAriaDescribedby'\nimport MaterialIcon from '../components/MaterialIcon'\n\ntype Props = {\n id: string\n element: FormTypes.EmailElement\n value: unknown\n onChange: FormElementValueChangeHandler<string>\n displayValidationMessage: boolean\n validationMessage: string | undefined\n autocompleteAttributes?: string\n} & IsDirtyProps\n\nfunction FormElementEmail({\n id,\n element,\n value,\n onChange,\n validationMessage,\n displayValidationMessage,\n isDirty,\n setIsDirty,\n autocompleteAttributes,\n}: Props) {\n const ariaDescribedby = useElementAriaDescribedby(id, element)\n const { isLookingUp } = React.useContext(LookupNotificationContext)\n const isDisplayingValidationMessage =\n (isDirty || displayValidationMessage) && !!validationMessage && !isLookingUp\n\n const text = typeof value === 'string' ? value : ''\n return (\n <div className=\"cypress-email-element\">\n <FormElementLabelContainer\n className=\"ob-email\"\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=\"email\"\n placeholder={element.placeholderValue}\n id={id}\n name={element.name}\n className=\"input ob-input cypress-email-control\"\n value={text}\n onChange={(e) =>\n onChange(element, {\n value: e.target.value || undefined,\n })\n }\n required={element.required}\n disabled={element.readOnly}\n onBlur={setIsDirty}\n aria-describedby={ariaDescribedby}\n autoComplete={autocompleteAttributes}\n />\n <span className=\"ob-input-icon icon is-small is-right\">\n <MaterialIcon className=\"is-size-5\">email</MaterialIcon>\n </span>\n </div>\n {!!element.readOnly && !!value && (\n <div className=\"control\">\n <CopyToClipboardButton\n className=\"button is-input-addon copy-button cypress-copy-to-clipboard-button\"\n text={text}\n />\n </div>\n )}\n <LookupButton\n isInputButton\n value={value}\n validationMessage={validationMessage}\n lookupButtonConfig={element.lookupButton}\n />\n </div>\n\n {isDisplayingValidationMessage && (\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(FormElementEmail)\n"]}
1
+ {"version":3,"file":"FormElementEmail.js","sourceRoot":"","sources":["../../src/form-elements/FormElementEmail.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,OAAO,qBAAqB,MAAM,8CAA8C,CAAA;AAChF,OAAO,YAAY,MAAM,qCAAqC,CAAA;AAE9D,OAAO,yBAAyB,MAAM,kDAAkD,CAAA;AAExF,OAAO,EAAE,yBAAyB,EAAE,MAAM,gCAAgC,CAAA;AAC1E,OAAO,yBAAyB,MAAM,oCAAoC,CAAA;AAC1E,OAAO,YAAY,MAAM,4BAA4B,CAAA;AAYrD,SAAS,gBAAgB,CAAC,EACxB,EAAE,EACF,OAAO,EACP,KAAK,EACL,QAAQ,EACR,iBAAiB,EACjB,wBAAwB,EACxB,OAAO,EACP,UAAU,EACV,sBAAsB,GAChB;IACN,MAAM,eAAe,GAAG,yBAAyB,CAAC,EAAE,EAAE,OAAO,CAAC,CAAA;IAC9D,MAAM,EAAE,WAAW,EAAE,GAAG,KAAK,CAAC,UAAU,CAAC,yBAAyB,CAAC,CAAA;IACnE,MAAM,6BAA6B,GACjC,CAAC,OAAO,IAAI,wBAAwB,CAAC,IAAI,CAAC,CAAC,iBAAiB,IAAI,CAAC,WAAW,CAAA;IAE9E,MAAM,IAAI,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAA;IACnD,OAAO,CACL,6BAAK,SAAS,EAAC,uBAAuB;QACpC,oBAAC,yBAAyB,IACxB,SAAS,EAAC,UAAU,EACpB,EAAE,EAAE,EAAE,EACN,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAE1B,6BAAK,SAAS,EAAC,kBAAkB;gBAC/B,6BAAK,SAAS,EAAC,qCAAqC;oBAClD,+BACE,IAAI,EAAC,OAAO,EACZ,WAAW,EAAE,OAAO,CAAC,gBAAgB,EACrC,EAAE,EAAE,EAAE,EACN,IAAI,EAAE,OAAO,CAAC,IAAI,EAClB,SAAS,EAAC,sCAAsC,EAChD,KAAK,EAAE,IAAI,EACX,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CACd,QAAQ,CAAC,OAAO,EAAE;4BAChB,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,KAAK,IAAI,SAAS;yBACnC,CAAC,EAEJ,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAC1B,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAC1B,MAAM,EAAE,UAAU,sBACA,eAAe,EACjC,YAAY,EAAE,sBAAsB,mBACrB,OAAO,CAAC,QAAQ,GAC/B;oBACF,8BAAM,SAAS,EAAC,sCAAsC;wBACpD,oBAAC,YAAY,IAAC,SAAS,EAAC,WAAW,YAAqB,CACnD,CACH;gBACL,CAAC,CAAC,OAAO,CAAC,QAAQ,IAAI,CAAC,CAAC,KAAK,IAAI,CAChC,6BAAK,SAAS,EAAC,SAAS;oBACtB,oBAAC,qBAAqB,IACpB,SAAS,EAAC,oEAAoE,EAC9E,IAAI,EAAE,IAAI,GACV,CACE,CACP;gBACD,oBAAC,YAAY,IACX,aAAa,QACb,KAAK,EAAE,KAAK,EACZ,iBAAiB,EAAE,iBAAiB,EACpC,kBAAkB,EAAE,OAAO,CAAC,YAAY,GACxC,CACE;YAEL,6BAA6B,IAAI,CAChC,6BAAK,IAAI,EAAC,OAAO,EAAC,SAAS,EAAC,kBAAkB;gBAC5C,6BAAK,SAAS,EAAC,2DAA2D,IACvE,iBAAiB,CACd,CACF,CACP,CACyB,CACxB,CACP,CAAA;AACH,CAAC;AAED,eAAe,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAA","sourcesContent":["import * as React from 'react'\n\nimport CopyToClipboardButton from '../components/renderer/CopyToClipboardButton'\nimport LookupButton from '../components/renderer/LookupButton'\nimport { FormTypes } from '@oneblink/types'\nimport FormElementLabelContainer from '../components/renderer/FormElementLabelContainer'\nimport { FormElementValueChangeHandler, IsDirtyProps } from '../types/form'\nimport { LookupNotificationContext } from '../hooks/useLookupNotification'\nimport useElementAriaDescribedby from '../hooks/useElementAriaDescribedby'\nimport MaterialIcon from '../components/MaterialIcon'\n\ntype Props = {\n id: string\n element: FormTypes.EmailElement\n value: unknown\n onChange: FormElementValueChangeHandler<string>\n displayValidationMessage: boolean\n validationMessage: string | undefined\n autocompleteAttributes?: string\n} & IsDirtyProps\n\nfunction FormElementEmail({\n id,\n element,\n value,\n onChange,\n validationMessage,\n displayValidationMessage,\n isDirty,\n setIsDirty,\n autocompleteAttributes,\n}: Props) {\n const ariaDescribedby = useElementAriaDescribedby(id, element)\n const { isLookingUp } = React.useContext(LookupNotificationContext)\n const isDisplayingValidationMessage =\n (isDirty || displayValidationMessage) && !!validationMessage && !isLookingUp\n\n const text = typeof value === 'string' ? value : ''\n return (\n <div className=\"cypress-email-element\">\n <FormElementLabelContainer\n className=\"ob-email\"\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=\"email\"\n placeholder={element.placeholderValue}\n id={id}\n name={element.name}\n className=\"input ob-input cypress-email-control\"\n value={text}\n onChange={(e) =>\n onChange(element, {\n value: e.target.value || undefined,\n })\n }\n required={element.required}\n disabled={element.readOnly}\n onBlur={setIsDirty}\n aria-describedby={ariaDescribedby}\n autoComplete={autocompleteAttributes}\n aria-required={element.required}\n />\n <span className=\"ob-input-icon icon is-small is-right\">\n <MaterialIcon className=\"is-size-5\">email</MaterialIcon>\n </span>\n </div>\n {!!element.readOnly && !!value && (\n <div className=\"control\">\n <CopyToClipboardButton\n className=\"button is-input-addon copy-button cypress-copy-to-clipboard-button\"\n text={text}\n />\n </div>\n )}\n <LookupButton\n isInputButton\n value={value}\n validationMessage={validationMessage}\n lookupButtonConfig={element.lookupButton}\n />\n </div>\n\n {isDisplayingValidationMessage && (\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(FormElementEmail)\n"]}
@@ -2,13 +2,13 @@ import * as React from 'react';
2
2
  import OneBlinkFormElements from '../components/renderer/OneBlinkFormElements';
3
3
  import ElementDOMId from '../utils/elementDOMIds';
4
4
  function FormElementForm({ formId, element, value, id, formElementValidation, displayValidationMessages, formElementConditionallyShown, onChange, onLookup, onUpdateFormElements, sectionState, }) {
5
- const handleNestedChange = React.useCallback((nestedElement, { value: nestedElementValue, executedLookups: nestedExecutedLookups, }, idPrefix) => {
5
+ const handleNestedChange = React.useCallback((nestedElement, { value: nestedElementValue, executedLookups: nestedExecutedLookups, sectionState, }, idPrefix) => {
6
6
  if (nestedElement.type === 'section') {
7
7
  // trigger onChange to update sectionState
8
8
  onChange({
9
9
  ...nestedElement,
10
10
  id: idPrefix ? `${idPrefix}${nestedElement.id}` : nestedElement.id,
11
- }, { executedLookups: undefined });
11
+ }, { executedLookups: undefined, sectionState });
12
12
  }
13
13
  if (!('name' in nestedElement))
14
14
  return;
@@ -31,6 +31,7 @@ function FormElementForm({ formId, element, value, id, formElementValidation, di
31
31
  : nestedExecutedLookups,
32
32
  };
33
33
  },
34
+ sectionState,
34
35
  });
35
36
  }, [element, onChange]);
36
37
  const handleLookup = React.useCallback((mergeLookupResults) => {
@@ -1 +1 @@
1
- {"version":3,"file":"FormElementForm.js","sourceRoot":"","sources":["../../src/form-elements/FormElementForm.tsx"],"names":[],"mappings":"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","sourcesContent":["import { FormTypes, SubmissionTypes } from '@oneblink/types'\nimport * as React from 'react'\nimport OneBlinkFormElements from '../components/renderer/OneBlinkFormElements'\nimport {\n ExecutedLookups,\n FormElementConditionallyShown,\n FormElementLookupHandler,\n FormElementValidation,\n NestedFormElementValueChangeHandler,\n SectionState,\n UpdateFormElementsHandler,\n} from '../types/form'\nimport ElementDOMId from '../utils/elementDOMIds'\n\nexport type Props = {\n formId: number\n id: string\n element: FormTypes.FormFormElement\n value: SubmissionTypes.S3SubmissionData['submission'] | undefined\n onChange: NestedFormElementValueChangeHandler<\n SubmissionTypes.S3SubmissionData['submission']\n >\n onLookup: FormElementLookupHandler\n formElementValidation: FormElementValidation | undefined\n displayValidationMessages: boolean\n formElementConditionallyShown: FormElementConditionallyShown | undefined\n onUpdateFormElements: UpdateFormElementsHandler\n sectionState: SectionState\n}\n\nfunction FormElementForm({\n formId,\n element,\n value,\n id,\n formElementValidation,\n displayValidationMessages,\n formElementConditionallyShown,\n onChange,\n onLookup,\n onUpdateFormElements,\n sectionState,\n}: Props) {\n const handleNestedChange = React.useCallback(\n (\n nestedElement: FormTypes.FormElement,\n {\n value: nestedElementValue,\n executedLookups: nestedExecutedLookups,\n }: Parameters<NestedFormElementValueChangeHandler>[1],\n idPrefix?: string,\n ) => {\n if (nestedElement.type === 'section') {\n // trigger onChange to update sectionState\n onChange(\n {\n ...nestedElement,\n id: idPrefix ? `${idPrefix}${nestedElement.id}` : nestedElement.id,\n },\n { executedLookups: undefined },\n )\n }\n if (!('name' in nestedElement)) return\n onChange(element, {\n value: (existingValue) => ({\n ...existingValue,\n [nestedElement.name]:\n typeof nestedElementValue === 'function'\n ? nestedElementValue(\n existingValue ? existingValue[nestedElement.name] : undefined,\n )\n : nestedElementValue,\n }),\n executedLookups: (existingExecutedLookups) => {\n if (\n typeof existingExecutedLookups === 'boolean' ||\n Array.isArray(existingExecutedLookups)\n ) {\n return {}\n }\n return {\n ...existingExecutedLookups,\n [nestedElement.name]:\n typeof nestedExecutedLookups === 'function'\n ? nestedExecutedLookups(\n existingExecutedLookups?.[\n nestedElement.name\n ] as ExecutedLookups,\n )\n : nestedExecutedLookups,\n }\n },\n })\n },\n [element, onChange],\n )\n\n const handleLookup = React.useCallback<FormElementLookupHandler>(\n (mergeLookupResults) => {\n onLookup((currentFormSubmission) => {\n let model = currentFormSubmission.submission[\n element.name\n ] as SubmissionTypes.S3SubmissionData['submission']\n let newExecutedLookups = currentFormSubmission.executedLookups?.[\n element.name\n ] as ExecutedLookups\n\n const elements = currentFormSubmission.elements.map((formElement) => {\n if (\n formElement.type === 'form' &&\n formElement.name === element.name &&\n Array.isArray(formElement.elements)\n ) {\n const { elements, submission, executedLookups } =\n mergeLookupResults({\n elements: formElement.elements,\n submission: model,\n lastElementUpdated: currentFormSubmission.lastElementUpdated,\n executedLookups: newExecutedLookups,\n sectionState: currentFormSubmission.sectionState,\n })\n model = submission\n newExecutedLookups = executedLookups as ExecutedLookups\n return {\n ...formElement,\n elements,\n }\n }\n return formElement\n })\n\n const submission = {\n ...currentFormSubmission.submission,\n [element.name]: model,\n }\n\n return {\n elements,\n submission,\n lastElementUpdated: currentFormSubmission.lastElementUpdated,\n executedLookups: {\n ...currentFormSubmission.executedLookups,\n [element.name]: newExecutedLookups,\n },\n sectionState: currentFormSubmission.sectionState,\n }\n })\n },\n [element.name, onLookup],\n )\n\n const validation = React.useMemo(() => {\n return !!formElementValidation &&\n typeof formElementValidation !== 'string' &&\n formElementValidation.type === 'formElements'\n ? formElementValidation.formElements\n : undefined\n }, [formElementValidation])\n\n const formElementsConditionallyShown = React.useMemo(() => {\n return formElementConditionallyShown &&\n formElementConditionallyShown.type === 'formElements'\n ? formElementConditionallyShown.formElements\n : undefined\n }, [formElementConditionallyShown])\n\n const parentElement = React.useMemo(() => {\n return {\n elements: Array.isArray(element.elements) ? element.elements : [],\n }\n }, [element.elements])\n\n const handleUpdateNestedFormElements =\n React.useCallback<UpdateFormElementsHandler>(\n (setter) => {\n onUpdateFormElements((formElements) => {\n return formElements.map((formElement) => {\n if (\n formElement.id === element.id &&\n formElement.type === 'form' &&\n Array.isArray(formElement.elements)\n ) {\n return {\n ...formElement,\n elements: setter(formElement.elements),\n }\n }\n return formElement\n })\n })\n },\n [element.id, onUpdateFormElements],\n )\n\n const elementDOMId = React.useMemo(() => new ElementDOMId(id), [id])\n\n return (\n <OneBlinkFormElements\n formId={formId}\n formElementsValidation={validation}\n displayValidationMessages={displayValidationMessages}\n elements={parentElement.elements}\n onChange={handleNestedChange}\n onLookup={handleLookup}\n formElementsConditionallyShown={formElementsConditionallyShown}\n model={value || {}}\n parentElement={parentElement}\n idPrefix={elementDOMId.subFormDOMIdPrefix}\n onUpdateFormElements={handleUpdateNestedFormElements}\n sectionState={sectionState}\n />\n )\n}\n\nexport default React.memo(FormElementForm)\n"]}
1
+ {"version":3,"file":"FormElementForm.js","sourceRoot":"","sources":["../../src/form-elements/FormElementForm.tsx"],"names":[],"mappings":"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","sourcesContent":["import { FormTypes, SubmissionTypes } from '@oneblink/types'\nimport * as React from 'react'\nimport OneBlinkFormElements from '../components/renderer/OneBlinkFormElements'\nimport {\n ExecutedLookups,\n FormElementConditionallyShown,\n FormElementLookupHandler,\n FormElementValidation,\n NestedFormElementValueChangeHandler,\n SectionState,\n UpdateFormElementsHandler,\n} from '../types/form'\nimport ElementDOMId from '../utils/elementDOMIds'\n\nexport type Props = {\n formId: number\n id: string\n element: FormTypes.FormFormElement\n value: SubmissionTypes.S3SubmissionData['submission'] | undefined\n onChange: NestedFormElementValueChangeHandler<\n SubmissionTypes.S3SubmissionData['submission']\n >\n onLookup: FormElementLookupHandler\n formElementValidation: FormElementValidation | undefined\n displayValidationMessages: boolean\n formElementConditionallyShown: FormElementConditionallyShown | undefined\n onUpdateFormElements: UpdateFormElementsHandler\n sectionState: SectionState\n}\n\nfunction FormElementForm({\n formId,\n element,\n value,\n id,\n formElementValidation,\n displayValidationMessages,\n formElementConditionallyShown,\n onChange,\n onLookup,\n onUpdateFormElements,\n sectionState,\n}: Props) {\n const handleNestedChange = React.useCallback(\n (\n nestedElement: FormTypes.FormElement,\n {\n value: nestedElementValue,\n executedLookups: nestedExecutedLookups,\n sectionState,\n }: Parameters<NestedFormElementValueChangeHandler>[1],\n idPrefix?: string,\n ) => {\n if (nestedElement.type === 'section') {\n // trigger onChange to update sectionState\n onChange(\n {\n ...nestedElement,\n id: idPrefix ? `${idPrefix}${nestedElement.id}` : nestedElement.id,\n },\n { executedLookups: undefined, sectionState },\n )\n }\n if (!('name' in nestedElement)) return\n onChange(element, {\n value: (existingValue) => ({\n ...existingValue,\n [nestedElement.name]:\n typeof nestedElementValue === 'function'\n ? nestedElementValue(\n existingValue ? existingValue[nestedElement.name] : undefined,\n )\n : nestedElementValue,\n }),\n executedLookups: (existingExecutedLookups) => {\n if (\n typeof existingExecutedLookups === 'boolean' ||\n Array.isArray(existingExecutedLookups)\n ) {\n return {}\n }\n return {\n ...existingExecutedLookups,\n [nestedElement.name]:\n typeof nestedExecutedLookups === 'function'\n ? nestedExecutedLookups(\n existingExecutedLookups?.[\n nestedElement.name\n ] as ExecutedLookups,\n )\n : nestedExecutedLookups,\n }\n },\n sectionState,\n })\n },\n [element, onChange],\n )\n\n const handleLookup = React.useCallback<FormElementLookupHandler>(\n (mergeLookupResults) => {\n onLookup((currentFormSubmission) => {\n let model = currentFormSubmission.submission[\n element.name\n ] as SubmissionTypes.S3SubmissionData['submission']\n let newExecutedLookups = currentFormSubmission.executedLookups?.[\n element.name\n ] as ExecutedLookups\n\n const elements = currentFormSubmission.elements.map((formElement) => {\n if (\n formElement.type === 'form' &&\n formElement.name === element.name &&\n Array.isArray(formElement.elements)\n ) {\n const { elements, submission, executedLookups } =\n mergeLookupResults({\n elements: formElement.elements,\n submission: model,\n lastElementUpdated: currentFormSubmission.lastElementUpdated,\n executedLookups: newExecutedLookups,\n sectionState: currentFormSubmission.sectionState,\n })\n model = submission\n newExecutedLookups = executedLookups as ExecutedLookups\n return {\n ...formElement,\n elements,\n }\n }\n return formElement\n })\n\n const submission = {\n ...currentFormSubmission.submission,\n [element.name]: model,\n }\n\n return {\n elements,\n submission,\n lastElementUpdated: currentFormSubmission.lastElementUpdated,\n executedLookups: {\n ...currentFormSubmission.executedLookups,\n [element.name]: newExecutedLookups,\n },\n sectionState: currentFormSubmission.sectionState,\n }\n })\n },\n [element.name, onLookup],\n )\n\n const validation = React.useMemo(() => {\n return !!formElementValidation &&\n typeof formElementValidation !== 'string' &&\n formElementValidation.type === 'formElements'\n ? formElementValidation.formElements\n : undefined\n }, [formElementValidation])\n\n const formElementsConditionallyShown = React.useMemo(() => {\n return formElementConditionallyShown &&\n formElementConditionallyShown.type === 'formElements'\n ? formElementConditionallyShown.formElements\n : undefined\n }, [formElementConditionallyShown])\n\n const parentElement = React.useMemo(() => {\n return {\n elements: Array.isArray(element.elements) ? element.elements : [],\n }\n }, [element.elements])\n\n const handleUpdateNestedFormElements =\n React.useCallback<UpdateFormElementsHandler>(\n (setter) => {\n onUpdateFormElements((formElements) => {\n return formElements.map((formElement) => {\n if (\n formElement.id === element.id &&\n formElement.type === 'form' &&\n Array.isArray(formElement.elements)\n ) {\n return {\n ...formElement,\n elements: setter(formElement.elements),\n }\n }\n return formElement\n })\n })\n },\n [element.id, onUpdateFormElements],\n )\n\n const elementDOMId = React.useMemo(() => new ElementDOMId(id), [id])\n\n return (\n <OneBlinkFormElements\n formId={formId}\n formElementsValidation={validation}\n displayValidationMessages={displayValidationMessages}\n elements={parentElement.elements}\n onChange={handleNestedChange}\n onLookup={handleLookup}\n formElementsConditionallyShown={formElementsConditionallyShown}\n model={value || {}}\n parentElement={parentElement}\n idPrefix={elementDOMId.subFormDOMIdPrefix}\n onUpdateFormElements={handleUpdateNestedFormElements}\n sectionState={sectionState}\n />\n )\n}\n\nexport default React.memo(FormElementForm)\n"]}
@@ -13,6 +13,7 @@ import useGoogleMapsApiKey from '../hooks/useGoogleMapsApiKey';
13
13
  import FormElementLabelContainer from '../components/renderer/FormElementLabelContainer';
14
14
  import { LookupNotificationContext } from '../hooks/useLookupNotification';
15
15
  import { useReverseGeocodeContext } from '../components/renderer/ReverseGeocode';
16
+ import useElementAriaDescribedby from '../hooks/useElementAriaDescribedby';
16
17
  export const stringifyLocation = (location) => {
17
18
  if (location) {
18
19
  return `${location.latitude},${location.longitude}`;
@@ -36,6 +37,7 @@ const mapHeight = 300;
36
37
  const initialMapZoom = 15;
37
38
  const apiUrl = 'https://maps.googleapis.com/maps/api/staticmap';
38
39
  function FormElementLocation({ id, element, value, onChange, validationMessage, displayValidationMessage, isDirty, setIsDirty, }) {
40
+ const ariaDescribedby = useElementAriaDescribedby(id, element);
39
41
  const [isLocationPickerOpen, showLocationPicker, hideLocationPicker] = useBooleanState(false);
40
42
  const [location, setLocation] = React.useState(undefined);
41
43
  const onClear = React.useCallback(() => {
@@ -95,7 +97,7 @@ function FormElementLocation({ id, element, value, onChange, validationMessage,
95
97
  'is-loading': isReverseGeocoding,
96
98
  }), onClick: onConfirm, disabled: element.readOnly || !location || isReverseGeocoding }, "Confirm"))) : (React.createElement(React.Fragment, null,
97
99
  React.createElement("button", { type: "button", className: "is-light button ob-button ob-button__clear ob-button-clear ob-location__button ob-location__button-clear cypress-clear-location-button", onClick: onClear, disabled: element.readOnly }, "Clear"),
98
- React.createElement("button", { type: "button", className: "is-primary button ob-button ob-button__edit ob-location__button ob-location__button-edit cypress-locate-button", onClick: onLocate, disabled: element.readOnly, onBlur: setIsDirty, id: id }, "Locate"))))),
100
+ React.createElement("button", { type: "button", className: "is-primary button ob-button ob-button__edit ob-location__button ob-location__button-edit cypress-locate-button", onClick: onLocate, disabled: element.readOnly, onBlur: setIsDirty, id: id, "aria-describedby": ariaDescribedby }, "Locate"))))),
99
101
  isDisplayingValidationMessage && (React.createElement("div", { role: "alert", className: "has-margin-top-8" },
100
102
  React.createElement("div", { className: "has-text-danger ob-error__text cypress-validation-message" }, validationMessage))),
101
103
  reverseGeocodingErrorMsg && (React.createElement("div", { role: "alert", className: "has-margin-top-8" },
@@ -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 { FormTypes } from '@oneblink/types'\nimport { Sentry } from '@oneblink/apps'\nimport clsx from 'clsx'\nimport { GoogleMap, Marker } from '@react-google-maps/api'\nimport queryString from 'query-string'\n\nimport useBooleanState from '../hooks/useBooleanState'\nimport useIsOffline from '../hooks/useIsOffline'\nimport * as geolocation from '../services/geolocation'\nimport OnLoading from '../components/renderer/OnLoading'\nimport defaultCoords from '../services/defaultCoordinates'\nimport useGoogle from '../hooks/useGoogle'\nimport useGoogleMapsApiKey from '../hooks/useGoogleMapsApiKey'\nimport FormElementLabelContainer from '../components/renderer/FormElementLabelContainer'\nimport { FormElementValueChangeHandler, IsDirtyProps } from '../types/form'\nimport { LookupNotificationContext } from '../hooks/useLookupNotification'\nimport { useReverseGeocodeContext } from '../components/renderer/ReverseGeocode'\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} & IsDirtyProps\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\nexport function 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'\n\nfunction FormElementLocation({\n id,\n element,\n value,\n onChange,\n validationMessage,\n displayValidationMessage,\n isDirty,\n setIsDirty,\n}: Props) {\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, {\n value: undefined,\n })\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, {\n value: location,\n })\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 const { isLookingUp } = React.useContext(LookupNotificationContext)\n const isDisplayingValidationMessage =\n (isDirty || displayValidationMessage) && !!validationMessage && !isLookingUp\n\n const { isReverseGeocoding, reverseGeocodingErrorMsg } =\n useReverseGeocodeContext()\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 || isReverseGeocoding ? (\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 || isReverseGeocoding}\n >\n Cancel\n </button>\n <button\n type=\"button\"\n className={clsx(\n 'is-primary button ob-button ob-button__confirm ob-location__button ob-location__button-confirm cypress-confirm-location-button',\n {\n 'is-loading': isReverseGeocoding,\n },\n )}\n onClick={onConfirm}\n disabled={element.readOnly || !location || isReverseGeocoding}\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 onBlur={setIsDirty}\n id={id}\n >\n Locate\n </button>\n </>\n )}\n </div>\n </div>\n\n {isDisplayingValidationMessage && (\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 {reverseGeocodingErrorMsg && (\n <div role=\"alert\" className=\"has-margin-top-8\">\n <div className=\"has-text-danger ob-error__text cypress-validation-message\">\n {reverseGeocodingErrorMsg}\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\" role=\"alert\">\n You are currently offline\n </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 = useGoogleMapsApiKey()\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 LocationPicker({\n location,\n onChange,\n}: {\n location: Coords\n onChange: (newLocation: Coords) => void\n}) {\n const { isLoaded } = useGoogle()\n\n return (\n <figure className=\"ob-figure\">\n {isLoaded && (\n <GoogleLocationPicker location={location} onChange={onChange} />\n )}\n </figure>\n )\n})\n\nconst GoogleLocationPicker = React.memo(function GoogleLocationPicker({\n location,\n onChange,\n}: {\n location: Coords\n onChange: (newLocation: Coords) => void\n}) {\n const [map, setMap] = React.useState<google.maps.Map | null>(null)\n const [marker, setMarker] = React.useState<google.maps.Marker | null>(null)\n\n const originalCenter = React.useRef<{ lat: number; lng: number }>({\n lat: location.latitude,\n lng: location.longitude,\n })\n\n const markerAnimation = React.useMemo(() => google.maps.Animation.DROP, [])\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 const handleDragEnd = React.useCallback(\n (e: google.maps.MapMouseEvent) => {\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 if (map) {\n map.panTo(e.latLng)\n }\n },\n [location.zoom, map, onChange],\n )\n\n const handleClick = React.useCallback(\n (e: google.maps.MapMouseEvent) => {\n handleDragEnd(e)\n\n if (!e.latLng || !marker) {\n return\n }\n\n marker.setPosition(e.latLng)\n // this enables the marker to animate after moving it\n marker.setMap(null)\n marker.setAnimation(markerAnimation)\n marker.setMap(map)\n },\n [handleDragEnd, map, marker, markerAnimation],\n )\n\n return (\n <GoogleMap\n onLoad={(map) => setMap(map)}\n onUnmount={() => setMap(null)}\n mapContainerStyle={{\n height: 300,\n }}\n center={originalCenter.current}\n zoom={location.zoom}\n onZoomChanged={onZoomChanged}\n onClick={handleClick}\n options={{ draggableCursor: 'pointer' }}\n >\n <Marker\n onLoad={(marker) => setMarker(marker)}\n onUnmount={() => setMarker(null)}\n animation={markerAnimation}\n position={originalCenter.current}\n draggable\n onDragEnd={handleDragEnd}\n ></Marker>\n </GoogleMap>\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 { FormTypes } from '@oneblink/types'\nimport { Sentry } from '@oneblink/apps'\nimport clsx from 'clsx'\nimport { GoogleMap, Marker } from '@react-google-maps/api'\nimport queryString from 'query-string'\n\nimport useBooleanState from '../hooks/useBooleanState'\nimport useIsOffline from '../hooks/useIsOffline'\nimport * as geolocation from '../services/geolocation'\nimport OnLoading from '../components/renderer/OnLoading'\nimport defaultCoords from '../services/defaultCoordinates'\nimport useGoogle from '../hooks/useGoogle'\nimport useGoogleMapsApiKey from '../hooks/useGoogleMapsApiKey'\nimport FormElementLabelContainer from '../components/renderer/FormElementLabelContainer'\nimport { FormElementValueChangeHandler, IsDirtyProps } from '../types/form'\nimport { LookupNotificationContext } from '../hooks/useLookupNotification'\nimport { useReverseGeocodeContext } from '../components/renderer/ReverseGeocode'\nimport useElementAriaDescribedby from '../hooks/useElementAriaDescribedby'\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} & IsDirtyProps\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\nexport function 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'\n\nfunction FormElementLocation({\n id,\n element,\n value,\n onChange,\n validationMessage,\n displayValidationMessage,\n isDirty,\n setIsDirty,\n}: Props) {\n const ariaDescribedby = useElementAriaDescribedby(id, element)\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, {\n value: undefined,\n })\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, {\n value: location,\n })\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 const { isLookingUp } = React.useContext(LookupNotificationContext)\n const isDisplayingValidationMessage =\n (isDirty || displayValidationMessage) && !!validationMessage && !isLookingUp\n\n const { isReverseGeocoding, reverseGeocodingErrorMsg } =\n useReverseGeocodeContext()\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 || isReverseGeocoding ? (\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 || isReverseGeocoding}\n >\n Cancel\n </button>\n <button\n type=\"button\"\n className={clsx(\n 'is-primary button ob-button ob-button__confirm ob-location__button ob-location__button-confirm cypress-confirm-location-button',\n {\n 'is-loading': isReverseGeocoding,\n },\n )}\n onClick={onConfirm}\n disabled={element.readOnly || !location || isReverseGeocoding}\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 onBlur={setIsDirty}\n id={id}\n aria-describedby={ariaDescribedby}\n >\n Locate\n </button>\n </>\n )}\n </div>\n </div>\n\n {isDisplayingValidationMessage && (\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 {reverseGeocodingErrorMsg && (\n <div role=\"alert\" className=\"has-margin-top-8\">\n <div className=\"has-text-danger ob-error__text cypress-validation-message\">\n {reverseGeocodingErrorMsg}\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\" role=\"alert\">\n You are currently offline\n </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 = useGoogleMapsApiKey()\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 LocationPicker({\n location,\n onChange,\n}: {\n location: Coords\n onChange: (newLocation: Coords) => void\n}) {\n const { isLoaded } = useGoogle()\n\n return (\n <figure className=\"ob-figure\">\n {isLoaded && (\n <GoogleLocationPicker location={location} onChange={onChange} />\n )}\n </figure>\n )\n})\n\nconst GoogleLocationPicker = React.memo(function GoogleLocationPicker({\n location,\n onChange,\n}: {\n location: Coords\n onChange: (newLocation: Coords) => void\n}) {\n const [map, setMap] = React.useState<google.maps.Map | null>(null)\n const [marker, setMarker] = React.useState<google.maps.Marker | null>(null)\n\n const originalCenter = React.useRef<{ lat: number; lng: number }>({\n lat: location.latitude,\n lng: location.longitude,\n })\n\n const markerAnimation = React.useMemo(() => google.maps.Animation.DROP, [])\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 const handleDragEnd = React.useCallback(\n (e: google.maps.MapMouseEvent) => {\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 if (map) {\n map.panTo(e.latLng)\n }\n },\n [location.zoom, map, onChange],\n )\n\n const handleClick = React.useCallback(\n (e: google.maps.MapMouseEvent) => {\n handleDragEnd(e)\n\n if (!e.latLng || !marker) {\n return\n }\n\n marker.setPosition(e.latLng)\n // this enables the marker to animate after moving it\n marker.setMap(null)\n marker.setAnimation(markerAnimation)\n marker.setMap(map)\n },\n [handleDragEnd, map, marker, markerAnimation],\n )\n\n return (\n <GoogleMap\n onLoad={(map) => setMap(map)}\n onUnmount={() => setMap(null)}\n mapContainerStyle={{\n height: 300,\n }}\n center={originalCenter.current}\n zoom={location.zoom}\n onZoomChanged={onZoomChanged}\n onClick={handleClick}\n options={{ draggableCursor: 'pointer' }}\n >\n <Marker\n onLoad={(marker) => setMarker(marker)}\n onUnmount={() => setMarker(null)}\n animation={markerAnimation}\n position={originalCenter.current}\n draggable\n onDragEnd={handleDragEnd}\n ></Marker>\n </GoogleMap>\n )\n})\n\nexport default React.memo(FormElementLocation)\n"]}
@@ -45,17 +45,17 @@ function FormElementNumber({ id, element, value, onChange, validationMessage, di
45
45
  React.createElement(FormElementLabelContainer, { className: "ob-number", id: id, element: element, required: element.required },
46
46
  !element.isSlider ? (React.createElement("div", { className: "field has-addons" },
47
47
  React.createElement("div", { className: "control is-expanded has-icons-right" },
48
- React.createElement("input", { type: "number", placeholder: element.placeholderValue, id: id, value: typeof value === 'number' ? value : '', name: element.name, className: "input ob-input cypress-number-control", onChange: handleChange, required: element.required, disabled: element.readOnly, onBlur: setIsDirty, ref: htmlInputElementRef, onWheel: handleWheel, "aria-describedby": ariaDescribedby, autoComplete: autocompleteAttributes }),
48
+ React.createElement("input", { type: "number", placeholder: element.placeholderValue, id: id, value: typeof value === 'number' ? value : '', name: element.name, className: "input ob-input cypress-number-control", onChange: handleChange, required: element.required, disabled: element.readOnly, onBlur: setIsDirty, ref: htmlInputElementRef, onWheel: handleWheel, "aria-describedby": ariaDescribedby, autoComplete: autocompleteAttributes, "aria-required": element.required }),
49
49
  React.createElement("span", { className: "ob-input-icon icon is-small is-right" },
50
50
  React.createElement(MaterialIcon, { className: "is-size-5" }, element.displayAsCurrency ? 'attach_money' : 'tag'))),
51
51
  !!element.readOnly && !!text && (React.createElement("div", { className: "control" },
52
52
  React.createElement(CopyToClipboardButton, { className: "button is-input-addon copy-button cypress-copy-to-clipboard-button", text: text }))),
53
- React.createElement(LookupButton, { isInputButton: true, value: value, validationMessage: validationMessage, lookupButtonConfig: element.lookupButton }))) : isPageVisible ? (React.createElement(SliderControl, { id: id, text: text, value: value, element: element, onChange: handleChange, onBlur: setIsDirty })) : undefined,
53
+ React.createElement(LookupButton, { isInputButton: true, value: value, validationMessage: validationMessage, lookupButtonConfig: element.lookupButton }))) : isPageVisible ? (React.createElement(SliderControl, { id: id, text: text, value: value, element: element, onChange: handleChange, onBlur: setIsDirty, ariaDescribedby: ariaDescribedby })) : undefined,
54
54
  isDisplayingValidationMessage && (React.createElement("div", { role: "alert", className: "has-margin-top-8" },
55
55
  React.createElement("div", { className: "has-text-danger ob-error__text cypress-validation-message" }, validationMessage))))));
56
56
  }
57
57
  const sliderBubbleWidthInPixels = 24;
58
- const SliderControl = React.memo(function SliderControl({ id, text, value, element, onChange, onBlur, }) {
58
+ const SliderControl = React.memo(function SliderControl({ id, text, value, element, onChange, onBlur, ariaDescribedby, }) {
59
59
  const sliderOutputRef = React.useRef(null);
60
60
  const sliderInputRef = React.useRef(null);
61
61
  const number = React.useMemo(() => (typeof value === 'number' ? value : parseFloat(value)), [value]);
@@ -88,7 +88,7 @@ const SliderControl = React.memo(function SliderControl({ id, text, value, eleme
88
88
  }, [element.maxNumber, element.minNumber, number, removeIsDraggingClass]);
89
89
  return (React.createElement("div", { className: "control" },
90
90
  React.createElement("output", { ref: sliderOutputRef, className: "ob-number__output cypress-number-output", htmlFor: id }, text),
91
- React.createElement("input", { ref: sliderInputRef, id: id, name: element.name, className: "slider ob-input is-fullwidth cypress-slider-number-control is-large is-circle cypress-number-control", step: element.sliderIncrement ? element.sliderIncrement : 1, min: element.minNumber, max: element.maxNumber, value: number, type: "range", onChange: onChange, required: element.required, disabled: element.readOnly, onBlur: onBlur })));
91
+ React.createElement("input", { ref: sliderInputRef, id: id, name: element.name, className: "slider ob-input is-fullwidth cypress-slider-number-control is-large is-circle cypress-number-control", step: element.sliderIncrement ? element.sliderIncrement : 1, min: element.minNumber, max: element.maxNumber, value: number, type: "range", onChange: onChange, required: element.required, "aria-describedby": ariaDescribedby, "aria-required": element.required, disabled: element.readOnly, onBlur: onBlur })));
92
92
  });
93
93
  export default React.memo(FormElementNumber);
94
94
  //# sourceMappingURL=FormElementNumber.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"FormElementNumber.js","sourceRoot":"","sources":["../../src/form-elements/FormElementNumber.tsx"],"names":[],"mappings":"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","sourcesContent":["import * as React from 'react'\nimport CopyToClipboardButton from '../components/renderer/CopyToClipboardButton'\nimport _debounce from 'lodash.debounce'\nimport LookupButton from '../components/renderer/LookupButton'\nimport { FormTypes } from '@oneblink/types'\nimport { localisationService } from '@oneblink/apps'\nimport FormElementLabelContainer from '../components/renderer/FormElementLabelContainer'\nimport { FormElementValueChangeHandler, IsDirtyProps } from '../types/form'\nimport useIsPageVisible from '../hooks/useIsPageVisible'\nimport { LookupNotificationContext } from '../hooks/useLookupNotification'\nimport useElementAriaDescribedby from '../hooks/useElementAriaDescribedby'\nimport MaterialIcon from '../components/MaterialIcon'\n\ntype Props = {\n id: string\n element: FormTypes.NumberElement\n value: unknown\n onChange: FormElementValueChangeHandler<number>\n displayValidationMessage: boolean\n validationMessage: string | undefined\n autocompleteAttributes?: string\n} & IsDirtyProps\n\nfunction FormElementNumber({\n id,\n element,\n value,\n onChange,\n validationMessage,\n displayValidationMessage,\n isDirty,\n setIsDirty,\n autocompleteAttributes,\n}: Props) {\n const ariaDescribedby = useElementAriaDescribedby(id, element)\n const isPageVisible = useIsPageVisible()\n\n const text = React.useMemo(() => {\n if (typeof value !== 'number') {\n return ''\n }\n if (element.displayAsCurrency) {\n return localisationService.formatCurrency(value)\n }\n return value.toString()\n }, [value, element.displayAsCurrency])\n const handleChange = React.useCallback(\n (event: React.ChangeEvent<HTMLInputElement>) => {\n const newValue = parseFloat(event.target.value)\n onChange(element, {\n value: isNaN(newValue) ? undefined : newValue,\n })\n },\n [element, onChange],\n )\n const htmlInputElementRef = React.useRef<HTMLInputElement>(null)\n\n //this onWheel callback prevents numbers changing while scrolling\n const handleWheel = React.useCallback(() => {\n if (htmlInputElementRef.current !== document.activeElement) {\n return\n }\n htmlInputElementRef.current?.blur()\n setTimeout(() => {\n htmlInputElementRef.current?.focus()\n })\n }, [])\n\n const { isLookingUp } = React.useContext(LookupNotificationContext)\n const isDisplayingValidationMessage =\n (isDirty || displayValidationMessage) && !!validationMessage && !isLookingUp\n\n return (\n <div className=\"cypress-number-element\">\n <FormElementLabelContainer\n className=\"ob-number\"\n id={id}\n element={element}\n required={element.required}\n >\n {!element.isSlider ? (\n <div className=\"field has-addons\">\n <div className=\"control is-expanded has-icons-right\">\n <input\n type=\"number\"\n placeholder={element.placeholderValue}\n id={id}\n value={typeof value === 'number' ? value : ''}\n name={element.name}\n className=\"input ob-input cypress-number-control\"\n onChange={handleChange}\n required={element.required}\n disabled={element.readOnly}\n onBlur={setIsDirty}\n ref={htmlInputElementRef}\n onWheel={handleWheel}\n aria-describedby={ariaDescribedby}\n autoComplete={autocompleteAttributes}\n />\n <span className=\"ob-input-icon icon is-small is-right\">\n <MaterialIcon className=\"is-size-5\">\n {element.displayAsCurrency ? 'attach_money' : 'tag'}\n </MaterialIcon>\n </span>\n </div>\n {!!element.readOnly && !!text && (\n <div className=\"control\">\n <CopyToClipboardButton\n className=\"button is-input-addon copy-button cypress-copy-to-clipboard-button\"\n text={text}\n />\n </div>\n )}\n <LookupButton\n isInputButton\n value={value}\n validationMessage={validationMessage}\n lookupButtonConfig={element.lookupButton}\n />\n </div>\n ) : isPageVisible ? (\n <SliderControl\n id={id}\n text={text}\n value={value}\n element={element}\n onChange={handleChange}\n onBlur={setIsDirty}\n />\n ) : undefined}\n\n {isDisplayingValidationMessage && (\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 sliderBubbleWidthInPixels = 24\n\nconst SliderControl = React.memo(function SliderControl({\n id,\n text,\n value,\n element,\n onChange,\n onBlur,\n}: {\n id: string\n text: string\n value: unknown\n element: FormTypes.NumberElement\n onChange: (event: React.ChangeEvent<HTMLInputElement>) => unknown\n onBlur: () => void\n}) {\n const sliderOutputRef = React.useRef<HTMLOutputElement>(null)\n const sliderInputRef = React.useRef<HTMLInputElement>(null)\n\n const number = React.useMemo(\n () => (typeof value === 'number' ? value : parseFloat(value as string)),\n [value],\n )\n\n const removeIsDraggingClass = React.useMemo(\n () =>\n _debounce((outputElement: HTMLOutputElement) => {\n if (outputElement.classList.contains('is-dragging')) {\n outputElement.classList.remove('is-dragging')\n }\n }, 500),\n [],\n )\n\n React.useEffect(() => {\n if (\n Number.isNaN(number) ||\n typeof element.maxNumber !== 'number' ||\n typeof element.minNumber !== 'number'\n ) {\n return\n }\n\n const outputElement = sliderOutputRef.current\n const inputElement = sliderInputRef.current\n if (outputElement && inputElement) {\n const range = element.maxNumber - element.minNumber\n const percentage = (number - element.minNumber) / range\n const inputWidth = inputElement.getBoundingClientRect().width\n const outputWidth = outputElement.getBoundingClientRect().width\n const sliderBubbleOffSetPixels =\n (percentage - 0.5) * -sliderBubbleWidthInPixels\n\n outputElement.style.left = `${percentage * inputWidth}px`\n outputElement.style.marginLeft = `-${\n outputWidth / 2 - sliderBubbleOffSetPixels\n }px`\n\n if (!outputElement.classList.contains('is-dragging')) {\n outputElement.classList.add('is-dragging')\n }\n removeIsDraggingClass(outputElement)\n }\n }, [element.maxNumber, element.minNumber, number, removeIsDraggingClass])\n\n return (\n <div className=\"control\">\n <output\n ref={sliderOutputRef}\n className=\"ob-number__output cypress-number-output\"\n htmlFor={id}\n >\n {text}\n </output>\n <input\n ref={sliderInputRef}\n id={id}\n name={element.name}\n className=\"slider ob-input is-fullwidth cypress-slider-number-control is-large is-circle cypress-number-control\"\n step={element.sliderIncrement ? element.sliderIncrement : 1}\n min={element.minNumber}\n max={element.maxNumber}\n value={number}\n type=\"range\"\n onChange={onChange}\n required={element.required}\n disabled={element.readOnly}\n onBlur={onBlur}\n />\n </div>\n )\n})\n\nexport default React.memo(FormElementNumber)\n"]}
1
+ {"version":3,"file":"FormElementNumber.js","sourceRoot":"","sources":["../../src/form-elements/FormElementNumber.tsx"],"names":[],"mappings":"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","sourcesContent":["import * as React from 'react'\nimport CopyToClipboardButton from '../components/renderer/CopyToClipboardButton'\nimport _debounce from 'lodash.debounce'\nimport LookupButton from '../components/renderer/LookupButton'\nimport { FormTypes } from '@oneblink/types'\nimport { localisationService } from '@oneblink/apps'\nimport FormElementLabelContainer from '../components/renderer/FormElementLabelContainer'\nimport { FormElementValueChangeHandler, IsDirtyProps } from '../types/form'\nimport useIsPageVisible from '../hooks/useIsPageVisible'\nimport { LookupNotificationContext } from '../hooks/useLookupNotification'\nimport useElementAriaDescribedby from '../hooks/useElementAriaDescribedby'\nimport MaterialIcon from '../components/MaterialIcon'\n\ntype Props = {\n id: string\n element: FormTypes.NumberElement\n value: unknown\n onChange: FormElementValueChangeHandler<number>\n displayValidationMessage: boolean\n validationMessage: string | undefined\n autocompleteAttributes?: string\n} & IsDirtyProps\n\nfunction FormElementNumber({\n id,\n element,\n value,\n onChange,\n validationMessage,\n displayValidationMessage,\n isDirty,\n setIsDirty,\n autocompleteAttributes,\n}: Props) {\n const ariaDescribedby = useElementAriaDescribedby(id, element)\n const isPageVisible = useIsPageVisible()\n\n const text = React.useMemo(() => {\n if (typeof value !== 'number') {\n return ''\n }\n if (element.displayAsCurrency) {\n return localisationService.formatCurrency(value)\n }\n return value.toString()\n }, [value, element.displayAsCurrency])\n const handleChange = React.useCallback(\n (event: React.ChangeEvent<HTMLInputElement>) => {\n const newValue = parseFloat(event.target.value)\n onChange(element, {\n value: isNaN(newValue) ? undefined : newValue,\n })\n },\n [element, onChange],\n )\n const htmlInputElementRef = React.useRef<HTMLInputElement>(null)\n\n //this onWheel callback prevents numbers changing while scrolling\n const handleWheel = React.useCallback(() => {\n if (htmlInputElementRef.current !== document.activeElement) {\n return\n }\n htmlInputElementRef.current?.blur()\n setTimeout(() => {\n htmlInputElementRef.current?.focus()\n })\n }, [])\n\n const { isLookingUp } = React.useContext(LookupNotificationContext)\n const isDisplayingValidationMessage =\n (isDirty || displayValidationMessage) && !!validationMessage && !isLookingUp\n\n return (\n <div className=\"cypress-number-element\">\n <FormElementLabelContainer\n className=\"ob-number\"\n id={id}\n element={element}\n required={element.required}\n >\n {!element.isSlider ? (\n <div className=\"field has-addons\">\n <div className=\"control is-expanded has-icons-right\">\n <input\n type=\"number\"\n placeholder={element.placeholderValue}\n id={id}\n value={typeof value === 'number' ? value : ''}\n name={element.name}\n className=\"input ob-input cypress-number-control\"\n onChange={handleChange}\n required={element.required}\n disabled={element.readOnly}\n onBlur={setIsDirty}\n ref={htmlInputElementRef}\n onWheel={handleWheel}\n aria-describedby={ariaDescribedby}\n autoComplete={autocompleteAttributes}\n aria-required={element.required}\n />\n <span className=\"ob-input-icon icon is-small is-right\">\n <MaterialIcon className=\"is-size-5\">\n {element.displayAsCurrency ? 'attach_money' : 'tag'}\n </MaterialIcon>\n </span>\n </div>\n {!!element.readOnly && !!text && (\n <div className=\"control\">\n <CopyToClipboardButton\n className=\"button is-input-addon copy-button cypress-copy-to-clipboard-button\"\n text={text}\n />\n </div>\n )}\n <LookupButton\n isInputButton\n value={value}\n validationMessage={validationMessage}\n lookupButtonConfig={element.lookupButton}\n />\n </div>\n ) : isPageVisible ? (\n <SliderControl\n id={id}\n text={text}\n value={value}\n element={element}\n onChange={handleChange}\n onBlur={setIsDirty}\n ariaDescribedby={ariaDescribedby}\n />\n ) : undefined}\n\n {isDisplayingValidationMessage && (\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 sliderBubbleWidthInPixels = 24\n\nconst SliderControl = React.memo(function SliderControl({\n id,\n text,\n value,\n element,\n onChange,\n onBlur,\n ariaDescribedby,\n}: {\n id: string\n text: string\n value: unknown\n element: FormTypes.NumberElement\n ariaDescribedby: string | undefined\n onChange: (event: React.ChangeEvent<HTMLInputElement>) => unknown\n onBlur: () => void\n}) {\n const sliderOutputRef = React.useRef<HTMLOutputElement>(null)\n const sliderInputRef = React.useRef<HTMLInputElement>(null)\n\n const number = React.useMemo(\n () => (typeof value === 'number' ? value : parseFloat(value as string)),\n [value],\n )\n\n const removeIsDraggingClass = React.useMemo(\n () =>\n _debounce((outputElement: HTMLOutputElement) => {\n if (outputElement.classList.contains('is-dragging')) {\n outputElement.classList.remove('is-dragging')\n }\n }, 500),\n [],\n )\n\n React.useEffect(() => {\n if (\n Number.isNaN(number) ||\n typeof element.maxNumber !== 'number' ||\n typeof element.minNumber !== 'number'\n ) {\n return\n }\n\n const outputElement = sliderOutputRef.current\n const inputElement = sliderInputRef.current\n if (outputElement && inputElement) {\n const range = element.maxNumber - element.minNumber\n const percentage = (number - element.minNumber) / range\n const inputWidth = inputElement.getBoundingClientRect().width\n const outputWidth = outputElement.getBoundingClientRect().width\n const sliderBubbleOffSetPixels =\n (percentage - 0.5) * -sliderBubbleWidthInPixels\n\n outputElement.style.left = `${percentage * inputWidth}px`\n outputElement.style.marginLeft = `-${\n outputWidth / 2 - sliderBubbleOffSetPixels\n }px`\n\n if (!outputElement.classList.contains('is-dragging')) {\n outputElement.classList.add('is-dragging')\n }\n removeIsDraggingClass(outputElement)\n }\n }, [element.maxNumber, element.minNumber, number, removeIsDraggingClass])\n\n return (\n <div className=\"control\">\n <output\n ref={sliderOutputRef}\n className=\"ob-number__output cypress-number-output\"\n htmlFor={id}\n >\n {text}\n </output>\n <input\n ref={sliderInputRef}\n id={id}\n name={element.name}\n className=\"slider ob-input is-fullwidth cypress-slider-number-control is-large is-circle cypress-number-control\"\n step={element.sliderIncrement ? element.sliderIncrement : 1}\n min={element.minNumber}\n max={element.maxNumber}\n value={number}\n type=\"range\"\n onChange={onChange}\n required={element.required}\n aria-describedby={ariaDescribedby}\n aria-required={element.required}\n disabled={element.readOnly}\n onBlur={onBlur}\n />\n </div>\n )\n})\n\nexport default React.memo(FormElementNumber)\n"]}
@@ -91,7 +91,7 @@ function FormElementPointCadastralParcel({ id, formId, element, value, onChange,
91
91
  value: undefined,
92
92
  });
93
93
  }
94
- }, required: element.required, disabled: element.readOnly, onBlur: setIsDirty, "aria-describedby": ariaDescribedby, autoComplete: autocompleteAttributes }),
94
+ }, required: element.required, disabled: element.readOnly, onBlur: setIsDirty, "aria-describedby": ariaDescribedby, autoComplete: autocompleteAttributes, "aria-required": element.required }),
95
95
  !isLoading && (React.createElement("span", { className: " ob-input-icon icon is-small is-right" }, value ? (React.createElement(MaterialIcon, { className: "is-size-5 has-text-success" }, "check")) : (error === null || error === void 0 ? void 0 : error.message) ? (React.createElement(MaterialIcon, { className: "is-size-5 has-text-danger" }, "error")) : (React.createElement(MaterialIcon, { className: "is-size-5" }, "map"))))),
96
96
  hasCopyButton && (React.createElement("div", { className: "control" },
97
97
  React.createElement(CopyToClipboardButton, { className: "button is-input-addon copy-button cypress-copy-to-clipboard-button", text: label })))),
@@ -1 +1 @@
1
- {"version":3,"file":"FormElementPointCadastralParcel.js","sourceRoot":"","sources":["../../src/form-elements/FormElementPointCadastralParcel.tsx"],"names":[],"mappings":"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","sourcesContent":["import * as React from 'react'\nimport clsx from 'clsx'\nimport CopyToClipboardButton from '../components/renderer/CopyToClipboardButton'\nimport { FormTypes, PointTypes } from '@oneblink/types'\nimport FormElementLabelContainer from '../components/renderer/FormElementLabelContainer'\nimport { FormElementValueChangeHandler, IsDirtyProps } from '../types/form'\nimport { LookupNotificationContext } from '../hooks/useLookupNotification'\nimport useElementAriaDescribedby from '../hooks/useElementAriaDescribedby'\nimport { formService } from '@oneblink/apps'\nimport { Collapse } from '@mui/material'\nimport {\n NotificationGrid,\n NotificationGridItem,\n} from '../components/NotificationGrid'\nimport MaterialIcon from '../components/MaterialIcon'\n\nconst pointCadastralParcelClass = 'ob-point-cadastral-parcel'\n\nfunction FormElementPointCadastralParcel({\n id,\n formId,\n element,\n value,\n onChange,\n validationMessage,\n displayValidationMessage,\n isDirty,\n setIsDirty,\n autocompleteAttributes,\n}: {\n id: string\n formId: number\n element: FormTypes.PointCadastralParcelElement\n value: PointTypes.PointCadastralParcelResponse | undefined\n onChange: FormElementValueChangeHandler<PointTypes.PointCadastralParcelResponse>\n displayValidationMessage: boolean\n validationMessage: string | undefined\n autocompleteAttributes?: string\n} & IsDirtyProps) {\n const ariaDescribedby = useElementAriaDescribedby(id, element)\n const parcelId = value?.parcelBundle?.[0]?.parcelId\n const [label, setLabel] = React.useState(parcelId || '')\n const [{ isLoading, error }, setState] = React.useState<{\n isLoading: boolean\n error: Error | null\n }>({\n isLoading: false,\n error: null,\n })\n\n const loadCadastralParcel = React.useCallback(\n async (abortSignal: AbortSignal) => {\n if (!label || label === parcelId) {\n return\n }\n\n setState({\n isLoading: true,\n error: null,\n })\n\n try {\n console.log('Attempting to load NSW point cadastral parcel', {\n formId,\n parcelId: label,\n })\n const result = await formService.getPointCadastralParcel(\n formId,\n label,\n abortSignal,\n )\n if (!abortSignal.aborted) {\n onChange(element, {\n value: result,\n })\n setState({\n error: null,\n isLoading: false,\n })\n }\n } catch (err) {\n if (!abortSignal.aborted) {\n setState({\n isLoading: false,\n error: err as Error,\n })\n }\n }\n },\n [element, formId, label, onChange, parcelId],\n )\n\n React.useEffect(() => {\n const abortController = new AbortController()\n const timeoutId = setTimeout(() => {\n loadCadastralParcel(abortController.signal)\n }, 750)\n return () => {\n abortController.abort()\n clearTimeout(timeoutId)\n }\n }, [loadCadastralParcel])\n\n // Ensure the label is set if the value is set outside of this component\n React.useEffect(() => {\n if (parcelId && label !== parcelId) {\n setLabel(parcelId)\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [value])\n\n const { isLookingUp } = React.useContext(LookupNotificationContext)\n const isDisplayingValidationMessage =\n (((isDirty || displayValidationMessage) &&\n !!validationMessage &&\n !isLoading) ||\n error) &&\n !isLookingUp\n\n const hasCopyButton = !!value && !!element.readOnly\n return (\n <div className=\"cypress-point-cadastral-parcel-element\">\n <FormElementLabelContainer\n className={pointCadastralParcelClass}\n id={id}\n element={element}\n required={element.required}\n >\n <div\n className={clsx('field has-addons', {\n 'no-addons-mobile': !hasCopyButton,\n })}\n >\n <div\n className={clsx('control is-expanded has-icons-right', {\n 'is-loading': isLoading,\n 'has-icons-right': !isLoading,\n })}\n >\n <input\n type=\"text\"\n id={id}\n name={element.name}\n className=\"input ob-input cypress-point-cadastral-parcel-control\"\n placeholder={element.placeholderValue}\n value={label}\n onChange={(e) => {\n setLabel(e.target.value)\n if (value) {\n onChange(element, {\n value: undefined,\n })\n }\n }}\n required={element.required}\n disabled={element.readOnly}\n onBlur={setIsDirty}\n aria-describedby={ariaDescribedby}\n autoComplete={autocompleteAttributes}\n />\n {!isLoading && (\n <span className=\" ob-input-icon icon is-small is-right\">\n {value ? (\n <MaterialIcon className=\"is-size-5 has-text-success\">\n check\n </MaterialIcon>\n ) : error?.message ? (\n <MaterialIcon className=\"is-size-5 has-text-danger\">\n error\n </MaterialIcon>\n ) : (\n <MaterialIcon className=\"is-size-5\">map</MaterialIcon>\n )}\n </span>\n )}\n </div>\n {hasCopyButton && (\n <div className=\"control\">\n <CopyToClipboardButton\n className=\"button is-input-addon copy-button cypress-copy-to-clipboard-button\"\n text={label}\n />\n </div>\n )}\n </div>\n {isDisplayingValidationMessage && (\n <div role=\"alert\" className=\"has-margin-top-8\">\n <div className=\"has-text-danger ob-error__text cypress-validation-message\">\n {error?.message || validationMessage}\n </div>\n </div>\n )}\n </FormElementLabelContainer>\n\n <Collapse in={!!value}>\n <NotificationGrid\n className={`${pointCadastralParcelClass}__record-display has-margin-top-6`}\n gridClassName={`${pointCadastralParcelClass}__container`}\n >\n <NotificationGridItem\n className={`${pointCadastralParcelClass}__container-address`}\n value={value?.features?.[0]?.properties?.formattedAddress}\n label=\"Address\"\n labelClassName={`${pointCadastralParcelClass}__detail-label`}\n valueClassName={`${pointCadastralParcelClass}__detail-value`}\n />\n <NotificationGridItem\n className={`${pointCadastralParcelClass}__container-lots`}\n value={value?.features?.[0]?.properties?.propertyBundle?.[0]?.parcelIds?.join(\n ', ',\n )}\n label=\"Lots\"\n labelClassName={`${pointCadastralParcelClass}__detail-label`}\n valueClassName={`${pointCadastralParcelClass}__detail-value`}\n />\n <NotificationGridItem\n className={`${pointCadastralParcelClass}__container-local-government-area-name`}\n value={\n value?.features?.[0]?.properties?.localGovernmentArea?.lgaName\n }\n label=\"Local Government Area\"\n labelClassName={`${pointCadastralParcelClass}__detail-label`}\n valueClassName={`${pointCadastralParcelClass}__detail-value`}\n />\n </NotificationGrid>\n </Collapse>\n </div>\n )\n}\n\nexport default React.memo(FormElementPointCadastralParcel)\n"]}
1
+ {"version":3,"file":"FormElementPointCadastralParcel.js","sourceRoot":"","sources":["../../src/form-elements/FormElementPointCadastralParcel.tsx"],"names":[],"mappings":"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","sourcesContent":["import * as React from 'react'\nimport clsx from 'clsx'\nimport CopyToClipboardButton from '../components/renderer/CopyToClipboardButton'\nimport { FormTypes, PointTypes } from '@oneblink/types'\nimport FormElementLabelContainer from '../components/renderer/FormElementLabelContainer'\nimport { FormElementValueChangeHandler, IsDirtyProps } from '../types/form'\nimport { LookupNotificationContext } from '../hooks/useLookupNotification'\nimport useElementAriaDescribedby from '../hooks/useElementAriaDescribedby'\nimport { formService } from '@oneblink/apps'\nimport { Collapse } from '@mui/material'\nimport {\n NotificationGrid,\n NotificationGridItem,\n} from '../components/NotificationGrid'\nimport MaterialIcon from '../components/MaterialIcon'\n\nconst pointCadastralParcelClass = 'ob-point-cadastral-parcel'\n\nfunction FormElementPointCadastralParcel({\n id,\n formId,\n element,\n value,\n onChange,\n validationMessage,\n displayValidationMessage,\n isDirty,\n setIsDirty,\n autocompleteAttributes,\n}: {\n id: string\n formId: number\n element: FormTypes.PointCadastralParcelElement\n value: PointTypes.PointCadastralParcelResponse | undefined\n onChange: FormElementValueChangeHandler<PointTypes.PointCadastralParcelResponse>\n displayValidationMessage: boolean\n validationMessage: string | undefined\n autocompleteAttributes?: string\n} & IsDirtyProps) {\n const ariaDescribedby = useElementAriaDescribedby(id, element)\n const parcelId = value?.parcelBundle?.[0]?.parcelId\n const [label, setLabel] = React.useState(parcelId || '')\n const [{ isLoading, error }, setState] = React.useState<{\n isLoading: boolean\n error: Error | null\n }>({\n isLoading: false,\n error: null,\n })\n\n const loadCadastralParcel = React.useCallback(\n async (abortSignal: AbortSignal) => {\n if (!label || label === parcelId) {\n return\n }\n\n setState({\n isLoading: true,\n error: null,\n })\n\n try {\n console.log('Attempting to load NSW point cadastral parcel', {\n formId,\n parcelId: label,\n })\n const result = await formService.getPointCadastralParcel(\n formId,\n label,\n abortSignal,\n )\n if (!abortSignal.aborted) {\n onChange(element, {\n value: result,\n })\n setState({\n error: null,\n isLoading: false,\n })\n }\n } catch (err) {\n if (!abortSignal.aborted) {\n setState({\n isLoading: false,\n error: err as Error,\n })\n }\n }\n },\n [element, formId, label, onChange, parcelId],\n )\n\n React.useEffect(() => {\n const abortController = new AbortController()\n const timeoutId = setTimeout(() => {\n loadCadastralParcel(abortController.signal)\n }, 750)\n return () => {\n abortController.abort()\n clearTimeout(timeoutId)\n }\n }, [loadCadastralParcel])\n\n // Ensure the label is set if the value is set outside of this component\n React.useEffect(() => {\n if (parcelId && label !== parcelId) {\n setLabel(parcelId)\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [value])\n\n const { isLookingUp } = React.useContext(LookupNotificationContext)\n const isDisplayingValidationMessage =\n (((isDirty || displayValidationMessage) &&\n !!validationMessage &&\n !isLoading) ||\n error) &&\n !isLookingUp\n\n const hasCopyButton = !!value && !!element.readOnly\n return (\n <div className=\"cypress-point-cadastral-parcel-element\">\n <FormElementLabelContainer\n className={pointCadastralParcelClass}\n id={id}\n element={element}\n required={element.required}\n >\n <div\n className={clsx('field has-addons', {\n 'no-addons-mobile': !hasCopyButton,\n })}\n >\n <div\n className={clsx('control is-expanded has-icons-right', {\n 'is-loading': isLoading,\n 'has-icons-right': !isLoading,\n })}\n >\n <input\n type=\"text\"\n id={id}\n name={element.name}\n className=\"input ob-input cypress-point-cadastral-parcel-control\"\n placeholder={element.placeholderValue}\n value={label}\n onChange={(e) => {\n setLabel(e.target.value)\n if (value) {\n onChange(element, {\n value: undefined,\n })\n }\n }}\n required={element.required}\n disabled={element.readOnly}\n onBlur={setIsDirty}\n aria-describedby={ariaDescribedby}\n autoComplete={autocompleteAttributes}\n aria-required={element.required}\n />\n {!isLoading && (\n <span className=\" ob-input-icon icon is-small is-right\">\n {value ? (\n <MaterialIcon className=\"is-size-5 has-text-success\">\n check\n </MaterialIcon>\n ) : error?.message ? (\n <MaterialIcon className=\"is-size-5 has-text-danger\">\n error\n </MaterialIcon>\n ) : (\n <MaterialIcon className=\"is-size-5\">map</MaterialIcon>\n )}\n </span>\n )}\n </div>\n {hasCopyButton && (\n <div className=\"control\">\n <CopyToClipboardButton\n className=\"button is-input-addon copy-button cypress-copy-to-clipboard-button\"\n text={label}\n />\n </div>\n )}\n </div>\n {isDisplayingValidationMessage && (\n <div role=\"alert\" className=\"has-margin-top-8\">\n <div className=\"has-text-danger ob-error__text cypress-validation-message\">\n {error?.message || validationMessage}\n </div>\n </div>\n )}\n </FormElementLabelContainer>\n\n <Collapse in={!!value}>\n <NotificationGrid\n className={`${pointCadastralParcelClass}__record-display has-margin-top-6`}\n gridClassName={`${pointCadastralParcelClass}__container`}\n >\n <NotificationGridItem\n className={`${pointCadastralParcelClass}__container-address`}\n value={value?.features?.[0]?.properties?.formattedAddress}\n label=\"Address\"\n labelClassName={`${pointCadastralParcelClass}__detail-label`}\n valueClassName={`${pointCadastralParcelClass}__detail-value`}\n />\n <NotificationGridItem\n className={`${pointCadastralParcelClass}__container-lots`}\n value={value?.features?.[0]?.properties?.propertyBundle?.[0]?.parcelIds?.join(\n ', ',\n )}\n label=\"Lots\"\n labelClassName={`${pointCadastralParcelClass}__detail-label`}\n valueClassName={`${pointCadastralParcelClass}__detail-value`}\n />\n <NotificationGridItem\n className={`${pointCadastralParcelClass}__container-local-government-area-name`}\n value={\n value?.features?.[0]?.properties?.localGovernmentArea?.lgaName\n }\n label=\"Local Government Area\"\n labelClassName={`${pointCadastralParcelClass}__detail-label`}\n valueClassName={`${pointCadastralParcelClass}__detail-value`}\n />\n </NotificationGrid>\n </Collapse>\n </div>\n )\n}\n\nexport default React.memo(FormElementPointCadastralParcel)\n"]}
@@ -12,16 +12,16 @@ import MaterialIcon from '../components/MaterialIcon';
12
12
  import ElementDOMId from '../utils/elementDOMIds';
13
13
  import { Collapse } from '@mui/material';
14
14
  const RepeatableSetIndexContext = React.createContext(0);
15
- function RepeatableSetEntryProvider({ index, isAnimated, onRemove, children, }) {
15
+ function RepeatableSetEntryProvider({ index, isAnimated, element, idPrefix, onRemove, children, }) {
16
16
  const [isExpanded, setIsExpanded] = React.useState(true);
17
17
  const handleRemove = React.useCallback(() => {
18
18
  if (isAnimated) {
19
19
  setIsExpanded(false);
20
20
  }
21
21
  else {
22
- onRemove(index);
22
+ onRemove(index, element, idPrefix);
23
23
  }
24
- }, [index, isAnimated, onRemove]);
24
+ }, [index, isAnimated, onRemove, element, idPrefix]);
25
25
  const node = (React.createElement(RepeatableSetIndexContext.Provider, { value: index }, children({
26
26
  onRemove: handleRemove,
27
27
  })));
@@ -29,7 +29,7 @@ function RepeatableSetEntryProvider({ index, isAnimated, onRemove, children, })
29
29
  return node;
30
30
  }
31
31
  return (React.createElement(Collapse, { in: isExpanded, appear: true, onExited: () => {
32
- onRemove(index);
32
+ onRemove(index, element, idPrefix);
33
33
  }, classes: {
34
34
  root: 'ob-repeatable-set__collapsible',
35
35
  wrapper: 'ob-repeatable-set__collapsible-wrapper',
@@ -62,10 +62,27 @@ function FormElementRepeatableSet({ formId, element, value, formElementValidatio
62
62
  newExistingExecutedLookups.push({});
63
63
  return newExistingExecutedLookups;
64
64
  },
65
+ sectionState: (currentSectionState) => {
66
+ return ((currentSectionState === null || currentSectionState === void 0 ? void 0 : currentSectionState.map((section) => {
67
+ const idPrefixPattern = new RegExp(`(.+)?${element.name}_entry-(.+)_(.+)`);
68
+ const entryIdPrefixMatches = section.id.match(idPrefixPattern);
69
+ if (entryIdPrefixMatches) {
70
+ const startOfId = entryIdPrefixMatches[1];
71
+ const entryIndex = parseInt(entryIdPrefixMatches[2]);
72
+ const restOfId = entryIdPrefixMatches[3];
73
+ if (entryIndex >= index) {
74
+ const newEntryIndex = entryIndex + 1;
75
+ section.id = `${startOfId ? startOfId : ''}${element.name}_entry-${newEntryIndex}_${restOfId}`;
76
+ }
77
+ }
78
+ return section;
79
+ }, [])) || []);
80
+ },
65
81
  });
66
82
  setIsDirty();
67
- }, [element, onChange, setIsDirty, entries]);
68
- const handleRemoveEntry = React.useCallback((index) => {
83
+ }, [element, onChange, setIsDirty, entries.length]);
84
+ const handleRemoveEntry = React.useCallback((index, element, idPrefix) => {
85
+ const entryIdPrefix = idPrefix || '';
69
86
  onChange(element, {
70
87
  value: (existingEntries) => {
71
88
  const newEntries = [...(existingEntries || [])];
@@ -80,16 +97,44 @@ function FormElementRepeatableSet({ formId, element, value, formElementValidatio
80
97
  newExistingExecutedLookups.splice(index, 1);
81
98
  return newExistingExecutedLookups;
82
99
  },
100
+ sectionState: (currentSectionState) => {
101
+ return ((currentSectionState === null || currentSectionState === void 0 ? void 0 : currentSectionState.reduce((state, section) => {
102
+ const idPrefixPattern = new RegExp(`(.+)?${element.name}_entry-(\\d+)`);
103
+ const entryIdPrefixMatches = entryIdPrefix.match(idPrefixPattern);
104
+ if (!section.id.startsWith(entryIdPrefix) &&
105
+ entryIdPrefixMatches) {
106
+ const parentElementPath = entryIdPrefixMatches[1] || `${element.name}_entry`;
107
+ // only update nested sections where the parent path matches the entry that was removed
108
+ if (section.id.startsWith(parentElementPath)) {
109
+ // Match pattern: {elementName}_entry-{index}_
110
+ // also yields a prefix and suffix for any match found
111
+ const idPrefixWithFullIdPattern = new RegExp(`(.+)?${element.name}_entry-(\\d+)_(.+)`);
112
+ const match = section.id.match(idPrefixWithFullIdPattern);
113
+ if (match) {
114
+ const oldEntryIndex = parseInt(match[2], 10);
115
+ if (oldEntryIndex > index) {
116
+ const prefix = match[1];
117
+ const restOfId = match[3];
118
+ const newEntryIndex = oldEntryIndex - 1;
119
+ section.id = `${prefix ? prefix : ''}${element.name}_entry-${newEntryIndex}_${restOfId}`;
120
+ }
121
+ }
122
+ }
123
+ state.push(section);
124
+ }
125
+ return state;
126
+ }, [])) || []);
127
+ },
83
128
  });
84
129
  setIsDirty();
85
- }, [element, onChange, setIsDirty]);
86
- const handleNestedChange = React.useCallback((index, nestedElement, { value, executedLookups, }, idPrefix) => {
130
+ }, [onChange, setIsDirty]);
131
+ const handleNestedChange = React.useCallback((index, nestedElement, { value, executedLookups, sectionState, }, idPrefix) => {
87
132
  if (nestedElement.type === 'section') {
88
133
  // trigger onChange to update sectionState
89
134
  onChange({
90
135
  ...nestedElement,
91
136
  id: idPrefix ? `${idPrefix}${nestedElement.id}` : nestedElement.id,
92
- }, { executedLookups: undefined });
137
+ }, { executedLookups: undefined, sectionState });
93
138
  }
94
139
  if (!('name' in nestedElement)) {
95
140
  return;
@@ -130,6 +175,7 @@ function FormElementRepeatableSet({ formId, element, value, formElementValidatio
130
175
  });
131
176
  return newExecutedLookups;
132
177
  },
178
+ sectionState,
133
179
  });
134
180
  }, [element, onChange]);
135
181
  const { minSetEntries, maxSetEntries } = useFormElementRepeatableSetEntries(element);
@@ -177,10 +223,11 @@ export default React.memo(FormElementRepeatableSet);
177
223
  const RepeatableSetEntry = React.memo(function RepeatableSetEntry({ formId, id, index, isEven, entry, element, formElementsConditionallyShown, displayValidationMessages, formElementsValidation, onChange, onLookup, onAdd, onRemove, onUpdateFormElements, showAddButton, sectionState, }) {
178
224
  const [isConfirmingRemove, confirmRemove, cancelRemove] = useBooleanState(false);
179
225
  const elementDOMId = React.useMemo(() => new ElementDOMId(id), [id]);
180
- const handleChange = React.useCallback((nestedElement, { value, executedLookups }, idPrefix) => {
226
+ const handleChange = React.useCallback((nestedElement, { value, executedLookups, sectionState }, idPrefix) => {
181
227
  onChange(index, nestedElement, {
182
228
  value,
183
229
  executedLookups,
230
+ sectionState,
184
231
  }, idPrefix);
185
232
  }, [index, onChange]);
186
233
  const handleLookup = React.useCallback((mergeLookupResults) => {
@@ -265,7 +312,8 @@ const RepeatableSetEntry = React.memo(function RepeatableSetEntry({ formId, id,
265
312
  });
266
313
  });
267
314
  }, [element.id, onUpdateFormElements]);
268
- return (React.createElement(RepeatableSetEntryProvider, { index: index, onRemove: onRemove, isAnimated: element.layout === 'MULTIPLE_ADD_BUTTONS' }, ({ onRemove }) => (React.createElement(React.Fragment, null,
315
+ const idPrefix = elementDOMId.repeatableSetEntryDOMIdPrefix(index.toString());
316
+ return (React.createElement(RepeatableSetEntryProvider, { index: index, element: element, idPrefix: idPrefix, onRemove: onRemove, isAnimated: element.layout === 'MULTIPLE_ADD_BUTTONS' }, ({ onRemove }) => (React.createElement(React.Fragment, null,
269
317
  React.createElement(Modal, { isOpen: isConfirmingRemove, className: "cypress-repeatable-set-prompt", titleClassName: "cypress-repeatable-set-remove-entry-header", title: element.removeSetEntryLabel || 'Remove Entry', actions: React.createElement(React.Fragment, null,
270
318
  React.createElement("button", { type: "button", className: "button ob-button is-light cypress-cancel-repeatable-set", onClick: cancelRemove }, "Cancel"),
271
319
  React.createElement("button", { type: "button", className: "button ob-button is-primary cypress-confirm-repeatable-set", onClick: () => {
@@ -274,7 +322,7 @@ const RepeatableSetEntry = React.memo(function RepeatableSetEntry({ formId, id,
274
322
  }, autoFocus: true }, "Yes")) }, "Are you sure you want to remove this entry?"),
275
323
  React.createElement("div", { className: clsx('ob-repeatable-set__container cypress-repeatable-set-container', validationClassName) },
276
324
  (!element.layout || element.layout === 'SINGLE_ADD_BUTTON') && (React.createElement(RemoveButton, { onConfirmRemove: confirmRemove, element: element, className: "ob-repeatable-set__button-remove-top", index: index })),
277
- React.createElement(OneBlinkFormElements, { formId: formId, idPrefix: elementDOMId.repeatableSetEntryDOMIdPrefix(index.toString()), isEven: isEven, formElementsValidation: formElementsValidation, displayValidationMessages: displayValidationMessages, elements: element.elements, onChange: handleChange, onLookup: handleLookup, model: entry, parentElement: element, formElementsConditionallyShown: formElementsConditionallyShown, onUpdateFormElements: handleUpdateNestedFormElements, sectionState: sectionState }),
325
+ React.createElement(OneBlinkFormElements, { formId: formId, idPrefix: idPrefix, isEven: isEven, formElementsValidation: formElementsValidation, displayValidationMessages: displayValidationMessages, elements: element.elements, onChange: handleChange, onLookup: handleLookup, model: entry, parentElement: element, formElementsConditionallyShown: formElementsConditionallyShown, onUpdateFormElements: handleUpdateNestedFormElements, sectionState: sectionState }),
278
326
  element.layout === 'MULTIPLE_ADD_BUTTONS' && (React.createElement(RemoveButton, { onConfirmRemove: confirmRemove, element: element, index: index, className: "ob-repeatable-set__button-remove-bottom" }))),
279
327
  showAddButton && (React.createElement(AddButton, { onAdd: () => onAdd(index + 1), element: element, classes: [
280
328
  'ob-button-repeatable-set-layout__multiple-add-buttons',