@overmap-ai/core 1.0.51-bulk-form-submission.4 → 1.0.51-fix-document-urls.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.
@@ -8,7 +8,7 @@ var _a;
8
8
  import * as React from "react";
9
9
  import React__default, { useState, useEffect, useRef, memo, useMemo, useCallback, createContext, createElement, useContext, forwardRef, Children, isValidElement, cloneElement, Fragment as Fragment$1, useLayoutEffect, useReducer, lazy, Suspense } from "react";
10
10
  import { jsx, jsxs, Fragment } from "react/jsx-runtime";
11
- import { unsafeShowToast, AlertDialogProvider, ToastProvider, DefaultTheme, Flex as Flex$1, IconButton, RiIcon, Text as Text$1, useSeverityColor, Checkbox, TextArea, Select, useToast, Badge, MultiSelect, useViewportSize, Overlay, ButtonGroup, Spinner, IconColorUtility, Tooltip, Popover, useSize, ToggleButton, Separator, OvermapItem, Button, ButtonList, divButtonProps, OvermapDropdownMenu, Input, useAlertDialog } from "@overmap-ai/blocks";
11
+ import { unsafeShowToast, AlertDialogProvider, ToastProvider, DefaultTheme, Flex as Flex$1, IconButton, RiIcon, Text as Text$1, useSeverityColor, Checkbox, TextArea, Select, useToast, Badge, MultiSelect, Overlay, Button, Spinner, useViewportSize, ButtonGroup, IconColorUtility, Tooltip, Popover, useSize, ToggleButton, Separator, OvermapItem, ButtonList, divButtonProps, OvermapDropdownMenu, Input, useAlertDialog } from "@overmap-ai/blocks";
12
12
  import { DepGraph } from "dependency-graph";
13
13
  import { offline as offline$1 } from "@redux-offline/redux-offline";
14
14
  import offlineConfig from "@redux-offline/redux-offline/lib/defaults";
@@ -27,6 +27,7 @@ import { useField, useFormikContext, useFormik, FormikProvider } from "formik";
27
27
  import get from "lodash.get";
28
28
  import Linkify from "linkify-react";
29
29
  import { DragDropContext, Droppable, Draggable } from "@hello-pangea/dnd";
30
+ import QrScannerAPI from "qr-scanner";
30
31
  import { read, utils } from "xlsx";
31
32
  import { pdfjs, Document, Page } from "react-pdf";
32
33
  import "react-pdf/dist/Page/AnnotationLayer.css";
@@ -4068,9 +4069,18 @@ const documentSlice = createSlice({
4068
4069
  }
4069
4070
  }
4070
4071
  for (const document2 of action.payload) {
4072
+ const existingDocument = state.documents[document2.offline_id];
4073
+ if (document2.organization !== void 0 && document2.organization !== existingDocument.organization) {
4074
+ throw new Error("organization cannot be updated");
4075
+ }
4076
+ if (document2.project !== void 0 && document2.project !== existingDocument.project) {
4077
+ throw new Error("project cannot be updated");
4078
+ }
4071
4079
  state.documents[document2.offline_id] = {
4072
- ...state.documents[document2.offline_id],
4080
+ ...existingDocument,
4073
4081
  ...document2
4082
+ // Without the cast, TypeScript doesn't realize that we have guaranteed that the document doesn't
4083
+ // have both a project and an organization.
4074
4084
  };
4075
4085
  }
4076
4086
  },
@@ -7997,17 +8007,28 @@ class LicenseService extends BaseApiService {
7997
8007
  }
7998
8008
  }
7999
8009
  class DocumentService extends BaseApiService {
8010
+ // TODO: Support adding for project or organization
8000
8011
  add(document2) {
8001
8012
  const { store } = this.client;
8002
8013
  const currentUserId = store.getState().userReducer.currentUser.id;
8003
8014
  const activeProjectId = store.getState().projectReducer.activeProjectId;
8004
- const offlineDocument = offline({ ...document2, created_by: currentUserId });
8005
- store.dispatch(addDocuments([offlineDocument]));
8015
+ if (!activeProjectId) {
8016
+ throw new Error("No active project ID while creating document.");
8017
+ }
8018
+ const offlineDocument = offline(document2);
8019
+ const submittedDocument = {
8020
+ ...offlineDocument,
8021
+ created_by: currentUserId,
8022
+ project: activeProjectId,
8023
+ organization: null,
8024
+ children_documents: []
8025
+ };
8026
+ store.dispatch(addDocuments([submittedDocument]));
8006
8027
  const promise = this.enqueueRequest({
8007
8028
  description: "Create Document",
8008
8029
  method: HttpMethod.POST,
8009
- url: `/projects/${activeProjectId}/create-document/`,
8010
- payload: { ...offlineDocument },
8030
+ url: `/projects/${activeProjectId}/documents/`,
8031
+ payload: offlineDocument,
8011
8032
  queryParams: {
8012
8033
  parent_document: offlineDocument.parent_document ?? void 0
8013
8034
  },
@@ -8018,7 +8039,7 @@ class DocumentService extends BaseApiService {
8018
8039
  promise.catch(() => {
8019
8040
  store.dispatch(removeDocuments([offlineDocument.offline_id]));
8020
8041
  });
8021
- return [offlineDocument, promise];
8042
+ return [submittedDocument, promise];
8022
8043
  }
8023
8044
  update(document2) {
8024
8045
  const { store } = this.client;
@@ -8118,15 +8139,25 @@ class DocumentService extends BaseApiService {
8118
8139
  }
8119
8140
  async refreshStore() {
8120
8141
  const { store } = this.client;
8121
- const activeProjectId = store.getState().projectReducer.activeProjectId;
8122
- const result = await this.enqueueRequest({
8142
+ const state = store.getState();
8143
+ const activeProjectId = state.projectReducer.activeProjectId;
8144
+ const projectDocumentsPromise = this.enqueueRequest({
8123
8145
  description: "Get project documents",
8124
8146
  method: HttpMethod.GET,
8125
- url: `/documents/projects/${activeProjectId}/`,
8147
+ url: `/projects/${activeProjectId}/documents/`,
8148
+ blockers: [],
8149
+ blocks: []
8150
+ });
8151
+ const activeOrganizationId = state.organizationReducer.activeOrganizationId;
8152
+ const organizationDocumentsPromise = this.enqueueRequest({
8153
+ description: "Get organization documents",
8154
+ method: HttpMethod.GET,
8155
+ url: `/organizations/${activeOrganizationId}/documents/`,
8126
8156
  blockers: [],
8127
8157
  blocks: []
8128
8158
  });
8129
- store.dispatch(setDocuments(result));
8159
+ store.dispatch(setDocuments(await projectDocumentsPromise));
8160
+ store.dispatch(addDocuments(await organizationDocumentsPromise));
8130
8161
  }
8131
8162
  }
8132
8163
  class AgentService extends BaseApiService {
@@ -8231,7 +8262,7 @@ const tabTrigger = "_tabTrigger_1w0fq_69";
8231
8262
  const patchfieldBorder = "_patchfieldBorder_1w0fq_73";
8232
8263
  const title = "_title_1w0fq_73";
8233
8264
  const error = "_error_1w0fq_89";
8234
- const styles$c = {
8265
+ const styles$d = {
8235
8266
  description: description$2,
8236
8267
  floatingButtonContainer: floatingButtonContainer$2,
8237
8268
  FullScreenImageContainer: FullScreenImageContainer$2,
@@ -8352,7 +8383,7 @@ const fileName$1 = "_fileName_10o76_31";
8352
8383
  const longIconButton$1 = "_longIconButton_10o76_36";
8353
8384
  const previewImage$1 = "_previewImage_10o76_42";
8354
8385
  const FullScreenImage$1 = "_FullScreenImage_10o76_12";
8355
- const styles$b = {
8386
+ const styles$c = {
8356
8387
  description: description$1,
8357
8388
  floatingButtonContainer: floatingButtonContainer$1,
8358
8389
  FullScreenImageContainer: FullScreenImageContainer$1,
@@ -8376,7 +8407,7 @@ const FullScreenImagePreview = memo((props) => {
8376
8407
  /* @__PURE__ */ jsx(
8377
8408
  "button",
8378
8409
  {
8379
- className: styles$b.FullScreenImageContainer,
8410
+ className: styles$c.FullScreenImageContainer,
8380
8411
  type: "button",
8381
8412
  onClick: () => {
8382
8413
  setShowPreview(false);
@@ -8384,7 +8415,7 @@ const FullScreenImagePreview = memo((props) => {
8384
8415
  children: /* @__PURE__ */ jsx(
8385
8416
  "img",
8386
8417
  {
8387
- className: styles$b.FullScreenImage,
8418
+ className: styles$c.FullScreenImage,
8388
8419
  src: url,
8389
8420
  alt: name,
8390
8421
  onClick: (e) => {
@@ -8394,11 +8425,11 @@ const FullScreenImagePreview = memo((props) => {
8394
8425
  )
8395
8426
  }
8396
8427
  ),
8397
- /* @__PURE__ */ jsxs(Flex$1, { className: styles$b.TopBarContainer, align: "center", children: [
8428
+ /* @__PURE__ */ jsxs(Flex$1, { className: styles$c.TopBarContainer, align: "center", children: [
8398
8429
  /* @__PURE__ */ jsx(
8399
8430
  IconButton,
8400
8431
  {
8401
- className: styles$b.longIconButton,
8432
+ className: styles$c.longIconButton,
8402
8433
  variant: "soft",
8403
8434
  "aria-label": "Exit preview",
8404
8435
  onClick: () => {
@@ -8407,11 +8438,11 @@ const FullScreenImagePreview = memo((props) => {
8407
8438
  children: /* @__PURE__ */ jsx(RiIcon, { icon: "RiArrowLeftLine" })
8408
8439
  }
8409
8440
  ),
8410
- /* @__PURE__ */ jsx(Text$1, { className: styles$b.fileName, children: name }),
8441
+ /* @__PURE__ */ jsx(Text$1, { className: styles$c.fileName, children: name }),
8411
8442
  /* @__PURE__ */ jsx(
8412
8443
  IconButton,
8413
8444
  {
8414
- className: styles$b.longIconButton,
8445
+ className: styles$c.longIconButton,
8415
8446
  variant: "soft",
8416
8447
  "aria-label": `Download ${name}`,
8417
8448
  onClick: handleDownload,
@@ -8439,7 +8470,7 @@ const InputWithLabel = (props) => {
8439
8470
  /* @__PURE__ */ jsx(
8440
8471
  "img",
8441
8472
  {
8442
- className: styles$b.previewImage,
8473
+ className: styles$c.previewImage,
8443
8474
  src: resolvedImageURL,
8444
8475
  alt: resolvedImage.name,
8445
8476
  onClick: () => {
@@ -8467,7 +8498,7 @@ const InputWithHelpText = (props) => {
8467
8498
  const { helpText, children, severity } = props;
8468
8499
  return /* @__PURE__ */ jsxs(Flex$1, { direction: "column", gap: "1", children: [
8469
8500
  children,
8470
- /* @__PURE__ */ jsx(Flex$1, { direction: "column", children: /* @__PURE__ */ jsx(Text$1, { size: "1", severity, className: styles$b.description, children: helpText }) })
8501
+ /* @__PURE__ */ jsx(Flex$1, { direction: "column", children: /* @__PURE__ */ jsx(Text$1, { size: "1", severity, className: styles$c.description, children: helpText }) })
8471
8502
  ] });
8472
8503
  };
8473
8504
  const InputWithLabelAndHelpText = (props) => {
@@ -8701,6 +8732,9 @@ function RiArrowUpLine(props) {
8701
8732
  function RiCalendarLine(props) {
8702
8733
  return GenIcon({ "tag": "svg", "attr": { "viewBox": "0 0 24 24", "fill": "currentColor" }, "child": [{ "tag": "path", "attr": { "d": "M9 1V3H15V1H17V3H21C21.5523 3 22 3.44772 22 4V20C22 20.5523 21.5523 21 21 21H3C2.44772 21 2 20.5523 2 20V4C2 3.44772 2.44772 3 3 3H7V1H9ZM20 11H4V19H20V11ZM7 5H4V9H20V5H17V7H15V5H9V7H7V5Z" }, "child": [] }] })(props);
8703
8734
  }
8735
+ function RiQrCodeLine(props) {
8736
+ return GenIcon({ "tag": "svg", "attr": { "viewBox": "0 0 24 24", "fill": "currentColor" }, "child": [{ "tag": "path", "attr": { "d": "M16 17V16H13V13H16V15H18V17H17V19H15V21H13V18H15V17H16ZM21 21H17V19H19V17H21V21ZM3 3H11V11H3V3ZM5 5V9H9V5H5ZM13 3H21V11H13V3ZM15 5V9H19V5H15ZM3 13H11V21H3V13ZM5 15V19H9V15H5ZM18 13H21V15H18V13ZM6 6H8V8H6V6ZM6 16H8V18H6V16ZM16 6H18V8H16V6Z" }, "child": [] }] })(props);
8737
+ }
8704
8738
  function RiFileCopyLine(props) {
8705
8739
  return GenIcon({ "tag": "svg", "attr": { "viewBox": "0 0 24 24", "fill": "currentColor" }, "child": [{ "tag": "path", "attr": { "d": "M6.9998 6V3C6.9998 2.44772 7.44752 2 7.9998 2H19.9998C20.5521 2 20.9998 2.44772 20.9998 3V17C20.9998 17.5523 20.5521 18 19.9998 18H16.9998V20.9991C16.9998 21.5519 16.5499 22 15.993 22H4.00666C3.45059 22 3 21.5554 3 20.9991L3.0026 7.00087C3.0027 6.44811 3.45264 6 4.00942 6H6.9998ZM5.00242 8L5.00019 20H14.9998V8H5.00242ZM8.9998 6H16.9998V16H18.9998V4H8.9998V6Z" }, "child": [] }] })(props);
8706
8740
  }
@@ -9604,9 +9638,9 @@ const Inset = React.forwardRef((props, forwardedRef) => {
9604
9638
  return React.createElement("div", { ...insetProps, ref: forwardedRef, className: classNames("rt-Inset", className, withBreakpoints(side, "rt-r-side"), withBreakpoints(clip, "rt-r-clip"), withBreakpoints(p, "rt-r-p"), withBreakpoints(px, "rt-r-px"), withBreakpoints(py, "rt-r-py"), withBreakpoints(pt, "rt-r-pt"), withBreakpoints(pr, "rt-r-pr"), withBreakpoints(pb, "rt-r-pb"), withBreakpoints(pl, "rt-r-pl"), withMarginProps(marginProps)) });
9605
9639
  });
9606
9640
  Inset.displayName = "Inset";
9607
- const sizes$7 = ["1", "2", "3", "4", "5", "6", "7", "8", "9"];
9641
+ const sizes$8 = ["1", "2", "3", "4", "5", "6", "7", "8", "9"];
9608
9642
  const headingPropDefs = {
9609
- size: { type: "enum", values: sizes$7, default: "6", responsive: true },
9643
+ size: { type: "enum", values: sizes$8, default: "6", responsive: true },
9610
9644
  weight: { ...weightProp, default: "bold" },
9611
9645
  align: alignProp,
9612
9646
  trim: trimProp,
@@ -9619,9 +9653,9 @@ const Heading = React.forwardRef((props, forwardedRef) => {
9619
9653
  return React.createElement($5e63c961fc1ce211$export$8c6ed5c666ac1360, { "data-accent-color": color, ...headingProps, ref: forwardedRef, className: classNames("rt-Heading", className, withBreakpoints(size, "rt-r-size"), withBreakpoints(weight, "rt-r-weight"), withBreakpoints(align, "rt-r-ta"), withBreakpoints(trim, "rt-r-lt"), { "rt-high-contrast": highContrast }, withMarginProps(marginProps)) }, asChild ? children : React.createElement(Tag, null, children));
9620
9654
  });
9621
9655
  Heading.displayName = "Heading";
9622
- const sizes$6 = ["1", "2", "3", "4", "5", "6", "7", "8", "9"];
9656
+ const sizes$7 = ["1", "2", "3", "4", "5", "6", "7", "8", "9"];
9623
9657
  const textPropDefs = {
9624
- size: { type: "enum", values: sizes$6, default: void 0, responsive: true },
9658
+ size: { type: "enum", values: sizes$7, default: void 0, responsive: true },
9625
9659
  weight: weightProp,
9626
9660
  align: alignProp,
9627
9661
  trim: trimProp,
@@ -9634,6 +9668,21 @@ const Text = React.forwardRef((props, forwardedRef) => {
9634
9668
  return React.createElement($5e63c961fc1ce211$export$8c6ed5c666ac1360, { "data-accent-color": color, ...textProps, ref: forwardedRef, className: classNames("rt-Text", className, withBreakpoints(size, "rt-r-size"), withBreakpoints(weight, "rt-r-weight"), withBreakpoints(align, "rt-r-ta"), withBreakpoints(trim, "rt-r-lt"), { "rt-high-contrast": highContrast }, withMarginProps(marginProps)) }, asChild ? children : React.createElement(Tag, null, children));
9635
9669
  });
9636
9670
  Text.displayName = "Text";
9671
+ const sizes$6 = ["1", "2", "3", "4", "5", "6", "7", "8", "9"];
9672
+ const variants$4 = ["solid", "soft", "outline", "ghost"];
9673
+ const codePropDefs = {
9674
+ size: { type: "enum", values: sizes$6, default: void 0, responsive: true },
9675
+ variant: { type: "enum", values: variants$4, default: "soft" },
9676
+ weight: weightProp,
9677
+ color: colorProp,
9678
+ highContrast: highContrastProp
9679
+ };
9680
+ const Code = React.forwardRef((props, forwardedRef) => {
9681
+ const { rest: marginRest, ...marginProps } = extractMarginProps(props);
9682
+ const { className, size = codePropDefs.size.default, variant = codePropDefs.variant.default, weight = codePropDefs.weight.default, color = codePropDefs.color.default, highContrast = codePropDefs.highContrast.default, ...codeProps } = marginRest;
9683
+ return React.createElement("code", { "data-accent-color": color, ...codeProps, ref: forwardedRef, className: classNames("rt-Code", className, withBreakpoints(size, "rt-r-size"), `rt-variant-${variant}`, withBreakpoints(weight, "rt-r-weight"), { "rt-high-contrast": highContrast }, withMarginProps(marginProps)) });
9684
+ });
9685
+ Code.displayName = "Code";
9637
9686
  const Em = React.forwardRef((props, forwardedRef) => React.createElement("em", { ...props, ref: forwardedRef, className: classNames("rt-Em", props.className) }));
9638
9687
  Em.displayName = "Em";
9639
9688
  const Strong = React.forwardRef((props, forwardedRef) => React.createElement("strong", { ...props, ref: forwardedRef, className: classNames("rt-Strong", props.className) }));
@@ -12024,7 +12073,7 @@ __publicField(StringOrTextField, "_validateMax", (path) => (value, allValues) =>
12024
12073
  });
12025
12074
  const clickableLinkContainer = "_clickableLinkContainer_1ace7_1";
12026
12075
  const TextFieldInputCopy = "_TextFieldInputCopy_1ace7_5";
12027
- const styles$a = {
12076
+ const styles$b = {
12028
12077
  clickableLinkContainer,
12029
12078
  TextFieldInputCopy
12030
12079
  };
@@ -12053,13 +12102,13 @@ const StringInput = memo((props) => {
12053
12102
  placeholder: field.placeholder,
12054
12103
  color
12055
12104
  }
12056
- ) : /* @__PURE__ */ jsxs(TextField$1.Root, { className: styles$a.clickableLinkContainer, children: [
12105
+ ) : /* @__PURE__ */ jsxs(TextField$1.Root, { className: styles$b.clickableLinkContainer, children: [
12057
12106
  /* @__PURE__ */ jsx(
12058
12107
  "div",
12059
12108
  {
12060
12109
  className: classNames$1(
12061
12110
  "rt-TextFieldInput rt-r-size-2 rt-variant-surface",
12062
- styles$a.TextFieldInputCopy
12111
+ styles$b.TextFieldInputCopy
12063
12112
  ),
12064
12113
  children: /* @__PURE__ */ jsx(
12065
12114
  Linkify,
@@ -12751,6 +12800,158 @@ __publicField(_MultiSelectField, "fieldTypeName", "Multi-select");
12751
12800
  __publicField(_MultiSelectField, "fieldTypeDescription", "Allows the user to select a multiple options from a list of options.");
12752
12801
  __publicField(_MultiSelectField, "Icon", RiCheckboxLine);
12753
12802
  let MultiSelectField = _MultiSelectField;
12803
+ const QrScannerWrapper = "_QrScannerWrapper_1puz3_1";
12804
+ const styles$a = {
12805
+ QrScannerWrapper
12806
+ };
12807
+ const QrInput = memo((props) => {
12808
+ const [{ inputId, labelId, label, helpText, size, severity, showInputOnly, field, fieldProps }, rest] = useFormikInput(props);
12809
+ const [showQrScanner, setShowQrScanner] = useState(false);
12810
+ const value = fieldProps.value;
12811
+ const handleQrScan = useCallback(
12812
+ (data) => {
12813
+ fieldProps.onChange({ target: { value: data } });
12814
+ setShowQrScanner(false);
12815
+ },
12816
+ [fieldProps]
12817
+ );
12818
+ const handleClearScanResult = useCallback(() => {
12819
+ fieldProps.onChange({ target: { value: "" } });
12820
+ }, [fieldProps]);
12821
+ const handleScanButtonClicked = useCallback(() => {
12822
+ setShowQrScanner(true);
12823
+ }, []);
12824
+ const handleQrScannerClose = useCallback(() => {
12825
+ setShowQrScanner(false);
12826
+ }, []);
12827
+ return /* @__PURE__ */ jsx(InputWithLabelAndHelpText, { helpText, severity, children: /* @__PURE__ */ jsxs(
12828
+ InputWithLabel,
12829
+ {
12830
+ size,
12831
+ severity,
12832
+ inputId,
12833
+ labelId,
12834
+ label: showInputOnly ? label : "",
12835
+ image: showInputOnly ? void 0 : field.image,
12836
+ flexProps: { direction: "column", justify: "start", align: "start", gap: "1" },
12837
+ children: [
12838
+ /* @__PURE__ */ jsx(
12839
+ Overlay,
12840
+ {
12841
+ open: showQrScanner,
12842
+ content: () => /* @__PURE__ */ jsx(QrScanner, { onQrScan: handleQrScan, onClose: handleQrScannerClose }),
12843
+ onOpenChange: setShowQrScanner
12844
+ }
12845
+ ),
12846
+ /* @__PURE__ */ jsxs(Flex, { width: "max-content", gap: "1", align: "center", children: [
12847
+ /* @__PURE__ */ jsxs(Button, { ...rest, variant: "soft", onClick: handleScanButtonClicked, children: [
12848
+ /* @__PURE__ */ jsx(RiIcon, { icon: "RiQrCodeLine" }),
12849
+ "Scan"
12850
+ ] }),
12851
+ value && /* @__PURE__ */ jsx(Text, { color: "jade", size: "1", children: /* @__PURE__ */ jsx(RiIcon, { icon: "RiCheckLine", style: { verticalAlign: "bottom" } }) })
12852
+ ] }),
12853
+ value && /* @__PURE__ */ jsx(Card, { children: /* @__PURE__ */ jsxs(Flex, { width: "max-content", gap: "2", align: "center", children: [
12854
+ /* @__PURE__ */ jsx(Code, { color: "gray", highContrast: true, children: value }),
12855
+ /* @__PURE__ */ jsx(
12856
+ IconButton,
12857
+ {
12858
+ severity: "info",
12859
+ variant: "ghost",
12860
+ "aria-label": "delete",
12861
+ size: "small",
12862
+ onClick: handleClearScanResult,
12863
+ children: /* @__PURE__ */ jsx(RiIcon, { icon: "RiCloseLine" })
12864
+ }
12865
+ )
12866
+ ] }) })
12867
+ ]
12868
+ }
12869
+ ) });
12870
+ });
12871
+ QrInput.displayName = "QrInput";
12872
+ const QrScanner = memo((props) => {
12873
+ const { onQrScan, onClose } = props;
12874
+ const videoRef = useRef(null);
12875
+ const [isScannerLoading, setIsScannerLoading] = useState(false);
12876
+ useEffect(() => {
12877
+ if (!videoRef.current)
12878
+ return;
12879
+ const qrScanner = new QrScannerAPI(
12880
+ videoRef.current,
12881
+ (result) => {
12882
+ const data = result.data;
12883
+ onQrScan(data);
12884
+ qrScanner.destroy();
12885
+ },
12886
+ {
12887
+ highlightCodeOutline: true,
12888
+ highlightScanRegion: true,
12889
+ maxScansPerSecond: 1
12890
+ }
12891
+ );
12892
+ setIsScannerLoading(true);
12893
+ qrScanner.start().then(() => {
12894
+ setIsScannerLoading(false);
12895
+ }).catch(() => {
12896
+ setIsScannerLoading(false);
12897
+ });
12898
+ }, [onQrScan]);
12899
+ return /* @__PURE__ */ jsxs(
12900
+ Flex,
12901
+ {
12902
+ className: styles$a.QrScannerWrapper,
12903
+ width: "100%",
12904
+ height: "100%",
12905
+ direction: "column",
12906
+ gap: "2",
12907
+ justify: "center",
12908
+ position: "relative",
12909
+ children: [
12910
+ /* @__PURE__ */ jsx(Flex, { width: "100%", position: "absolute", top: "0", p: "2", children: /* @__PURE__ */ jsx(IconButton, { "aria-label": "close", variant: "soft", severity: "info", highContrast: true, onClick: onClose, children: /* @__PURE__ */ jsx(RiIcon, { icon: "RiCloseLine" }) }) }),
12911
+ /* @__PURE__ */ jsxs(Box, { style: { maxWidth: "100%", maxHeight: "100%" }, position: "relative", children: [
12912
+ /* @__PURE__ */ jsx("video", { ref: videoRef, style: { width: "100%", height: "100%" } }),
12913
+ isScannerLoading && /* @__PURE__ */ jsx(
12914
+ Flex,
12915
+ {
12916
+ position: "absolute",
12917
+ inset: "0",
12918
+ style: { background: "var(--color-background)" },
12919
+ justify: "center",
12920
+ align: "center",
12921
+ children: /* @__PURE__ */ jsx(Spinner, {})
12922
+ }
12923
+ )
12924
+ ] })
12925
+ ]
12926
+ }
12927
+ );
12928
+ });
12929
+ QrScanner.displayName = "QrScanner";
12930
+ const emptyQrField = {
12931
+ ...emptyBaseField,
12932
+ type: "qr"
12933
+ };
12934
+ const _QrField = class _QrField extends BaseField {
12935
+ constructor(options) {
12936
+ super({ ...options, type: "qr" });
12937
+ __publicField(this, "onlyValidateAfterTouched", false);
12938
+ }
12939
+ serialize() {
12940
+ return super._serialize();
12941
+ }
12942
+ static deserialize(data) {
12943
+ if (data.type !== "qr")
12944
+ throw new Error("Type mismatch.");
12945
+ return new _QrField(data);
12946
+ }
12947
+ getInput(props) {
12948
+ return /* @__PURE__ */ jsx(QrInput, { ...props, field: this });
12949
+ }
12950
+ };
12951
+ __publicField(_QrField, "fieldTypeName", "QR");
12952
+ __publicField(_QrField, "fieldTypeDescription", "Used for scanning/reading QR codes.");
12953
+ __publicField(_QrField, "Icon", RiQrCodeLine);
12954
+ let QrField = _QrField;
12754
12955
  const FieldInputCloner = memo((props) => {
12755
12956
  const { field, ...rest } = props;
12756
12957
  const [{ value: identifier }] = useField(field.options.clonedFieldIdentifier);
@@ -14008,6 +14209,7 @@ const FieldTypeToClsMapping = {
14008
14209
  text: TextField,
14009
14210
  custom: CustomField,
14010
14211
  upload: UploadField,
14212
+ qr: QrField,
14011
14213
  // TODO: Underscore
14012
14214
  "multi-string": MultiStringField,
14013
14215
  "multi-select": MultiSelectField
@@ -14021,6 +14223,7 @@ const FieldTypeToEmptyFieldMapping = {
14021
14223
  text: emptyTextField,
14022
14224
  custom: emptyCustomField,
14023
14225
  upload: emptyUploadField,
14226
+ qr: emptyQrField,
14024
14227
  // TODO: Underscore
14025
14228
  "multi-string": emptyMultiStringField,
14026
14229
  "multi-select": emptyMultiSelectField
@@ -14108,7 +14311,7 @@ const FieldSectionLayout = memo((props) => {
14108
14311
  return /* @__PURE__ */ jsx(Card, { children: /* @__PURE__ */ jsxs(Flex$1, { direction: "column", gap: "3", children: [
14109
14312
  /* @__PURE__ */ jsxs(Flex$1, { direction: "column", children: [
14110
14313
  /* @__PURE__ */ jsx(Heading, { as: "h3", size: "3", children: label }),
14111
- /* @__PURE__ */ jsx(Text$1, { className: styles$b.description, children: description2 })
14314
+ /* @__PURE__ */ jsx(Text$1, { className: styles$c.description, children: description2 })
14112
14315
  ] }),
14113
14316
  inputs
14114
14317
  ] }) });
@@ -14351,7 +14554,7 @@ const FormRenderer = memo(
14351
14554
  [schema.title]
14352
14555
  );
14353
14556
  const Description = useMemo(
14354
- () => typeof schema.description === "string" ? /* @__PURE__ */ jsx(Text$1, { className: styles$b.description, children: schema.description }) : schema.description,
14557
+ () => typeof schema.description === "string" ? /* @__PURE__ */ jsx(Text$1, { className: styles$c.description, children: schema.description }) : schema.description,
14355
14558
  [schema.description]
14356
14559
  );
14357
14560
  const inputs = useFieldInputs(schema.fields, { formId: formId2, disabled: readonly });
@@ -14367,7 +14570,7 @@ const FormRenderer = memo(
14367
14570
  !hideDescription && Description
14368
14571
  ] }) }),
14369
14572
  inputs,
14370
- !readonly && /* @__PURE__ */ jsxs(Flex$1, { className: styles$b.floatingButtonContainer, align: "center", justify: "end", gap: "2", children: [
14573
+ !readonly && /* @__PURE__ */ jsxs(Flex$1, { className: styles$c.floatingButtonContainer, align: "center", justify: "end", gap: "2", children: [
14371
14574
  cancelText && /* @__PURE__ */ jsx(Button, { severity: "info", ...buttonProps, type: "button", onClick: onCancel, children: cancelText }),
14372
14575
  /* @__PURE__ */ jsx(Button, { ...buttonProps, type: "submit", disabled: !formik.isValid, children: submitText })
14373
14576
  ] })
@@ -15715,12 +15918,12 @@ const FormBuilder = memo(
15715
15918
  });
15716
15919
  const previewSchema = useMemo(() => formRevisionToSchema(formik.values), [formik.values]);
15717
15920
  return /* @__PURE__ */ jsx(Tabs.Root, { ref, defaultValue: "edit", children: /* @__PURE__ */ jsxs(Flex$1, { direction: "column", gap: "2", children: [
15718
- showTabs && /* @__PURE__ */ jsxs(Tabs.List, { className: classNames$1(styles$c.tabsList, tabsListClassName), children: [
15719
- /* @__PURE__ */ jsx(Tabs.Trigger, { className: styles$c.tabTrigger, value: "edit", children: /* @__PURE__ */ jsxs(Flex$1, { align: "center", gap: "2", children: [
15921
+ showTabs && /* @__PURE__ */ jsxs(Tabs.List, { className: classNames$1(styles$d.tabsList, tabsListClassName), children: [
15922
+ /* @__PURE__ */ jsx(Tabs.Trigger, { className: styles$d.tabTrigger, value: "edit", children: /* @__PURE__ */ jsxs(Flex$1, { align: "center", gap: "2", children: [
15720
15923
  /* @__PURE__ */ jsx(RiIcon, { icon: "RiPencilLine" }),
15721
15924
  "Edit"
15722
15925
  ] }) }),
15723
- /* @__PURE__ */ jsx(Tabs.Trigger, { className: styles$c.tabTrigger, value: "preview", children: /* @__PURE__ */ jsxs(Flex$1, { align: "center", gap: "2", children: [
15926
+ /* @__PURE__ */ jsx(Tabs.Trigger, { className: styles$d.tabTrigger, value: "preview", children: /* @__PURE__ */ jsxs(Flex$1, { align: "center", gap: "2", children: [
15724
15927
  /* @__PURE__ */ jsx(RiIcon, { icon: "RiEyeLine" }),
15725
15928
  "Preview"
15726
15929
  ] }) })
@@ -15744,8 +15947,8 @@ const FormBuilder = memo(
15744
15947
  render: ({ setValue, value, meta }) => /* @__PURE__ */ jsx(InputWithHelpText, { severity: "danger", helpText: meta.error ?? null, children: /* @__PURE__ */ jsx(
15745
15948
  Input,
15746
15949
  {
15747
- className: classNames$1(styles$c.title, {
15748
- [styles$c.error]: meta.error
15950
+ className: classNames$1(styles$d.title, {
15951
+ [styles$d.error]: meta.error
15749
15952
  }),
15750
15953
  placeholder: "Form title",
15751
15954
  value,
@@ -15767,7 +15970,7 @@ const FormBuilder = memo(
15767
15970
  render: ({ setValue, value }) => /* @__PURE__ */ jsx(
15768
15971
  TextArea,
15769
15972
  {
15770
- className: styles$c.description,
15973
+ className: styles$d.description,
15771
15974
  placeholder: "Explain the purpose of this form",
15772
15975
  value,
15773
15976
  onChange: (event) => {
@@ -15785,7 +15988,7 @@ const FormBuilder = memo(
15785
15988
  /* @__PURE__ */ jsx(FieldsEditor, { fieldsOnly }),
15786
15989
  /* @__PURE__ */ jsx(Text$1, { severity: "danger", size: "1", children: typeof formik.errors.fields === "string" && formik.errors.fields })
15787
15990
  ] }),
15788
- /* @__PURE__ */ jsxs(Flex$1, { className: styles$c.floatingButtonContainer, align: "center", justify: "end", gap: "2", children: [
15991
+ /* @__PURE__ */ jsxs(Flex$1, { className: styles$d.floatingButtonContainer, align: "center", justify: "end", gap: "2", children: [
15789
15992
  onCancel && /* @__PURE__ */ jsx(Button, { type: "button", variant: "solid", severity: "info", onClick: onCancel, children: "Cancel" }),
15790
15993
  /* @__PURE__ */ jsx(Button, { type: "submit", children: "Save form" })
15791
15994
  ] })
@@ -15820,6 +16023,9 @@ const index = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePropert
15820
16023
  NumberInput,
15821
16024
  PatchField,
15822
16025
  PatchFormProvider,
16026
+ QrField,
16027
+ QrInput,
16028
+ QrScanner,
15823
16029
  SelectField,
15824
16030
  SelectInput,
15825
16031
  StringField,
@@ -15834,6 +16040,7 @@ const index = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePropert
15834
16040
  emptyMultiSelectField,
15835
16041
  emptyMultiStringField,
15836
16042
  emptyNumberField,
16043
+ emptyQrField,
15837
16044
  emptySelectField,
15838
16045
  emptyStringField,
15839
16046
  emptyTextField,
@@ -15924,6 +16131,9 @@ export {
15924
16131
  ProjectFileService,
15925
16132
  ProjectService,
15926
16133
  ProjectType,
16134
+ QrField,
16135
+ QrInput,
16136
+ QrScanner,
15927
16137
  SDKContext,
15928
16138
  SDKProvider,
15929
16139
  SUPPORTED_IMAGE_FILE_TYPES,
@@ -16047,6 +16257,7 @@ export {
16047
16257
  emptyMultiSelectField,
16048
16258
  emptyMultiStringField,
16049
16259
  emptyNumberField,
16260
+ emptyQrField,
16050
16261
  emptySelectField,
16051
16262
  emptyStringField,
16052
16263
  emptyTextField,