@oneblink/apps-react 4.0.0-beta.6 → 4.0.0-beta.8
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/OneBlinkAutoSaveForm.d.ts +1 -0
- package/dist/OneBlinkAutoSaveForm.js +1 -0
- package/dist/OneBlinkAutoSaveForm.js.map +1 -1
- package/dist/OneBlinkForm.d.ts +2 -0
- package/dist/OneBlinkForm.js +2 -0
- package/dist/OneBlinkForm.js.map +1 -1
- package/dist/OneBlinkReadOnlyForm.d.ts +1 -0
- package/dist/OneBlinkReadOnlyForm.js +1 -0
- package/dist/OneBlinkReadOnlyForm.js.map +1 -1
- package/dist/PaymentReceipt.d.ts +4 -0
- package/dist/PaymentReceipt.js +4 -0
- package/dist/PaymentReceipt.js.map +1 -1
- package/dist/components/formStore/OneBlinkFormStoreClearFiltersButton.d.ts +5 -0
- package/dist/components/formStore/OneBlinkFormStoreClearFiltersButton.js +5 -0
- package/dist/components/formStore/OneBlinkFormStoreClearFiltersButton.js.map +1 -1
- package/dist/components/formStore/OneBlinkFormStoreColumnsButton.d.ts +5 -0
- package/dist/components/formStore/OneBlinkFormStoreColumnsButton.js +5 -0
- package/dist/components/formStore/OneBlinkFormStoreColumnsButton.js.map +1 -1
- package/dist/components/formStore/OneBlinkFormStoreDownloadButton.d.ts +5 -0
- package/dist/components/formStore/OneBlinkFormStoreDownloadButton.js +5 -0
- package/dist/components/formStore/OneBlinkFormStoreDownloadButton.js.map +1 -1
- package/dist/components/formStore/OneBlinkFormStoreProvider.d.ts +5 -0
- package/dist/components/formStore/OneBlinkFormStoreProvider.js +5 -0
- package/dist/components/formStore/OneBlinkFormStoreProvider.js.map +1 -1
- package/dist/components/formStore/OneBlinkFormStoreRefreshButton.d.ts +5 -0
- package/dist/components/formStore/OneBlinkFormStoreRefreshButton.js +5 -0
- package/dist/components/formStore/OneBlinkFormStoreRefreshButton.js.map +1 -1
- package/dist/components/formStore/OneBlinkFormStoreTable.d.ts +4 -0
- package/dist/components/formStore/OneBlinkFormStoreTable.js +4 -0
- package/dist/components/formStore/OneBlinkFormStoreTable.js.map +1 -1
- package/dist/components/pickers/V4CompatibleDatePicker.d.ts +5 -0
- package/dist/components/pickers/V4CompatibleDatePicker.js +5 -0
- package/dist/components/pickers/V4CompatibleDatePicker.js.map +1 -1
- package/dist/components/pickers/V4CompatibleDateTimePicker.d.ts +5 -0
- package/dist/components/pickers/V4CompatibleDateTimePicker.js +5 -0
- package/dist/components/pickers/V4CompatibleDateTimePicker.js.map +1 -1
- package/dist/components/pickers/V4CompatibleTimePicker.d.ts +5 -0
- package/dist/components/pickers/V4CompatibleTimePicker.js +5 -0
- package/dist/components/pickers/V4CompatibleTimePicker.js.map +1 -1
- package/dist/components/renderer/LookupButton.js +2 -2
- package/dist/components/renderer/LookupButton.js.map +1 -1
- package/dist/components/renderer/LookupNotification.js +26 -22
- package/dist/components/renderer/LookupNotification.js.map +1 -1
- package/dist/components/renderer/ProgressBar.d.ts +5 -0
- package/dist/components/renderer/ProgressBar.js +5 -0
- package/dist/components/renderer/ProgressBar.js.map +1 -1
- package/dist/form-elements/FormElementBarcodeScanner.js +2 -2
- package/dist/form-elements/FormElementBarcodeScanner.js.map +1 -1
- package/dist/hooks/useAuth.d.ts +3 -1
- package/dist/hooks/useAuth.js +3 -1
- package/dist/hooks/useAuth.js.map +1 -1
- package/dist/hooks/useBooleanState.d.ts +1 -0
- package/dist/hooks/useBooleanState.js +1 -0
- package/dist/hooks/useBooleanState.js.map +1 -1
- package/dist/hooks/useClickOutsideElement.d.ts +1 -0
- package/dist/hooks/useClickOutsideElement.js +1 -0
- package/dist/hooks/useClickOutsideElement.js.map +1 -1
- package/dist/hooks/useDrafts.d.ts +3 -1
- package/dist/hooks/useDrafts.js +3 -1
- package/dist/hooks/useDrafts.js.map +1 -1
- package/dist/hooks/useFormSubmissionAutoSaveState.d.ts +1 -0
- package/dist/hooks/useFormSubmissionAutoSaveState.js +1 -0
- package/dist/hooks/useFormSubmissionAutoSaveState.js.map +1 -1
- package/dist/hooks/useFormSubmissionState.d.ts +1 -0
- package/dist/hooks/useFormSubmissionState.js +1 -0
- package/dist/hooks/useFormSubmissionState.js.map +1 -1
- package/dist/hooks/useIsMounted.d.ts +1 -0
- package/dist/hooks/useIsMounted.js +1 -0
- package/dist/hooks/useIsMounted.js.map +1 -1
- package/dist/hooks/useIsOffline.d.ts +5 -0
- package/dist/hooks/useIsOffline.js +5 -0
- package/dist/hooks/useIsOffline.js.map +1 -1
- package/dist/hooks/useLoadDataState.d.ts +2 -0
- package/dist/hooks/useLoadDataState.js +2 -0
- package/dist/hooks/useLoadDataState.js.map +1 -1
- package/dist/hooks/useLogin.d.ts +4 -2
- package/dist/hooks/useLogin.js +1 -0
- package/dist/hooks/useLogin.js.map +1 -1
- package/dist/hooks/useLookupNotification.d.ts +6 -2
- package/dist/hooks/useLookupNotification.js +29 -3
- package/dist/hooks/useLookupNotification.js.map +1 -1
- package/dist/hooks/useNullableState.d.ts +2 -0
- package/dist/hooks/useNullableState.js +2 -0
- package/dist/hooks/useNullableState.js.map +1 -1
- package/dist/hooks/usePendingSubmissions.d.ts +9 -1
- package/dist/hooks/usePendingSubmissions.js +17 -14
- package/dist/hooks/usePendingSubmissions.js.map +1 -1
- package/dist/hooks/useSignUp.d.ts +5 -0
- package/dist/hooks/useSignUp.js +5 -0
- package/dist/hooks/useSignUp.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
@@ -1,5 +1,10 @@
|
|
1
1
|
import { LinearProgressProps } from '@mui/material';
|
2
2
|
import * as React from 'react';
|
3
|
+
/**
|
4
|
+
* @param props
|
5
|
+
* @returns
|
6
|
+
* @group Components
|
7
|
+
*/
|
3
8
|
declare const _default: React.MemoExoticComponent<({ progress, ...rest }: Omit<LinearProgressProps, "value" | "variant"> & {
|
4
9
|
progress: number;
|
5
10
|
}) => JSX.Element>;
|
@@ -3,5 +3,10 @@ import * as React from 'react';
|
|
3
3
|
const ProgressBar = ({ progress, ...rest }) => {
|
4
4
|
return React.createElement(LinearProgress, { ...rest, variant: "determinate", value: progress });
|
5
5
|
};
|
6
|
+
/**
|
7
|
+
* @param props
|
8
|
+
* @returns
|
9
|
+
* @group Components
|
10
|
+
*/
|
6
11
|
export default React.memo(ProgressBar);
|
7
12
|
//# sourceMappingURL=ProgressBar.js.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"ProgressBar.js","sourceRoot":"","sources":["../../../src/components/renderer/ProgressBar.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAuB,MAAM,eAAe,CAAA;AACnE,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,MAAM,WAAW,GAAG,CAAC,EACnB,QAAQ,EACR,GAAG,IAAI,EAGR,EAAE,EAAE;IACH,OAAO,oBAAC,cAAc,OAAK,IAAI,EAAE,OAAO,EAAC,aAAa,EAAC,KAAK,EAAE,QAAQ,GAAI,CAAA;AAC5E,CAAC,CAAA;AAED,eAAe,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA","sourcesContent":["import { LinearProgress, LinearProgressProps } from '@mui/material'\nimport * as React from 'react'\n\nconst ProgressBar = ({\n progress,\n ...rest\n}: Omit<LinearProgressProps, 'value' | 'variant'> & {\n progress: number\n}) => {\n return <LinearProgress {...rest} variant=\"determinate\" value={progress} />\n}\n\nexport default React.memo(ProgressBar)\n"]}
|
1
|
+
{"version":3,"file":"ProgressBar.js","sourceRoot":"","sources":["../../../src/components/renderer/ProgressBar.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAuB,MAAM,eAAe,CAAA;AACnE,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,MAAM,WAAW,GAAG,CAAC,EACnB,QAAQ,EACR,GAAG,IAAI,EAGR,EAAE,EAAE;IACH,OAAO,oBAAC,cAAc,OAAK,IAAI,EAAE,OAAO,EAAC,aAAa,EAAC,KAAK,EAAE,QAAQ,GAAI,CAAA;AAC5E,CAAC,CAAA;AAED;;;;GAIG;AACH,eAAe,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA","sourcesContent":["import { LinearProgress, LinearProgressProps } from '@mui/material'\nimport * as React from 'react'\n\nconst ProgressBar = ({\n progress,\n ...rest\n}: Omit<LinearProgressProps, 'value' | 'variant'> & {\n progress: number\n}) => {\n return <LinearProgress {...rest} variant=\"determinate\" value={progress} />\n}\n\n/**\n * @param props\n * @returns\n * @group Components\n */\nexport default React.memo(ProgressBar)\n"]}
|
@@ -16,12 +16,12 @@ const redLineHeightInPixels = 1;
|
|
16
16
|
function FormElementBarcodeScanner({ id, element, value, onChange, validationMessage, displayValidationMessage, isDirty, setIsDirty, }) {
|
17
17
|
const [isCameraOpen, startBarcodeScanner, stopBarcodeScanner] = useBooleanState(false);
|
18
18
|
const [error, setError] = React.useState(null);
|
19
|
-
const { onLookup } = useLookupNotification();
|
19
|
+
const { onLookup } = useLookupNotification(value);
|
20
20
|
const handleScan = React.useCallback((newValue) => {
|
21
21
|
setIsDirty();
|
22
22
|
onChange(element, newValue);
|
23
23
|
stopBarcodeScanner();
|
24
|
-
onLookup(
|
24
|
+
onLookup();
|
25
25
|
}, [element, onChange, onLookup, setIsDirty, stopBarcodeScanner]);
|
26
26
|
const openBarcodeScanner = React.useCallback(() => {
|
27
27
|
if (window.cordova) {
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"FormElementBarcodeScanner.js","sourceRoot":"","sources":["../../src/form-elements/FormElementBarcodeScanner.tsx"],"names":[],"mappings":"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","sourcesContent":["import * as React from 'react'\nimport clsx from 'clsx'\nimport jsQR from 'jsqr'\n\nimport OnLoading from '../components/renderer/OnLoading'\nimport CopyToClipboardButton from '../components/renderer/CopyToClipboardButton'\nimport quaggaReader from '../services/barcode-readers/quagger.js'\nimport useBooleanState from '../hooks/useBooleanState'\nimport LookupButton from '../components/renderer/LookupButton'\nimport { FormTypes } from '@oneblink/types'\nimport FormElementLabelContainer from '../components/renderer/FormElementLabelContainer'\nimport { Sentry } from '@oneblink/apps'\nimport useLookupNotification from '../hooks/useLookupNotification'\nimport { FormElementValueChangeHandler, IsDirtyProps } from '../types/form'\n\nconst MS_BETWEEN_IMAGE_PROCESSING = 10\nconst fadedSquareWidthInPixels = 200\nconst fadedSquareHeightInPixels = 150\nconst redLineHeightInPixels = 1\n\ntype Props = {\n id: string\n element: FormTypes.BarcodeScannerElement\n value: unknown | undefined\n onChange: FormElementValueChangeHandler<string>\n displayValidationMessage: boolean\n validationMessage: string | undefined\n} & IsDirtyProps\n\nfunction FormElementBarcodeScanner({\n id,\n element,\n value,\n onChange,\n validationMessage,\n displayValidationMessage,\n isDirty,\n setIsDirty,\n}: Props) {\n const [isCameraOpen, startBarcodeScanner, stopBarcodeScanner] =\n useBooleanState(false)\n const [error, setError] = React.useState<Error | null>(null)\n\n const { onLookup } = useLookupNotification()\n const handleScan = React.useCallback(\n (newValue: string | undefined) => {\n setIsDirty()\n onChange(element, newValue)\n stopBarcodeScanner()\n onLookup(newValue)\n },\n [element, onChange, onLookup, setIsDirty, stopBarcodeScanner],\n )\n\n const openBarcodeScanner = React.useCallback(() => {\n if (window.cordova) {\n setError(null)\n // @ts-expect-error ???\n window.cordova.plugins.barcodeScanner.scan(\n // @ts-expect-error ???\n (result) => {\n if (!result.cancelled) {\n handleScan(result.text)\n }\n },\n // @ts-expect-error ???\n (error) => {\n setError(\n new Error(\n `An error has occurred: \"${error}\". Please click \"Cancel\" below to try again. If the problem persists, please contact support.`,\n ),\n )\n },\n {\n showFlipCameraButton: true,\n showTorchButton: true,\n },\n )\n } else {\n startBarcodeScanner()\n }\n }, [handleScan, startBarcodeScanner])\n\n const text = typeof value === 'string' ? value : ''\n return (\n <div className=\"cypress-barcode-scanner-element\">\n <FormElementLabelContainer\n className=\"ob-barcode-scanner\"\n element={element}\n id={id}\n required={element.required}\n >\n {error && (\n <figure className=\"ob-figure\">\n <div className=\"figure-content has-text-centered\">\n <div>\n <h4 className=\"title is-4\">Whoops...</h4>\n <p>{error.message}</p>\n </div>\n </div>\n </figure>\n )}\n\n {isCameraOpen ? (\n <BarcodeScanner\n element={element}\n onScan={handleScan}\n onClose={stopBarcodeScanner}\n />\n ) : (\n <div>\n <div className=\"field has-addons\">\n <div className=\"control is-expanded has-icons-right\">\n <input\n type=\"text\"\n placeholder={element.placeholderValue}\n id={id}\n name={element.name}\n className=\"input ob-input cypress-barcode-scanner-control has-margin-bottom-8\"\n value={text}\n onChange={(e) =>\n onChange(element, e.target.value || undefined)\n }\n required={element.required}\n disabled={element.readOnly}\n onBlur={setIsDirty}\n />\n <span className=\"ob-input-icon icon is-small is-right\">\n <i className=\"material-icons is-size-5\">document_scanner</i>\n </span>\n </div>\n {!!element.readOnly && !!value && (\n <div className=\"control\">\n <CopyToClipboardButton\n className=\"button is-input-addon copy-button cypress-copy-to-clipboard-button\"\n text={text}\n />\n </div>\n )}\n <LookupButton\n isInputButton\n value={value}\n validationMessage={validationMessage}\n />\n </div>\n\n <button\n type=\"button\"\n className=\"button ob-button ob-button__open is-primary cypress-start-scan-barcode-button\"\n disabled={element.readOnly}\n onClick={openBarcodeScanner}\n >\n Scan Barcode\n </button>\n </div>\n )}\n\n {(isDirty || displayValidationMessage) && !!validationMessage && (\n <div role=\"alert\" className=\"has-margin-top-8\">\n <div className=\"has-text-danger ob-error__text cypress-validation-message\">\n {validationMessage}\n </div>\n </div>\n )}\n </FormElementLabelContainer>\n </div>\n )\n}\n\nexport default React.memo(FormElementBarcodeScanner)\n\ntype BarcodeScannerProps = {\n element: FormTypes.BarcodeScannerElement\n onScan: (barcode: string | undefined) => void\n onClose: () => void\n}\n\nfunction BarcodeScanner({ element, onScan, onClose }: BarcodeScannerProps) {\n const videoElementRef = React.useRef<HTMLVideoElement>(null)\n const figureElementRef = React.useRef<HTMLDivElement>(null)\n\n const [{ isLoading = false, selectedDeviceId, error }, setState] =\n React.useState<{\n isLoading: boolean\n selectedDeviceId: string | undefined\n error: Error | undefined\n }>({\n isLoading: true,\n selectedDeviceId: undefined,\n error: undefined,\n })\n const [camera, setCamera] = React.useState<HTML5Camera | null>(null)\n\n const setError = React.useCallback((error: Error) => {\n setState({\n error,\n isLoading: false,\n selectedDeviceId: undefined,\n })\n }, [])\n\n // Create timeout using $timeout outside of the scan function so\n // so that we can cancel it when navigating away from screen\n const scanImageForBarcode = React.useCallback(\n (\n videoElement: HTMLVideoElement,\n waitInMS: number,\n options: {\n sourceX: number\n sourceY: number\n sourceWidth: number\n sourceHeight: number\n },\n checkStop: () => boolean,\n ) => {\n const restrictedBarcodeTypes = element.restrictedBarcodeTypes || []\n // Using $timeout here instead of $interval as we dont know\n // exactly how long each processing of the image will take.\n setTimeout(async () => {\n if (checkStop()) return\n const canvasElement = document.createElement('canvas')\n\n canvasElement.width = options.sourceWidth\n canvasElement.height = options.sourceHeight\n\n const canvasContext = canvasElement.getContext('2d')\n if (canvasContext) {\n canvasContext.drawImage(\n videoElement,\n options.sourceX,\n options.sourceY,\n canvasElement.width,\n canvasElement.height,\n 0,\n 0,\n canvasElement.width,\n canvasElement.height,\n )\n\n if (\n !element.restrictBarcodeTypes ||\n (element.restrictedBarcodeTypes || []).indexOf('qr_reader') > -1\n ) {\n const imageData = canvasContext.getImageData(\n 0,\n 0,\n canvasElement.width,\n canvasElement.height,\n )\n\n const code = jsQR(\n imageData.data,\n imageData.width,\n imageData.height,\n {\n inversionAttempts: 'dontInvert',\n },\n )\n\n if (code) {\n return onScan(code.data)\n }\n }\n }\n\n if (\n !element.restrictBarcodeTypes ||\n !(\n restrictedBarcodeTypes.length === 1 &&\n restrictedBarcodeTypes[0] === 'qr_reader'\n )\n ) {\n const base64Image = canvasElement.toDataURL('image/png')\n const quaggaResult = await quaggaReader(\n base64Image,\n restrictedBarcodeTypes,\n )\n if (quaggaResult) {\n return onScan(quaggaResult)\n }\n }\n\n if (checkStop()) return\n\n scanImageForBarcode(\n videoElement,\n MS_BETWEEN_IMAGE_PROCESSING,\n options,\n checkStop,\n )\n }, waitInMS)\n },\n [element.restrictBarcodeTypes, element.restrictedBarcodeTypes, onScan],\n )\n\n const switchCamera = React.useCallback(() => {\n if (!camera) {\n return\n }\n\n // We will just be rotating between the available camera.\n const nextDeviceIndex =\n camera.availableDevices.findIndex(\n (mediaDeviceInfo) => mediaDeviceInfo.deviceId === camera.activeDeviceId,\n ) + 1\n const nextDevice =\n camera.availableDevices[nextDeviceIndex] || camera.availableDevices[0]\n setState({\n error: undefined,\n isLoading: true,\n selectedDeviceId: nextDevice.deviceId,\n })\n }, [camera])\n\n React.useEffect(() => {\n if (!videoElementRef.current) {\n return\n }\n\n const newCamera = new HTML5Camera(videoElementRef.current)\n setCamera(newCamera)\n\n return () => {\n newCamera.close()\n }\n }, [])\n\n React.useEffect(() => {\n if (\n !camera ||\n error ||\n // If attempting to open the device that is currently open,\n // we will not attempt to open again.\n (selectedDeviceId && camera.activeDeviceId === selectedDeviceId)\n ) {\n return\n }\n\n let ignore = false\n\n ;(async () => {\n try {\n const videoElement = videoElementRef.current\n const figureElement = figureElementRef.current\n if (!videoElement || !figureElement) {\n return\n }\n\n console.log('Opening camera with:', selectedDeviceId || 'UNKNOWN')\n await camera.open(selectedDeviceId)\n\n if (ignore) {\n return\n }\n\n setState({\n error: undefined,\n isLoading: false,\n selectedDeviceId,\n })\n\n // @ts-expect-error ???\n const fadedSquareElement: HTMLDivElement =\n figureElement.getElementsByClassName('ob-barcode-scanner__square')[0]\n // @ts-expect-error ???\n const redLineElement: HTMLDivElement =\n figureElement.getElementsByClassName('ob-barcode-scanner__line')[0]\n console.log('videoElement Width pixels', videoElement.clientWidth)\n console.log('videoElement Height pixels', videoElement.clientHeight)\n console.log('videoElement Width', videoElement.videoWidth)\n console.log('videoElement Height', videoElement.videoHeight)\n\n // Faded Square needs its values set in pixels\n const fadedSquareLeftInPixels =\n (videoElement.clientWidth - fadedSquareWidthInPixels) / 2\n console.log('fadedSquareLeftInPixels', fadedSquareLeftInPixels)\n const fadedSquareTopInPixels =\n (videoElement.clientHeight - fadedSquareHeightInPixels) / 2\n console.log('fadedSquareTopInPixels', fadedSquareTopInPixels)\n\n fadedSquareElement.style.borderBottom = `${fadedSquareTopInPixels}px`\n fadedSquareElement.style.borderTop = `${fadedSquareTopInPixels}px`\n fadedSquareElement.style.borderLeft = `${fadedSquareLeftInPixels}px`\n fadedSquareElement.style.borderRight = `${fadedSquareLeftInPixels}px`\n fadedSquareElement.style.borderColor = 'rgba(0, 0, 0, 0.25)'\n fadedSquareElement.style.borderStyle = 'solid'\n\n redLineElement.style.height = `${redLineHeightInPixels}px`\n redLineElement.style.top = `${\n (videoElement.clientHeight - redLineHeightInPixels) / 2\n }px`\n redLineElement.style.left = `${fadedSquareLeftInPixels}px`\n redLineElement.style.right = `${fadedSquareLeftInPixels}px`\n\n // Need to calculate the actual width, which is not in pixels\n const ratio = videoElement.videoWidth / videoElement.clientWidth\n console.log('pixel to video Ratio', ratio)\n\n const left = ratio * fadedSquareLeftInPixels\n console.log('left in video measurement', left)\n const top = ratio * fadedSquareTopInPixels\n console.log('top in video measurement', top)\n\n const fadedSquareWidth = fadedSquareWidthInPixels * ratio\n console.log('red square in video measurement', fadedSquareWidth)\n\n // Wait a little before scanning the first image\n // to prevent image processing staring before\n // camera is ready.\n scanImageForBarcode(\n videoElement,\n 250,\n {\n sourceX: left,\n sourceY: top,\n sourceWidth: fadedSquareWidth,\n sourceHeight: fadedSquareWidth,\n },\n () => ignore,\n )\n } catch (error) {\n if (ignore) {\n return\n }\n console.warn('Error while attempting to open camera', error)\n Sentry.captureException(error)\n switch ((error as Error).name) {\n case 'NotSupportedError': {\n setError(\n new Error(\n 'Your browser does not support accessing your camera. Please click \"Cancel\" below and type in the barcode value manually.',\n ),\n )\n break\n }\n case 'NotAllowedError': {\n setError(\n new Error(\n 'Cannot scan for barcodes without granting the application access to the camera. Please click \"Cancel\" below to try again.',\n ),\n )\n break\n }\n default: {\n setError(\n new Error(\n 'An unknown error has occurred, please click \"Cancel\" below to try again. If the problem persists, please contact support.',\n ),\n )\n }\n }\n }\n })()\n\n return () => {\n ignore = true\n }\n }, [camera, error, scanImageForBarcode, selectedDeviceId, setError])\n\n return (\n <div>\n <figure className=\"ob-figure\" ref={figureElementRef}>\n <div className=\"figure-content has-text-centered\">\n {isLoading && <OnLoading small />}\n\n {!!error && (\n <div>\n <h4 className=\"title is-4\">Whoops...</h4>\n <p>{error.message}</p>\n </div>\n )}\n\n <div\n className={clsx('is-relative', {\n 'is-hidden': isLoading || error,\n })}\n >\n <div className=\"ob-barcode-scanner__square\"></div>\n <div className=\"ob-barcode-scanner__line\"></div>\n <video\n ref={videoElementRef}\n autoPlay\n playsInline\n className=\"ob-barcode-scanner__video\"\n />\n </div>\n </div>\n </figure>\n\n <div className=\"buttons ob-buttons\">\n <button\n type=\"button\"\n className=\"button ob-button ob-button__cancel is-light cypress-cancel-scan-barcode-button\"\n onClick={onClose}\n >\n Cancel\n </button>\n {(camera?.availableDevices.length || 1) > 1 && (\n <button\n type=\"button\"\n className=\"button ob-button ob-button__switch-camera is-primary cypress-switch-camera-button\"\n onClick={switchCamera}\n >\n Switch Camera\n </button>\n )}\n </div>\n </div>\n )\n}\n\nclass HTML5Camera {\n availableDevices: MediaDeviceInfo[]\n htmlVideoElement: HTMLVideoElement\n mediaStream: MediaStream | undefined\n\n constructor(htmlVideoElement: HTMLVideoElement) {\n this.htmlVideoElement = htmlVideoElement\n this.availableDevices = []\n this.mediaStream = undefined\n }\n\n get activeDeviceId(): string | undefined {\n if (this.mediaStream) {\n const [activeMediaStreamTrack] = this.mediaStream.getTracks()\n return activeMediaStreamTrack?.getSettings()?.deviceId\n }\n }\n\n async open(deviceId?: string) {\n if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {\n const error = new Error()\n error.name = 'NotSupportedError'\n throw error\n }\n\n this.close()\n\n const constraints = {\n video: {\n facingMode: deviceId ? undefined : 'environment',\n deviceId: deviceId ? { exact: deviceId } : undefined,\n },\n }\n const mediaStream = await navigator.mediaDevices.getUserMedia(constraints)\n this.mediaStream = mediaStream\n this.htmlVideoElement.srcObject = mediaStream\n\n if (!this.availableDevices.length) {\n const availableDevices = await navigator.mediaDevices.enumerateDevices()\n this.availableDevices = availableDevices.filter(\n (mediaDeviceInfo) =>\n mediaDeviceInfo.kind === 'videoinput' && !!mediaDeviceInfo.deviceId,\n )\n }\n\n await new Promise((resolve) =>\n this.htmlVideoElement.addEventListener('canplay', resolve, {\n once: true,\n }),\n )\n }\n\n close() {\n if (this.mediaStream) {\n this.mediaStream.getTracks().forEach((track) => {\n track.stop()\n })\n this.mediaStream = undefined\n }\n }\n}\n"]}
|
1
|
+
{"version":3,"file":"FormElementBarcodeScanner.js","sourceRoot":"","sources":["../../src/form-elements/FormElementBarcodeScanner.tsx"],"names":[],"mappings":"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","sourcesContent":["import * as React from 'react'\nimport clsx from 'clsx'\nimport jsQR from 'jsqr'\n\nimport OnLoading from '../components/renderer/OnLoading'\nimport CopyToClipboardButton from '../components/renderer/CopyToClipboardButton'\nimport quaggaReader from '../services/barcode-readers/quagger.js'\nimport useBooleanState from '../hooks/useBooleanState'\nimport LookupButton from '../components/renderer/LookupButton'\nimport { FormTypes } from '@oneblink/types'\nimport FormElementLabelContainer from '../components/renderer/FormElementLabelContainer'\nimport { Sentry } from '@oneblink/apps'\nimport useLookupNotification from '../hooks/useLookupNotification'\nimport { FormElementValueChangeHandler, IsDirtyProps } from '../types/form'\n\nconst MS_BETWEEN_IMAGE_PROCESSING = 10\nconst fadedSquareWidthInPixels = 200\nconst fadedSquareHeightInPixels = 150\nconst redLineHeightInPixels = 1\n\ntype Props = {\n id: string\n element: FormTypes.BarcodeScannerElement\n value: unknown | undefined\n onChange: FormElementValueChangeHandler<string>\n displayValidationMessage: boolean\n validationMessage: string | undefined\n} & IsDirtyProps\n\nfunction FormElementBarcodeScanner({\n id,\n element,\n value,\n onChange,\n validationMessage,\n displayValidationMessage,\n isDirty,\n setIsDirty,\n}: Props) {\n const [isCameraOpen, startBarcodeScanner, stopBarcodeScanner] =\n useBooleanState(false)\n const [error, setError] = React.useState<Error | null>(null)\n\n const { onLookup } = useLookupNotification(value)\n const handleScan = React.useCallback(\n (newValue: string | undefined) => {\n setIsDirty()\n onChange(element, newValue)\n stopBarcodeScanner()\n onLookup()\n },\n [element, onChange, onLookup, setIsDirty, stopBarcodeScanner],\n )\n\n const openBarcodeScanner = React.useCallback(() => {\n if (window.cordova) {\n setError(null)\n // @ts-expect-error ???\n window.cordova.plugins.barcodeScanner.scan(\n // @ts-expect-error ???\n (result) => {\n if (!result.cancelled) {\n handleScan(result.text)\n }\n },\n // @ts-expect-error ???\n (error) => {\n setError(\n new Error(\n `An error has occurred: \"${error}\". Please click \"Cancel\" below to try again. If the problem persists, please contact support.`,\n ),\n )\n },\n {\n showFlipCameraButton: true,\n showTorchButton: true,\n },\n )\n } else {\n startBarcodeScanner()\n }\n }, [handleScan, startBarcodeScanner])\n\n const text = typeof value === 'string' ? value : ''\n return (\n <div className=\"cypress-barcode-scanner-element\">\n <FormElementLabelContainer\n className=\"ob-barcode-scanner\"\n element={element}\n id={id}\n required={element.required}\n >\n {error && (\n <figure className=\"ob-figure\">\n <div className=\"figure-content has-text-centered\">\n <div>\n <h4 className=\"title is-4\">Whoops...</h4>\n <p>{error.message}</p>\n </div>\n </div>\n </figure>\n )}\n\n {isCameraOpen ? (\n <BarcodeScanner\n element={element}\n onScan={handleScan}\n onClose={stopBarcodeScanner}\n />\n ) : (\n <div>\n <div className=\"field has-addons\">\n <div className=\"control is-expanded has-icons-right\">\n <input\n type=\"text\"\n placeholder={element.placeholderValue}\n id={id}\n name={element.name}\n className=\"input ob-input cypress-barcode-scanner-control has-margin-bottom-8\"\n value={text}\n onChange={(e) =>\n onChange(element, e.target.value || undefined)\n }\n required={element.required}\n disabled={element.readOnly}\n onBlur={setIsDirty}\n />\n <span className=\"ob-input-icon icon is-small is-right\">\n <i className=\"material-icons is-size-5\">document_scanner</i>\n </span>\n </div>\n {!!element.readOnly && !!value && (\n <div className=\"control\">\n <CopyToClipboardButton\n className=\"button is-input-addon copy-button cypress-copy-to-clipboard-button\"\n text={text}\n />\n </div>\n )}\n <LookupButton\n isInputButton\n value={value}\n validationMessage={validationMessage}\n />\n </div>\n\n <button\n type=\"button\"\n className=\"button ob-button ob-button__open is-primary cypress-start-scan-barcode-button\"\n disabled={element.readOnly}\n onClick={openBarcodeScanner}\n >\n Scan Barcode\n </button>\n </div>\n )}\n\n {(isDirty || displayValidationMessage) && !!validationMessage && (\n <div role=\"alert\" className=\"has-margin-top-8\">\n <div className=\"has-text-danger ob-error__text cypress-validation-message\">\n {validationMessage}\n </div>\n </div>\n )}\n </FormElementLabelContainer>\n </div>\n )\n}\n\nexport default React.memo(FormElementBarcodeScanner)\n\ntype BarcodeScannerProps = {\n element: FormTypes.BarcodeScannerElement\n onScan: (barcode: string | undefined) => void\n onClose: () => void\n}\n\nfunction BarcodeScanner({ element, onScan, onClose }: BarcodeScannerProps) {\n const videoElementRef = React.useRef<HTMLVideoElement>(null)\n const figureElementRef = React.useRef<HTMLDivElement>(null)\n\n const [{ isLoading = false, selectedDeviceId, error }, setState] =\n React.useState<{\n isLoading: boolean\n selectedDeviceId: string | undefined\n error: Error | undefined\n }>({\n isLoading: true,\n selectedDeviceId: undefined,\n error: undefined,\n })\n const [camera, setCamera] = React.useState<HTML5Camera | null>(null)\n\n const setError = React.useCallback((error: Error) => {\n setState({\n error,\n isLoading: false,\n selectedDeviceId: undefined,\n })\n }, [])\n\n // Create timeout using $timeout outside of the scan function so\n // so that we can cancel it when navigating away from screen\n const scanImageForBarcode = React.useCallback(\n (\n videoElement: HTMLVideoElement,\n waitInMS: number,\n options: {\n sourceX: number\n sourceY: number\n sourceWidth: number\n sourceHeight: number\n },\n checkStop: () => boolean,\n ) => {\n const restrictedBarcodeTypes = element.restrictedBarcodeTypes || []\n // Using $timeout here instead of $interval as we dont know\n // exactly how long each processing of the image will take.\n setTimeout(async () => {\n if (checkStop()) return\n const canvasElement = document.createElement('canvas')\n\n canvasElement.width = options.sourceWidth\n canvasElement.height = options.sourceHeight\n\n const canvasContext = canvasElement.getContext('2d')\n if (canvasContext) {\n canvasContext.drawImage(\n videoElement,\n options.sourceX,\n options.sourceY,\n canvasElement.width,\n canvasElement.height,\n 0,\n 0,\n canvasElement.width,\n canvasElement.height,\n )\n\n if (\n !element.restrictBarcodeTypes ||\n (element.restrictedBarcodeTypes || []).indexOf('qr_reader') > -1\n ) {\n const imageData = canvasContext.getImageData(\n 0,\n 0,\n canvasElement.width,\n canvasElement.height,\n )\n\n const code = jsQR(\n imageData.data,\n imageData.width,\n imageData.height,\n {\n inversionAttempts: 'dontInvert',\n },\n )\n\n if (code) {\n return onScan(code.data)\n }\n }\n }\n\n if (\n !element.restrictBarcodeTypes ||\n !(\n restrictedBarcodeTypes.length === 1 &&\n restrictedBarcodeTypes[0] === 'qr_reader'\n )\n ) {\n const base64Image = canvasElement.toDataURL('image/png')\n const quaggaResult = await quaggaReader(\n base64Image,\n restrictedBarcodeTypes,\n )\n if (quaggaResult) {\n return onScan(quaggaResult)\n }\n }\n\n if (checkStop()) return\n\n scanImageForBarcode(\n videoElement,\n MS_BETWEEN_IMAGE_PROCESSING,\n options,\n checkStop,\n )\n }, waitInMS)\n },\n [element.restrictBarcodeTypes, element.restrictedBarcodeTypes, onScan],\n )\n\n const switchCamera = React.useCallback(() => {\n if (!camera) {\n return\n }\n\n // We will just be rotating between the available camera.\n const nextDeviceIndex =\n camera.availableDevices.findIndex(\n (mediaDeviceInfo) => mediaDeviceInfo.deviceId === camera.activeDeviceId,\n ) + 1\n const nextDevice =\n camera.availableDevices[nextDeviceIndex] || camera.availableDevices[0]\n setState({\n error: undefined,\n isLoading: true,\n selectedDeviceId: nextDevice.deviceId,\n })\n }, [camera])\n\n React.useEffect(() => {\n if (!videoElementRef.current) {\n return\n }\n\n const newCamera = new HTML5Camera(videoElementRef.current)\n setCamera(newCamera)\n\n return () => {\n newCamera.close()\n }\n }, [])\n\n React.useEffect(() => {\n if (\n !camera ||\n error ||\n // If attempting to open the device that is currently open,\n // we will not attempt to open again.\n (selectedDeviceId && camera.activeDeviceId === selectedDeviceId)\n ) {\n return\n }\n\n let ignore = false\n\n ;(async () => {\n try {\n const videoElement = videoElementRef.current\n const figureElement = figureElementRef.current\n if (!videoElement || !figureElement) {\n return\n }\n\n console.log('Opening camera with:', selectedDeviceId || 'UNKNOWN')\n await camera.open(selectedDeviceId)\n\n if (ignore) {\n return\n }\n\n setState({\n error: undefined,\n isLoading: false,\n selectedDeviceId,\n })\n\n // @ts-expect-error ???\n const fadedSquareElement: HTMLDivElement =\n figureElement.getElementsByClassName('ob-barcode-scanner__square')[0]\n // @ts-expect-error ???\n const redLineElement: HTMLDivElement =\n figureElement.getElementsByClassName('ob-barcode-scanner__line')[0]\n console.log('videoElement Width pixels', videoElement.clientWidth)\n console.log('videoElement Height pixels', videoElement.clientHeight)\n console.log('videoElement Width', videoElement.videoWidth)\n console.log('videoElement Height', videoElement.videoHeight)\n\n // Faded Square needs its values set in pixels\n const fadedSquareLeftInPixels =\n (videoElement.clientWidth - fadedSquareWidthInPixels) / 2\n console.log('fadedSquareLeftInPixels', fadedSquareLeftInPixels)\n const fadedSquareTopInPixels =\n (videoElement.clientHeight - fadedSquareHeightInPixels) / 2\n console.log('fadedSquareTopInPixels', fadedSquareTopInPixels)\n\n fadedSquareElement.style.borderBottom = `${fadedSquareTopInPixels}px`\n fadedSquareElement.style.borderTop = `${fadedSquareTopInPixels}px`\n fadedSquareElement.style.borderLeft = `${fadedSquareLeftInPixels}px`\n fadedSquareElement.style.borderRight = `${fadedSquareLeftInPixels}px`\n fadedSquareElement.style.borderColor = 'rgba(0, 0, 0, 0.25)'\n fadedSquareElement.style.borderStyle = 'solid'\n\n redLineElement.style.height = `${redLineHeightInPixels}px`\n redLineElement.style.top = `${\n (videoElement.clientHeight - redLineHeightInPixels) / 2\n }px`\n redLineElement.style.left = `${fadedSquareLeftInPixels}px`\n redLineElement.style.right = `${fadedSquareLeftInPixels}px`\n\n // Need to calculate the actual width, which is not in pixels\n const ratio = videoElement.videoWidth / videoElement.clientWidth\n console.log('pixel to video Ratio', ratio)\n\n const left = ratio * fadedSquareLeftInPixels\n console.log('left in video measurement', left)\n const top = ratio * fadedSquareTopInPixels\n console.log('top in video measurement', top)\n\n const fadedSquareWidth = fadedSquareWidthInPixels * ratio\n console.log('red square in video measurement', fadedSquareWidth)\n\n // Wait a little before scanning the first image\n // to prevent image processing staring before\n // camera is ready.\n scanImageForBarcode(\n videoElement,\n 250,\n {\n sourceX: left,\n sourceY: top,\n sourceWidth: fadedSquareWidth,\n sourceHeight: fadedSquareWidth,\n },\n () => ignore,\n )\n } catch (error) {\n if (ignore) {\n return\n }\n console.warn('Error while attempting to open camera', error)\n Sentry.captureException(error)\n switch ((error as Error).name) {\n case 'NotSupportedError': {\n setError(\n new Error(\n 'Your browser does not support accessing your camera. Please click \"Cancel\" below and type in the barcode value manually.',\n ),\n )\n break\n }\n case 'NotAllowedError': {\n setError(\n new Error(\n 'Cannot scan for barcodes without granting the application access to the camera. Please click \"Cancel\" below to try again.',\n ),\n )\n break\n }\n default: {\n setError(\n new Error(\n 'An unknown error has occurred, please click \"Cancel\" below to try again. If the problem persists, please contact support.',\n ),\n )\n }\n }\n }\n })()\n\n return () => {\n ignore = true\n }\n }, [camera, error, scanImageForBarcode, selectedDeviceId, setError])\n\n return (\n <div>\n <figure className=\"ob-figure\" ref={figureElementRef}>\n <div className=\"figure-content has-text-centered\">\n {isLoading && <OnLoading small />}\n\n {!!error && (\n <div>\n <h4 className=\"title is-4\">Whoops...</h4>\n <p>{error.message}</p>\n </div>\n )}\n\n <div\n className={clsx('is-relative', {\n 'is-hidden': isLoading || error,\n })}\n >\n <div className=\"ob-barcode-scanner__square\"></div>\n <div className=\"ob-barcode-scanner__line\"></div>\n <video\n ref={videoElementRef}\n autoPlay\n playsInline\n className=\"ob-barcode-scanner__video\"\n />\n </div>\n </div>\n </figure>\n\n <div className=\"buttons ob-buttons\">\n <button\n type=\"button\"\n className=\"button ob-button ob-button__cancel is-light cypress-cancel-scan-barcode-button\"\n onClick={onClose}\n >\n Cancel\n </button>\n {(camera?.availableDevices.length || 1) > 1 && (\n <button\n type=\"button\"\n className=\"button ob-button ob-button__switch-camera is-primary cypress-switch-camera-button\"\n onClick={switchCamera}\n >\n Switch Camera\n </button>\n )}\n </div>\n </div>\n )\n}\n\nclass HTML5Camera {\n availableDevices: MediaDeviceInfo[]\n htmlVideoElement: HTMLVideoElement\n mediaStream: MediaStream | undefined\n\n constructor(htmlVideoElement: HTMLVideoElement) {\n this.htmlVideoElement = htmlVideoElement\n this.availableDevices = []\n this.mediaStream = undefined\n }\n\n get activeDeviceId(): string | undefined {\n if (this.mediaStream) {\n const [activeMediaStreamTrack] = this.mediaStream.getTracks()\n return activeMediaStreamTrack?.getSettings()?.deviceId\n }\n }\n\n async open(deviceId?: string) {\n if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {\n const error = new Error()\n error.name = 'NotSupportedError'\n throw error\n }\n\n this.close()\n\n const constraints = {\n video: {\n facingMode: deviceId ? undefined : 'environment',\n deviceId: deviceId ? { exact: deviceId } : undefined,\n },\n }\n const mediaStream = await navigator.mediaDevices.getUserMedia(constraints)\n this.mediaStream = mediaStream\n this.htmlVideoElement.srcObject = mediaStream\n\n if (!this.availableDevices.length) {\n const availableDevices = await navigator.mediaDevices.enumerateDevices()\n this.availableDevices = availableDevices.filter(\n (mediaDeviceInfo) =>\n mediaDeviceInfo.kind === 'videoinput' && !!mediaDeviceInfo.deviceId,\n )\n }\n\n await new Promise((resolve) =>\n this.htmlVideoElement.addEventListener('canplay', resolve, {\n once: true,\n }),\n )\n }\n\n close() {\n if (this.mediaStream) {\n this.mediaStream.getTracks().forEach((track) => {\n track.stop()\n })\n this.mediaStream = undefined\n }\n }\n}\n"]}
|
package/dist/hooks/useAuth.d.ts
CHANGED
@@ -29,7 +29,7 @@ export type AuthContextValue = {
|
|
29
29
|
*
|
30
30
|
* ```jsx
|
31
31
|
* import * as React from 'react'
|
32
|
-
* import { AuthContextProvider } from '@oneblink/apps-react'
|
32
|
+
* import { AuthContextProvider, useAuth } from '@oneblink/apps-react'
|
33
33
|
*
|
34
34
|
* function Component() {
|
35
35
|
* const auth = useAuth()
|
@@ -52,6 +52,7 @@ export type AuthContextValue = {
|
|
52
52
|
*
|
53
53
|
* @param props
|
54
54
|
* @returns
|
55
|
+
* @group Components
|
55
56
|
*/
|
56
57
|
export declare function AuthContextProvider({ children, formsKeyToken, userToken, }: {
|
57
58
|
/** Your application components */
|
@@ -84,5 +85,6 @@ export declare function AuthContextProvider({ children, formsKeyToken, userToken
|
|
84
85
|
* ```
|
85
86
|
*
|
86
87
|
* @returns
|
88
|
+
* @group Hooks
|
87
89
|
*/
|
88
90
|
export default function useAuth(): AuthContextValue;
|
package/dist/hooks/useAuth.js
CHANGED
@@ -16,7 +16,7 @@ const AuthContext = React.createContext({
|
|
16
16
|
*
|
17
17
|
* ```jsx
|
18
18
|
* import * as React from 'react'
|
19
|
-
* import { AuthContextProvider } from '@oneblink/apps-react'
|
19
|
+
* import { AuthContextProvider, useAuth } from '@oneblink/apps-react'
|
20
20
|
*
|
21
21
|
* function Component() {
|
22
22
|
* const auth = useAuth()
|
@@ -39,6 +39,7 @@ const AuthContext = React.createContext({
|
|
39
39
|
*
|
40
40
|
* @param props
|
41
41
|
* @returns
|
42
|
+
* @group Components
|
42
43
|
*/
|
43
44
|
export function AuthContextProvider({ children, formsKeyToken, userToken, }) {
|
44
45
|
const [value, setValue] = React.useState(() => {
|
@@ -88,6 +89,7 @@ export function AuthContextProvider({ children, formsKeyToken, userToken, }) {
|
|
88
89
|
* ```
|
89
90
|
*
|
90
91
|
* @returns
|
92
|
+
* @group Hooks
|
91
93
|
*/
|
92
94
|
export default function useAuth() {
|
93
95
|
return React.useContext(AuthContext);
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"useAuth.js","sourceRoot":"","sources":["../../src/hooks/useAuth.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAuB5C,MAAM,WAAW,GAAG,KAAK,CAAC,aAAa,CAAmB;IACxD,UAAU,EAAE,KAAK;IACjB,WAAW,EAAE,IAAI;IACjB,gBAAgB,EAAE,SAAS;IAC3B,eAAe,EAAE,KAAK;CACvB,CAAC,CAAA;AACF
|
1
|
+
{"version":3,"file":"useAuth.js","sourceRoot":"","sources":["../../src/hooks/useAuth.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAuB5C,MAAM,WAAW,GAAG,KAAK,CAAC,aAAa,CAAmB;IACxD,UAAU,EAAE,KAAK;IACjB,WAAW,EAAE,IAAI;IACjB,gBAAgB,EAAE,SAAS;IAC3B,eAAe,EAAE,KAAK;CACvB,CAAC,CAAA;AACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,MAAM,UAAU,mBAAmB,CAAC,EAClC,QAAQ,EACR,aAAa,EACb,SAAS,GAcV;IACC,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,GAAG,EAAE;QAC5C,WAAW,CAAC,gBAAgB,CAAC,aAAa,CAAC,CAAA;QAC3C,WAAW,CAAC,YAAY,CAAC,SAAS,CAAC,CAAA;QACnC,OAAO;YACL,UAAU,EAAE,WAAW,CAAC,UAAU,EAAE;YACpC,WAAW,EAAE,WAAW,CAAC,cAAc,EAAE;YACzC,gBAAgB,EAAE,WAAW,CAAC,mBAAmB,EAAE;YACnD,eAAe,EAAE,CAAC,CAAC,aAAa;SACjC,CAAA;IACH,CAAC,CAAC,CAAA;IAEF,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACnB,WAAW,CAAC,gBAAgB,CAAC,aAAa,CAAC,CAAA;QAC3C,QAAQ,CAAC,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;YAC1B,GAAG,YAAY;YACf,eAAe,EAAE,CAAC,CAAC,aAAa;SACjC,CAAC,CAAC,CAAA;IACL,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,CAAA;IAEnB,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACnB,WAAW,CAAC,YAAY,CAAC,SAAS,CAAC,CAAA;IACrC,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAA;IAEf,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACnB,OAAO,WAAW,CAAC,oBAAoB,CAAC,GAAG,EAAE,CAC3C,QAAQ,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;YACrB,GAAG,OAAO;YACV,UAAU,EAAE,WAAW,CAAC,UAAU,EAAE;YACpC,WAAW,EAAE,WAAW,CAAC,cAAc,EAAE;YACzC,gBAAgB,EAAE,WAAW,CAAC,mBAAmB,EAAE;SACpD,CAAC,CAAC,CACJ,CAAA;IACH,CAAC,EAAE,EAAE,CAAC,CAAA;IAEN,OAAO,oBAAC,WAAW,CAAC,QAAQ,IAAC,KAAK,EAAE,KAAK,IAAG,QAAQ,CAAwB,CAAA;AAC9E,CAAC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,CAAC,OAAO,UAAU,OAAO;IAC7B,OAAO,KAAK,CAAC,UAAU,CAAC,WAAW,CAAC,CAAA;AACtC,CAAC","sourcesContent":["import * as React from 'react'\nimport { authService } from '@oneblink/apps'\nimport { UserProfile } from '@oneblink/types/typescript/misc'\n\nexport type AuthContextValue = {\n /** `true` if the current user is logged in */\n isLoggedIn: boolean\n /**\n * See\n * [auth-service.getUserProfile()](https://oneblink.github.io/apps/modules/authService.html#getUserProfile)\n */\n userProfile: UserProfile | null\n /**\n * See\n * [auth-service.getUserFriendlyName()](https://oneblink.github.io/apps/modules/authService.html#getUserFriendlyName)\n */\n userFriendlyName: string | undefined\n /**\n * `true` if [`<AuthContextProvider />`](#AuthContextProvider) was passed the\n * `formsKeyToken` prop\n */\n isUsingFormsKey: boolean\n}\n\nconst AuthContext = React.createContext<AuthContextValue>({\n isLoggedIn: false,\n userProfile: null,\n userFriendlyName: undefined,\n isUsingFormsKey: false,\n})\n/**\n * `<AuthContextProvider />` is a React Component that provides the context for\n * the `useAuth()` hook to be used by components further down your component\n * tree. **It should only be included in your component tree once and ideally at\n * the root of the application.**\n *\n * #### Example\n *\n * ```jsx\n * import * as React from 'react'\n * import { AuthContextProvider, useAuth } from '@oneblink/apps-react'\n *\n * function Component() {\n * const auth = useAuth()\n * // use auth here\n * }\n *\n * function App() {\n * return (\n * <AuthContextProvider>\n * <Component />\n * </AuthContextProvider>\n * )\n * }\n *\n * const root = document.getElementById('root')\n * if (root) {\n * ReactDOM.render(<App />, root)\n * }\n * ```\n *\n * @param props\n * @returns\n * @group Components\n */\nexport function AuthContextProvider({\n children,\n formsKeyToken,\n userToken,\n}: {\n /** Your application components */\n children: React.ReactNode\n /**\n * A Forms Key token being used to make requests to the OneBlink API on behalf\n * of the user\n */\n formsKeyToken?: string\n /**\n * An encrypted user token that will be used included in the submission on\n * behalf of the user\n */\n userToken?: string\n}) {\n const [value, setValue] = React.useState(() => {\n authService.setFormsKeyToken(formsKeyToken)\n authService.setUserToken(userToken)\n return {\n isLoggedIn: authService.isLoggedIn(),\n userProfile: authService.getUserProfile(),\n userFriendlyName: authService.getUserFriendlyName(),\n isUsingFormsKey: !!formsKeyToken,\n }\n })\n\n React.useEffect(() => {\n authService.setFormsKeyToken(formsKeyToken)\n setValue((currentValue) => ({\n ...currentValue,\n isUsingFormsKey: !!formsKeyToken,\n }))\n }, [formsKeyToken])\n\n React.useEffect(() => {\n authService.setUserToken(userToken)\n }, [userToken])\n\n React.useEffect(() => {\n return authService.registerAuthListener(() =>\n setValue((current) => ({\n ...current,\n isLoggedIn: authService.isLoggedIn(),\n userProfile: authService.getUserProfile(),\n userFriendlyName: authService.getUserFriendlyName(),\n })),\n )\n }, [])\n\n return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>\n}\n\n/**\n * A React hook for containing state associated the current user. **This hook\n * requires [`<AuthContextProvider />`](./AuthContextProvider.html) to be\n * present in your component tree.**\n *\n * Example\n *\n * ```js\n * import { useAuth } from '@oneblink/apps-react'\n *\n * function Component() {\n * const { isLoggedIn, userProfile, userFriendlyName, isUsingFormsKey } =\n * useAuth()\n * }\n * ```\n *\n * @returns\n * @group Hooks\n */\nexport default function useAuth() {\n return React.useContext(AuthContext)\n}\n"]}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"useBooleanState.js","sourceRoot":"","sources":["../../src/hooks/useBooleanState.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B
|
1
|
+
{"version":3,"file":"useBooleanState.js","sourceRoot":"","sources":["../../src/hooks/useBooleanState.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,MAAM,CAAC,OAAO,UAAU,eAAe,CACrC,YAAqB;IAOrB,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAA;IACtD,MAAM,MAAM,GAAG,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAA;IAC1D,MAAM,OAAO,GAAG,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC,CAAA;IAC5D,MAAM,MAAM,GAAG,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC,CAAA;IAC3E,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,CAAA;AACzC,CAAC","sourcesContent":["import * as React from 'react'\n\n/**\n * This function is a react hook for boolean state that comes with\n * `useCallback`s for 'turning on', 'turning off' and toggling the state.\n *\n * ## Return\n *\n * The return type of `useBooleanState(true)` is an array where:\n *\n * - The first item is a `boolean` (the state).\n * - The second item is `() => void` (a function that sets the state to true).\n * - The third item is `() => void` (a function that sets the state to false).\n * - The fourth item is `() => void` (a function that toggles the state to the\n * opposite of what it currently is).\n *\n * As such, the items in the array can be destructured and named whatever you\n * like:\n *\n * ```js\n * import { useBooleanState } from '@oneblink/apps-react'\n *\n * const [dialogIsOpen, openDialog, closeDialog, toggleDialog] =\n * useBooleanState(true)\n * ```\n *\n * These properties can then be used like:\n *\n * ```js\n * openDialog()\n * closeDialog()\n * toggleDialog()\n * ```\n *\n * @param defaultValue\n * @returns\n * @group Hooks\n */\nexport default function useBooleanState(\n defaultValue: boolean,\n): [\n state: boolean,\n setTrue: () => void,\n setFalse: () => void,\n toggle: () => void,\n] {\n const [state, setState] = React.useState(defaultValue)\n const turnOn = React.useCallback(() => setState(true), [])\n const turnOff = React.useCallback(() => setState(false), [])\n const toggle = React.useCallback(() => setState((current) => !current), [])\n return [state, turnOn, turnOff, toggle]\n}\n"]}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"useClickOutsideElement.js","sourceRoot":"","sources":["../../src/hooks/useClickOutsideElement.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B
|
1
|
+
{"version":3,"file":"useClickOutsideElement.js","sourceRoot":"","sources":["../../src/hooks/useClickOutsideElement.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,MAAM,CAAC,OAAO,UAAU,sBAAsB,CAC5C,GAAoC,EACpC,QAAoB;IAEpB,MAAM,kBAAkB,GAAG,KAAK,CAAC,WAAW,CAC1C,CAAC,KAAY,EAAE,EAAE;QACf,IAAI,GAAG,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAc,CAAC,EAAE;YAC9D,QAAQ,EAAE,CAAA;SACX;IACH,CAAC,EACD,CAAC,QAAQ,EAAE,GAAG,CAAC,CAChB,CAAA;IACD,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACnB,QAAQ,CAAC,gBAAgB,CAAC,WAAW,EAAE,kBAAkB,CAAC,CAAA;QAC1D,OAAO,GAAG,EAAE;YACV,QAAQ,CAAC,mBAAmB,CAAC,WAAW,EAAE,kBAAkB,CAAC,CAAA;QAC/D,CAAC,CAAA;IACH,CAAC,EAAE,CAAC,kBAAkB,CAAC,CAAC,CAAA;AAC1B,CAAC","sourcesContent":["import * as React from 'react'\n\n/**\n * This function is a react hook for watching for click events outside of a\n * particular element. The hook will add and remove its own `eventListener`.\n *\n * - For performance reasons, it is important to pass a memoised function as the\n * callback argument, eg:\n *\n * ```js\n * React.useCallback(() => {}, [])\n * ```\n *\n * ## Example\n *\n * ```js\n * import * as React from 'react'\n * import { useClickOutsideElement } from '@oneblink/apps-react'\n *\n * const MyComponent = () => {\n * const narrowDivRef = React.useRef(null)\n * useClickOutsideElement(\n * narrowDivRef,\n * React.useCallback(() => {\n * console.log('Wide Div was clicked outside of narrow div...')\n * }, []),\n * )\n *\n * return (\n * <div className=\"wide-div\">\n * <div ref={narrowDivRef} className=\"narrow-div\"></div>\n * </div>\n * )\n * }\n *\n * export default MyComponent\n * ```\n *\n * @param ref\n * @param callback\n * @group Hooks\n */\nexport default function useClickOutsideElement(\n ref: { current: HTMLElement | null },\n callback: () => void,\n) {\n const handleClickOutside = React.useCallback(\n (event: Event) => {\n if (ref.current && !ref.current.contains(event.target as Node)) {\n callback()\n }\n },\n [callback, ref],\n )\n React.useEffect(() => {\n document.addEventListener('mousedown', handleClickOutside)\n return () => {\n document.removeEventListener('mousedown', handleClickOutside)\n }\n }, [handleClickOutside])\n}\n"]}
|
@@ -33,7 +33,7 @@ export type DraftsContextValue = {
|
|
33
33
|
*
|
34
34
|
* ```jsx
|
35
35
|
* import * as React from 'react'
|
36
|
-
* import { DraftsContextProvider } from '@oneblink/apps-react'
|
36
|
+
* import { DraftsContextProvider, useDrafts } from '@oneblink/apps-react'
|
37
37
|
*
|
38
38
|
* function Component() {
|
39
39
|
* const draftsContext = useDrafts()
|
@@ -56,6 +56,7 @@ export type DraftsContextValue = {
|
|
56
56
|
*
|
57
57
|
* @param props
|
58
58
|
* @returns
|
59
|
+
* @group Components
|
59
60
|
*/
|
60
61
|
export declare function DraftsContextProvider({
|
61
62
|
/** The identifier for the forms app associated with the user's drafts */
|
@@ -76,5 +77,6 @@ children, }: {
|
|
76
77
|
* outside of the `<DraftsContextProvider />` component.
|
77
78
|
*
|
78
79
|
* @returns
|
80
|
+
* @group Hooks
|
79
81
|
*/
|
80
82
|
export default function useDrafts(): DraftsContextValue;
|
package/dist/hooks/useDrafts.js
CHANGED
@@ -23,7 +23,7 @@ const DraftsContext = React.createContext(undefined);
|
|
23
23
|
*
|
24
24
|
* ```jsx
|
25
25
|
* import * as React from 'react'
|
26
|
-
* import { DraftsContextProvider } from '@oneblink/apps-react'
|
26
|
+
* import { DraftsContextProvider, useDrafts } from '@oneblink/apps-react'
|
27
27
|
*
|
28
28
|
* function Component() {
|
29
29
|
* const draftsContext = useDrafts()
|
@@ -46,6 +46,7 @@ const DraftsContext = React.createContext(undefined);
|
|
46
46
|
*
|
47
47
|
* @param props
|
48
48
|
* @returns
|
49
|
+
* @group Components
|
49
50
|
*/
|
50
51
|
export function DraftsContextProvider({
|
51
52
|
/** The identifier for the forms app associated with the user's drafts */
|
@@ -191,6 +192,7 @@ children, }) {
|
|
191
192
|
* outside of the `<DraftsContextProvider />` component.
|
192
193
|
*
|
193
194
|
* @returns
|
195
|
+
* @group Hooks
|
194
196
|
*/
|
195
197
|
export default function useDrafts() {
|
196
198
|
const value = React.useContext(DraftsContext);
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"useDrafts.js","sourceRoot":"","sources":["../../src/hooks/useDrafts.tsx"],"names":[],"mappings":"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","sourcesContent":["import * as React from 'react'\nimport { draftService, submissionService } from '@oneblink/apps'\nimport { SubmissionTypes } from '@oneblink/types'\nimport useAuth from './useAuth'\nimport useIsMounted from './useIsMounted'\nimport useIsOffline from './useIsOffline'\n\n/** The value returned from `useDrafts()` hook */\nexport type DraftsContextValue = {\n /** `true` drafts are currently loading. */\n isLoading: boolean\n /** An Error object if loading drafts fails */\n loadError: Error | null\n /** The incomplete submissions that were saved for later */\n drafts: SubmissionTypes.FormsAppDraft[]\n /** A function to trigger loading of the drafts */\n reloadDrafts: () => unknown\n /** A function to clear Error object from loading drafts */\n clearLoadError: () => void\n /** `true` drafts are syncing with other devices */\n isSyncing: boolean\n /** A function to trigger syncing of the drafts */\n syncDrafts: () => unknown\n /** An Error object if syncing drafts fails */\n syncError: Error | null\n /** A function to clear Error object from syncing drafts */\n clearSyncError: () => void\n /** A function to remove a draft */\n deleteDraft: (draftId: string) => Promise<void>\n}\n\nconst defaultLoadState = {\n isLoading: false,\n loadError: null,\n drafts: [],\n}\n\nconst defaultSyncState = {\n isSyncing: false,\n syncError: null,\n}\n\nconst DraftsContext = React.createContext<DraftsContextValue | undefined>(\n undefined,\n)\n\n/**\n * React Component that provides the context for the `useDrafts()` hook to be\n * used by components further down your component tree. **It should only be\n * included in your component tree once and ideally at the root of the\n * application.**\n *\n * #### Example\n *\n * ```jsx\n * import * as React from 'react'\n * import { DraftsContextProvider } from '@oneblink/apps-react'\n *\n * function Component() {\n * const draftsContext = useDrafts()\n * // use drafts here\n * }\n *\n * function App() {\n * return (\n * <DraftsContextProvider>\n * <Component />\n * </DraftsContextProvider>\n * )\n * }\n *\n * const root = document.getElementById('root')\n * if (root) {\n * ReactDOM.render(<App />, root)\n * }\n * ```\n *\n * @param props\n * @returns\n */\nexport function DraftsContextProvider({\n /** The identifier for the forms app associated with the user's drafts */\n formsAppId,\n /**\n * `true` if drafts are enabled, otherwise `false`. Can be used for account\n * tier validation.\n */\n isDraftsEnabled,\n /** Your application components */\n children,\n}: {\n formsAppId: number\n isDraftsEnabled: boolean\n children: React.ReactNode\n}) {\n const isMounted = useIsMounted()\n const isOffline = useIsOffline()\n const { isLoggedIn, isUsingFormsKey } = useAuth()\n\n const [syncState, setSyncState] = React.useState<{\n isSyncing: boolean\n syncError: Error | null\n }>(defaultSyncState)\n const clearSyncError = React.useCallback(() => {\n setSyncState((currentState) => ({\n ...currentState,\n syncError: null,\n }))\n }, [])\n const syncDrafts = React.useCallback(async () => {\n if (!isDraftsEnabled || !isLoggedIn || isUsingFormsKey) {\n return\n }\n\n if (isMounted.current) {\n setSyncState({\n isSyncing: true,\n syncError: null,\n })\n }\n\n let newError = null\n\n try {\n await draftService.syncDrafts({\n formsAppId,\n throwError: false,\n })\n } catch (error) {\n newError = error as Error\n }\n\n if (isMounted.current) {\n setSyncState({\n isSyncing: false,\n syncError: newError,\n })\n }\n }, [formsAppId, isDraftsEnabled, isLoggedIn, isMounted, isUsingFormsKey])\n\n const [loadState, setLoadState] = React.useState<{\n isLoading: boolean\n loadError: Error | null\n drafts: SubmissionTypes.FormsAppDraft[]\n }>(defaultLoadState)\n const clearLoadError = React.useCallback(() => {\n setLoadState((currentState) => ({\n ...currentState,\n loadError: null,\n }))\n }, [])\n const reloadDrafts = React.useCallback(async () => {\n if (!isLoggedIn) {\n if (isMounted.current) {\n setLoadState({\n isLoading: false,\n loadError: null,\n drafts: [],\n })\n }\n return\n }\n\n if (isMounted.current) {\n setLoadState((currentState) => ({\n isLoading: true,\n loadError: null,\n drafts: currentState.drafts,\n }))\n }\n\n let newError = null\n let newDrafts: SubmissionTypes.FormsAppDraft[] = []\n\n try {\n newDrafts = await draftService.getDrafts()\n } catch (error) {\n newError = error as Error\n }\n\n if (isMounted.current) {\n setLoadState({\n isLoading: false,\n loadError: newError,\n drafts: newDrafts,\n })\n }\n }, [isMounted, isLoggedIn])\n\n const deleteDraft = React.useCallback(\n (draftId) => {\n return draftService.deleteDraft(draftId, formsAppId)\n },\n [formsAppId],\n )\n\n const value = React.useMemo(\n () => ({\n // Sync\n syncDrafts,\n isSyncing: syncState.isSyncing,\n syncError: syncState.syncError,\n clearSyncError,\n // Load\n reloadDrafts,\n isLoading: loadState.isLoading,\n drafts: loadState.drafts,\n loadError: loadState.loadError,\n clearLoadError,\n // Delete,\n deleteDraft,\n }),\n [\n clearLoadError,\n clearSyncError,\n loadState.drafts,\n loadState.isLoading,\n loadState.loadError,\n reloadDrafts,\n syncDrafts,\n syncState.isSyncing,\n syncState.syncError,\n deleteDraft,\n ],\n )\n\n React.useEffect(() => {\n reloadDrafts()\n const unregisterPendingQueueListener =\n submissionService.registerPendingQueueListener(reloadDrafts)\n const unregisterDraftsListener = draftService.registerDraftsListener(\n (drafts) => {\n setLoadState({\n isLoading: false,\n drafts,\n loadError: null,\n })\n },\n )\n return () => {\n unregisterPendingQueueListener()\n unregisterDraftsListener()\n }\n }, [reloadDrafts])\n\n React.useEffect(() => {\n if (!isOffline) {\n syncDrafts()\n }\n }, [isOffline, syncDrafts])\n\n return (\n <DraftsContext.Provider value={value}>{children}</DraftsContext.Provider>\n )\n}\n\n/**\n * React hook to get the context value for Drafts. Will throw an Error if used\n * outside of the `<DraftsContextProvider />` component.\n *\n * @returns\n */\nexport default function useDrafts(): DraftsContextValue {\n const value = React.useContext(DraftsContext)\n if (!value) {\n throw new Error(\n `\"useDrafts\" hook was used outside of the \"<DraftsContextProvider />\" component's children.`,\n )\n }\n return value\n}\n"]}
|
1
|
+
{"version":3,"file":"useDrafts.js","sourceRoot":"","sources":["../../src/hooks/useDrafts.tsx"],"names":[],"mappings":"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","sourcesContent":["import * as React from 'react'\nimport { draftService, submissionService } from '@oneblink/apps'\nimport { SubmissionTypes } from '@oneblink/types'\nimport useAuth from './useAuth'\nimport useIsMounted from './useIsMounted'\nimport useIsOffline from './useIsOffline'\n\n/** The value returned from `useDrafts()` hook */\nexport type DraftsContextValue = {\n /** `true` drafts are currently loading. */\n isLoading: boolean\n /** An Error object if loading drafts fails */\n loadError: Error | null\n /** The incomplete submissions that were saved for later */\n drafts: SubmissionTypes.FormsAppDraft[]\n /** A function to trigger loading of the drafts */\n reloadDrafts: () => unknown\n /** A function to clear Error object from loading drafts */\n clearLoadError: () => void\n /** `true` drafts are syncing with other devices */\n isSyncing: boolean\n /** A function to trigger syncing of the drafts */\n syncDrafts: () => unknown\n /** An Error object if syncing drafts fails */\n syncError: Error | null\n /** A function to clear Error object from syncing drafts */\n clearSyncError: () => void\n /** A function to remove a draft */\n deleteDraft: (draftId: string) => Promise<void>\n}\n\nconst defaultLoadState = {\n isLoading: false,\n loadError: null,\n drafts: [],\n}\n\nconst defaultSyncState = {\n isSyncing: false,\n syncError: null,\n}\n\nconst DraftsContext = React.createContext<DraftsContextValue | undefined>(\n undefined,\n)\n\n/**\n * React Component that provides the context for the `useDrafts()` hook to be\n * used by components further down your component tree. **It should only be\n * included in your component tree once and ideally at the root of the\n * application.**\n *\n * #### Example\n *\n * ```jsx\n * import * as React from 'react'\n * import { DraftsContextProvider, useDrafts } from '@oneblink/apps-react'\n *\n * function Component() {\n * const draftsContext = useDrafts()\n * // use drafts here\n * }\n *\n * function App() {\n * return (\n * <DraftsContextProvider>\n * <Component />\n * </DraftsContextProvider>\n * )\n * }\n *\n * const root = document.getElementById('root')\n * if (root) {\n * ReactDOM.render(<App />, root)\n * }\n * ```\n *\n * @param props\n * @returns\n * @group Components\n */\nexport function DraftsContextProvider({\n /** The identifier for the forms app associated with the user's drafts */\n formsAppId,\n /**\n * `true` if drafts are enabled, otherwise `false`. Can be used for account\n * tier validation.\n */\n isDraftsEnabled,\n /** Your application components */\n children,\n}: {\n formsAppId: number\n isDraftsEnabled: boolean\n children: React.ReactNode\n}) {\n const isMounted = useIsMounted()\n const isOffline = useIsOffline()\n const { isLoggedIn, isUsingFormsKey } = useAuth()\n\n const [syncState, setSyncState] = React.useState<{\n isSyncing: boolean\n syncError: Error | null\n }>(defaultSyncState)\n const clearSyncError = React.useCallback(() => {\n setSyncState((currentState) => ({\n ...currentState,\n syncError: null,\n }))\n }, [])\n const syncDrafts = React.useCallback(async () => {\n if (!isDraftsEnabled || !isLoggedIn || isUsingFormsKey) {\n return\n }\n\n if (isMounted.current) {\n setSyncState({\n isSyncing: true,\n syncError: null,\n })\n }\n\n let newError = null\n\n try {\n await draftService.syncDrafts({\n formsAppId,\n throwError: false,\n })\n } catch (error) {\n newError = error as Error\n }\n\n if (isMounted.current) {\n setSyncState({\n isSyncing: false,\n syncError: newError,\n })\n }\n }, [formsAppId, isDraftsEnabled, isLoggedIn, isMounted, isUsingFormsKey])\n\n const [loadState, setLoadState] = React.useState<{\n isLoading: boolean\n loadError: Error | null\n drafts: SubmissionTypes.FormsAppDraft[]\n }>(defaultLoadState)\n const clearLoadError = React.useCallback(() => {\n setLoadState((currentState) => ({\n ...currentState,\n loadError: null,\n }))\n }, [])\n const reloadDrafts = React.useCallback(async () => {\n if (!isLoggedIn) {\n if (isMounted.current) {\n setLoadState({\n isLoading: false,\n loadError: null,\n drafts: [],\n })\n }\n return\n }\n\n if (isMounted.current) {\n setLoadState((currentState) => ({\n isLoading: true,\n loadError: null,\n drafts: currentState.drafts,\n }))\n }\n\n let newError = null\n let newDrafts: SubmissionTypes.FormsAppDraft[] = []\n\n try {\n newDrafts = await draftService.getDrafts()\n } catch (error) {\n newError = error as Error\n }\n\n if (isMounted.current) {\n setLoadState({\n isLoading: false,\n loadError: newError,\n drafts: newDrafts,\n })\n }\n }, [isMounted, isLoggedIn])\n\n const deleteDraft = React.useCallback(\n (draftId) => {\n return draftService.deleteDraft(draftId, formsAppId)\n },\n [formsAppId],\n )\n\n const value = React.useMemo(\n () => ({\n // Sync\n syncDrafts,\n isSyncing: syncState.isSyncing,\n syncError: syncState.syncError,\n clearSyncError,\n // Load\n reloadDrafts,\n isLoading: loadState.isLoading,\n drafts: loadState.drafts,\n loadError: loadState.loadError,\n clearLoadError,\n // Delete,\n deleteDraft,\n }),\n [\n clearLoadError,\n clearSyncError,\n loadState.drafts,\n loadState.isLoading,\n loadState.loadError,\n reloadDrafts,\n syncDrafts,\n syncState.isSyncing,\n syncState.syncError,\n deleteDraft,\n ],\n )\n\n React.useEffect(() => {\n reloadDrafts()\n const unregisterPendingQueueListener =\n submissionService.registerPendingQueueListener(reloadDrafts)\n const unregisterDraftsListener = draftService.registerDraftsListener(\n (drafts) => {\n setLoadState({\n isLoading: false,\n drafts,\n loadError: null,\n })\n },\n )\n return () => {\n unregisterPendingQueueListener()\n unregisterDraftsListener()\n }\n }, [reloadDrafts])\n\n React.useEffect(() => {\n if (!isOffline) {\n syncDrafts()\n }\n }, [isOffline, syncDrafts])\n\n return (\n <DraftsContext.Provider value={value}>{children}</DraftsContext.Provider>\n )\n}\n\n/**\n * React hook to get the context value for Drafts. Will throw an Error if used\n * outside of the `<DraftsContextProvider />` component.\n *\n * @returns\n * @group Hooks\n */\nexport default function useDrafts(): DraftsContextValue {\n const value = React.useContext(DraftsContext)\n if (!value) {\n throw new Error(\n `\"useDrafts\" hook was used outside of the \"<DraftsContextProvider />\" component's children.`,\n )\n }\n return value\n}\n"]}
|
@@ -9,6 +9,7 @@ import { FormTypes, SubmissionTypes } from '@oneblink/types';
|
|
9
9
|
*
|
10
10
|
* @param options
|
11
11
|
* @returns
|
12
|
+
* @group Hooks
|
12
13
|
*/
|
13
14
|
export default function useFormSubmissionAutoSaveState({ form, initialSubmission, resumeAtElement, removeAutoSaveDataBeforeSubmit, removeAutoSaveDataBeforeSaveDraft, autoSaveKey, onCancel, onSubmit, onSaveDraft, }: {
|
14
15
|
form: FormTypes.Form;
|
@@ -10,6 +10,7 @@ import useFormSubmissionState from './useFormSubmissionState';
|
|
10
10
|
*
|
11
11
|
* @param options
|
12
12
|
* @returns
|
13
|
+
* @group Hooks
|
13
14
|
*/
|
14
15
|
export default function useFormSubmissionAutoSaveState({ form, initialSubmission, resumeAtElement, removeAutoSaveDataBeforeSubmit, removeAutoSaveDataBeforeSaveDraft, autoSaveKey, onCancel, onSubmit, onSaveDraft, }) {
|
15
16
|
const [{ definition, submission, lastElementUpdated }, setFormSubmission] = useFormSubmissionState(form, initialSubmission, resumeAtElement);
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"useFormSubmissionAutoSaveState.js","sourceRoot":"","sources":["../../src/hooks/useFormSubmissionAutoSaveState.ts"],"names":[],"mappings":"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","sourcesContent":["import * as React from 'react'\nimport _throttle from 'lodash.throttle'\nimport { autoSaveService, submissionService, Sentry } from '@oneblink/apps'\nimport { FormTypes, SubmissionTypes } from '@oneblink/types'\nimport useFormSubmissionState from './useFormSubmissionState'\nimport { FormElement } from '@oneblink/types/typescript/forms'\n\n/**\n * Use this if you want to implement a controlled auto saving form. See\n * {@link OneBlinkFormControlled} for a full example. If you do not need to\n * control the `submission` or `definition` properties, you can use the\n * {@link OneBlinkAutoSaveForm} component.\n *\n * @param options\n * @returns\n */\nexport default function useFormSubmissionAutoSaveState({\n form,\n initialSubmission,\n resumeAtElement,\n removeAutoSaveDataBeforeSubmit,\n removeAutoSaveDataBeforeSaveDraft,\n autoSaveKey,\n onCancel,\n onSubmit,\n onSaveDraft,\n}: {\n form: FormTypes.Form\n removeAutoSaveDataBeforeSubmit?: boolean\n removeAutoSaveDataBeforeSaveDraft?: boolean\n autoSaveKey: string\n onCancel: () => unknown\n onSubmit: (newFormSubmission: submissionService.NewFormSubmission) => unknown\n initialSubmission?: SubmissionTypes.S3SubmissionData['submission']\n resumeAtElement?: FormTypes.FormElement\n onSaveDraft?: (\n newDraftSubmission: submissionService.NewDraftSubmission,\n ) => unknown\n}) {\n const [{ definition, submission, lastElementUpdated }, setFormSubmission] =\n useFormSubmissionState(form, initialSubmission, resumeAtElement)\n\n const [\n { isLoadingAutoSaveSubmission, autoSaveSubmission, autoSaveElement },\n setAutoSaveState,\n ] = React.useState<{\n isLoadingAutoSaveSubmission: boolean\n autoSaveSubmission: SubmissionTypes.S3SubmissionData['submission'] | null\n autoSaveElement: FormElement | null\n }>({\n isLoadingAutoSaveSubmission: true,\n autoSaveSubmission: null,\n autoSaveElement: null,\n })\n\n const throttledAutoSave = React.useMemo(() => {\n return _throttle(\n (\n model: SubmissionTypes.S3SubmissionData['submission'],\n lastElementUpdated?: FormElement,\n ) => {\n console.log('Auto saving...')\n autoSaveService\n .upsertAutoSaveData(definition.id, autoSaveKey, model)\n .then(() => {\n if (lastElementUpdated) {\n return autoSaveService.upsertAutoSaveData<FormElement>(\n definition.id,\n `LAST_ELEMENT_UPDATED_${autoSaveKey}`,\n lastElementUpdated,\n )\n }\n })\n .catch((error) => {\n console.warn('Error while auto saving', error)\n Sentry.captureException(error)\n })\n },\n 9580, // https://en.wikipedia.org/wiki/100_metres\n { trailing: true, leading: false },\n )\n }, [autoSaveKey, definition.id])\n\n const cancelAutoSave = React.useCallback(() => {\n if (throttledAutoSave) {\n throttledAutoSave.cancel()\n }\n }, [throttledAutoSave])\n\n const deleteAutoSaveSubmission = React.useCallback(() => {\n return autoSaveService\n .deleteAutoSaveData(definition.id, autoSaveKey)\n .catch((error) => {\n console.warn('Error removing auto save data: ', error)\n Sentry.captureException(error)\n })\n }, [autoSaveKey, definition.id])\n\n const handleSubmit = React.useCallback(\n (submissionResult: submissionService.NewFormSubmission) => {\n cancelAutoSave()\n if (removeAutoSaveDataBeforeSubmit !== false) {\n deleteAutoSaveSubmission()\n }\n onSubmit(submissionResult)\n },\n [\n cancelAutoSave,\n deleteAutoSaveSubmission,\n onSubmit,\n removeAutoSaveDataBeforeSubmit,\n ],\n )\n\n const handleSaveDraft = React.useMemo(() => {\n if (onSaveDraft) {\n return (newDraftSubmission: submissionService.NewDraftSubmission) => {\n cancelAutoSave()\n if (removeAutoSaveDataBeforeSaveDraft !== false) {\n deleteAutoSaveSubmission()\n }\n if (onSaveDraft) {\n onSaveDraft(newDraftSubmission)\n }\n }\n }\n }, [\n cancelAutoSave,\n deleteAutoSaveSubmission,\n onSaveDraft,\n removeAutoSaveDataBeforeSaveDraft,\n ])\n\n const handleNavigateAway = React.useCallback(() => {\n cancelAutoSave()\n deleteAutoSaveSubmission()\n }, [cancelAutoSave, deleteAutoSaveSubmission])\n\n const handleCancel = React.useCallback(() => {\n cancelAutoSave()\n deleteAutoSaveSubmission()\n onCancel()\n }, [cancelAutoSave, deleteAutoSaveSubmission, onCancel])\n\n React.useEffect(() => {\n let ignore = false\n const loadAutoSaveData = async () => {\n try {\n const autoSaveSubmission = await autoSaveService.getAutoSaveData<\n SubmissionTypes.S3SubmissionData['submission']\n >(definition.id, autoSaveKey)\n const autoSaveElement =\n await autoSaveService.getAutoSaveData<FormElement>(\n definition.id,\n `LAST_ELEMENT_UPDATED_${autoSaveKey}`,\n )\n if (!ignore) {\n setAutoSaveState({\n isLoadingAutoSaveSubmission: false,\n autoSaveSubmission,\n autoSaveElement,\n })\n }\n } catch (error) {\n console.warn('Error loading auto save data', error)\n Sentry.captureException(error)\n if (!ignore) {\n setAutoSaveState({\n isLoadingAutoSaveSubmission: false,\n autoSaveSubmission: null,\n autoSaveElement: null,\n })\n }\n }\n }\n loadAutoSaveData()\n return () => {\n ignore = true\n }\n }, [autoSaveKey, definition.id])\n\n // Clean up throttle function on unmount\n React.useEffect(() => {\n return () => {\n cancelAutoSave()\n }\n }, [cancelAutoSave])\n\n const setFormSubmissionAutoSave: typeof setFormSubmission = React.useCallback(\n (formSubmission) => {\n setFormSubmission((currentFormSubmission) => {\n const newFormSubmission =\n typeof formSubmission === 'function'\n ? formSubmission(currentFormSubmission)\n : formSubmission\n\n throttledAutoSave(\n newFormSubmission.submission,\n newFormSubmission.lastElementUpdated,\n )\n\n return newFormSubmission\n })\n },\n [setFormSubmission, throttledAutoSave],\n )\n\n const startNewSubmission = React.useCallback(() => {\n deleteAutoSaveSubmission()\n setAutoSaveState({\n isLoadingAutoSaveSubmission: false,\n autoSaveSubmission: null,\n autoSaveElement: null,\n })\n }, [deleteAutoSaveSubmission])\n\n const continueAutoSaveSubmission = React.useCallback(() => {\n if (autoSaveSubmission) {\n setFormSubmission((currentFormSubmission) => ({\n ...currentFormSubmission,\n submission: autoSaveSubmission,\n lastElementUpdated: autoSaveElement ? autoSaveElement : undefined,\n }))\n }\n setAutoSaveState({\n isLoadingAutoSaveSubmission: false,\n autoSaveSubmission: null,\n autoSaveElement: null,\n })\n }, [autoSaveSubmission, setFormSubmission, autoSaveElement])\n\n return {\n definition,\n submission,\n lastElementUpdated,\n isLoadingAutoSaveSubmission,\n isAutoSaveSubmissionAvailable: autoSaveSubmission !== null,\n startNewSubmission,\n continueAutoSaveSubmission,\n handleSubmit,\n handleCancel,\n handleSaveDraft,\n handleNavigateAway,\n setFormSubmission: setFormSubmissionAutoSave,\n }\n}\n"]}
|
1
|
+
{"version":3,"file":"useFormSubmissionAutoSaveState.js","sourceRoot":"","sources":["../../src/hooks/useFormSubmissionAutoSaveState.ts"],"names":[],"mappings":"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","sourcesContent":["import * as React from 'react'\nimport _throttle from 'lodash.throttle'\nimport { autoSaveService, submissionService, Sentry } from '@oneblink/apps'\nimport { FormTypes, SubmissionTypes } from '@oneblink/types'\nimport useFormSubmissionState from './useFormSubmissionState'\nimport { FormElement } from '@oneblink/types/typescript/forms'\n\n/**\n * Use this if you want to implement a controlled auto saving form. See\n * {@link OneBlinkFormControlled} for a full example. If you do not need to\n * control the `submission` or `definition` properties, you can use the\n * {@link OneBlinkAutoSaveForm} component.\n *\n * @param options\n * @returns\n * @group Hooks\n */\nexport default function useFormSubmissionAutoSaveState({\n form,\n initialSubmission,\n resumeAtElement,\n removeAutoSaveDataBeforeSubmit,\n removeAutoSaveDataBeforeSaveDraft,\n autoSaveKey,\n onCancel,\n onSubmit,\n onSaveDraft,\n}: {\n form: FormTypes.Form\n removeAutoSaveDataBeforeSubmit?: boolean\n removeAutoSaveDataBeforeSaveDraft?: boolean\n autoSaveKey: string\n onCancel: () => unknown\n onSubmit: (newFormSubmission: submissionService.NewFormSubmission) => unknown\n initialSubmission?: SubmissionTypes.S3SubmissionData['submission']\n resumeAtElement?: FormTypes.FormElement\n onSaveDraft?: (\n newDraftSubmission: submissionService.NewDraftSubmission,\n ) => unknown\n}) {\n const [{ definition, submission, lastElementUpdated }, setFormSubmission] =\n useFormSubmissionState(form, initialSubmission, resumeAtElement)\n\n const [\n { isLoadingAutoSaveSubmission, autoSaveSubmission, autoSaveElement },\n setAutoSaveState,\n ] = React.useState<{\n isLoadingAutoSaveSubmission: boolean\n autoSaveSubmission: SubmissionTypes.S3SubmissionData['submission'] | null\n autoSaveElement: FormElement | null\n }>({\n isLoadingAutoSaveSubmission: true,\n autoSaveSubmission: null,\n autoSaveElement: null,\n })\n\n const throttledAutoSave = React.useMemo(() => {\n return _throttle(\n (\n model: SubmissionTypes.S3SubmissionData['submission'],\n lastElementUpdated?: FormElement,\n ) => {\n console.log('Auto saving...')\n autoSaveService\n .upsertAutoSaveData(definition.id, autoSaveKey, model)\n .then(() => {\n if (lastElementUpdated) {\n return autoSaveService.upsertAutoSaveData<FormElement>(\n definition.id,\n `LAST_ELEMENT_UPDATED_${autoSaveKey}`,\n lastElementUpdated,\n )\n }\n })\n .catch((error) => {\n console.warn('Error while auto saving', error)\n Sentry.captureException(error)\n })\n },\n 9580, // https://en.wikipedia.org/wiki/100_metres\n { trailing: true, leading: false },\n )\n }, [autoSaveKey, definition.id])\n\n const cancelAutoSave = React.useCallback(() => {\n if (throttledAutoSave) {\n throttledAutoSave.cancel()\n }\n }, [throttledAutoSave])\n\n const deleteAutoSaveSubmission = React.useCallback(() => {\n return autoSaveService\n .deleteAutoSaveData(definition.id, autoSaveKey)\n .catch((error) => {\n console.warn('Error removing auto save data: ', error)\n Sentry.captureException(error)\n })\n }, [autoSaveKey, definition.id])\n\n const handleSubmit = React.useCallback(\n (submissionResult: submissionService.NewFormSubmission) => {\n cancelAutoSave()\n if (removeAutoSaveDataBeforeSubmit !== false) {\n deleteAutoSaveSubmission()\n }\n onSubmit(submissionResult)\n },\n [\n cancelAutoSave,\n deleteAutoSaveSubmission,\n onSubmit,\n removeAutoSaveDataBeforeSubmit,\n ],\n )\n\n const handleSaveDraft = React.useMemo(() => {\n if (onSaveDraft) {\n return (newDraftSubmission: submissionService.NewDraftSubmission) => {\n cancelAutoSave()\n if (removeAutoSaveDataBeforeSaveDraft !== false) {\n deleteAutoSaveSubmission()\n }\n if (onSaveDraft) {\n onSaveDraft(newDraftSubmission)\n }\n }\n }\n }, [\n cancelAutoSave,\n deleteAutoSaveSubmission,\n onSaveDraft,\n removeAutoSaveDataBeforeSaveDraft,\n ])\n\n const handleNavigateAway = React.useCallback(() => {\n cancelAutoSave()\n deleteAutoSaveSubmission()\n }, [cancelAutoSave, deleteAutoSaveSubmission])\n\n const handleCancel = React.useCallback(() => {\n cancelAutoSave()\n deleteAutoSaveSubmission()\n onCancel()\n }, [cancelAutoSave, deleteAutoSaveSubmission, onCancel])\n\n React.useEffect(() => {\n let ignore = false\n const loadAutoSaveData = async () => {\n try {\n const autoSaveSubmission = await autoSaveService.getAutoSaveData<\n SubmissionTypes.S3SubmissionData['submission']\n >(definition.id, autoSaveKey)\n const autoSaveElement =\n await autoSaveService.getAutoSaveData<FormElement>(\n definition.id,\n `LAST_ELEMENT_UPDATED_${autoSaveKey}`,\n )\n if (!ignore) {\n setAutoSaveState({\n isLoadingAutoSaveSubmission: false,\n autoSaveSubmission,\n autoSaveElement,\n })\n }\n } catch (error) {\n console.warn('Error loading auto save data', error)\n Sentry.captureException(error)\n if (!ignore) {\n setAutoSaveState({\n isLoadingAutoSaveSubmission: false,\n autoSaveSubmission: null,\n autoSaveElement: null,\n })\n }\n }\n }\n loadAutoSaveData()\n return () => {\n ignore = true\n }\n }, [autoSaveKey, definition.id])\n\n // Clean up throttle function on unmount\n React.useEffect(() => {\n return () => {\n cancelAutoSave()\n }\n }, [cancelAutoSave])\n\n const setFormSubmissionAutoSave: typeof setFormSubmission = React.useCallback(\n (formSubmission) => {\n setFormSubmission((currentFormSubmission) => {\n const newFormSubmission =\n typeof formSubmission === 'function'\n ? formSubmission(currentFormSubmission)\n : formSubmission\n\n throttledAutoSave(\n newFormSubmission.submission,\n newFormSubmission.lastElementUpdated,\n )\n\n return newFormSubmission\n })\n },\n [setFormSubmission, throttledAutoSave],\n )\n\n const startNewSubmission = React.useCallback(() => {\n deleteAutoSaveSubmission()\n setAutoSaveState({\n isLoadingAutoSaveSubmission: false,\n autoSaveSubmission: null,\n autoSaveElement: null,\n })\n }, [deleteAutoSaveSubmission])\n\n const continueAutoSaveSubmission = React.useCallback(() => {\n if (autoSaveSubmission) {\n setFormSubmission((currentFormSubmission) => ({\n ...currentFormSubmission,\n submission: autoSaveSubmission,\n lastElementUpdated: autoSaveElement ? autoSaveElement : undefined,\n }))\n }\n setAutoSaveState({\n isLoadingAutoSaveSubmission: false,\n autoSaveSubmission: null,\n autoSaveElement: null,\n })\n }, [autoSaveSubmission, setFormSubmission, autoSaveElement])\n\n return {\n definition,\n submission,\n lastElementUpdated,\n isLoadingAutoSaveSubmission,\n isAutoSaveSubmissionAvailable: autoSaveSubmission !== null,\n startNewSubmission,\n continueAutoSaveSubmission,\n handleSubmit,\n handleCancel,\n handleSaveDraft,\n handleNavigateAway,\n setFormSubmission: setFormSubmissionAutoSave,\n }\n}\n"]}
|
@@ -35,6 +35,7 @@ import { FormTypes, SubmissionTypes } from '@oneblink/types';
|
|
35
35
|
* with
|
36
36
|
* @param lastElementUpdated
|
37
37
|
* @returns
|
38
|
+
* @group Hooks
|
38
39
|
*/
|
39
40
|
export default function useFormSubmissionState(form: FormTypes.Form, initialSubmission?: SubmissionTypes.S3SubmissionData['submission'], lastElementUpdated?: FormTypes.FormElement): [{
|
40
41
|
definition: FormTypes.Form;
|
@@ -36,6 +36,7 @@ import generateDefaultData from '../services/generate-default-data';
|
|
36
36
|
* with
|
37
37
|
* @param lastElementUpdated
|
38
38
|
* @returns
|
39
|
+
* @group Hooks
|
39
40
|
*/
|
40
41
|
export default function useFormSubmissionState(form, initialSubmission, lastElementUpdated) {
|
41
42
|
return React.useState(() => {
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"useFormSubmissionState.js","sourceRoot":"","sources":["../../src/hooks/useFormSubmissionState.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,UAAU,MAAM,kBAAkB,CAAA;AAEzC,OAAO,mBAAmB,MAAM,mCAAmC,CAAA;AACnE
|
1
|
+
{"version":3,"file":"useFormSubmissionState.js","sourceRoot":"","sources":["../../src/hooks/useFormSubmissionState.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,UAAU,MAAM,kBAAkB,CAAA;AAEzC,OAAO,mBAAmB,MAAM,mCAAmC,CAAA;AACnE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,MAAM,CAAC,OAAO,UAAU,sBAAsB,CAC5C,IAAoB,EACpB,iBAAkE,EAClE,kBAA0C;IAE1C,OAAO,KAAK,CAAC,QAAQ,CAAC,GAAG,EAAE;QACzB,MAAM,UAAU,GAAG,UAAU,CAAC,IAAI,CAAC,CAAA;QACnC,MAAM,WAAW,GAAG,mBAAmB,CACrC,UAAU,CAAC,QAAQ,EACnB,iBAAiB,IAAI,EAAE,CACxB,CAAA;QACD,OAAO;YACL,UAAU;YACV,UAAU,EAAE,WAAW;YACvB,kBAAkB;SACnB,CAAA;IACH,CAAC,CAAC,CAAA;AACJ,CAAC","sourcesContent":["import * as React from 'react'\nimport _cloneDeep from 'lodash.clonedeep'\nimport { FormTypes, SubmissionTypes } from '@oneblink/types'\nimport generateDefaultData from '../services/generate-default-data'\n/**\n * This function is a simple wrapper around the react hook `useState()`. The\n * results can be passed to the [`<OneBlinkForm\n * />`](https://oneblink.github.io/apps-react/somewhere) //TODO: Fix link\n * component.\n *\n * ## Example\n *\n * ```js\n * import {\n * useFormSubmissionState,\n * OneBlinkFormControlled,\n * } from '@oneblink/apps-react'\n *\n * function Uncontrolled({ form, initialSubmission, ...props }) {\n * const [{ definition, submission }, setFormSubmission] =\n * useFormSubmissionState(form, initialSubmission)\n *\n * return (\n * <OneBlinkFormControlled\n * {...props}\n * definition={definition}\n * submission={submission}\n * setFormSubmission={setFormSubmission}\n * lastElementUpdated={lastElementUpdated}\n * />\n * )\n * }\n * ```\n *\n * @param form The OneBlink Form to render\n * @param initialSubmission The initial submission data to populate the form\n * with\n * @param lastElementUpdated\n * @returns\n * @group Hooks\n */\nexport default function useFormSubmissionState(\n form: FormTypes.Form,\n initialSubmission?: SubmissionTypes.S3SubmissionData['submission'],\n lastElementUpdated?: FormTypes.FormElement,\n) {\n return React.useState(() => {\n const definition = _cloneDeep(form)\n const defaultData = generateDefaultData(\n definition.elements,\n initialSubmission || {},\n )\n return {\n definition,\n submission: defaultData,\n lastElementUpdated,\n }\n })\n}\n"]}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"useIsMounted.js","sourceRoot":"","sources":["../../src/hooks/useIsMounted.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B
|
1
|
+
{"version":3,"file":"useIsMounted.js","sourceRoot":"","sources":["../../src/hooks/useIsMounted.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,CAAC,OAAO,UAAU,YAAY;IAIlC,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;IACrC,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACnB,SAAS,CAAC,OAAO,GAAG,IAAI,CAAA;QACxB,OAAO,GAAG,EAAE;YACV,SAAS,CAAC,OAAO,GAAG,KAAK,CAAA;QAC3B,CAAC,CAAA;IACH,CAAC,EAAE,EAAE,CAAC,CAAA;IACN,OAAO,SAAS,CAAA;AAClB,CAAC","sourcesContent":["import * as React from 'react'\n\n/**\n * This function is a react hook for determining whether the consuming component\n * is currently mounted on the DOM.\n *\n * ## Example\n *\n * ```js\n * import { useIsMounted } from '@oneblink/apps-react'\n *\n * const isMounted = useIsMounted()\n *\n * if (isMounted.current) {\n * // DO SOMETHING HERE\n * }\n * ```\n *\n * @returns\n * @group Hooks\n */\nexport default function useIsMounted(): {\n /** Whether the current component is mounted. */\n current: boolean\n} {\n const isMounted = React.useRef(false)\n React.useEffect(() => {\n isMounted.current = true\n return () => {\n isMounted.current = false\n }\n }, [])\n return isMounted\n}\n"]}
|