@oneblink/apps-react 2.14.2-beta.6 → 3.0.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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('value', search);
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"]}
@@ -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) => !optionsForElementId.ok);
18
- if (nonOkResponse && !nonOkResponse.ok) {
19
- setState(nonOkResponse);
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
- if (optionsForElementId.ok) {
26
- formElementsService.forEachFormElementWithOptions(clonedForm.elements, (formElement) => {
27
- if (formElement.id === optionsForElementId.elementId) {
28
- formElement.options = optionsForElementId.options;
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;IAKpC,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GACrB,KAAK,CAAC,QAAQ,CAAkD,IAAI,CAAC,CAAA;IACvE,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,CAAC,mBAAmB,CAAC,EAAE,CACjD,CAAA;YACD,IAAI,aAAa,IAAI,CAAC,aAAa,CAAC,EAAE,EAAE;gBACtC,QAAQ,CAAC,aAAa,CAAC,CAAA;gBACvB,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,IAAI,mBAAmB,CAAC,EAAE,EAAE;wBAC1B,mBAAmB,CAAC,6BAA6B,CAC/C,UAAU,CAAC,QAAQ,EACnB,CAAC,WAAW,EAAE,EAAE;4BACd,IAAI,WAAW,CAAC,EAAE,KAAK,mBAAmB,CAAC,SAAS,EAAE;gCACpD,WAAW,CAAC,OAAO,GAAG,mBAAmB,CAAC,OAAO,CAAA;6BAClD;wBACH,CAAC,CACF,CAAA;qBACF;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 elementId: string\n error: OneBlinkAppsError\n} | null {\n const [state, setState] =\n React.useState<ReturnType<typeof useDynamicOptionsLoaderState>>(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.ok,\n )\n if (nonOkResponse && !nonOkResponse.ok) {\n setState(nonOkResponse)\n return\n }\n\n setFormSubmission((currentFormSubmission) => {\n const clonedForm: FormTypes.Form = _cloneDeep(\n currentFormSubmission.definition,\n )\n for (const optionsForElementId of optionsByElementId) {\n if (optionsForElementId.ok) {\n formElementsService.forEachFormElementWithOptions(\n clonedForm.elements,\n (formElement) => {\n if (formElement.id === optionsForElementId.elementId) {\n formElement.options = optionsForElementId.options\n }\n },\n )\n }\n }\n return {\n ...currentFormSubmission,\n definition: clonedForm,\n }\n })\n })()\n\n return () => {\n abortController.abort()\n }\n }, [form, setFormSubmission, state])\n\n return state\n}\n"]}
1
+ {"version":3,"file":"useDynamicOptionsLoaderState.js","sourceRoot":"","sources":["../../src/hooks/useDynamicOptionsLoaderState.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"]}
@@ -16,7 +16,6 @@ export default function useInfiniteScrollDataLoad<Filters, T>({ limit, isManual,
16
16
  limit: number;
17
17
  offset: number;
18
18
  nextOffset?: number | undefined;
19
- total?: number;
20
19
  };
21
20
  }>;
22
21
  onValidateFilters?: (filters: Filters) => boolean;
@@ -30,5 +29,4 @@ export default function useInfiniteScrollDataLoad<Filters, T>({ limit, isManual,
30
29
  onChangeFilters: OnChangeFilters<Filters>;
31
30
  onReplace: (replacer: (record: T) => T) => void;
32
31
  nextOffset: number;
33
- total: number | undefined;
34
32
  };
@@ -19,12 +19,11 @@ export default function useInfiniteScrollDataLoad({ limit, isManual, debounceSea
19
19
  filters: changeHandler(currentState.filters),
20
20
  }));
21
21
  }, []);
22
- const [{ isLoading, records, error, nextOffset, total }, setState] = React.useState({
22
+ const [{ isLoading, records, error, nextOffset }, setState] = React.useState({
23
23
  isLoading: 'INITIAL',
24
24
  records: [],
25
25
  error: null,
26
26
  nextOffset: 0,
27
- total: undefined,
28
27
  });
29
28
  const fetchRecords = React.useCallback(async (abortSignal) => {
30
29
  if (onValidateFilters) {
@@ -49,7 +48,6 @@ export default function useInfiniteScrollDataLoad({ limit, isManual, debounceSea
49
48
  records: [...currentState.records, ...result.records],
50
49
  isLoading: null,
51
50
  nextOffset: result.meta.nextOffset || 0,
52
- total: result.meta.total,
53
51
  }));
54
52
  }
55
53
  catch (error) {
@@ -126,7 +124,6 @@ export default function useInfiniteScrollDataLoad({ limit, isManual, debounceSea
126
124
  onChangeFilters,
127
125
  onReplace,
128
126
  nextOffset,
129
- total,
130
127
  };
131
128
  }
132
129
  //# sourceMappingURL=useInfiniteScrollDataLoad.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"useInfiniteScrollDataLoad.js","sourceRoot":"","sources":["../../src/hooks/useInfiniteScrollDataLoad.tsx"],"names":[],"mappings":"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","sourcesContent":["import * as React from 'react'\n\nimport useQuery from './useQuery'\n\nexport type ChangeHandler<T> = (filters: T) => T\nexport type OnChangeFilters<T> = (\n changeHandler: ChangeHandler<T>,\n shouldDebounce: boolean,\n) => void\n\nexport type LoadingType = 'INITIAL' | 'MORE' | null\n\nexport default function useInfiniteScrollDataLoad<Filters, T>({\n limit,\n isManual,\n debounceSearchMs,\n onDefaultFilters,\n onSearch,\n onValidateFilters,\n}: {\n limit: number\n isManual?: boolean\n debounceSearchMs?: number\n onDefaultFilters: (query: ReturnType<typeof useQuery>) => Filters\n onSearch: (\n filters: Filters,\n paging: {\n limit: number\n offset: number\n },\n abortSignal: AbortSignal,\n ) => Promise<{\n records: T[]\n meta: {\n limit: number\n offset: number\n nextOffset?: number | undefined\n total?: number\n }\n }>\n onValidateFilters?: (filters: Filters) => boolean\n}) {\n const query = useQuery()\n\n const [{ forceReload, shouldDebounce, offset, filters }, setOffsetState] =\n React.useState<{\n forceReload: boolean\n shouldDebounce: boolean\n offset: number\n filters: Filters\n }>(() => {\n return {\n forceReload: false,\n shouldDebounce: false,\n offset: 0,\n filters: onDefaultFilters(query),\n }\n })\n\n const onChangeFilters = React.useCallback<OnChangeFilters<Filters>>(\n (changeHandler, shouldDebounce) => {\n setOffsetState((currentState) => ({\n ...currentState,\n afterRefresh: false,\n shouldDebounce,\n offset: 0,\n filters: changeHandler(currentState.filters),\n }))\n },\n [],\n )\n\n const [{ isLoading, records, error, nextOffset, total }, setState] =\n React.useState<{\n isLoading: LoadingType\n records: T[]\n error: Error | null\n nextOffset: number\n total?: number\n }>({\n isLoading: 'INITIAL',\n records: [],\n error: null,\n nextOffset: 0,\n total: undefined,\n })\n\n const fetchRecords = React.useCallback(\n async (abortSignal: AbortSignal) => {\n if (onValidateFilters) {\n const isValid = onValidateFilters(filters)\n if (!isValid) {\n return\n }\n }\n\n setState((currentState) => ({\n ...currentState,\n error: null,\n records: offset === 0 ? [] : currentState.records,\n isLoading: offset === 0 ? 'INITIAL' : 'MORE',\n }))\n try {\n const result = await onSearch(\n filters,\n {\n limit,\n offset,\n },\n abortSignal,\n )\n setState((currentState) => ({\n error: null,\n records: [...currentState.records, ...result.records],\n isLoading: null,\n nextOffset: result.meta.nextOffset || 0,\n total: result.meta.total,\n }))\n } catch (error) {\n if (abortSignal.aborted) {\n return\n }\n console.warn('An error occurred while fetching records', error)\n setState((currentState) => ({\n ...currentState,\n error: error as Error,\n isLoading: null,\n }))\n }\n },\n [onValidateFilters, filters, offset, onSearch, limit],\n )\n\n React.useEffect(() => {\n const controller = new AbortController()\n const timeoutId = setTimeout(\n () => {\n fetchRecords(controller.signal)\n },\n shouldDebounce ? debounceSearchMs || 0 : 0,\n )\n return () => {\n clearTimeout(timeoutId)\n controller.abort()\n }\n }, [debounceSearchMs, fetchRecords, shouldDebounce, forceReload])\n\n const onLoad = React.useCallback((newOffset?: number) => {\n setOffsetState((currentState) => {\n return {\n ...currentState,\n offset: typeof newOffset === 'number' ? newOffset : currentState.offset,\n forceReload: !currentState.forceReload,\n shouldDebounce: false,\n }\n })\n }, [])\n\n React.useEffect(() => {\n if (isManual) {\n return\n }\n const scrollEventListener = () => {\n // Bails early if we have not fetched data yet and:\n // - there's an error\n // - it's already loading\n // - there's nothing left to load\n if (!document.body || error || isLoading || !nextOffset) {\n return\n }\n\n // Checks that the page has scrolled to the bottom\n if (window.innerHeight + window.scrollY >= document.body.scrollHeight) {\n onLoad(nextOffset)\n }\n }\n // Binds our scroll event handler\n window.addEventListener('scroll', scrollEventListener)\n\n return () => {\n window.removeEventListener('scroll', scrollEventListener)\n }\n }, [error, isLoading, isManual, nextOffset, onLoad])\n\n const onRefresh = React.useCallback(() => {\n onLoad(0)\n }, [onLoad])\n\n const onReplace = React.useCallback((replacer: (record: T) => T) => {\n setState((state) => ({\n ...state,\n records: state.records.map(replacer),\n }))\n }, [])\n\n return {\n isLoading,\n loadError: error,\n records,\n onRefresh,\n onTryAgain: onLoad,\n filters,\n onChangeFilters,\n onReplace,\n nextOffset,\n total,\n }\n}\n"]}
1
+ {"version":3,"file":"useInfiniteScrollDataLoad.js","sourceRoot":"","sources":["../../src/hooks/useInfiniteScrollDataLoad.tsx"],"names":[],"mappings":"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","sourcesContent":["import * as React from 'react'\n\nimport useQuery from './useQuery'\n\nexport type ChangeHandler<T> = (filters: T) => T\nexport type OnChangeFilters<T> = (\n changeHandler: ChangeHandler<T>,\n shouldDebounce: boolean,\n) => void\n\nexport type LoadingType = 'INITIAL' | 'MORE' | null\n\nexport default function useInfiniteScrollDataLoad<Filters, T>({\n limit,\n isManual,\n debounceSearchMs,\n onDefaultFilters,\n onSearch,\n onValidateFilters,\n}: {\n limit: number\n isManual?: boolean\n debounceSearchMs?: number\n onDefaultFilters: (query: ReturnType<typeof useQuery>) => Filters\n onSearch: (\n filters: Filters,\n paging: {\n limit: number\n offset: number\n },\n abortSignal: AbortSignal,\n ) => Promise<{\n records: T[]\n meta: {\n limit: number\n offset: number\n nextOffset?: number | undefined\n }\n }>\n onValidateFilters?: (filters: Filters) => boolean\n}) {\n const query = useQuery()\n\n const [{ forceReload, shouldDebounce, offset, filters }, setOffsetState] =\n React.useState<{\n forceReload: boolean\n shouldDebounce: boolean\n offset: number\n filters: Filters\n }>(() => {\n return {\n forceReload: false,\n shouldDebounce: false,\n offset: 0,\n filters: onDefaultFilters(query),\n }\n })\n\n const onChangeFilters = React.useCallback<OnChangeFilters<Filters>>(\n (changeHandler, shouldDebounce) => {\n setOffsetState((currentState) => ({\n ...currentState,\n afterRefresh: false,\n shouldDebounce,\n offset: 0,\n filters: changeHandler(currentState.filters),\n }))\n },\n [],\n )\n\n const [{ isLoading, records, error, nextOffset }, setState] = React.useState<{\n isLoading: LoadingType\n records: T[]\n error: Error | null\n nextOffset: number\n }>({\n isLoading: 'INITIAL',\n records: [],\n error: null,\n nextOffset: 0,\n })\n\n const fetchRecords = React.useCallback(\n async (abortSignal: AbortSignal) => {\n if (onValidateFilters) {\n const isValid = onValidateFilters(filters)\n if (!isValid) {\n return\n }\n }\n\n setState((currentState) => ({\n ...currentState,\n error: null,\n records: offset === 0 ? [] : currentState.records,\n isLoading: offset === 0 ? 'INITIAL' : 'MORE',\n }))\n try {\n const result = await onSearch(\n filters,\n {\n limit,\n offset,\n },\n abortSignal,\n )\n setState((currentState) => ({\n error: null,\n records: [...currentState.records, ...result.records],\n isLoading: null,\n nextOffset: result.meta.nextOffset || 0,\n }))\n } catch (error) {\n if (abortSignal.aborted) {\n return\n }\n console.warn('An error occurred while fetching records', error)\n setState((currentState) => ({\n ...currentState,\n error: error as Error,\n isLoading: null,\n }))\n }\n },\n [onValidateFilters, filters, offset, onSearch, limit],\n )\n\n React.useEffect(() => {\n const controller = new AbortController()\n const timeoutId = setTimeout(\n () => {\n fetchRecords(controller.signal)\n },\n shouldDebounce ? debounceSearchMs || 0 : 0,\n )\n return () => {\n clearTimeout(timeoutId)\n controller.abort()\n }\n }, [debounceSearchMs, fetchRecords, shouldDebounce, forceReload])\n\n const onLoad = React.useCallback((newOffset?: number) => {\n setOffsetState((currentState) => {\n return {\n ...currentState,\n offset: typeof newOffset === 'number' ? newOffset : currentState.offset,\n forceReload: !currentState.forceReload,\n shouldDebounce: false,\n }\n })\n }, [])\n\n React.useEffect(() => {\n if (isManual) {\n return\n }\n const scrollEventListener = () => {\n // Bails early if we have not fetched data yet and:\n // - there's an error\n // - it's already loading\n // - there's nothing left to load\n if (!document.body || error || isLoading || !nextOffset) {\n return\n }\n\n // Checks that the page has scrolled to the bottom\n if (window.innerHeight + window.scrollY >= document.body.scrollHeight) {\n onLoad(nextOffset)\n }\n }\n // Binds our scroll event handler\n window.addEventListener('scroll', scrollEventListener)\n\n return () => {\n window.removeEventListener('scroll', scrollEventListener)\n }\n }, [error, isLoading, isManual, nextOffset, onLoad])\n\n const onRefresh = React.useCallback(() => {\n onLoad(0)\n }, [onLoad])\n\n const onReplace = React.useCallback((replacer: (record: T) => T) => {\n setState((state) => ({\n ...state,\n records: state.records.map(replacer),\n }))\n }, [])\n\n return {\n isLoading,\n loadError: error,\n records,\n onRefresh,\n onTryAgain: onLoad,\n filters,\n onChangeFilters,\n onReplace,\n nextOffset,\n }\n}\n"]}
@@ -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;
@@ -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 & Reset Password
46
- const [{ isResettingTemporaryPassword, isLoggingIn, loginError, resetTemporaryPasswordCallback, }, setLoginState,] = React.useState({
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
- resetTemporaryPasswordCallback: null,
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
- isResettingTemporaryPassword: false,
73
- resetTemporaryPasswordCallback: null,
72
+ setLoginState((currentState) => ({
73
+ ...currentState,
74
74
  isLoggingIn: true,
75
75
  loginError: null,
76
- });
76
+ }));
77
77
  try {
78
- const newResetPasswordCallback = await authService.loginUsernamePassword(username, password);
79
- if (newResetPasswordCallback) {
80
- if (isMounted.current) {
81
- setLoginState({
82
- isResettingTemporaryPassword: false,
83
- isLoggingIn: false,
84
- resetTemporaryPasswordCallback: newResetPasswordCallback,
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
- isResettingTemporaryPassword: false,
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: !!resetTemporaryPasswordCallback,
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"]}
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": "2.14.2-beta.6",
4
+ "version": "3.0.0-beta.1",
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": "^3.2.0-beta.4",
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",