@oneblink/apps-react 6.9.2 → 6.10.0-beta.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/dist/components/ConfirmDialog.d.ts +22 -0
  2. package/dist/components/ConfirmDialog.js +40 -0
  3. package/dist/components/ConfirmDialog.js.map +1 -0
  4. package/dist/components/InputClear.d.ts +8 -0
  5. package/dist/components/InputClear.js +11 -0
  6. package/dist/components/InputClear.js.map +1 -0
  7. package/dist/components/InputField.d.ts +7 -0
  8. package/dist/components/InputField.js +17 -0
  9. package/dist/components/InputField.js.map +1 -0
  10. package/dist/components/SuccessSnackbar.d.ts +8 -0
  11. package/dist/components/SuccessSnackbar.js +19 -0
  12. package/dist/components/SuccessSnackbar.js.map +1 -0
  13. package/dist/components/calendar-bookings/CalendarBookingsCancelForm.d.ts +4 -0
  14. package/dist/components/calendar-bookings/CalendarBookingsCancelForm.js +28 -0
  15. package/dist/components/calendar-bookings/CalendarBookingsCancelForm.js.map +1 -0
  16. package/dist/components/calendar-bookings/CalendarBookingsContainer.d.ts +7 -0
  17. package/dist/components/calendar-bookings/CalendarBookingsContainer.js +34 -0
  18. package/dist/components/calendar-bookings/CalendarBookingsContainer.js.map +1 -0
  19. package/dist/components/calendar-bookings/CalendarBookingsForm.d.ts +7 -0
  20. package/dist/components/calendar-bookings/CalendarBookingsForm.js +131 -0
  21. package/dist/components/calendar-bookings/CalendarBookingsForm.js.map +1 -0
  22. package/dist/components/calendar-bookings/CalendarBookingsProvider.d.ts +13 -0
  23. package/dist/components/calendar-bookings/CalendarBookingsProvider.js +64 -0
  24. package/dist/components/calendar-bookings/CalendarBookingsProvider.js.map +1 -0
  25. package/dist/components/calendar-bookings/CalendarBookingsReschedulingForm.d.ts +4 -0
  26. package/dist/components/calendar-bookings/CalendarBookingsReschedulingForm.js +37 -0
  27. package/dist/components/calendar-bookings/CalendarBookingsReschedulingForm.js.map +1 -0
  28. package/dist/components/calendar-bookings/ErrorModal.d.ts +10 -0
  29. package/dist/components/calendar-bookings/ErrorModal.js +48 -0
  30. package/dist/components/calendar-bookings/ErrorModal.js.map +1 -0
  31. package/dist/components/mfa/MfaDialog.d.ts +9 -0
  32. package/dist/components/mfa/MfaDialog.js +86 -0
  33. package/dist/components/mfa/MfaDialog.js.map +1 -0
  34. package/dist/components/mfa/MultiFactorAuthentication.d.ts +46 -0
  35. package/dist/components/mfa/MultiFactorAuthentication.js +112 -0
  36. package/dist/components/mfa/MultiFactorAuthentication.js.map +1 -0
  37. package/dist/form-elements/FormElementTextarea.js +6 -2
  38. package/dist/form-elements/FormElementTextarea.js.map +1 -1
  39. package/dist/hooks/useConditionalLogic.js +9 -2
  40. package/dist/hooks/useConditionalLogic.js.map +1 -1
  41. package/dist/hooks/useMfa.d.ts +99 -0
  42. package/dist/hooks/useMfa.js +220 -0
  43. package/dist/hooks/useMfa.js.map +1 -0
  44. package/dist/index.d.ts +5 -0
  45. package/dist/index.js +5 -0
  46. package/dist/index.js.map +1 -1
  47. package/dist/services/form-validation.js +2 -1
  48. package/dist/services/form-validation.js.map +1 -1
  49. package/dist/styles/calendar-booking-form.scss +7 -0
  50. package/dist/styles.css +8 -0
  51. package/dist/styles.scss +1 -0
  52. package/package.json +4 -2
@@ -0,0 +1,22 @@
1
+ import * as React from 'react';
2
+ import { DialogProps } from '@mui/material';
3
+ type Props = {
4
+ isOpen: boolean;
5
+ onClose: () => void;
6
+ onConfirm: (abortSignal: AbortSignal) => unknown;
7
+ children: React.ReactNode;
8
+ title: string;
9
+ confirmButtonText: string;
10
+ confirmButtonIcon: React.ReactNode;
11
+ cypress?: {
12
+ dialog?: string;
13
+ confirmButton?: string;
14
+ cancelButton?: string;
15
+ error?: string;
16
+ title?: string;
17
+ };
18
+ TransitionProps?: DialogProps['TransitionProps'];
19
+ disabled?: boolean;
20
+ };
21
+ export default function ConfirmDialog({ isOpen, onClose, children, onConfirm, title, confirmButtonText, confirmButtonIcon, cypress, TransitionProps, disabled, }: Props): React.JSX.Element;
22
+ export {};
@@ -0,0 +1,40 @@
1
+ import * as React from 'react';
2
+ import { Dialog, DialogActions, DialogTitle, DialogContent, Button, Portal, } from '@mui/material';
3
+ import { LoadingButton } from '@mui/lab';
4
+ import useIsMounted from '../hooks/useIsMounted';
5
+ import ErrorSnackbar from './ErrorSnackbar';
6
+ export default function ConfirmDialog({ isOpen, onClose, children, onConfirm, title, confirmButtonText, confirmButtonIcon, cypress, TransitionProps, disabled, }) {
7
+ const isMounted = useIsMounted();
8
+ const [isConfirming, setIsConfirming] = React.useState(false);
9
+ const [error, setError] = React.useState(null);
10
+ const handleConfirm = React.useCallback(async () => {
11
+ setIsConfirming(true);
12
+ setError(null);
13
+ let newError = null;
14
+ const abortController = new AbortController();
15
+ try {
16
+ await onConfirm(abortController.signal);
17
+ }
18
+ catch (error) {
19
+ newError = error;
20
+ }
21
+ if (isMounted.current && !abortController.signal.aborted) {
22
+ setIsConfirming(false);
23
+ setError(newError);
24
+ }
25
+ }, [isMounted, onConfirm]);
26
+ return (React.createElement(React.Fragment, null,
27
+ React.createElement(Dialog, { open: isOpen, maxWidth: "sm", fullWidth: true, onClose: !isConfirming ? onClose : undefined, "data-cypress": cypress === null || cypress === void 0 ? void 0 : cypress.dialog, TransitionProps: {
28
+ onExiting: () => setError(null),
29
+ ...(TransitionProps ? TransitionProps : {}),
30
+ } },
31
+ React.createElement(DialogTitle, { "data-cypress": cypress === null || cypress === void 0 ? void 0 : cypress.title }, title),
32
+ React.createElement(DialogContent, { dividers: true }, children),
33
+ React.createElement(DialogActions, null,
34
+ React.createElement(Button, { disabled: isConfirming, onClick: onClose, "data-cypress": cypress === null || cypress === void 0 ? void 0 : cypress.cancelButton }, "Cancel"),
35
+ React.createElement(LoadingButton, { variant: "contained", loading: isConfirming, autoFocus: true, startIcon: confirmButtonIcon, loadingPosition: "start", onClick: handleConfirm, "data-cypress": cypress === null || cypress === void 0 ? void 0 : cypress.confirmButton, disabled: disabled }, confirmButtonText))),
36
+ React.createElement(Portal, null,
37
+ React.createElement(ErrorSnackbar, { open: !!error, onClose: setError },
38
+ React.createElement("span", { "data-cypress": cypress === null || cypress === void 0 ? void 0 : cypress.error }, error === null || error === void 0 ? void 0 : error.message)))));
39
+ }
40
+ //# sourceMappingURL=ConfirmDialog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConfirmDialog.js","sourceRoot":"","sources":["../../src/components/ConfirmDialog.tsx"],"names":[],"mappings":"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","sourcesContent":["import * as React from 'react'\nimport {\n Dialog,\n DialogActions,\n DialogTitle,\n DialogContent,\n Button,\n Portal,\n DialogProps,\n} from '@mui/material'\nimport { LoadingButton } from '@mui/lab'\nimport useIsMounted from '../hooks/useIsMounted'\nimport ErrorSnackbar from './ErrorSnackbar'\n\ntype Props = {\n isOpen: boolean\n onClose: () => void\n onConfirm: (abortSignal: AbortSignal) => unknown\n children: React.ReactNode\n title: string\n confirmButtonText: string\n confirmButtonIcon: React.ReactNode\n cypress?: {\n dialog?: string\n confirmButton?: string\n cancelButton?: string\n error?: string\n title?: string\n }\n TransitionProps?: DialogProps['TransitionProps']\n disabled?: boolean\n}\n\nexport default function ConfirmDialog({\n isOpen,\n onClose,\n children,\n onConfirm,\n title,\n confirmButtonText,\n confirmButtonIcon,\n cypress,\n TransitionProps,\n disabled,\n}: Props) {\n const isMounted = useIsMounted()\n const [isConfirming, setIsConfirming] = React.useState(false)\n const [error, setError] = React.useState<Error | null>(null)\n const handleConfirm = React.useCallback(async () => {\n setIsConfirming(true)\n setError(null)\n let newError = null\n\n const abortController = new AbortController()\n try {\n await onConfirm(abortController.signal)\n } catch (error) {\n newError = error as Error\n }\n\n if (isMounted.current && !abortController.signal.aborted) {\n setIsConfirming(false)\n setError(newError)\n }\n }, [isMounted, onConfirm])\n return (\n <React.Fragment>\n <Dialog\n open={isOpen}\n maxWidth=\"sm\"\n fullWidth\n onClose={!isConfirming ? onClose : undefined}\n data-cypress={cypress?.dialog}\n TransitionProps={{\n onExiting: () => setError(null),\n ...(TransitionProps ? TransitionProps : {}),\n }}\n >\n <DialogTitle data-cypress={cypress?.title}>{title}</DialogTitle>\n <DialogContent dividers>{children}</DialogContent>\n <DialogActions>\n <Button\n disabled={isConfirming}\n onClick={onClose}\n data-cypress={cypress?.cancelButton}\n >\n Cancel\n </Button>\n\n <LoadingButton\n variant=\"contained\"\n loading={isConfirming}\n autoFocus\n startIcon={confirmButtonIcon}\n loadingPosition=\"start\"\n onClick={handleConfirm}\n data-cypress={cypress?.confirmButton}\n disabled={disabled}\n >\n {confirmButtonText}\n </LoadingButton>\n </DialogActions>\n </Dialog>\n <Portal>\n <ErrorSnackbar open={!!error} onClose={setError}>\n <span data-cypress={cypress?.error}>{error?.message}</span>\n </ErrorSnackbar>\n </Portal>\n </React.Fragment>\n )\n}\n"]}
@@ -0,0 +1,8 @@
1
+ import * as React from 'react';
2
+ interface Props {
3
+ onClear: () => void;
4
+ select?: boolean;
5
+ value: unknown;
6
+ }
7
+ declare const _default: React.NamedExoticComponent<Props>;
8
+ export default _default;
@@ -0,0 +1,11 @@
1
+ import * as React from 'react';
2
+ import { Box, IconButton, Icon } from '@mui/material';
3
+ const InputClear = ({ onClear, select, value }) => {
4
+ if (!value || (Array.isArray(value) && !value.length))
5
+ return null;
6
+ return (React.createElement(Box, { mr: select ? 2 : 0, alignItems: "center", display: "flex" },
7
+ React.createElement(IconButton, { size: "small", onClick: onClear },
8
+ React.createElement(Icon, null, "close"))));
9
+ };
10
+ export default React.memo(InputClear);
11
+ //# sourceMappingURL=InputClear.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InputClear.js","sourceRoot":"","sources":["../../src/components/InputClear.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,EAAE,GAAG,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,eAAe,CAAA;AAOrD,MAAM,UAAU,GAAG,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAS,EAAE,EAAE;IACvD,IAAI,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC;QAAE,OAAO,IAAI,CAAA;IAClE,OAAO,CACL,oBAAC,GAAG,IAAC,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,UAAU,EAAC,QAAQ,EAAC,OAAO,EAAC,MAAM;QACzD,oBAAC,UAAU,IAAC,IAAI,EAAC,OAAO,EAAC,OAAO,EAAE,OAAO;YACvC,oBAAC,IAAI,gBAAa,CACP,CACT,CACP,CAAA;AACH,CAAC,CAAA;AAED,eAAe,KAAK,CAAC,IAAI,CAAQ,UAAU,CAAC,CAAA","sourcesContent":["import * as React from 'react'\nimport { Box, IconButton, Icon } from '@mui/material'\ninterface Props {\n onClear: () => void\n select?: boolean\n value: unknown\n}\n\nconst InputClear = ({ onClear, select, value }: Props) => {\n if (!value || (Array.isArray(value) && !value.length)) return null\n return (\n <Box mr={select ? 2 : 0} alignItems=\"center\" display=\"flex\">\n <IconButton size=\"small\" onClick={onClear}>\n <Icon>close</Icon>\n </IconButton>\n </Box>\n )\n}\n\nexport default React.memo<Props>(InputClear)\n"]}
@@ -0,0 +1,7 @@
1
+ import * as React from 'react';
2
+ import { TextField } from '@mui/material';
3
+ type Props = React.ComponentProps<typeof TextField> & {
4
+ onClear?: () => void;
5
+ };
6
+ declare const _default: React.NamedExoticComponent<Props>;
7
+ export default _default;
@@ -0,0 +1,17 @@
1
+ import * as React from 'react';
2
+ import { TextField } from '@mui/material';
3
+ import InputClear from './InputClear';
4
+ const InputField = ({ margin = 'dense', variant = 'outlined', size = 'small', InputProps, onClear, ...props }) => {
5
+ const inputProps = React.useMemo(() => {
6
+ if (InputProps)
7
+ return InputProps;
8
+ if (onClear) {
9
+ return {
10
+ endAdornment: (React.createElement(InputClear, { select: props.select, value: props.value, onClear: onClear })),
11
+ };
12
+ }
13
+ }, [InputProps, onClear, props.select, props.value]);
14
+ return (React.createElement(TextField, { variant: variant, margin: margin, InputProps: inputProps, size: size, ...props }));
15
+ };
16
+ export default React.memo(InputField);
17
+ //# sourceMappingURL=InputField.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InputField.js","sourceRoot":"","sources":["../../src/components/InputField.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AACzC,OAAO,UAAU,MAAM,cAAc,CAAA;AAMrC,MAAM,UAAU,GAAG,CAAC,EAClB,MAAM,GAAG,OAAO,EAChB,OAAO,GAAG,UAAU,EACpB,IAAI,GAAG,OAAO,EACd,UAAU,EACV,OAAO,EACP,GAAG,KAAK,EACF,EAAE,EAAE;IACV,MAAM,UAAU,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE;QACpC,IAAI,UAAU;YAAE,OAAO,UAAU,CAAA;QACjC,IAAI,OAAO,EAAE,CAAC;YACZ,OAAO;gBACL,YAAY,EAAE,CACZ,oBAAC,UAAU,IACT,MAAM,EAAE,KAAK,CAAC,MAAM,EACpB,KAAK,EAAE,KAAK,CAAC,KAAK,EAClB,OAAO,EAAE,OAAO,GAChB,CACH;aACF,CAAA;QACH,CAAC;IACH,CAAC,EAAE,CAAC,UAAU,EAAE,OAAO,EAAE,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CAAA;IAEpD,OAAO,CACL,oBAAC,SAAS,IACR,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,UAAU,EACtB,IAAI,EAAE,IAAI,KACN,KAAK,GACT,CACH,CAAA;AACH,CAAC,CAAA;AAED,eAAe,KAAK,CAAC,IAAI,CAAQ,UAAU,CAAC,CAAA","sourcesContent":["import * as React from 'react'\nimport { TextField } from '@mui/material'\nimport InputClear from './InputClear'\n\ntype Props = React.ComponentProps<typeof TextField> & {\n onClear?: () => void\n}\n\nconst InputField = ({\n margin = 'dense',\n variant = 'outlined',\n size = 'small',\n InputProps,\n onClear,\n ...props\n}: Props) => {\n const inputProps = React.useMemo(() => {\n if (InputProps) return InputProps\n if (onClear) {\n return {\n endAdornment: (\n <InputClear\n select={props.select}\n value={props.value}\n onClear={onClear}\n />\n ),\n }\n }\n }, [InputProps, onClear, props.select, props.value])\n\n return (\n <TextField\n variant={variant}\n margin={margin}\n InputProps={inputProps}\n size={size}\n {...props}\n />\n )\n}\n\nexport default React.memo<Props>(InputField)\n"]}
@@ -0,0 +1,8 @@
1
+ import * as React from 'react';
2
+ declare function SuccessSnackbar({ open, onClose, children, }: {
3
+ open: boolean;
4
+ children: React.ReactNode;
5
+ onClose: (isOpen: false) => void;
6
+ }): React.JSX.Element;
7
+ declare const _default: React.MemoExoticComponent<typeof SuccessSnackbar>;
8
+ export default _default;
@@ -0,0 +1,19 @@
1
+ import * as React from 'react';
2
+ import { Grid, Icon, Snackbar, SnackbarContent } from '@mui/material';
3
+ function SuccessSnackbar({ open, onClose, children, }) {
4
+ return (React.createElement(Snackbar, { anchorOrigin: {
5
+ vertical: 'bottom',
6
+ horizontal: 'right',
7
+ }, open: open, onClose: (event, reason) => {
8
+ if (reason === 'clickaway') {
9
+ return;
10
+ }
11
+ onClose(false);
12
+ }, autoHideDuration: 3000 },
13
+ React.createElement(SnackbarContent, { sx: { bgcolor: 'success.main' }, message: React.createElement(Grid, { container: true, spacing: 2, alignItems: "center" },
14
+ React.createElement(Grid, { item: true, xs: "auto" },
15
+ React.createElement(Icon, null, "check_circle")),
16
+ React.createElement(Grid, { item: true, xs: true }, children)) })));
17
+ }
18
+ export default React.memo(SuccessSnackbar);
19
+ //# sourceMappingURL=SuccessSnackbar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SuccessSnackbar.js","sourceRoot":"","sources":["../../src/components/SuccessSnackbar.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAErE,SAAS,eAAe,CAAC,EACvB,IAAI,EACJ,OAAO,EACP,QAAQ,GAKT;IACC,OAAO,CACL,oBAAC,QAAQ,IACP,YAAY,EAAE;YACZ,QAAQ,EAAE,QAAQ;YAClB,UAAU,EAAE,OAAO;SACpB,EACD,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE;YACzB,IAAI,MAAM,KAAK,WAAW,EAAE,CAAC;gBAC3B,OAAM;YACR,CAAC;YAED,OAAO,CAAC,KAAK,CAAC,CAAA;QAChB,CAAC,EACD,gBAAgB,EAAE,IAAI;QAEtB,oBAAC,eAAe,IACd,EAAE,EAAE,EAAE,OAAO,EAAE,cAAc,EAAE,EAC/B,OAAO,EACL,oBAAC,IAAI,IAAC,SAAS,QAAC,OAAO,EAAE,CAAC,EAAE,UAAU,EAAC,QAAQ;gBAC7C,oBAAC,IAAI,IAAC,IAAI,QAAC,EAAE,EAAC,MAAM;oBAClB,oBAAC,IAAI,uBAAoB,CACpB;gBACP,oBAAC,IAAI,IAAC,IAAI,QAAC,EAAE,UACV,QAAQ,CACJ,CACF,GAET,CACO,CACZ,CAAA;AACH,CAAC;AAED,eAAe,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,CAAA","sourcesContent":["import * as React from 'react'\nimport { Grid, Icon, Snackbar, SnackbarContent } from '@mui/material'\n\nfunction SuccessSnackbar({\n open,\n onClose,\n children,\n}: {\n open: boolean\n children: React.ReactNode\n onClose: (isOpen: false) => void\n}) {\n return (\n <Snackbar\n anchorOrigin={{\n vertical: 'bottom',\n horizontal: 'right',\n }}\n open={open}\n onClose={(event, reason) => {\n if (reason === 'clickaway') {\n return\n }\n\n onClose(false)\n }}\n autoHideDuration={3000}\n >\n <SnackbarContent\n sx={{ bgcolor: 'success.main' }}\n message={\n <Grid container spacing={2} alignItems=\"center\">\n <Grid item xs=\"auto\">\n <Icon>check_circle</Icon>\n </Grid>\n <Grid item xs>\n {children}\n </Grid>\n </Grid>\n }\n />\n </Snackbar>\n )\n}\n\nexport default React.memo(SuccessSnackbar)\n"]}
@@ -0,0 +1,4 @@
1
+ import React from 'react';
2
+ declare function CalendarBookingsCancelForm(): React.JSX.Element;
3
+ declare const _default: React.MemoExoticComponent<typeof CalendarBookingsCancelForm>;
4
+ export default _default;
@@ -0,0 +1,28 @@
1
+ import React from 'react';
2
+ import { NylasScheduling } from '@nylas/react';
3
+ import { schedulingService } from '@oneblink/apps';
4
+ import ErrorMessage from '../messages/ErrorMessage';
5
+ import CalendarBookingsContainer from './CalendarBookingsContainer';
6
+ import useCalendarBookings from './CalendarBookingsProvider';
7
+ function NylasCancelForm({ sessionId, bookingRef, }) {
8
+ const { setBookingError, themeConfig } = useCalendarBookings();
9
+ if (!bookingRef) {
10
+ return (React.createElement(ErrorMessage, { title: "Error Retrieving Data", gutterTop: true },
11
+ React.createElement("span", { className: "cypress-booking-ref-not-found-error-message" }, "Could not find a calendar booking to cancel")));
12
+ }
13
+ return (React.createElement("div", { className: "ob-scheduling-booking-form" },
14
+ React.createElement(NylasScheduling, { sessionId: sessionId, eventOverrides: {
15
+ bookedEventInfo: async (event) => {
16
+ var _a;
17
+ event.preventDefault();
18
+ if (event.detail.error) {
19
+ setBookingError((_a = event.detail.error.message) !== null && _a !== void 0 ? _a : 'Calendar Booking Error');
20
+ }
21
+ },
22
+ }, themeConfig: themeConfig, cancelBookingRef: bookingRef, enableUserFeedback: false, nylasBranding: false })));
23
+ }
24
+ function CalendarBookingsCancelForm() {
25
+ return (React.createElement(CalendarBookingsContainer, { fetchConfiguration: schedulingService.createNylasExistingBookingSession }, (props) => React.createElement(NylasCancelForm, { ...props })));
26
+ }
27
+ export default React.memo(CalendarBookingsCancelForm);
28
+ //# sourceMappingURL=CalendarBookingsCancelForm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CalendarBookingsCancelForm.js","sourceRoot":"","sources":["../../../src/components/calendar-bookings/CalendarBookingsCancelForm.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AAClD,OAAO,YAAY,MAAM,0BAA0B,CAAA;AACnD,OAAO,yBAAyB,MAAM,6BAA6B,CAAA;AACnE,OAAO,mBAAmB,MAAM,4BAA4B,CAAA;AAE5D,SAAS,eAAe,CAAC,EACvB,SAAS,EACT,UAAU,GAKX;IACC,MAAM,EAAE,eAAe,EAAE,WAAW,EAAE,GAAG,mBAAmB,EAAE,CAAA;IAE9D,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,OAAO,CACL,oBAAC,YAAY,IAAC,KAAK,EAAC,uBAAuB,EAAC,SAAS;YACnD,8BAAM,SAAS,EAAC,6CAA6C,kDAEtD,CACM,CAChB,CAAA;IACH,CAAC;IAED,OAAO,CACL,6BAAK,SAAS,EAAC,4BAA4B;QACzC,oBAAC,eAAe,IACd,SAAS,EAAE,SAAS,EACpB,cAAc,EAAE;gBACd,eAAe,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE;;oBAC/B,KAAK,CAAC,cAAc,EAAE,CAAA;oBACtB,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;wBACvB,eAAe,CACb,MAAA,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,mCAAI,wBAAwB,CACvD,CAAA;oBACH,CAAC;gBACH,CAAC;aACF,EACD,WAAW,EAAE,WAAW,EACxB,gBAAgB,EAAE,UAAU,EAC5B,kBAAkB,EAAE,KAAK,EACzB,aAAa,EAAE,KAAK,GACpB,CACE,CACP,CAAA;AACH,CAAC;AAED,SAAS,0BAA0B;IACjC,OAAO,CACL,oBAAC,yBAAyB,IACxB,kBAAkB,EAAE,iBAAiB,CAAC,iCAAiC,IAEtE,CAAC,KAAK,EAAE,EAAE,CAAC,oBAAC,eAAe,OAAK,KAAK,GAAI,CAChB,CAC7B,CAAA;AACH,CAAC;AAED,eAAe,KAAK,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAA","sourcesContent":["import React from 'react'\nimport { NylasScheduling } from '@nylas/react'\nimport { schedulingService } from '@oneblink/apps'\nimport ErrorMessage from '../messages/ErrorMessage'\nimport CalendarBookingsContainer from './CalendarBookingsContainer'\nimport useCalendarBookings from './CalendarBookingsProvider'\n\nfunction NylasCancelForm({\n sessionId,\n bookingRef,\n}: Awaited<\n ReturnType<typeof schedulingService.createNylasExistingBookingSession>\n> & {\n submissionId: string\n}) {\n const { setBookingError, themeConfig } = useCalendarBookings()\n\n if (!bookingRef) {\n return (\n <ErrorMessage title=\"Error Retrieving Data\" gutterTop>\n <span className=\"cypress-booking-ref-not-found-error-message\">\n Could not find a calendar booking to cancel\n </span>\n </ErrorMessage>\n )\n }\n\n return (\n <div className=\"ob-scheduling-booking-form\">\n <NylasScheduling\n sessionId={sessionId}\n eventOverrides={{\n bookedEventInfo: async (event) => {\n event.preventDefault()\n if (event.detail.error) {\n setBookingError(\n event.detail.error.message ?? 'Calendar Booking Error',\n )\n }\n },\n }}\n themeConfig={themeConfig}\n cancelBookingRef={bookingRef}\n enableUserFeedback={false}\n nylasBranding={false}\n />\n </div>\n )\n}\n\nfunction CalendarBookingsCancelForm() {\n return (\n <CalendarBookingsContainer\n fetchConfiguration={schedulingService.createNylasExistingBookingSession}\n >\n {(props) => <NylasCancelForm {...props} />}\n </CalendarBookingsContainer>\n )\n}\n\nexport default React.memo(CalendarBookingsCancelForm)\n"]}
@@ -0,0 +1,7 @@
1
+ import React from 'react';
2
+ export default function CalendarBookingsContainer<T>({ fetchConfiguration, children, }: {
3
+ fetchConfiguration: (submissionId: string, abortSignal: AbortSignal) => Promise<T>;
4
+ children: (renderProps: {
5
+ submissionId: string;
6
+ } & T) => React.ReactNode;
7
+ }): React.JSX.Element;
@@ -0,0 +1,34 @@
1
+ import React from 'react';
2
+ import useQuery from '../../hooks/useQuery';
3
+ import useLoadDataState from '../../hooks/useLoadDataState';
4
+ import ErrorMessage from '../messages/ErrorMessage';
5
+ import { CalendarBookingsProvider } from './CalendarBookingsProvider';
6
+ import OnLoading from '../renderer/OnLoading';
7
+ import ErrorModal from './ErrorModal';
8
+ function CalendarBookingLoader({ submissionId, fetchConfiguration, children, }) {
9
+ const [nylasSchedulingState, refreshNylasState] = useLoadDataState(React.useCallback(async (abortSignal) => {
10
+ return await fetchConfiguration(submissionId, abortSignal);
11
+ }, [fetchConfiguration, submissionId]));
12
+ if (nylasSchedulingState.status === 'LOADING') {
13
+ return (React.createElement("div", { className: "has-margin-top-1" },
14
+ React.createElement("div", { className: "cypress-loading has-text-centered" },
15
+ React.createElement(OnLoading, { className: "has-text-centered" }))));
16
+ }
17
+ if (nylasSchedulingState.status === 'ERROR') {
18
+ return (React.createElement(ErrorModal, { error: nylasSchedulingState.error, onClose: refreshNylasState }));
19
+ }
20
+ return (React.createElement(CalendarBookingsProvider, { refreshNylasState: refreshNylasState }, children({
21
+ ...nylasSchedulingState.result,
22
+ submissionId,
23
+ })));
24
+ }
25
+ export default function CalendarBookingsContainer({ fetchConfiguration, children, }) {
26
+ const { submissionId: submissionIdQs } = useQuery();
27
+ const submissionId = React.useMemo(() => (typeof submissionIdQs === 'string' ? submissionIdQs : undefined), [submissionIdQs]);
28
+ if (!submissionId) {
29
+ return (React.createElement(ErrorMessage, { title: "Missing Configuration", gutterTop: true },
30
+ React.createElement("span", { className: "cypress-scheduling-booking-form-invalid-querystring ob-scheduling-booking-form__invalid-querystring-message" }, "It seems you have navigated here incorrectly. Please go back.")));
31
+ }
32
+ return (React.createElement(CalendarBookingLoader, { fetchConfiguration: fetchConfiguration, submissionId: submissionId }, children));
33
+ }
34
+ //# sourceMappingURL=CalendarBookingsContainer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CalendarBookingsContainer.js","sourceRoot":"","sources":["../../../src/components/calendar-bookings/CalendarBookingsContainer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,QAAQ,MAAM,sBAAsB,CAAA;AAC3C,OAAO,gBAAgB,MAAM,8BAA8B,CAAA;AAC3D,OAAO,YAAY,MAAM,0BAA0B,CAAA;AACnD,OAAO,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAA;AACrE,OAAO,SAAS,MAAM,uBAAuB,CAAA;AAC7C,OAAO,UAAU,MAAM,cAAc,CAAA;AAOrC,SAAS,qBAAqB,CAAI,EAChC,YAAY,EACZ,kBAAkB,EAClB,QAAQ,GAKT;IACC,MAAM,CAAC,oBAAoB,EAAE,iBAAiB,CAAC,GAAG,gBAAgB,CAChE,KAAK,CAAC,WAAW,CACf,KAAK,EAAE,WAAW,EAAE,EAAE;QACpB,OAAO,MAAM,kBAAkB,CAAC,YAAY,EAAE,WAAW,CAAC,CAAA;IAC5D,CAAC,EACD,CAAC,kBAAkB,EAAE,YAAY,CAAC,CACnC,CACF,CAAA;IAED,IAAI,oBAAoB,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QAC9C,OAAO,CACL,6BAAK,SAAS,EAAC,kBAAkB;YAC/B,6BAAK,SAAS,EAAC,mCAAmC;gBAChD,oBAAC,SAAS,IAAC,SAAS,EAAC,mBAAmB,GAAG,CACvC,CACF,CACP,CAAA;IACH,CAAC;IAED,IAAI,oBAAoB,CAAC,MAAM,KAAK,OAAO,EAAE,CAAC;QAC5C,OAAO,CACL,oBAAC,UAAU,IACT,KAAK,EAAE,oBAAoB,CAAC,KAAK,EACjC,OAAO,EAAE,iBAAiB,GAC1B,CACH,CAAA;IACH,CAAC;IAED,OAAO,CACL,oBAAC,wBAAwB,IAAC,iBAAiB,EAAE,iBAAiB,IAC3D,QAAQ,CAAC;QACR,GAAG,oBAAoB,CAAC,MAAM;QAC9B,YAAY;KACb,CAAC,CACuB,CAC5B,CAAA;AACH,CAAC;AAED,MAAM,CAAC,OAAO,UAAU,yBAAyB,CAAI,EACnD,kBAAkB,EAClB,QAAQ,GAOT;IACC,MAAM,EAAE,YAAY,EAAE,cAAc,EAAE,GAAG,QAAQ,EAAE,CAAA;IAEnD,MAAM,YAAY,GAAG,KAAK,CAAC,OAAO,CAChC,GAAG,EAAE,CAAC,CAAC,OAAO,cAAc,KAAK,QAAQ,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,SAAS,CAAC,EACvE,CAAC,cAAc,CAAC,CACjB,CAAA;IAED,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,OAAO,CACL,oBAAC,YAAY,IAAC,KAAK,EAAC,uBAAuB,EAAC,SAAS;YACnD,8BAAM,SAAS,EAAC,6GAA6G,oEAEtH,CACM,CAChB,CAAA;IACH,CAAC;IAED,OAAO,CACL,oBAAC,qBAAqB,IACpB,kBAAkB,EAAE,kBAAkB,EACtC,YAAY,EAAE,YAAY,IAEzB,QAAQ,CACa,CACzB,CAAA;AACH,CAAC","sourcesContent":["import React from 'react'\nimport useQuery from '../../hooks/useQuery'\nimport useLoadDataState from '../../hooks/useLoadDataState'\nimport ErrorMessage from '../messages/ErrorMessage'\nimport { CalendarBookingsProvider } from './CalendarBookingsProvider'\nimport OnLoading from '../renderer/OnLoading'\nimport ErrorModal from './ErrorModal'\n\ntype FetchConfiguration<T> = (\n submissionId: string,\n abortSignal: AbortSignal,\n) => Promise<T>\n\nfunction CalendarBookingLoader<T>({\n submissionId,\n fetchConfiguration,\n children,\n}: {\n submissionId: string\n fetchConfiguration: FetchConfiguration<T>\n children: (renderProps: { submissionId: string } & T) => React.ReactNode\n}) {\n const [nylasSchedulingState, refreshNylasState] = useLoadDataState<T>(\n React.useCallback(\n async (abortSignal) => {\n return await fetchConfiguration(submissionId, abortSignal)\n },\n [fetchConfiguration, submissionId],\n ),\n )\n\n if (nylasSchedulingState.status === 'LOADING') {\n return (\n <div className=\"has-margin-top-1\">\n <div className=\"cypress-loading has-text-centered\">\n <OnLoading className=\"has-text-centered\" />\n </div>\n </div>\n )\n }\n\n if (nylasSchedulingState.status === 'ERROR') {\n return (\n <ErrorModal\n error={nylasSchedulingState.error}\n onClose={refreshNylasState}\n />\n )\n }\n\n return (\n <CalendarBookingsProvider refreshNylasState={refreshNylasState}>\n {children({\n ...nylasSchedulingState.result,\n submissionId,\n })}\n </CalendarBookingsProvider>\n )\n}\n\nexport default function CalendarBookingsContainer<T>({\n fetchConfiguration,\n children,\n}: {\n fetchConfiguration: (\n submissionId: string,\n abortSignal: AbortSignal,\n ) => Promise<T>\n children: (renderProps: { submissionId: string } & T) => React.ReactNode\n}) {\n const { submissionId: submissionIdQs } = useQuery()\n\n const submissionId = React.useMemo(\n () => (typeof submissionIdQs === 'string' ? submissionIdQs : undefined),\n [submissionIdQs],\n )\n\n if (!submissionId) {\n return (\n <ErrorMessage title=\"Missing Configuration\" gutterTop>\n <span className=\"cypress-scheduling-booking-form-invalid-querystring ob-scheduling-booking-form__invalid-querystring-message\">\n It seems you have navigated here incorrectly. Please go back.\n </span>\n </ErrorMessage>\n )\n }\n\n return (\n <CalendarBookingLoader\n fetchConfiguration={fetchConfiguration}\n submissionId={submissionId}\n >\n {children}\n </CalendarBookingLoader>\n )\n}\n"]}
@@ -0,0 +1,7 @@
1
+ import * as React from 'react';
2
+ import { submissionService } from '@oneblink/apps';
3
+ declare function CalendarBookingsForm({ onDone, }: {
4
+ onDone: (formSubmissionResult: submissionService.FormSubmissionResult) => Promise<void>;
5
+ }): React.JSX.Element;
6
+ declare const _default: React.MemoExoticComponent<typeof CalendarBookingsForm>;
7
+ export default _default;
@@ -0,0 +1,131 @@
1
+ import * as React from 'react';
2
+ import { NylasScheduling } from '@nylas/react';
3
+ import { Collapse, Fade } from '@mui/material';
4
+ import { schedulingService, } from '@oneblink/apps';
5
+ import clsx from 'clsx';
6
+ import { Receipt } from '../receipts';
7
+ import ErrorModal from './ErrorModal';
8
+ import OnLoading from '../renderer/OnLoading';
9
+ import CalendarBookingsContainer from './CalendarBookingsContainer';
10
+ import useCalendarBookings from './CalendarBookingsProvider';
11
+ function NylasBookingForm({ submissionId, name, email, configurationId, sessionId, onBookingConfirmed, onDone, }) {
12
+ const { setBookingError, onTimeSlotConfirmed } = useCalendarBookings();
13
+ const [{ formSubmissionResult, isRunningPostSubmissionAction, postSubmissionError, isConfirmingBooking, confirmingBookingError, }, setPostSubmissionState,] = React.useState({
14
+ formSubmissionResult: null,
15
+ isRunningPostSubmissionAction: false,
16
+ postSubmissionError: null,
17
+ isConfirmingBooking: false,
18
+ confirmingBookingError: null,
19
+ });
20
+ const clearPostSubmissionError = React.useCallback(() => {
21
+ setPostSubmissionState((currentState) => ({
22
+ ...currentState,
23
+ postSubmissionError: null,
24
+ }));
25
+ }, []);
26
+ const clearConfirmingBookingError = React.useCallback(() => {
27
+ setPostSubmissionState((currentState) => ({
28
+ ...currentState,
29
+ confirmingBookingError: null,
30
+ }));
31
+ }, []);
32
+ const executePostSubmissionAction = React.useCallback(async (formSubmissionResult) => {
33
+ setPostSubmissionState((currentState) => ({
34
+ ...currentState,
35
+ formSubmissionResult,
36
+ isRunningPostSubmissionAction: true,
37
+ postSubmissionError: null,
38
+ }));
39
+ try {
40
+ await onDone({
41
+ ...formSubmissionResult,
42
+ scheduling: null,
43
+ });
44
+ }
45
+ catch (error) {
46
+ console.warn('Error while running post submission action', error);
47
+ setPostSubmissionState((currentState) => ({
48
+ ...currentState,
49
+ formSubmissionResult,
50
+ isRunningPostSubmissionAction: false,
51
+ postSubmissionError: error,
52
+ }));
53
+ }
54
+ }, [onDone]);
55
+ const handleConfirmedBooking = React.useCallback(async () => {
56
+ setPostSubmissionState((currentState) => ({
57
+ ...currentState,
58
+ isConfirmingBooking: true,
59
+ confirmingBookingError: null,
60
+ }));
61
+ try {
62
+ const formSubmissionResult = await onBookingConfirmed();
63
+ setPostSubmissionState((currentState) => ({
64
+ ...currentState,
65
+ formSubmissionResult,
66
+ }));
67
+ if (formSubmissionResult.payment) {
68
+ setTimeout(async () => {
69
+ executePostSubmissionAction(formSubmissionResult);
70
+ }, 2000);
71
+ }
72
+ else {
73
+ setPostSubmissionState((currentState) => ({
74
+ ...currentState,
75
+ isConfirmingBooking: false,
76
+ formSubmissionResult,
77
+ }));
78
+ }
79
+ }
80
+ catch (error) {
81
+ console.warn('Error while handling confirmed booking', error);
82
+ setPostSubmissionState((currentState) => ({
83
+ ...currentState,
84
+ isConfirmingBooking: false,
85
+ confirmingBookingError: error,
86
+ }));
87
+ }
88
+ }, [onBookingConfirmed, executePostSubmissionAction]);
89
+ return (React.createElement(React.Fragment, null,
90
+ React.createElement(Collapse, { in: isConfirmingBooking },
91
+ React.createElement("div", { className: "has-margin-top-1" },
92
+ React.createElement("div", { className: "cypress-loading has-text-centered" },
93
+ React.createElement(OnLoading, { className: "has-text-centered" }),
94
+ React.createElement(Fade, { in: !!(formSubmissionResult === null || formSubmissionResult === void 0 ? void 0 : formSubmissionResult.payment) },
95
+ React.createElement("span", null, "Redirecting to payment"))))),
96
+ React.createElement("div", { className: "ob-scheduling-booking-form" },
97
+ !(formSubmissionResult === null || formSubmissionResult === void 0 ? void 0 : formSubmissionResult.payment) && (React.createElement(NylasScheduling, { eventOverrides: {
98
+ timeslotConfirmed: onTimeSlotConfirmed,
99
+ bookedEventInfo: async (event) => {
100
+ var _a;
101
+ event.preventDefault();
102
+ if (event.detail.error) {
103
+ setBookingError((_a = event.detail.error.message) !== null && _a !== void 0 ? _a : 'Calendar Booking Error');
104
+ }
105
+ else {
106
+ await handleConfirmedBooking();
107
+ }
108
+ },
109
+ }, bookingInfo: {
110
+ primaryParticipant: {
111
+ name: name !== null && name !== void 0 ? name : '',
112
+ email: email !== null && email !== void 0 ? email : '',
113
+ },
114
+ additionalFields: {
115
+ submissionId: {
116
+ value: submissionId,
117
+ type: 'text',
118
+ },
119
+ },
120
+ }, enableUserFeedback: false, configurationId: configurationId, sessionId: sessionId, nylasBranding: false })),
121
+ formSubmissionResult && !formSubmissionResult.payment && (React.createElement(Receipt, { className: "ob-scheduling-receipt", containerClassName: "ob-scheduling-receipt__container" },
122
+ React.createElement("div", { className: "buttons" },
123
+ React.createElement("button", { type: "button", className: clsx('is-primary button ob-button ob-scheduling-receipt__button ob-scheduling-receipt__okay-button cypress-scheduling-receipt-okay-button', { 'is-loading': isRunningPostSubmissionAction }), disabled: isRunningPostSubmissionAction, onClick: () => executePostSubmissionAction(formSubmissionResult) }, "Done")))),
124
+ React.createElement(ErrorModal, { error: postSubmissionError, onClose: clearPostSubmissionError }),
125
+ React.createElement(ErrorModal, { error: confirmingBookingError, onClose: clearConfirmingBookingError }))));
126
+ }
127
+ function CalendarBookingsForm({ onDone, }) {
128
+ return (React.createElement(CalendarBookingsContainer, { fetchConfiguration: schedulingService.createNylasNewBookingSession }, (props) => React.createElement(NylasBookingForm, { ...props, onDone: onDone })));
129
+ }
130
+ export default React.memo(CalendarBookingsForm);
131
+ //# sourceMappingURL=CalendarBookingsForm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CalendarBookingsForm.js","sourceRoot":"","sources":["../../../src/components/calendar-bookings/CalendarBookingsForm.tsx"],"names":[],"mappings":"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","sourcesContent":["import * as React from 'react'\nimport { NylasScheduling } from '@nylas/react'\nimport { Collapse, Fade } from '@mui/material'\nimport {\n schedulingService,\n submissionService,\n OneBlinkAppsError,\n} from '@oneblink/apps'\nimport clsx from 'clsx'\nimport { Receipt } from '../receipts'\nimport ErrorModal from './ErrorModal'\nimport OnLoading from '../renderer/OnLoading'\nimport CalendarBookingsContainer from './CalendarBookingsContainer'\nimport useCalendarBookings from './CalendarBookingsProvider'\n\nfunction NylasBookingForm({\n submissionId,\n name,\n email,\n configurationId,\n sessionId,\n onBookingConfirmed,\n onDone,\n}: Awaited<\n ReturnType<typeof schedulingService.createNylasNewBookingSession>\n> & {\n submissionId: string\n onDone: (\n formSubmissionResult: submissionService.FormSubmissionResult,\n ) => Promise<void>\n}) {\n const { setBookingError, onTimeSlotConfirmed } = useCalendarBookings()\n\n const [\n {\n formSubmissionResult,\n isRunningPostSubmissionAction,\n postSubmissionError,\n isConfirmingBooking,\n confirmingBookingError,\n },\n setPostSubmissionState,\n ] = React.useState<{\n formSubmissionResult: submissionService.FormSubmissionResult | null\n isRunningPostSubmissionAction: boolean\n postSubmissionError: OneBlinkAppsError | null\n isConfirmingBooking: boolean\n confirmingBookingError: OneBlinkAppsError | null\n }>({\n formSubmissionResult: null,\n isRunningPostSubmissionAction: false,\n postSubmissionError: null,\n isConfirmingBooking: false,\n confirmingBookingError: null,\n })\n const clearPostSubmissionError = React.useCallback(() => {\n setPostSubmissionState((currentState) => ({\n ...currentState,\n postSubmissionError: null,\n }))\n }, [])\n const clearConfirmingBookingError = React.useCallback(() => {\n setPostSubmissionState((currentState) => ({\n ...currentState,\n confirmingBookingError: null,\n }))\n }, [])\n\n const executePostSubmissionAction = React.useCallback(\n async (formSubmissionResult: submissionService.FormSubmissionResult) => {\n setPostSubmissionState((currentState) => ({\n ...currentState,\n formSubmissionResult,\n isRunningPostSubmissionAction: true,\n postSubmissionError: null,\n }))\n\n try {\n await onDone({\n ...formSubmissionResult,\n scheduling: null,\n })\n } catch (error) {\n console.warn('Error while running post submission action', error)\n setPostSubmissionState((currentState) => ({\n ...currentState,\n formSubmissionResult,\n isRunningPostSubmissionAction: false,\n postSubmissionError: error as OneBlinkAppsError,\n }))\n }\n },\n [onDone],\n )\n\n const handleConfirmedBooking = React.useCallback(async () => {\n setPostSubmissionState((currentState) => ({\n ...currentState,\n isConfirmingBooking: true,\n confirmingBookingError: null,\n }))\n\n try {\n const formSubmissionResult = await onBookingConfirmed()\n setPostSubmissionState((currentState) => ({\n ...currentState,\n formSubmissionResult,\n }))\n if (formSubmissionResult.payment) {\n setTimeout(async () => {\n executePostSubmissionAction(formSubmissionResult)\n }, 2000)\n } else {\n setPostSubmissionState((currentState) => ({\n ...currentState,\n isConfirmingBooking: false,\n formSubmissionResult,\n }))\n }\n } catch (error) {\n console.warn('Error while handling confirmed booking', error)\n setPostSubmissionState((currentState) => ({\n ...currentState,\n isConfirmingBooking: false,\n confirmingBookingError: error as OneBlinkAppsError,\n }))\n }\n }, [onBookingConfirmed, executePostSubmissionAction])\n\n return (\n <>\n <Collapse in={isConfirmingBooking}>\n <div className=\"has-margin-top-1\">\n <div className=\"cypress-loading has-text-centered\">\n <OnLoading className=\"has-text-centered\" />\n <Fade in={!!formSubmissionResult?.payment}>\n <span>Redirecting to payment</span>\n </Fade>\n </div>\n </div>\n </Collapse>\n\n <div className=\"ob-scheduling-booking-form\">\n {!formSubmissionResult?.payment && (\n <NylasScheduling\n eventOverrides={{\n timeslotConfirmed: onTimeSlotConfirmed,\n bookedEventInfo: async (event) => {\n event.preventDefault()\n\n if (event.detail.error) {\n setBookingError(\n event.detail.error.message ?? 'Calendar Booking Error',\n )\n } else {\n await handleConfirmedBooking()\n }\n },\n }}\n bookingInfo={{\n primaryParticipant: {\n name: name ?? '',\n email: email ?? '',\n },\n additionalFields: {\n submissionId: {\n value: submissionId,\n type: 'text',\n },\n },\n }}\n enableUserFeedback={false}\n configurationId={configurationId}\n sessionId={sessionId}\n nylasBranding={false}\n />\n )}\n\n {formSubmissionResult && !formSubmissionResult.payment && (\n <Receipt\n className=\"ob-scheduling-receipt\"\n containerClassName=\"ob-scheduling-receipt__container\"\n >\n <div className=\"buttons\">\n <button\n type=\"button\"\n className={clsx(\n 'is-primary button ob-button ob-scheduling-receipt__button ob-scheduling-receipt__okay-button cypress-scheduling-receipt-okay-button',\n { 'is-loading': isRunningPostSubmissionAction },\n )}\n disabled={isRunningPostSubmissionAction}\n onClick={() =>\n executePostSubmissionAction(formSubmissionResult)\n }\n >\n Done\n </button>\n </div>\n </Receipt>\n )}\n\n <ErrorModal\n error={postSubmissionError}\n onClose={clearPostSubmissionError}\n />\n\n <ErrorModal\n error={confirmingBookingError}\n onClose={clearConfirmingBookingError}\n />\n </div>\n </>\n )\n}\n\nfunction CalendarBookingsForm({\n onDone,\n}: {\n onDone: (\n formSubmissionResult: submissionService.FormSubmissionResult,\n ) => Promise<void>\n}) {\n return (\n <CalendarBookingsContainer\n fetchConfiguration={schedulingService.createNylasNewBookingSession}\n >\n {(props) => <NylasBookingForm {...props} onDone={onDone} />}\n </CalendarBookingsContainer>\n )\n}\n\nexport default React.memo(CalendarBookingsForm)\n"]}
@@ -0,0 +1,13 @@
1
+ import React, { ComponentProps } from 'react';
2
+ import { NylasScheduling } from '@nylas/react';
3
+ type CalendarBookingsContextProps = {
4
+ setBookingError: (errorString: string) => void;
5
+ onTimeSlotConfirmed: () => Promise<void>;
6
+ themeConfig: ComponentProps<typeof NylasScheduling>['themeConfig'];
7
+ };
8
+ export declare function CalendarBookingsProvider({ children, refreshNylasState, }: {
9
+ children: React.ReactNode;
10
+ refreshNylasState: () => void;
11
+ }): React.JSX.Element;
12
+ export default function useCalendarBookings(): CalendarBookingsContextProps;
13
+ export {};
@@ -0,0 +1,64 @@
1
+ import React, { useContext, createContext, useMemo, useCallback, } from 'react';
2
+ import { Snackbar, Alert, Button, useTheme } from '@mui/material';
3
+ import Color from 'color';
4
+ import useBooleanState from '../../hooks/useBooleanState';
5
+ const CalendarBookingsContext = createContext({
6
+ setBookingError: () => { },
7
+ onTimeSlotConfirmed: async () => { },
8
+ themeConfig: {},
9
+ });
10
+ export function CalendarBookingsProvider({ children, refreshNylasState, }) {
11
+ const [isShowingErrorSnack, showErrorSnack, hideErrorSnack] = useBooleanState(false);
12
+ const [bookingError, _setBookingError] = React.useState();
13
+ const setBookingError = useCallback((errorString) => {
14
+ _setBookingError(errorString);
15
+ showErrorSnack();
16
+ }, [showErrorSnack]);
17
+ /**
18
+ * The alternative here is to set the submissionId field to multi-line-text
19
+ * input then use the below css It works because the booking form only has 1
20
+ * multi-line-text input Unfortunately chrome won't allow :nth-child selectors
21
+ * on part() selectors ::part(nbf__textarea-component) { display: none; }
22
+ */
23
+ const onTimeSlotConfirmed = React.useCallback(async () => {
24
+ setTimeout(() => {
25
+ var _a, _b, _c, _d;
26
+ const submissionIdInputComponent = (_d = (_c = (_b = (_a = document
27
+ .querySelector('nylas-scheduling')) === null || _a === void 0 ? void 0 : _a.shadowRoot) === null || _b === void 0 ? void 0 : _b.querySelector('nylas-booking-form')) === null || _c === void 0 ? void 0 : _c.shadowRoot) === null || _d === void 0 ? void 0 : _d.querySelector('#submissionId');
28
+ if (submissionIdInputComponent) {
29
+ submissionIdInputComponent.style.display = 'none';
30
+ }
31
+ }, 50);
32
+ }, []);
33
+ const theme = useTheme();
34
+ const colorIsLight = useMemo(() => Color(theme.palette.primary.main).isLight(), [theme.palette.primary.main]);
35
+ const themeConfig = useMemo(() => {
36
+ const nylasTheme = {
37
+ '--nylas-info': theme.palette.info.main,
38
+ '--nylas-success': theme.palette.success.main,
39
+ '--nylas-warning': theme.palette.warning.main,
40
+ '--nylas-error': theme.palette.error.main,
41
+ '--nylas-font-family': theme.typography.fontFamily,
42
+ '--nylas-font-size': theme.typography.fontSize.toString(),
43
+ };
44
+ if (!colorIsLight) {
45
+ nylasTheme['--nylas-primary'] = theme.palette.primary.main;
46
+ }
47
+ return nylasTheme;
48
+ }, [theme.palette, colorIsLight, theme.typography]);
49
+ const value = useMemo(() => ({
50
+ setBookingError,
51
+ onTimeSlotConfirmed,
52
+ themeConfig,
53
+ }), [setBookingError, onTimeSlotConfirmed, themeConfig]);
54
+ return (React.createElement(CalendarBookingsContext.Provider, { value: value },
55
+ React.createElement(React.Fragment, null,
56
+ children,
57
+ React.createElement(Snackbar, { anchorOrigin: { vertical: 'bottom', horizontal: 'right' }, open: isShowingErrorSnack },
58
+ React.createElement(Alert, { onClose: hideErrorSnack, severity: 'error', elevation: 6, variant: "filled", action: React.createElement(Button, { color: "inherit", variant: "text", size: "small", onClick: refreshNylasState },
59
+ React.createElement("b", null, "Start Again")) }, bookingError)))));
60
+ }
61
+ export default function useCalendarBookings() {
62
+ return useContext(CalendarBookingsContext);
63
+ }
64
+ //# sourceMappingURL=CalendarBookingsProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CalendarBookingsProvider.js","sourceRoot":"","sources":["../../../src/components/calendar-bookings/CalendarBookingsProvider.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, {\n useContext,\n createContext,\n useMemo,\n useCallback,\n ComponentProps,\n} from 'react'\nimport { NylasScheduling } from '@nylas/react'\nimport { Snackbar, Alert, Button, useTheme } from '@mui/material'\nimport Color from 'color'\nimport useBooleanState from '../../hooks/useBooleanState'\n\ntype CalendarBookingsContextProps = {\n setBookingError: (errorString: string) => void\n onTimeSlotConfirmed: () => Promise<void>\n themeConfig: ComponentProps<typeof NylasScheduling>['themeConfig']\n}\n\nconst CalendarBookingsContext = createContext<CalendarBookingsContextProps>({\n setBookingError: () => {},\n onTimeSlotConfirmed: async () => {},\n themeConfig: {},\n})\n\nexport function CalendarBookingsProvider({\n children,\n refreshNylasState,\n}: {\n children: React.ReactNode\n refreshNylasState: () => void\n}) {\n const [isShowingErrorSnack, showErrorSnack, hideErrorSnack] =\n useBooleanState(false)\n const [bookingError, _setBookingError] = React.useState<string>()\n\n const setBookingError = useCallback(\n (errorString: string) => {\n _setBookingError(errorString)\n showErrorSnack()\n },\n [showErrorSnack],\n )\n\n /**\n * The alternative here is to set the submissionId field to multi-line-text\n * input then use the below css It works because the booking form only has 1\n * multi-line-text input Unfortunately chrome won't allow :nth-child selectors\n * on part() selectors ::part(nbf__textarea-component) { display: none; }\n */\n const onTimeSlotConfirmed = React.useCallback(async () => {\n setTimeout(() => {\n const submissionIdInputComponent = document\n .querySelector('nylas-scheduling')\n ?.shadowRoot?.querySelector('nylas-booking-form')\n ?.shadowRoot?.querySelector('#submissionId') as HTMLElement | undefined\n\n if (submissionIdInputComponent) {\n submissionIdInputComponent.style.display = 'none'\n }\n }, 50)\n }, [])\n\n const theme = useTheme()\n\n const colorIsLight = useMemo(\n () => Color(theme.palette.primary.main).isLight(),\n [theme.palette.primary.main],\n )\n\n const themeConfig = useMemo(() => {\n const nylasTheme: ComponentProps<typeof NylasScheduling>['themeConfig'] = {\n '--nylas-info': theme.palette.info.main,\n '--nylas-success': theme.palette.success.main,\n '--nylas-warning': theme.palette.warning.main,\n '--nylas-error': theme.palette.error.main,\n '--nylas-font-family': theme.typography.fontFamily,\n '--nylas-font-size': theme.typography.fontSize.toString(),\n }\n\n if (!colorIsLight) {\n nylasTheme['--nylas-primary'] = theme.palette.primary.main\n }\n return nylasTheme\n }, [theme.palette, colorIsLight, theme.typography])\n\n const value = useMemo(\n () => ({\n setBookingError,\n onTimeSlotConfirmed,\n themeConfig,\n }),\n [setBookingError, onTimeSlotConfirmed, themeConfig],\n )\n\n return (\n <CalendarBookingsContext.Provider value={value}>\n <>\n {children}\n <Snackbar\n anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}\n open={isShowingErrorSnack}\n >\n <Alert\n onClose={hideErrorSnack}\n severity={'error'}\n elevation={6}\n variant=\"filled\"\n action={\n <Button\n color=\"inherit\"\n variant=\"text\"\n size=\"small\"\n onClick={refreshNylasState}\n >\n <b>Start Again</b>\n </Button>\n }\n >\n {bookingError}\n </Alert>\n </Snackbar>\n </>\n </CalendarBookingsContext.Provider>\n )\n}\n\nexport default function useCalendarBookings() {\n return useContext(CalendarBookingsContext)\n}\n"]}
@@ -0,0 +1,4 @@
1
+ import React from 'react';
2
+ declare function ReschedulingForm(): React.JSX.Element;
3
+ declare const _default: React.MemoExoticComponent<typeof ReschedulingForm>;
4
+ export default _default;
@@ -0,0 +1,37 @@
1
+ import React from 'react';
2
+ import { NylasScheduling } from '@nylas/react';
3
+ import { schedulingService } from '@oneblink/apps';
4
+ import ErrorMessage from '../messages/ErrorMessage';
5
+ import CalendarBookingsContainer from './CalendarBookingsContainer';
6
+ import useCalendarBookings from './CalendarBookingsProvider';
7
+ function NylasReschedulingForm({ submissionId, name, email, sessionId, bookingRef, }) {
8
+ const { setBookingError, onTimeSlotConfirmed, themeConfig } = useCalendarBookings();
9
+ if (!bookingRef) {
10
+ return (React.createElement(ErrorMessage, { title: "Error Retrieving Data", gutterTop: true },
11
+ React.createElement("span", { className: "cypress-booking-ref-not-found-error-message" }, "Could not find a calendar booking to reschedule")));
12
+ }
13
+ return (React.createElement("div", { className: "ob-scheduling-booking-form" },
14
+ React.createElement(NylasScheduling, { sessionId: sessionId, eventOverrides: {
15
+ timeslotConfirmed: onTimeSlotConfirmed,
16
+ bookedEventInfo: async (event) => {
17
+ var _a;
18
+ event.preventDefault();
19
+ if (event.detail.error) {
20
+ setBookingError((_a = event.detail.error.message) !== null && _a !== void 0 ? _a : 'Calendar Booking Error');
21
+ }
22
+ },
23
+ }, bookingInfo: {
24
+ primaryParticipant: {
25
+ name: name !== null && name !== void 0 ? name : '',
26
+ email: email !== null && email !== void 0 ? email : '',
27
+ },
28
+ additionalFields: {
29
+ submissionId: { value: submissionId, type: 'text' },
30
+ },
31
+ }, themeConfig: themeConfig, enableUserFeedback: false, rescheduleBookingRef: bookingRef, nylasBranding: false })));
32
+ }
33
+ function ReschedulingForm() {
34
+ return (React.createElement(CalendarBookingsContainer, { fetchConfiguration: schedulingService.createNylasExistingBookingSession }, (props) => React.createElement(NylasReschedulingForm, { ...props })));
35
+ }
36
+ export default React.memo(ReschedulingForm);
37
+ //# sourceMappingURL=CalendarBookingsReschedulingForm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CalendarBookingsReschedulingForm.js","sourceRoot":"","sources":["../../../src/components/calendar-bookings/CalendarBookingsReschedulingForm.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AAClD,OAAO,YAAY,MAAM,0BAA0B,CAAA;AACnD,OAAO,yBAAyB,MAAM,6BAA6B,CAAA;AACnE,OAAO,mBAAmB,MAAM,4BAA4B,CAAA;AAE5D,SAAS,qBAAqB,CAAC,EAC7B,YAAY,EACZ,IAAI,EACJ,KAAK,EACL,SAAS,EACT,UAAU,GAKX;IACC,MAAM,EAAE,eAAe,EAAE,mBAAmB,EAAE,WAAW,EAAE,GACzD,mBAAmB,EAAE,CAAA;IAEvB,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,OAAO,CACL,oBAAC,YAAY,IAAC,KAAK,EAAC,uBAAuB,EAAC,SAAS;YACnD,8BAAM,SAAS,EAAC,6CAA6C,sDAEtD,CACM,CAChB,CAAA;IACH,CAAC;IAED,OAAO,CACL,6BAAK,SAAS,EAAC,4BAA4B;QACzC,oBAAC,eAAe,IACd,SAAS,EAAE,SAAS,EACpB,cAAc,EAAE;gBACd,iBAAiB,EAAE,mBAAmB;gBACtC,eAAe,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE;;oBAC/B,KAAK,CAAC,cAAc,EAAE,CAAA;oBACtB,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;wBACvB,eAAe,CACb,MAAA,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,mCAAI,wBAAwB,CACvD,CAAA;oBACH,CAAC;gBACH,CAAC;aACF,EACD,WAAW,EAAE;gBACX,kBAAkB,EAAE;oBAClB,IAAI,EAAE,IAAI,aAAJ,IAAI,cAAJ,IAAI,GAAI,EAAE;oBAChB,KAAK,EAAE,KAAK,aAAL,KAAK,cAAL,KAAK,GAAI,EAAE;iBACnB;gBACD,gBAAgB,EAAE;oBAChB,YAAY,EAAE,EAAE,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,EAAE;iBACpD;aACF,EACD,WAAW,EAAE,WAAW,EACxB,kBAAkB,EAAE,KAAK,EACzB,oBAAoB,EAAE,UAAU,EAChC,aAAa,EAAE,KAAK,GACpB,CACE,CACP,CAAA;AACH,CAAC;AAED,SAAS,gBAAgB;IACvB,OAAO,CACL,oBAAC,yBAAyB,IACxB,kBAAkB,EAAE,iBAAiB,CAAC,iCAAiC,IAEtE,CAAC,KAAK,EAAE,EAAE,CAAC,oBAAC,qBAAqB,OAAK,KAAK,GAAI,CACtB,CAC7B,CAAA;AACH,CAAC;AAED,eAAe,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAA","sourcesContent":["import React from 'react'\nimport { NylasScheduling } from '@nylas/react'\nimport { schedulingService } from '@oneblink/apps'\nimport ErrorMessage from '../messages/ErrorMessage'\nimport CalendarBookingsContainer from './CalendarBookingsContainer'\nimport useCalendarBookings from './CalendarBookingsProvider'\n\nfunction NylasReschedulingForm({\n submissionId,\n name,\n email,\n sessionId,\n bookingRef,\n}: Awaited<\n ReturnType<typeof schedulingService.createNylasExistingBookingSession>\n> & {\n submissionId: string\n}) {\n const { setBookingError, onTimeSlotConfirmed, themeConfig } =\n useCalendarBookings()\n\n if (!bookingRef) {\n return (\n <ErrorMessage title=\"Error Retrieving Data\" gutterTop>\n <span className=\"cypress-booking-ref-not-found-error-message\">\n Could not find a calendar booking to reschedule\n </span>\n </ErrorMessage>\n )\n }\n\n return (\n <div className=\"ob-scheduling-booking-form\">\n <NylasScheduling\n sessionId={sessionId}\n eventOverrides={{\n timeslotConfirmed: onTimeSlotConfirmed,\n bookedEventInfo: async (event) => {\n event.preventDefault()\n if (event.detail.error) {\n setBookingError(\n event.detail.error.message ?? 'Calendar Booking Error',\n )\n }\n },\n }}\n bookingInfo={{\n primaryParticipant: {\n name: name ?? '',\n email: email ?? '',\n },\n additionalFields: {\n submissionId: { value: submissionId, type: 'text' },\n },\n }}\n themeConfig={themeConfig}\n enableUserFeedback={false}\n rescheduleBookingRef={bookingRef}\n nylasBranding={false}\n />\n </div>\n )\n}\n\nfunction ReschedulingForm() {\n return (\n <CalendarBookingsContainer\n fetchConfiguration={schedulingService.createNylasExistingBookingSession}\n >\n {(props) => <NylasReschedulingForm {...props} />}\n </CalendarBookingsContainer>\n )\n}\n\nexport default React.memo(ReschedulingForm)\n"]}
@@ -0,0 +1,10 @@
1
+ import * as React from 'react';
2
+ import { OneBlinkAppsError } from '@oneblink/apps';
3
+ type Props = {
4
+ error: OneBlinkAppsError | Error | null;
5
+ closeButtonLabel?: string;
6
+ closeButtonClassName?: string;
7
+ onClose: () => unknown;
8
+ };
9
+ declare const _default: React.NamedExoticComponent<Props>;
10
+ export default _default;