@oneblink/apps-react 8.9.2-beta.5 → 8.10.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/dist/components/ImageCropper/CropModal.d.ts +9 -0
  2. package/dist/components/ImageCropper/CropModal.js +28 -0
  3. package/dist/components/ImageCropper/CropModal.js.map +1 -0
  4. package/dist/components/ImageCropper/index.d.ts +20 -0
  5. package/dist/components/ImageCropper/index.js +111 -0
  6. package/dist/components/ImageCropper/index.js.map +1 -0
  7. package/dist/components/ImageCropper/resource-components.d.ts +10 -0
  8. package/dist/components/ImageCropper/resource-components.js +30 -0
  9. package/dist/components/ImageCropper/resource-components.js.map +1 -0
  10. package/dist/components/renderer/AnnotationModal.d.ts +4 -0
  11. package/dist/components/renderer/AnnotationModal.js +26 -2
  12. package/dist/components/renderer/AnnotationModal.js.map +1 -1
  13. package/dist/components/renderer/LookupNotification.js +1 -1
  14. package/dist/components/renderer/LookupNotification.js.map +1 -1
  15. package/dist/components/renderer/attachments/DropdownMenu.d.ts +2 -0
  16. package/dist/components/renderer/attachments/DropdownMenu.js +14 -2
  17. package/dist/components/renderer/attachments/DropdownMenu.js.map +1 -1
  18. package/dist/components/renderer/attachments/FileCard.d.ts +3 -1
  19. package/dist/components/renderer/attachments/FileCard.js +2 -2
  20. package/dist/components/renderer/attachments/FileCard.js.map +1 -1
  21. package/dist/form-elements/FormElementCamera.js +66 -49
  22. package/dist/form-elements/FormElementCamera.js.map +1 -1
  23. package/dist/form-elements/FormElementFile.js +80 -2
  24. package/dist/form-elements/FormElementFile.js.map +1 -1
  25. package/dist/hooks/attachments/useAttachment.d.ts +1 -0
  26. package/dist/hooks/attachments/useAttachment.js +3 -0
  27. package/dist/hooks/attachments/useAttachment.js.map +1 -1
  28. package/dist/hooks/attachments/useAttachments.js +3 -3
  29. package/dist/hooks/attachments/useAttachments.js.map +1 -1
  30. package/dist/index.d.ts +1 -0
  31. package/dist/index.js +1 -0
  32. package/dist/index.js.map +1 -1
  33. package/dist/styles/camera.scss +31 -1
  34. package/dist/styles/downloadable-files.scss +4 -4
  35. package/dist/styles/utils.scss +4 -0
  36. package/dist/styles.css +39 -5
  37. package/package.json +2 -1
@@ -0,0 +1,9 @@
1
+ import * as React from 'react';
2
+ import { Area } from 'react-easy-crop';
3
+ declare function AnnotationModal({ imageSrc, onClose, onSave, }: {
4
+ imageSrc: string;
5
+ onClose: () => void;
6
+ onSave: (imageArea: Area) => void;
7
+ }): React.JSX.Element;
8
+ declare const _default: React.MemoExoticComponent<typeof AnnotationModal>;
9
+ export default _default;
@@ -0,0 +1,28 @@
1
+ import * as React from 'react';
2
+ import ImageCropper from '.';
3
+ import scrollingService from '../../services/scrolling-service';
4
+ function AnnotationModal({ imageSrc, onClose, onSave, }) {
5
+ const annotationContentElementRef = React.useRef(null);
6
+ const [croppedAreaPixels, setCroppedAreaPixels] = React.useState(null);
7
+ const handleSaveCrop = React.useCallback(async () => {
8
+ if (!croppedAreaPixels)
9
+ return;
10
+ onSave(croppedAreaPixels);
11
+ }, [croppedAreaPixels, onSave]);
12
+ React.useEffect(() => {
13
+ scrollingService.disableScrolling();
14
+ return () => {
15
+ scrollingService.enableScrolling();
16
+ };
17
+ }, []);
18
+ return (React.createElement("div", { className: "modal is-active" },
19
+ React.createElement("div", { className: "modal-background-faded" }),
20
+ React.createElement("div", { className: "ob-crop ob-border-radius" },
21
+ React.createElement("div", { ref: annotationContentElementRef, className: "ob-crop__content ob-border-radius" },
22
+ React.createElement(ImageCropper, { imgSrc: imageSrc, onCropComplete: setCroppedAreaPixels })),
23
+ React.createElement("div", { className: "ob-annotation__buttons ob-annotation__buttons-actions" },
24
+ React.createElement("button", { type: "button", className: "button is-light ob-button ob-annotation__button ob-annotation__button-action cypress-crop-cancel-button", onClick: onClose }, "Cancel"),
25
+ React.createElement("button", { type: "button", className: "button is-primary ob-button ob-annotation__button ob-annotation__button-action cypress-crop-save-button", disabled: !croppedAreaPixels, onClick: handleSaveCrop }, "Save")))));
26
+ }
27
+ export default React.memo(AnnotationModal);
28
+ //# sourceMappingURL=CropModal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CropModal.js","sourceRoot":"","sources":["../../../src/components/ImageCropper/CropModal.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,YAAY,MAAM,GAAG,CAAA;AAE5B,OAAO,gBAAgB,MAAM,kCAAkC,CAAA;AAE/D,SAAS,eAAe,CAAC,EACvB,QAAQ,EACR,OAAO,EACP,MAAM,GAKP;IACC,MAAM,2BAA2B,GAAG,KAAK,CAAC,MAAM,CAAiB,IAAI,CAAC,CAAA;IAEtE,MAAM,CAAC,iBAAiB,EAAE,oBAAoB,CAAC,GAAG,KAAK,CAAC,QAAQ,CAC9D,IAAI,CACL,CAAA;IAED,MAAM,cAAc,GAAG,KAAK,CAAC,WAAW,CAAC,KAAK,IAAI,EAAE;QAClD,IAAI,CAAC,iBAAiB;YAAE,OAAM;QAE9B,MAAM,CAAC,iBAAiB,CAAC,CAAA;IAC3B,CAAC,EAAE,CAAC,iBAAiB,EAAE,MAAM,CAAC,CAAC,CAAA;IAE/B,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACnB,gBAAgB,CAAC,gBAAgB,EAAE,CAAA;QAEnC,OAAO,GAAG,EAAE;YACV,gBAAgB,CAAC,eAAe,EAAE,CAAA;QACpC,CAAC,CAAA;IACH,CAAC,EAAE,EAAE,CAAC,CAAA;IAEN,OAAO,CACL,6BAAK,SAAS,EAAC,iBAAiB;QAC9B,6BAAK,SAAS,EAAC,wBAAwB,GAAO;QAC9C,6BAAK,SAAS,EAAC,0BAA0B;YACvC,6BACE,GAAG,EAAE,2BAA2B,EAChC,SAAS,EAAC,mCAAmC;gBAE7C,oBAAC,YAAY,IACX,MAAM,EAAE,QAAQ,EAChB,cAAc,EAAE,oBAAoB,GACpC,CACE;YACN,6BAAK,SAAS,EAAC,uDAAuD;gBACpE,gCACE,IAAI,EAAC,QAAQ,EACb,SAAS,EAAC,yGAAyG,EACnH,OAAO,EAAE,OAAO,aAGT;gBACT,gCACE,IAAI,EAAC,QAAQ,EACb,SAAS,EAAC,yGAAyG,EACnH,QAAQ,EAAE,CAAC,iBAAiB,EAC5B,OAAO,EAAE,cAAc,WAGhB,CACL,CACF,CACF,CACP,CAAA;AACH,CAAC;AAED,eAAe,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,CAAA","sourcesContent":["import * as React from 'react'\nimport ImageCropper from '.'\nimport { Area } from 'react-easy-crop'\nimport scrollingService from '../../services/scrolling-service'\n\nfunction AnnotationModal({\n imageSrc,\n onClose,\n onSave,\n}: {\n imageSrc: string\n onClose: () => void\n onSave: (imageArea: Area) => void\n}) {\n const annotationContentElementRef = React.useRef<HTMLDivElement>(null)\n\n const [croppedAreaPixels, setCroppedAreaPixels] = React.useState<Area | null>(\n null,\n )\n\n const handleSaveCrop = React.useCallback(async () => {\n if (!croppedAreaPixels) return\n\n onSave(croppedAreaPixels)\n }, [croppedAreaPixels, onSave])\n\n React.useEffect(() => {\n scrollingService.disableScrolling()\n\n return () => {\n scrollingService.enableScrolling()\n }\n }, [])\n\n return (\n <div className=\"modal is-active\">\n <div className=\"modal-background-faded\"></div>\n <div className=\"ob-crop ob-border-radius\">\n <div\n ref={annotationContentElementRef}\n className=\"ob-crop__content ob-border-radius\"\n >\n <ImageCropper\n imgSrc={imageSrc}\n onCropComplete={setCroppedAreaPixels}\n />\n </div>\n <div className=\"ob-annotation__buttons ob-annotation__buttons-actions\">\n <button\n type=\"button\"\n className=\"button is-light ob-button ob-annotation__button ob-annotation__button-action cypress-crop-cancel-button\"\n onClick={onClose}\n >\n Cancel\n </button>\n <button\n type=\"button\"\n className=\"button is-primary ob-button ob-annotation__button ob-annotation__button-action cypress-crop-save-button\"\n disabled={!croppedAreaPixels}\n onClick={handleSaveCrop}\n >\n Save\n </button>\n </div>\n </div>\n </div>\n )\n}\n\nexport default React.memo(AnnotationModal)\n"]}
@@ -0,0 +1,20 @@
1
+ import React from 'react';
2
+ import { Area, CropperProps } from 'react-easy-crop';
3
+ declare const _default: React.MemoExoticComponent<({ imgSrc, disabled, onCropComplete, outputAspectRatio, zoomWithScroll, cropperStyles, }: {
4
+ imgSrc: string;
5
+ disabled?: boolean;
6
+ onCropComplete: (croppedAreaPixels: Area) => void;
7
+ outputAspectRatio?: number;
8
+ zoomWithScroll?: boolean;
9
+ cropperStyles?: CropperProps["style"];
10
+ }) => React.JSX.Element>;
11
+ export default _default;
12
+ export declare const getAspectRatio: ({ width, height, }: {
13
+ width: number;
14
+ height: number;
15
+ }) => number;
16
+ export declare const generateCroppedImageBlob: ({ croppedAreaPixels, imgSrc, fileType, }: {
17
+ croppedAreaPixels: Area;
18
+ imgSrc: string;
19
+ fileType?: string;
20
+ }) => Promise<Blob | null>;
@@ -0,0 +1,111 @@
1
+ import React, { memo, useMemo } from 'react';
2
+ import Cropper from 'react-easy-crop';
3
+ import { CropContainer, ZoomSlider, SLIDER_WHEEL_INTERVAL_VALUE, } from './resource-components';
4
+ const defaultZoom = 1;
5
+ const defaultCrop = { x: 0, y: 0 };
6
+ const emptyFn = () => { };
7
+ // 2. Fix up styling and classes
8
+ const ImageCropper = ({ imgSrc, disabled, onCropComplete, outputAspectRatio, zoomWithScroll, cropperStyles, }) => {
9
+ const [crop, setCrop] = React.useState(defaultCrop);
10
+ const [zoom, setZoom] = React.useState(defaultZoom);
11
+ const [image, setImage] = React.useState(null);
12
+ React.useEffect(() => {
13
+ if (outputAspectRatio) {
14
+ // If we have a desired aspect ratio, we dont need to get it from the current image
15
+ return;
16
+ }
17
+ createImage(imgSrc)
18
+ .then(setImage)
19
+ .catch((error) => {
20
+ console.error('Error loading image to get aspect ratio for cropping', error);
21
+ });
22
+ }, [outputAspectRatio, imgSrc]);
23
+ const calculatedAspectRatio = useMemo(() => {
24
+ if (outputAspectRatio) {
25
+ return outputAspectRatio;
26
+ }
27
+ if (image) {
28
+ return getAspectRatio({
29
+ width: image.width,
30
+ height: image.height,
31
+ });
32
+ }
33
+ }, [outputAspectRatio, image]);
34
+ return (React.createElement("div", { className: "ob-cropper__container" },
35
+ React.createElement(CropContainer, { className: "ob-cropper__cropper-wrapper" },
36
+ React.createElement(Cropper, { image: imgSrc, crop: crop, zoom: zoom, aspect: calculatedAspectRatio, onCropChange: disabled ? emptyFn : setCrop, onCropComplete: (...args) => {
37
+ if (disabled) {
38
+ return;
39
+ }
40
+ onCropComplete(args[1]);
41
+ }, onZoomChange: setZoom, zoomSpeed: SLIDER_WHEEL_INTERVAL_VALUE, zoomWithScroll: zoomWithScroll, classes: {
42
+ containerClassName: 'ob-border-radius',
43
+ }, style: cropperStyles })),
44
+ React.createElement("div", { className: "ob-cropper__zoom-slider-wrapper" },
45
+ React.createElement(ZoomSlider, { value: zoom, setValue: setZoom, disabled: disabled }))));
46
+ };
47
+ export default memo(ImageCropper);
48
+ export const getAspectRatio = ({ width, height, }) => width / height;
49
+ const createImage = (url) => {
50
+ return new Promise((resolve, reject) => {
51
+ const image = new Image();
52
+ image.onload = () => {
53
+ resolve(image);
54
+ };
55
+ image.onerror = (error) => {
56
+ reject(error);
57
+ };
58
+ image.src = url;
59
+ return image;
60
+ });
61
+ };
62
+ export const generateCroppedImageBlob = async ({ croppedAreaPixels, imgSrc,
63
+ // width,
64
+ // height,
65
+ fileType, }) => {
66
+ if (!croppedAreaPixels || !imgSrc) {
67
+ return null;
68
+ }
69
+ // Source image/canvas
70
+ const image = await createImage(imgSrc);
71
+ const canvas = document.createElement('canvas');
72
+ const ctx = canvas.getContext('2d');
73
+ if (!ctx) {
74
+ return null;
75
+ }
76
+ canvas.width = image.width;
77
+ canvas.height = image.height;
78
+ ctx.drawImage(image, 0, 0);
79
+ // Destination image/canvas
80
+ const croppedCanvas = document.createElement('canvas');
81
+ const croppedCtx = croppedCanvas.getContext('2d');
82
+ if (!croppedCtx) {
83
+ return null;
84
+ }
85
+ croppedCanvas.width = croppedAreaPixels.width;
86
+ croppedCanvas.height = croppedAreaPixels.height;
87
+ // Draw the cropped source image onto the destination canvas
88
+ croppedCtx.drawImage(canvas,
89
+ // source x
90
+ croppedAreaPixels.x,
91
+ // source y
92
+ croppedAreaPixels.y,
93
+ // source width
94
+ croppedAreaPixels.width,
95
+ // source height
96
+ croppedAreaPixels.height,
97
+ // destination x
98
+ 0,
99
+ // destination y
100
+ 0,
101
+ // destination width
102
+ croppedAreaPixels.width,
103
+ // destination height
104
+ croppedAreaPixels.height);
105
+ return new Promise((resolve) => {
106
+ croppedCanvas.toBlob((file) => {
107
+ resolve(file);
108
+ }, fileType);
109
+ });
110
+ };
111
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/components/ImageCropper/index.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { memo, useMemo } from 'react'\nimport Cropper, { Area, Point, CropperProps } from 'react-easy-crop'\nimport {\n CropContainer,\n ZoomSlider,\n SLIDER_WHEEL_INTERVAL_VALUE,\n} from './resource-components'\n\nconst defaultZoom = 1\nconst defaultCrop = { x: 0, y: 0 }\n\nconst emptyFn = () => {}\n\n// 2. Fix up styling and classes\nconst ImageCropper = ({\n imgSrc,\n disabled,\n onCropComplete,\n outputAspectRatio,\n zoomWithScroll,\n cropperStyles,\n}: {\n imgSrc: string\n disabled?: boolean\n onCropComplete: (croppedAreaPixels: Area) => void\n outputAspectRatio?: number\n zoomWithScroll?: boolean\n cropperStyles?: CropperProps['style']\n}) => {\n const [crop, setCrop] = React.useState<Point>(defaultCrop)\n const [zoom, setZoom] = React.useState(defaultZoom)\n const [image, setImage] = React.useState<HTMLImageElement | null>(null)\n\n React.useEffect(() => {\n if (outputAspectRatio) {\n // If we have a desired aspect ratio, we dont need to get it from the current image\n return\n }\n createImage(imgSrc)\n .then(setImage)\n .catch((error) => {\n console.error(\n 'Error loading image to get aspect ratio for cropping',\n error,\n )\n })\n }, [outputAspectRatio, imgSrc])\n\n const calculatedAspectRatio = useMemo(() => {\n if (outputAspectRatio) {\n return outputAspectRatio\n }\n if (image) {\n return getAspectRatio({\n width: image.width,\n height: image.height,\n })\n }\n }, [outputAspectRatio, image])\n\n return (\n <div className=\"ob-cropper__container\">\n <CropContainer className=\"ob-cropper__cropper-wrapper\">\n <Cropper\n image={imgSrc}\n crop={crop}\n zoom={zoom}\n aspect={calculatedAspectRatio}\n onCropChange={disabled ? emptyFn : setCrop}\n onCropComplete={(...args) => {\n if (disabled) {\n return\n }\n onCropComplete(args[1])\n }}\n onZoomChange={setZoom}\n zoomSpeed={SLIDER_WHEEL_INTERVAL_VALUE}\n zoomWithScroll={zoomWithScroll}\n classes={{\n containerClassName: 'ob-border-radius',\n }}\n style={cropperStyles}\n />\n </CropContainer>\n <div className=\"ob-cropper__zoom-slider-wrapper\">\n <ZoomSlider value={zoom} setValue={setZoom} disabled={disabled} />\n </div>\n </div>\n )\n}\n\nexport default memo(ImageCropper)\n\nexport const getAspectRatio = ({\n width,\n height,\n}: {\n width: number\n height: number\n}) => width / height\n\nconst createImage = (url: string): Promise<HTMLImageElement> => {\n return new Promise((resolve, reject) => {\n const image = new Image()\n image.onload = () => {\n resolve(image)\n }\n image.onerror = (error) => {\n reject(error)\n }\n image.src = url\n return image\n })\n}\n\nexport const generateCroppedImageBlob = async ({\n croppedAreaPixels,\n imgSrc,\n // width,\n // height,\n fileType,\n}: {\n croppedAreaPixels: Area\n imgSrc: string\n // width: number\n // height: number\n fileType?: string\n}): Promise<Blob | null> => {\n if (!croppedAreaPixels || !imgSrc) {\n return null\n }\n // Source image/canvas\n const image = await createImage(imgSrc)\n const canvas = document.createElement('canvas')\n const ctx = canvas.getContext('2d')\n if (!ctx) {\n return null\n }\n canvas.width = image.width\n canvas.height = image.height\n ctx.drawImage(image, 0, 0)\n\n // Destination image/canvas\n const croppedCanvas = document.createElement('canvas')\n const croppedCtx = croppedCanvas.getContext('2d')\n if (!croppedCtx) {\n return null\n }\n croppedCanvas.width = croppedAreaPixels.width\n croppedCanvas.height = croppedAreaPixels.height\n\n // Draw the cropped source image onto the destination canvas\n croppedCtx.drawImage(\n canvas,\n // source x\n croppedAreaPixels.x,\n // source y\n croppedAreaPixels.y,\n // source width\n croppedAreaPixels.width,\n // source height\n croppedAreaPixels.height,\n // destination x\n 0,\n // destination y\n 0,\n // destination width\n croppedAreaPixels.width,\n // destination height\n croppedAreaPixels.height,\n )\n\n return new Promise((resolve) => {\n croppedCanvas.toBlob((file) => {\n resolve(file)\n }, fileType)\n })\n}\n"]}
@@ -0,0 +1,10 @@
1
+ import * as React from 'react';
2
+ export declare const CropContainer: import("@emotion/styled").StyledComponent<import("@mui/system").MUIStyledCommonProps<import("@mui/material").Theme> & {
3
+ height?: number;
4
+ }, React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
5
+ export declare const SLIDER_WHEEL_INTERVAL_VALUE: number;
6
+ export declare const ZoomSlider: ({ value, disabled, setValue, }: {
7
+ value: number;
8
+ disabled?: boolean;
9
+ setValue: (value: number) => void;
10
+ }) => React.JSX.Element;
@@ -0,0 +1,30 @@
1
+ import { styled, Stack, IconButton, Slider } from '@mui/material';
2
+ import MaterialIcon from '../MaterialIcon';
3
+ import * as React from 'react';
4
+ export const CropContainer = styled('div', {
5
+ shouldForwardProp: (prop) => prop !== 'height',
6
+ })(({ height }) => ({
7
+ position: 'relative',
8
+ width: '100%',
9
+ ...(height ? { height } : { flex: 1 }),
10
+ }));
11
+ const SLIDER_STEP_INTERVAL_VALUE = 0.025;
12
+ const SLIDER_MIN_VALUE = 1;
13
+ const SLIDER_MAX_VALUE = 3;
14
+ const SLIDER_BUTTON_INTERVAL_VALUE = SLIDER_STEP_INTERVAL_VALUE * 10;
15
+ export const SLIDER_WHEEL_INTERVAL_VALUE = SLIDER_STEP_INTERVAL_VALUE * 6;
16
+ export const ZoomSlider = ({ value, disabled = false, setValue, }) => {
17
+ return (React.createElement(Stack, { spacing: 2, direction: "row", alignItems: "center", justifyContent: "center", pt: 3 },
18
+ React.createElement(IconButton, { disabled: value === SLIDER_MIN_VALUE || disabled, onClick: () => {
19
+ const newValue = parseFloat((value - SLIDER_BUTTON_INTERVAL_VALUE).toFixed(3));
20
+ setValue(newValue < SLIDER_MIN_VALUE ? SLIDER_MIN_VALUE : newValue);
21
+ }, className: "ob-cropper__zoom-slider-minus-button" },
22
+ React.createElement(MaterialIcon, null, "remove")),
23
+ React.createElement(Slider, { "aria-label": "Image Zoom", value: value, min: SLIDER_MIN_VALUE, max: SLIDER_MAX_VALUE, step: SLIDER_STEP_INTERVAL_VALUE, onChange: (e, value) => typeof value === 'number' && setValue(value), disabled: disabled, className: "ob-cropper__zoom-slider" }),
24
+ React.createElement(IconButton, { disabled: value === SLIDER_MAX_VALUE || disabled, onClick: () => {
25
+ const newValue = parseFloat((value + SLIDER_BUTTON_INTERVAL_VALUE).toFixed(3));
26
+ setValue(newValue > SLIDER_MAX_VALUE ? SLIDER_MAX_VALUE : newValue);
27
+ }, className: "ob-cropper__zoom-slider-plus-button" },
28
+ React.createElement(MaterialIcon, null, "add"))));
29
+ };
30
+ //# sourceMappingURL=resource-components.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resource-components.js","sourceRoot":"","sources":["../../../src/components/ImageCropper/resource-components.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,eAAe,CAAA;AACjE,OAAO,YAAY,MAAM,iBAAiB,CAAA;AAC1C,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,MAAM,CAAC,MAAM,aAAa,GAAG,MAAM,CAAC,KAAK,EAAE;IACzC,iBAAiB,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,QAAQ;CAC/C,CAAC,CAAsB,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC;IACvC,QAAQ,EAAE,UAAU;IACpB,KAAK,EAAE,MAAM;IACb,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;CACvC,CAAC,CAAC,CAAA;AAEH,MAAM,0BAA0B,GAAG,KAAK,CAAA;AACxC,MAAM,gBAAgB,GAAG,CAAC,CAAA;AAC1B,MAAM,gBAAgB,GAAG,CAAC,CAAA;AAC1B,MAAM,4BAA4B,GAAG,0BAA0B,GAAG,EAAE,CAAA;AACpE,MAAM,CAAC,MAAM,2BAA2B,GAAG,0BAA0B,GAAG,CAAC,CAAA;AAEzE,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,EACzB,KAAK,EACL,QAAQ,GAAG,KAAK,EAChB,QAAQ,GAKT,EAAE,EAAE;IACH,OAAO,CACL,oBAAC,KAAK,IACJ,OAAO,EAAE,CAAC,EACV,SAAS,EAAC,KAAK,EACf,UAAU,EAAC,QAAQ,EACnB,cAAc,EAAC,QAAQ,EACvB,EAAE,EAAE,CAAC;QAEL,oBAAC,UAAU,IACT,QAAQ,EAAE,KAAK,KAAK,gBAAgB,IAAI,QAAQ,EAChD,OAAO,EAAE,GAAG,EAAE;gBACZ,MAAM,QAAQ,GAAG,UAAU,CACzB,CAAC,KAAK,GAAG,4BAA4B,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAClD,CAAA;gBACD,QAAQ,CAAC,QAAQ,GAAG,gBAAgB,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAA;YACrE,CAAC,EACD,SAAS,EAAC,sCAAsC;YAEhD,oBAAC,YAAY,iBAAsB,CACxB;QACb,oBAAC,MAAM,kBACM,YAAY,EACvB,KAAK,EAAE,KAAK,EACZ,GAAG,EAAE,gBAAgB,EACrB,GAAG,EAAE,gBAAgB,EACrB,IAAI,EAAE,0BAA0B,EAChC,QAAQ,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,QAAQ,CAAC,KAAK,CAAC,EACpE,QAAQ,EAAE,QAAQ,EAClB,SAAS,EAAC,yBAAyB,GACnC;QACF,oBAAC,UAAU,IACT,QAAQ,EAAE,KAAK,KAAK,gBAAgB,IAAI,QAAQ,EAChD,OAAO,EAAE,GAAG,EAAE;gBACZ,MAAM,QAAQ,GAAG,UAAU,CACzB,CAAC,KAAK,GAAG,4BAA4B,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAClD,CAAA;gBACD,QAAQ,CAAC,QAAQ,GAAG,gBAAgB,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAA;YACrE,CAAC,EACD,SAAS,EAAC,qCAAqC;YAE/C,oBAAC,YAAY,cAAmB,CACrB,CACP,CACT,CAAA;AACH,CAAC,CAAA","sourcesContent":["import { styled, Stack, IconButton, Slider } from '@mui/material'\nimport MaterialIcon from '../MaterialIcon'\nimport * as React from 'react'\n\nexport const CropContainer = styled('div', {\n shouldForwardProp: (prop) => prop !== 'height',\n})<{ height?: number }>(({ height }) => ({\n position: 'relative',\n width: '100%',\n ...(height ? { height } : { flex: 1 }),\n}))\n\nconst SLIDER_STEP_INTERVAL_VALUE = 0.025\nconst SLIDER_MIN_VALUE = 1\nconst SLIDER_MAX_VALUE = 3\nconst SLIDER_BUTTON_INTERVAL_VALUE = SLIDER_STEP_INTERVAL_VALUE * 10\nexport const SLIDER_WHEEL_INTERVAL_VALUE = SLIDER_STEP_INTERVAL_VALUE * 6\n\nexport const ZoomSlider = ({\n value,\n disabled = false,\n setValue,\n}: {\n value: number\n disabled?: boolean\n setValue: (value: number) => void\n}) => {\n return (\n <Stack\n spacing={2}\n direction=\"row\"\n alignItems=\"center\"\n justifyContent=\"center\"\n pt={3}\n >\n <IconButton\n disabled={value === SLIDER_MIN_VALUE || disabled}\n onClick={() => {\n const newValue = parseFloat(\n (value - SLIDER_BUTTON_INTERVAL_VALUE).toFixed(3),\n )\n setValue(newValue < SLIDER_MIN_VALUE ? SLIDER_MIN_VALUE : newValue)\n }}\n className=\"ob-cropper__zoom-slider-minus-button\"\n >\n <MaterialIcon>remove</MaterialIcon>\n </IconButton>\n <Slider\n aria-label=\"Image Zoom\"\n value={value}\n min={SLIDER_MIN_VALUE}\n max={SLIDER_MAX_VALUE}\n step={SLIDER_STEP_INTERVAL_VALUE}\n onChange={(e, value) => typeof value === 'number' && setValue(value)}\n disabled={disabled}\n className=\"ob-cropper__zoom-slider\"\n />\n <IconButton\n disabled={value === SLIDER_MAX_VALUE || disabled}\n onClick={() => {\n const newValue = parseFloat(\n (value + SLIDER_BUTTON_INTERVAL_VALUE).toFixed(3),\n )\n setValue(newValue > SLIDER_MAX_VALUE ? SLIDER_MAX_VALUE : newValue)\n }}\n className=\"ob-cropper__zoom-slider-plus-button\"\n >\n <MaterialIcon>add</MaterialIcon>\n </IconButton>\n </Stack>\n )\n}\n"]}
@@ -6,3 +6,7 @@ declare function AnnotationModal({ imageSrc, onClose, onSave, }: {
6
6
  }): React.JSX.Element;
7
7
  declare const _default: React.MemoExoticComponent<typeof AnnotationModal>;
8
8
  export default _default;
9
+ export declare const superimposeAnnotationOnImage: ({ annotationDataUri, attachmentUrl, }: {
10
+ annotationDataUri: string;
11
+ attachmentUrl: string;
12
+ }) => Promise<Blob | undefined>;
@@ -3,6 +3,7 @@ import clsx from 'clsx';
3
3
  import SignatureCanvas from 'react-signature-canvas';
4
4
  import useBooleanState from '../../hooks/useBooleanState';
5
5
  import scrollingService from '../../services/scrolling-service';
6
+ import { canvasToBlob } from '../../services/blob-utils';
6
7
  const annotationButtonColours = [
7
8
  '#000000',
8
9
  '#ffffff',
@@ -85,8 +86,8 @@ function AnnotationModal({ imageSrc, onClose, onSave, }) {
85
86
  }, [imageSrc]);
86
87
  return (React.createElement("div", { className: "modal is-active" },
87
88
  React.createElement("div", { className: "modal-background-faded" }),
88
- React.createElement("div", { className: "ob-annotation" },
89
- React.createElement("div", { className: "ob-annotation__buttons ob-annotation__buttons-colours" }, annotationButtonColours.map((colour, index) => {
89
+ React.createElement("div", { className: "ob-annotation ob-border-radius" },
90
+ React.createElement("div", { className: "ob-annotation__buttons ob-annotation__buttons-colours ob-border-radius" }, annotationButtonColours.map((colour, index) => {
90
91
  return (React.createElement("button", { key: index, type: "button", className: clsx('button ob-annotation__button ob-annotation__button-colour cypress-annotation-colour-button', {
91
92
  'is-selected': penColour === colour,
92
93
  }), onClick: () => setPenColour(colour), style: { backgroundColor: colour } }));
@@ -99,4 +100,27 @@ function AnnotationModal({ imageSrc, onClose, onSave, }) {
99
100
  React.createElement("button", { type: "button", className: "button is-primary ob-button ob-annotation__button ob-annotation__button-action cypress-annotation-save-button", disabled: !isDirty, onClick: handleSaveAnnotation }, "Save")))));
100
101
  }
101
102
  export default React.memo(AnnotationModal);
103
+ export const superimposeAnnotationOnImage = async ({ annotationDataUri, attachmentUrl, }) => {
104
+ const canvas = document.createElement('canvas');
105
+ const ctx = canvas.getContext('2d');
106
+ if (!ctx) {
107
+ return;
108
+ }
109
+ const image = new Image();
110
+ return new Promise((resolve, reject) => {
111
+ image.onload = function () {
112
+ canvas.width = image.width;
113
+ canvas.height = image.height;
114
+ ctx.drawImage(image, 0, 0);
115
+ const annotationImage = new Image();
116
+ annotationImage.onload = function () {
117
+ ctx.drawImage(annotationImage, 0, 0, canvas.width, canvas.height);
118
+ canvasToBlob(canvas).then(resolve).catch(reject);
119
+ };
120
+ annotationImage.src = annotationDataUri;
121
+ };
122
+ image.setAttribute('crossorigin', 'anonymous');
123
+ image.src = attachmentUrl;
124
+ });
125
+ };
102
126
  //# sourceMappingURL=AnnotationModal.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"AnnotationModal.js","sourceRoot":"","sources":["../../../src/components/renderer/AnnotationModal.tsx"],"names":[],"mappings":"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","sourcesContent":["import * as React from 'react'\nimport clsx from 'clsx'\nimport SignatureCanvas from 'react-signature-canvas'\n\nimport useBooleanState from '../../hooks/useBooleanState'\nimport scrollingService from '../../services/scrolling-service'\n\nconst annotationButtonColours = [\n '#000000',\n '#ffffff',\n '#f44336',\n '#e91e63',\n '#9c27b0',\n '#673ab7',\n '#3f51b5',\n '#2196f3',\n '#03a9f4',\n '#00bcd4',\n '#009688',\n '#4caf50',\n '#8bc34a',\n '#cddc39',\n '#ffee58',\n '#ffca28',\n '#ffa726',\n '#ff5722',\n]\n\nfunction AnnotationModal({\n imageSrc,\n onClose,\n onSave,\n}: {\n imageSrc: string\n onClose: () => void\n onSave: (newValue: string) => void\n}) {\n const annotationContentElementRef = React.useRef<HTMLDivElement>(null)\n const bmSignaturePadRef = React.useRef<HTMLDivElement>(null)\n const signatureCanvasRef = React.useRef<SignatureCanvas>(null)\n\n const [isDirty, setDirty] = useBooleanState(false)\n const [penColour, setPenColour] = React.useState(annotationButtonColours[0])\n\n const handleCancelAnnotation = React.useCallback(() => {\n if (signatureCanvasRef.current) {\n console.log('Clearing annotation...')\n signatureCanvasRef.current.clear()\n }\n onClose()\n }, [onClose])\n\n const handleSaveAnnotation = React.useCallback(() => {\n if (signatureCanvasRef.current) {\n onSave(signatureCanvasRef.current.toDataURL())\n }\n }, [onSave])\n\n // SETTING CANVAS FROM PASSED VALUE\n React.useEffect(() => {\n const annotationContentElement = annotationContentElementRef.current\n const bmSignaturePadElement = bmSignaturePadRef.current\n const signatureCanvas = signatureCanvasRef.current\n if (\n !annotationContentElement ||\n !bmSignaturePadElement ||\n !signatureCanvas ||\n typeof imageSrc !== 'string'\n ) {\n return\n }\n const canvasElement = signatureCanvas.getCanvas()\n\n // Disable scrolling to allow for smooth drawing\n scrollingService.disableScrolling()\n\n const maxWidth = annotationContentElement.clientWidth\n const maxHeight = annotationContentElement.clientHeight\n\n const i = new Image()\n i.onload = function () {\n const imageWidth = i.width\n const imageHeight = i.height\n let canvasWidth = imageWidth\n let canvasHeight = imageHeight\n\n if (imageWidth > maxWidth || imageHeight > maxHeight) {\n const widthRatio = maxWidth / imageWidth\n const heightRatio = maxHeight / imageHeight\n const ratio = Math.min(widthRatio, heightRatio)\n\n canvasWidth = ratio * imageWidth\n canvasHeight = ratio * imageHeight\n }\n\n bmSignaturePadElement.style.width = `${canvasWidth}px`\n bmSignaturePadElement.style.height = `${canvasHeight}px`\n bmSignaturePadElement.style.backgroundSize = 'cover'\n bmSignaturePadElement.style.backgroundImage = `url(${imageSrc})`\n canvasElement.width = canvasWidth\n canvasElement.height = canvasHeight\n }\n console.log('imageSrc', imageSrc)\n i.src = imageSrc\n\n return () => {\n scrollingService.enableScrolling()\n }\n }, [imageSrc])\n\n return (\n <div className=\"modal is-active\">\n <div className=\"modal-background-faded\"></div>\n <div className=\"ob-annotation\">\n <div className=\"ob-annotation__buttons ob-annotation__buttons-colours\">\n {annotationButtonColours.map((colour, index) => {\n return (\n <button\n key={index}\n type=\"button\"\n className={clsx(\n 'button ob-annotation__button ob-annotation__button-colour cypress-annotation-colour-button',\n {\n 'is-selected': penColour === colour,\n },\n )}\n onClick={() => setPenColour(colour)}\n style={{ backgroundColor: colour }}\n />\n )\n })}\n </div>\n <div\n ref={annotationContentElementRef}\n className=\"ob-annotation__content\"\n >\n <div\n ref={bmSignaturePadRef}\n className=\"ob-annotation__signature-pad cypress-annotation-signature-pad\"\n >\n <SignatureCanvas\n ref={signatureCanvasRef}\n clearOnResize={false}\n onEnd={setDirty}\n penColor={penColour}\n />\n </div>\n </div>\n <div className=\"ob-annotation__buttons ob-annotation__buttons-actions\">\n <button\n type=\"button\"\n className=\"button is-light ob-button ob-annotation__button ob-annotation__button-action cypress-annotation-cancel-button\"\n onClick={handleCancelAnnotation}\n >\n Cancel\n </button>\n <button\n type=\"button\"\n className=\"button is-primary ob-button ob-annotation__button ob-annotation__button-action cypress-annotation-save-button\"\n disabled={!isDirty}\n onClick={handleSaveAnnotation}\n >\n Save\n </button>\n </div>\n </div>\n </div>\n )\n}\n\nexport default React.memo(AnnotationModal)\n"]}
1
+ {"version":3,"file":"AnnotationModal.js","sourceRoot":"","sources":["../../../src/components/renderer/AnnotationModal.tsx"],"names":[],"mappings":"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","sourcesContent":["import * as React from 'react'\nimport clsx from 'clsx'\nimport SignatureCanvas from 'react-signature-canvas'\n\nimport useBooleanState from '../../hooks/useBooleanState'\nimport scrollingService from '../../services/scrolling-service'\nimport { canvasToBlob } from '../../services/blob-utils'\n\nconst annotationButtonColours = [\n '#000000',\n '#ffffff',\n '#f44336',\n '#e91e63',\n '#9c27b0',\n '#673ab7',\n '#3f51b5',\n '#2196f3',\n '#03a9f4',\n '#00bcd4',\n '#009688',\n '#4caf50',\n '#8bc34a',\n '#cddc39',\n '#ffee58',\n '#ffca28',\n '#ffa726',\n '#ff5722',\n]\n\nfunction AnnotationModal({\n imageSrc,\n onClose,\n onSave,\n}: {\n imageSrc: string\n onClose: () => void\n onSave: (newValue: string) => void\n}) {\n const annotationContentElementRef = React.useRef<HTMLDivElement>(null)\n const bmSignaturePadRef = React.useRef<HTMLDivElement>(null)\n const signatureCanvasRef = React.useRef<SignatureCanvas>(null)\n\n const [isDirty, setDirty] = useBooleanState(false)\n const [penColour, setPenColour] = React.useState(annotationButtonColours[0])\n\n const handleCancelAnnotation = React.useCallback(() => {\n if (signatureCanvasRef.current) {\n console.log('Clearing annotation...')\n signatureCanvasRef.current.clear()\n }\n onClose()\n }, [onClose])\n\n const handleSaveAnnotation = React.useCallback(() => {\n if (signatureCanvasRef.current) {\n onSave(signatureCanvasRef.current.toDataURL())\n }\n }, [onSave])\n\n // SETTING CANVAS FROM PASSED VALUE\n React.useEffect(() => {\n const annotationContentElement = annotationContentElementRef.current\n const bmSignaturePadElement = bmSignaturePadRef.current\n const signatureCanvas = signatureCanvasRef.current\n if (\n !annotationContentElement ||\n !bmSignaturePadElement ||\n !signatureCanvas ||\n typeof imageSrc !== 'string'\n ) {\n return\n }\n const canvasElement = signatureCanvas.getCanvas()\n\n // Disable scrolling to allow for smooth drawing\n scrollingService.disableScrolling()\n\n const maxWidth = annotationContentElement.clientWidth\n const maxHeight = annotationContentElement.clientHeight\n\n const i = new Image()\n i.onload = function () {\n const imageWidth = i.width\n const imageHeight = i.height\n let canvasWidth = imageWidth\n let canvasHeight = imageHeight\n\n if (imageWidth > maxWidth || imageHeight > maxHeight) {\n const widthRatio = maxWidth / imageWidth\n const heightRatio = maxHeight / imageHeight\n const ratio = Math.min(widthRatio, heightRatio)\n\n canvasWidth = ratio * imageWidth\n canvasHeight = ratio * imageHeight\n }\n\n bmSignaturePadElement.style.width = `${canvasWidth}px`\n bmSignaturePadElement.style.height = `${canvasHeight}px`\n bmSignaturePadElement.style.backgroundSize = 'cover'\n bmSignaturePadElement.style.backgroundImage = `url(${imageSrc})`\n canvasElement.width = canvasWidth\n canvasElement.height = canvasHeight\n }\n console.log('imageSrc', imageSrc)\n i.src = imageSrc\n\n return () => {\n scrollingService.enableScrolling()\n }\n }, [imageSrc])\n\n return (\n <div className=\"modal is-active\">\n <div className=\"modal-background-faded\"></div>\n <div className=\"ob-annotation ob-border-radius\">\n <div className=\"ob-annotation__buttons ob-annotation__buttons-colours ob-border-radius\">\n {annotationButtonColours.map((colour, index) => {\n return (\n <button\n key={index}\n type=\"button\"\n className={clsx(\n 'button ob-annotation__button ob-annotation__button-colour cypress-annotation-colour-button',\n {\n 'is-selected': penColour === colour,\n },\n )}\n onClick={() => setPenColour(colour)}\n style={{ backgroundColor: colour }}\n />\n )\n })}\n </div>\n <div\n ref={annotationContentElementRef}\n className=\"ob-annotation__content\"\n >\n <div\n ref={bmSignaturePadRef}\n className=\"ob-annotation__signature-pad cypress-annotation-signature-pad\"\n >\n <SignatureCanvas\n ref={signatureCanvasRef}\n clearOnResize={false}\n onEnd={setDirty}\n penColor={penColour}\n />\n </div>\n </div>\n <div className=\"ob-annotation__buttons ob-annotation__buttons-actions\">\n <button\n type=\"button\"\n className=\"button is-light ob-button ob-annotation__button ob-annotation__button-action cypress-annotation-cancel-button\"\n onClick={handleCancelAnnotation}\n >\n Cancel\n </button>\n <button\n type=\"button\"\n className=\"button is-primary ob-button ob-annotation__button ob-annotation__button-action cypress-annotation-save-button\"\n disabled={!isDirty}\n onClick={handleSaveAnnotation}\n >\n Save\n </button>\n </div>\n </div>\n </div>\n )\n}\n\nexport default React.memo(AnnotationModal)\n\nexport const superimposeAnnotationOnImage = async ({\n annotationDataUri,\n attachmentUrl,\n}: {\n annotationDataUri: string\n attachmentUrl: string\n}): Promise<Blob | undefined> => {\n const canvas = document.createElement('canvas')\n const ctx = canvas.getContext('2d')\n if (!ctx) {\n return\n }\n\n const image = new Image()\n return new Promise<Blob>((resolve, reject) => {\n image.onload = function () {\n canvas.width = image.width\n canvas.height = image.height\n\n ctx.drawImage(image, 0, 0)\n\n const annotationImage = new Image()\n annotationImage.onload = function () {\n ctx.drawImage(annotationImage, 0, 0, canvas.width, canvas.height)\n canvasToBlob(canvas).then(resolve).catch(reject)\n }\n annotationImage.src = annotationDataUri\n }\n image.setAttribute('crossorigin', 'anonymous')\n image.src = attachmentUrl\n })\n}\n"]}
@@ -166,7 +166,7 @@ function LookupNotificationComponent({ autoLookupValue, stringifyAutoLookupValue
166
166
  }
167
167
  setHasLookupFailed(true);
168
168
  mergeLookupData({
169
- newValue: model[element.name],
169
+ newValue: newValue,
170
170
  dataLookupResult: {},
171
171
  elementLookupResult: [],
172
172
  executedLookup: { [element.name]: false },
@@ -1 +1 @@
1
- {"version":3,"file":"LookupNotification.js","sourceRoot":"","sources":["../../../src/components/renderer/LookupNotification.tsx"],"names":[],"mappings":"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","sourcesContent":["import * as React from 'react'\nimport clsx from 'clsx'\nimport { generateHeaders } from '@oneblink/apps/dist/services/fetch'\nimport { Sentry, formService } from '@oneblink/apps'\nimport { FormTypes, SubmissionTypes } from '@oneblink/types'\n\nimport useIsOffline from '../../hooks/useIsOffline'\nimport OnLoading from './OnLoading'\nimport generateDefaultData from '../../services/generate-default-data'\nimport {\n LookupNotificationContext,\n LookupNotificationContextValue,\n} from '../../hooks/useLookupNotification'\nimport useFormDefinition from '../../hooks/useFormDefinition'\nimport useInjectPages from '../../hooks/useInjectPages'\nimport useFormSubmissionModel from '../../hooks/useFormSubmissionModelContext'\nimport useFormIsReadOnly from '../../hooks/useFormIsReadOnly'\nimport useIsMounted from '../../hooks/useIsMounted'\nimport useFormElementLookups from '../../hooks/useFormElementLookups'\nimport mergeExecutedLookups from '../../utils/merge-executed-lookups'\n\nimport { FormElementLookupHandler, ExecutedLookups } from '../../types/form'\nimport ErrorMessage from '../messages/ErrorMessage'\nimport MaterialIcon from '../MaterialIcon'\n\ntype FetchLookupPayload = {\n element: FormTypes.LookupFormElement\n definition?: FormTypes.Form\n submission: SubmissionTypes.S3SubmissionData['submission']\n}\ntype Props = {\n autoLookupValue?: unknown\n stringifyAutoLookupValue?: (autoLookupValue: unknown) => string\n element: FormTypes.LookupFormElement\n onLookup: FormElementLookupHandler\n children: React.ReactNode\n}\n\nfunction LookupNotificationComponent({\n autoLookupValue,\n stringifyAutoLookupValue,\n element,\n onLookup,\n children,\n}: Props) {\n const isMounted = useIsMounted()\n const isOffline = useIsOffline()\n const definition = useFormDefinition()\n const injectPagesAfter = useInjectPages()\n const { isLoading, formElementLookups, loadError, onTryAgain } =\n useFormElementLookups()\n\n const [onCancelLookup, setOnCancelLookup] = React.useState<\n (() => void) | undefined\n >(undefined)\n const [isLookingUp, setIsLookingUp] = React.useState(false)\n const [hasLookupFailed, setHasLookupFailed] = React.useState(false)\n const [hasLookupSucceeded, setHasLookupSucceeded] = React.useState(false)\n const [isCancellable, setIsCancellable] = React.useState(false)\n const [isDisabled, setIsDisabled] = React.useState(false)\n const [lookupErrorHTML, setLookupErrorHTML] = React.useState<string | null>(\n null,\n )\n const formIsReadOnly = useFormIsReadOnly()\n const { formSubmissionModel: model } = useFormSubmissionModel()\n\n const formElementElementLookup = React.useMemo(() => {\n return formElementLookups.find(\n ({ id }) => element.isElementLookup && id === element.elementLookupId,\n )\n }, [element.elementLookupId, element.isElementLookup, formElementLookups])\n\n const formElementDataLookup = React.useMemo(() => {\n return formElementLookups.find(\n ({ id }) => element.isDataLookup && id === element.dataLookupId,\n )\n }, [element.dataLookupId, element.isDataLookup, formElementLookups])\n\n const runLookupOnClear = React.useMemo<boolean>(() => {\n return !!(\n formElementDataLookup?.runLookupOnClear ||\n formElementElementLookup?.runLookupOnClear\n )\n }, [\n formElementDataLookup?.runLookupOnClear,\n formElementElementLookup?.runLookupOnClear,\n ])\n\n const excludeDefinition = React.useMemo(() => {\n return !!(\n (formElementDataLookup?.type !== 'STATIC_DATA' &&\n formElementDataLookup?.excludeDefinition) ||\n (formElementElementLookup?.type !== 'STATIC_DATA' &&\n formElementElementLookup?.excludeDefinition)\n )\n }, [formElementDataLookup, formElementElementLookup])\n\n const mergeLookupData = React.useCallback(\n ({\n newValue,\n dataLookupResult,\n elementLookupResult,\n executedLookup,\n }: {\n newValue: unknown\n dataLookupResult:\n | SubmissionTypes.S3SubmissionData['submission']\n | undefined\n elementLookupResult: FormTypes.FormElement[] | undefined\n executedLookup: ExecutedLookups\n }) => {\n const executedLookupResult = executedLookup?.[element.name]\n if (elementLookupResult && executedLookupResult !== false) {\n if (elementLookupResult[0] && elementLookupResult[0].type === 'page') {\n injectPagesAfter(\n element,\n elementLookupResult as FormTypes.PageElement[],\n dataLookupResult,\n )\n return\n }\n }\n\n onLookup(({ submission, elements, executedLookups }) => {\n let allElements: FormTypes.FormElement[] = elements\n if (\n Array.isArray(elementLookupResult) &&\n executedLookupResult !== false\n ) {\n const indexOfElement = elements.findIndex(\n ({ id }) => id === element.id,\n )\n if (indexOfElement === -1) {\n console.log('Could not find element', element)\n } else {\n // Filter out already injected elements if lookup was successful\n allElements = elements.filter(\n // @ts-expect-error Sorry typescript, we need to check a property you don't approve of :(\n (e) => e.injectedByElementId !== element.id,\n )\n allElements.splice(\n indexOfElement + 1,\n 0,\n ...elementLookupResult.map((e) => {\n // @ts-expect-error Sorry typescript, we need to check a property you don't approve of :(\n e.injectedByElementId = element.id\n return e\n }),\n )\n }\n }\n\n return {\n elements: allElements,\n submission: generateDefaultData(allElements, {\n ...submission,\n [element.name]: newValue,\n ...dataLookupResult,\n }),\n executedLookups: mergeExecutedLookups({\n dataLookupResult,\n currentSubmission: submission,\n executedLookups: {\n ...executedLookups,\n ...executedLookup,\n },\n }),\n }\n })\n },\n [element, injectPagesAfter, onLookup],\n )\n\n const isNotStaticLookup = React.useMemo(() => {\n return (\n (formElementDataLookup && formElementDataLookup.type !== 'STATIC_DATA') ||\n (formElementElementLookup &&\n formElementElementLookup.type !== 'STATIC_DATA')\n )\n }, [formElementDataLookup, formElementElementLookup])\n\n const triggerLookup = React.useCallback<\n LookupNotificationContextValue['onLookup']\n >(\n async ({ newValue, abortController, continueLookupOnAbort }) => {\n // No lookups for read only forms\n if (formIsReadOnly) return\n\n setIsLookingUp(true)\n\n if (isOffline && isNotStaticLookup) {\n setHasLookupFailed(true)\n return\n }\n\n setIsDisabled(true)\n setIsCancellable(false)\n setHasLookupFailed(false)\n setHasLookupSucceeded(false)\n setLookupErrorHTML(null)\n setOnCancelLookup(() => () => {\n if (isMounted.current) {\n setIsLookingUp(false)\n }\n abortController.abort()\n })\n\n // After certain amount of time, show the cancel button\n const isCancellableTimeout = setTimeout(() => {\n setIsCancellable(!abortController.signal.aborted)\n }, 5000)\n\n const payload: FetchLookupPayload = {\n element,\n definition: !excludeDefinition ? definition : undefined,\n submission: {\n ...model,\n [element.name]: newValue,\n },\n }\n\n try {\n const [dataLookupResult, elementLookupResult] = await Promise.all([\n fetchLookup(formElementDataLookup, payload, abortController.signal),\n fetchLookup(\n formElementElementLookup,\n payload,\n abortController.signal,\n ),\n ])\n\n mergeLookupData({\n newValue,\n dataLookupResult: dataLookupResult as\n | SubmissionTypes.S3SubmissionData['submission']\n | undefined,\n elementLookupResult: elementLookupResult as\n | FormTypes.FormElement[]\n | undefined,\n executedLookup: { [element.name]: true },\n })\n\n if (isMounted.current) {\n setHasLookupSucceeded(true)\n }\n\n // After certain amount of time, hide the lookup succeeded message\n setTimeout(() => {\n if (isMounted.current) {\n setIsLookingUp(false)\n }\n }, 750)\n } catch (error) {\n if (!isMounted.current) {\n return\n }\n\n if (abortController.signal.aborted) {\n console.log('Fetch aborted')\n if (!continueLookupOnAbort) {\n setIsLookingUp(false)\n }\n return\n }\n\n setHasLookupFailed(true)\n mergeLookupData({\n newValue: model[element.name],\n dataLookupResult: {},\n elementLookupResult: [],\n executedLookup: { [element.name]: false },\n })\n setLookupErrorHTML(\n typeof error === 'string'\n ? error\n : 'It looks like something went wrong.<br/>Please try again.<br />If the issue continues, please contact support.',\n )\n } finally {\n clearTimeout(isCancellableTimeout)\n if (isMounted.current) {\n setIsDisabled(false)\n setOnCancelLookup(undefined)\n }\n }\n },\n [\n definition,\n element,\n excludeDefinition,\n formElementDataLookup,\n formElementElementLookup,\n formIsReadOnly,\n isMounted,\n isNotStaticLookup,\n isOffline,\n mergeLookupData,\n model,\n ],\n )\n\n // For certain elements, do not add click event\n // instead, watch model for changes and trigger lookup function.\n // We add this stringify function here to allow the value to be\n // an object which may have a reference change, but the values\n // have not changed. e.g. the 'location' element's value\n const autoLookupValueString = React.useMemo(() => {\n if (stringifyAutoLookupValue) {\n return stringifyAutoLookupValue(autoLookupValue)\n } else {\n return autoLookupValue\n }\n }, [autoLookupValue, stringifyAutoLookupValue])\n React.useEffect(() => {\n if (isLoading || loadError) {\n return\n }\n const hasLookupRan = hasLookupFailed || hasLookupSucceeded\n\n // For lookups configured with `runLookupOnClear` set to true, we want to\n // allow empty values for `autoLookupValue`, but only if the lookup has\n // been ran previously. This prevents the lookup running on load with an empty value.\n if (\n (autoLookupValue === undefined || autoLookupValue === null) &&\n (!runLookupOnClear || !hasLookupRan)\n ) {\n setIsLookingUp(false)\n return\n }\n const abortController = new AbortController()\n triggerLookup({\n newValue: autoLookupValue,\n abortController,\n continueLookupOnAbort: true,\n })\n return () => {\n abortController.abort()\n }\n // Wants to use \"triggerLookup\" as a dependency,\n // however, this will change on any change made on any\n // element. Checking if \"value\" has changed is enough\n // to trigger a lookup when the correct dependencies change\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [autoLookupValueString, isLoading])\n\n const retryLookup = React.useCallback(() => {\n const abortController = new AbortController()\n triggerLookup({\n newValue: autoLookupValue,\n abortController,\n continueLookupOnAbort: true,\n })\n }, [autoLookupValue, triggerLookup])\n\n const contextValue = React.useMemo(\n () => ({\n isLookup: true,\n isDisabled,\n isLoading,\n onLookup: triggerLookup,\n allowLookupOnEmptyValue: runLookupOnClear,\n isLookingUp,\n }),\n [isDisabled, isLoading, runLookupOnClear, triggerLookup, isLookingUp],\n )\n\n return (\n <LookupNotificationContext.Provider value={contextValue}>\n {children}\n\n {loadError && (\n <ErrorMessage\n title=\"Error Loading Configuration\"\n onTryAgain={onTryAgain}\n >\n <span className=\"cypress-lookup-notification-loading-error\">\n {loadError.message}\n </span>\n </ErrorMessage>\n )}\n\n <div\n className={clsx('ob-lookup__notification', {\n 'is-looking-up': isLookingUp,\n 'is-extended':\n hasLookupFailed || (isCancellable && !hasLookupSucceeded),\n 'is-retryable':\n hasLookupFailed &&\n autoLookupValue !== undefined &&\n autoLookupValue !== null,\n })}\n >\n <div className=\"notification has-margin-top-7 has-text-centered\">\n {hasLookupFailed && (\n <>\n <button\n type=\"button\"\n className=\"delete fade-in\"\n onClick={() => setIsLookingUp(false)}\n aria-label=\"lookup-failure-close-button\"\n />\n\n <div>\n {isOffline && isNotStaticLookup ? (\n <div>\n <MaterialIcon className=\"fade-in has-text-warning\">\n wifi_off\n </MaterialIcon>\n <p className=\"fade-in\" role=\"alert\">\n It looks like you&apos;re offline. Please try again when\n connectivity is restored.\n </p>\n </div>\n ) : (\n <div>\n <MaterialIcon className=\"fade-in has-text-danger\">\n error_outline\n </MaterialIcon>\n <p\n role=\"alert\"\n className=\"fade-in\"\n // eslint-disable-next-line react/no-danger\n dangerouslySetInnerHTML={{\n __html: lookupErrorHTML || '',\n }}\n />\n {autoLookupValue !== undefined &&\n autoLookupValue !== null && (\n <button\n type=\"button\"\n className={clsx(\n 'fade-in button is-primary ob-lookup__retry-button cypress-retry-lookup-button has-margin-top-8',\n )}\n onClick={() => retryLookup()}\n disabled={isDisabled || isLoading}\n aria-label=\"lookup-retry-button\"\n >\n <span></span>\n <span className=\"icon\">\n <MaterialIcon className=\"refresh\">\n refresh\n </MaterialIcon>\n </span>\n <span>&nbsp;Retry Lookup</span>\n </button>\n )}\n </div>\n )}\n </div>\n </>\n )}\n\n {hasLookupSucceeded && (\n <>\n <MaterialIcon\n className=\"has-text-success fade-in\"\n role=\"status\"\n aria-label=\"lookup successful\"\n >\n check_circle_outline\n </MaterialIcon>\n </>\n )}\n\n {!hasLookupSucceeded && !hasLookupFailed && <OnLoading small />}\n\n {isCancellable && !hasLookupSucceeded && !hasLookupFailed && (\n <div className=\"has-margin-top-5 fade-in\" role=\"alert\">\n <p>Taking longer than expected?</p>\n <button\n type=\"button\"\n className=\"button has-margin-top-8\"\n onClick={onCancelLookup}\n >\n Cancel\n </button>\n </div>\n )}\n </div>\n </div>\n </LookupNotificationContext.Provider>\n )\n}\n\nexport default function LookupNotification(props: Props) {\n if (props.element.isDataLookup || props.element.isElementLookup) {\n return <LookupNotificationComponent {...props} />\n }\n\n return <>{props.children}</>\n}\n\nasync function fetchLookup(\n formElementLookup: formService.FormElementLookupResult | undefined,\n payload: FetchLookupPayload,\n abortSignal: AbortSignal,\n): Promise<\n | SubmissionTypes.S3SubmissionData['submission']\n | FormTypes.FormElement[]\n | undefined\n> {\n if (!formElementLookup) {\n return\n }\n\n if (formElementLookup.records) {\n const elementName = payload.element.name\n const inputValue = payload.submission[elementName]\n\n const matchingRecord = formElementLookup.records.find(\n (r) =>\n (r.inputType === 'UNDEFINED' && !inputValue) ||\n (r.inputType !== 'UNDEFINED' && r.inputValue === inputValue),\n )\n\n // insert prefill values\n return matchingRecord?.preFills.reduce<\n SubmissionTypes.S3SubmissionData['submission']\n >((lookupResult, prefill) => {\n switch (prefill.type) {\n case 'TEXT':\n lookupResult[prefill.formElementName] = prefill.text\n break\n case 'NUMBER':\n lookupResult[prefill.formElementName] = prefill.number\n break\n case 'CLEAR':\n lookupResult[prefill.formElementName] = undefined\n break\n }\n return lookupResult\n }, {})\n }\n\n if (!formElementLookup.url) {\n console.log(\n 'Could not find dynamic URL or static records for form element lookup:',\n formElementLookup,\n )\n throw new Error('Could not find element lookup configuration')\n }\n\n const headers = await generateHeaders()\n console.log(\n `Attempting a ${formElementLookup.type} lookup request to:`,\n formElementLookup.url,\n )\n const response = await fetch(formElementLookup.url, {\n method: 'POST',\n headers,\n body: JSON.stringify(payload),\n signal: abortSignal,\n })\n\n const data = await response.json()\n console.log(\n 'Response from lookup to: POST',\n formElementLookup.url,\n response.status,\n data,\n )\n\n if (!response.ok) {\n Sentry.captureException(\n new Error(`Received ${response.status} status code from lookup`),\n )\n if (response.status === 400 && data && data.message) {\n throw data.message\n }\n throw new Error('Invalid response from lookup')\n }\n\n return data as FormTypes.FormElement[]\n}\n"]}
1
+ {"version":3,"file":"LookupNotification.js","sourceRoot":"","sources":["../../../src/components/renderer/LookupNotification.tsx"],"names":[],"mappings":"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","sourcesContent":["import * as React from 'react'\nimport clsx from 'clsx'\nimport { generateHeaders } from '@oneblink/apps/dist/services/fetch'\nimport { Sentry, formService } from '@oneblink/apps'\nimport { FormTypes, SubmissionTypes } from '@oneblink/types'\n\nimport useIsOffline from '../../hooks/useIsOffline'\nimport OnLoading from './OnLoading'\nimport generateDefaultData from '../../services/generate-default-data'\nimport {\n LookupNotificationContext,\n LookupNotificationContextValue,\n} from '../../hooks/useLookupNotification'\nimport useFormDefinition from '../../hooks/useFormDefinition'\nimport useInjectPages from '../../hooks/useInjectPages'\nimport useFormSubmissionModel from '../../hooks/useFormSubmissionModelContext'\nimport useFormIsReadOnly from '../../hooks/useFormIsReadOnly'\nimport useIsMounted from '../../hooks/useIsMounted'\nimport useFormElementLookups from '../../hooks/useFormElementLookups'\nimport mergeExecutedLookups from '../../utils/merge-executed-lookups'\n\nimport { FormElementLookupHandler, ExecutedLookups } from '../../types/form'\nimport ErrorMessage from '../messages/ErrorMessage'\nimport MaterialIcon from '../MaterialIcon'\n\ntype FetchLookupPayload = {\n element: FormTypes.LookupFormElement\n definition?: FormTypes.Form\n submission: SubmissionTypes.S3SubmissionData['submission']\n}\ntype Props = {\n autoLookupValue?: unknown\n stringifyAutoLookupValue?: (autoLookupValue: unknown) => string\n element: FormTypes.LookupFormElement\n onLookup: FormElementLookupHandler\n children: React.ReactNode\n}\n\nfunction LookupNotificationComponent({\n autoLookupValue,\n stringifyAutoLookupValue,\n element,\n onLookup,\n children,\n}: Props) {\n const isMounted = useIsMounted()\n const isOffline = useIsOffline()\n const definition = useFormDefinition()\n const injectPagesAfter = useInjectPages()\n const { isLoading, formElementLookups, loadError, onTryAgain } =\n useFormElementLookups()\n\n const [onCancelLookup, setOnCancelLookup] = React.useState<\n (() => void) | undefined\n >(undefined)\n const [isLookingUp, setIsLookingUp] = React.useState(false)\n const [hasLookupFailed, setHasLookupFailed] = React.useState(false)\n const [hasLookupSucceeded, setHasLookupSucceeded] = React.useState(false)\n const [isCancellable, setIsCancellable] = React.useState(false)\n const [isDisabled, setIsDisabled] = React.useState(false)\n const [lookupErrorHTML, setLookupErrorHTML] = React.useState<string | null>(\n null,\n )\n const formIsReadOnly = useFormIsReadOnly()\n const { formSubmissionModel: model } = useFormSubmissionModel()\n\n const formElementElementLookup = React.useMemo(() => {\n return formElementLookups.find(\n ({ id }) => element.isElementLookup && id === element.elementLookupId,\n )\n }, [element.elementLookupId, element.isElementLookup, formElementLookups])\n\n const formElementDataLookup = React.useMemo(() => {\n return formElementLookups.find(\n ({ id }) => element.isDataLookup && id === element.dataLookupId,\n )\n }, [element.dataLookupId, element.isDataLookup, formElementLookups])\n\n const runLookupOnClear = React.useMemo<boolean>(() => {\n return !!(\n formElementDataLookup?.runLookupOnClear ||\n formElementElementLookup?.runLookupOnClear\n )\n }, [\n formElementDataLookup?.runLookupOnClear,\n formElementElementLookup?.runLookupOnClear,\n ])\n\n const excludeDefinition = React.useMemo(() => {\n return !!(\n (formElementDataLookup?.type !== 'STATIC_DATA' &&\n formElementDataLookup?.excludeDefinition) ||\n (formElementElementLookup?.type !== 'STATIC_DATA' &&\n formElementElementLookup?.excludeDefinition)\n )\n }, [formElementDataLookup, formElementElementLookup])\n\n const mergeLookupData = React.useCallback(\n ({\n newValue,\n dataLookupResult,\n elementLookupResult,\n executedLookup,\n }: {\n newValue: unknown\n dataLookupResult:\n | SubmissionTypes.S3SubmissionData['submission']\n | undefined\n elementLookupResult: FormTypes.FormElement[] | undefined\n executedLookup: ExecutedLookups\n }) => {\n const executedLookupResult = executedLookup?.[element.name]\n if (elementLookupResult && executedLookupResult !== false) {\n if (elementLookupResult[0] && elementLookupResult[0].type === 'page') {\n injectPagesAfter(\n element,\n elementLookupResult as FormTypes.PageElement[],\n dataLookupResult,\n )\n return\n }\n }\n\n onLookup(({ submission, elements, executedLookups }) => {\n let allElements: FormTypes.FormElement[] = elements\n if (\n Array.isArray(elementLookupResult) &&\n executedLookupResult !== false\n ) {\n const indexOfElement = elements.findIndex(\n ({ id }) => id === element.id,\n )\n if (indexOfElement === -1) {\n console.log('Could not find element', element)\n } else {\n // Filter out already injected elements if lookup was successful\n allElements = elements.filter(\n // @ts-expect-error Sorry typescript, we need to check a property you don't approve of :(\n (e) => e.injectedByElementId !== element.id,\n )\n allElements.splice(\n indexOfElement + 1,\n 0,\n ...elementLookupResult.map((e) => {\n // @ts-expect-error Sorry typescript, we need to check a property you don't approve of :(\n e.injectedByElementId = element.id\n return e\n }),\n )\n }\n }\n\n return {\n elements: allElements,\n submission: generateDefaultData(allElements, {\n ...submission,\n [element.name]: newValue,\n ...dataLookupResult,\n }),\n executedLookups: mergeExecutedLookups({\n dataLookupResult,\n currentSubmission: submission,\n executedLookups: {\n ...executedLookups,\n ...executedLookup,\n },\n }),\n }\n })\n },\n [element, injectPagesAfter, onLookup],\n )\n\n const isNotStaticLookup = React.useMemo(() => {\n return (\n (formElementDataLookup && formElementDataLookup.type !== 'STATIC_DATA') ||\n (formElementElementLookup &&\n formElementElementLookup.type !== 'STATIC_DATA')\n )\n }, [formElementDataLookup, formElementElementLookup])\n\n const triggerLookup = React.useCallback<\n LookupNotificationContextValue['onLookup']\n >(\n async ({ newValue, abortController, continueLookupOnAbort }) => {\n // No lookups for read only forms\n if (formIsReadOnly) return\n\n setIsLookingUp(true)\n\n if (isOffline && isNotStaticLookup) {\n setHasLookupFailed(true)\n return\n }\n\n setIsDisabled(true)\n setIsCancellable(false)\n setHasLookupFailed(false)\n setHasLookupSucceeded(false)\n setLookupErrorHTML(null)\n setOnCancelLookup(() => () => {\n if (isMounted.current) {\n setIsLookingUp(false)\n }\n abortController.abort()\n })\n\n // After certain amount of time, show the cancel button\n const isCancellableTimeout = setTimeout(() => {\n setIsCancellable(!abortController.signal.aborted)\n }, 5000)\n\n const payload: FetchLookupPayload = {\n element,\n definition: !excludeDefinition ? definition : undefined,\n submission: {\n ...model,\n [element.name]: newValue,\n },\n }\n\n try {\n const [dataLookupResult, elementLookupResult] = await Promise.all([\n fetchLookup(formElementDataLookup, payload, abortController.signal),\n fetchLookup(\n formElementElementLookup,\n payload,\n abortController.signal,\n ),\n ])\n\n mergeLookupData({\n newValue,\n dataLookupResult: dataLookupResult as\n | SubmissionTypes.S3SubmissionData['submission']\n | undefined,\n elementLookupResult: elementLookupResult as\n | FormTypes.FormElement[]\n | undefined,\n executedLookup: { [element.name]: true },\n })\n\n if (isMounted.current) {\n setHasLookupSucceeded(true)\n }\n\n // After certain amount of time, hide the lookup succeeded message\n setTimeout(() => {\n if (isMounted.current) {\n setIsLookingUp(false)\n }\n }, 750)\n } catch (error) {\n if (!isMounted.current) {\n return\n }\n\n if (abortController.signal.aborted) {\n console.log('Fetch aborted')\n if (!continueLookupOnAbort) {\n setIsLookingUp(false)\n }\n return\n }\n\n setHasLookupFailed(true)\n mergeLookupData({\n newValue: newValue,\n dataLookupResult: {},\n elementLookupResult: [],\n executedLookup: { [element.name]: false },\n })\n setLookupErrorHTML(\n typeof error === 'string'\n ? error\n : 'It looks like something went wrong.<br/>Please try again.<br />If the issue continues, please contact support.',\n )\n } finally {\n clearTimeout(isCancellableTimeout)\n if (isMounted.current) {\n setIsDisabled(false)\n setOnCancelLookup(undefined)\n }\n }\n },\n [\n definition,\n element,\n excludeDefinition,\n formElementDataLookup,\n formElementElementLookup,\n formIsReadOnly,\n isMounted,\n isNotStaticLookup,\n isOffline,\n mergeLookupData,\n model,\n ],\n )\n\n // For certain elements, do not add click event\n // instead, watch model for changes and trigger lookup function.\n // We add this stringify function here to allow the value to be\n // an object which may have a reference change, but the values\n // have not changed. e.g. the 'location' element's value\n const autoLookupValueString = React.useMemo(() => {\n if (stringifyAutoLookupValue) {\n return stringifyAutoLookupValue(autoLookupValue)\n } else {\n return autoLookupValue\n }\n }, [autoLookupValue, stringifyAutoLookupValue])\n React.useEffect(() => {\n if (isLoading || loadError) {\n return\n }\n const hasLookupRan = hasLookupFailed || hasLookupSucceeded\n\n // For lookups configured with `runLookupOnClear` set to true, we want to\n // allow empty values for `autoLookupValue`, but only if the lookup has\n // been ran previously. This prevents the lookup running on load with an empty value.\n if (\n (autoLookupValue === undefined || autoLookupValue === null) &&\n (!runLookupOnClear || !hasLookupRan)\n ) {\n setIsLookingUp(false)\n return\n }\n const abortController = new AbortController()\n triggerLookup({\n newValue: autoLookupValue,\n abortController,\n continueLookupOnAbort: true,\n })\n return () => {\n abortController.abort()\n }\n // Wants to use \"triggerLookup\" as a dependency,\n // however, this will change on any change made on any\n // element. Checking if \"value\" has changed is enough\n // to trigger a lookup when the correct dependencies change\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [autoLookupValueString, isLoading])\n\n const retryLookup = React.useCallback(() => {\n const abortController = new AbortController()\n triggerLookup({\n newValue: autoLookupValue,\n abortController,\n continueLookupOnAbort: true,\n })\n }, [autoLookupValue, triggerLookup])\n\n const contextValue = React.useMemo(\n () => ({\n isLookup: true,\n isDisabled,\n isLoading,\n onLookup: triggerLookup,\n allowLookupOnEmptyValue: runLookupOnClear,\n isLookingUp,\n }),\n [isDisabled, isLoading, runLookupOnClear, triggerLookup, isLookingUp],\n )\n\n return (\n <LookupNotificationContext.Provider value={contextValue}>\n {children}\n\n {loadError && (\n <ErrorMessage\n title=\"Error Loading Configuration\"\n onTryAgain={onTryAgain}\n >\n <span className=\"cypress-lookup-notification-loading-error\">\n {loadError.message}\n </span>\n </ErrorMessage>\n )}\n\n <div\n className={clsx('ob-lookup__notification', {\n 'is-looking-up': isLookingUp,\n 'is-extended':\n hasLookupFailed || (isCancellable && !hasLookupSucceeded),\n 'is-retryable':\n hasLookupFailed &&\n autoLookupValue !== undefined &&\n autoLookupValue !== null,\n })}\n >\n <div className=\"notification has-margin-top-7 has-text-centered\">\n {hasLookupFailed && (\n <>\n <button\n type=\"button\"\n className=\"delete fade-in\"\n onClick={() => setIsLookingUp(false)}\n aria-label=\"lookup-failure-close-button\"\n />\n\n <div>\n {isOffline && isNotStaticLookup ? (\n <div>\n <MaterialIcon className=\"fade-in has-text-warning\">\n wifi_off\n </MaterialIcon>\n <p className=\"fade-in\" role=\"alert\">\n It looks like you&apos;re offline. Please try again when\n connectivity is restored.\n </p>\n </div>\n ) : (\n <div>\n <MaterialIcon className=\"fade-in has-text-danger\">\n error_outline\n </MaterialIcon>\n <p\n role=\"alert\"\n className=\"fade-in\"\n // eslint-disable-next-line react/no-danger\n dangerouslySetInnerHTML={{\n __html: lookupErrorHTML || '',\n }}\n />\n {autoLookupValue !== undefined &&\n autoLookupValue !== null && (\n <button\n type=\"button\"\n className={clsx(\n 'fade-in button is-primary ob-lookup__retry-button cypress-retry-lookup-button has-margin-top-8',\n )}\n onClick={() => retryLookup()}\n disabled={isDisabled || isLoading}\n aria-label=\"lookup-retry-button\"\n >\n <span></span>\n <span className=\"icon\">\n <MaterialIcon className=\"refresh\">\n refresh\n </MaterialIcon>\n </span>\n <span>&nbsp;Retry Lookup</span>\n </button>\n )}\n </div>\n )}\n </div>\n </>\n )}\n\n {hasLookupSucceeded && (\n <>\n <MaterialIcon\n className=\"has-text-success fade-in\"\n role=\"status\"\n aria-label=\"lookup successful\"\n >\n check_circle_outline\n </MaterialIcon>\n </>\n )}\n\n {!hasLookupSucceeded && !hasLookupFailed && <OnLoading small />}\n\n {isCancellable && !hasLookupSucceeded && !hasLookupFailed && (\n <div className=\"has-margin-top-5 fade-in\" role=\"alert\">\n <p>Taking longer than expected?</p>\n <button\n type=\"button\"\n className=\"button has-margin-top-8\"\n onClick={onCancelLookup}\n >\n Cancel\n </button>\n </div>\n )}\n </div>\n </div>\n </LookupNotificationContext.Provider>\n )\n}\n\nexport default function LookupNotification(props: Props) {\n if (props.element.isDataLookup || props.element.isElementLookup) {\n return <LookupNotificationComponent {...props} />\n }\n\n return <>{props.children}</>\n}\n\nasync function fetchLookup(\n formElementLookup: formService.FormElementLookupResult | undefined,\n payload: FetchLookupPayload,\n abortSignal: AbortSignal,\n): Promise<\n | SubmissionTypes.S3SubmissionData['submission']\n | FormTypes.FormElement[]\n | undefined\n> {\n if (!formElementLookup) {\n return\n }\n\n if (formElementLookup.records) {\n const elementName = payload.element.name\n const inputValue = payload.submission[elementName]\n\n const matchingRecord = formElementLookup.records.find(\n (r) =>\n (r.inputType === 'UNDEFINED' && !inputValue) ||\n (r.inputType !== 'UNDEFINED' && r.inputValue === inputValue),\n )\n\n // insert prefill values\n return matchingRecord?.preFills.reduce<\n SubmissionTypes.S3SubmissionData['submission']\n >((lookupResult, prefill) => {\n switch (prefill.type) {\n case 'TEXT':\n lookupResult[prefill.formElementName] = prefill.text\n break\n case 'NUMBER':\n lookupResult[prefill.formElementName] = prefill.number\n break\n case 'CLEAR':\n lookupResult[prefill.formElementName] = undefined\n break\n }\n return lookupResult\n }, {})\n }\n\n if (!formElementLookup.url) {\n console.log(\n 'Could not find dynamic URL or static records for form element lookup:',\n formElementLookup,\n )\n throw new Error('Could not find element lookup configuration')\n }\n\n const headers = await generateHeaders()\n console.log(\n `Attempting a ${formElementLookup.type} lookup request to:`,\n formElementLookup.url,\n )\n const response = await fetch(formElementLookup.url, {\n method: 'POST',\n headers,\n body: JSON.stringify(payload),\n signal: abortSignal,\n })\n\n const data = await response.json()\n console.log(\n 'Response from lookup to: POST',\n formElementLookup.url,\n response.status,\n data,\n )\n\n if (!response.ok) {\n Sentry.captureException(\n new Error(`Received ${response.status} status code from lookup`),\n )\n if (response.status === 400 && data && data.message) {\n throw data.message\n }\n throw new Error('Invalid response from lookup')\n }\n\n return data as FormTypes.FormElement[]\n}\n"]}
@@ -7,6 +7,8 @@ interface Props {
7
7
  onDownload?: () => void;
8
8
  onRetry?: () => void;
9
9
  attachmentUrl: string | null | undefined;
10
+ onAnnotate?: () => void;
11
+ onCrop?: () => void;
10
12
  }
11
13
  declare const _default: React.NamedExoticComponent<Props>;
12
14
  export default _default;
@@ -3,7 +3,7 @@ import clsx from 'clsx';
3
3
  import useBooleanState from '../../../hooks/useBooleanState';
4
4
  import useClickOutsideElement from '../../../hooks/useClickOutsideElement';
5
5
  import MaterialIcon from '../../MaterialIcon';
6
- const DropdownMenu = ({ element, onRemove, onDownload, onRetry, attachmentUrl, }) => {
6
+ const DropdownMenu = ({ element, onRemove, onDownload, onRetry, attachmentUrl, onAnnotate, onCrop, }) => {
7
7
  const dropDownRef = React.useRef(null);
8
8
  const [isShowingMore, showMore, hideMore] = useBooleanState(false);
9
9
  useClickOutsideElement(dropDownRef, React.useCallback(() => {
@@ -41,7 +41,19 @@ const DropdownMenu = ({ element, onRemove, onDownload, onRetry, attachmentUrl, }
41
41
  }), onClick: () => {
42
42
  hideMore();
43
43
  onRemove();
44
- }, role: "menuitem" }, "Remove"))))));
44
+ }, role: "menuitem" }, "Remove")),
45
+ onAnnotate && (React.createElement("a", { className: clsx('dropdown-item cypress-file-annotate-button', {
46
+ 'ob-files__menu-annotate-hidden': element.readOnly,
47
+ }), onClick: () => {
48
+ hideMore();
49
+ onAnnotate();
50
+ }, role: "menuitem" }, "Annotate")),
51
+ onCrop && (React.createElement("a", { className: clsx('dropdown-item cypress-file-crop-button', {
52
+ 'ob-files__menu-crop-hidden': element.readOnly,
53
+ }), onClick: () => {
54
+ hideMore();
55
+ onCrop();
56
+ }, role: "menuitem" }, "Crop"))))));
45
57
  };
46
58
  export default React.memo(DropdownMenu);
47
59
  //# sourceMappingURL=DropdownMenu.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"DropdownMenu.js","sourceRoot":"","sources":["../../../../src/components/renderer/attachments/DropdownMenu.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,IAAI,MAAM,MAAM,CAAA;AAEvB,OAAO,eAAe,MAAM,gCAAgC,CAAA;AAC5D,OAAO,sBAAsB,MAAM,uCAAuC,CAAA;AAC1E,OAAO,YAAY,MAAM,oBAAoB,CAAA;AAW7C,MAAM,YAAY,GAAG,CAAC,EACpB,OAAO,EACP,QAAQ,EACR,UAAU,EACV,OAAO,EACP,aAAa,GACP,EAAE,EAAE;IACV,MAAM,WAAW,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;IACtC,MAAM,CAAC,aAAa,EAAE,QAAQ,EAAE,QAAQ,CAAC,GAAG,eAAe,CAAC,KAAK,CAAC,CAAA;IAElE,sBAAsB,CACpB,WAAW,EACX,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE;QACrB,IAAI,aAAa,EAAE,CAAC;YAClB,QAAQ,EAAE,CAAA;QACZ,CAAC;IACH,CAAC,EAAE,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC,CAC9B,CAAA;IAED,OAAO,CACL,6BACE,SAAS,EAAE,IAAI,CAAC,kCAAkC,EAAE;YAClD,WAAW,EAAE,aAAa;SAC3B,CAAC,EACF,GAAG,EAAE,WAAW;QAEhB,6BAAK,SAAS,EAAC,kBAAkB;YAC/B,gCACE,IAAI,EAAC,QAAQ,EACb,SAAS,EAAC,uDAAuD,mBACnD,MAAM,mBACN,eAAe,EAC7B,OAAO,EAAE,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ;gBAE5C,oBAAC,YAAY,IAAC,SAAS,EAAC,qBAAqB,gBAAyB,CAC/D,CACL;QACN,6BAAK,SAAS,EAAC,eAAe,EAAC,IAAI,EAAC,MAAM;YACxC,6BAAK,SAAS,EAAC,kBAAkB;gBAC9B,OAAO,IAAI,CACV,2BACE,SAAS,EAAC,yCAAyC,EACnD,OAAO,EAAE,GAAG,EAAE;wBACZ,QAAQ,EAAE,CAAA;wBACV,OAAO,EAAE,CAAA;oBACX,CAAC,EACD,IAAI,EAAC,UAAU,YAGb,CACL;gBACA,UAAU,IAAI,CACb,2BACE,SAAS,EAAC,4CAA4C,EACtD,OAAO,EAAE,GAAG,EAAE;wBACZ,QAAQ,EAAE,CAAA;wBACV,UAAU,EAAE,CAAA;oBACd,CAAC,EACD,IAAI,EAAC,UAAU,eAGb,CACL;gBACA,aAAa,IAAI,CAChB,2BACE,IAAI,EAAE,aAAa,EACnB,MAAM,EAAC,QAAQ,EACf,GAAG,EAAC,YAAY,EAChB,SAAS,EAAC,wCAAwC,EAClD,KAAK,EAAE;wBACL,OAAO,EAAE,MAAM;wBACf,UAAU,EAAE,QAAQ;wBACpB,GAAG,EAAE,CAAC;qBACP,EACD,OAAO,EAAE,GAAG,EAAE;wBACZ,QAAQ,EAAE,CAAA;oBACZ,CAAC;oBAED,yCAAiB;oBACjB,oBAAC,YAAY,IAAC,SAAS,EAAC,YAAY,kBAA2B,CAC7D,CACL;gBACA,QAAQ,IAAI,CACX,2BACE,SAAS,EAAE,IAAI,CAAC,0CAA0C,EAAE;wBAC1D,8BAA8B,EAAE,OAAO,CAAC,QAAQ;qBACjD,CAAC,EACF,OAAO,EAAE,GAAG,EAAE;wBACZ,QAAQ,EAAE,CAAA;wBACV,QAAQ,EAAE,CAAA;oBACZ,CAAC,EACD,IAAI,EAAC,UAAU,aAGb,CACL,CACG,CACF,CACF,CACP,CAAA;AACH,CAAC,CAAA;AAED,eAAe,KAAK,CAAC,IAAI,CAAQ,YAAY,CAAC,CAAA","sourcesContent":["import * as React from 'react'\nimport clsx from 'clsx'\nimport { FormTypes } from '@oneblink/types'\nimport useBooleanState from '../../../hooks/useBooleanState'\nimport useClickOutsideElement from '../../../hooks/useClickOutsideElement'\nimport MaterialIcon from '../../MaterialIcon'\n\ninterface Props {\n element: FormTypes.FilesElement\n /** If set to `undefined`, the remove button will be hidden */\n onRemove: (() => void) | undefined\n onDownload?: () => void\n onRetry?: () => void\n attachmentUrl: string | null | undefined\n}\n\nconst DropdownMenu = ({\n element,\n onRemove,\n onDownload,\n onRetry,\n attachmentUrl,\n}: Props) => {\n const dropDownRef = React.useRef(null)\n const [isShowingMore, showMore, hideMore] = useBooleanState(false)\n\n useClickOutsideElement(\n dropDownRef,\n React.useCallback(() => {\n if (isShowingMore) {\n hideMore()\n }\n }, [hideMore, isShowingMore]),\n )\n\n return (\n <div\n className={clsx('dropdown is-right ob-files__menu', {\n 'is-active': isShowingMore,\n })}\n ref={dropDownRef}\n >\n <div className=\"dropdown-trigger\">\n <button\n type=\"button\"\n className=\"button ob-files__menu-button cypress-file-menu-button\"\n aria-haspopup=\"true\"\n aria-controls=\"dropdown-menu\"\n onClick={isShowingMore ? hideMore : showMore}\n >\n <MaterialIcon className=\"ob-files__menu-icon\">more_vert</MaterialIcon>\n </button>\n </div>\n <div className=\"dropdown-menu\" role=\"menu\">\n <div className=\"dropdown-content\">\n {onRetry && (\n <a\n className=\"dropdown-item cypress-file-retry-button\"\n onClick={() => {\n hideMore()\n onRetry()\n }}\n role=\"menuitem\"\n >\n Retry\n </a>\n )}\n {onDownload && (\n <a\n className=\"dropdown-item cypress-file-download-button\"\n onClick={() => {\n hideMore()\n onDownload()\n }}\n role=\"menuitem\"\n >\n Download\n </a>\n )}\n {attachmentUrl && (\n <a\n href={attachmentUrl}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"dropdown-item cypress-file-open-button\"\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 2,\n }}\n onClick={() => {\n hideMore()\n }}\n >\n <span>Open</span>\n <MaterialIcon className=\"icon-small\">open_in_new</MaterialIcon>\n </a>\n )}\n {onRemove && (\n <a\n className={clsx('dropdown-item cypress-file-remove-button', {\n 'ob-files__menu-remove-hidden': element.readOnly,\n })}\n onClick={() => {\n hideMore()\n onRemove()\n }}\n role=\"menuitem\"\n >\n Remove\n </a>\n )}\n </div>\n </div>\n </div>\n )\n}\n\nexport default React.memo<Props>(DropdownMenu)\n"]}
1
+ {"version":3,"file":"DropdownMenu.js","sourceRoot":"","sources":["../../../../src/components/renderer/attachments/DropdownMenu.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,IAAI,MAAM,MAAM,CAAA;AAEvB,OAAO,eAAe,MAAM,gCAAgC,CAAA;AAC5D,OAAO,sBAAsB,MAAM,uCAAuC,CAAA;AAC1E,OAAO,YAAY,MAAM,oBAAoB,CAAA;AAa7C,MAAM,YAAY,GAAG,CAAC,EACpB,OAAO,EACP,QAAQ,EACR,UAAU,EACV,OAAO,EACP,aAAa,EACb,UAAU,EACV,MAAM,GACA,EAAE,EAAE;IACV,MAAM,WAAW,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;IACtC,MAAM,CAAC,aAAa,EAAE,QAAQ,EAAE,QAAQ,CAAC,GAAG,eAAe,CAAC,KAAK,CAAC,CAAA;IAElE,sBAAsB,CACpB,WAAW,EACX,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE;QACrB,IAAI,aAAa,EAAE,CAAC;YAClB,QAAQ,EAAE,CAAA;QACZ,CAAC;IACH,CAAC,EAAE,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC,CAC9B,CAAA;IAED,OAAO,CACL,6BACE,SAAS,EAAE,IAAI,CAAC,kCAAkC,EAAE;YAClD,WAAW,EAAE,aAAa;SAC3B,CAAC,EACF,GAAG,EAAE,WAAW;QAEhB,6BAAK,SAAS,EAAC,kBAAkB;YAC/B,gCACE,IAAI,EAAC,QAAQ,EACb,SAAS,EAAC,uDAAuD,mBACnD,MAAM,mBACN,eAAe,EAC7B,OAAO,EAAE,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ;gBAE5C,oBAAC,YAAY,IAAC,SAAS,EAAC,qBAAqB,gBAAyB,CAC/D,CACL;QACN,6BAAK,SAAS,EAAC,eAAe,EAAC,IAAI,EAAC,MAAM;YACxC,6BAAK,SAAS,EAAC,kBAAkB;gBAC9B,OAAO,IAAI,CACV,2BACE,SAAS,EAAC,yCAAyC,EACnD,OAAO,EAAE,GAAG,EAAE;wBACZ,QAAQ,EAAE,CAAA;wBACV,OAAO,EAAE,CAAA;oBACX,CAAC,EACD,IAAI,EAAC,UAAU,YAGb,CACL;gBACA,UAAU,IAAI,CACb,2BACE,SAAS,EAAC,4CAA4C,EACtD,OAAO,EAAE,GAAG,EAAE;wBACZ,QAAQ,EAAE,CAAA;wBACV,UAAU,EAAE,CAAA;oBACd,CAAC,EACD,IAAI,EAAC,UAAU,eAGb,CACL;gBACA,aAAa,IAAI,CAChB,2BACE,IAAI,EAAE,aAAa,EACnB,MAAM,EAAC,QAAQ,EACf,GAAG,EAAC,YAAY,EAChB,SAAS,EAAC,wCAAwC,EAClD,KAAK,EAAE;wBACL,OAAO,EAAE,MAAM;wBACf,UAAU,EAAE,QAAQ;wBACpB,GAAG,EAAE,CAAC;qBACP,EACD,OAAO,EAAE,GAAG,EAAE;wBACZ,QAAQ,EAAE,CAAA;oBACZ,CAAC;oBAED,yCAAiB;oBACjB,oBAAC,YAAY,IAAC,SAAS,EAAC,YAAY,kBAA2B,CAC7D,CACL;gBACA,QAAQ,IAAI,CACX,2BACE,SAAS,EAAE,IAAI,CAAC,0CAA0C,EAAE;wBAC1D,8BAA8B,EAAE,OAAO,CAAC,QAAQ;qBACjD,CAAC,EACF,OAAO,EAAE,GAAG,EAAE;wBACZ,QAAQ,EAAE,CAAA;wBACV,QAAQ,EAAE,CAAA;oBACZ,CAAC,EACD,IAAI,EAAC,UAAU,aAGb,CACL;gBACA,UAAU,IAAI,CACb,2BACE,SAAS,EAAE,IAAI,CAAC,4CAA4C,EAAE;wBAC5D,gCAAgC,EAAE,OAAO,CAAC,QAAQ;qBACnD,CAAC,EACF,OAAO,EAAE,GAAG,EAAE;wBACZ,QAAQ,EAAE,CAAA;wBACV,UAAU,EAAE,CAAA;oBACd,CAAC,EACD,IAAI,EAAC,UAAU,eAGb,CACL;gBACA,MAAM,IAAI,CACT,2BACE,SAAS,EAAE,IAAI,CAAC,wCAAwC,EAAE;wBACxD,4BAA4B,EAAE,OAAO,CAAC,QAAQ;qBAC/C,CAAC,EACF,OAAO,EAAE,GAAG,EAAE;wBACZ,QAAQ,EAAE,CAAA;wBACV,MAAM,EAAE,CAAA;oBACV,CAAC,EACD,IAAI,EAAC,UAAU,WAGb,CACL,CACG,CACF,CACF,CACP,CAAA;AACH,CAAC,CAAA;AAED,eAAe,KAAK,CAAC,IAAI,CAAQ,YAAY,CAAC,CAAA","sourcesContent":["import * as React from 'react'\nimport clsx from 'clsx'\nimport { FormTypes } from '@oneblink/types'\nimport useBooleanState from '../../../hooks/useBooleanState'\nimport useClickOutsideElement from '../../../hooks/useClickOutsideElement'\nimport MaterialIcon from '../../MaterialIcon'\n\ninterface Props {\n element: FormTypes.FilesElement\n /** If set to `undefined`, the remove button will be hidden */\n onRemove: (() => void) | undefined\n onDownload?: () => void\n onRetry?: () => void\n attachmentUrl: string | null | undefined\n onAnnotate?: () => void\n onCrop?: () => void\n}\n\nconst DropdownMenu = ({\n element,\n onRemove,\n onDownload,\n onRetry,\n attachmentUrl,\n onAnnotate,\n onCrop,\n}: Props) => {\n const dropDownRef = React.useRef(null)\n const [isShowingMore, showMore, hideMore] = useBooleanState(false)\n\n useClickOutsideElement(\n dropDownRef,\n React.useCallback(() => {\n if (isShowingMore) {\n hideMore()\n }\n }, [hideMore, isShowingMore]),\n )\n\n return (\n <div\n className={clsx('dropdown is-right ob-files__menu', {\n 'is-active': isShowingMore,\n })}\n ref={dropDownRef}\n >\n <div className=\"dropdown-trigger\">\n <button\n type=\"button\"\n className=\"button ob-files__menu-button cypress-file-menu-button\"\n aria-haspopup=\"true\"\n aria-controls=\"dropdown-menu\"\n onClick={isShowingMore ? hideMore : showMore}\n >\n <MaterialIcon className=\"ob-files__menu-icon\">more_vert</MaterialIcon>\n </button>\n </div>\n <div className=\"dropdown-menu\" role=\"menu\">\n <div className=\"dropdown-content\">\n {onRetry && (\n <a\n className=\"dropdown-item cypress-file-retry-button\"\n onClick={() => {\n hideMore()\n onRetry()\n }}\n role=\"menuitem\"\n >\n Retry\n </a>\n )}\n {onDownload && (\n <a\n className=\"dropdown-item cypress-file-download-button\"\n onClick={() => {\n hideMore()\n onDownload()\n }}\n role=\"menuitem\"\n >\n Download\n </a>\n )}\n {attachmentUrl && (\n <a\n href={attachmentUrl}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"dropdown-item cypress-file-open-button\"\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 2,\n }}\n onClick={() => {\n hideMore()\n }}\n >\n <span>Open</span>\n <MaterialIcon className=\"icon-small\">open_in_new</MaterialIcon>\n </a>\n )}\n {onRemove && (\n <a\n className={clsx('dropdown-item cypress-file-remove-button', {\n 'ob-files__menu-remove-hidden': element.readOnly,\n })}\n onClick={() => {\n hideMore()\n onRemove()\n }}\n role=\"menuitem\"\n >\n Remove\n </a>\n )}\n {onAnnotate && (\n <a\n className={clsx('dropdown-item cypress-file-annotate-button', {\n 'ob-files__menu-annotate-hidden': element.readOnly,\n })}\n onClick={() => {\n hideMore()\n onAnnotate()\n }}\n role=\"menuitem\"\n >\n Annotate\n </a>\n )}\n {onCrop && (\n <a\n className={clsx('dropdown-item cypress-file-crop-button', {\n 'ob-files__menu-crop-hidden': element.readOnly,\n })}\n onClick={() => {\n hideMore()\n onCrop()\n }}\n role=\"menuitem\"\n >\n Crop\n </a>\n )}\n </div>\n </div>\n </div>\n )\n}\n\nexport default React.memo<Props>(DropdownMenu)\n"]}