@oneblink/apps-react 2.14.2 → 3.0.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/QuillHTML.js +3 -1
- package/dist/components/QuillHTML.js.map +1 -1
- package/dist/components/renderer/FormElementLabelContainer.js +3 -3
- package/dist/components/renderer/FormElementLabelContainer.js.map +1 -1
- package/dist/form-elements/FormElementAutocomplete.js +4 -4
- package/dist/form-elements/FormElementAutocomplete.js.map +1 -1
- package/dist/form-elements/FormElementCalculation.js +2 -3
- package/dist/form-elements/FormElementCalculation.js.map +1 -1
- package/dist/form-elements/FormElementHTML.js +2 -2
- package/dist/form-elements/FormElementHTML.js.map +1 -1
- package/dist/hooks/useDynamicOptionsLoaderState.js +24 -9
- package/dist/hooks/useDynamicOptionsLoaderState.js.map +1 -1
- package/dist/hooks/useLogin.d.ts +3 -0
- package/dist/hooks/useLogin.js +63 -24
- package/dist/hooks/useLogin.js.map +1 -1
- package/dist/hooks/useReplaceableText.d.ts +1 -0
- package/dist/hooks/{useReplaceableHTML.js → useReplaceableText.js} +4 -6
- package/dist/hooks/useReplaceableText.js.map +1 -0
- package/package.json +2 -2
- package/dist/hooks/useReplaceableHTML.d.ts +0 -1
- package/dist/hooks/useReplaceableHTML.js.map +0 -1
@@ -1,10 +1,12 @@
|
|
1
1
|
import * as React from 'react';
|
2
2
|
import clsx from 'clsx';
|
3
|
+
import sanitizeHtml from '../services/sanitize-html';
|
3
4
|
export default function QuillHTML({ html, ...props }) {
|
5
|
+
const __html = React.useMemo(() => sanitizeHtml(html), [html]);
|
4
6
|
return (React.createElement("div", { ...props, className: clsx(props.className, 'ql-editor'),
|
5
7
|
// eslint-disable-next-line react/no-danger
|
6
8
|
dangerouslySetInnerHTML: {
|
7
|
-
__html
|
9
|
+
__html,
|
8
10
|
} }));
|
9
11
|
}
|
10
12
|
//# sourceMappingURL=QuillHTML.js.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"QuillHTML.js","sourceRoot":"","sources":["../../src/components/QuillHTML.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,IAAI,MAAM,MAAM,CAAA;
|
1
|
+
{"version":3,"file":"QuillHTML.js","sourceRoot":"","sources":["../../src/components/QuillHTML.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,IAAI,MAAM,MAAM,CAAA;AACvB,OAAO,YAAY,MAAM,2BAA2B,CAAA;AAEpD,MAAM,CAAC,OAAO,UAAU,SAAS,CAAC,EAChC,IAAI,EACJ,GAAG,KAAK,EAGT;IACC,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAA;IAC9D,OAAO,CACL,gCACM,KAAK,EACT,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,WAAW,CAAC;QAC7C,2CAA2C;QAC3C,uBAAuB,EAAE;YACvB,MAAM;SACP,GACD,CACH,CAAA;AACH,CAAC","sourcesContent":["import * as React from 'react'\nimport clsx from 'clsx'\nimport sanitizeHtml from '../services/sanitize-html'\n\nexport default function QuillHTML({\n html,\n ...props\n}: React.ComponentProps<'div'> & {\n html: string\n}) {\n const __html = React.useMemo(() => sanitizeHtml(html), [html])\n return (\n <div\n {...props}\n className={clsx(props.className, 'ql-editor')}\n // eslint-disable-next-line react/no-danger\n dangerouslySetInnerHTML={{\n __html,\n }}\n />\n )\n}\n"]}
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import * as React from 'react';
|
2
2
|
import { Tooltip } from '@mui/material';
|
3
3
|
import clsx from 'clsx';
|
4
|
-
import
|
4
|
+
import useReplaceableText from '../../hooks/useReplaceableText';
|
5
5
|
import QuillHTML from '../QuillHTML';
|
6
6
|
function FormElementLabelContainer({ className, element, id, required, children, leading, }) {
|
7
7
|
return (React.createElement("div", { className: clsx('ob-form__element', className) },
|
@@ -17,12 +17,12 @@ function FormElementLabelContainer({ className, element, id, required, children,
|
|
17
17
|
children));
|
18
18
|
}
|
19
19
|
export function HintTooltip({ hint }) {
|
20
|
-
const html =
|
20
|
+
const html = useReplaceableText(hint);
|
21
21
|
return (React.createElement(Tooltip, { title: React.createElement(QuillHTML, { html: html, className: "ob-hint-tooltip" }), arrow: true, enterTouchDelay: 0, leaveTouchDelay: 10000 },
|
22
22
|
React.createElement("i", { className: "material-icons has-text-grey-light ob-label__hint" }, "info")));
|
23
23
|
}
|
24
24
|
export function HintBelowLabel({ hint }) {
|
25
|
-
const html =
|
25
|
+
const html = useReplaceableText(hint);
|
26
26
|
return React.createElement(QuillHTML, { html: html, className: "ob-hint-text" });
|
27
27
|
}
|
28
28
|
export default React.memo(FormElementLabelContainer);
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"FormElementLabelContainer.js","sourceRoot":"","sources":["../../../src/components/renderer/FormElementLabelContainer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AACvC,OAAO,IAAI,MAAM,MAAM,CAAA;AAEvB,OAAO,kBAAkB,MAAM,gCAAgC,CAAA;AAC/D,OAAO,SAAS,MAAM,cAAc,CAAA;AAEpC,SAAS,yBAAyB,CAAC,EACjC,SAAS,EACT,OAAO,EACP,EAAE,EACF,QAAQ,EACR,QAAQ,EACR,OAAO,GAQR;IACC,OAAO,CACL,6BAAK,SAAS,EAAE,IAAI,CAAC,kBAAkB,EAAE,SAAS,CAAC;QACjD,6BAAK,SAAS,EAAC,2BAA2B;YACvC,OAAO;YACR,+BACE,SAAS,EAAE,IAAI,CAAC,UAAU,EAAE;oBAC1B,gCAAgC,EAAE,QAAQ;iBAC3C,CAAC,EACF,OAAO,EAAE,EAAE,IAEV,OAAO,CAAC,KAAK,CACR;YACP,OAAO,CAAC,IAAI;gBACX,CAAC,OAAO,CAAC,YAAY,KAAK,SAAS,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,IAAI,CAC/D,oBAAC,WAAW,IAAC,IAAI,EAAE,OAAO,CAAC,IAAI,GAAI,CACpC,CACC;QACL,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,YAAY,KAAK,aAAa,IAAI,CACzD,6BAAK,SAAS,EAAC,yBAAyB;YACtC,oBAAC,cAAc,IAAC,IAAI,EAAE,OAAO,CAAC,IAAI,GAAI,CAClC,CACP;QACA,QAAQ,CACL,CACP,CAAA;AACH,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,EAAE,IAAI,EAAoB;IACpD,MAAM,IAAI,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAA;IAErC,OAAO,CACL,oBAAC,OAAO,IACN,KAAK,EAAE,oBAAC,SAAS,IAAC,IAAI,EAAE,IAAI,EAAE,SAAS,EAAC,iBAAiB,GAAG,EAC5D,KAAK,QACL,eAAe,EAAE,CAAC,EAClB,eAAe,EAAE,KAAK;QAEtB,2BAAG,SAAS,EAAC,mDAAmD,WAAS,CACjE,CACX,CAAA;AACH,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,EAAE,IAAI,EAAoB;IACvD,MAAM,IAAI,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAA;IAErC,OAAO,oBAAC,SAAS,IAAC,IAAI,EAAE,IAAI,EAAE,SAAS,EAAC,cAAc,GAAG,CAAA;AAC3D,CAAC;AAED,eAAe,KAAK,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAA","sourcesContent":["import * as React from 'react'\nimport { Tooltip } from '@mui/material'\nimport clsx from 'clsx'\nimport { FormTypes } from '@oneblink/types'\nimport
|
1
|
+
{"version":3,"file":"FormElementLabelContainer.js","sourceRoot":"","sources":["../../../src/components/renderer/FormElementLabelContainer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AACvC,OAAO,IAAI,MAAM,MAAM,CAAA;AAEvB,OAAO,kBAAkB,MAAM,gCAAgC,CAAA;AAC/D,OAAO,SAAS,MAAM,cAAc,CAAA;AAEpC,SAAS,yBAAyB,CAAC,EACjC,SAAS,EACT,OAAO,EACP,EAAE,EACF,QAAQ,EACR,QAAQ,EACR,OAAO,GAQR;IACC,OAAO,CACL,6BAAK,SAAS,EAAE,IAAI,CAAC,kBAAkB,EAAE,SAAS,CAAC;QACjD,6BAAK,SAAS,EAAC,2BAA2B;YACvC,OAAO;YACR,+BACE,SAAS,EAAE,IAAI,CAAC,UAAU,EAAE;oBAC1B,gCAAgC,EAAE,QAAQ;iBAC3C,CAAC,EACF,OAAO,EAAE,EAAE,IAEV,OAAO,CAAC,KAAK,CACR;YACP,OAAO,CAAC,IAAI;gBACX,CAAC,OAAO,CAAC,YAAY,KAAK,SAAS,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,IAAI,CAC/D,oBAAC,WAAW,IAAC,IAAI,EAAE,OAAO,CAAC,IAAI,GAAI,CACpC,CACC;QACL,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,YAAY,KAAK,aAAa,IAAI,CACzD,6BAAK,SAAS,EAAC,yBAAyB;YACtC,oBAAC,cAAc,IAAC,IAAI,EAAE,OAAO,CAAC,IAAI,GAAI,CAClC,CACP;QACA,QAAQ,CACL,CACP,CAAA;AACH,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,EAAE,IAAI,EAAoB;IACpD,MAAM,IAAI,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAA;IAErC,OAAO,CACL,oBAAC,OAAO,IACN,KAAK,EAAE,oBAAC,SAAS,IAAC,IAAI,EAAE,IAAI,EAAE,SAAS,EAAC,iBAAiB,GAAG,EAC5D,KAAK,QACL,eAAe,EAAE,CAAC,EAClB,eAAe,EAAE,KAAK;QAEtB,2BAAG,SAAS,EAAC,mDAAmD,WAAS,CACjE,CACX,CAAA;AACH,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,EAAE,IAAI,EAAoB;IACvD,MAAM,IAAI,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAA;IAErC,OAAO,oBAAC,SAAS,IAAC,IAAI,EAAE,IAAI,EAAE,SAAS,EAAC,cAAc,GAAG,CAAA;AAC3D,CAAC;AAED,eAAe,KAAK,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAA","sourcesContent":["import * as React from 'react'\nimport { Tooltip } from '@mui/material'\nimport clsx from 'clsx'\nimport { FormTypes } from '@oneblink/types'\nimport useReplaceableText from '../../hooks/useReplaceableText'\nimport QuillHTML from '../QuillHTML'\n\nfunction FormElementLabelContainer({\n className,\n element,\n id,\n required,\n children,\n leading,\n}: {\n className: string\n element: FormTypes.FormElementBase\n id: string\n required: boolean\n children: React.ReactNode\n leading?: React.ReactNode\n}) {\n return (\n <div className={clsx('ob-form__element', className)}>\n <div className=\"label ob-label__container\">\n {leading}\n <label\n className={clsx('ob-label', {\n 'ob-label__required is-required': required,\n })}\n htmlFor={id}\n >\n {element.label}\n </label>\n {element.hint &&\n (element.hintPosition === 'TOOLTIP' || !element.hintPosition) && (\n <HintTooltip hint={element.hint} />\n )}\n </div>\n {element.hint && element.hintPosition === 'BELOW_LABEL' && (\n <div className=\"ob-hint-text__container\">\n <HintBelowLabel hint={element.hint} />\n </div>\n )}\n {children}\n </div>\n )\n}\n\nexport function HintTooltip({ hint }: { hint: string }) {\n const html = useReplaceableText(hint)\n\n return (\n <Tooltip\n title={<QuillHTML html={html} className=\"ob-hint-tooltip\" />}\n arrow\n enterTouchDelay={0}\n leaveTouchDelay={10000}\n >\n <i className=\"material-icons has-text-grey-light ob-label__hint\">info</i>\n </Tooltip>\n )\n}\n\nexport function HintBelowLabel({ hint }: { hint: string }) {\n const html = useReplaceableText(hint)\n\n return <QuillHTML html={html} className=\"ob-hint-text\" />\n}\n\nexport default React.memo(FormElementLabelContainer)\n"]}
|
@@ -44,12 +44,12 @@ const AutocompleteFilter = React.memo(function AutocompleteFilter({ id, element,
|
|
44
44
|
React.createElement(FormElementOptions, { options: element.options, conditionallyShownOptionsElement: conditionallyShownOptionsElement },
|
45
45
|
React.createElement(AutocompleteDropdown, { id: id, label: label, disabled: element.readOnly, placeholder: element.placeholderValue, required: element.required, value: value, validationMessage: validationMessage, displayValidationMessage: displayValidationMessage, onChangeValue: onChange, onChangeLabel: setLabel, onSearch: handleSearch, searchDebounceMs: 0, searchMinCharacters: 0, isDirty: isDirty, setIsDirty: setIsDirty })))));
|
46
46
|
});
|
47
|
-
const AutocompleteFetch = React.memo(function AutocompleteFetch({ id, element, value, onChange, validationMessage, displayValidationMessage, searchUrl, isDirty, setIsDirty, }) {
|
47
|
+
const AutocompleteFetch = React.memo(function AutocompleteFetch({ id, element, value, onChange, validationMessage, displayValidationMessage, searchUrl, searchQuerystringParameter, isDirty, setIsDirty, }) {
|
48
48
|
const [label, setLabel] = React.useState('');
|
49
49
|
const handleSearch = React.useCallback(async (search, abortSignal) => {
|
50
50
|
const headers = await generateHeaders();
|
51
51
|
const url = new URL(searchUrl);
|
52
|
-
url.searchParams.append(
|
52
|
+
url.searchParams.append(searchQuerystringParameter, search);
|
53
53
|
const response = await fetch(url.href, {
|
54
54
|
headers,
|
55
55
|
signal: abortSignal,
|
@@ -60,7 +60,7 @@ const AutocompleteFetch = React.memo(function AutocompleteFetch({ id, element, v
|
|
60
60
|
}
|
61
61
|
const data = await response.json();
|
62
62
|
return formElementsService.parseFormElementOptionsSet(data);
|
63
|
-
}, [searchUrl]);
|
63
|
+
}, [searchQuerystringParameter, searchUrl]);
|
64
64
|
// Ensure the label is set if the value is set outside of this component
|
65
65
|
React.useEffect(() => {
|
66
66
|
if (!label && typeof value === 'string') {
|
@@ -77,7 +77,7 @@ function FormElementAutocomplete({ conditionallyShownOptionsElement, onChange, .
|
|
77
77
|
onChange(props.element, newValue);
|
78
78
|
}, [onChange, props.element]);
|
79
79
|
if (props.element.optionsType === 'SEARCH' && props.element.searchUrl) {
|
80
|
-
return (React.createElement(AutocompleteFetch, { ...props, onChange: handleChange, searchUrl: props.element.searchUrl }));
|
80
|
+
return (React.createElement(AutocompleteFetch, { ...props, onChange: handleChange, searchUrl: props.element.searchUrl, searchQuerystringParameter: props.element.searchQuerystringParameter || 'value' }));
|
81
81
|
}
|
82
82
|
return (React.createElement(AutocompleteFilter, { ...props, onChange: handleChange, conditionallyShownOptionsElement: conditionallyShownOptionsElement }));
|
83
83
|
}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"FormElementAutocomplete.js","sourceRoot":"","sources":["../../src/form-elements/FormElementAutocomplete.tsx"],"names":[],"mappings":"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","sourcesContent":["import * as React from 'react'\nimport { formElementsService } from '@oneblink/sdk-core'\nimport { generateHeaders } from '@oneblink/apps/dist/services/fetch'\n\nimport FormElementOptions from '../components/renderer/FormElementOptions'\nimport useFormElementOptions from '../hooks/useFormElementOptions'\nimport AutocompleteDropdown from '../components/renderer/AutocompleteDropdown'\nimport FormElementLabelContainer from '../components/renderer/FormElementLabelContainer'\nimport { FormTypes } from '@oneblink/types'\nimport {\n FormElementValueChangeHandler,\n FormElementConditionallyShownElement,\n IsDirtyProps,\n} from '../types/form'\n\ntype _BaseProps = {\n id: string\n element: FormTypes.AutoCompleteElement\n value: unknown | undefined\n displayValidationMessage: boolean\n validationMessage: string | undefined\n} & IsDirtyProps\n\ntype _AutocompleteChangeHandlerProps = _BaseProps & {\n onChange: (newValue: unknown | undefined) => void\n}\n\ntype _AutocompleteConditionallyShowOptionProps = {\n conditionallyShownOptionsElement:\n | FormElementConditionallyShownElement\n | undefined\n}\n\ntype AutocompleteFilterProps = _AutocompleteChangeHandlerProps &\n _AutocompleteConditionallyShowOptionProps\n\ntype AutocompleteFetchProps = _AutocompleteChangeHandlerProps & {\n searchUrl: string\n}\n\ntype Props = _BaseProps &\n _AutocompleteConditionallyShowOptionProps & {\n onChange: FormElementValueChangeHandler<string>\n }\n\nconst AutocompleteFilter = React.memo(function AutocompleteFilter({\n id,\n element,\n value,\n onChange,\n conditionallyShownOptionsElement,\n validationMessage,\n displayValidationMessage,\n isDirty,\n setIsDirty,\n}: AutocompleteFilterProps) {\n const [label, setLabel] = React.useState('')\n\n const onFilter = React.useCallback(\n (option: FormTypes.ChoiceElementOption) => {\n // If the user has typed nothing in, display all options\n if (!label) {\n return true\n }\n\n const lowerCase = label.toLowerCase()\n\n return option.label.toLowerCase().includes(lowerCase)\n },\n [label],\n )\n\n const handleChange = React.useCallback(\n //useFormElementOptions expects the first arg to be the element\n (element: FormTypes.FormElement, newValue: unknown) => onChange(newValue),\n [onChange],\n )\n\n const filteredOptions = useFormElementOptions({\n element,\n value,\n onChange: handleChange,\n conditionallyShownOptionsElement,\n onFilter,\n })\n\n const handleSearch = React.useCallback(async () => {\n return filteredOptions\n }, [filteredOptions])\n\n // Ensure the label matches the value selected\n React.useEffect(() => {\n if (!Array.isArray(element.options)) {\n return\n }\n\n const option = element.options.find((option) => option.value === value)\n if (option && label !== option.label) {\n setLabel(option.label)\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [element.options, value])\n\n return (\n <div className=\"cypress-autocomplete-filter-element\">\n <FormElementLabelContainer\n className=\"ob-autocomplete\"\n element={element}\n id={id}\n required={element.required}\n >\n <FormElementOptions\n options={element.options}\n conditionallyShownOptionsElement={conditionallyShownOptionsElement}\n >\n <AutocompleteDropdown\n id={id}\n label={label}\n disabled={element.readOnly}\n placeholder={element.placeholderValue}\n required={element.required}\n value={value}\n validationMessage={validationMessage}\n displayValidationMessage={displayValidationMessage}\n onChangeValue={onChange}\n onChangeLabel={setLabel}\n onSearch={handleSearch}\n searchDebounceMs={0}\n searchMinCharacters={0}\n isDirty={isDirty}\n setIsDirty={setIsDirty}\n />\n </FormElementOptions>\n </FormElementLabelContainer>\n </div>\n )\n})\n\nconst AutocompleteFetch = React.memo(function AutocompleteFetch({\n id,\n element,\n value,\n onChange,\n validationMessage,\n displayValidationMessage,\n searchUrl,\n isDirty,\n setIsDirty,\n}: AutocompleteFetchProps) {\n const [label, setLabel] = React.useState('')\n\n const handleSearch = React.useCallback(\n async (search: string, abortSignal: AbortSignal) => {\n const headers = await generateHeaders()\n const url = new URL(searchUrl)\n url.searchParams.append('value', search)\n const response = await fetch(url.href, {\n headers,\n signal: abortSignal,\n })\n\n if (!response.ok) {\n const text = await response.text()\n throw new Error(text)\n }\n\n const data = await response.json()\n return formElementsService.parseFormElementOptionsSet(data)\n },\n [searchUrl],\n )\n\n // Ensure the label is set if the value is set outside of this component\n React.useEffect(() => {\n if (!label && typeof value === 'string') {\n setLabel(value)\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [value])\n\n return (\n <div className=\"cypress-autocomplete-search-element\">\n <FormElementLabelContainer\n className=\"ob-autocomplete\"\n element={element}\n id={id}\n required={element.required}\n >\n <AutocompleteDropdown\n id={id}\n label={label}\n disabled={element.readOnly}\n placeholder={element.placeholderValue}\n required={element.required}\n value={value}\n validationMessage={validationMessage}\n displayValidationMessage={displayValidationMessage}\n onChangeValue={onChange}\n onChangeLabel={setLabel}\n searchDebounceMs={750}\n searchMinCharacters={1}\n onSearch={handleSearch}\n isDirty={isDirty}\n setIsDirty={setIsDirty}\n />\n </FormElementLabelContainer>\n </div>\n )\n})\n\nfunction FormElementAutocomplete({\n conditionallyShownOptionsElement,\n onChange,\n ...props\n}: Props) {\n const handleChange = React.useCallback(\n (newValue: unknown) => {\n onChange(props.element, newValue as string | undefined)\n },\n [onChange, props.element],\n )\n if (props.element.optionsType === 'SEARCH' && props.element.searchUrl) {\n return (\n <AutocompleteFetch\n {...props}\n onChange={handleChange}\n searchUrl={props.element.searchUrl}\n />\n )\n }\n\n return (\n <AutocompleteFilter\n {...props}\n onChange={handleChange}\n conditionallyShownOptionsElement={conditionallyShownOptionsElement}\n />\n )\n}\n\nexport default React.memo(FormElementAutocomplete)\n"]}
|
1
|
+
{"version":3,"file":"FormElementAutocomplete.js","sourceRoot":"","sources":["../../src/form-elements/FormElementAutocomplete.tsx"],"names":[],"mappings":"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","sourcesContent":["import * as React from 'react'\nimport { formElementsService } from '@oneblink/sdk-core'\nimport { generateHeaders } from '@oneblink/apps/dist/services/fetch'\n\nimport FormElementOptions from '../components/renderer/FormElementOptions'\nimport useFormElementOptions from '../hooks/useFormElementOptions'\nimport AutocompleteDropdown from '../components/renderer/AutocompleteDropdown'\nimport FormElementLabelContainer from '../components/renderer/FormElementLabelContainer'\nimport { FormTypes } from '@oneblink/types'\nimport {\n FormElementValueChangeHandler,\n FormElementConditionallyShownElement,\n IsDirtyProps,\n} from '../types/form'\n\ntype _BaseProps = {\n id: string\n element: FormTypes.AutoCompleteElement\n value: unknown | undefined\n displayValidationMessage: boolean\n validationMessage: string | undefined\n} & IsDirtyProps\n\ntype _AutocompleteChangeHandlerProps = _BaseProps & {\n onChange: (newValue: unknown | undefined) => void\n}\n\ntype _AutocompleteConditionallyShowOptionProps = {\n conditionallyShownOptionsElement:\n | FormElementConditionallyShownElement\n | undefined\n}\n\ntype AutocompleteFilterProps = _AutocompleteChangeHandlerProps &\n _AutocompleteConditionallyShowOptionProps\n\ntype AutocompleteFetchProps = _AutocompleteChangeHandlerProps & {\n searchUrl: string\n searchQuerystringParameter: string\n}\n\ntype Props = _BaseProps &\n _AutocompleteConditionallyShowOptionProps & {\n onChange: FormElementValueChangeHandler<string>\n }\n\nconst AutocompleteFilter = React.memo(function AutocompleteFilter({\n id,\n element,\n value,\n onChange,\n conditionallyShownOptionsElement,\n validationMessage,\n displayValidationMessage,\n isDirty,\n setIsDirty,\n}: AutocompleteFilterProps) {\n const [label, setLabel] = React.useState('')\n\n const onFilter = React.useCallback(\n (option: FormTypes.ChoiceElementOption) => {\n // If the user has typed nothing in, display all options\n if (!label) {\n return true\n }\n\n const lowerCase = label.toLowerCase()\n\n return option.label.toLowerCase().includes(lowerCase)\n },\n [label],\n )\n\n const handleChange = React.useCallback(\n //useFormElementOptions expects the first arg to be the element\n (element: FormTypes.FormElement, newValue: unknown) => onChange(newValue),\n [onChange],\n )\n\n const filteredOptions = useFormElementOptions({\n element,\n value,\n onChange: handleChange,\n conditionallyShownOptionsElement,\n onFilter,\n })\n\n const handleSearch = React.useCallback(async () => {\n return filteredOptions\n }, [filteredOptions])\n\n // Ensure the label matches the value selected\n React.useEffect(() => {\n if (!Array.isArray(element.options)) {\n return\n }\n\n const option = element.options.find((option) => option.value === value)\n if (option && label !== option.label) {\n setLabel(option.label)\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [element.options, value])\n\n return (\n <div className=\"cypress-autocomplete-filter-element\">\n <FormElementLabelContainer\n className=\"ob-autocomplete\"\n element={element}\n id={id}\n required={element.required}\n >\n <FormElementOptions\n options={element.options}\n conditionallyShownOptionsElement={conditionallyShownOptionsElement}\n >\n <AutocompleteDropdown\n id={id}\n label={label}\n disabled={element.readOnly}\n placeholder={element.placeholderValue}\n required={element.required}\n value={value}\n validationMessage={validationMessage}\n displayValidationMessage={displayValidationMessage}\n onChangeValue={onChange}\n onChangeLabel={setLabel}\n onSearch={handleSearch}\n searchDebounceMs={0}\n searchMinCharacters={0}\n isDirty={isDirty}\n setIsDirty={setIsDirty}\n />\n </FormElementOptions>\n </FormElementLabelContainer>\n </div>\n )\n})\n\nconst AutocompleteFetch = React.memo(function AutocompleteFetch({\n id,\n element,\n value,\n onChange,\n validationMessage,\n displayValidationMessage,\n searchUrl,\n searchQuerystringParameter,\n isDirty,\n setIsDirty,\n}: AutocompleteFetchProps) {\n const [label, setLabel] = React.useState('')\n\n const handleSearch = React.useCallback(\n async (search: string, abortSignal: AbortSignal) => {\n const headers = await generateHeaders()\n const url = new URL(searchUrl)\n url.searchParams.append(searchQuerystringParameter, search)\n const response = await fetch(url.href, {\n headers,\n signal: abortSignal,\n })\n\n if (!response.ok) {\n const text = await response.text()\n throw new Error(text)\n }\n\n const data = await response.json()\n return formElementsService.parseFormElementOptionsSet(data)\n },\n [searchQuerystringParameter, searchUrl],\n )\n\n // Ensure the label is set if the value is set outside of this component\n React.useEffect(() => {\n if (!label && typeof value === 'string') {\n setLabel(value)\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [value])\n\n return (\n <div className=\"cypress-autocomplete-search-element\">\n <FormElementLabelContainer\n className=\"ob-autocomplete\"\n element={element}\n id={id}\n required={element.required}\n >\n <AutocompleteDropdown\n id={id}\n label={label}\n disabled={element.readOnly}\n placeholder={element.placeholderValue}\n required={element.required}\n value={value}\n validationMessage={validationMessage}\n displayValidationMessage={displayValidationMessage}\n onChangeValue={onChange}\n onChangeLabel={setLabel}\n searchDebounceMs={750}\n searchMinCharacters={1}\n onSearch={handleSearch}\n isDirty={isDirty}\n setIsDirty={setIsDirty}\n />\n </FormElementLabelContainer>\n </div>\n )\n})\n\nfunction FormElementAutocomplete({\n conditionallyShownOptionsElement,\n onChange,\n ...props\n}: Props) {\n const handleChange = React.useCallback(\n (newValue: unknown) => {\n onChange(props.element, newValue as string | undefined)\n },\n [onChange, props.element],\n )\n if (props.element.optionsType === 'SEARCH' && props.element.searchUrl) {\n return (\n <AutocompleteFetch\n {...props}\n onChange={handleChange}\n searchUrl={props.element.searchUrl}\n searchQuerystringParameter={\n props.element.searchQuerystringParameter || 'value'\n }\n />\n )\n }\n\n return (\n <AutocompleteFilter\n {...props}\n onChange={handleChange}\n conditionallyShownOptionsElement={conditionallyShownOptionsElement}\n />\n )\n}\n\nexport default React.memo(FormElementAutocomplete)\n"]}
|
@@ -1,7 +1,6 @@
|
|
1
1
|
import * as React from 'react';
|
2
2
|
import ExpressionParser from 'morph-expressions';
|
3
3
|
import escapeString from 'escape-string-regexp';
|
4
|
-
import sanitizeHtmlStandard from '../services/sanitize-html';
|
5
4
|
import useFormSubmissionModel from '../hooks/useFormSubmissionModelContext';
|
6
5
|
import { Sentry } from '@oneblink/apps';
|
7
6
|
import { localisationService } from '@oneblink/apps';
|
@@ -25,9 +24,9 @@ function FormElementCalculation({ element, onChange, value }) {
|
|
25
24
|
htmlTemplate = element.preCalculationDisplay;
|
26
25
|
}
|
27
26
|
const numberValue = typeof value === 'number' ? value : 0;
|
28
|
-
return
|
27
|
+
return (htmlTemplate || '').replace(/{result}/gi, element.displayAsCurrency
|
29
28
|
? localisationService.formatCurrency(numberValue)
|
30
|
-
: localisationService.formatNumber(numberValue))
|
29
|
+
: localisationService.formatNumber(numberValue));
|
31
30
|
}, [element, value]);
|
32
31
|
const registerProperty = React.useCallback((exprParser, { replacement, nestedElementNames, }) => {
|
33
32
|
exprParser.registerProperty(replacement, (submission) => {
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"FormElementCalculation.js","sourceRoot":"","sources":["../../src/form-elements/FormElementCalculation.tsx"],"names":[],"mappings":"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","sourcesContent":["import * as React from 'react'\nimport ExpressionParser from 'morph-expressions'\nimport escapeString from 'escape-string-regexp'\nimport sanitizeHtmlStandard from '../services/sanitize-html'\nimport useFormSubmissionModel from '../hooks/useFormSubmissionModelContext'\nimport { FormTypes } from '@oneblink/types'\nimport { Sentry } from '@oneblink/apps'\nimport { localisationService } from '@oneblink/apps'\nimport {\n FormElementValueChangeHandler,\n FormSubmissionModel,\n} from '../types/form'\nimport { formElementsService } from '@oneblink/sdk-core'\nimport QuillHTML from '../components/QuillHTML'\ntype Props = {\n element: FormTypes.CalculationElement\n onChange: FormElementValueChangeHandler<number>\n value: unknown | undefined\n}\n\nconst isUnenteredValue = (value: unknown | undefined) => {\n return !value && value !== 0\n}\n\nconst isObjectWithValue = (obj: unknown): obj is { value: unknown } => {\n return typeof obj === 'object' && obj !== null && 'value' in obj\n}\n\nfunction FormElementCalculation({ element, onChange, value }: Props) {\n const { formSubmissionModel } = useFormSubmissionModel()\n\n const htmlValue = React.useMemo(() => {\n let htmlTemplate\n\n if (!isNaN(value as number)) {\n htmlTemplate = element.defaultValue\n } else {\n console.log(\n '[Calculation] Was not a number... setting pre-calculation display',\n )\n htmlTemplate = element.preCalculationDisplay\n }\n\n const numberValue = typeof value === 'number' ? value : 0\n return sanitizeHtmlStandard(\n (htmlTemplate || '').replace(\n /{result}/gi,\n element.displayAsCurrency\n ? localisationService.formatCurrency(numberValue)\n : localisationService.formatNumber(numberValue),\n ),\n )\n }, [element, value])\n\n const registerProperty = React.useCallback(\n (\n exprParser: typeof ExpressionParser,\n {\n replacement,\n nestedElementNames,\n }: {\n replacement: string\n nestedElementNames: string[]\n },\n ) => {\n exprParser.registerProperty(\n replacement,\n (submission: FormSubmissionModel) => {\n const defaultAccumulator = submission[nestedElementNames[0]]\n\n return nestedElementNames.reduce(\n (\n elementValue: unknown | undefined,\n elementName: string,\n index: number,\n ) => {\n // Numbers can just be returned as is\n if (typeof elementValue === 'number') {\n return elementValue\n }\n\n // attempt to get a number from the element value as a string.\n // NaN is accounted for is the calculation\n // so we can return that from here\n if (typeof elementValue === 'string') {\n return parseFloat(elementValue)\n }\n\n if (Array.isArray(elementValue)) {\n // If there are no entries, we can return null\n // to prevent the calculation from running.\n if (!elementValue.length) {\n return NaN\n }\n\n // An array could be an element that allows multiple\n // values e.g. checkboxes. If thats that case, we just\n // add them all together and move on\n const elementValues = elementValue.map((entry) =>\n parseFloat(entry),\n )\n if (elementValues.every((entry) => !Number.isNaN(entry))) {\n return elementValues.reduce(\n (number, entry) => number + entry,\n 0,\n )\n }\n\n // Other wise attempt to process it as a repeatable set\n // If we found another repeatable set to process,\n // pass it to the next element name to\n // iterate over the entries\n\n // If we are processing the entries in a repeatable set,\n // we can sum the numbers elements in the entries\n const nextElementName = nestedElementNames[index + 1]\n\n let isNestedRepeatableSet = false\n const nestedElementValues = elementValue.reduce(\n (nestedElementValues, entry) => {\n if (entry) {\n const nextElementValue = entry[nextElementName]\n if (Array.isArray(nextElementValue)) {\n if (nextElementValue.length) {\n nestedElementValues.push(...nextElementValue)\n isNestedRepeatableSet = true\n }\n } else {\n nestedElementValues.push(nextElementValue)\n }\n }\n return nestedElementValues\n },\n [],\n )\n\n // If the nested element values are all arrays, we can pass them on to the next iteration\n if (isNestedRepeatableSet) {\n return nestedElementValues\n }\n\n return nestedElementValues.reduce(\n (total: number, nestedElementValue: unknown | undefined) => {\n if (Number.isNaN(total)) {\n return NaN\n }\n const value = parseFloat(nestedElementValue as string)\n if (Number.isNaN(value)) {\n return NaN\n }\n return total + value\n },\n 0,\n )\n }\n\n // \"compliance\" form element has an object value with a \"value\" property.\n if (\n isObjectWithValue(elementValue) &&\n typeof elementValue.value === 'string'\n ) {\n return parseFloat(elementValue.value)\n }\n\n // We did not find a number value from the known elements,\n // we will assume we are at the end of the line.\n return NaN\n },\n defaultAccumulator,\n )\n },\n )\n },\n [],\n )\n\n const { calculation, hasError } = React.useMemo(() => {\n const exprParser = new ExpressionParser()\n exprParser.registerFunction('ROUND', (value: number, precision: number) => {\n if (!Number.isNaN(value) && Number.isFinite(value)) {\n return parseFloat(value.toFixed(precision))\n }\n return null\n })\n exprParser.registerFunction(\n 'ISNULL',\n (value: unknown | undefined, defaultValue: number) => {\n if (isUnenteredValue(value)) {\n return defaultValue || 0\n }\n return value\n },\n )\n\n try {\n if (!element.calculation) throw new Error('Element has no calculation.')\n const elementNames: string[] = []\n formElementsService.matchElementsTagRegex(\n element.calculation,\n ({ elementName }) => {\n elementNames.push(elementName)\n },\n )\n\n const code = elementNames.reduce((code, elementName, index) => {\n const regex = new RegExp(escapeString(`{ELEMENT:${elementName}}`), 'g')\n const replacement = `a${index}`\n registerProperty(exprParser, {\n replacement,\n nestedElementNames: elementName.split('|'),\n })\n return code.replace(regex, replacement)\n }, element.calculation || '')\n\n return {\n calculation: exprParser.parse(code.trim()),\n hasError: false,\n }\n } catch (e) {\n console.warn(\n 'Error while setting up parsing for calculation element',\n element,\n e,\n )\n Sentry.captureException(e)\n return {\n calculation: null,\n hasError: true,\n }\n }\n }, [element, registerProperty])\n\n // MODEL LISTENER\n React.useEffect(() => {\n if (!calculation) return\n const newValue = calculation.eval(formSubmissionModel)\n if (value === newValue || (value === undefined && isNaN(newValue))) {\n return\n }\n if (!isNaN(newValue)) {\n onChange(element, newValue)\n } else {\n onChange(element, undefined)\n }\n }, [calculation, element, formSubmissionModel, onChange, value])\n\n return (\n <div className=\"cypress-calculation-element\">\n <div className=\"ob-form__element ob-calculation\">\n <QuillHTML\n html={htmlValue}\n className=\"cypress-calculation-result ob-calculation__content\"\n />\n {hasError && (\n <div\n className=\"notification cypress-calculation-is-invalid\"\n role=\"alert\"\n >\n <div className=\"columns is-vcentered\">\n <div className=\"column is-narrow\">\n <i className=\"material-icons has-text-warning\">error</i>\n </div>\n <div className=\"column\">\n <p>There is an error in the calculation for this element.</p>\n </div>\n </div>\n </div>\n )}\n </div>\n </div>\n )\n}\n\nexport default React.memo(FormElementCalculation)\n"]}
|
1
|
+
{"version":3,"file":"FormElementCalculation.js","sourceRoot":"","sources":["../../src/form-elements/FormElementCalculation.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,gBAAgB,MAAM,mBAAmB,CAAA;AAChD,OAAO,YAAY,MAAM,sBAAsB,CAAA;AAC/C,OAAO,sBAAsB,MAAM,wCAAwC,CAAA;AAE3E,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAA;AACvC,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAA;AAKpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAA;AACxD,OAAO,SAAS,MAAM,yBAAyB,CAAA;AAO/C,MAAM,gBAAgB,GAAG,CAAC,KAA0B,EAAE,EAAE;IACtD,OAAO,CAAC,KAAK,IAAI,KAAK,KAAK,CAAC,CAAA;AAC9B,CAAC,CAAA;AAED,MAAM,iBAAiB,GAAG,CAAC,GAAY,EAA6B,EAAE;IACpE,OAAO,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,IAAI,OAAO,IAAI,GAAG,CAAA;AAClE,CAAC,CAAA;AAED,SAAS,sBAAsB,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAS;IACjE,MAAM,EAAE,mBAAmB,EAAE,GAAG,sBAAsB,EAAE,CAAA;IAExD,MAAM,SAAS,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE;QACnC,IAAI,YAAY,CAAA;QAEhB,IAAI,CAAC,KAAK,CAAC,KAAe,CAAC,EAAE;YAC3B,YAAY,GAAG,OAAO,CAAC,YAAY,CAAA;SACpC;aAAM;YACL,OAAO,CAAC,GAAG,CACT,mEAAmE,CACpE,CAAA;YACD,YAAY,GAAG,OAAO,CAAC,qBAAqB,CAAA;SAC7C;QAED,MAAM,WAAW,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAA;QACzD,OAAO,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC,OAAO,CACjC,YAAY,EACZ,OAAO,CAAC,iBAAiB;YACvB,CAAC,CAAC,mBAAmB,CAAC,cAAc,CAAC,WAAW,CAAC;YACjD,CAAC,CAAC,mBAAmB,CAAC,YAAY,CAAC,WAAW,CAAC,CAClD,CAAA;IACH,CAAC,EAAE,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,CAAA;IAEpB,MAAM,gBAAgB,GAAG,KAAK,CAAC,WAAW,CACxC,CACE,UAAmC,EACnC,EACE,WAAW,EACX,kBAAkB,GAInB,EACD,EAAE;QACF,UAAU,CAAC,gBAAgB,CACzB,WAAW,EACX,CAAC,UAA+B,EAAE,EAAE;YAClC,MAAM,kBAAkB,GAAG,UAAU,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,CAAA;YAE5D,OAAO,kBAAkB,CAAC,MAAM,CAC9B,CACE,YAAiC,EACjC,WAAmB,EACnB,KAAa,EACb,EAAE;gBACF,qCAAqC;gBACrC,IAAI,OAAO,YAAY,KAAK,QAAQ,EAAE;oBACpC,OAAO,YAAY,CAAA;iBACpB;gBAED,8DAA8D;gBAC9D,0CAA0C;gBAC1C,kCAAkC;gBAClC,IAAI,OAAO,YAAY,KAAK,QAAQ,EAAE;oBACpC,OAAO,UAAU,CAAC,YAAY,CAAC,CAAA;iBAChC;gBAED,IAAI,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE;oBAC/B,8CAA8C;oBAC9C,2CAA2C;oBAC3C,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE;wBACxB,OAAO,GAAG,CAAA;qBACX;oBAED,oDAAoD;oBACpD,sDAAsD;oBACtD,oCAAoC;oBACpC,MAAM,aAAa,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAC/C,UAAU,CAAC,KAAK,CAAC,CAClB,CAAA;oBACD,IAAI,aAAa,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE;wBACxD,OAAO,aAAa,CAAC,MAAM,CACzB,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC,MAAM,GAAG,KAAK,EACjC,CAAC,CACF,CAAA;qBACF;oBAED,uDAAuD;oBACvD,iDAAiD;oBACjD,sCAAsC;oBACtC,2BAA2B;oBAE3B,wDAAwD;oBACxD,iDAAiD;oBACjD,MAAM,eAAe,GAAG,kBAAkB,CAAC,KAAK,GAAG,CAAC,CAAC,CAAA;oBAErD,IAAI,qBAAqB,GAAG,KAAK,CAAA;oBACjC,MAAM,mBAAmB,GAAG,YAAY,CAAC,MAAM,CAC7C,CAAC,mBAAmB,EAAE,KAAK,EAAE,EAAE;wBAC7B,IAAI,KAAK,EAAE;4BACT,MAAM,gBAAgB,GAAG,KAAK,CAAC,eAAe,CAAC,CAAA;4BAC/C,IAAI,KAAK,CAAC,OAAO,CAAC,gBAAgB,CAAC,EAAE;gCACnC,IAAI,gBAAgB,CAAC,MAAM,EAAE;oCAC3B,mBAAmB,CAAC,IAAI,CAAC,GAAG,gBAAgB,CAAC,CAAA;oCAC7C,qBAAqB,GAAG,IAAI,CAAA;iCAC7B;6BACF;iCAAM;gCACL,mBAAmB,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAA;6BAC3C;yBACF;wBACD,OAAO,mBAAmB,CAAA;oBAC5B,CAAC,EACD,EAAE,CACH,CAAA;oBAED,yFAAyF;oBACzF,IAAI,qBAAqB,EAAE;wBACzB,OAAO,mBAAmB,CAAA;qBAC3B;oBAED,OAAO,mBAAmB,CAAC,MAAM,CAC/B,CAAC,KAAa,EAAE,kBAAuC,EAAE,EAAE;wBACzD,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE;4BACvB,OAAO,GAAG,CAAA;yBACX;wBACD,MAAM,KAAK,GAAG,UAAU,CAAC,kBAA4B,CAAC,CAAA;wBACtD,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE;4BACvB,OAAO,GAAG,CAAA;yBACX;wBACD,OAAO,KAAK,GAAG,KAAK,CAAA;oBACtB,CAAC,EACD,CAAC,CACF,CAAA;iBACF;gBAED,yEAAyE;gBACzE,IACE,iBAAiB,CAAC,YAAY,CAAC;oBAC/B,OAAO,YAAY,CAAC,KAAK,KAAK,QAAQ,EACtC;oBACA,OAAO,UAAU,CAAC,YAAY,CAAC,KAAK,CAAC,CAAA;iBACtC;gBAED,0DAA0D;gBAC1D,gDAAgD;gBAChD,OAAO,GAAG,CAAA;YACZ,CAAC,EACD,kBAAkB,CACnB,CAAA;QACH,CAAC,CACF,CAAA;IACH,CAAC,EACD,EAAE,CACH,CAAA;IAED,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE;QACnD,MAAM,UAAU,GAAG,IAAI,gBAAgB,EAAE,CAAA;QACzC,UAAU,CAAC,gBAAgB,CAAC,OAAO,EAAE,CAAC,KAAa,EAAE,SAAiB,EAAE,EAAE;YACxE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE;gBAClD,OAAO,UAAU,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAA;aAC5C;YACD,OAAO,IAAI,CAAA;QACb,CAAC,CAAC,CAAA;QACF,UAAU,CAAC,gBAAgB,CACzB,QAAQ,EACR,CAAC,KAA0B,EAAE,YAAoB,EAAE,EAAE;YACnD,IAAI,gBAAgB,CAAC,KAAK,CAAC,EAAE;gBAC3B,OAAO,YAAY,IAAI,CAAC,CAAA;aACzB;YACD,OAAO,KAAK,CAAA;QACd,CAAC,CACF,CAAA;QAED,IAAI;YACF,IAAI,CAAC,OAAO,CAAC,WAAW;gBAAE,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAA;YACxE,MAAM,YAAY,GAAa,EAAE,CAAA;YACjC,mBAAmB,CAAC,qBAAqB,CACvC,OAAO,CAAC,WAAW,EACnB,CAAC,EAAE,WAAW,EAAE,EAAE,EAAE;gBAClB,YAAY,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;YAChC,CAAC,CACF,CAAA;YAED,MAAM,IAAI,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,EAAE;gBAC5D,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,YAAY,CAAC,YAAY,WAAW,GAAG,CAAC,EAAE,GAAG,CAAC,CAAA;gBACvE,MAAM,WAAW,GAAG,IAAI,KAAK,EAAE,CAAA;gBAC/B,gBAAgB,CAAC,UAAU,EAAE;oBAC3B,WAAW;oBACX,kBAAkB,EAAE,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC;iBAC3C,CAAC,CAAA;gBACF,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,WAAW,CAAC,CAAA;YACzC,CAAC,EAAE,OAAO,CAAC,WAAW,IAAI,EAAE,CAAC,CAAA;YAE7B,OAAO;gBACL,WAAW,EAAE,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;gBAC1C,QAAQ,EAAE,KAAK;aAChB,CAAA;SACF;QAAC,OAAO,CAAC,EAAE;YACV,OAAO,CAAC,IAAI,CACV,wDAAwD,EACxD,OAAO,EACP,CAAC,CACF,CAAA;YACD,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAA;YAC1B,OAAO;gBACL,WAAW,EAAE,IAAI;gBACjB,QAAQ,EAAE,IAAI;aACf,CAAA;SACF;IACH,CAAC,EAAE,CAAC,OAAO,EAAE,gBAAgB,CAAC,CAAC,CAAA;IAE/B,iBAAiB;IACjB,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACnB,IAAI,CAAC,WAAW;YAAE,OAAM;QACxB,MAAM,QAAQ,GAAG,WAAW,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAA;QACtD,IAAI,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,KAAK,SAAS,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE;YAClE,OAAM;SACP;QACD,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE;YACpB,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAA;SAC5B;aAAM;YACL,QAAQ,CAAC,OAAO,EAAE,SAAS,CAAC,CAAA;SAC7B;IACH,CAAC,EAAE,CAAC,WAAW,EAAE,OAAO,EAAE,mBAAmB,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAA;IAEhE,OAAO,CACL,6BAAK,SAAS,EAAC,6BAA6B;QAC1C,6BAAK,SAAS,EAAC,iCAAiC;YAC9C,oBAAC,SAAS,IACR,IAAI,EAAE,SAAS,EACf,SAAS,EAAC,oDAAoD,GAC9D;YACD,QAAQ,IAAI,CACX,6BACE,SAAS,EAAC,6CAA6C,EACvD,IAAI,EAAC,OAAO;gBAEZ,6BAAK,SAAS,EAAC,sBAAsB;oBACnC,6BAAK,SAAS,EAAC,kBAAkB;wBAC/B,2BAAG,SAAS,EAAC,iCAAiC,YAAU,CACpD;oBACN,6BAAK,SAAS,EAAC,QAAQ;wBACrB,wFAA6D,CACzD,CACF,CACF,CACP,CACG,CACF,CACP,CAAA;AACH,CAAC;AAED,eAAe,KAAK,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAA","sourcesContent":["import * as React from 'react'\nimport ExpressionParser from 'morph-expressions'\nimport escapeString from 'escape-string-regexp'\nimport useFormSubmissionModel from '../hooks/useFormSubmissionModelContext'\nimport { FormTypes } from '@oneblink/types'\nimport { Sentry } from '@oneblink/apps'\nimport { localisationService } from '@oneblink/apps'\nimport {\n FormElementValueChangeHandler,\n FormSubmissionModel,\n} from '../types/form'\nimport { formElementsService } from '@oneblink/sdk-core'\nimport QuillHTML from '../components/QuillHTML'\ntype Props = {\n element: FormTypes.CalculationElement\n onChange: FormElementValueChangeHandler<number>\n value: unknown | undefined\n}\n\nconst isUnenteredValue = (value: unknown | undefined) => {\n return !value && value !== 0\n}\n\nconst isObjectWithValue = (obj: unknown): obj is { value: unknown } => {\n return typeof obj === 'object' && obj !== null && 'value' in obj\n}\n\nfunction FormElementCalculation({ element, onChange, value }: Props) {\n const { formSubmissionModel } = useFormSubmissionModel()\n\n const htmlValue = React.useMemo(() => {\n let htmlTemplate\n\n if (!isNaN(value as number)) {\n htmlTemplate = element.defaultValue\n } else {\n console.log(\n '[Calculation] Was not a number... setting pre-calculation display',\n )\n htmlTemplate = element.preCalculationDisplay\n }\n\n const numberValue = typeof value === 'number' ? value : 0\n return (htmlTemplate || '').replace(\n /{result}/gi,\n element.displayAsCurrency\n ? localisationService.formatCurrency(numberValue)\n : localisationService.formatNumber(numberValue),\n )\n }, [element, value])\n\n const registerProperty = React.useCallback(\n (\n exprParser: typeof ExpressionParser,\n {\n replacement,\n nestedElementNames,\n }: {\n replacement: string\n nestedElementNames: string[]\n },\n ) => {\n exprParser.registerProperty(\n replacement,\n (submission: FormSubmissionModel) => {\n const defaultAccumulator = submission[nestedElementNames[0]]\n\n return nestedElementNames.reduce(\n (\n elementValue: unknown | undefined,\n elementName: string,\n index: number,\n ) => {\n // Numbers can just be returned as is\n if (typeof elementValue === 'number') {\n return elementValue\n }\n\n // attempt to get a number from the element value as a string.\n // NaN is accounted for is the calculation\n // so we can return that from here\n if (typeof elementValue === 'string') {\n return parseFloat(elementValue)\n }\n\n if (Array.isArray(elementValue)) {\n // If there are no entries, we can return null\n // to prevent the calculation from running.\n if (!elementValue.length) {\n return NaN\n }\n\n // An array could be an element that allows multiple\n // values e.g. checkboxes. If thats that case, we just\n // add them all together and move on\n const elementValues = elementValue.map((entry) =>\n parseFloat(entry),\n )\n if (elementValues.every((entry) => !Number.isNaN(entry))) {\n return elementValues.reduce(\n (number, entry) => number + entry,\n 0,\n )\n }\n\n // Other wise attempt to process it as a repeatable set\n // If we found another repeatable set to process,\n // pass it to the next element name to\n // iterate over the entries\n\n // If we are processing the entries in a repeatable set,\n // we can sum the numbers elements in the entries\n const nextElementName = nestedElementNames[index + 1]\n\n let isNestedRepeatableSet = false\n const nestedElementValues = elementValue.reduce(\n (nestedElementValues, entry) => {\n if (entry) {\n const nextElementValue = entry[nextElementName]\n if (Array.isArray(nextElementValue)) {\n if (nextElementValue.length) {\n nestedElementValues.push(...nextElementValue)\n isNestedRepeatableSet = true\n }\n } else {\n nestedElementValues.push(nextElementValue)\n }\n }\n return nestedElementValues\n },\n [],\n )\n\n // If the nested element values are all arrays, we can pass them on to the next iteration\n if (isNestedRepeatableSet) {\n return nestedElementValues\n }\n\n return nestedElementValues.reduce(\n (total: number, nestedElementValue: unknown | undefined) => {\n if (Number.isNaN(total)) {\n return NaN\n }\n const value = parseFloat(nestedElementValue as string)\n if (Number.isNaN(value)) {\n return NaN\n }\n return total + value\n },\n 0,\n )\n }\n\n // \"compliance\" form element has an object value with a \"value\" property.\n if (\n isObjectWithValue(elementValue) &&\n typeof elementValue.value === 'string'\n ) {\n return parseFloat(elementValue.value)\n }\n\n // We did not find a number value from the known elements,\n // we will assume we are at the end of the line.\n return NaN\n },\n defaultAccumulator,\n )\n },\n )\n },\n [],\n )\n\n const { calculation, hasError } = React.useMemo(() => {\n const exprParser = new ExpressionParser()\n exprParser.registerFunction('ROUND', (value: number, precision: number) => {\n if (!Number.isNaN(value) && Number.isFinite(value)) {\n return parseFloat(value.toFixed(precision))\n }\n return null\n })\n exprParser.registerFunction(\n 'ISNULL',\n (value: unknown | undefined, defaultValue: number) => {\n if (isUnenteredValue(value)) {\n return defaultValue || 0\n }\n return value\n },\n )\n\n try {\n if (!element.calculation) throw new Error('Element has no calculation.')\n const elementNames: string[] = []\n formElementsService.matchElementsTagRegex(\n element.calculation,\n ({ elementName }) => {\n elementNames.push(elementName)\n },\n )\n\n const code = elementNames.reduce((code, elementName, index) => {\n const regex = new RegExp(escapeString(`{ELEMENT:${elementName}}`), 'g')\n const replacement = `a${index}`\n registerProperty(exprParser, {\n replacement,\n nestedElementNames: elementName.split('|'),\n })\n return code.replace(regex, replacement)\n }, element.calculation || '')\n\n return {\n calculation: exprParser.parse(code.trim()),\n hasError: false,\n }\n } catch (e) {\n console.warn(\n 'Error while setting up parsing for calculation element',\n element,\n e,\n )\n Sentry.captureException(e)\n return {\n calculation: null,\n hasError: true,\n }\n }\n }, [element, registerProperty])\n\n // MODEL LISTENER\n React.useEffect(() => {\n if (!calculation) return\n const newValue = calculation.eval(formSubmissionModel)\n if (value === newValue || (value === undefined && isNaN(newValue))) {\n return\n }\n if (!isNaN(newValue)) {\n onChange(element, newValue)\n } else {\n onChange(element, undefined)\n }\n }, [calculation, element, formSubmissionModel, onChange, value])\n\n return (\n <div className=\"cypress-calculation-element\">\n <div className=\"ob-form__element ob-calculation\">\n <QuillHTML\n html={htmlValue}\n className=\"cypress-calculation-result ob-calculation__content\"\n />\n {hasError && (\n <div\n className=\"notification cypress-calculation-is-invalid\"\n role=\"alert\"\n >\n <div className=\"columns is-vcentered\">\n <div className=\"column is-narrow\">\n <i className=\"material-icons has-text-warning\">error</i>\n </div>\n <div className=\"column\">\n <p>There is an error in the calculation for this element.</p>\n </div>\n </div>\n </div>\n )}\n </div>\n </div>\n )\n}\n\nexport default React.memo(FormElementCalculation)\n"]}
|
@@ -1,8 +1,8 @@
|
|
1
1
|
import * as React from 'react';
|
2
|
-
import
|
2
|
+
import useReplaceableText from '../hooks/useReplaceableText';
|
3
3
|
import QuillHTML from '../components/QuillHTML';
|
4
4
|
function FormElementHTML({ element }) {
|
5
|
-
const html =
|
5
|
+
const html = useReplaceableText(element.defaultValue);
|
6
6
|
return (React.createElement("div", { className: "cypress-html-element" },
|
7
7
|
React.createElement("div", { className: "ob-form__element ob-information cypress-html-element" },
|
8
8
|
React.createElement(QuillHTML, { html: html, className: "cypress-html-element-content ob-information__content" }))));
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"FormElementHTML.js","sourceRoot":"","sources":["../../src/form-elements/FormElementHTML.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,OAAO,kBAAkB,MAAM,6BAA6B,CAAA;AAC5D,OAAO,SAAS,MAAM,yBAAyB,CAAA;AAM/C,SAAS,eAAe,CAAC,EAAE,OAAO,EAAS;IACzC,MAAM,IAAI,GAAG,kBAAkB,CAAC,OAAO,CAAC,YAAY,CAAC,CAAA;IAErD,OAAO,CACL,6BAAK,SAAS,EAAC,sBAAsB;QACnC,6BAAK,SAAS,EAAC,sDAAsD;YACnE,oBAAC,SAAS,IACR,IAAI,EAAE,IAAI,EACV,SAAS,EAAC,sDAAsD,GAChE,CACE,CACF,CACP,CAAA;AACH,CAAC;AAED,eAAe,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,CAAA","sourcesContent":["import * as React from 'react'\nimport { FormTypes } from '@oneblink/types'\nimport
|
1
|
+
{"version":3,"file":"FormElementHTML.js","sourceRoot":"","sources":["../../src/form-elements/FormElementHTML.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,OAAO,kBAAkB,MAAM,6BAA6B,CAAA;AAC5D,OAAO,SAAS,MAAM,yBAAyB,CAAA;AAM/C,SAAS,eAAe,CAAC,EAAE,OAAO,EAAS;IACzC,MAAM,IAAI,GAAG,kBAAkB,CAAC,OAAO,CAAC,YAAY,CAAC,CAAA;IAErD,OAAO,CACL,6BAAK,SAAS,EAAC,sBAAsB;QACnC,6BAAK,SAAS,EAAC,sDAAsD;YACnE,oBAAC,SAAS,IACR,IAAI,EAAE,IAAI,EACV,SAAS,EAAC,sDAAsD,GAChE,CACE,CACF,CACP,CAAA;AACH,CAAC;AAED,eAAe,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,CAAA","sourcesContent":["import * as React from 'react'\nimport { FormTypes } from '@oneblink/types'\nimport useReplaceableText from '../hooks/useReplaceableText'\nimport QuillHTML from '../components/QuillHTML'\n\ntype Props = {\n element: FormTypes.HtmlElement\n}\n\nfunction FormElementHTML({ element }: Props) {\n const html = useReplaceableText(element.defaultValue)\n\n return (\n <div className=\"cypress-html-element\">\n <div className=\"ob-form__element ob-information cypress-html-element\">\n <QuillHTML\n html={html}\n className=\"cypress-html-element-content ob-information__content\"\n />\n </div>\n </div>\n )\n}\n\nexport default React.memo(FormElementHTML)\n"]}
|
@@ -14,21 +14,36 @@ export default function useDynamicOptionsLoaderState(form, setFormSubmission) {
|
|
14
14
|
if (abortController.signal.aborted || !optionsByElementId.length) {
|
15
15
|
return;
|
16
16
|
}
|
17
|
-
const nonOkResponse = optionsByElementId.find((optionsForElementId) =>
|
18
|
-
if (nonOkResponse &&
|
19
|
-
setState(
|
17
|
+
const nonOkResponse = optionsByElementId.find((optionsForElementId) => optionsForElementId.type === 'ERROR');
|
18
|
+
if (nonOkResponse && nonOkResponse.type === 'ERROR') {
|
19
|
+
setState({
|
20
|
+
elementId: nonOkResponse.elementId,
|
21
|
+
error: nonOkResponse.error,
|
22
|
+
});
|
20
23
|
return;
|
21
24
|
}
|
22
25
|
setFormSubmission((currentFormSubmission) => {
|
23
26
|
const clonedForm = _cloneDeep(currentFormSubmission.definition);
|
24
27
|
for (const optionsForElementId of optionsByElementId) {
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
28
|
+
formElementsService.forEachFormElementWithOptions(clonedForm.elements, (formElement) => {
|
29
|
+
if (formElement.id === optionsForElementId.elementId) {
|
30
|
+
switch (optionsForElementId.type) {
|
31
|
+
case 'OPTIONS': {
|
32
|
+
formElement.options = optionsForElementId.options;
|
33
|
+
break;
|
34
|
+
}
|
35
|
+
case 'SEARCH': {
|
36
|
+
if (formElement.type === 'autocomplete') {
|
37
|
+
formElement.optionsType = 'SEARCH';
|
38
|
+
formElement.searchUrl = optionsForElementId.url;
|
39
|
+
formElement.searchQuerystringParameter =
|
40
|
+
optionsForElementId.searchQuerystringParameter;
|
41
|
+
}
|
42
|
+
break;
|
43
|
+
}
|
29
44
|
}
|
30
|
-
}
|
31
|
-
}
|
45
|
+
}
|
46
|
+
});
|
32
47
|
}
|
33
48
|
return {
|
34
49
|
...currentFormSubmission,
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"useDynamicOptionsLoaderState.js","sourceRoot":"","sources":["../../src/hooks/useDynamicOptionsLoaderState.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,UAAU,MAAM,kBAAkB,CAAA;AACzC,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAA;AACxD,OAAO,EAAE,WAAW,EAAqB,MAAM,gBAAgB,CAAA;AAI/D,MAAM,CAAC,OAAO,UAAU,4BAA4B,CAClD,IAAoB,EACpB,iBAAoC;
|
1
|
+
{"version":3,"file":"useDynamicOptionsLoaderState.js","sourceRoot":"","sources":["../../src/hooks/useDynamicOptionsLoaderState.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,UAAU,MAAM,kBAAkB,CAAA;AACzC,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAA;AACxD,OAAO,EAAE,WAAW,EAAqB,MAAM,gBAAgB,CAAA;AAI/D,MAAM,CAAC,OAAO,UAAU,4BAA4B,CAClD,IAAoB,EACpB,iBAAoC;IAEpC,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,KAAK,CAAC,QAAQ,CAG9B,IAAI,CAAC,CAAA;IACf,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACnB,IAAI,KAAK,EAAE;YACT,OAAM;SACP;QAED,MAAM,eAAe,GAAG,IAAI,eAAe,EAAE,CAE5C;QAAA,CAAC,KAAK,IAAI,EAAE;YACX,MAAM,kBAAkB,GAAG,MAAM,WAAW,CAAC,4BAA4B,CACvE,IAAI,CACL,CAAA;YAED,IAAI,eAAe,CAAC,MAAM,CAAC,OAAO,IAAI,CAAC,kBAAkB,CAAC,MAAM,EAAE;gBAChE,OAAM;aACP;YAED,MAAM,aAAa,GAAG,kBAAkB,CAAC,IAAI,CAC3C,CAAC,mBAAmB,EAAE,EAAE,CAAC,mBAAmB,CAAC,IAAI,KAAK,OAAO,CAC9D,CAAA;YACD,IAAI,aAAa,IAAI,aAAa,CAAC,IAAI,KAAK,OAAO,EAAE;gBACnD,QAAQ,CAAC;oBACP,SAAS,EAAE,aAAa,CAAC,SAAS;oBAClC,KAAK,EAAE,aAAa,CAAC,KAAK;iBAC3B,CAAC,CAAA;gBACF,OAAM;aACP;YAED,iBAAiB,CAAC,CAAC,qBAAqB,EAAE,EAAE;gBAC1C,MAAM,UAAU,GAAmB,UAAU,CAC3C,qBAAqB,CAAC,UAAU,CACjC,CAAA;gBACD,KAAK,MAAM,mBAAmB,IAAI,kBAAkB,EAAE;oBACpD,mBAAmB,CAAC,6BAA6B,CAC/C,UAAU,CAAC,QAAQ,EACnB,CAAC,WAAW,EAAE,EAAE;wBACd,IAAI,WAAW,CAAC,EAAE,KAAK,mBAAmB,CAAC,SAAS,EAAE;4BACpD,QAAQ,mBAAmB,CAAC,IAAI,EAAE;gCAChC,KAAK,SAAS,CAAC,CAAC;oCACd,WAAW,CAAC,OAAO,GAAG,mBAAmB,CAAC,OAAO,CAAA;oCACjD,MAAK;iCACN;gCACD,KAAK,QAAQ,CAAC,CAAC;oCACb,IAAI,WAAW,CAAC,IAAI,KAAK,cAAc,EAAE;wCACvC,WAAW,CAAC,WAAW,GAAG,QAAQ,CAAA;wCAClC,WAAW,CAAC,SAAS,GAAG,mBAAmB,CAAC,GAAG,CAAA;wCAC/C,WAAW,CAAC,0BAA0B;4CACpC,mBAAmB,CAAC,0BAA0B,CAAA;qCACjD;oCACD,MAAK;iCACN;6BACF;yBACF;oBACH,CAAC,CACF,CAAA;iBACF;gBACD,OAAO;oBACL,GAAG,qBAAqB;oBACxB,UAAU,EAAE,UAAU;iBACvB,CAAA;YACH,CAAC,CAAC,CAAA;QACJ,CAAC,CAAC,EAAE,CAAA;QAEJ,OAAO,GAAG,EAAE;YACV,eAAe,CAAC,KAAK,EAAE,CAAA;QACzB,CAAC,CAAA;IACH,CAAC,EAAE,CAAC,IAAI,EAAE,iBAAiB,EAAE,KAAK,CAAC,CAAC,CAAA;IAEpC,OAAO,KAAK,CAAA;AACd,CAAC","sourcesContent":["import * as React from 'react'\nimport _cloneDeep from 'lodash.clonedeep'\nimport { formElementsService } from '@oneblink/sdk-core'\nimport { formService, OneBlinkAppsError } from '@oneblink/apps'\nimport { FormTypes } from '@oneblink/types'\nimport { SetFormSubmission } from '../types/form'\n\nexport default function useDynamicOptionsLoaderState(\n form: FormTypes.Form,\n setFormSubmission: SetFormSubmission,\n) {\n const [state, setState] = React.useState<{\n elementId: string\n error: OneBlinkAppsError\n } | null>(null)\n React.useEffect(() => {\n if (state) {\n return\n }\n\n const abortController = new AbortController()\n\n ;(async () => {\n const optionsByElementId = await formService.getFormElementDynamicOptions(\n form,\n )\n\n if (abortController.signal.aborted || !optionsByElementId.length) {\n return\n }\n\n const nonOkResponse = optionsByElementId.find(\n (optionsForElementId) => optionsForElementId.type === 'ERROR',\n )\n if (nonOkResponse && nonOkResponse.type === 'ERROR') {\n setState({\n elementId: nonOkResponse.elementId,\n error: nonOkResponse.error,\n })\n return\n }\n\n setFormSubmission((currentFormSubmission) => {\n const clonedForm: FormTypes.Form = _cloneDeep(\n currentFormSubmission.definition,\n )\n for (const optionsForElementId of optionsByElementId) {\n formElementsService.forEachFormElementWithOptions(\n clonedForm.elements,\n (formElement) => {\n if (formElement.id === optionsForElementId.elementId) {\n switch (optionsForElementId.type) {\n case 'OPTIONS': {\n formElement.options = optionsForElementId.options\n break\n }\n case 'SEARCH': {\n if (formElement.type === 'autocomplete') {\n formElement.optionsType = 'SEARCH'\n formElement.searchUrl = optionsForElementId.url\n formElement.searchQuerystringParameter =\n optionsForElementId.searchQuerystringParameter\n }\n break\n }\n }\n }\n },\n )\n }\n return {\n ...currentFormSubmission,\n definition: clonedForm,\n }\n })\n })()\n\n return () => {\n abortController.abort()\n }\n }, [form, setFormSubmission, state])\n\n return state\n}\n"]}
|
package/dist/hooks/useLogin.d.ts
CHANGED
@@ -13,6 +13,9 @@ export default function useLogin({ username, password, newPassword, newPasswordC
|
|
13
13
|
isPasswordTemporary: boolean;
|
14
14
|
isResettingTemporaryPassword: boolean;
|
15
15
|
resetTemporaryPassword: () => Promise<void>;
|
16
|
+
isMfaCodeRequired: boolean;
|
17
|
+
isSubmittingMfaCode: boolean;
|
18
|
+
submitMfaCode: () => Promise<void>;
|
16
19
|
isShowingForgotPassword: boolean;
|
17
20
|
showForgotPassword: () => void;
|
18
21
|
hideForgotPassword: () => void;
|
package/dist/hooks/useLogin.js
CHANGED
@@ -42,12 +42,13 @@ export default function useLogin({ username, password, newPassword, newPasswordC
|
|
42
42
|
isInvalid: newPassword !== newPasswordConfirmed,
|
43
43
|
};
|
44
44
|
}, [newPassword, newPasswordConfirmed]);
|
45
|
-
// Login
|
46
|
-
const [{ isResettingTemporaryPassword, isLoggingIn, loginError,
|
45
|
+
// Login, Reset Password, MFA
|
46
|
+
const [{ isResettingTemporaryPassword, isLoggingIn, loginError, loginAttemptResponse, isSubmittingMfaCode, }, setLoginState,] = React.useState({
|
47
47
|
isResettingTemporaryPassword: false,
|
48
48
|
isLoggingIn: false,
|
49
49
|
loginError: null,
|
50
|
-
|
50
|
+
loginAttemptResponse: undefined,
|
51
|
+
isSubmittingMfaCode: false,
|
51
52
|
});
|
52
53
|
const clearLoginError = React.useCallback(() => setLoginState((current) => ({
|
53
54
|
...current,
|
@@ -68,34 +69,29 @@ export default function useLogin({ username, password, newPassword, newPasswordC
|
|
68
69
|
}));
|
69
70
|
return;
|
70
71
|
}
|
71
|
-
setLoginState({
|
72
|
-
|
73
|
-
resetTemporaryPasswordCallback: null,
|
72
|
+
setLoginState((currentState) => ({
|
73
|
+
...currentState,
|
74
74
|
isLoggingIn: true,
|
75
75
|
loginError: null,
|
76
|
-
});
|
76
|
+
}));
|
77
77
|
try {
|
78
|
-
const
|
79
|
-
if (
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
loginError: null,
|
86
|
-
});
|
87
|
-
}
|
78
|
+
const newLoginAttemptResponse = await authService.loginUsernamePassword(username, password);
|
79
|
+
if (isMounted.current) {
|
80
|
+
setLoginState((currentState) => ({
|
81
|
+
...currentState,
|
82
|
+
isLoggingIn: false,
|
83
|
+
loginAttemptResponse: newLoginAttemptResponse,
|
84
|
+
}));
|
88
85
|
}
|
89
86
|
}
|
90
87
|
catch (error) {
|
91
88
|
Sentry.captureException(error);
|
92
89
|
if (isMounted.current) {
|
93
|
-
setLoginState({
|
94
|
-
|
90
|
+
setLoginState((currentState) => ({
|
91
|
+
...currentState,
|
95
92
|
isLoggingIn: false,
|
96
|
-
resetTemporaryPasswordCallback: null,
|
97
93
|
loginError: error,
|
98
|
-
});
|
94
|
+
}));
|
99
95
|
}
|
100
96
|
}
|
101
97
|
}, [
|
@@ -106,6 +102,7 @@ export default function useLogin({ username, password, newPassword, newPasswordC
|
|
106
102
|
usernameValidation.isInvalid,
|
107
103
|
]);
|
108
104
|
const resetTemporaryPassword = React.useCallback(async () => {
|
105
|
+
const resetTemporaryPasswordCallback = loginAttemptResponse === null || loginAttemptResponse === void 0 ? void 0 : loginAttemptResponse.resetPasswordCallback;
|
109
106
|
if (!resetTemporaryPasswordCallback) {
|
110
107
|
return;
|
111
108
|
}
|
@@ -129,7 +126,14 @@ export default function useLogin({ username, password, newPassword, newPasswordC
|
|
129
126
|
loginError: null,
|
130
127
|
}));
|
131
128
|
try {
|
132
|
-
await resetTemporaryPasswordCallback(newPassword);
|
129
|
+
const resetPasswordResponse = await resetTemporaryPasswordCallback(newPassword);
|
130
|
+
if (isMounted.current) {
|
131
|
+
setLoginState((currentState) => ({
|
132
|
+
...currentState,
|
133
|
+
isResettingTemporaryPassword: false,
|
134
|
+
loginAttemptResponse: resetPasswordResponse,
|
135
|
+
}));
|
136
|
+
}
|
133
137
|
}
|
134
138
|
catch (error) {
|
135
139
|
Sentry.captureException(error);
|
@@ -143,11 +147,42 @@ export default function useLogin({ username, password, newPassword, newPasswordC
|
|
143
147
|
}
|
144
148
|
}, [
|
145
149
|
isMounted,
|
150
|
+
loginAttemptResponse === null || loginAttemptResponse === void 0 ? void 0 : loginAttemptResponse.resetPasswordCallback,
|
146
151
|
newPassword,
|
147
152
|
newPasswordConfirmedValidation.isInvalid,
|
148
153
|
newPasswordValidation.isInvalid,
|
149
|
-
resetTemporaryPasswordCallback,
|
150
154
|
]);
|
155
|
+
const submitMfaCode = React.useCallback(async () => {
|
156
|
+
const mfaCodeCallback = loginAttemptResponse === null || loginAttemptResponse === void 0 ? void 0 : loginAttemptResponse.mfaCodeCallback;
|
157
|
+
if (!mfaCodeCallback) {
|
158
|
+
return;
|
159
|
+
}
|
160
|
+
setLoginState((current) => ({
|
161
|
+
...current,
|
162
|
+
isSubmittingMfaCode: true,
|
163
|
+
loginError: null,
|
164
|
+
}));
|
165
|
+
try {
|
166
|
+
const mfaResponse = await mfaCodeCallback(code);
|
167
|
+
if (isMounted.current) {
|
168
|
+
setLoginState((currentState) => ({
|
169
|
+
...currentState,
|
170
|
+
isSubmittingMfaCode: false,
|
171
|
+
loginAttemptResponse: mfaResponse,
|
172
|
+
}));
|
173
|
+
}
|
174
|
+
}
|
175
|
+
catch (error) {
|
176
|
+
Sentry.captureException(error);
|
177
|
+
if (isMounted.current) {
|
178
|
+
setLoginState((current) => ({
|
179
|
+
...current,
|
180
|
+
isSubmittingMfaCode: false,
|
181
|
+
loginError: error,
|
182
|
+
}));
|
183
|
+
}
|
184
|
+
}
|
185
|
+
}, [code, isMounted, loginAttemptResponse === null || loginAttemptResponse === void 0 ? void 0 : loginAttemptResponse.mfaCodeCallback]);
|
151
186
|
// Forgot Password
|
152
187
|
const [isShowingForgotPassword, showForgotPassword, hideForgotPassword] = useBooleanState(false);
|
153
188
|
const [{ resetForgottenPasswordCallback, isSendingForgotPasswordCode, isResettingForgottenPassword, forgotPasswordError, }, setForgotPasswordState,] = React.useState({
|
@@ -269,9 +304,13 @@ export default function useLogin({ username, password, newPassword, newPasswordC
|
|
269
304
|
loginError,
|
270
305
|
clearLoginError,
|
271
306
|
// Reset Temp Password
|
272
|
-
isPasswordTemporary: !!
|
307
|
+
isPasswordTemporary: !!(loginAttemptResponse === null || loginAttemptResponse === void 0 ? void 0 : loginAttemptResponse.resetPasswordCallback),
|
273
308
|
isResettingTemporaryPassword,
|
274
309
|
resetTemporaryPassword,
|
310
|
+
// MFA Code
|
311
|
+
isMfaCodeRequired: !!(loginAttemptResponse === null || loginAttemptResponse === void 0 ? void 0 : loginAttemptResponse.mfaCodeCallback),
|
312
|
+
isSubmittingMfaCode,
|
313
|
+
submitMfaCode,
|
275
314
|
// Showing Forgot Password
|
276
315
|
isShowingForgotPassword,
|
277
316
|
showForgotPassword,
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"useLogin.js","sourceRoot":"","sources":["../../src/hooks/useLogin.ts"],"names":[],"mappings":"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","sourcesContent":["import * as React from 'react'\nimport { authService, Sentry } from '@oneblink/apps'\n\nimport useIsMounted from './useIsMounted'\nimport useBooleanState from './useBooleanState'\n\nexport default function useLogin({\n username,\n password,\n newPassword,\n newPasswordConfirmed,\n code,\n}: {\n username: string\n password: string\n newPassword: string\n newPasswordConfirmed: string\n code: string\n}) {\n const isMounted = useIsMounted()\n\n // Validation\n const usernameValidation = React.useMemo(() => {\n return {\n isInvalid: !username.trim(),\n }\n }, [username])\n\n const passwordValidation = React.useMemo(() => {\n return {\n isInvalid: !password.trim(),\n }\n }, [password])\n\n const codeValidation = React.useMemo(() => {\n return {\n isInvalid: !code.trim(),\n }\n }, [code])\n\n const newPasswordValidation = React.useMemo(() => {\n const validation = {\n hasLowercaseLetter: /[a-z]+/.test(newPassword),\n hasUpperCaseLetter: /[A-Z]+/.test(newPassword),\n hasNumber: /\\d+/.test(newPassword),\n hasSpecialCharacter: /[\\^$*.[\\]{}()?|\\-\"!@#%&/,><':;|_~`]+/.test(\n newPassword,\n ),\n hasMinLength: newPassword.length >= 8,\n isInvalid: true,\n }\n validation.isInvalid =\n !validation.hasLowercaseLetter ||\n !validation.hasUpperCaseLetter ||\n !validation.hasNumber ||\n !validation.hasSpecialCharacter ||\n !validation.hasMinLength\n return validation\n }, [newPassword])\n\n const newPasswordConfirmedValidation = React.useMemo(() => {\n return {\n isInvalid: newPassword !== newPasswordConfirmed,\n }\n }, [newPassword, newPasswordConfirmed])\n\n // Login & Reset Password\n const [\n {\n isResettingTemporaryPassword,\n isLoggingIn,\n loginError,\n resetTemporaryPasswordCallback,\n },\n setLoginState,\n ] = React.useState<{\n isResettingTemporaryPassword: boolean\n isLoggingIn: boolean\n loginError: null | Error\n resetTemporaryPasswordCallback: null | ((newPassword: string) => void)\n }>({\n isResettingTemporaryPassword: false,\n isLoggingIn: false,\n loginError: null,\n resetTemporaryPasswordCallback: null,\n })\n const clearLoginError = React.useCallback(\n () =>\n setLoginState((current) => ({\n ...current,\n loginError: null,\n })),\n [],\n )\n const loginWithUsernamePassword = React.useCallback(async () => {\n if (usernameValidation.isInvalid) {\n setLoginState((current) => ({\n ...current,\n loginError: new Error('Please enter a valid email address'),\n }))\n return\n }\n if (passwordValidation.isInvalid) {\n setLoginState((current) => ({\n ...current,\n loginError: new Error('Please enter a valid password'),\n }))\n return\n }\n\n setLoginState({\n isResettingTemporaryPassword: false,\n resetTemporaryPasswordCallback: null,\n isLoggingIn: true,\n loginError: null,\n })\n\n try {\n const newResetPasswordCallback = await authService.loginUsernamePassword(\n username,\n password,\n )\n if (newResetPasswordCallback) {\n if (isMounted.current) {\n setLoginState({\n isResettingTemporaryPassword: false,\n isLoggingIn: false,\n resetTemporaryPasswordCallback: newResetPasswordCallback,\n loginError: null,\n })\n }\n }\n } catch (error) {\n Sentry.captureException(error)\n if (isMounted.current) {\n setLoginState({\n isResettingTemporaryPassword: false,\n isLoggingIn: false,\n resetTemporaryPasswordCallback: null,\n loginError: error as Error,\n })\n }\n }\n }, [\n isMounted,\n password,\n passwordValidation.isInvalid,\n username,\n usernameValidation.isInvalid,\n ])\n\n const resetTemporaryPassword = React.useCallback(async () => {\n if (!resetTemporaryPasswordCallback) {\n return\n }\n\n if (newPasswordValidation.isInvalid) {\n setLoginState((current) => ({\n ...current,\n loginError: new Error('Please enter a valid password'),\n }))\n return\n }\n\n if (newPasswordConfirmedValidation.isInvalid) {\n setLoginState((current) => ({\n ...current,\n loginError: new Error('Please confirm your new password'),\n }))\n return\n }\n\n setLoginState((current) => ({\n ...current,\n isResettingPassword: true,\n loginError: null,\n }))\n\n try {\n await resetTemporaryPasswordCallback(newPassword)\n } catch (error) {\n Sentry.captureException(error)\n if (isMounted.current) {\n setLoginState((current) => ({\n ...current,\n isResettingPassword: false,\n loginError: error as Error,\n }))\n }\n }\n }, [\n isMounted,\n newPassword,\n newPasswordConfirmedValidation.isInvalid,\n newPasswordValidation.isInvalid,\n resetTemporaryPasswordCallback,\n ])\n\n // Forgot Password\n const [isShowingForgotPassword, showForgotPassword, hideForgotPassword] =\n useBooleanState(false)\n const [\n {\n resetForgottenPasswordCallback,\n isSendingForgotPasswordCode,\n isResettingForgottenPassword,\n forgotPasswordError,\n },\n setForgotPasswordState,\n ] = React.useState<{\n isSendingForgotPasswordCode: boolean\n forgotPasswordError: null | Error\n resetForgottenPasswordCallback:\n | null\n | ((code: string, newPassword: string) => void)\n isResettingForgottenPassword: boolean\n }>({\n isSendingForgotPasswordCode: false,\n forgotPasswordError: null,\n resetForgottenPasswordCallback: null,\n isResettingForgottenPassword: false,\n })\n const clearForgotPasswordError = React.useCallback(\n () =>\n setForgotPasswordState((current) => ({\n ...current,\n forgotPasswordError: null,\n })),\n [],\n )\n const sendForgotPasswordCode = React.useCallback(async () => {\n if (usernameValidation.isInvalid) {\n setForgotPasswordState((current) => ({\n ...current,\n forgotPasswordError: new Error('Please enter a valid email address'),\n }))\n return\n }\n\n setForgotPasswordState({\n isSendingForgotPasswordCode: true,\n resetForgottenPasswordCallback: null,\n forgotPasswordError: null,\n isResettingForgottenPassword: false,\n })\n\n try {\n const newResetForgottenPasswordCallback =\n await authService.forgotPassword(username)\n if (isMounted.current) {\n setForgotPasswordState({\n isSendingForgotPasswordCode: false,\n resetForgottenPasswordCallback: newResetForgottenPasswordCallback,\n forgotPasswordError: null,\n isResettingForgottenPassword: false,\n })\n }\n } catch (error) {\n Sentry.captureException(error)\n if (isMounted.current) {\n setForgotPasswordState({\n isSendingForgotPasswordCode: false,\n resetForgottenPasswordCallback: null,\n forgotPasswordError: error as Error,\n isResettingForgottenPassword: false,\n })\n }\n }\n }, [isMounted, username, usernameValidation.isInvalid])\n\n const resetForgottenPassword = React.useCallback(async () => {\n if (!resetForgottenPasswordCallback) {\n return\n }\n\n if (codeValidation.isInvalid) {\n setForgotPasswordState((current) => ({\n ...current,\n forgotPasswordError: new Error(\n 'Please enter the code that was sent to your email address',\n ),\n }))\n }\n if (newPasswordValidation.isInvalid) {\n setForgotPasswordState((current) => ({\n ...current,\n forgotPasswordError: new Error('Please enter a valid password'),\n }))\n return\n }\n if (newPasswordConfirmedValidation.isInvalid) {\n setForgotPasswordState((current) => ({\n ...current,\n forgotPasswordError: new Error('Please confirm your new password'),\n }))\n return\n }\n\n setForgotPasswordState((current) => ({\n ...current,\n isChangingPassword: true,\n forgotPasswordError: null,\n }))\n\n try {\n await resetForgottenPasswordCallback(code, newPassword)\n if (isMounted.current) {\n setForgotPasswordState({\n isSendingForgotPasswordCode: false,\n resetForgottenPasswordCallback: null,\n forgotPasswordError: null,\n isResettingForgottenPassword: false,\n })\n hideForgotPassword()\n }\n } catch (error) {\n Sentry.captureException(error)\n if (isMounted.current) {\n setForgotPasswordState((current) => ({\n ...current,\n isChangingPassword: false,\n forgotPasswordError: error as Error,\n }))\n }\n }\n }, [\n resetForgottenPasswordCallback,\n codeValidation.isInvalid,\n newPasswordValidation.isInvalid,\n newPasswordConfirmedValidation.isInvalid,\n code,\n newPassword,\n isMounted,\n hideForgotPassword,\n ])\n\n const loginWithGoogle = React.useCallback(() => {\n authService.loginHostedUI('Google')\n }, [])\n\n return {\n // Login\n loginWithGoogle,\n loginWithUsernamePassword,\n isLoggingIn,\n loginError,\n clearLoginError,\n // Reset Temp Password\n isPasswordTemporary: !!resetTemporaryPasswordCallback,\n isResettingTemporaryPassword,\n resetTemporaryPassword,\n // Showing Forgot Password\n isShowingForgotPassword,\n showForgotPassword,\n hideForgotPassword,\n forgotPasswordError,\n clearForgotPasswordError,\n // Sending Forgot Password Code\n isSendingForgotPasswordCode,\n sendForgotPasswordCode,\n // Resetting Forgotten Password\n hasSentForgotPasswordCode: !!resetForgottenPasswordCallback,\n isResettingForgottenPassword,\n resetForgottenPassword,\n // Validation\n usernameValidation,\n passwordValidation,\n codeValidation,\n newPasswordValidation,\n newPasswordConfirmedValidation,\n }\n}\n"]}
|
1
|
+
{"version":3,"file":"useLogin.js","sourceRoot":"","sources":["../../src/hooks/useLogin.ts"],"names":[],"mappings":"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","sourcesContent":["import * as React from 'react'\nimport { authService, Sentry } from '@oneblink/apps'\n\nimport useIsMounted from './useIsMounted'\nimport useBooleanState from './useBooleanState'\n\nexport default function useLogin({\n username,\n password,\n newPassword,\n newPasswordConfirmed,\n code,\n}: {\n username: string\n password: string\n newPassword: string\n newPasswordConfirmed: string\n code: string\n}) {\n const isMounted = useIsMounted()\n\n // Validation\n const usernameValidation = React.useMemo(() => {\n return {\n isInvalid: !username.trim(),\n }\n }, [username])\n\n const passwordValidation = React.useMemo(() => {\n return {\n isInvalid: !password.trim(),\n }\n }, [password])\n\n const codeValidation = React.useMemo(() => {\n return {\n isInvalid: !code.trim(),\n }\n }, [code])\n\n const newPasswordValidation = React.useMemo(() => {\n const validation = {\n hasLowercaseLetter: /[a-z]+/.test(newPassword),\n hasUpperCaseLetter: /[A-Z]+/.test(newPassword),\n hasNumber: /\\d+/.test(newPassword),\n hasSpecialCharacter: /[\\^$*.[\\]{}()?|\\-\"!@#%&/,><':;|_~`]+/.test(\n newPassword,\n ),\n hasMinLength: newPassword.length >= 8,\n isInvalid: true,\n }\n validation.isInvalid =\n !validation.hasLowercaseLetter ||\n !validation.hasUpperCaseLetter ||\n !validation.hasNumber ||\n !validation.hasSpecialCharacter ||\n !validation.hasMinLength\n return validation\n }, [newPassword])\n\n const newPasswordConfirmedValidation = React.useMemo(() => {\n return {\n isInvalid: newPassword !== newPasswordConfirmed,\n }\n }, [newPassword, newPasswordConfirmed])\n\n // Login, Reset Password, MFA\n const [\n {\n isResettingTemporaryPassword,\n isLoggingIn,\n loginError,\n loginAttemptResponse,\n isSubmittingMfaCode,\n },\n setLoginState,\n ] = React.useState<{\n isResettingTemporaryPassword: boolean\n isLoggingIn: boolean\n loginError: null | Error\n loginAttemptResponse: authService.LoginAttemptResponse | undefined\n isSubmittingMfaCode: boolean\n }>({\n isResettingTemporaryPassword: false,\n isLoggingIn: false,\n loginError: null,\n loginAttemptResponse: undefined,\n isSubmittingMfaCode: false,\n })\n const clearLoginError = React.useCallback(\n () =>\n setLoginState((current) => ({\n ...current,\n loginError: null,\n })),\n [],\n )\n const loginWithUsernamePassword = React.useCallback(async () => {\n if (usernameValidation.isInvalid) {\n setLoginState((current) => ({\n ...current,\n loginError: new Error('Please enter a valid email address'),\n }))\n return\n }\n if (passwordValidation.isInvalid) {\n setLoginState((current) => ({\n ...current,\n loginError: new Error('Please enter a valid password'),\n }))\n return\n }\n\n setLoginState((currentState) => ({\n ...currentState,\n isLoggingIn: true,\n loginError: null,\n }))\n\n try {\n const newLoginAttemptResponse = await authService.loginUsernamePassword(\n username,\n password,\n )\n if (isMounted.current) {\n setLoginState((currentState) => ({\n ...currentState,\n isLoggingIn: false,\n loginAttemptResponse: newLoginAttemptResponse,\n }))\n }\n } catch (error) {\n Sentry.captureException(error)\n if (isMounted.current) {\n setLoginState((currentState) => ({\n ...currentState,\n isLoggingIn: false,\n loginError: error as Error,\n }))\n }\n }\n }, [\n isMounted,\n password,\n passwordValidation.isInvalid,\n username,\n usernameValidation.isInvalid,\n ])\n\n const resetTemporaryPassword = React.useCallback(async () => {\n const resetTemporaryPasswordCallback =\n loginAttemptResponse?.resetPasswordCallback\n if (!resetTemporaryPasswordCallback) {\n return\n }\n\n if (newPasswordValidation.isInvalid) {\n setLoginState((current) => ({\n ...current,\n loginError: new Error('Please enter a valid password'),\n }))\n return\n }\n\n if (newPasswordConfirmedValidation.isInvalid) {\n setLoginState((current) => ({\n ...current,\n loginError: new Error('Please confirm your new password'),\n }))\n return\n }\n\n setLoginState((current) => ({\n ...current,\n isResettingPassword: true,\n loginError: null,\n }))\n\n try {\n const resetPasswordResponse = await resetTemporaryPasswordCallback(\n newPassword,\n )\n if (isMounted.current) {\n setLoginState((currentState) => ({\n ...currentState,\n isResettingTemporaryPassword: false,\n loginAttemptResponse: resetPasswordResponse,\n }))\n }\n } catch (error) {\n Sentry.captureException(error)\n if (isMounted.current) {\n setLoginState((current) => ({\n ...current,\n isResettingPassword: false,\n loginError: error as Error,\n }))\n }\n }\n }, [\n isMounted,\n loginAttemptResponse?.resetPasswordCallback,\n newPassword,\n newPasswordConfirmedValidation.isInvalid,\n newPasswordValidation.isInvalid,\n ])\n\n const submitMfaCode = React.useCallback(async () => {\n const mfaCodeCallback = loginAttemptResponse?.mfaCodeCallback\n if (!mfaCodeCallback) {\n return\n }\n\n setLoginState((current) => ({\n ...current,\n isSubmittingMfaCode: true,\n loginError: null,\n }))\n\n try {\n const mfaResponse = await mfaCodeCallback(code)\n if (isMounted.current) {\n setLoginState((currentState) => ({\n ...currentState,\n isSubmittingMfaCode: false,\n loginAttemptResponse: mfaResponse,\n }))\n }\n } catch (error) {\n Sentry.captureException(error)\n if (isMounted.current) {\n setLoginState((current) => ({\n ...current,\n isSubmittingMfaCode: false,\n loginError: error as Error,\n }))\n }\n }\n }, [code, isMounted, loginAttemptResponse?.mfaCodeCallback])\n\n // Forgot Password\n const [isShowingForgotPassword, showForgotPassword, hideForgotPassword] =\n useBooleanState(false)\n const [\n {\n resetForgottenPasswordCallback,\n isSendingForgotPasswordCode,\n isResettingForgottenPassword,\n forgotPasswordError,\n },\n setForgotPasswordState,\n ] = React.useState<{\n isSendingForgotPasswordCode: boolean\n forgotPasswordError: null | Error\n resetForgottenPasswordCallback:\n | null\n | ((code: string, newPassword: string) => void)\n isResettingForgottenPassword: boolean\n }>({\n isSendingForgotPasswordCode: false,\n forgotPasswordError: null,\n resetForgottenPasswordCallback: null,\n isResettingForgottenPassword: false,\n })\n const clearForgotPasswordError = React.useCallback(\n () =>\n setForgotPasswordState((current) => ({\n ...current,\n forgotPasswordError: null,\n })),\n [],\n )\n const sendForgotPasswordCode = React.useCallback(async () => {\n if (usernameValidation.isInvalid) {\n setForgotPasswordState((current) => ({\n ...current,\n forgotPasswordError: new Error('Please enter a valid email address'),\n }))\n return\n }\n\n setForgotPasswordState({\n isSendingForgotPasswordCode: true,\n resetForgottenPasswordCallback: null,\n forgotPasswordError: null,\n isResettingForgottenPassword: false,\n })\n\n try {\n const newResetForgottenPasswordCallback =\n await authService.forgotPassword(username)\n if (isMounted.current) {\n setForgotPasswordState({\n isSendingForgotPasswordCode: false,\n resetForgottenPasswordCallback: newResetForgottenPasswordCallback,\n forgotPasswordError: null,\n isResettingForgottenPassword: false,\n })\n }\n } catch (error) {\n Sentry.captureException(error)\n if (isMounted.current) {\n setForgotPasswordState({\n isSendingForgotPasswordCode: false,\n resetForgottenPasswordCallback: null,\n forgotPasswordError: error as Error,\n isResettingForgottenPassword: false,\n })\n }\n }\n }, [isMounted, username, usernameValidation.isInvalid])\n\n const resetForgottenPassword = React.useCallback(async () => {\n if (!resetForgottenPasswordCallback) {\n return\n }\n\n if (codeValidation.isInvalid) {\n setForgotPasswordState((current) => ({\n ...current,\n forgotPasswordError: new Error(\n 'Please enter the code that was sent to your email address',\n ),\n }))\n }\n if (newPasswordValidation.isInvalid) {\n setForgotPasswordState((current) => ({\n ...current,\n forgotPasswordError: new Error('Please enter a valid password'),\n }))\n return\n }\n if (newPasswordConfirmedValidation.isInvalid) {\n setForgotPasswordState((current) => ({\n ...current,\n forgotPasswordError: new Error('Please confirm your new password'),\n }))\n return\n }\n\n setForgotPasswordState((current) => ({\n ...current,\n isChangingPassword: true,\n forgotPasswordError: null,\n }))\n\n try {\n await resetForgottenPasswordCallback(code, newPassword)\n if (isMounted.current) {\n setForgotPasswordState({\n isSendingForgotPasswordCode: false,\n resetForgottenPasswordCallback: null,\n forgotPasswordError: null,\n isResettingForgottenPassword: false,\n })\n hideForgotPassword()\n }\n } catch (error) {\n Sentry.captureException(error)\n if (isMounted.current) {\n setForgotPasswordState((current) => ({\n ...current,\n isChangingPassword: false,\n forgotPasswordError: error as Error,\n }))\n }\n }\n }, [\n resetForgottenPasswordCallback,\n codeValidation.isInvalid,\n newPasswordValidation.isInvalid,\n newPasswordConfirmedValidation.isInvalid,\n code,\n newPassword,\n isMounted,\n hideForgotPassword,\n ])\n\n const loginWithGoogle = React.useCallback(() => {\n authService.loginHostedUI('Google')\n }, [])\n\n return {\n // Login\n loginWithGoogle,\n loginWithUsernamePassword,\n isLoggingIn,\n loginError,\n clearLoginError,\n // Reset Temp Password\n isPasswordTemporary: !!loginAttemptResponse?.resetPasswordCallback,\n isResettingTemporaryPassword,\n resetTemporaryPassword,\n // MFA Code\n isMfaCodeRequired: !!loginAttemptResponse?.mfaCodeCallback,\n isSubmittingMfaCode,\n submitMfaCode,\n // Showing Forgot Password\n isShowingForgotPassword,\n showForgotPassword,\n hideForgotPassword,\n forgotPasswordError,\n clearForgotPasswordError,\n // Sending Forgot Password Code\n isSendingForgotPasswordCode,\n sendForgotPasswordCode,\n // Resetting Forgotten Password\n hasSentForgotPasswordCode: !!resetForgottenPasswordCallback,\n isResettingForgottenPassword,\n resetForgottenPassword,\n // Validation\n usernameValidation,\n passwordValidation,\n codeValidation,\n newPasswordValidation,\n newPasswordConfirmedValidation,\n }\n}\n"]}
|
@@ -0,0 +1 @@
|
|
1
|
+
export default function useReplaceableText(text: string): string;
|
@@ -2,16 +2,14 @@ import { localisationService } from '@oneblink/apps';
|
|
2
2
|
import * as React from 'react';
|
3
3
|
import useFormSubmissionModel from './useFormSubmissionModelContext';
|
4
4
|
import { useRepeatableSetIndexText } from '../form-elements/FormElementRepeatableSet';
|
5
|
-
|
6
|
-
export default function useReplaceableHTML(text) {
|
5
|
+
export default function useReplaceableText(text) {
|
7
6
|
const textWithIndex = useRepeatableSetIndexText(text);
|
8
|
-
const html = React.useMemo(() => sanitizeHtml(textWithIndex), [textWithIndex]);
|
9
7
|
const { formSubmissionModel, elements } = useFormSubmissionModel();
|
10
8
|
return React.useMemo(() => {
|
11
|
-
return localisationService.replaceInjectablesWithElementValues(
|
9
|
+
return localisationService.replaceInjectablesWithElementValues(textWithIndex, {
|
12
10
|
submission: formSubmissionModel,
|
13
11
|
formElements: elements,
|
14
12
|
});
|
15
|
-
}, [elements, formSubmissionModel,
|
13
|
+
}, [elements, formSubmissionModel, textWithIndex]);
|
16
14
|
}
|
17
|
-
//# sourceMappingURL=
|
15
|
+
//# sourceMappingURL=useReplaceableText.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"useReplaceableText.js","sourceRoot":"","sources":["../../src/hooks/useReplaceableText.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAA;AACpD,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,sBAAsB,MAAM,iCAAiC,CAAA;AACpE,OAAO,EAAE,yBAAyB,EAAE,MAAM,2CAA2C,CAAA;AAErF,MAAM,CAAC,OAAO,UAAU,kBAAkB,CAAC,IAAY;IACrD,MAAM,aAAa,GAAG,yBAAyB,CAAC,IAAI,CAAC,CAAA;IACrD,MAAM,EAAE,mBAAmB,EAAE,QAAQ,EAAE,GAAG,sBAAsB,EAAE,CAAA;IAClE,OAAO,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE;QACxB,OAAO,mBAAmB,CAAC,mCAAmC,CAC5D,aAAa,EACb;YACE,UAAU,EAAE,mBAAmB;YAC/B,YAAY,EAAE,QAAQ;SACvB,CACF,CAAA;IACH,CAAC,EAAE,CAAC,QAAQ,EAAE,mBAAmB,EAAE,aAAa,CAAC,CAAC,CAAA;AACpD,CAAC","sourcesContent":["import { localisationService } from '@oneblink/apps'\nimport * as React from 'react'\nimport useFormSubmissionModel from './useFormSubmissionModelContext'\nimport { useRepeatableSetIndexText } from '../form-elements/FormElementRepeatableSet'\n\nexport default function useReplaceableText(text: string) {\n const textWithIndex = useRepeatableSetIndexText(text)\n const { formSubmissionModel, elements } = useFormSubmissionModel()\n return React.useMemo(() => {\n return localisationService.replaceInjectablesWithElementValues(\n textWithIndex,\n {\n submission: formSubmissionModel,\n formElements: elements,\n },\n )\n }, [elements, formSubmissionModel, textWithIndex])\n}\n"]}
|
package/package.json
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
{
|
2
2
|
"name": "@oneblink/apps-react",
|
3
3
|
"description": "Helper functions for OneBlink apps in ReactJS.",
|
4
|
-
"version": "
|
4
|
+
"version": "3.0.0-beta.2",
|
5
5
|
"author": "OneBlink <developers@oneblink.io> (https://oneblink.io)",
|
6
6
|
"bugs": {
|
7
7
|
"url": "https://github.com/oneblink/apps-react/issues"
|
@@ -47,7 +47,7 @@
|
|
47
47
|
"@mui/lab": "^5.0.0-alpha.95",
|
48
48
|
"@mui/material": "^5.10.1",
|
49
49
|
"@mui/x-date-pickers": "^5.0.0-beta.6",
|
50
|
-
"@oneblink/apps": "^
|
50
|
+
"@oneblink/apps": "^4.0.0-beta.2",
|
51
51
|
"@oneblink/release-cli": "^2.0.2",
|
52
52
|
"@oneblink/types": "github:oneblink/types",
|
53
53
|
"@types/blueimp-load-image": "^5.16.0",
|
@@ -1 +0,0 @@
|
|
1
|
-
export default function useReplaceableHTML(text: string): string;
|
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"file":"useReplaceableHTML.js","sourceRoot":"","sources":["../../src/hooks/useReplaceableHTML.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAA;AACpD,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,sBAAsB,MAAM,iCAAiC,CAAA;AACpE,OAAO,EAAE,yBAAyB,EAAE,MAAM,2CAA2C,CAAA;AACrF,OAAO,YAAY,MAAM,2BAA2B,CAAA;AAEpD,MAAM,CAAC,OAAO,UAAU,kBAAkB,CAAC,IAAY;IACrD,MAAM,aAAa,GAAG,yBAAyB,CAAC,IAAI,CAAC,CAAA;IACrD,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,YAAY,CAAC,aAAa,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,CAAA;IAC9E,MAAM,EAAE,mBAAmB,EAAE,QAAQ,EAAE,GAAG,sBAAsB,EAAE,CAAA;IAClE,OAAO,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE;QACxB,OAAO,mBAAmB,CAAC,mCAAmC,CAAC,IAAI,EAAE;YACnE,UAAU,EAAE,mBAAmB;YAC/B,YAAY,EAAE,QAAQ;SACvB,CAAC,CAAA;IACJ,CAAC,EAAE,CAAC,QAAQ,EAAE,mBAAmB,EAAE,IAAI,CAAC,CAAC,CAAA;AAC3C,CAAC","sourcesContent":["import { localisationService } from '@oneblink/apps'\nimport * as React from 'react'\nimport useFormSubmissionModel from './useFormSubmissionModelContext'\nimport { useRepeatableSetIndexText } from '../form-elements/FormElementRepeatableSet'\nimport sanitizeHtml from '../services/sanitize-html'\n\nexport default function useReplaceableHTML(text: string) {\n const textWithIndex = useRepeatableSetIndexText(text)\n const html = React.useMemo(() => sanitizeHtml(textWithIndex), [textWithIndex])\n const { formSubmissionModel, elements } = useFormSubmissionModel()\n return React.useMemo(() => {\n return localisationService.replaceInjectablesWithElementValues(html, {\n submission: formSubmissionModel,\n formElements: elements,\n })\n }, [elements, formSubmissionModel, html])\n}\n"]}
|