@overmap-ai/forms 1.0.32-react-flow-david-fixes.41 → 1.0.32

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 (96) hide show
  1. package/dist/form/Observable/index.d.ts +1 -0
  2. package/dist/form/UUIDFile/UUIDFile.d.ts +5 -0
  3. package/dist/form/UUIDFile/index.d.ts +1 -0
  4. package/dist/form/UUIDPromise/index.d.ts +2 -0
  5. package/dist/form/UUIDPromise/utils.d.ts +4 -0
  6. package/dist/form/builder/components/CreateFieldDropdownMenu.d.ts +8 -0
  7. package/dist/form/builder/components/FieldBuilder.d.ts +1 -1
  8. package/dist/form/builder/components/FieldBuilderWithActions.d.ts +9 -0
  9. package/dist/form/builder/components/index.d.ts +2 -1
  10. package/dist/form/builder/hooks.d.ts +1 -1
  11. package/dist/form/builder/list/FieldSectionWithActions.d.ts +1 -1
  12. package/dist/form/builder/utils.d.ts +2 -2
  13. package/dist/form/components/DisplayFile.d.ts +9 -0
  14. package/dist/form/components/index.d.ts +1 -0
  15. package/dist/form/conditions/BaseCondition/BaseCondition.d.ts +6 -7
  16. package/dist/form/conditions/BaseCondition/typings.d.ts +4 -4
  17. package/dist/form/conditions/BooleanFieldCondition/BooleanFieldCondition.d.ts +4 -6
  18. package/dist/form/conditions/CheckboxListFieldCondition/CheckboxListFieldCondition.d.ts +4 -6
  19. package/dist/form/conditions/ConditionManager/ConditionManager.d.ts +15 -0
  20. package/dist/form/conditions/ConditionManager/hooks.d.ts +4 -0
  21. package/dist/form/conditions/ConditionManager/index.d.ts +3 -0
  22. package/dist/form/conditions/ConditionManager/typings.d.ts +2 -0
  23. package/dist/form/conditions/DateFieldCondition/DateFieldCondition.d.ts +4 -6
  24. package/dist/form/conditions/MultiSelectFieldCondition/MultiSelectFieldCondition.d.ts +4 -14
  25. package/dist/form/conditions/MultiStringFieldCondition/MultiStringFieldCondition.d.ts +4 -6
  26. package/dist/form/conditions/NumberFieldCondition/NumberFieldCondition.d.ts +4 -17
  27. package/dist/form/conditions/OTPFieldCondition/OTPFieldCondition.d.ts +4 -6
  28. package/dist/form/conditions/PassFailFieldCondition/PassFailFieldCondition.d.ts +18 -0
  29. package/dist/form/conditions/PassFailFieldCondition/PassFailFieldConditionCell.d.ts +6 -0
  30. package/dist/form/conditions/PassFailFieldCondition/index.d.ts +3 -0
  31. package/dist/form/conditions/PassFailFieldCondition/typings.d.ts +4 -0
  32. package/dist/form/conditions/RadioFieldCondition/RadioFieldCondition.d.ts +4 -6
  33. package/dist/form/conditions/RatingFieldCondition/RatingFieldCondition.d.ts +21 -0
  34. package/dist/form/conditions/RatingFieldCondition/RatingFieldConditionCell.d.ts +6 -0
  35. package/dist/form/conditions/RatingFieldCondition/index.d.ts +3 -0
  36. package/dist/form/conditions/RatingFieldCondition/typings.d.ts +4 -0
  37. package/dist/form/conditions/ScanFieldCondition/ScanFieldCondition.d.ts +4 -6
  38. package/dist/form/conditions/SelectFieldCondition/SelectFieldCondition.d.ts +4 -6
  39. package/dist/form/conditions/StringFieldCondition/StringFieldCondition.d.ts +4 -6
  40. package/dist/form/conditions/TextFieldCondition/TextFieldCondition.d.ts +4 -6
  41. package/dist/form/conditions/UploadFieldCondition/UploadFieldCondition.d.ts +8 -8
  42. package/dist/form/conditions/constants.d.ts +32 -0
  43. package/dist/form/conditions/index.d.ts +3 -0
  44. package/dist/form/conditions/typings.d.ts +6 -3
  45. package/dist/form/conditions/utils.d.ts +3 -4
  46. package/dist/form/fields/BaseField/BaseField.d.ts +5 -6
  47. package/dist/form/fields/BaseField/typings.d.ts +3 -4
  48. package/dist/form/fields/BaseFormElement/BaseFormElement.d.ts +9 -9
  49. package/dist/form/fields/BaseFormElement/typings.d.ts +3 -3
  50. package/dist/form/fields/BaseOptionsField/BaseOptionsField.d.ts +6 -6
  51. package/dist/form/fields/BaseOptionsField/typings.d.ts +2 -2
  52. package/dist/form/fields/BaseStringField/BaseStringField.d.ts +3 -3
  53. package/dist/form/fields/BaseStringField/typings.d.ts +1 -1
  54. package/dist/form/fields/BooleanField/BooleanField.d.ts +2 -3
  55. package/dist/form/fields/CheckboxListField/CheckboxListField.d.ts +1 -1
  56. package/dist/form/fields/DateField/DateField.d.ts +1 -1
  57. package/dist/form/fields/FieldSection/FieldSection.d.ts +5 -7
  58. package/dist/form/fields/FieldSection/typings.d.ts +2 -2
  59. package/dist/form/fields/MultiSelectField/MultiSelectField.d.ts +1 -1
  60. package/dist/form/fields/MultiStringField/MultiStringField.d.ts +1 -1
  61. package/dist/form/fields/NumberField/NumberField.d.ts +1 -1
  62. package/dist/form/fields/OneTimePasswordField/OTPField.d.ts +1 -1
  63. package/dist/form/fields/PassFailField/PassFailField.d.ts +30 -0
  64. package/dist/form/fields/PassFailField/PassFailInput.d.ts +7 -0
  65. package/dist/form/fields/PassFailField/constants.d.ts +7 -0
  66. package/dist/form/fields/PassFailField/index.d.ts +5 -0
  67. package/dist/form/fields/PassFailField/typings.d.ts +17 -0
  68. package/dist/form/fields/PassFailField/utils.d.ts +7 -0
  69. package/dist/form/fields/RadioField/RadioField.d.ts +1 -1
  70. package/dist/form/fields/RatingField/RatingField.d.ts +32 -0
  71. package/dist/form/fields/RatingField/RatingInput.d.ts +7 -0
  72. package/dist/form/fields/RatingField/index.d.ts +3 -0
  73. package/dist/form/fields/RatingField/typings.d.ts +4 -0
  74. package/dist/form/fields/ScanField/ScanField.d.ts +1 -1
  75. package/dist/form/fields/SelectField/SelectField.d.ts +1 -1
  76. package/dist/form/fields/UploadField/UploadField.d.ts +10 -9
  77. package/dist/form/fields/UploadField/index.d.ts +0 -1
  78. package/dist/form/fields/UploadField/utils.d.ts +0 -3
  79. package/dist/form/fields/constants.d.ts +6 -2
  80. package/dist/form/fields/index.d.ts +2 -0
  81. package/dist/form/fields/typings.d.ts +14 -16
  82. package/dist/form/fields/utils.d.ts +6 -1
  83. package/dist/form/index.d.ts +3 -0
  84. package/dist/form/modifiers/file.d.ts +3 -2
  85. package/dist/form/modifiers/index.d.ts +1 -0
  86. package/dist/form/modifiers/passFailStatus.d.ts +6 -0
  87. package/dist/form/modifiers/utils.d.ts +1 -1
  88. package/dist/form/schema/FieldSchema.d.ts +6 -5
  89. package/dist/form/typings.d.ts +6 -2
  90. package/dist/form/utils.d.ts +5 -11
  91. package/dist/forms.js +2117 -678
  92. package/dist/forms.umd.cjs +2115 -676
  93. package/package.json +3 -5
  94. package/dist/form/builder/components/FieldWithActions.d.ts +0 -10
  95. /package/dist/form/{observable → Observable}/Observable.d.ts +0 -0
  96. /package/dist/form/{fields/UploadField → UUIDPromise}/UUIDPromise.d.ts +0 -0
package/dist/forms.js CHANGED
@@ -2,9 +2,9 @@ var __defProp = Object.defineProperty;
2
2
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
3
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
4
  import { jsxs, jsx, Fragment as Fragment$1 } from "react/jsx-runtime";
5
- import { Card, LuIcon, Text, Spinner, Overlay, ButtonGroup, Tooltip, IconButton, Separator, Input, Badge, Checkbox, CheckboxGroup, Popover, Button, DayPicker, Menu, OneTimePasswordField, RadioGroup, TextArea, stopPropagation, Heading, useToast, ToggleGroup } from "@overmap-ai/blocks";
5
+ import { Card, LuIcon, Text, Spinner, Overlay, ButtonGroup, Tooltip, IconButton, Separator, Input, Badge, Checkbox, CheckboxGroup, Popover, Button, DayPicker, Menu, OneTimePasswordField, RadioGroup, TextArea, Rating, stopPropagation, Heading, useToast, ToggleGroup } from "@overmap-ai/blocks";
6
6
  import { cx } from "class-variance-authority";
7
- import { memo, forwardRef, createContext, useContext, useRef, useCallback, useState, useEffect, useMemo, Fragment, use, useLayoutEffect, useId } from "react";
7
+ import { forwardRef, createElement, memo, createContext, useContext, useRef, useCallback, useState, useEffect, useMemo, Fragment, use, useLayoutEffect, useId } from "react";
8
8
  import "@xyflow/react/dist/style.css";
9
9
  import { getBezierPath, Position, BaseEdge, EdgeLabelRenderer, NodeToolbar, Handle, MarkerType, useNodesState, useEdgesState, ReactFlow, Panel } from "@xyflow/react";
10
10
  import { useField, useFormikContext, useFormik, FormikProvider } from "formik";
@@ -17,11 +17,609 @@ import { DecodeHintType as DecodeHintType$2, useZxing } from "react-zxing";
17
17
  import get from "lodash.get";
18
18
  import Dagre from "@dagrejs/dagre";
19
19
  import set from "lodash.set";
20
+ /**
21
+ * @license lucide-react v0.542.0 - ISC
22
+ *
23
+ * This source code is licensed under the ISC license.
24
+ * See the LICENSE file in the root directory of this source tree.
25
+ */
26
+ const toKebabCase = (string) => string.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();
27
+ const toCamelCase = (string) => string.replace(
28
+ /^([A-Z])|[\s-_]+(\w)/g,
29
+ (match, p1, p2) => p2 ? p2.toUpperCase() : p1.toLowerCase()
30
+ );
31
+ const toPascalCase = (string) => {
32
+ const camelCase = toCamelCase(string);
33
+ return camelCase.charAt(0).toUpperCase() + camelCase.slice(1);
34
+ };
35
+ const mergeClasses = (...classes) => classes.filter((className, index, array) => {
36
+ return Boolean(className) && className.trim() !== "" && array.indexOf(className) === index;
37
+ }).join(" ").trim();
38
+ const hasA11yProp = (props) => {
39
+ for (const prop in props) {
40
+ if (prop.startsWith("aria-") || prop === "role" || prop === "title") {
41
+ return true;
42
+ }
43
+ }
44
+ };
45
+ /**
46
+ * @license lucide-react v0.542.0 - ISC
47
+ *
48
+ * This source code is licensed under the ISC license.
49
+ * See the LICENSE file in the root directory of this source tree.
50
+ */
51
+ var defaultAttributes = {
52
+ xmlns: "http://www.w3.org/2000/svg",
53
+ width: 24,
54
+ height: 24,
55
+ viewBox: "0 0 24 24",
56
+ fill: "none",
57
+ stroke: "currentColor",
58
+ strokeWidth: 2,
59
+ strokeLinecap: "round",
60
+ strokeLinejoin: "round"
61
+ };
62
+ /**
63
+ * @license lucide-react v0.542.0 - ISC
64
+ *
65
+ * This source code is licensed under the ISC license.
66
+ * See the LICENSE file in the root directory of this source tree.
67
+ */
68
+ const Icon = forwardRef(
69
+ ({
70
+ color = "currentColor",
71
+ size = 24,
72
+ strokeWidth = 2,
73
+ absoluteStrokeWidth,
74
+ className = "",
75
+ children,
76
+ iconNode,
77
+ ...rest
78
+ }, ref) => createElement(
79
+ "svg",
80
+ {
81
+ ref,
82
+ ...defaultAttributes,
83
+ width: size,
84
+ height: size,
85
+ stroke: color,
86
+ strokeWidth: absoluteStrokeWidth ? Number(strokeWidth) * 24 / Number(size) : strokeWidth,
87
+ className: mergeClasses("lucide", className),
88
+ ...!children && !hasA11yProp(rest) && { "aria-hidden": "true" },
89
+ ...rest
90
+ },
91
+ [
92
+ ...iconNode.map(([tag, attrs]) => createElement(tag, attrs)),
93
+ ...Array.isArray(children) ? children : [children]
94
+ ]
95
+ )
96
+ );
97
+ /**
98
+ * @license lucide-react v0.542.0 - ISC
99
+ *
100
+ * This source code is licensed under the ISC license.
101
+ * See the LICENSE file in the root directory of this source tree.
102
+ */
103
+ const createLucideIcon = (iconName, iconNode) => {
104
+ const Component = forwardRef(
105
+ ({ className, ...props }, ref) => createElement(Icon, {
106
+ ref,
107
+ iconNode,
108
+ className: mergeClasses(
109
+ `lucide-${toKebabCase(toPascalCase(iconName))}`,
110
+ `lucide-${iconName}`,
111
+ className
112
+ ),
113
+ ...props
114
+ })
115
+ );
116
+ Component.displayName = toPascalCase(iconName);
117
+ return Component;
118
+ };
119
+ /**
120
+ * @license lucide-react v0.542.0 - ISC
121
+ *
122
+ * This source code is licensed under the ISC license.
123
+ * See the LICENSE file in the root directory of this source tree.
124
+ */
125
+ const __iconNode$D = [
126
+ ["path", { d: "M3 12h18", key: "1i2n21" }],
127
+ ["path", { d: "M3 18h18", key: "1h113x" }],
128
+ ["path", { d: "M3 6h18", key: "d0wm0j" }]
129
+ ];
130
+ const AlignJustify = createLucideIcon("align-justify", __iconNode$D);
131
+ /**
132
+ * @license lucide-react v0.542.0 - ISC
133
+ *
134
+ * This source code is licensed under the ISC license.
135
+ * See the LICENSE file in the root directory of this source tree.
136
+ */
137
+ const __iconNode$C = [
138
+ ["path", { d: "m3 16 4 4 4-4", key: "1co6wj" }],
139
+ ["path", { d: "M7 20V4", key: "1yoxec" }],
140
+ ["path", { d: "m21 8-4-4-4 4", key: "1c9v7m" }],
141
+ ["path", { d: "M17 4v16", key: "7dpous" }]
142
+ ];
143
+ const ArrowDownUp = createLucideIcon("arrow-down-up", __iconNode$C);
144
+ /**
145
+ * @license lucide-react v0.542.0 - ISC
146
+ *
147
+ * This source code is licensed under the ISC license.
148
+ * See the LICENSE file in the root directory of this source tree.
149
+ */
150
+ const __iconNode$B = [
151
+ ["path", { d: "M8 3 4 7l4 4", key: "9rb6wj" }],
152
+ ["path", { d: "M4 7h16", key: "6tx8e3" }],
153
+ ["path", { d: "m16 21 4-4-4-4", key: "siv7j2" }],
154
+ ["path", { d: "M20 17H4", key: "h6l3hr" }]
155
+ ];
156
+ const ArrowLeftRight = createLucideIcon("arrow-left-right", __iconNode$B);
157
+ /**
158
+ * @license lucide-react v0.542.0 - ISC
159
+ *
160
+ * This source code is licensed under the ISC license.
161
+ * See the LICENSE file in the root directory of this source tree.
162
+ */
163
+ const __iconNode$A = [
164
+ ["path", { d: "M8 2v4", key: "1cmpym" }],
165
+ ["path", { d: "M16 2v4", key: "4m81vk" }],
166
+ ["rect", { width: "18", height: "18", x: "3", y: "4", rx: "2", key: "1hopcy" }],
167
+ ["path", { d: "M3 10h18", key: "8toen8" }]
168
+ ];
169
+ const Calendar = createLucideIcon("calendar", __iconNode$A);
170
+ /**
171
+ * @license lucide-react v0.542.0 - ISC
172
+ *
173
+ * This source code is licensed under the ISC license.
174
+ * See the LICENSE file in the root directory of this source tree.
175
+ */
176
+ const __iconNode$z = [["path", { d: "M20 6 9 17l-5-5", key: "1gmf2c" }]];
177
+ const Check = createLucideIcon("check", __iconNode$z);
178
+ /**
179
+ * @license lucide-react v0.542.0 - ISC
180
+ *
181
+ * This source code is licensed under the ISC license.
182
+ * See the LICENSE file in the root directory of this source tree.
183
+ */
184
+ const __iconNode$y = [["path", { d: "m6 9 6 6 6-6", key: "qrunsl" }]];
185
+ const ChevronDown = createLucideIcon("chevron-down", __iconNode$y);
186
+ /**
187
+ * @license lucide-react v0.542.0 - ISC
188
+ *
189
+ * This source code is licensed under the ISC license.
190
+ * See the LICENSE file in the root directory of this source tree.
191
+ */
192
+ const __iconNode$x = [
193
+ ["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }],
194
+ ["path", { d: "m9 12 2 2 4-4", key: "dzmm74" }]
195
+ ];
196
+ const CircleCheck = createLucideIcon("circle-check", __iconNode$x);
197
+ /**
198
+ * @license lucide-react v0.542.0 - ISC
199
+ *
200
+ * This source code is licensed under the ISC license.
201
+ * See the LICENSE file in the root directory of this source tree.
202
+ */
203
+ const __iconNode$w = [
204
+ ["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }],
205
+ ["circle", { cx: "12", cy: "12", r: "1", key: "41hilf" }]
206
+ ];
207
+ const CircleDot = createLucideIcon("circle-dot", __iconNode$w);
208
+ /**
209
+ * @license lucide-react v0.542.0 - ISC
210
+ *
211
+ * This source code is licensed under the ISC license.
212
+ * See the LICENSE file in the root directory of this source tree.
213
+ */
214
+ const __iconNode$v = [
215
+ ["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }],
216
+ ["path", { d: "M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3", key: "1u773s" }],
217
+ ["path", { d: "M12 17h.01", key: "p32p05" }]
218
+ ];
219
+ const CircleQuestionMark = createLucideIcon("circle-question-mark", __iconNode$v);
220
+ /**
221
+ * @license lucide-react v0.542.0 - ISC
222
+ *
223
+ * This source code is licensed under the ISC license.
224
+ * See the LICENSE file in the root directory of this source tree.
225
+ */
226
+ const __iconNode$u = [
227
+ ["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }],
228
+ ["path", { d: "m15 9-6 6", key: "1uzhvr" }],
229
+ ["path", { d: "m9 9 6 6", key: "z0biqf" }]
230
+ ];
231
+ const CircleX = createLucideIcon("circle-x", __iconNode$u);
232
+ /**
233
+ * @license lucide-react v0.542.0 - ISC
234
+ *
235
+ * This source code is licensed under the ISC license.
236
+ * See the LICENSE file in the root directory of this source tree.
237
+ */
238
+ const __iconNode$t = [["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }]];
239
+ const Circle = createLucideIcon("circle", __iconNode$t);
240
+ /**
241
+ * @license lucide-react v0.542.0 - ISC
242
+ *
243
+ * This source code is licensed under the ISC license.
244
+ * See the LICENSE file in the root directory of this source tree.
245
+ */
246
+ const __iconNode$s = [
247
+ ["rect", { width: "8", height: "4", x: "8", y: "2", rx: "1", ry: "1", key: "tgr4d6" }],
248
+ [
249
+ "path",
250
+ {
251
+ d: "M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2",
252
+ key: "116196"
253
+ }
254
+ ],
255
+ ["path", { d: "M12 11h4", key: "1jrz19" }],
256
+ ["path", { d: "M12 16h4", key: "n85exb" }],
257
+ ["path", { d: "M8 11h.01", key: "1dfujw" }],
258
+ ["path", { d: "M8 16h.01", key: "18s6g9" }]
259
+ ];
260
+ const ClipboardList = createLucideIcon("clipboard-list", __iconNode$s);
261
+ /**
262
+ * @license lucide-react v0.542.0 - ISC
263
+ *
264
+ * This source code is licensed under the ISC license.
265
+ * See the LICENSE file in the root directory of this source tree.
266
+ */
267
+ const __iconNode$r = [
268
+ ["path", { d: "m12 15 2 2 4-4", key: "2c609p" }],
269
+ ["rect", { width: "14", height: "14", x: "8", y: "8", rx: "2", ry: "2", key: "17jyea" }],
270
+ ["path", { d: "M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2", key: "zix9uf" }]
271
+ ];
272
+ const CopyCheck = createLucideIcon("copy-check", __iconNode$r);
273
+ /**
274
+ * @license lucide-react v0.542.0 - ISC
275
+ *
276
+ * This source code is licensed under the ISC license.
277
+ * See the LICENSE file in the root directory of this source tree.
278
+ */
279
+ const __iconNode$q = [
280
+ ["rect", { width: "14", height: "14", x: "8", y: "8", rx: "2", ry: "2", key: "17jyea" }],
281
+ ["path", { d: "M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2", key: "zix9uf" }]
282
+ ];
283
+ const Copy = createLucideIcon("copy", __iconNode$q);
284
+ /**
285
+ * @license lucide-react v0.542.0 - ISC
286
+ *
287
+ * This source code is licensed under the ISC license.
288
+ * See the LICENSE file in the root directory of this source tree.
289
+ */
290
+ const __iconNode$p = [
291
+ ["path", { d: "M12 15V3", key: "m9g1x1" }],
292
+ ["path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4", key: "ih7n3h" }],
293
+ ["path", { d: "m7 10 5 5 5-5", key: "brsn70" }]
294
+ ];
295
+ const Download = createLucideIcon("download", __iconNode$p);
296
+ /**
297
+ * @license lucide-react v0.542.0 - ISC
298
+ *
299
+ * This source code is licensed under the ISC license.
300
+ * See the LICENSE file in the root directory of this source tree.
301
+ */
302
+ const __iconNode$o = [
303
+ ["path", { d: "M12 17h.01", key: "p32p05" }],
304
+ ["path", { d: "M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7z", key: "1mlx9k" }],
305
+ ["path", { d: "M9.1 9a3 3 0 0 1 5.82 1c0 2-3 3-3 3", key: "mhlwft" }]
306
+ ];
307
+ const FileQuestionMark = createLucideIcon("file-question-mark", __iconNode$o);
308
+ /**
309
+ * @license lucide-react v0.542.0 - ISC
310
+ *
311
+ * This source code is licensed under the ISC license.
312
+ * See the LICENSE file in the root directory of this source tree.
313
+ */
314
+ const __iconNode$n = [
315
+ ["path", { d: "M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z", key: "1rqfz7" }],
316
+ ["path", { d: "M12 9v4", key: "juzpu7" }],
317
+ ["path", { d: "M12 17h.01", key: "p32p05" }]
318
+ ];
319
+ const FileWarning = createLucideIcon("file-warning", __iconNode$n);
320
+ /**
321
+ * @license lucide-react v0.542.0 - ISC
322
+ *
323
+ * This source code is licensed under the ISC license.
324
+ * See the LICENSE file in the root directory of this source tree.
325
+ */
326
+ const __iconNode$m = [
327
+ ["path", { d: "M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z", key: "1rqfz7" }],
328
+ ["path", { d: "M14 2v4a2 2 0 0 0 2 2h4", key: "tnqrlb" }]
329
+ ];
330
+ const File$1 = createLucideIcon("file", __iconNode$m);
331
+ /**
332
+ * @license lucide-react v0.542.0 - ISC
333
+ *
334
+ * This source code is licensed under the ISC license.
335
+ * See the LICENSE file in the root directory of this source tree.
336
+ */
337
+ const __iconNode$l = [
338
+ ["line", { x1: "6", x2: "6", y1: "3", y2: "15", key: "17qcm7" }],
339
+ ["circle", { cx: "18", cy: "6", r: "3", key: "1h7g24" }],
340
+ ["circle", { cx: "6", cy: "18", r: "3", key: "fqmcym" }],
341
+ ["path", { d: "M18 9a9 9 0 0 1-9 9", key: "n2h4wq" }]
342
+ ];
343
+ const GitBranch = createLucideIcon("git-branch", __iconNode$l);
344
+ /**
345
+ * @license lucide-react v0.542.0 - ISC
346
+ *
347
+ * This source code is licensed under the ISC license.
348
+ * See the LICENSE file in the root directory of this source tree.
349
+ */
350
+ const __iconNode$k = [
351
+ ["line", { x1: "4", x2: "20", y1: "9", y2: "9", key: "4lhtct" }],
352
+ ["line", { x1: "4", x2: "20", y1: "15", y2: "15", key: "vyu0kd" }],
353
+ ["line", { x1: "10", x2: "8", y1: "3", y2: "21", key: "1ggp8o" }],
354
+ ["line", { x1: "16", x2: "14", y1: "3", y2: "21", key: "weycgp" }]
355
+ ];
356
+ const Hash = createLucideIcon("hash", __iconNode$k);
357
+ /**
358
+ * @license lucide-react v0.542.0 - ISC
359
+ *
360
+ * This source code is licensed under the ISC license.
361
+ * See the LICENSE file in the root directory of this source tree.
362
+ */
363
+ const __iconNode$j = [
364
+ ["rect", { width: "18", height: "18", x: "3", y: "3", rx: "2", ry: "2", key: "1m3agn" }],
365
+ ["circle", { cx: "9", cy: "9", r: "2", key: "af1f0g" }],
366
+ ["path", { d: "m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21", key: "1xmnt7" }]
367
+ ];
368
+ const Image = createLucideIcon("image", __iconNode$j);
369
+ /**
370
+ * @license lucide-react v0.542.0 - ISC
371
+ *
372
+ * This source code is licensed under the ISC license.
373
+ * See the LICENSE file in the root directory of this source tree.
374
+ */
375
+ const __iconNode$i = [
376
+ ["rect", { width: "18", height: "7", x: "3", y: "3", rx: "1", key: "f1a2em" }],
377
+ ["rect", { width: "7", height: "7", x: "3", y: "14", rx: "1", key: "1bb6yr" }],
378
+ ["rect", { width: "7", height: "7", x: "14", y: "14", rx: "1", key: "nxv5o0" }]
379
+ ];
380
+ const LayoutPanelTop = createLucideIcon("layout-panel-top", __iconNode$i);
381
+ /**
382
+ * @license lucide-react v0.542.0 - ISC
383
+ *
384
+ * This source code is licensed under the ISC license.
385
+ * See the LICENSE file in the root directory of this source tree.
386
+ */
387
+ const __iconNode$h = [
388
+ ["path", { d: "m3 17 2 2 4-4", key: "1jhpwq" }],
389
+ ["path", { d: "m3 7 2 2 4-4", key: "1obspn" }],
390
+ ["path", { d: "M13 6h8", key: "15sg57" }],
391
+ ["path", { d: "M13 12h8", key: "h98zly" }],
392
+ ["path", { d: "M13 18h8", key: "oe0vm4" }]
393
+ ];
394
+ const ListChecks = createLucideIcon("list-checks", __iconNode$h);
395
+ /**
396
+ * @license lucide-react v0.542.0 - ISC
397
+ *
398
+ * This source code is licensed under the ISC license.
399
+ * See the LICENSE file in the root directory of this source tree.
400
+ */
401
+ const __iconNode$g = [
402
+ ["rect", { x: "3", y: "5", width: "6", height: "6", rx: "1", key: "1defrl" }],
403
+ ["path", { d: "m3 17 2 2 4-4", key: "1jhpwq" }],
404
+ ["path", { d: "M13 6h8", key: "15sg57" }],
405
+ ["path", { d: "M13 12h8", key: "h98zly" }],
406
+ ["path", { d: "M13 18h8", key: "oe0vm4" }]
407
+ ];
408
+ const ListTodo = createLucideIcon("list-todo", __iconNode$g);
409
+ /**
410
+ * @license lucide-react v0.542.0 - ISC
411
+ *
412
+ * This source code is licensed under the ISC license.
413
+ * See the LICENSE file in the root directory of this source tree.
414
+ */
415
+ const __iconNode$f = [
416
+ ["path", { d: "M3 12h.01", key: "nlz23k" }],
417
+ ["path", { d: "M3 18h.01", key: "1tta3j" }],
418
+ ["path", { d: "M3 6h.01", key: "1rqtza" }],
419
+ ["path", { d: "M8 12h13", key: "1za7za" }],
420
+ ["path", { d: "M8 18h13", key: "1lx6n3" }],
421
+ ["path", { d: "M8 6h13", key: "ik3vkj" }]
422
+ ];
423
+ const List = createLucideIcon("list", __iconNode$f);
424
+ /**
425
+ * @license lucide-react v0.542.0 - ISC
426
+ *
427
+ * This source code is licensed under the ISC license.
428
+ * See the LICENSE file in the root directory of this source tree.
429
+ */
430
+ const __iconNode$e = [
431
+ ["path", { d: "M8 3H5a2 2 0 0 0-2 2v3", key: "1dcmit" }],
432
+ ["path", { d: "M21 8V5a2 2 0 0 0-2-2h-3", key: "1e4gt3" }],
433
+ ["path", { d: "M3 16v3a2 2 0 0 0 2 2h3", key: "wsl5sc" }],
434
+ ["path", { d: "M16 21h3a2 2 0 0 0 2-2v-3", key: "18trek" }]
435
+ ];
436
+ const Maximize = createLucideIcon("maximize", __iconNode$e);
437
+ /**
438
+ * @license lucide-react v0.542.0 - ISC
439
+ *
440
+ * This source code is licensed under the ISC license.
441
+ * See the LICENSE file in the root directory of this source tree.
442
+ */
443
+ const __iconNode$d = [["path", { d: "M5 12h14", key: "1ays0h" }]];
444
+ const Minus = createLucideIcon("minus", __iconNode$d);
445
+ /**
446
+ * @license lucide-react v0.542.0 - ISC
447
+ *
448
+ * This source code is licensed under the ISC license.
449
+ * See the LICENSE file in the root directory of this source tree.
450
+ */
451
+ const __iconNode$c = [
452
+ ["path", { d: "M8 18L12 22L16 18", key: "cskvfv" }],
453
+ ["path", { d: "M12 2V22", key: "r89rzk" }]
454
+ ];
455
+ const MoveDown = createLucideIcon("move-down", __iconNode$c);
456
+ /**
457
+ * @license lucide-react v0.542.0 - ISC
458
+ *
459
+ * This source code is licensed under the ISC license.
460
+ * See the LICENSE file in the root directory of this source tree.
461
+ */
462
+ const __iconNode$b = [
463
+ ["path", { d: "M8 6L12 2L16 6", key: "1yvkyx" }],
464
+ ["path", { d: "M12 2V22", key: "r89rzk" }]
465
+ ];
466
+ const MoveUp = createLucideIcon("move-up", __iconNode$b);
467
+ /**
468
+ * @license lucide-react v0.542.0 - ISC
469
+ *
470
+ * This source code is licensed under the ISC license.
471
+ * See the LICENSE file in the root directory of this source tree.
472
+ */
473
+ const __iconNode$a = [
474
+ ["path", { d: "M5 12h14", key: "1ays0h" }],
475
+ ["path", { d: "M12 5v14", key: "s699le" }]
476
+ ];
477
+ const Plus = createLucideIcon("plus", __iconNode$a);
478
+ /**
479
+ * @license lucide-react v0.542.0 - ISC
480
+ *
481
+ * This source code is licensed under the ISC license.
482
+ * See the LICENSE file in the root directory of this source tree.
483
+ */
484
+ const __iconNode$9 = [
485
+ ["rect", { width: "20", height: "12", x: "2", y: "6", rx: "2", key: "9lu3g6" }],
486
+ ["path", { d: "M12 12h.01", key: "1mp3jc" }],
487
+ ["path", { d: "M17 12h.01", key: "1m0b6t" }],
488
+ ["path", { d: "M7 12h.01", key: "eqddd0" }]
489
+ ];
490
+ const RectangleEllipsis = createLucideIcon("rectangle-ellipsis", __iconNode$9);
491
+ /**
492
+ * @license lucide-react v0.542.0 - ISC
493
+ *
494
+ * This source code is licensed under the ISC license.
495
+ * See the LICENSE file in the root directory of this source tree.
496
+ */
497
+ const __iconNode$8 = [
498
+ ["path", { d: "M3 7V5a2 2 0 0 1 2-2h2", key: "aa7l1z" }],
499
+ ["path", { d: "M17 3h2a2 2 0 0 1 2 2v2", key: "4qcy5o" }],
500
+ ["path", { d: "M21 17v2a2 2 0 0 1-2 2h-2", key: "6vwrx8" }],
501
+ ["path", { d: "M7 21H5a2 2 0 0 1-2-2v-2", key: "ioqczr" }]
502
+ ];
503
+ const Scan = createLucideIcon("scan", __iconNode$8);
504
+ /**
505
+ * @license lucide-react v0.542.0 - ISC
506
+ *
507
+ * This source code is licensed under the ISC license.
508
+ * See the LICENSE file in the root directory of this source tree.
509
+ */
510
+ const __iconNode$7 = [
511
+ [
512
+ "path",
513
+ {
514
+ d: "M9.671 4.136a2.34 2.34 0 0 1 4.659 0 2.34 2.34 0 0 0 3.319 1.915 2.34 2.34 0 0 1 2.33 4.033 2.34 2.34 0 0 0 0 3.831 2.34 2.34 0 0 1-2.33 4.033 2.34 2.34 0 0 0-3.319 1.915 2.34 2.34 0 0 1-4.659 0 2.34 2.34 0 0 0-3.32-1.915 2.34 2.34 0 0 1-2.33-4.033 2.34 2.34 0 0 0 0-3.831A2.34 2.34 0 0 1 6.35 6.051a2.34 2.34 0 0 0 3.319-1.915",
515
+ key: "1i5ecw"
516
+ }
517
+ ],
518
+ ["circle", { cx: "12", cy: "12", r: "3", key: "1v7zrd" }]
519
+ ];
520
+ const Settings = createLucideIcon("settings", __iconNode$7);
521
+ /**
522
+ * @license lucide-react v0.542.0 - ISC
523
+ *
524
+ * This source code is licensed under the ISC license.
525
+ * See the LICENSE file in the root directory of this source tree.
526
+ */
527
+ const __iconNode$6 = [
528
+ ["rect", { width: "18", height: "18", x: "3", y: "3", rx: "2", key: "afitv7" }],
529
+ ["path", { d: "m9 12 2 2 4-4", key: "dzmm74" }]
530
+ ];
531
+ const SquareCheck = createLucideIcon("square-check", __iconNode$6);
532
+ /**
533
+ * @license lucide-react v0.542.0 - ISC
534
+ *
535
+ * This source code is licensed under the ISC license.
536
+ * See the LICENSE file in the root directory of this source tree.
537
+ */
538
+ const __iconNode$5 = [
539
+ ["path", { d: "M5 3a2 2 0 0 0-2 2", key: "y57alp" }],
540
+ ["path", { d: "M19 3a2 2 0 0 1 2 2", key: "18rm91" }],
541
+ ["path", { d: "M21 19a2 2 0 0 1-2 2", key: "1j7049" }],
542
+ ["path", { d: "M5 21a2 2 0 0 1-2-2", key: "sbafld" }],
543
+ ["path", { d: "M9 3h1", key: "1yesri" }],
544
+ ["path", { d: "M9 21h1", key: "15o7lz" }],
545
+ ["path", { d: "M14 3h1", key: "1ec4yj" }],
546
+ ["path", { d: "M14 21h1", key: "v9vybs" }],
547
+ ["path", { d: "M3 9v1", key: "1r0deq" }],
548
+ ["path", { d: "M21 9v1", key: "mxsmne" }],
549
+ ["path", { d: "M3 14v1", key: "vnatye" }],
550
+ ["path", { d: "M21 14v1", key: "169vum" }]
551
+ ];
552
+ const SquareDashed = createLucideIcon("square-dashed", __iconNode$5);
553
+ /**
554
+ * @license lucide-react v0.542.0 - ISC
555
+ *
556
+ * This source code is licensed under the ISC license.
557
+ * See the LICENSE file in the root directory of this source tree.
558
+ */
559
+ const __iconNode$4 = [
560
+ [
561
+ "path",
562
+ {
563
+ d: "M11.525 2.295a.53.53 0 0 1 .95 0l2.31 4.679a2.123 2.123 0 0 0 1.595 1.16l5.166.756a.53.53 0 0 1 .294.904l-3.736 3.638a2.123 2.123 0 0 0-.611 1.878l.882 5.14a.53.53 0 0 1-.771.56l-4.618-2.428a2.122 2.122 0 0 0-1.973 0L6.396 21.01a.53.53 0 0 1-.77-.56l.881-5.139a2.122 2.122 0 0 0-.611-1.879L2.16 9.795a.53.53 0 0 1 .294-.906l5.165-.755a2.122 2.122 0 0 0 1.597-1.16z",
564
+ key: "r04s7s"
565
+ }
566
+ ]
567
+ ];
568
+ const Star = createLucideIcon("star", __iconNode$4);
569
+ /**
570
+ * @license lucide-react v0.542.0 - ISC
571
+ *
572
+ * This source code is licensed under the ISC license.
573
+ * See the LICENSE file in the root directory of this source tree.
574
+ */
575
+ const __iconNode$3 = [
576
+ ["path", { d: "M12 20h-1a2 2 0 0 1-2-2 2 2 0 0 1-2 2H6", key: "1528k5" }],
577
+ ["path", { d: "M13 8h7a2 2 0 0 1 2 2v4a2 2 0 0 1-2 2h-7", key: "13ksps" }],
578
+ ["path", { d: "M5 16H4a2 2 0 0 1-2-2v-4a2 2 0 0 1 2-2h1", key: "1n9rhb" }],
579
+ ["path", { d: "M6 4h1a2 2 0 0 1 2 2 2 2 0 0 1 2-2h1", key: "1mj8rg" }],
580
+ ["path", { d: "M9 6v12", key: "velyjx" }]
581
+ ];
582
+ const TextCursorInput = createLucideIcon("text-cursor-input", __iconNode$3);
583
+ /**
584
+ * @license lucide-react v0.542.0 - ISC
585
+ *
586
+ * This source code is licensed under the ISC license.
587
+ * See the LICENSE file in the root directory of this source tree.
588
+ */
589
+ const __iconNode$2 = [
590
+ ["path", { d: "M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6", key: "miytrc" }],
591
+ ["path", { d: "M3 6h18", key: "d0wm0j" }],
592
+ ["path", { d: "M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2", key: "e791ji" }]
593
+ ];
594
+ const Trash = createLucideIcon("trash", __iconNode$2);
595
+ /**
596
+ * @license lucide-react v0.542.0 - ISC
597
+ *
598
+ * This source code is licensed under the ISC license.
599
+ * See the LICENSE file in the root directory of this source tree.
600
+ */
601
+ const __iconNode$1 = [
602
+ ["path", { d: "M12 3v12", key: "1x0j5s" }],
603
+ ["path", { d: "m17 8-5-5-5 5", key: "7q97r8" }],
604
+ ["path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4", key: "ih7n3h" }]
605
+ ];
606
+ const Upload = createLucideIcon("upload", __iconNode$1);
607
+ /**
608
+ * @license lucide-react v0.542.0 - ISC
609
+ *
610
+ * This source code is licensed under the ISC license.
611
+ * See the LICENSE file in the root directory of this source tree.
612
+ */
613
+ const __iconNode = [
614
+ ["path", { d: "M18 6 6 18", key: "1bl5f8" }],
615
+ ["path", { d: "m6 6 12 12", key: "d8bk6v" }]
616
+ ];
617
+ const X = createLucideIcon("x", __iconNode);
20
618
  const FileCard = memo(
21
619
  forwardRef((props, ref) => {
22
620
  const { file, className, error, rightSlot, ...rest } = props;
23
621
  return /* @__PURE__ */ jsxs(Card, { className: cx(className, "flex w-full items-center gap-2 text-sm"), ref, ...rest, children: [
24
- error ? /* @__PURE__ */ jsx(LuIcon, { icon: "file-question-mark" }) : /* @__PURE__ */ jsx(LuIcon, { icon: "file", color: "var(--base-a11)" }),
622
+ error ? /* @__PURE__ */ jsx(LuIcon, { icon: FileQuestionMark }) : /* @__PURE__ */ jsx(LuIcon, { icon: File$1, color: "var(--base-a11)" }),
25
623
  !error ? file ? /* @__PURE__ */ jsx(Text, { className: "truncate", children: file.name }) : /* @__PURE__ */ jsx("div", { className: "flex w-full justify-center", children: /* @__PURE__ */ jsx(Spinner, {}) }) : /* @__PURE__ */ jsx(Text, { accentColor: "danger", className: "truncate", children: error }),
26
624
  rightSlot
27
625
  ] });
@@ -79,12 +677,11 @@ class BaseFormElement extends Observable {
79
677
  }
80
678
  class BaseField extends BaseFormElement {
81
679
  constructor(options) {
82
- const { label, description = null, required, image, fieldValidators = [], ...base } = options;
680
+ const { label, description = null, required, image, ...base } = options;
83
681
  super(base);
84
682
  __publicField(this, "label");
85
683
  __publicField(this, "description");
86
684
  __publicField(this, "required");
87
- __publicField(this, "fieldValidators");
88
685
  __publicField(this, "image");
89
686
  /**
90
687
  * By default, validation doesn't execute on `onChange` events when editing fields
@@ -97,7 +694,6 @@ class BaseField extends BaseFormElement {
97
694
  this.description = description;
98
695
  this.required = required;
99
696
  this.image = image;
100
- this.fieldValidators = fieldValidators;
101
697
  }
102
698
  getError(value) {
103
699
  if (this.required && this.isValueBlank(value)) {
@@ -123,24 +719,22 @@ class BaseField extends BaseFormElement {
123
719
  label: this.label,
124
720
  description: this.description,
125
721
  required: this.required,
126
- image: this.image,
127
- fieldValidators: this.fieldValidators
722
+ image: this.image
128
723
  };
129
724
  }
130
725
  setOptions(options) {
131
- const { label, description = null, required, image, fieldValidators, ...base } = options;
726
+ const { label, description = null, required, image, ...base } = options;
132
727
  this.label = label ?? this.label;
133
728
  this.description = description ?? this.description;
134
729
  this.required = required ?? this.required;
135
730
  this.image = image ?? this.image;
136
- this.fieldValidators = fieldValidators ?? this.fieldValidators;
137
731
  super.setOptions(base);
138
732
  }
139
733
  isValueBlank(value) {
140
734
  return this.areValuesEqual(value, this.blankValue());
141
735
  }
142
736
  getFieldValidators() {
143
- return [...this.fieldValidators];
737
+ return [];
144
738
  }
145
739
  }
146
740
  __publicField(BaseField, "fieldTypeName");
@@ -184,15 +778,15 @@ const ImageViewer = memo((props) => {
184
778
  variant: "ghost",
185
779
  children: [
186
780
  /* @__PURE__ */ jsxs(Tooltip.Root, { children: [
187
- /* @__PURE__ */ jsx(Tooltip.Trigger, { asChild: true, children: /* @__PURE__ */ jsx(IconButton, { onClick: handleCopy, "aria-label": "copy to clipboard", children: /* @__PURE__ */ jsx(LuIcon, { icon: "copy" }) }) }),
781
+ /* @__PURE__ */ jsx(Tooltip.Trigger, { asChild: true, children: /* @__PURE__ */ jsx(IconButton, { onClick: handleCopy, "aria-label": "copy to clipboard", children: /* @__PURE__ */ jsx(LuIcon, { icon: Copy }) }) }),
188
782
  /* @__PURE__ */ jsx(Tooltip.Content, { size: "sm", children: "Copy" })
189
783
  ] }),
190
784
  /* @__PURE__ */ jsxs(Tooltip.Root, { children: [
191
- /* @__PURE__ */ jsx(Tooltip.Trigger, { asChild: true, children: /* @__PURE__ */ jsx(IconButton, { onClick: handleDownload, "aria-label": "download", children: /* @__PURE__ */ jsx(LuIcon, { icon: "download" }) }) }),
785
+ /* @__PURE__ */ jsx(Tooltip.Trigger, { asChild: true, children: /* @__PURE__ */ jsx(IconButton, { onClick: handleDownload, "aria-label": "download", children: /* @__PURE__ */ jsx(LuIcon, { icon: Download }) }) }),
192
786
  /* @__PURE__ */ jsx(Tooltip.Content, { size: "sm", children: "Download" })
193
787
  ] }),
194
788
  /* @__PURE__ */ jsx(Separator, { orientation: "vertical", size: "sm" }),
195
- /* @__PURE__ */ jsx(Overlay.Close, { asChild: true, children: /* @__PURE__ */ jsx(IconButton, { onClick: onClose, "aria-label": "close", children: /* @__PURE__ */ jsx(LuIcon, { icon: "x" }) }) })
789
+ /* @__PURE__ */ jsx(Overlay.Close, { asChild: true, children: /* @__PURE__ */ jsx(IconButton, { onClick: onClose, "aria-label": "close", children: /* @__PURE__ */ jsx(LuIcon, { icon: X }) }) })
196
790
  ]
197
791
  }
198
792
  ),
@@ -430,7 +1024,7 @@ const MultiStringInput = memo((props) => {
430
1024
  "aria-label": "Add option",
431
1025
  disabled: !!internalError || disabled,
432
1026
  onClick: addOption,
433
- children: /* @__PURE__ */ jsx(LuIcon, { icon: "plus" })
1027
+ children: /* @__PURE__ */ jsx(LuIcon, { icon: Plus })
434
1028
  }
435
1029
  )
436
1030
  ] })
@@ -477,7 +1071,7 @@ const MultiStringInput = memo((props) => {
477
1071
  onClick: () => {
478
1072
  handleDeleteOption(index);
479
1073
  },
480
- children: /* @__PURE__ */ jsx(LuIcon, { icon: "x" })
1074
+ children: /* @__PURE__ */ jsx(LuIcon, { icon: X })
481
1075
  }
482
1076
  )
483
1077
  ]
@@ -665,7 +1259,7 @@ const BooleanInput = memo((props) => {
665
1259
  accentColor: "primary",
666
1260
  variant: "surface",
667
1261
  disabled,
668
- children: /* @__PURE__ */ jsx(Checkbox.Indicator, { children: /* @__PURE__ */ jsx(LuIcon, { icon: "check" }) })
1262
+ children: /* @__PURE__ */ jsx(Checkbox.Indicator, { children: /* @__PURE__ */ jsx(LuIcon, { icon: Check }) })
669
1263
  }
670
1264
  )
671
1265
  }
@@ -694,7 +1288,6 @@ const _BooleanField = class _BooleanField extends BaseField {
694
1288
  });
695
1289
  }
696
1290
  static deserialize(data) {
697
- if (data.type !== "boolean") throw new Error("Type mismatch.");
698
1291
  return new _BooleanField(data);
699
1292
  }
700
1293
  serializeValue(value) {
@@ -807,8 +1400,7 @@ const _NumberField = class _NumberField extends BaseField {
807
1400
  description: "Minimum value",
808
1401
  integers: true,
809
1402
  required: false,
810
- identifier: `${path}minimum`,
811
- fieldValidators: []
1403
+ identifier: `${path}minimum`
812
1404
  }),
813
1405
  showDirectly: false
814
1406
  },
@@ -818,8 +1410,7 @@ const _NumberField = class _NumberField extends BaseField {
818
1410
  description: "Maximum value",
819
1411
  integers: true,
820
1412
  required: false,
821
- identifier: `${path}maximum`,
822
- fieldValidators: []
1413
+ identifier: `${path}maximum`
823
1414
  }),
824
1415
  showDirectly: false
825
1416
  },
@@ -944,7 +1535,6 @@ class BaseStringField extends BaseField {
944
1535
  identifier: `${path}minimum_length`,
945
1536
  minimum: 0,
946
1537
  maximum: 100,
947
- fieldValidators: [],
948
1538
  integers: true
949
1539
  }),
950
1540
  showDirectly: false
@@ -958,7 +1548,6 @@ class BaseStringField extends BaseField {
958
1548
  minimum: 1,
959
1549
  maximum: LONG_TEXT_FIELD_MAX_LENGTH,
960
1550
  // TODO: depends on short vs long text
961
- fieldValidators: [],
962
1551
  // TODO: default: 500 (see: "Short text fields can hold up to 500 characters on a single line.")
963
1552
  integers: true
964
1553
  }),
@@ -1061,7 +1650,7 @@ const CheckboxListInput = memo((props) => {
1061
1650
  onValuesChange: handleChange,
1062
1651
  disabled,
1063
1652
  children: field.options.map((option, index) => /* @__PURE__ */ jsxs("label", { className: "flex gap-2 items-center min-w-0", children: [
1064
- /* @__PURE__ */ jsx(CheckboxGroup.Item, { value: option.value, children: /* @__PURE__ */ jsx(CheckboxGroup.ItemIndicator, { children: /* @__PURE__ */ jsx(LuIcon, { icon: "check" }) }) }),
1653
+ /* @__PURE__ */ jsx(CheckboxGroup.Item, { value: option.value, children: /* @__PURE__ */ jsx(CheckboxGroup.ItemIndicator, { children: /* @__PURE__ */ jsx(LuIcon, { icon: Check }) }) }),
1065
1654
  /* @__PURE__ */ jsx(Text, { size: "sm", accentColor: "base", className: "truncate", children: option.label })
1066
1655
  ] }, `${inputId}-${option.value}-${index}`))
1067
1656
  }
@@ -1163,7 +1752,7 @@ const DateInput = memo((props) => {
1163
1752
  month: "2-digit",
1164
1753
  day: "2-digit"
1165
1754
  }) : "yyyy-mm-dd",
1166
- /* @__PURE__ */ jsx(LuIcon, { icon: "chevron-down" })
1755
+ /* @__PURE__ */ jsx(LuIcon, { icon: ChevronDown })
1167
1756
  ]
1168
1757
  }
1169
1758
  ) }),
@@ -1274,13 +1863,13 @@ const MultiSelectInput = memo((props) => {
1274
1863
  disabled,
1275
1864
  children: [
1276
1865
  /* @__PURE__ */ jsx("span", { className: "truncate", children: value && value.length > 0 ? value.join(", ") : field.placeholder ?? "Select one or more..." }),
1277
- /* @__PURE__ */ jsx(LuIcon, { icon: "chevron-down" })
1866
+ /* @__PURE__ */ jsx(LuIcon, { icon: ChevronDown })
1278
1867
  ]
1279
1868
  }
1280
1869
  ) }),
1281
1870
  /* @__PURE__ */ jsx(Menu.Content, { children: /* @__PURE__ */ jsx(Menu.Scroll, { children: /* @__PURE__ */ jsxs(Menu.MultiSelectGroup, { values: value, onValuesChange: handleChange, children: [
1282
1871
  /* @__PURE__ */ jsxs(Menu.SelectAllItem, { children: [
1283
- /* @__PURE__ */ jsx(Menu.CheckboxItemIndicator, { children: (indeterminate) => indeterminate ? /* @__PURE__ */ jsx(LuIcon, { icon: "minus" }) : /* @__PURE__ */ jsx(LuIcon, { icon: "check" }) }),
1872
+ /* @__PURE__ */ jsx(Menu.CheckboxItemIndicator, { children: (indeterminate) => indeterminate ? /* @__PURE__ */ jsx(LuIcon, { icon: Minus }) : /* @__PURE__ */ jsx(LuIcon, { icon: Check }) }),
1284
1873
  "Select all"
1285
1874
  ] }),
1286
1875
  field.options.map((option, index) => /* @__PURE__ */ jsxs(
@@ -1288,7 +1877,7 @@ const MultiSelectInput = memo((props) => {
1288
1877
  {
1289
1878
  value: option.value,
1290
1879
  children: [
1291
- /* @__PURE__ */ jsx(Menu.SelectedIndicator, { children: /* @__PURE__ */ jsx(LuIcon, { icon: "check" }) }),
1880
+ /* @__PURE__ */ jsx(Menu.SelectedIndicator, { children: /* @__PURE__ */ jsx(LuIcon, { icon: Check }) }),
1292
1881
  option.label
1293
1882
  ]
1294
1883
  },
@@ -1394,12 +1983,12 @@ const SelectInput = memo((props) => {
1394
1983
  disabled,
1395
1984
  children: [
1396
1985
  /* @__PURE__ */ jsx("span", { className: "truncate", children: currentOption ? currentOption.label : field.placeholder ?? "Select one..." }),
1397
- /* @__PURE__ */ jsx(LuIcon, { icon: "chevron-down" })
1986
+ /* @__PURE__ */ jsx(LuIcon, { icon: ChevronDown })
1398
1987
  ]
1399
1988
  }
1400
1989
  ) }),
1401
1990
  /* @__PURE__ */ jsx(Menu.Content, { children: /* @__PURE__ */ jsx(Menu.Scroll, { children: /* @__PURE__ */ jsx(Menu.SelectGroup, { required: false, value: value ?? void 0, onValueChange: handleChange, children: field.options.map((option, index) => /* @__PURE__ */ jsxs(Menu.SelectItem, { value: option.value, children: [
1402
- /* @__PURE__ */ jsx(Menu.SelectedIndicator, { children: /* @__PURE__ */ jsx(LuIcon, { icon: "check" }) }),
1991
+ /* @__PURE__ */ jsx(Menu.SelectedIndicator, { children: /* @__PURE__ */ jsx(LuIcon, { icon: Check }) }),
1403
1992
  option.label
1404
1993
  ] }, `${inputId}-${option.value}-${index}`)) }) }) })
1405
1994
  ] })
@@ -1485,17 +2074,10 @@ const OTPInput = memo((props) => {
1485
2074
  },
1486
2075
  [field, helpers, touched]
1487
2076
  );
1488
- const handleBlur = useCallback(
1489
- (e) => {
1490
- const { relatedTarget } = e;
1491
- if (relatedTarget instanceof Element && inputUuids.includes(relatedTarget.id)) {
1492
- return;
1493
- }
1494
- onChange(internalValue);
1495
- onBlur(internalValue);
1496
- },
1497
- [inputUuids, internalValue, onBlur, onChange]
1498
- );
2077
+ const handleBlur = useCallback(() => {
2078
+ onChange(internalValue);
2079
+ onBlur(internalValue);
2080
+ }, [internalValue, onBlur, onChange]);
1499
2081
  return /* @__PURE__ */ jsx(InputWithLabelAndHelpText, { helpText: computedHelpText, severity, children: /* @__PURE__ */ jsx(
1500
2082
  InputWithLabel,
1501
2083
  {
@@ -1525,8 +2107,9 @@ const OTPInput = memo((props) => {
1525
2107
  accentColor: "base",
1526
2108
  variant: "surface",
1527
2109
  size: "sm",
2110
+ onBlur: handleBlur,
1528
2111
  children: [
1529
- inputUuids.map((inputUuid) => /* @__PURE__ */ jsx(OneTimePasswordField.Input, { id: inputUuid, onBlur: handleBlur }, inputUuid)),
2112
+ inputUuids.map((inputUuid) => /* @__PURE__ */ jsx(OneTimePasswordField.Input, { id: inputUuid }, inputUuid)),
1530
2113
  /* @__PURE__ */ jsx(OneTimePasswordField.HiddenInput, {})
1531
2114
  ]
1532
2115
  }
@@ -1556,8 +2139,7 @@ const _OTPField = class _OTPField extends BaseField {
1556
2139
  required: false,
1557
2140
  minimum: 1,
1558
2141
  maximum: 16,
1559
- identifier: `${path}length`,
1560
- fieldValidators: []
2142
+ identifier: `${path}length`
1561
2143
  }),
1562
2144
  showDirectly: false
1563
2145
  },
@@ -1653,6 +2235,564 @@ const _OTPField = class _OTPField extends BaseField {
1653
2235
  __publicField(_OTPField, "fieldTypeName", "OTP");
1654
2236
  __publicField(_OTPField, "fieldTypeDescription", "Allows specifying a number within a given range.");
1655
2237
  let OTPField = _OTPField;
2238
+ const passFailFieldStatusMapping = {
2239
+ pass: {
2240
+ label: "Pass",
2241
+ icon: CircleCheck
2242
+ },
2243
+ fail: {
2244
+ label: "Fail",
2245
+ icon: CircleX
2246
+ },
2247
+ na: {
2248
+ label: "N/A",
2249
+ icon: CircleQuestionMark
2250
+ }
2251
+ };
2252
+ const passFailFieldStatuses = Object.keys(passFailFieldStatusMapping);
2253
+ class UUIDFile extends File {
2254
+ constructor(uuid, ...args) {
2255
+ super(...args);
2256
+ __publicField(this, "uuid");
2257
+ this.uuid = uuid;
2258
+ }
2259
+ static from(uuid, file) {
2260
+ return new UUIDFile(uuid, [file], file.name, {
2261
+ lastModified: file.lastModified,
2262
+ type: file.type
2263
+ });
2264
+ }
2265
+ }
2266
+ class UUIDPromise extends Promise {
2267
+ constructor(executor, uuid) {
2268
+ super(executor);
2269
+ __publicField(this, "_uuid");
2270
+ this._uuid = uuid;
2271
+ }
2272
+ get uuid() {
2273
+ return this._uuid;
2274
+ }
2275
+ set uuid(uuid) {
2276
+ this._uuid = uuid;
2277
+ }
2278
+ static from(promise, uuid) {
2279
+ return new UUIDPromise((resolve, reject) => {
2280
+ Promise.resolve(promise).then(resolve).catch(reject);
2281
+ }, uuid);
2282
+ }
2283
+ then(onFulfilled, onRejected) {
2284
+ const promise = super.then(onFulfilled, onRejected);
2285
+ promise.uuid = this.uuid;
2286
+ return promise;
2287
+ }
2288
+ catch(onRejected) {
2289
+ const promise = super.catch(onRejected);
2290
+ promise.uuid = this.uuid;
2291
+ return promise;
2292
+ }
2293
+ finally(onFinally) {
2294
+ const promise = super.finally(onFinally);
2295
+ promise.uuid = this.uuid;
2296
+ return promise;
2297
+ }
2298
+ }
2299
+ function isFileAndPromiseArray(value) {
2300
+ if (!Array.isArray(value)) return false;
2301
+ return value.every((item) => item instanceof UUIDPromise || item instanceof UUIDFile);
2302
+ }
2303
+ function areFileAndPromiseArraysEqual(value1, value2) {
2304
+ if (!value1.every((promise1) => value2.some((promise2) => promise1.uuid === promise2.uuid))) return false;
2305
+ if (!value2.every((promise2) => value1.some((promise1) => promise1.uuid === promise2.uuid))) return false;
2306
+ return true;
2307
+ }
2308
+ const ImageCard = memo(
2309
+ forwardRef((props, forwardedRef) => {
2310
+ const { file, alt, error, rightSlot, className, ...rest } = props;
2311
+ return /* @__PURE__ */ jsxs(
2312
+ Card,
2313
+ {
2314
+ className: cx(className, "relative flex h-[200px] w-full flex-col gap-2 overflow-hidden items-center"),
2315
+ ref: forwardedRef,
2316
+ ...rest,
2317
+ children: [
2318
+ !file && !error && /* @__PURE__ */ jsx("div", { className: "absolute inset-0 grow flex items-center justify-center", children: /* @__PURE__ */ jsx(Spinner, {}) }),
2319
+ !!file && !error && /* @__PURE__ */ jsx(Card, { className: "flex max-w-full grow items-center !p-0 justify-center overflow-hidden bg-clip-padding", children: /* @__PURE__ */ jsx(
2320
+ "img",
2321
+ {
2322
+ className: "max-w-full object-cover",
2323
+ src: URL.createObjectURL(file),
2324
+ alt: alt ?? file.name
2325
+ }
2326
+ ) }),
2327
+ (!!file || !!error) && /* @__PURE__ */ jsxs(
2328
+ "div",
2329
+ {
2330
+ className: cx("flex w-full items-center gap-2 self-end", {
2331
+ "bg-transparent": !file
2332
+ }),
2333
+ children: [
2334
+ error ? /* @__PURE__ */ jsx(LuIcon, { icon: FileWarning }) : file && /* @__PURE__ */ jsx(LuIcon, { icon: File$1 }),
2335
+ /* @__PURE__ */ jsx(Text, { className: "truncate", size: "sm", children: error ?? (file == null ? void 0 : file.name) }),
2336
+ rightSlot
2337
+ ]
2338
+ }
2339
+ )
2340
+ ]
2341
+ }
2342
+ );
2343
+ })
2344
+ );
2345
+ const convertBytesToLargestUnit = (bytes) => {
2346
+ const units = ["byte", "kilobyte", "megabyte"];
2347
+ let sizeInUnit = bytes;
2348
+ let unitIndex = 0;
2349
+ while (sizeInUnit > 1e3 && unitIndex < units.length - 1) {
2350
+ sizeInUnit /= 1e3;
2351
+ unitIndex++;
2352
+ }
2353
+ const formatter = new Intl.NumberFormat([], {
2354
+ // 0 for bytes and kilobytes, 1 for megabytes
2355
+ maximumFractionDigits: Math.max(0, unitIndex - 1),
2356
+ style: "unit",
2357
+ unit: units[unitIndex]
2358
+ });
2359
+ return formatter.format(sizeInUnit);
2360
+ };
2361
+ const DisplayFile = memo((props) => {
2362
+ const { file, onRemove, disabled } = props;
2363
+ const [resolvedFile, setResolvedFile] = useState(null);
2364
+ const [error, setError] = useState(null);
2365
+ const openImageViewer = useImageViewer();
2366
+ const { url, name } = useMemo(() => {
2367
+ let url2 = null;
2368
+ let name2;
2369
+ let size;
2370
+ if (resolvedFile == null ? void 0 : resolvedFile.type.startsWith("image/")) {
2371
+ url2 = URL.createObjectURL(resolvedFile);
2372
+ }
2373
+ if (resolvedFile) {
2374
+ name2 = resolvedFile.name;
2375
+ size = convertBytesToLargestUnit(resolvedFile.size);
2376
+ } else {
2377
+ name2 = "Downloading...";
2378
+ size = "...";
2379
+ }
2380
+ return { url: url2, name: name2, size };
2381
+ }, [resolvedFile]);
2382
+ useEffect(() => {
2383
+ if (file instanceof UUIDPromise) {
2384
+ file.then((file2) => {
2385
+ setResolvedFile(file2);
2386
+ }).catch((err) => {
2387
+ setError(err instanceof Error ? err.message : "Unknown error");
2388
+ });
2389
+ } else {
2390
+ setResolvedFile(file);
2391
+ }
2392
+ }, [file]);
2393
+ const handleDownload = useCallback(
2394
+ (event) => {
2395
+ event.stopPropagation();
2396
+ if (!resolvedFile) {
2397
+ throw new Error("Cannot download a file that is not resolved.");
2398
+ }
2399
+ const blob = new Blob([resolvedFile]);
2400
+ saveAs(blob, name);
2401
+ },
2402
+ [name, resolvedFile]
2403
+ );
2404
+ const handleDelete = useCallback(
2405
+ (e) => {
2406
+ e.stopPropagation();
2407
+ onRemove();
2408
+ },
2409
+ [onRemove]
2410
+ );
2411
+ const handleImageCardClick = useCallback(() => {
2412
+ if (!resolvedFile) return;
2413
+ openImageViewer((closeFileViewer) => ({
2414
+ file: resolvedFile,
2415
+ onDelete: !disabled ? () => {
2416
+ onRemove();
2417
+ closeFileViewer();
2418
+ } : void 0
2419
+ }));
2420
+ }, [disabled, onRemove, openImageViewer, resolvedFile]);
2421
+ const rightSlotContent = useMemo(
2422
+ () => /* @__PURE__ */ jsxs(ButtonGroup, { className: "flex grow justify-end", variant: "ghost", accentColor: "base", size: "sm", children: [
2423
+ /* @__PURE__ */ jsx(
2424
+ IconButton,
2425
+ {
2426
+ "aria-label": `Download ${name}`,
2427
+ type: "button",
2428
+ onClick: handleDownload,
2429
+ disabled: !resolvedFile,
2430
+ children: /* @__PURE__ */ jsx(LuIcon, { icon: Download })
2431
+ }
2432
+ ),
2433
+ !disabled && /* @__PURE__ */ jsx(IconButton, { type: "button", "aria-label": `Remove ${name}`, disabled, onClick: handleDelete, children: /* @__PURE__ */ jsx(LuIcon, { icon: Trash }) })
2434
+ ] }),
2435
+ [disabled, handleDelete, handleDownload, name, resolvedFile]
2436
+ );
2437
+ return url ? /* @__PURE__ */ jsx(
2438
+ ImageCard,
2439
+ {
2440
+ className: "cursor-pointer",
2441
+ onClick: handleImageCardClick,
2442
+ file: resolvedFile,
2443
+ error: error ?? void 0,
2444
+ rightSlot: rightSlotContent
2445
+ }
2446
+ ) : /* @__PURE__ */ jsx(FileCard, { file: resolvedFile, error: error ?? void 0, rightSlot: rightSlotContent });
2447
+ });
2448
+ DisplayFile.displayName = "DisplayFile";
2449
+ const PassFailInput = memo((props) => {
2450
+ const [
2451
+ { inputId, labelId, size, severity, showInputOnly, field, helpText, label, fieldProps, touched, helpers },
2452
+ { disabled }
2453
+ ] = useFormikInput(props);
2454
+ const { value, onChange, onBlur, name } = fieldProps;
2455
+ const [internalNotes, setInternalNotes] = useState("");
2456
+ const input = useRef(null);
2457
+ const computedHelpText = showInputOnly ? null : helpText;
2458
+ const computedLabel = showInputOnly ? "" : label;
2459
+ const showNotesAndFiles = value.status && field.showNotesAndFilesOn.includes(value.status);
2460
+ const handleStatusChange = useCallback(
2461
+ (status) => {
2462
+ const newValue = field.cleanValue({
2463
+ ...value,
2464
+ status
2465
+ });
2466
+ onChange(newValue);
2467
+ onBlur(newValue);
2468
+ },
2469
+ [field, onBlur, onChange, value]
2470
+ );
2471
+ useEffect(() => {
2472
+ setInternalNotes(value.notes);
2473
+ }, [value]);
2474
+ const handleNotesChange = useCallback(
2475
+ (e) => {
2476
+ const notes = e.target.value;
2477
+ setInternalNotes(notes);
2478
+ if (touched || !field.onlyValidateAfterTouched) {
2479
+ helpers.setError(
2480
+ field.getError({
2481
+ ...value,
2482
+ notes: internalNotes
2483
+ })
2484
+ );
2485
+ }
2486
+ },
2487
+ [field, helpers, internalNotes, touched, value]
2488
+ );
2489
+ const handleNotesBlur = useCallback(() => {
2490
+ const newValue = {
2491
+ ...value,
2492
+ notes: internalNotes
2493
+ };
2494
+ onChange(newValue);
2495
+ onBlur(newValue);
2496
+ }, [internalNotes, onBlur, onChange, value]);
2497
+ const handleRemoveFile = useCallback(
2498
+ (index) => {
2499
+ const files = [...value.files];
2500
+ files.splice(index, 1);
2501
+ onChange({
2502
+ ...value,
2503
+ files
2504
+ });
2505
+ },
2506
+ [onChange, value]
2507
+ );
2508
+ const handleFileButtonClick = useCallback(() => {
2509
+ var _a2;
2510
+ (_a2 = input.current) == null ? void 0 : _a2.click();
2511
+ }, []);
2512
+ const handleFilesChange = useCallback(
2513
+ (e) => {
2514
+ const files = Array.from(e.target.files ?? []).map((file) => UUIDFile.from(v4(), file));
2515
+ const newValue = {
2516
+ ...value,
2517
+ files: [...value.files, ...files]
2518
+ };
2519
+ onChange(newValue);
2520
+ onBlur(newValue);
2521
+ },
2522
+ [onBlur, onChange, value]
2523
+ );
2524
+ useEffect(() => {
2525
+ if (!input.current) return;
2526
+ const abortController = new AbortController();
2527
+ input.current.addEventListener(
2528
+ "cancel",
2529
+ () => {
2530
+ onBlur(value);
2531
+ },
2532
+ {
2533
+ signal: abortController.signal
2534
+ }
2535
+ );
2536
+ return () => {
2537
+ abortController.abort();
2538
+ };
2539
+ }, [onBlur, value]);
2540
+ const statusInputId = `${inputId}-status`;
2541
+ const notesInputId = `${inputId}-notes`;
2542
+ const filesInputId = `${inputId}-files`;
2543
+ return /* @__PURE__ */ jsx(InputWithLabelAndHelpText, { helpText: computedHelpText, severity, children: /* @__PURE__ */ jsx(
2544
+ InputWithLabel,
2545
+ {
2546
+ size,
2547
+ severity,
2548
+ inputId,
2549
+ labelId,
2550
+ label: computedLabel,
2551
+ image: showInputOnly ? void 0 : field.image,
2552
+ children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
2553
+ /* @__PURE__ */ jsx(
2554
+ RadioGroup.Root,
2555
+ {
2556
+ id: statusInputId,
2557
+ className: "flex gap-2",
2558
+ name,
2559
+ value: value.status,
2560
+ disabled,
2561
+ accentColor: "base",
2562
+ variant: "surface",
2563
+ size: "sm",
2564
+ onValueChange: handleStatusChange,
2565
+ children: passFailFieldStatuses.map((status) => {
2566
+ const { label: label2 } = passFailFieldStatusMapping[status];
2567
+ return /* @__PURE__ */ jsxs("label", { className: "flex gap-2 items-center min-w-0", children: [
2568
+ /* @__PURE__ */ jsx(RadioGroup.Item, { value: status, children: /* @__PURE__ */ jsx(RadioGroup.Indicator, { children: /* @__PURE__ */ jsx(LuIcon, { icon: Circle, className: "fill-current" }) }) }),
2569
+ /* @__PURE__ */ jsx(Text, { size: "sm", accentColor: "base", className: "truncate", children: label2 })
2570
+ ] }, `${inputId}-${status}`);
2571
+ })
2572
+ }
2573
+ ),
2574
+ showNotesAndFiles && /* @__PURE__ */ jsxs(Fragment$1, { children: [
2575
+ /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(
2576
+ TextArea,
2577
+ {
2578
+ id: notesInputId,
2579
+ value: internalNotes,
2580
+ name,
2581
+ onChange: handleNotesChange,
2582
+ onBlur: handleNotesBlur,
2583
+ className: "field-sizing-content w-full min-h-12",
2584
+ placeholder: "Notes",
2585
+ resize: "vertical",
2586
+ accentColor: "base",
2587
+ variant: "surface",
2588
+ size: "sm",
2589
+ disabled
2590
+ }
2591
+ ) }),
2592
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
2593
+ /* @__PURE__ */ jsxs(
2594
+ Button,
2595
+ {
2596
+ className: "w-max",
2597
+ size: "sm",
2598
+ variant: "soft",
2599
+ accentColor: "base",
2600
+ onClick: handleFileButtonClick,
2601
+ type: "button",
2602
+ disabled,
2603
+ children: [
2604
+ /* @__PURE__ */ jsx(LuIcon, { icon: Upload }),
2605
+ "Select files"
2606
+ ]
2607
+ }
2608
+ ),
2609
+ /* @__PURE__ */ jsx(
2610
+ "input",
2611
+ {
2612
+ id: filesInputId,
2613
+ name,
2614
+ type: "file",
2615
+ ref: input,
2616
+ multiple: true,
2617
+ className: "hidden",
2618
+ onChange: handleFilesChange,
2619
+ value: ""
2620
+ }
2621
+ ),
2622
+ value.files.length > 0 && /* @__PURE__ */ jsx("div", { className: "flex h-max flex-col gap-2", children: value.files.map((file, index) => /* @__PURE__ */ jsx(
2623
+ DisplayFile,
2624
+ {
2625
+ file,
2626
+ onRemove: () => {
2627
+ handleRemoveFile(index);
2628
+ },
2629
+ disabled
2630
+ },
2631
+ index
2632
+ )) })
2633
+ ] })
2634
+ ] })
2635
+ ] })
2636
+ }
2637
+ ) });
2638
+ });
2639
+ PassFailInput.displayName = "PassFailInput";
2640
+ const isPassFailFieldStatus = (value) => {
2641
+ return typeof value === "string" && passFailFieldStatuses.includes(value);
2642
+ };
2643
+ const isSerializedPassFailFieldValue = (value) => {
2644
+ if (value === null || typeof value !== "object") return false;
2645
+ if (!("status" in value) || !isPassFailFieldStatus(value.status)) return false;
2646
+ if (!("notes" in value) || !(typeof value.notes === "string")) return false;
2647
+ if (!("files" in value) || !(Array.isArray(value.files) && value.files.length === 0)) return false;
2648
+ return true;
2649
+ };
2650
+ const isPassFailFieldValue = (value) => {
2651
+ if (value === null || typeof value !== "object") return false;
2652
+ if (!("status" in value) || !isPassFailFieldStatus(value.status)) return false;
2653
+ if (!("notes" in value) || !(typeof value.notes === "string")) return false;
2654
+ if (!("files" in value) || !isFileAndPromiseArray(value.files)) return false;
2655
+ return true;
2656
+ };
2657
+ const serializePassFailFieldValue = (value) => {
2658
+ return {
2659
+ status: value.status,
2660
+ notes: value.notes,
2661
+ files: []
2662
+ };
2663
+ };
2664
+ const deserializePassFailFieldValue = (value) => {
2665
+ return {
2666
+ status: value.status,
2667
+ notes: value.notes,
2668
+ files: []
2669
+ };
2670
+ };
2671
+ const arePassFieldValuesEqual = (value1, value2) => {
2672
+ if (value1.status !== value2.status) return false;
2673
+ if (value1.notes !== value2.notes) return false;
2674
+ if (!areFileAndPromiseArraysEqual(value1.files, value2.files)) return false;
2675
+ return true;
2676
+ };
2677
+ const _PassFailField = class _PassFailField extends BaseField {
2678
+ constructor(options) {
2679
+ const { showNotesAndFilesOn, ...rest } = options;
2680
+ super(rest);
2681
+ __publicField(this, "type", "pass-fail");
2682
+ __publicField(this, "onlyValidateAfterTouched", false);
2683
+ __publicField(this, "showNotesAndFilesOn");
2684
+ this.showNotesAndFilesOn = showNotesAndFilesOn;
2685
+ }
2686
+ static getFieldCreationSchema(parentPath = "") {
2687
+ const path = parentPath && `${parentPath}.`;
2688
+ return [
2689
+ {
2690
+ field: new MultiSelectField({
2691
+ identifier: `${path}showNotesAndFilesOn`,
2692
+ label: "Show notes and files on",
2693
+ description: "Show the notes and files on desired statuses.",
2694
+ options: passFailFieldStatuses.map((status) => {
2695
+ const { label } = passFailFieldStatusMapping[status];
2696
+ return {
2697
+ value: status,
2698
+ label
2699
+ };
2700
+ }),
2701
+ required: false
2702
+ }),
2703
+ showDirectly: false
2704
+ }
2705
+ ];
2706
+ }
2707
+ serialize() {
2708
+ return {
2709
+ ...super.serialize(),
2710
+ showNotesAndFilesOn: this.showNotesAndFilesOn
2711
+ };
2712
+ }
2713
+ getOptions() {
2714
+ return {
2715
+ ...super.getOptions(),
2716
+ showNotesAndFilesOn: this.showNotesAndFilesOn
2717
+ };
2718
+ }
2719
+ duplicate(identifier) {
2720
+ return new _PassFailField({
2721
+ ...this.getOptions(),
2722
+ identifier
2723
+ });
2724
+ }
2725
+ setOptions(options) {
2726
+ const { showNotesAndFilesOn, ...rest } = options;
2727
+ this.showNotesAndFilesOn = showNotesAndFilesOn ?? this.showNotesAndFilesOn;
2728
+ super.setOptions(rest);
2729
+ }
2730
+ getFieldValidators() {
2731
+ const validators = super.getFieldValidators();
2732
+ const showNotesAndFileOn = this.showNotesAndFilesOn;
2733
+ const blankValue = this.blankValue();
2734
+ if (showNotesAndFileOn.length > 0) {
2735
+ validators.push((value) => {
2736
+ if (!value.status || !showNotesAndFileOn.includes(value.status)) return;
2737
+ if (blankValue.notes === value.notes) {
2738
+ return "Notes is required.";
2739
+ }
2740
+ });
2741
+ validators.push((value) => {
2742
+ if (!value.status || !showNotesAndFileOn.includes(value.status)) return;
2743
+ if (areFileAndPromiseArraysEqual(blankValue.files, value.files)) {
2744
+ return "Files is required.";
2745
+ }
2746
+ });
2747
+ }
2748
+ return validators;
2749
+ }
2750
+ static deserialize(data) {
2751
+ return new _PassFailField({
2752
+ ...data,
2753
+ showNotesAndFilesOn: data.showNotesAndFilesOn ?? false
2754
+ });
2755
+ }
2756
+ serializeValue(value) {
2757
+ return serializePassFailFieldValue(value);
2758
+ }
2759
+ deserializeValue(value) {
2760
+ return deserializePassFailFieldValue(value);
2761
+ }
2762
+ render(props) {
2763
+ return /* @__PURE__ */ jsx(PassFailInput, { field: this, ...props });
2764
+ }
2765
+ isSerializedValueValid(value) {
2766
+ return isSerializedPassFailFieldValue(value);
2767
+ }
2768
+ isValueValid(value) {
2769
+ return isPassFailFieldValue(value);
2770
+ }
2771
+ areValuesEqual(value1, value2) {
2772
+ return arePassFieldValuesEqual(value1, value2);
2773
+ }
2774
+ blankValue() {
2775
+ return {
2776
+ status: null,
2777
+ notes: "",
2778
+ files: []
2779
+ };
2780
+ }
2781
+ cleanValue(value) {
2782
+ if (value.status && this.showNotesAndFilesOn.includes(value.status)) {
2783
+ return value;
2784
+ } else {
2785
+ return {
2786
+ status: value.status,
2787
+ notes: "",
2788
+ files: []
2789
+ };
2790
+ }
2791
+ }
2792
+ };
2793
+ __publicField(_PassFailField, "fieldTypeName", "Pass - Fail");
2794
+ __publicField(_PassFailField, "fieldTypeDescription", "Track pass, fail, or N/A outcome.");
2795
+ let PassFailField = _PassFailField;
1656
2796
  const RadioInput = memo((props) => {
1657
2797
  const [{ inputId, labelId, size, severity, showInputOnly, field, helpText, label, fieldProps }, { disabled }] = useFormikInput(props);
1658
2798
  const { name, onChange, onBlur, value } = fieldProps;
@@ -1678,68 +2818,207 @@ const RadioInput = memo((props) => {
1678
2818
  labelId,
1679
2819
  label: computedLabel,
1680
2820
  image: showInputOnly ? void 0 : field.image,
1681
- children: /* @__PURE__ */ jsxs(
1682
- RadioGroup.Root,
1683
- {
1684
- id: inputId,
1685
- name,
1686
- className: "flex flex-col gap-1",
1687
- accentColor: "base",
1688
- variant: "surface",
1689
- size: "sm",
1690
- value: value ?? "",
1691
- onValueChange: handleChange,
1692
- disabled,
1693
- children: [
1694
- field.options.map((option, index) => /* @__PURE__ */ jsxs("label", { className: "flex gap-2 items-center min-w-0", children: [
1695
- /* @__PURE__ */ jsx(RadioGroup.Item, { value: option.value, children: /* @__PURE__ */ jsx(RadioGroup.Indicator, { children: /* @__PURE__ */ jsx(LuIcon, { icon: "circle", className: "fill-current" }) }) }),
1696
- /* @__PURE__ */ jsx(Text, { size: "sm", accentColor: "base", className: "truncate", children: option.label })
1697
- ] }, `${inputId}-${option.value}-${index}`)),
1698
- !!value && /* @__PURE__ */ jsxs(
1699
- Button,
2821
+ children: /* @__PURE__ */ jsxs(
2822
+ RadioGroup.Root,
2823
+ {
2824
+ id: inputId,
2825
+ name,
2826
+ className: "flex flex-col gap-1",
2827
+ accentColor: "base",
2828
+ variant: "surface",
2829
+ size: "sm",
2830
+ value: value ?? "",
2831
+ onValueChange: handleChange,
2832
+ disabled,
2833
+ children: [
2834
+ field.options.map((option, index) => /* @__PURE__ */ jsxs("label", { className: "flex gap-2 items-center min-w-0", children: [
2835
+ /* @__PURE__ */ jsx(RadioGroup.Item, { value: option.value, children: /* @__PURE__ */ jsx(RadioGroup.Indicator, { children: /* @__PURE__ */ jsx(LuIcon, { icon: Circle, className: "fill-current" }) }) }),
2836
+ /* @__PURE__ */ jsx(Text, { size: "sm", accentColor: "base", className: "truncate", children: option.label })
2837
+ ] }, `${inputId}-${option.value}-${index}`)),
2838
+ !!value && /* @__PURE__ */ jsxs(
2839
+ Button,
2840
+ {
2841
+ onClick: handleClear,
2842
+ className: "w-max -mx-2",
2843
+ type: "button",
2844
+ variant: "ghost",
2845
+ accentColor: "base",
2846
+ size: "sm",
2847
+ children: [
2848
+ /* @__PURE__ */ jsx(LuIcon, { icon: X }),
2849
+ "Clear"
2850
+ ]
2851
+ }
2852
+ )
2853
+ ]
2854
+ }
2855
+ )
2856
+ }
2857
+ ) });
2858
+ });
2859
+ RadioInput.displayName = "SelectInput";
2860
+ const _RadioField = class _RadioField extends BaseOptionsField {
2861
+ constructor(options) {
2862
+ super(options);
2863
+ __publicField(this, "type", "radio");
2864
+ __publicField(this, "onlyValidateAfterTouched", false);
2865
+ }
2866
+ serialize() {
2867
+ return super.serialize();
2868
+ }
2869
+ getOptions() {
2870
+ return super.getOptions();
2871
+ }
2872
+ duplicate(identifier) {
2873
+ return new _RadioField({
2874
+ ...this.getOptions(),
2875
+ identifier
2876
+ });
2877
+ }
2878
+ setOptions(options) {
2879
+ super.setOptions(options);
2880
+ }
2881
+ static deserialize(data) {
2882
+ return new _RadioField(data);
2883
+ }
2884
+ serializeValue(value) {
2885
+ return value;
2886
+ }
2887
+ deserializeValue(value) {
2888
+ return value;
2889
+ }
2890
+ render(props) {
2891
+ return /* @__PURE__ */ jsx(RadioInput, { field: this, ...props });
2892
+ }
2893
+ isSerializedValueValid(value) {
2894
+ return typeof value === "string" || value === "null";
2895
+ }
2896
+ isValueValid(value) {
2897
+ return typeof value === "string" || value === "null";
2898
+ }
2899
+ blankValue() {
2900
+ return null;
2901
+ }
2902
+ areValuesEqual(value1, value2) {
2903
+ return value1 === value2;
2904
+ }
2905
+ };
2906
+ __publicField(_RadioField, "fieldTypeName", "Option list");
2907
+ __publicField(_RadioField, "fieldTypeDescription", "Allows the user to select a single option from a list of options.");
2908
+ let RadioField = _RadioField;
2909
+ const RatingInput = memo((props) => {
2910
+ const [{ inputId, labelId, size, severity, showInputOnly, field, helpText, label, fieldProps }, { disabled }] = useFormikInput(props);
2911
+ const { name, onChange, onBlur, value } = fieldProps;
2912
+ const computedHelpText = showInputOnly ? null : helpText;
2913
+ const computedLabel = showInputOnly ? "" : label;
2914
+ const handleChange = useCallback(
2915
+ (value2) => {
2916
+ onChange(value2);
2917
+ onBlur(value2);
2918
+ },
2919
+ [onBlur, onChange]
2920
+ );
2921
+ const handleClear = useCallback(() => {
2922
+ onChange(null);
2923
+ onBlur(null);
2924
+ }, [onBlur, onChange]);
2925
+ const ratingOptions = Array.from({ length: field.maxRating }, (_, i) => i + 1);
2926
+ return /* @__PURE__ */ jsx(InputWithLabelAndHelpText, { helpText: computedHelpText, severity, children: /* @__PURE__ */ jsx(
2927
+ InputWithLabel,
2928
+ {
2929
+ size,
2930
+ severity,
2931
+ inputId,
2932
+ labelId,
2933
+ label: computedLabel,
2934
+ image: showInputOnly ? void 0 : field.image,
2935
+ children: /* @__PURE__ */ jsxs("div", { className: "flex flex-row gap-1 items-center", children: [
2936
+ /* @__PURE__ */ jsx(
2937
+ Rating.Root,
2938
+ {
2939
+ id: inputId,
2940
+ name,
2941
+ className: "flex items-center gap-0.5",
2942
+ value,
2943
+ onValueChange: handleChange,
2944
+ disabled,
2945
+ children: ratingOptions.map((rating) => /* @__PURE__ */ jsx(
2946
+ Rating.Item,
1700
2947
  {
1701
- onClick: handleClear,
1702
- className: "w-max -mx-2",
1703
- type: "button",
1704
- variant: "ghost",
1705
- accentColor: "base",
1706
- size: "sm",
1707
- children: [
1708
- /* @__PURE__ */ jsx(LuIcon, { icon: "x" }),
1709
- "Clear"
1710
- ]
1711
- }
1712
- )
1713
- ]
1714
- }
1715
- )
2948
+ value: rating,
2949
+ className: "group size-7 flex cursor-pointer disabled:opacity-50 disabled:pointer-events-none items-center justify-center text-yellow-500 transition-colors",
2950
+ children: /* @__PURE__ */ jsx(LuIcon, { icon: Star, className: "group-data-[active=true]:fill-current size-full" })
2951
+ },
2952
+ `${inputId}-${rating}`
2953
+ ))
2954
+ }
2955
+ ),
2956
+ !disabled && value !== null && /* @__PURE__ */ jsx(IconButton, { onClick: handleClear, type: "button", variant: "ghost", accentColor: "base", size: "sm", children: /* @__PURE__ */ jsx(LuIcon, { icon: X }) })
2957
+ ] })
1716
2958
  }
1717
2959
  ) });
1718
2960
  });
1719
- RadioInput.displayName = "SelectInput";
1720
- const _RadioField = class _RadioField extends BaseOptionsField {
2961
+ RatingInput.displayName = "RatingInput";
2962
+ const _RatingField = class _RatingField extends BaseField {
1721
2963
  constructor(options) {
1722
- super(options);
1723
- __publicField(this, "type", "radio");
1724
- __publicField(this, "onlyValidateAfterTouched", false);
2964
+ const { maxRating, ...rest } = options;
2965
+ super(rest);
2966
+ __publicField(this, "type", "rating");
2967
+ __publicField(this, "maxRating");
2968
+ this.maxRating = maxRating;
2969
+ }
2970
+ static getFieldCreationSchema(parentPath = "") {
2971
+ const path = parentPath && `${parentPath}.`;
2972
+ return [
2973
+ {
2974
+ field: new NumberField({
2975
+ label: "Max Rating",
2976
+ description: "Maximum rating value",
2977
+ integers: true,
2978
+ required: false,
2979
+ minimum: 1,
2980
+ maximum: 10,
2981
+ identifier: `${path}maxRating`
2982
+ }),
2983
+ showDirectly: false
2984
+ }
2985
+ ];
2986
+ }
2987
+ getFieldValidators() {
2988
+ const validators = super.getFieldValidators();
2989
+ const max = this.maxRating;
2990
+ validators.push((value) => {
2991
+ if (typeof value === "number" && (value < 1 || value > max)) {
2992
+ return `Rating must be between 1 and ${max}.`;
2993
+ }
2994
+ });
2995
+ return validators;
1725
2996
  }
1726
2997
  serialize() {
1727
- return super.serialize();
2998
+ return {
2999
+ ...super.serialize(),
3000
+ maxRating: this.maxRating
3001
+ };
1728
3002
  }
1729
3003
  getOptions() {
1730
- return super.getOptions();
3004
+ return {
3005
+ ...super.getOptions(),
3006
+ maxRating: this.maxRating
3007
+ };
1731
3008
  }
1732
3009
  duplicate(identifier) {
1733
- return new _RadioField({
3010
+ return new _RatingField({
1734
3011
  ...this.getOptions(),
1735
3012
  identifier
1736
3013
  });
1737
3014
  }
1738
3015
  setOptions(options) {
1739
- super.setOptions(options);
3016
+ const { maxRating, ...rest } = options;
3017
+ this.maxRating = maxRating ?? this.maxRating;
3018
+ super.setOptions(rest);
1740
3019
  }
1741
3020
  static deserialize(data) {
1742
- return new _RadioField(data);
3021
+ return new _RatingField(data);
1743
3022
  }
1744
3023
  serializeValue(value) {
1745
3024
  return value;
@@ -1748,24 +3027,24 @@ const _RadioField = class _RadioField extends BaseOptionsField {
1748
3027
  return value;
1749
3028
  }
1750
3029
  render(props) {
1751
- return /* @__PURE__ */ jsx(RadioInput, { field: this, ...props });
3030
+ return /* @__PURE__ */ jsx(RatingInput, { field: this, ...props });
1752
3031
  }
1753
3032
  isSerializedValueValid(value) {
1754
- return typeof value === "string" || value === "null";
3033
+ return typeof value === "number" || value === null;
1755
3034
  }
1756
3035
  isValueValid(value) {
1757
- return typeof value === "string" || value === "null";
1758
- }
1759
- blankValue() {
1760
- return null;
3036
+ return typeof value === "number" || value === null;
1761
3037
  }
1762
3038
  areValuesEqual(value1, value2) {
1763
3039
  return value1 === value2;
1764
3040
  }
3041
+ blankValue() {
3042
+ return null;
3043
+ }
1765
3044
  };
1766
- __publicField(_RadioField, "fieldTypeName", "Option list");
1767
- __publicField(_RadioField, "fieldTypeDescription", "Allows the user to select a single option from a list of options.");
1768
- let RadioField = _RadioField;
3045
+ __publicField(_RatingField, "fieldTypeName", "Rating");
3046
+ __publicField(_RatingField, "fieldTypeDescription", "Allows users to select a rating value.");
3047
+ let RatingField = _RatingField;
1769
3048
  const ScannerContext = createContext(() => {
1770
3049
  throw new Error("No ScannerProvider found");
1771
3050
  });
@@ -29904,7 +31183,7 @@ const ScannerInternal = memo((props) => {
29904
31183
  hints: SCANNER_HINTS
29905
31184
  });
29906
31185
  return /* @__PURE__ */ jsxs("div", { className: "flex size-full flex-col justify-center overflow-hidden bg-(--color-background)", children: [
29907
- /* @__PURE__ */ jsx("div", { className: "flex w-full justify-end p-4", children: /* @__PURE__ */ jsx(Overlay.Close, { asChild: true, children: /* @__PURE__ */ jsx(IconButton, { "aria-label": "close", variant: "soft", accentColor: "base", children: /* @__PURE__ */ jsx(LuIcon, { icon: "x" }) }) }) }),
31186
+ /* @__PURE__ */ jsx("div", { className: "flex w-full justify-end p-4", children: /* @__PURE__ */ jsx(Overlay.Close, { asChild: true, children: /* @__PURE__ */ jsx(IconButton, { "aria-label": "close", variant: "soft", accentColor: "base", children: /* @__PURE__ */ jsx(LuIcon, { icon: X }) }) }) }),
29908
31187
  /* @__PURE__ */ jsx("div", { className: "grow w-full max-h-full overflow-hidden p-4", children: /* @__PURE__ */ jsx("video", { className: "size-full", ref }) })
29909
31188
  ] });
29910
31189
  });
@@ -30011,7 +31290,7 @@ const ScanInput = memo((props) => {
30011
31290
  accentColor: "base",
30012
31291
  disabled,
30013
31292
  children: [
30014
- /* @__PURE__ */ jsx(LuIcon, { icon: "maximize" }),
31293
+ /* @__PURE__ */ jsx(LuIcon, { icon: Maximize }),
30015
31294
  "Scan"
30016
31295
  ]
30017
31296
  }
@@ -30149,7 +31428,6 @@ const _StringField = class _StringField extends BaseStringField {
30149
31428
  super.setOptions(options);
30150
31429
  }
30151
31430
  static deserialize(data) {
30152
- if (data.type !== "string") throw new Error("Type mismatch.");
30153
31431
  const { maximum_length, minimum_length, ...rest } = data;
30154
31432
  return new _StringField({
30155
31433
  ...rest,
@@ -30259,107 +31537,6 @@ const _TextField = class _TextField extends BaseStringField {
30259
31537
  __publicField(_TextField, "fieldTypeName", "Paragraph");
30260
31538
  __publicField(_TextField, "fieldTypeDescription", `Paragraph fields can hold up to ${LONG_TEXT_FIELD_MAX_LENGTH} characters and can have multiple lines.`);
30261
31539
  let TextField = _TextField;
30262
- const ImageCard = memo(
30263
- forwardRef((props, forwardedRef) => {
30264
- const { file, alt, error, rightSlot, className, ...rest } = props;
30265
- return /* @__PURE__ */ jsxs(
30266
- Card,
30267
- {
30268
- className: cx(className, "relative flex h-[200px] w-full flex-col gap-2 overflow-hidden items-center"),
30269
- ref: forwardedRef,
30270
- ...rest,
30271
- children: [
30272
- !file && !error && /* @__PURE__ */ jsx("div", { className: "absolute inset-0 grow flex items-center justify-center", children: /* @__PURE__ */ jsx(Spinner, {}) }),
30273
- !!file && !error && /* @__PURE__ */ jsx(Card, { className: "flex max-w-full grow items-center !p-0 justify-center overflow-hidden bg-clip-padding", children: /* @__PURE__ */ jsx(
30274
- "img",
30275
- {
30276
- className: "max-w-full object-cover",
30277
- src: URL.createObjectURL(file),
30278
- alt: alt ?? file.name
30279
- }
30280
- ) }),
30281
- (!!file || !!error) && /* @__PURE__ */ jsxs(
30282
- "div",
30283
- {
30284
- className: cx("flex w-full items-center gap-2 self-end", {
30285
- "bg-transparent": !file
30286
- }),
30287
- children: [
30288
- error ? /* @__PURE__ */ jsx(LuIcon, { icon: "file-warning" }) : file && /* @__PURE__ */ jsx(LuIcon, { icon: "file" }),
30289
- /* @__PURE__ */ jsx(Text, { className: "truncate", size: "sm", children: error ?? (file == null ? void 0 : file.name) }),
30290
- rightSlot
30291
- ]
30292
- }
30293
- )
30294
- ]
30295
- }
30296
- );
30297
- })
30298
- );
30299
- class UUIDPromise extends Promise {
30300
- constructor(executor, uuid) {
30301
- super(executor);
30302
- __publicField(this, "_uuid");
30303
- this._uuid = uuid;
30304
- }
30305
- get uuid() {
30306
- return this._uuid;
30307
- }
30308
- set uuid(uuid) {
30309
- this._uuid = uuid;
30310
- }
30311
- static from(promise, uuid) {
30312
- return new UUIDPromise((resolve, reject) => {
30313
- Promise.resolve(promise).then(resolve).catch(reject);
30314
- }, uuid);
30315
- }
30316
- then(onFulfilled, onRejected) {
30317
- const promise = super.then(onFulfilled, onRejected);
30318
- promise.uuid = this.uuid;
30319
- return promise;
30320
- }
30321
- catch(onRejected) {
30322
- const promise = super.catch(onRejected);
30323
- promise.uuid = this.uuid;
30324
- return promise;
30325
- }
30326
- finally(onFinally) {
30327
- const promise = super.finally(onFinally);
30328
- promise.uuid = this.uuid;
30329
- return promise;
30330
- }
30331
- }
30332
- const convertBytesToLargestUnit = (bytes) => {
30333
- const units = ["byte", "kilobyte", "megabyte"];
30334
- let sizeInUnit = bytes;
30335
- let unitIndex = 0;
30336
- while (sizeInUnit > 1e3 && unitIndex < units.length - 1) {
30337
- sizeInUnit /= 1e3;
30338
- unitIndex++;
30339
- }
30340
- const formatter = new Intl.NumberFormat([], {
30341
- // 0 for bytes and kilobytes, 1 for megabytes
30342
- maximumFractionDigits: Math.max(0, unitIndex - 1),
30343
- style: "unit",
30344
- unit: units[unitIndex]
30345
- });
30346
- return formatter.format(sizeInUnit);
30347
- };
30348
- function areFilesEqual(file1, file2) {
30349
- return file1.name === file2.name && file1.size === file2.size && file1.type === file2.type;
30350
- }
30351
- function separateFilesFromPromises(filesOrPromises) {
30352
- const files = [];
30353
- const promises = [];
30354
- for (const fileOrPromise of filesOrPromises) {
30355
- if (fileOrPromise instanceof UUIDPromise) {
30356
- promises.push(fileOrPromise);
30357
- } else {
30358
- files.push(fileOrPromise);
30359
- }
30360
- }
30361
- return [files, promises];
30362
- }
30363
31540
  const UploadInput = memo((props) => {
30364
31541
  var _a2;
30365
31542
  const [{ inputId, labelId, label, size, severity, helpText, showInputOnly, field, fieldProps }, { disabled }] = useFormikInput(props);
@@ -30384,7 +31561,7 @@ const UploadInput = memo((props) => {
30384
31561
  onBlur([]);
30385
31562
  return;
30386
31563
  }
30387
- const fileArray = Array.from(files);
31564
+ const fileArray = Array.from(files).map((file) => UUIDFile.from(v4(), file));
30388
31565
  const newValue = [...value, ...fileArray];
30389
31566
  onChange(newValue);
30390
31567
  onBlur(newValue);
@@ -30439,7 +31616,7 @@ const UploadInput = memo((props) => {
30439
31616
  type: "button",
30440
31617
  disabled,
30441
31618
  children: [
30442
- /* @__PURE__ */ jsx(LuIcon, { icon: "upload" }),
31619
+ /* @__PURE__ */ jsx(LuIcon, { icon: Upload }),
30443
31620
  buttonText
30444
31621
  ]
30445
31622
  }
@@ -30464,7 +31641,6 @@ const UploadInput = memo((props) => {
30464
31641
  Array.isArray(value) && value.length > 0 && /* @__PURE__ */ jsx("div", { className: "flex h-max flex-col gap-2", children: value.map((file, index) => /* @__PURE__ */ jsx(
30465
31642
  DisplayFile,
30466
31643
  {
30467
- field,
30468
31644
  file,
30469
31645
  onRemove: () => {
30470
31646
  handleRemove(index);
@@ -30476,92 +31652,6 @@ const UploadInput = memo((props) => {
30476
31652
  ] });
30477
31653
  });
30478
31654
  UploadInput.displayName = "UploadInput";
30479
- const DisplayFile = memo((props) => {
30480
- const { file, field, onRemove, disabled } = props;
30481
- const [resolvedFile, setResolvedFile] = useState(null);
30482
- const openImageViewer = useImageViewer();
30483
- const error = useMemo(() => resolvedFile && field.getError([resolvedFile]), [field, resolvedFile]);
30484
- const { url, name } = useMemo(() => {
30485
- let url2 = null;
30486
- let name2;
30487
- let size;
30488
- if (resolvedFile == null ? void 0 : resolvedFile.type.startsWith("image/")) {
30489
- url2 = URL.createObjectURL(resolvedFile);
30490
- }
30491
- if (resolvedFile) {
30492
- name2 = resolvedFile.name;
30493
- size = convertBytesToLargestUnit(resolvedFile.size);
30494
- } else {
30495
- name2 = "Downloading...";
30496
- size = "...";
30497
- }
30498
- return { url: url2, name: name2, size };
30499
- }, [resolvedFile]);
30500
- useEffect(() => {
30501
- if (file instanceof UUIDPromise) {
30502
- file.then((file2) => {
30503
- setResolvedFile(file2);
30504
- }).catch(console.error);
30505
- } else {
30506
- setResolvedFile(file);
30507
- }
30508
- }, [file]);
30509
- const handleDownload = useCallback(
30510
- (event) => {
30511
- event.stopPropagation();
30512
- if (!resolvedFile) {
30513
- throw new Error("Cannot download a file that is not resolved.");
30514
- }
30515
- const blob = new Blob([resolvedFile]);
30516
- saveAs(blob, name);
30517
- },
30518
- [name, resolvedFile]
30519
- );
30520
- const handleDelete = useCallback(
30521
- (e) => {
30522
- e.stopPropagation();
30523
- onRemove();
30524
- },
30525
- [onRemove]
30526
- );
30527
- const handleImageCardClick = useCallback(() => {
30528
- if (!resolvedFile) return;
30529
- openImageViewer((closeFileViewer) => ({
30530
- file: resolvedFile,
30531
- onDelete: !disabled ? () => {
30532
- onRemove();
30533
- closeFileViewer();
30534
- } : void 0
30535
- }));
30536
- }, [disabled, onRemove, openImageViewer, resolvedFile]);
30537
- const rightSlotContent = useMemo(
30538
- () => /* @__PURE__ */ jsxs(ButtonGroup, { className: "flex grow justify-end", variant: "ghost", accentColor: "base", size: "sm", children: [
30539
- /* @__PURE__ */ jsx(
30540
- IconButton,
30541
- {
30542
- "aria-label": `Download ${name}`,
30543
- type: "button",
30544
- onClick: handleDownload,
30545
- disabled: !resolvedFile,
30546
- children: /* @__PURE__ */ jsx(LuIcon, { icon: "download" })
30547
- }
30548
- ),
30549
- !disabled && /* @__PURE__ */ jsx(IconButton, { type: "button", "aria-label": `Remove ${name}`, disabled, onClick: handleDelete, children: /* @__PURE__ */ jsx(LuIcon, { icon: "trash" }) })
30550
- ] }),
30551
- [disabled, handleDelete, handleDownload, name, resolvedFile]
30552
- );
30553
- return url ? /* @__PURE__ */ jsx(
30554
- ImageCard,
30555
- {
30556
- className: "cursor-pointer",
30557
- onClick: handleImageCardClick,
30558
- file: resolvedFile,
30559
- error: error ?? void 0,
30560
- rightSlot: rightSlotContent
30561
- }
30562
- ) : /* @__PURE__ */ jsx(FileCard, { file: resolvedFile, error: error ?? void 0, rightSlot: rightSlotContent });
30563
- });
30564
- DisplayFile.displayName = "DisplayFile";
30565
31655
  const _UploadField = class _UploadField extends BaseField {
30566
31656
  constructor(options) {
30567
31657
  const { extensions, maximum_files, maximum_size, ...base } = options;
@@ -30641,7 +31731,7 @@ const _UploadField = class _UploadField extends BaseField {
30641
31731
  const maxFileSizeInB = maxFileSizeInMB * 1e3 * 1e3;
30642
31732
  const maxFiles = this.maxFiles || 1;
30643
31733
  validators.push((value) => {
30644
- if (value && value.some((file) => file instanceof File && file.size > maxFileSizeInB)) {
31734
+ if (value && value.some((file) => file instanceof UUIDFile && file.size > maxFileSizeInB)) {
30645
31735
  return `Files must be at most ${maxFileSizeInMB}MB.`;
30646
31736
  }
30647
31737
  });
@@ -30698,16 +31788,10 @@ const _UploadField = class _UploadField extends BaseField {
30698
31788
  }
30699
31789
  isValueValid(value) {
30700
31790
  if (!Array.isArray(value)) return false;
30701
- return value.every((item) => item instanceof UUIDPromise || item instanceof File);
31791
+ return value.every((item) => item instanceof UUIDPromise || item instanceof UUIDFile);
30702
31792
  }
30703
31793
  areValuesEqual(value1, value2) {
30704
- const [files1, promises1] = separateFilesFromPromises(value1);
30705
- const [files2, promises2] = separateFilesFromPromises(value2);
30706
- if (!files1.every((file1) => files2.some((file2) => areFilesEqual(file1, file2)))) return false;
30707
- if (!files2.every((file2) => files1.some((file1) => areFilesEqual(file1, file2)))) return false;
30708
- if (!promises1.every((promise1) => promises2.some((promise2) => promise1.uuid === promise2.uuid))) return false;
30709
- if (!promises2.every((promise2) => promises1.some((promise1) => promise1.uuid === promise2.uuid))) return false;
30710
- return true;
31794
+ return areFileAndPromiseArraysEqual(value1, value2);
30711
31795
  }
30712
31796
  blankValue() {
30713
31797
  return [];
@@ -30729,23 +31813,27 @@ const FieldTypeToClsMapping = {
30729
31813
  "multi-select": MultiSelectField,
30730
31814
  radio: RadioField,
30731
31815
  "checkbox-list": CheckboxListField,
30732
- otp: OTPField
31816
+ "pass-fail": PassFailField,
31817
+ otp: OTPField,
31818
+ rating: RatingField
30733
31819
  };
30734
31820
  const fieldIcons = {
30735
- boolean: "square-check",
30736
- date: "calendar",
30737
- "multi-string": "list",
30738
- number: "hash",
30739
- qr: "scan",
30740
- "multi-select": "list-checks",
30741
- select: "list-todo",
30742
- string: "text-cursor-input",
30743
- text: "align-justify",
30744
- upload: "upload",
30745
- section: "layout-panel-top",
30746
- radio: "circle-dot",
30747
- "checkbox-list": "copy-check",
30748
- otp: "rectangle-ellipsis"
31821
+ boolean: SquareCheck,
31822
+ date: Calendar,
31823
+ "multi-string": List,
31824
+ number: Hash,
31825
+ qr: Scan,
31826
+ "multi-select": ListChecks,
31827
+ select: ListTodo,
31828
+ string: TextCursorInput,
31829
+ text: AlignJustify,
31830
+ upload: Upload,
31831
+ section: LayoutPanelTop,
31832
+ radio: CircleDot,
31833
+ "checkbox-list": CopyCheck,
31834
+ "pass-fail": ClipboardList,
31835
+ otp: RectangleEllipsis,
31836
+ rating: Star
30749
31837
  };
30750
31838
  const maxFileSizeMB = 50;
30751
31839
  const maxFileSizeKB = maxFileSizeMB * 1e3;
@@ -30952,6 +32040,42 @@ const NumberRangeNotInConditionModifier = ConditionModifier.create({
30952
32040
  serialize: (filterValue) => filterValue,
30953
32041
  deserialize: (filterValue) => filterValue
30954
32042
  });
32043
+ const PassFailEqualsConditionModifier = ConditionModifier.create({
32044
+ id: "pass-fail-equals",
32045
+ modifierFn: (value, filterValue) => {
32046
+ return value === filterValue;
32047
+ },
32048
+ label: "is",
32049
+ serialize: (filterValue) => filterValue,
32050
+ deserialize: (filterValue) => filterValue
32051
+ });
32052
+ const PassFailNotEqualsConditionModifier = ConditionModifier.create({
32053
+ id: "pass-fail-not-equals",
32054
+ modifierFn: (value, filterValue) => {
32055
+ return value !== filterValue;
32056
+ },
32057
+ label: "is not",
32058
+ serialize: (filterValue) => filterValue,
32059
+ deserialize: (filterValue) => filterValue
32060
+ });
32061
+ const PassFailArrayIncludesConditionModifier = ConditionModifier.create({
32062
+ id: "pass-fail-array-includes",
32063
+ modifierFn: (value, filterValue) => {
32064
+ return filterValue.includes(value);
32065
+ },
32066
+ label: "is any of",
32067
+ serialize: (filterValue) => filterValue,
32068
+ deserialize: (filterValue) => filterValue
32069
+ });
32070
+ const PassFailArrayExcludesConditionModifier = ConditionModifier.create({
32071
+ id: "pass-fail-array-excludes",
32072
+ modifierFn: (value, filterValue) => {
32073
+ return !filterValue.includes(value);
32074
+ },
32075
+ label: "is none of",
32076
+ serialize: (filterValue) => filterValue,
32077
+ deserialize: (filterValue) => filterValue
32078
+ });
30955
32079
  const StringEqualsConditionModifier = ConditionModifier.create({
30956
32080
  id: "nullable-string-equals",
30957
32081
  modifierFn: (value, filterValue) => {
@@ -31091,9 +32215,11 @@ class BaseCondition extends Observable {
31091
32215
  __publicField(this, "apply", (value) => {
31092
32216
  const modifier = this.modifiers[this.conditionModifier];
31093
32217
  const conditionValue = this.getConditionValue();
31094
- if (conditionValue === void 0 || !modifier.isConditionValueValid(conditionValue)) return true;
31095
- if (!modifier.isValueValid(value)) return false;
31096
- return modifier.modifier.modifierFn(value, conditionValue);
32218
+ if (conditionValue == void 0) return true;
32219
+ if (!modifier.isConditionValueValid(conditionValue)) return true;
32220
+ const transformedValue = this.transformValue(value);
32221
+ if (!modifier.isValueValid(transformedValue)) return false;
32222
+ return modifier.modifier.modifierFn(transformedValue, conditionValue);
31097
32223
  });
31098
32224
  this.id = id;
31099
32225
  this.field = field;
@@ -31109,6 +32235,9 @@ class BaseCondition extends Observable {
31109
32235
  conditionModifier: this.conditionModifier
31110
32236
  };
31111
32237
  }
32238
+ transformValue(value) {
32239
+ return value;
32240
+ }
31112
32241
  }
31113
32242
  const formId = "form-builder";
31114
32243
  const UNLABELLED_FIELD_LABEL = "Unlabelled";
@@ -31121,12 +32250,12 @@ const SelectItemTemplate = genericMemo(function(props) {
31121
32250
  if (typeof children === "function") {
31122
32251
  return /* @__PURE__ */ jsxs(Fragment$1, { children: [
31123
32252
  children(meta),
31124
- /* @__PURE__ */ jsx(Menu.SelectedIndicator, { className: "ml-[auto]", children: /* @__PURE__ */ jsx(LuIcon, { icon: "check" }) })
32253
+ /* @__PURE__ */ jsx(Menu.SelectedIndicator, { className: "ml-[auto]", children: /* @__PURE__ */ jsx(LuIcon, { icon: Check }) })
31125
32254
  ] });
31126
32255
  } else {
31127
32256
  return /* @__PURE__ */ jsxs(Fragment$1, { children: [
31128
32257
  children,
31129
- /* @__PURE__ */ jsx(Menu.SelectedIndicator, { className: "ml-[auto]", children: /* @__PURE__ */ jsx(LuIcon, { icon: "check" }) })
32258
+ /* @__PURE__ */ jsx(Menu.SelectedIndicator, { className: "ml-[auto]", children: /* @__PURE__ */ jsx(LuIcon, { icon: Check }) })
31130
32259
  ] });
31131
32260
  }
31132
32261
  },
@@ -31141,12 +32270,12 @@ const MultiSelectItemTemplate = genericMemo(function(props) {
31141
32270
  if (typeof children === "function") {
31142
32271
  return /* @__PURE__ */ jsxs(Fragment$1, { children: [
31143
32272
  children(meta),
31144
- /* @__PURE__ */ jsx(Menu.SelectedIndicator, { className: "ml-auto", children: /* @__PURE__ */ jsx(LuIcon, { icon: "check" }) })
32273
+ /* @__PURE__ */ jsx(Menu.SelectedIndicator, { className: "ml-auto", children: /* @__PURE__ */ jsx(LuIcon, { icon: Check }) })
31145
32274
  ] });
31146
32275
  } else {
31147
32276
  return /* @__PURE__ */ jsxs(Fragment$1, { children: [
31148
32277
  children,
31149
- /* @__PURE__ */ jsx(Menu.SelectedIndicator, { className: "ml-auto", children: /* @__PURE__ */ jsx(LuIcon, { icon: "check" }) })
32278
+ /* @__PURE__ */ jsx(Menu.SelectedIndicator, { className: "ml-auto", children: /* @__PURE__ */ jsx(LuIcon, { icon: Check }) })
31150
32279
  ] });
31151
32280
  }
31152
32281
  },
@@ -31161,12 +32290,12 @@ const SelectAllItemTemplate = memo((props) => {
31161
32290
  if (typeof children === "function") {
31162
32291
  return /* @__PURE__ */ jsxs(Fragment$1, { children: [
31163
32292
  children(meta),
31164
- /* @__PURE__ */ jsx(Menu.CheckboxItemIndicator, { className: "ml-[auto]", children: (indeterminate) => indeterminate ? /* @__PURE__ */ jsx(LuIcon, { icon: "minus" }) : /* @__PURE__ */ jsx(LuIcon, { icon: "check" }) })
32293
+ /* @__PURE__ */ jsx(Menu.CheckboxItemIndicator, { className: "ml-[auto]", children: (indeterminate) => indeterminate ? /* @__PURE__ */ jsx(LuIcon, { icon: Minus }) : /* @__PURE__ */ jsx(LuIcon, { icon: Check }) })
31165
32294
  ] });
31166
32295
  } else {
31167
32296
  return /* @__PURE__ */ jsxs(Fragment$1, { children: [
31168
32297
  children,
31169
- /* @__PURE__ */ jsx(Menu.CheckboxItemIndicator, { className: "ml-[auto]", children: (indeterminate) => indeterminate ? /* @__PURE__ */ jsx(LuIcon, { icon: "minus" }) : /* @__PURE__ */ jsx(LuIcon, { icon: "check" }) })
32298
+ /* @__PURE__ */ jsx(Menu.CheckboxItemIndicator, { className: "ml-[auto]", children: (indeterminate) => indeterminate ? /* @__PURE__ */ jsx(LuIcon, { icon: Minus }) : /* @__PURE__ */ jsx(LuIcon, { icon: Check }) })
31170
32299
  ] });
31171
32300
  }
31172
32301
  },
@@ -31260,7 +32389,7 @@ const MultiStringPopover = memo((props) => {
31260
32389
  variant: "soft",
31261
32390
  type: "button",
31262
32391
  onClick: handleAddValueClick,
31263
- children: /* @__PURE__ */ jsx(LuIcon, { icon: "plus" })
32392
+ children: /* @__PURE__ */ jsx(LuIcon, { icon: Plus })
31264
32393
  }
31265
32394
  )
31266
32395
  ] }),
@@ -31283,7 +32412,7 @@ const MultiStringPopover = memo((props) => {
31283
32412
  onClick: () => {
31284
32413
  handleRemoveValueClick(index);
31285
32414
  },
31286
- children: /* @__PURE__ */ jsx(LuIcon, { icon: "x" })
32415
+ children: /* @__PURE__ */ jsx(LuIcon, { icon: X })
31287
32416
  }
31288
32417
  )
31289
32418
  ]
@@ -31343,7 +32472,7 @@ const RemoveConditionButton = (props) => {
31343
32472
  const handleRemoveFilter = useCallback(() => {
31344
32473
  onClick(condition);
31345
32474
  }, [condition, onClick]);
31346
- return /* @__PURE__ */ jsx(IconButton, { onClick: handleRemoveFilter, ...rest, children: /* @__PURE__ */ jsx(LuIcon, { icon: "x" }) });
32475
+ return /* @__PURE__ */ jsx(IconButton, { onClick: handleRemoveFilter, ...rest, children: /* @__PURE__ */ jsx(LuIcon, { icon: X }) });
31347
32476
  };
31348
32477
  RemoveConditionButton.displayName = "RemoveConditionButton";
31349
32478
  const SelectFieldOptionMultiSelectGroup = memo((props) => {
@@ -31458,7 +32587,7 @@ const BooleanFieldConditionCell = (props) => {
31458
32587
  /* @__PURE__ */ jsx(RemoveConditionButton, { condition, onClick: onRemove })
31459
32588
  ] });
31460
32589
  };
31461
- const modifiers$c = {
32590
+ const modifiers$e = {
31462
32591
  equals: createConditionModifierConfig({
31463
32592
  modifier: BooleanEqualsConditionModifier,
31464
32593
  isValueValid: (_value) => true,
@@ -31475,13 +32604,11 @@ const modifiers$c = {
31475
32604
  class BooleanFieldCondition extends BaseCondition {
31476
32605
  constructor(options) {
31477
32606
  super(options);
31478
- __publicField(this, "defaultConditionModifier", "equals");
31479
- __publicField(this, "defaultConditionValue");
31480
- __publicField(this, "modifiers", modifiers$c);
32607
+ __publicField(this, "modifiers", modifiers$e);
31481
32608
  }
31482
32609
  static deserialize(serializedCondition, field) {
31483
32610
  const { conditionValue, conditionModifier, ...rest } = serializedCondition;
31484
- const modifierConfig = modifiers$c[conditionModifier];
32611
+ const modifierConfig = modifiers$e[conditionModifier];
31485
32612
  let deserializedValue = void 0;
31486
32613
  if (conditionValue !== void 0) {
31487
32614
  deserializedValue = modifierConfig.modifier.deserialize(conditionValue);
@@ -31537,7 +32664,7 @@ const CheckboxListFieldConditionCell = (props) => {
31537
32664
  /* @__PURE__ */ jsx(RemoveConditionButton, { condition, onClick: onRemove })
31538
32665
  ] });
31539
32666
  };
31540
- const modifiers$b = {
32667
+ const modifiers$d = {
31541
32668
  equals: createConditionModifierConfig({
31542
32669
  modifier: StringArrayEqualsConditionModifier,
31543
32670
  isValueValid: (_value) => true,
@@ -31572,13 +32699,11 @@ const modifiers$b = {
31572
32699
  class CheckboxListFieldCondition extends BaseCondition {
31573
32700
  constructor(options) {
31574
32701
  super(options);
31575
- __publicField(this, "defaultConditionModifier", "equals");
31576
- __publicField(this, "defaultConditionValue");
31577
- __publicField(this, "modifiers", modifiers$b);
32702
+ __publicField(this, "modifiers", modifiers$d);
31578
32703
  }
31579
32704
  static deserialize(serializedCondition, field) {
31580
32705
  const { conditionValue, conditionModifier, ...rest } = serializedCondition;
31581
- const modifierConfig = modifiers$b[conditionModifier];
32706
+ const modifierConfig = modifiers$d[conditionModifier];
31582
32707
  const deserializedValue = conditionValue !== void 0 && modifierConfig.isSerializedValueValid(conditionValue) ? modifierConfig.modifier.deserialize(conditionValue) : void 0;
31583
32708
  return new CheckboxListFieldCondition({ field, conditionModifier, conditionValue: deserializedValue, ...rest });
31584
32709
  }
@@ -31653,7 +32778,7 @@ const DateFieldConditionCell = (props) => {
31653
32778
  /* @__PURE__ */ jsx(RemoveConditionButton, { condition, onClick: onRemove })
31654
32779
  ] });
31655
32780
  };
31656
- const modifiers$a = {
32781
+ const modifiers$c = {
31657
32782
  equals: createConditionModifierConfig({
31658
32783
  modifier: DateEqualsConditionModifier,
31659
32784
  isValueValid: (value) => value instanceof Date,
@@ -31694,13 +32819,11 @@ const modifiers$a = {
31694
32819
  class DateFieldCondition extends BaseCondition {
31695
32820
  constructor(options) {
31696
32821
  super(options);
31697
- __publicField(this, "defaultConditionModifier", "equals");
31698
- __publicField(this, "defaultConditionValue");
31699
- __publicField(this, "modifiers", modifiers$a);
32822
+ __publicField(this, "modifiers", modifiers$c);
31700
32823
  }
31701
32824
  static deserialize(serializedCondition, field) {
31702
32825
  const { conditionValue, conditionModifier, ...rest } = serializedCondition;
31703
- const modifierConfig = modifiers$a[conditionModifier];
32826
+ const modifierConfig = modifiers$c[conditionModifier];
31704
32827
  const deserializedValue = conditionValue !== void 0 && modifierConfig.isSerializedValueValid(conditionValue) ? (
31705
32828
  // @ts-expect-error calling isSerializedValueValid means conditionValue is of appropriate type
31706
32829
  modifierConfig.modifier.deserialize(conditionValue)
@@ -31756,7 +32879,7 @@ const MultiSelectFieldConditionCell = (props) => {
31756
32879
  /* @__PURE__ */ jsx(RemoveConditionButton, { condition, onClick: onRemove })
31757
32880
  ] });
31758
32881
  };
31759
- const modifiers$9 = {
32882
+ const modifiers$b = {
31760
32883
  equals: createConditionModifierConfig({
31761
32884
  modifier: StringArrayEqualsConditionModifier,
31762
32885
  isValueValid: (_value) => true,
@@ -31791,13 +32914,11 @@ const modifiers$9 = {
31791
32914
  class MultiSelectFieldCondition extends BaseCondition {
31792
32915
  constructor(options) {
31793
32916
  super(options);
31794
- __publicField(this, "defaultConditionValue");
31795
- __publicField(this, "defaultConditionModifier", "equals");
31796
- __publicField(this, "modifiers", modifiers$9);
32917
+ __publicField(this, "modifiers", modifiers$b);
31797
32918
  }
31798
32919
  static deserialize(serializedCondition, field) {
31799
32920
  const { conditionValue, conditionModifier, ...rest } = serializedCondition;
31800
- const modifierConfig = modifiers$9[conditionModifier];
32921
+ const modifierConfig = modifiers$b[conditionModifier];
31801
32922
  const deserializedValue = conditionValue !== void 0 && modifierConfig.isSerializedValueValid(conditionValue) ? modifierConfig.modifier.deserialize(conditionValue) : void 0;
31802
32923
  return new MultiSelectFieldCondition({ field, conditionModifier, conditionValue: deserializedValue, ...rest });
31803
32924
  }
@@ -31841,7 +32962,7 @@ const MultiStringFieldConditionCell = (props) => {
31841
32962
  /* @__PURE__ */ jsx(RemoveConditionButton, { condition, onClick: onRemove })
31842
32963
  ] });
31843
32964
  };
31844
- const modifiers$8 = {
32965
+ const modifiers$a = {
31845
32966
  equals: createConditionModifierConfig({
31846
32967
  modifier: StringArrayEqualsConditionModifier,
31847
32968
  isValueValid: (_value) => true,
@@ -31876,13 +32997,11 @@ const modifiers$8 = {
31876
32997
  class MultiStringFieldCondition extends BaseCondition {
31877
32998
  constructor(options) {
31878
32999
  super(options);
31879
- __publicField(this, "defaultConditionValue");
31880
- __publicField(this, "defaultConditionModifier", "equals");
31881
- __publicField(this, "modifiers", modifiers$8);
33000
+ __publicField(this, "modifiers", modifiers$a);
31882
33001
  }
31883
33002
  static deserialize(serializedCondition, field) {
31884
33003
  const { conditionValue, conditionModifier, ...rest } = serializedCondition;
31885
- const modifierConfig = modifiers$8[conditionModifier];
33004
+ const modifierConfig = modifiers$a[conditionModifier];
31886
33005
  const deserializedValue = conditionValue !== void 0 && modifierConfig.isSerializedValueValid(conditionValue) ? modifierConfig.modifier.deserialize(conditionValue) : void 0;
31887
33006
  return new MultiStringFieldCondition({ field, conditionModifier, conditionValue: deserializedValue, ...rest });
31888
33007
  }
@@ -31961,7 +33080,7 @@ const NumberFieldConditionCell = (props) => {
31961
33080
  /* @__PURE__ */ jsx(RemoveConditionButton, { condition, onClick: onRemove })
31962
33081
  ] });
31963
33082
  };
31964
- const modifiers$7 = {
33083
+ const modifiers$9 = {
31965
33084
  equals: createConditionModifierConfig({
31966
33085
  modifier: NumberEqualsConditionModifier,
31967
33086
  isValueValid: (value) => typeof value === "number",
@@ -32014,13 +33133,11 @@ const modifiers$7 = {
32014
33133
  class NumberFieldCondition extends BaseCondition {
32015
33134
  constructor(options) {
32016
33135
  super(options);
32017
- __publicField(this, "defaultConditionValue");
32018
- __publicField(this, "defaultConditionModifier", "equals");
32019
- __publicField(this, "modifiers", modifiers$7);
33136
+ __publicField(this, "modifiers", modifiers$9);
32020
33137
  }
32021
33138
  static deserialize(serializedCondition, field) {
32022
33139
  const { conditionValue, conditionModifier, ...rest } = serializedCondition;
32023
- const modifierConfig = modifiers$7[conditionModifier];
33140
+ const modifierConfig = modifiers$9[conditionModifier];
32024
33141
  const deserializedValue = conditionValue !== void 0 && modifierConfig.isSerializedValueValid(conditionValue) ? (
32025
33142
  // @ts-expect-error calling isSerializedValueValid means conditionValue is of appropriate type
32026
33143
  modifierConfig.modifier.deserialize(conditionValue)
@@ -32064,7 +33181,7 @@ const OTPFieldConditionCell = (props) => {
32064
33181
  /* @__PURE__ */ jsx(RemoveConditionButton, { condition, onClick: onRemove })
32065
33182
  ] });
32066
33183
  };
32067
- const modifiers$6 = {
33184
+ const modifiers$8 = {
32068
33185
  equals: createConditionModifierConfig({
32069
33186
  modifier: StringEqualsConditionModifier,
32070
33187
  isValueValid: (_value) => true,
@@ -32093,13 +33210,11 @@ const modifiers$6 = {
32093
33210
  class OTPFieldCondition extends BaseCondition {
32094
33211
  constructor(options) {
32095
33212
  super(options);
32096
- __publicField(this, "defaultConditionValue");
32097
- __publicField(this, "defaultConditionModifier", "equals");
32098
- __publicField(this, "modifiers", modifiers$6);
33213
+ __publicField(this, "modifiers", modifiers$8);
32099
33214
  }
32100
33215
  static deserialize(serializedCondition, field) {
32101
33216
  const { conditionValue, conditionModifier, ...rest } = serializedCondition;
32102
- const modifierConfig = modifiers$6[conditionModifier];
33217
+ const modifierConfig = modifiers$8[conditionModifier];
32103
33218
  const deserializedValue = conditionValue !== void 0 && modifierConfig.isSerializedValueValid(conditionValue) ? modifierConfig.modifier.deserialize(conditionValue) : void 0;
32104
33219
  return new OTPFieldCondition({ field, conditionModifier, conditionValue: deserializedValue, ...rest });
32105
33220
  }
@@ -32107,6 +33222,117 @@ class OTPFieldCondition extends BaseCondition {
32107
33222
  return /* @__PURE__ */ jsx(OTPFieldConditionCell, { condition: this, ...props }, this.id);
32108
33223
  }
32109
33224
  }
33225
+ const PassFailFieldConditionCell = (props) => {
33226
+ const { condition, onRemove } = props;
33227
+ const field = condition.field;
33228
+ const conditionValue = condition.getConditionValue();
33229
+ const conditionModifier = condition.getConditionModifier();
33230
+ const getFilterValueUi = () => {
33231
+ switch (conditionModifier) {
33232
+ case "equals":
33233
+ case "notEquals": {
33234
+ const equalsModifier = condition.modifiers.equals;
33235
+ const equalsFilterValue = conditionValue !== void 0 && equalsModifier.isConditionValueValid(conditionValue) ? conditionValue : void 0;
33236
+ return /* @__PURE__ */ jsxs(Menu.Root, { children: [
33237
+ /* @__PURE__ */ jsx(Menu.ClickTrigger, { children: /* @__PURE__ */ jsx(Button, { type: "button", className: "min-w-0 shrink-1 grow", children: /* @__PURE__ */ jsx("span", { className: "truncate", children: equalsFilterValue !== void 0 ? equalsFilterValue ? passFailFieldStatusMapping[equalsFilterValue].label : "empty" : "..." }) }) }),
33238
+ /* @__PURE__ */ jsx(Menu.Content, { size: "sm", children: /* @__PURE__ */ jsx(
33239
+ Menu.SelectGroup,
33240
+ {
33241
+ required: false,
33242
+ value: equalsFilterValue,
33243
+ onValueChange: condition.setConditionValue,
33244
+ children: passFailFieldStatuses.map((status) => {
33245
+ const { label } = passFailFieldStatusMapping[status];
33246
+ return /* @__PURE__ */ jsx(SelectItemTemplate, { value: status, children: /* @__PURE__ */ jsx("span", { className: "truncate", children: label }) }, status);
33247
+ })
33248
+ }
33249
+ ) })
33250
+ ] });
33251
+ }
33252
+ case "includes":
33253
+ case "excludes": {
33254
+ const includesModifier = condition.modifiers.includes;
33255
+ const includesModifierFilterValue = conditionValue !== void 0 && includesModifier.isConditionValueValid(conditionValue) ? conditionValue : void 0;
33256
+ return /* @__PURE__ */ jsxs(Menu.Root, { children: [
33257
+ /* @__PURE__ */ jsx(Menu.ClickTrigger, { children: /* @__PURE__ */ jsx(Button, { type: "button", children: includesModifierFilterValue ? `${includesModifierFilterValue.length} statuses` : "..." }) }),
33258
+ /* @__PURE__ */ jsx(Menu.Content, { size: "sm", children: /* @__PURE__ */ jsxs(
33259
+ Menu.MultiSelectGroup,
33260
+ {
33261
+ values: includesModifierFilterValue ?? EMPTY_ARRAY,
33262
+ onValuesChange: condition.setConditionValue,
33263
+ children: [
33264
+ /* @__PURE__ */ jsx(SelectAllItemTemplate, { children: "Select all" }),
33265
+ passFailFieldStatuses.map((status) => {
33266
+ const { label, icon } = passFailFieldStatusMapping[status];
33267
+ return /* @__PURE__ */ jsxs(MultiSelectItemTemplate, { value: status, children: [
33268
+ /* @__PURE__ */ jsx(LuIcon, { icon }),
33269
+ /* @__PURE__ */ jsx("span", { className: "truncate", children: label })
33270
+ ] }, status);
33271
+ })
33272
+ ]
33273
+ }
33274
+ ) })
33275
+ ] });
33276
+ }
33277
+ }
33278
+ };
33279
+ return /* @__PURE__ */ jsxs(ButtonGroup, { className: "flex w-max max-w-full min-w-0 gap-0.5", size: "sm", variant: "fill", accentColor: "base", children: [
33280
+ /* @__PURE__ */ jsxs(Badge, { className: "min-w-0 shrink-1", size: "sm", variant: "fill", accentColor: "base", children: [
33281
+ /* @__PURE__ */ jsx(LuIcon, { icon: fieldIcons[field.type] }),
33282
+ /* @__PURE__ */ jsx("span", { className: "truncate", children: field.label || UNLABELLED_FIELD_LABEL })
33283
+ ] }),
33284
+ /* @__PURE__ */ jsx(ConditionModifierDropdown, { condition, children: /* @__PURE__ */ jsx(Button, { type: "button", children: condition.modifiers[conditionModifier].modifier.label }) }),
33285
+ getFilterValueUi(),
33286
+ /* @__PURE__ */ jsx(RemoveConditionButton, { condition, onClick: onRemove })
33287
+ ] });
33288
+ };
33289
+ const modifiers$7 = {
33290
+ equals: createConditionModifierConfig({
33291
+ modifier: PassFailEqualsConditionModifier,
33292
+ isValueValid: (value) => value !== null,
33293
+ isConditionValueValid: (conditionValue) => typeof conditionValue === "string",
33294
+ isSerializedValueValid: (serializedConditionValue) => typeof serializedConditionValue === "string"
33295
+ }),
33296
+ notEquals: createConditionModifierConfig({
33297
+ modifier: PassFailNotEqualsConditionModifier,
33298
+ isValueValid: (value) => value !== null,
33299
+ isConditionValueValid: (conditionValue) => typeof conditionValue === "string",
33300
+ isSerializedValueValid: (serializedConditionValue) => typeof serializedConditionValue === "string"
33301
+ }),
33302
+ includes: createConditionModifierConfig({
33303
+ modifier: PassFailArrayIncludesConditionModifier,
33304
+ isValueValid: (value) => value !== null,
33305
+ isConditionValueValid: (conditionValue) => Array.isArray(conditionValue),
33306
+ isSerializedValueValid: (serializedConditionValue) => Array.isArray(serializedConditionValue)
33307
+ }),
33308
+ excludes: createConditionModifierConfig({
33309
+ modifier: PassFailArrayExcludesConditionModifier,
33310
+ isValueValid: (value) => value !== null,
33311
+ isConditionValueValid: (conditionValue) => Array.isArray(conditionValue),
33312
+ isSerializedValueValid: (serializedConditionValue) => Array.isArray(serializedConditionValue)
33313
+ })
33314
+ };
33315
+ class PassFailFieldCondition extends BaseCondition {
33316
+ constructor(options) {
33317
+ super(options);
33318
+ __publicField(this, "modifiers", modifiers$7);
33319
+ }
33320
+ static deserialize(serializedCondition, field) {
33321
+ const { conditionValue, conditionModifier, ...rest } = serializedCondition;
33322
+ const modifierConfig = modifiers$7[conditionModifier];
33323
+ const deserializedValue = conditionValue !== void 0 && modifierConfig.isSerializedValueValid(conditionValue) ? (
33324
+ // @ts-expect-error calling isSerializedValueValid means conditionValue is of appropriate type
33325
+ modifierConfig.modifier.deserialize(conditionValue)
33326
+ ) : void 0;
33327
+ return new PassFailFieldCondition({ field, conditionModifier, conditionValue: deserializedValue, ...rest });
33328
+ }
33329
+ transformValue(value) {
33330
+ return value.status;
33331
+ }
33332
+ render(props) {
33333
+ return /* @__PURE__ */ jsx(PassFailFieldConditionCell, { condition: this, ...props }, this.id);
33334
+ }
33335
+ }
32110
33336
  const RadioFieldConditionCell = (props) => {
32111
33337
  const { condition, onRemove } = props;
32112
33338
  const field = condition.field;
@@ -32127,16 +33353,6 @@ const RadioFieldConditionCell = (props) => {
32127
33353
  }
32128
33354
  return mapping;
32129
33355
  }, [normalizedOptions]);
32130
- const handleValuesChange = useCallback(
32131
- (values) => {
32132
- if (values.length > 0) {
32133
- condition.setConditionValue(values);
32134
- } else {
32135
- condition.setConditionValue([]);
32136
- }
32137
- },
32138
- [condition]
32139
- );
32140
33356
  const getFilterValueUi = () => {
32141
33357
  switch (conditionModifier) {
32142
33358
  case "equals":
@@ -32166,8 +33382,8 @@ const RadioFieldConditionCell = (props) => {
32166
33382
  SelectFieldOptionMultiSelectGroup,
32167
33383
  {
32168
33384
  selectFieldOptions: field.options,
32169
- values: includesModifierFilterValue ?? [],
32170
- onValuesChange: handleValuesChange
33385
+ values: includesModifierFilterValue ?? EMPTY_ARRAY,
33386
+ onValuesChange: condition.setConditionValue
32171
33387
  }
32172
33388
  ) })
32173
33389
  ] });
@@ -32184,7 +33400,7 @@ const RadioFieldConditionCell = (props) => {
32184
33400
  /* @__PURE__ */ jsx(RemoveConditionButton, { condition, onClick: onRemove })
32185
33401
  ] });
32186
33402
  };
32187
- const modifiers$5 = {
33403
+ const modifiers$6 = {
32188
33404
  equals: createConditionModifierConfig({
32189
33405
  modifier: StringEqualsConditionModifier,
32190
33406
  isValueValid: (value) => typeof value === "string",
@@ -32213,13 +33429,11 @@ const modifiers$5 = {
32213
33429
  class RadioFieldCondition extends BaseCondition {
32214
33430
  constructor(options) {
32215
33431
  super(options);
32216
- __publicField(this, "defaultConditionValue");
32217
- __publicField(this, "defaultConditionModifier", "equals");
32218
- __publicField(this, "modifiers", modifiers$5);
33432
+ __publicField(this, "modifiers", modifiers$6);
32219
33433
  }
32220
33434
  static deserialize(serializedCondition, field) {
32221
33435
  const { conditionValue, conditionModifier, ...rest } = serializedCondition;
32222
- const modifierConfig = modifiers$5[conditionModifier];
33436
+ const modifierConfig = modifiers$6[conditionModifier];
32223
33437
  const deserializedValue = conditionValue !== void 0 && modifierConfig.isSerializedValueValid(conditionValue) ? (
32224
33438
  // @ts-expect-error calling isSerializedValueValid means conditionValue is of appropriate type
32225
33439
  modifierConfig.modifier.deserialize(conditionValue)
@@ -32230,6 +33444,146 @@ class RadioFieldCondition extends BaseCondition {
32230
33444
  return /* @__PURE__ */ jsx(RadioFieldConditionCell, { condition: this, ...props }, this.id);
32231
33445
  }
32232
33446
  }
33447
+ const RatingFieldConditionCell = (props) => {
33448
+ const { condition, onRemove } = props;
33449
+ const field = condition.field;
33450
+ const conditionValue = condition.getConditionValue();
33451
+ const conditionModifier = condition.getConditionModifier();
33452
+ const getFilterValueUi = () => {
33453
+ switch (conditionModifier) {
33454
+ case "equals":
33455
+ case "notEquals":
33456
+ case "greaterThanOrEquals":
33457
+ case "lessThanOrEquals":
33458
+ case "greaterThan":
33459
+ case "lessThan": {
33460
+ const modifier = condition.modifiers[conditionModifier];
33461
+ const filterValue = conditionValue !== void 0 && modifier.isConditionValueValid(conditionValue) ? conditionValue : void 0;
33462
+ return /* @__PURE__ */ jsx(
33463
+ NumberInputPopover,
33464
+ {
33465
+ value: filterValue ?? null,
33466
+ onValueChange: (value) => condition.setConditionValue(value ?? void 0),
33467
+ size: "sm",
33468
+ children: /* @__PURE__ */ jsx(Button, { type: "button", className: "truncate", children: filterValue !== void 0 ? filterValue : "..." })
33469
+ }
33470
+ );
33471
+ }
33472
+ case "inRange":
33473
+ case "notInRange": {
33474
+ const inRangeModifier = condition.modifiers.inRange;
33475
+ const rangeFilterValue = conditionValue !== void 0 && inRangeModifier.isConditionValueValid(conditionValue) ? conditionValue : void 0;
33476
+ return /* @__PURE__ */ jsxs(Fragment$1, { children: [
33477
+ /* @__PURE__ */ jsx(
33478
+ NumberInputPopover,
33479
+ {
33480
+ value: (rangeFilterValue == null ? void 0 : rangeFilterValue.from) ?? null,
33481
+ onValueChange: (value) => {
33482
+ condition.setConditionValue({
33483
+ from: value,
33484
+ to: (rangeFilterValue == null ? void 0 : rangeFilterValue.to) ?? null
33485
+ });
33486
+ },
33487
+ size: "sm",
33488
+ children: /* @__PURE__ */ jsx(Button, { className: "truncate", children: (rangeFilterValue == null ? void 0 : rangeFilterValue.from) ?? "..." })
33489
+ }
33490
+ ),
33491
+ /* @__PURE__ */ jsx(
33492
+ NumberInputPopover,
33493
+ {
33494
+ value: (rangeFilterValue == null ? void 0 : rangeFilterValue.to) ?? null,
33495
+ onValueChange: (value) => {
33496
+ condition.setConditionValue({
33497
+ from: (rangeFilterValue == null ? void 0 : rangeFilterValue.from) ?? null,
33498
+ to: value
33499
+ });
33500
+ },
33501
+ size: "sm",
33502
+ children: /* @__PURE__ */ jsx(Button, { className: "truncate", children: (rangeFilterValue == null ? void 0 : rangeFilterValue.to) ?? "..." })
33503
+ }
33504
+ )
33505
+ ] });
33506
+ }
33507
+ }
33508
+ };
33509
+ return /* @__PURE__ */ jsxs(ButtonGroup, { className: "flex w-max max-w-full min-w-0 gap-0.5", size: "sm", variant: "fill", accentColor: "base", children: [
33510
+ /* @__PURE__ */ jsxs(Badge, { className: "min-w-0 shrink-1", size: "sm", variant: "fill", accentColor: "base", children: [
33511
+ /* @__PURE__ */ jsx(LuIcon, { icon: fieldIcons[field.type] }),
33512
+ /* @__PURE__ */ jsx("span", { className: "truncate", children: field.label || UNLABELLED_FIELD_LABEL })
33513
+ ] }),
33514
+ /* @__PURE__ */ jsx(ConditionModifierDropdown, { condition, children: /* @__PURE__ */ jsx(Button, { type: "button", children: condition.modifiers[conditionModifier].modifier.label }) }),
33515
+ getFilterValueUi(),
33516
+ /* @__PURE__ */ jsx(RemoveConditionButton, { condition, onClick: onRemove })
33517
+ ] });
33518
+ };
33519
+ const modifiers$5 = {
33520
+ equals: createConditionModifierConfig({
33521
+ modifier: NumberEqualsConditionModifier,
33522
+ isValueValid: (value) => typeof value === "number",
33523
+ isConditionValueValid: (conditionValue) => typeof conditionValue === "number",
33524
+ isSerializedValueValid: (conditionValue) => typeof conditionValue === "number"
33525
+ }),
33526
+ notEquals: createConditionModifierConfig({
33527
+ modifier: NumberNotEqualsConditionModifier,
33528
+ isValueValid: (value) => typeof value === "number",
33529
+ isConditionValueValid: (conditionValue) => typeof conditionValue === "number",
33530
+ isSerializedValueValid: (conditionValue) => typeof conditionValue === "number"
33531
+ }),
33532
+ lessThan: createConditionModifierConfig({
33533
+ modifier: NumberLessThanConditionModifier,
33534
+ isValueValid: (value) => typeof value === "number",
33535
+ isConditionValueValid: (conditionValue) => typeof conditionValue === "number",
33536
+ isSerializedValueValid: (conditionValue) => typeof conditionValue === "number"
33537
+ }),
33538
+ lessThanOrEquals: createConditionModifierConfig({
33539
+ modifier: NumberLessThanOrEqualsConditionModifier,
33540
+ isValueValid: (value) => typeof value === "number",
33541
+ isConditionValueValid: (conditionValue) => typeof conditionValue === "number",
33542
+ isSerializedValueValid: (conditionValue) => typeof conditionValue === "number"
33543
+ }),
33544
+ greaterThan: createConditionModifierConfig({
33545
+ modifier: NumberGreaterThanConditionModifier,
33546
+ isValueValid: (value) => typeof value === "number",
33547
+ isConditionValueValid: (conditionValue) => typeof conditionValue === "number",
33548
+ isSerializedValueValid: (conditionValue) => typeof conditionValue === "number"
33549
+ }),
33550
+ greaterThanOrEquals: createConditionModifierConfig({
33551
+ modifier: NumberGreaterThanOrEqualsConditionModifier,
33552
+ isValueValid: (value) => typeof value === "number",
33553
+ isConditionValueValid: (conditionValue) => typeof conditionValue === "number",
33554
+ isSerializedValueValid: (conditionValue) => typeof conditionValue === "number"
33555
+ }),
33556
+ inRange: createConditionModifierConfig({
33557
+ modifier: NumberRangeInConditionModifier,
33558
+ isValueValid: (value) => typeof value === "number",
33559
+ isConditionValueValid: (conditionValue) => typeof conditionValue === "object",
33560
+ isSerializedValueValid: (conditionValue) => typeof conditionValue === "object"
33561
+ }),
33562
+ notInRange: createConditionModifierConfig({
33563
+ modifier: NumberRangeNotInConditionModifier,
33564
+ isValueValid: (value) => typeof value === "number",
33565
+ isConditionValueValid: (conditionValue) => typeof conditionValue === "object",
33566
+ isSerializedValueValid: (conditionValue) => typeof conditionValue === "object"
33567
+ })
33568
+ };
33569
+ class RatingFieldCondition extends BaseCondition {
33570
+ constructor(options) {
33571
+ super(options);
33572
+ __publicField(this, "modifiers", modifiers$5);
33573
+ }
33574
+ static deserialize(serializedCondition, field) {
33575
+ const { conditionValue, conditionModifier, ...rest } = serializedCondition;
33576
+ const modifierConfig = modifiers$5[conditionModifier];
33577
+ const deserializedValue = conditionValue !== void 0 && modifierConfig.isSerializedValueValid(conditionValue) ? (
33578
+ // @ts-expect-error calling isSerializedValueValid means conditionValue is of appropriate type
33579
+ modifierConfig.modifier.deserialize(conditionValue)
33580
+ ) : void 0;
33581
+ return new RatingFieldCondition({ field, conditionModifier, conditionValue: deserializedValue, ...rest });
33582
+ }
33583
+ render(props) {
33584
+ return /* @__PURE__ */ jsx(RatingFieldConditionCell, { condition: this, ...props }, this.id);
33585
+ }
33586
+ }
32233
33587
  const ScanFieldConditionCell = (props) => {
32234
33588
  const { condition, onRemove } = props;
32235
33589
  const field = condition.field;
@@ -32292,8 +33646,6 @@ const modifiers$4 = {
32292
33646
  class ScanFieldCondition extends BaseCondition {
32293
33647
  constructor(options) {
32294
33648
  super(options);
32295
- __publicField(this, "defaultConditionValue");
32296
- __publicField(this, "defaultConditionModifier", "equals");
32297
33649
  __publicField(this, "modifiers", modifiers$4);
32298
33650
  }
32299
33651
  static deserialize(serializedCondition, field) {
@@ -32412,8 +33764,6 @@ const modifiers$3 = {
32412
33764
  class SelectFieldCondition extends BaseCondition {
32413
33765
  constructor(options) {
32414
33766
  super(options);
32415
- __publicField(this, "defaultConditionValue");
32416
- __publicField(this, "defaultConditionModifier", "equals");
32417
33767
  __publicField(this, "modifiers", modifiers$3);
32418
33768
  }
32419
33769
  static deserialize(serializedCondition, field) {
@@ -32491,8 +33841,6 @@ const modifiers$2 = {
32491
33841
  class StringFieldCondition extends BaseCondition {
32492
33842
  constructor(options) {
32493
33843
  super(options);
32494
- __publicField(this, "defaultConditionValue");
32495
- __publicField(this, "defaultConditionModifier", "equals");
32496
33844
  __publicField(this, "modifiers", modifiers$2);
32497
33845
  }
32498
33846
  static deserialize(serializedCondition, field) {
@@ -32567,8 +33915,6 @@ const modifiers$1 = {
32567
33915
  class TextFieldCondition extends BaseCondition {
32568
33916
  constructor(options) {
32569
33917
  super(options);
32570
- __publicField(this, "defaultConditionValue");
32571
- __publicField(this, "defaultConditionModifier", "equals");
32572
33918
  __publicField(this, "modifiers", modifiers$1);
32573
33919
  }
32574
33920
  static deserialize(serializedCondition, field) {
@@ -32639,8 +33985,6 @@ const modifiers = {
32639
33985
  class UploadFieldCondition extends BaseCondition {
32640
33986
  constructor(options) {
32641
33987
  super(options);
32642
- __publicField(this, "defaultConditionValue");
32643
- __publicField(this, "defaultConditionModifier", "equals");
32644
33988
  __publicField(this, "modifiers", modifiers);
32645
33989
  }
32646
33990
  static deserialize(serializedCondition, field) {
@@ -32653,43 +33997,35 @@ class UploadFieldCondition extends BaseCondition {
32653
33997
  return /* @__PURE__ */ jsx(UploadFieldConditionCell, { condition: this, ...props }, this.id);
32654
33998
  }
32655
33999
  }
32656
- const deserializeCondition = (serializedCondition, field) => {
32657
- switch (serializedCondition.type) {
32658
- case "text":
32659
- return TextFieldCondition.deserialize(serializedCondition, field);
32660
- case "boolean":
32661
- return BooleanFieldCondition.deserialize(serializedCondition, field);
32662
- case "number":
32663
- return NumberFieldCondition.deserialize(serializedCondition, field);
32664
- case "date":
32665
- return DateFieldCondition.deserialize(serializedCondition, field);
32666
- case "string":
32667
- return StringFieldCondition.deserialize(serializedCondition, field);
32668
- case "select":
32669
- return SelectFieldCondition.deserialize(serializedCondition, field);
32670
- case "multi-string":
32671
- return MultiStringFieldCondition.deserialize(serializedCondition, field);
32672
- case "multi-select":
32673
- return MultiSelectFieldCondition.deserialize(serializedCondition, field);
32674
- case "upload":
32675
- return UploadFieldCondition.deserialize(serializedCondition, field);
32676
- case "qr":
32677
- return ScanFieldCondition.deserialize(serializedCondition, field);
32678
- case "radio":
32679
- return RadioFieldCondition.deserialize(serializedCondition, field);
32680
- case "checkbox-list":
32681
- return CheckboxListFieldCondition.deserialize(serializedCondition, field);
32682
- case "otp":
32683
- return OTPFieldCondition.deserialize(serializedCondition, field);
32684
- }
34000
+ const ConditionTypeToClsMapping = {
34001
+ date: DateFieldCondition,
34002
+ number: NumberFieldCondition,
34003
+ boolean: BooleanFieldCondition,
34004
+ select: SelectFieldCondition,
34005
+ string: StringFieldCondition,
34006
+ text: TextFieldCondition,
34007
+ upload: UploadFieldCondition,
34008
+ qr: ScanFieldCondition,
34009
+ "multi-string": MultiStringFieldCondition,
34010
+ "multi-select": MultiSelectFieldCondition,
34011
+ radio: RadioFieldCondition,
34012
+ "checkbox-list": CheckboxListFieldCondition,
34013
+ "pass-fail": PassFailFieldCondition,
34014
+ otp: OTPFieldCondition,
34015
+ rating: RatingFieldCondition
32685
34016
  };
32686
- const deserializeConditions = (serializedConditions, fields) => {
34017
+ const deserializeCondition = (field, serializedCondition) => {
34018
+ if (field.type !== serializedCondition.type)
34019
+ throw new Error(`field and condition type mismatch ${field.type} !== ${serializedCondition.type}`);
34020
+ return ConditionTypeToClsMapping[serializedCondition.type].deserialize(serializedCondition, field);
34021
+ };
34022
+ const deserializeConditions = (fields, serializedConditions) => {
32687
34023
  const fieldsMapping = {};
32688
34024
  for (const field of fields) {
32689
34025
  fieldsMapping[field.identifier] = field;
32690
34026
  }
32691
34027
  return serializedConditions.map(
32692
- (serializedCondition) => deserializeCondition(serializedCondition, fieldsMapping[serializedCondition.fieldId])
34028
+ (serializedCondition) => deserializeCondition(fieldsMapping[serializedCondition.fieldId], serializedCondition)
32693
34029
  );
32694
34030
  };
32695
34031
  const applyConditions = (conditions, values) => {
@@ -32697,35 +34033,53 @@ const applyConditions = (conditions, values) => {
32697
34033
  return condition.apply(values[condition.field.identifier]);
32698
34034
  }) : true;
32699
34035
  };
32700
- const deserializeField = (serializedField) => {
32701
- switch (serializedField.type) {
32702
- case "boolean":
32703
- return BooleanField.deserialize(serializedField);
32704
- case "text":
32705
- return TextField.deserialize(serializedField);
32706
- case "number":
32707
- return NumberField.deserialize(serializedField);
32708
- case "date":
32709
- return DateField.deserialize(serializedField);
32710
- case "select":
32711
- return SelectField.deserialize(serializedField);
32712
- case "multi-string":
32713
- return MultiStringField.deserialize(serializedField);
32714
- case "multi-select":
32715
- return MultiSelectField.deserialize(serializedField);
32716
- case "upload":
32717
- return UploadField.deserialize(serializedField);
32718
- case "qr":
32719
- return ScanField.deserialize(serializedField);
32720
- case "radio":
32721
- return RadioField.deserialize(serializedField);
32722
- case "checkbox-list":
32723
- return CheckboxListField.deserialize(serializedField);
32724
- case "string":
32725
- return StringField.deserialize(serializedField);
32726
- case "otp":
32727
- return OTPField.deserialize(serializedField);
34036
+ class ConditionManager extends Observable {
34037
+ constructor(conditions) {
34038
+ super();
34039
+ __publicField(this, "conditions");
34040
+ __publicField(this, "conditionObserver", () => {
34041
+ this.conditions = [...this.conditions];
34042
+ this.notify(this);
34043
+ });
34044
+ __publicField(this, "initConditions", (conditions) => {
34045
+ for (const c of conditions) c.observe(this.conditionObserver);
34046
+ return conditions;
34047
+ });
34048
+ this.conditions = this.initConditions(conditions);
34049
+ }
34050
+ getConditions() {
34051
+ return this.conditions;
34052
+ }
34053
+ addCondition(condition) {
34054
+ this.conditions = this.initConditions([...this.conditions, condition]);
34055
+ this.notify(this);
34056
+ }
34057
+ addConditions(conditions) {
34058
+ this.conditions = this.initConditions([...this.conditions, ...conditions]);
34059
+ this.notify(this);
34060
+ }
34061
+ removeCondition(condition) {
34062
+ this.conditions = this.initConditions(this.conditions.filter((c) => c.id !== condition.id));
34063
+ this.notify(this);
32728
34064
  }
34065
+ removeConditions(conditions) {
34066
+ const conditionIds = new Set(conditions.map((c) => c.id));
34067
+ this.conditions = this.initConditions(this.conditions.filter((c) => !conditionIds.has(c.id)));
34068
+ this.notify(this);
34069
+ }
34070
+ applyConditions(values) {
34071
+ return applyConditions(this.conditions, values);
34072
+ }
34073
+ }
34074
+ const useConditionManager = (conditions, onConditionsChange) => {
34075
+ return useMemo(() => {
34076
+ const ret = new ConditionManager(conditions);
34077
+ ret.observe((conditionManager) => onConditionsChange(conditionManager.getConditions()));
34078
+ return ret;
34079
+ }, [conditions, onConditionsChange]);
34080
+ };
34081
+ const deserializeField = (serializedField) => {
34082
+ return FieldTypeToClsMapping[serializedField.type].deserialize(serializedField);
32729
34083
  };
32730
34084
  function deserializeFields(fields) {
32731
34085
  return fields.map(deserialize);
@@ -32800,6 +34154,85 @@ function cleanSerializedFieldValues(fields, values) {
32800
34154
  }
32801
34155
  return ret;
32802
34156
  }
34157
+ function extractFilesAndPromisesFromFieldValues(fields, values) {
34158
+ const cleanValues = cleanFieldValues(fields, values);
34159
+ const valuesRet = {};
34160
+ const filesRet = {};
34161
+ for (const field of fields) {
34162
+ if (!(field.identifier in cleanValues)) continue;
34163
+ const value = cleanValues[field.identifier];
34164
+ switch (field.type) {
34165
+ case "upload":
34166
+ if (!field.isValueValid(value)) break;
34167
+ filesRet[field.identifier] = value;
34168
+ valuesRet[field.identifier] = [];
34169
+ break;
34170
+ case "pass-fail":
34171
+ if (!field.isValueValid(value)) break;
34172
+ filesRet[field.identifier] = value.files;
34173
+ valuesRet[field.identifier] = {
34174
+ ...value,
34175
+ files: []
34176
+ };
34177
+ break;
34178
+ default:
34179
+ valuesRet[field.identifier] = values[field.identifier];
34180
+ }
34181
+ }
34182
+ return [valuesRet, filesRet];
34183
+ }
34184
+ function insertFilesAndPromisesToFieldValues(fields, values, filesAndPromises) {
34185
+ const ret = {};
34186
+ for (const field of fields) {
34187
+ if (!(field.identifier in values)) continue;
34188
+ const value = values[field.identifier];
34189
+ switch (field.type) {
34190
+ case "upload":
34191
+ if (!field.isValueValid(value)) break;
34192
+ ret[field.identifier] = filesAndPromises[field.identifier] ?? [];
34193
+ break;
34194
+ case "pass-fail":
34195
+ if (!field.isValueValid(value)) break;
34196
+ ret[field.identifier] = {
34197
+ ...value,
34198
+ files: filesAndPromises[field.identifier] ?? []
34199
+ };
34200
+ break;
34201
+ default:
34202
+ if (!field.isValueValid(value)) break;
34203
+ ret[field.identifier] = value;
34204
+ }
34205
+ }
34206
+ return ret;
34207
+ }
34208
+ const initializeFieldValues = (fields, values) => {
34209
+ const ret = {};
34210
+ for (const field of fields) {
34211
+ const value = values[field.identifier];
34212
+ ret[field.identifier] = value !== void 0 ? value : field.blankValue();
34213
+ }
34214
+ return ret;
34215
+ };
34216
+ const changedFieldValues = (fields, values1, values2) => {
34217
+ const ret = {};
34218
+ for (const field of fields) {
34219
+ const value1 = values1[field.identifier];
34220
+ const value2 = values2[field.identifier];
34221
+ if (field.areValuesEqual(value1, value2)) continue;
34222
+ ret[field.identifier] = value2;
34223
+ }
34224
+ return ret;
34225
+ };
34226
+ const unchangedFieldValues = (fields, values1, values2) => {
34227
+ const ret = {};
34228
+ for (const field of fields) {
34229
+ const value1 = values1[field.identifier];
34230
+ const value2 = values2[field.identifier];
34231
+ if (!field.areValuesEqual(value1, value2)) continue;
34232
+ ret[field.identifier] = value2;
34233
+ }
34234
+ return ret;
34235
+ };
32803
34236
  const RendererContext = createContext({});
32804
34237
  const FieldSectionLayout = memo((props) => {
32805
34238
  const { fieldSection: section, ...rest } = props;
@@ -32880,7 +34313,7 @@ const _FieldSection = class _FieldSection extends BaseFormElement {
32880
34313
  const fields = data.fields.map(deserializeField);
32881
34314
  const conditions = {};
32882
34315
  for (const [sectionId, serializedConditions] of Object.entries(data.conditions)) {
32883
- conditions[sectionId] = deserializeConditions(serializedConditions, fields);
34316
+ conditions[sectionId] = deserializeConditions(fields, serializedConditions);
32884
34317
  }
32885
34318
  return new _FieldSection({ ...data, fields, conditions });
32886
34319
  }
@@ -32921,12 +34354,10 @@ const _FieldSection = class _FieldSection extends BaseFormElement {
32921
34354
  getFields() {
32922
34355
  return this.fields;
32923
34356
  }
32924
- addField(field) {
32925
- this.fields = this.initFields([...this.fields, field]);
32926
- this.notify(this);
32927
- }
32928
- addFields(fields) {
32929
- this.fields = this.initFields([...this.fields, ...fields]);
34357
+ addField(field, index) {
34358
+ const copy = [...this.fields];
34359
+ copy.splice(index ?? this.fields.length, 0, field);
34360
+ this.fields = this.initFields(copy);
32930
34361
  this.notify(this);
32931
34362
  }
32932
34363
  moveField(sourceIndex, targetIndex) {
@@ -32945,16 +34376,6 @@ const _FieldSection = class _FieldSection extends BaseFormElement {
32945
34376
  this.conditions = newConditions;
32946
34377
  this.notify(this);
32947
34378
  }
32948
- removeFields(fields) {
32949
- const fieldIdentifiers = new Set(fields.map(({ identifier }) => identifier));
32950
- this.fields = this.initFields(this.fields.filter(({ identifier }) => !fieldIdentifiers.has(identifier)));
32951
- const newConditions = {};
32952
- for (const [sectionId, conditions] of Object.entries(this.conditions)) {
32953
- newConditions[sectionId] = conditions.filter(({ field }) => !fieldIdentifiers.has(field.identifier));
32954
- }
32955
- this.conditions = newConditions;
32956
- this.notify(this);
32957
- }
32958
34379
  getConditions(identifier) {
32959
34380
  return this.conditions[identifier];
32960
34381
  }
@@ -33034,27 +34455,20 @@ class FieldSchema extends Observable {
33034
34455
  getFieldSections() {
33035
34456
  return this.fieldSections;
33036
34457
  }
33037
- addFieldSection(field) {
33038
- this.fieldSections = this.initFields([...this.fieldSections, field]);
34458
+ addFieldSection(fieldSection, index) {
34459
+ const copy = [...this.fieldSections];
34460
+ copy.splice(index ?? this.fieldSections.length, 0, fieldSection);
34461
+ this.fieldSections = this.initFields(copy);
33039
34462
  this.notify(this);
33040
34463
  }
33041
- addFieldSections(fields) {
33042
- this.fieldSections = this.initFields([...this.fieldSections, ...fields]);
33043
- this.notify(this);
33044
- }
33045
- removeFieldSection(field) {
33046
- const newFields = this.fieldSections.filter((f) => f.identifier !== field.identifier);
33047
- for (const field2 of newFields) {
33048
- field2.removeConditional(field2.identifier);
34464
+ removeFieldSection(fieldSection) {
34465
+ const newFields = this.fieldSections.filter((f) => f.identifier !== fieldSection.identifier);
34466
+ for (const field of newFields) {
34467
+ field.removeConditional(field.identifier);
33049
34468
  }
33050
34469
  this.fieldSections = this.initFields(newFields);
33051
34470
  this.notify(this);
33052
34471
  }
33053
- removeFieldSections(fields) {
33054
- const fieldsIds = new Set(fields.map((f) => f.identifier));
33055
- this.fieldSections = this.initFields(this.fieldSections.filter((f) => !fieldsIds.has(f.identifier)));
33056
- this.notify(this);
33057
- }
33058
34472
  moveFieldSection(sourceIndex, targetIndex) {
33059
34473
  const newFields = [...this.fieldSections];
33060
34474
  const [removedElement] = newFields.splice(sourceIndex, 1);
@@ -33068,44 +34482,70 @@ class FieldSchema extends Observable {
33068
34482
  serializeValues(values) {
33069
34483
  return serializeFieldValues(this.getFields(), values);
33070
34484
  }
34485
+ deserializeConditions(conditions) {
34486
+ return deserializeConditions(this.getFields(), conditions);
34487
+ }
34488
+ initializeValues(values) {
34489
+ return initializeFieldValues(this.getFields(), values);
34490
+ }
33071
34491
  }
33072
34492
  const FieldSchemaContext = createContext(new FieldSchema([]));
33073
34493
  const FormBuilderContext = createContext({});
34494
+ const useFieldTypeItems = (onSelect = () => null) => {
34495
+ return useMemo(() => {
34496
+ const entries = Object.entries(FieldTypeToClsMapping);
34497
+ return entries.map(([type, fieldClass]) => ({
34498
+ children: fieldClass.fieldTypeName,
34499
+ icon: /* @__PURE__ */ jsx(LuIcon, { icon: fieldIcons[type] }),
34500
+ value: type,
34501
+ onSelect: () => {
34502
+ onSelect(type);
34503
+ }
34504
+ }));
34505
+ }, [onSelect]);
34506
+ };
34507
+ const CreateFieldDropdownMenu = memo((props) => {
34508
+ const { children, variant, size, accentColor, onSelectFieldType, ...rest } = props;
34509
+ const fieldTypeItems = useFieldTypeItems(onSelectFieldType);
34510
+ return /* @__PURE__ */ jsxs(Menu.Root, { ...rest, children: [
34511
+ /* @__PURE__ */ jsx(Menu.ClickTrigger, { children }),
34512
+ /* @__PURE__ */ jsx(Menu.Content, { variant, size, accentColor, children: /* @__PURE__ */ jsx(Menu.Scroll, { children: fieldTypeItems.flat().map((item) => /* @__PURE__ */ jsxs(Menu.Item, { onSelect: item.onSelect, children: [
34513
+ item.icon,
34514
+ item.children
34515
+ ] }, item.value)) }) })
34516
+ ] });
34517
+ });
34518
+ CreateFieldDropdownMenu.displayName = "CreateFieldDropdownMenu";
33074
34519
  const createField = (type) => {
33075
34520
  switch (type) {
33076
34521
  case "text":
33077
- return new TextField({ fieldValidators: [], label: "", required: false, identifier: v4() });
34522
+ return new TextField({ label: "", required: false, identifier: v4() });
33078
34523
  case "boolean":
33079
34524
  return new BooleanField({
33080
- fieldValidators: [],
33081
34525
  label: "",
33082
34526
  required: false,
33083
34527
  identifier: v4()
33084
34528
  });
33085
34529
  case "number":
33086
34530
  return new NumberField({
33087
- fieldValidators: [],
33088
34531
  label: "",
33089
34532
  required: false,
33090
34533
  identifier: v4()
33091
34534
  });
33092
34535
  case "date":
33093
34536
  return new DateField({
33094
- fieldValidators: [],
33095
34537
  label: "",
33096
34538
  required: false,
33097
34539
  identifier: v4()
33098
34540
  });
33099
34541
  case "string":
33100
34542
  return new StringField({
33101
- fieldValidators: [],
33102
34543
  label: "",
33103
34544
  required: false,
33104
34545
  identifier: v4()
33105
34546
  });
33106
34547
  case "select":
33107
34548
  return new SelectField({
33108
- fieldValidators: [],
33109
34549
  label: "",
33110
34550
  options: [],
33111
34551
  required: false,
@@ -33113,14 +34553,12 @@ const createField = (type) => {
33113
34553
  });
33114
34554
  case "multi-string":
33115
34555
  return new MultiStringField({
33116
- fieldValidators: [],
33117
34556
  label: "",
33118
34557
  required: false,
33119
34558
  identifier: v4()
33120
34559
  });
33121
34560
  case "multi-select":
33122
34561
  return new MultiSelectField({
33123
- fieldValidators: [],
33124
34562
  label: "",
33125
34563
  options: [],
33126
34564
  required: false,
@@ -33128,21 +34566,20 @@ const createField = (type) => {
33128
34566
  });
33129
34567
  case "upload":
33130
34568
  return new UploadField({
33131
- fieldValidators: [],
33132
34569
  label: "",
33133
34570
  required: false,
33134
- identifier: v4()
34571
+ identifier: v4(),
34572
+ maximum_files: 6,
34573
+ maximum_size: maxFileSizeMB
33135
34574
  });
33136
34575
  case "qr":
33137
34576
  return new ScanField({
33138
- fieldValidators: [],
33139
34577
  label: "",
33140
34578
  required: false,
33141
34579
  identifier: v4()
33142
34580
  });
33143
34581
  case "radio":
33144
34582
  return new RadioField({
33145
- fieldValidators: [],
33146
34583
  label: "",
33147
34584
  options: [],
33148
34585
  required: false,
@@ -33150,21 +34587,34 @@ const createField = (type) => {
33150
34587
  });
33151
34588
  case "checkbox-list":
33152
34589
  return new CheckboxListField({
33153
- fieldValidators: [],
33154
34590
  label: "",
33155
34591
  options: [],
33156
34592
  required: false,
33157
34593
  identifier: v4()
33158
34594
  });
34595
+ case "pass-fail":
34596
+ return new PassFailField({
34597
+ label: "",
34598
+ required: false,
34599
+ identifier: v4(),
34600
+ showNotesAndFilesOn: ["fail"]
34601
+ // TODO: what defaults
34602
+ });
33159
34603
  case "otp":
33160
34604
  return new OTPField({
33161
- fieldValidators: [],
33162
34605
  label: "",
33163
34606
  validationType: "none",
33164
34607
  required: false,
33165
34608
  identifier: v4(),
33166
34609
  length: 6
33167
34610
  });
34611
+ case "rating":
34612
+ return new RatingField({
34613
+ label: "",
34614
+ required: false,
34615
+ identifier: v4(),
34616
+ maxRating: 5
34617
+ });
33168
34618
  }
33169
34619
  };
33170
34620
  const createCondition = (field) => {
@@ -33248,6 +34698,13 @@ const createCondition = (field) => {
33248
34698
  conditionModifier: "equals",
33249
34699
  field
33250
34700
  });
34701
+ case "pass-fail":
34702
+ return new PassFailFieldCondition({
34703
+ id: v4(),
34704
+ conditionValue: void 0,
34705
+ conditionModifier: "equals",
34706
+ field
34707
+ });
33251
34708
  case "otp":
33252
34709
  return new OTPFieldCondition({
33253
34710
  id: v4(),
@@ -33255,6 +34712,13 @@ const createCondition = (field) => {
33255
34712
  conditionModifier: "equals",
33256
34713
  field
33257
34714
  });
34715
+ case "rating":
34716
+ return new RatingFieldCondition({
34717
+ id: v4(),
34718
+ conditionValue: void 0,
34719
+ conditionModifier: "equals",
34720
+ field
34721
+ });
33258
34722
  }
33259
34723
  };
33260
34724
  const getFieldCreationSchema = (type, path) => {
@@ -33275,8 +34739,12 @@ const getFieldCreationSchema = (type, path) => {
33275
34739
  return TextField.getFieldCreationSchema(path);
33276
34740
  case "upload":
33277
34741
  return UploadField.getFieldCreationSchema(path);
34742
+ case "pass-fail":
34743
+ return PassFailField.getFieldCreationSchema(path);
33278
34744
  case "otp":
33279
34745
  return OTPField.getFieldCreationSchema(path);
34746
+ case "rating":
34747
+ return RatingField.getFieldCreationSchema(path);
33280
34748
  default:
33281
34749
  return;
33282
34750
  }
@@ -33294,7 +34762,7 @@ const FieldSettingsPopover = memo((props) => {
33294
34762
  accentColor: "base",
33295
34763
  ...hasError && { color: SEVERITY_COLOR_MAPPING.danger },
33296
34764
  children: [
33297
- /* @__PURE__ */ jsx(LuIcon, { icon: "settings" }),
34765
+ /* @__PURE__ */ jsx(LuIcon, { icon: Settings }),
33298
34766
  "Settings"
33299
34767
  ]
33300
34768
  },
@@ -33305,7 +34773,7 @@ const FieldSettingsPopover = memo((props) => {
33305
34773
  });
33306
34774
  FieldSettingsPopover.displayName = "FieldSettingsPopover";
33307
34775
  const FieldBuilder = memo((props) => {
33308
- const { parentPath, index, field } = props;
34776
+ const { parentPath, fieldIndex, field } = props;
33309
34777
  const { errors } = useFormikContext();
33310
34778
  const openImageViewer = useImageViewer();
33311
34779
  const { disableRequiredFields } = use(FormBuilderContext);
@@ -33321,17 +34789,16 @@ const FieldBuilder = memo((props) => {
33321
34789
  const handleImageDelete = useCallback(() => {
33322
34790
  field.setOptions({ image: void 0 });
33323
34791
  }, [field]);
33324
- const type = field.type;
33325
34792
  const [directlyShownFields, popoverFields] = useMemo(() => {
33326
34793
  const directlyShownFields2 = [];
33327
34794
  const popoverFields2 = [];
33328
- const fieldObject = getFieldCreationSchema(field.type, `${parentPath}.${index}`) ?? [];
34795
+ const fieldObject = getFieldCreationSchema(field.type, `${parentPath}.${fieldIndex}`) ?? [];
33329
34796
  for (const item of fieldObject) {
33330
34797
  if (item.showDirectly) directlyShownFields2.push(item.field);
33331
34798
  else popoverFields2.push(item.field);
33332
34799
  }
33333
34800
  return [directlyShownFields2, popoverFields2];
33334
- }, [field, parentPath, index]);
34801
+ }, [field, parentPath, fieldIndex]);
33335
34802
  const directlyShownInputs = useFieldInputs(directlyShownFields, {
33336
34803
  formId,
33337
34804
  disabled: false
@@ -33356,7 +34823,7 @@ const FieldBuilder = memo((props) => {
33356
34823
  /* @__PURE__ */ jsxs("div", { className: "flex gap-2 w-full justify-between", children: [
33357
34824
  /* @__PURE__ */ jsxs("div", { className: "flex gap-2 items-center", children: [
33358
34825
  /* @__PURE__ */ jsxs(Badge, { accentColor: "base", variant: "soft", size: "sm", children: [
33359
- /* @__PURE__ */ jsx(LuIcon, { icon: fieldIcons[type] }),
34826
+ /* @__PURE__ */ jsx(LuIcon, { icon: fieldIcons[field.type] }),
33360
34827
  fieldTypeName
33361
34828
  ] }),
33362
34829
  !disableRequiredFields && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
@@ -33366,7 +34833,7 @@ const FieldBuilder = memo((props) => {
33366
34833
  checked: field.required,
33367
34834
  onCheckedChange: (required) => field.setOptions({ required: !!required }),
33368
34835
  size: "sm",
33369
- children: /* @__PURE__ */ jsx(Checkbox.Indicator, { children: /* @__PURE__ */ jsx(LuIcon, { icon: "check" }) })
34836
+ children: /* @__PURE__ */ jsx(Checkbox.Indicator, { children: /* @__PURE__ */ jsx(LuIcon, { icon: Check }) })
33370
34837
  }
33371
34838
  ),
33372
34839
  /* @__PURE__ */ jsx(Text, { size: "sm", accentColor: "base", children: "Required" })
@@ -33394,7 +34861,7 @@ const FieldBuilder = memo((props) => {
33394
34861
  "aria-label": "delete",
33395
34862
  onClick: handleImageDelete,
33396
34863
  size: "sm",
33397
- children: /* @__PURE__ */ jsx(LuIcon, { icon: "trash" })
34864
+ children: /* @__PURE__ */ jsx(LuIcon, { icon: Trash })
33398
34865
  }
33399
34866
  )
33400
34867
  ] }),
@@ -33425,46 +34892,26 @@ const FieldBuilder = memo((props) => {
33425
34892
  ] });
33426
34893
  });
33427
34894
  FieldBuilder.displayName = "FieldBuilder";
33428
- const FieldDropdownMenu = memo((props) => {
33429
- const { children, variant, size, accentColor, fields, onSelectField, ...rest } = props;
33430
- return /* @__PURE__ */ jsxs(Menu.Root, { ...rest, children: [
33431
- /* @__PURE__ */ jsx(Menu.ClickTrigger, { children }),
33432
- /* @__PURE__ */ jsx(Menu.Content, { variant, size, accentColor, children: fields.map((field) => {
33433
- return /* @__PURE__ */ jsxs(Menu.Item, { onSelect: () => onSelectField(field), children: [
33434
- /* @__PURE__ */ jsx(LuIcon, { icon: fieldIcons[field.type] }),
33435
- field.label || UNLABELLED_FIELD_LABEL
33436
- ] }, field.identifier);
33437
- }) })
33438
- ] });
33439
- });
33440
- FieldDropdownMenu.displayName = "IssueDataFilterMenu";
33441
- const FieldSectionDropdownMenu = memo((props) => {
33442
- const { children, variant, size, accentColor, fieldSections, onSelectFieldCondition, ...rest } = props;
33443
- return /* @__PURE__ */ jsxs(Menu.Root, { ...rest, children: [
33444
- /* @__PURE__ */ jsx(Menu.ClickTrigger, { children }),
33445
- /* @__PURE__ */ jsx(Menu.Content, { variant, size, accentColor, children: fieldSections.map((fieldSection) => {
33446
- return /* @__PURE__ */ jsxs(Menu.Item, { onSelect: () => onSelectFieldCondition(fieldSection), children: [
33447
- /* @__PURE__ */ jsx(LuIcon, { icon: fieldIcons[fieldSection.type] }),
33448
- fieldSection.label || UNLABELLED_SECTION_LABEL
33449
- ] }, fieldSection.identifier);
33450
- }) })
33451
- ] });
33452
- });
33453
- FieldSectionDropdownMenu.displayName = "IssueDataFilterMenu";
33454
- const FieldWithActions = memo((props) => {
33455
- const { field, fieldSection, index, sectionIndex, remove } = props;
34895
+ const FieldBuilderWithActions = memo((props) => {
34896
+ const { field, fieldSection, fieldIndex, sectionIndex } = props;
33456
34897
  const { showError } = useToast();
33457
34898
  const fileInputRef = useRef(null);
33458
34899
  const parentPath = `fields.${sectionIndex}.fields`;
34900
+ const handleAddField = useCallback(
34901
+ (type) => {
34902
+ fieldSection.addField(createField(type), fieldIndex + 1);
34903
+ },
34904
+ [fieldIndex, fieldSection]
34905
+ );
33459
34906
  const duplicateField = useCallback(() => {
33460
34907
  fieldSection.addField(field.duplicate(v4()));
33461
34908
  }, [field, fieldSection]);
33462
34909
  const moveField = useCallback(
33463
34910
  (direction) => {
33464
34911
  const targetIndex = direction === "up" ? sectionIndex - 1 : sectionIndex + 1;
33465
- fieldSection.moveField(index, targetIndex);
34912
+ fieldSection.moveField(fieldIndex, targetIndex);
33466
34913
  },
33467
- [fieldSection, index, sectionIndex]
34914
+ [fieldSection, fieldIndex, sectionIndex]
33468
34915
  );
33469
34916
  const uploadImage = useCallback(
33470
34917
  (event) => {
@@ -33496,21 +34943,48 @@ const FieldWithActions = memo((props) => {
33496
34943
  (_a2 = fileInputRef.current) == null ? void 0 : _a2.click();
33497
34944
  }, []);
33498
34945
  const handleRemove = useCallback(() => {
33499
- remove(field);
33500
- }, [field, remove]);
34946
+ fieldSection.removeField(field);
34947
+ }, [field, fieldSection]);
33501
34948
  return /* @__PURE__ */ jsxs(Card, { className: "flex items-center justify-between gap-4 w-full", children: [
33502
- /* @__PURE__ */ jsx(FieldBuilder, { index, field, parentPath }),
34949
+ /* @__PURE__ */ jsx(FieldBuilder, { fieldIndex, field, parentPath }),
33503
34950
  /* @__PURE__ */ jsxs(ButtonGroup, { className: "flex-col gap-0.5 flex", variant: "ghost", accentColor: "base", size: "sm", children: [
33504
- /* @__PURE__ */ jsx(IconButton, { type: "button", onClick: handleMoveUp, children: /* @__PURE__ */ jsx(LuIcon, { icon: "move-up" }) }),
33505
- /* @__PURE__ */ jsx(IconButton, { type: "button", onClick: handleMoveDown, children: /* @__PURE__ */ jsx(LuIcon, { icon: "move-down" }) }),
33506
- /* @__PURE__ */ jsx(IconButton, { type: "button", onClick: duplicateField, children: /* @__PURE__ */ jsx(LuIcon, { icon: "copy" }) }),
33507
- /* @__PURE__ */ jsx(IconButton, { type: "button", onClick: handleUploadImage, children: /* @__PURE__ */ jsx(LuIcon, { icon: "image" }) }),
33508
- /* @__PURE__ */ jsx(IconButton, { type: "button", onClick: handleRemove, children: /* @__PURE__ */ jsx(LuIcon, { icon: "trash" }) })
34951
+ /* @__PURE__ */ jsx(CreateFieldDropdownMenu, { onSelectFieldType: handleAddField, children: /* @__PURE__ */ jsx(IconButton, { type: "button", children: /* @__PURE__ */ jsx(LuIcon, { icon: Plus }) }) }),
34952
+ /* @__PURE__ */ jsx(IconButton, { type: "button", onClick: handleMoveUp, children: /* @__PURE__ */ jsx(LuIcon, { icon: MoveUp }) }),
34953
+ /* @__PURE__ */ jsx(IconButton, { type: "button", onClick: handleMoveDown, children: /* @__PURE__ */ jsx(LuIcon, { icon: MoveDown }) }),
34954
+ /* @__PURE__ */ jsx(IconButton, { type: "button", onClick: duplicateField, children: /* @__PURE__ */ jsx(LuIcon, { icon: Copy }) }),
34955
+ /* @__PURE__ */ jsx(IconButton, { type: "button", onClick: handleUploadImage, children: /* @__PURE__ */ jsx(LuIcon, { icon: Image }) }),
34956
+ /* @__PURE__ */ jsx(IconButton, { type: "button", onClick: handleRemove, children: /* @__PURE__ */ jsx(LuIcon, { icon: Trash }) })
33509
34957
  ] }),
33510
34958
  /* @__PURE__ */ jsx("input", { className: "hidden", ref: fileInputRef, type: "file", accept: "image/*", onChange: uploadImage })
33511
34959
  ] });
33512
34960
  });
33513
- FieldWithActions.displayName = "FieldWithActions";
34961
+ FieldBuilderWithActions.displayName = "FieldBuilderWithActions";
34962
+ const FieldDropdownMenu = memo((props) => {
34963
+ const { children, variant, size, accentColor, fields, onSelectField, ...rest } = props;
34964
+ return /* @__PURE__ */ jsxs(Menu.Root, { ...rest, children: [
34965
+ /* @__PURE__ */ jsx(Menu.ClickTrigger, { children }),
34966
+ /* @__PURE__ */ jsx(Menu.Content, { variant, size, accentColor, children: /* @__PURE__ */ jsx(Menu.Scroll, { children: fields.map((field) => {
34967
+ return /* @__PURE__ */ jsxs(Menu.Item, { onSelect: () => onSelectField(field), children: [
34968
+ /* @__PURE__ */ jsx(LuIcon, { icon: fieldIcons[field.type] }),
34969
+ field.label || UNLABELLED_FIELD_LABEL
34970
+ ] }, field.identifier);
34971
+ }) }) })
34972
+ ] });
34973
+ });
34974
+ FieldDropdownMenu.displayName = "IssueDataFilterMenu";
34975
+ const FieldSectionDropdownMenu = memo((props) => {
34976
+ const { children, variant, size, accentColor, fieldSections, onSelectFieldCondition, ...rest } = props;
34977
+ return /* @__PURE__ */ jsxs(Menu.Root, { ...rest, children: [
34978
+ /* @__PURE__ */ jsx(Menu.ClickTrigger, { children }),
34979
+ /* @__PURE__ */ jsx(Menu.Content, { variant, size, accentColor, children: fieldSections.map((fieldSection) => {
34980
+ return /* @__PURE__ */ jsxs(Menu.Item, { onSelect: () => onSelectFieldCondition(fieldSection), children: [
34981
+ /* @__PURE__ */ jsx(LuIcon, { icon: fieldIcons[fieldSection.type] }),
34982
+ fieldSection.label || UNLABELLED_SECTION_LABEL
34983
+ ] }, fieldSection.identifier);
34984
+ }) })
34985
+ ] });
34986
+ });
34987
+ FieldSectionDropdownMenu.displayName = "IssueDataFilterMenu";
33514
34988
  const FieldSectionConditionEdgeComponent = memo((props) => {
33515
34989
  const { id, sourceX, sourceY, targetX, targetY, style, markerEnd, data } = props;
33516
34990
  const { targetSection, sourceSection, layoutDirection } = data;
@@ -33564,7 +35038,7 @@ const FieldSectionConditionEdgeComponent = memo((props) => {
33564
35038
  variant: "surface",
33565
35039
  size: "xs",
33566
35040
  accentColor: "base",
33567
- children: /* @__PURE__ */ jsx(LuIcon, { icon: "plus" })
35041
+ children: /* @__PURE__ */ jsx(LuIcon, { icon: Plus })
33568
35042
  }
33569
35043
  ) }),
33570
35044
  /* @__PURE__ */ jsxs(Tooltip.Root, { children: [
@@ -33578,7 +35052,7 @@ const FieldSectionConditionEdgeComponent = memo((props) => {
33578
35052
  accentColor: "base",
33579
35053
  color: "danger",
33580
35054
  onClick: handleDelete,
33581
- children: /* @__PURE__ */ jsx(LuIcon, { icon: "trash" })
35055
+ children: /* @__PURE__ */ jsx(LuIcon, { icon: Trash })
33582
35056
  }
33583
35057
  ) }),
33584
35058
  /* @__PURE__ */ jsx(Tooltip.Content, { size: "sm", children: "Remove conditional logic" })
@@ -33594,27 +35068,14 @@ const FieldSectionConditionEdgeComponent = memo((props) => {
33594
35068
  ] });
33595
35069
  });
33596
35070
  FieldSectionConditionEdgeComponent.displayName = "FieldSectionConditionEdgeComponent";
33597
- const useFieldTypeItems = (onSelect = () => null) => {
33598
- return useMemo(() => {
33599
- const entries = Object.entries(FieldTypeToClsMapping);
33600
- return entries.map(([type, fieldClass]) => ({
33601
- children: fieldClass.fieldTypeName,
33602
- icon: /* @__PURE__ */ jsx(LuIcon, { icon: fieldIcons[type] }),
33603
- value: type,
33604
- onSelect: () => {
33605
- onSelect(type);
33606
- }
33607
- }));
33608
- }, [onSelect]);
33609
- };
33610
35071
  const FieldSectionNodeComponent = memo((props) => {
33611
35072
  const { data, selected } = props;
33612
35073
  const { fieldSection, index: sectionIndex, layoutDirection } = data;
33613
35074
  const fieldSchema = use(FieldSchemaContext);
33614
- const removeSection = useCallback(() => {
35075
+ const handleRemoveSection = useCallback(() => {
33615
35076
  fieldSchema.removeFieldSection(fieldSection);
33616
35077
  }, [fieldSchema, fieldSection]);
33617
- const addField = useCallback(
35078
+ const handleAddField = useCallback(
33618
35079
  (type) => {
33619
35080
  fieldSection.addField(createField(type));
33620
35081
  },
@@ -33628,13 +35089,6 @@ const FieldSectionNodeComponent = memo((props) => {
33628
35089
  const handleDuplicate = useCallback(() => {
33629
35090
  fieldSchema.addFieldSection(fieldSection.duplicate(v4()));
33630
35091
  }, [fieldSchema, fieldSection]);
33631
- const fieldTypeItems = useFieldTypeItems(addField);
33632
- const removeField = useCallback(
33633
- (field) => {
33634
- fieldSection.removeField(field);
33635
- },
33636
- [fieldSection]
33637
- );
33638
35092
  return /* @__PURE__ */ jsxs(
33639
35093
  Card,
33640
35094
  {
@@ -33668,25 +35122,18 @@ const FieldSectionNodeComponent = memo((props) => {
33668
35122
  ] }),
33669
35123
  /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
33670
35124
  /* @__PURE__ */ jsx(Text, { weight: "bold", children: "Fields" }),
33671
- /* @__PURE__ */ jsxs(Menu.Root, { children: [
33672
- /* @__PURE__ */ jsx(Menu.ClickTrigger, { children: /* @__PURE__ */ jsxs(Button, { type: "button", variant: "soft", size: "sm", accentColor: "base", children: [
33673
- /* @__PURE__ */ jsx(LuIcon, { icon: "plus" }),
33674
- " Add field"
33675
- ] }) }),
33676
- /* @__PURE__ */ jsx(Menu.Content, { children: /* @__PURE__ */ jsx(Menu.Scroll, { children: fieldTypeItems.flat().map((item) => /* @__PURE__ */ jsxs(Menu.Item, { onSelect: item.onSelect, children: [
33677
- item.icon,
33678
- item.children
33679
- ] }, item.value)) }) })
33680
- ] })
35125
+ /* @__PURE__ */ jsx(CreateFieldDropdownMenu, { onSelectFieldType: handleAddField, children: /* @__PURE__ */ jsxs(Button, { type: "button", variant: "soft", size: "sm", accentColor: "base", children: [
35126
+ /* @__PURE__ */ jsx(LuIcon, { icon: Plus }),
35127
+ " Add field"
35128
+ ] }) })
33681
35129
  ] }),
33682
35130
  /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-3", children: fieldSection.fields.map((child, index) => /* @__PURE__ */ jsx(
33683
- FieldWithActions,
35131
+ FieldBuilderWithActions,
33684
35132
  {
33685
35133
  field: child,
33686
35134
  fieldSection,
33687
- index,
33688
- sectionIndex,
33689
- remove: removeField
35135
+ fieldIndex: index,
35136
+ sectionIndex
33690
35137
  },
33691
35138
  child.identifier
33692
35139
  )) })
@@ -33707,9 +35154,9 @@ const FieldSectionNodeComponent = memo((props) => {
33707
35154
  size: "xs",
33708
35155
  onClick: (e) => e.stopPropagation(),
33709
35156
  children: /* @__PURE__ */ jsxs(ButtonGroup, { className: "flex flex-col gap-2", variant: "surface", size: "xs", accentColor: "base", children: [
33710
- /* @__PURE__ */ jsx(IconButton, { type: "button", onClick: handleAddBranch, children: /* @__PURE__ */ jsx(LuIcon, { icon: "git-branch" }) }),
33711
- /* @__PURE__ */ jsx(IconButton, { type: "button", onClick: handleDuplicate, children: /* @__PURE__ */ jsx(LuIcon, { icon: "copy" }) }),
33712
- /* @__PURE__ */ jsx(IconButton, { type: "button", onClick: removeSection, children: /* @__PURE__ */ jsx(LuIcon, { icon: "trash" }) })
35157
+ /* @__PURE__ */ jsx(IconButton, { type: "button", onClick: handleAddBranch, children: /* @__PURE__ */ jsx(LuIcon, { icon: GitBranch }) }),
35158
+ /* @__PURE__ */ jsx(IconButton, { type: "button", onClick: handleDuplicate, children: /* @__PURE__ */ jsx(LuIcon, { icon: Copy }) }),
35159
+ /* @__PURE__ */ jsx(IconButton, { type: "button", onClick: handleRemoveSection, children: /* @__PURE__ */ jsx(LuIcon, { icon: Trash }) })
33713
35160
  ] })
33714
35161
  }
33715
35162
  )
@@ -33926,7 +35373,7 @@ const FormBuilderFlowBuilder = memo(() => {
33926
35373
  }
33927
35374
  ),
33928
35375
  /* @__PURE__ */ jsx(Panel, { position: "top-left", children: /* @__PURE__ */ jsx(ButtonGroup, { className: "flex items-center justify-end gap-2", size: "sm", children: /* @__PURE__ */ jsxs(Button, { type: "button", variant: "surface", onClick: handleAddSection, children: [
33929
- /* @__PURE__ */ jsx(LuIcon, { icon: "plus" }),
35376
+ /* @__PURE__ */ jsx(LuIcon, { icon: Plus }),
33930
35377
  " Add section"
33931
35378
  ] }) }) }),
33932
35379
  /* @__PURE__ */ jsxs(Panel, { position: "top-right", className: "flex flex-col items-center gap-2", children: [
@@ -33940,16 +35387,16 @@ const FormBuilderFlowBuilder = memo(() => {
33940
35387
  value: layoutDirection,
33941
35388
  onValueChange: setLayoutDirection,
33942
35389
  children: [
33943
- /* @__PURE__ */ jsx(ToggleGroup.IconItem, { className: "rounded-b-none", value: "LR", type: "button", children: /* @__PURE__ */ jsx(LuIcon, { icon: "arrow-right-left" }) }),
33944
- /* @__PURE__ */ jsx(ToggleGroup.IconItem, { className: "rounded-t-none", value: "TB", type: "button", children: /* @__PURE__ */ jsx(LuIcon, { icon: "arrow-down-up" }) })
35390
+ /* @__PURE__ */ jsx(ToggleGroup.IconItem, { className: "rounded-b-none", value: "LR", type: "button", children: /* @__PURE__ */ jsx(LuIcon, { icon: ArrowLeftRight }) }),
35391
+ /* @__PURE__ */ jsx(ToggleGroup.IconItem, { className: "rounded-t-none", value: "TB", type: "button", children: /* @__PURE__ */ jsx(LuIcon, { icon: ArrowDownUp }) })
33945
35392
  ]
33946
35393
  }
33947
35394
  ),
33948
35395
  /* @__PURE__ */ jsx(Separator, { size: "sm" }),
33949
35396
  /* @__PURE__ */ jsxs(ButtonGroup, { className: "flex flex-col ", size: "sm", accentColor: "base", variant: "soft", children: [
33950
- /* @__PURE__ */ jsx(IconButton, { className: "rounded-b-none", onClick: () => reactFlow == null ? void 0 : reactFlow.zoomIn(), type: "button", children: /* @__PURE__ */ jsx(LuIcon, { icon: "plus" }) }),
33951
- /* @__PURE__ */ jsx(IconButton, { onClick: () => reactFlow == null ? void 0 : reactFlow.zoomOut(), radius: "none", type: "button", children: /* @__PURE__ */ jsx(LuIcon, { icon: "minus" }) }),
33952
- /* @__PURE__ */ jsx(IconButton, { className: "rounded-t-none", onClick: () => reactFlow == null ? void 0 : reactFlow.fitView(), type: "button", children: /* @__PURE__ */ jsx(LuIcon, { icon: "square-dashed" }) })
35397
+ /* @__PURE__ */ jsx(IconButton, { className: "rounded-b-none", onClick: () => reactFlow == null ? void 0 : reactFlow.zoomIn(), type: "button", children: /* @__PURE__ */ jsx(LuIcon, { icon: Plus }) }),
35398
+ /* @__PURE__ */ jsx(IconButton, { onClick: () => reactFlow == null ? void 0 : reactFlow.zoomOut(), radius: "none", type: "button", children: /* @__PURE__ */ jsx(LuIcon, { icon: Minus }) }),
35399
+ /* @__PURE__ */ jsx(IconButton, { className: "rounded-t-none", onClick: () => reactFlow == null ? void 0 : reactFlow.fitView(), type: "button", children: /* @__PURE__ */ jsx(LuIcon, { icon: SquareDashed }) })
33953
35400
  ] })
33954
35401
  ] }),
33955
35402
  /* @__PURE__ */ jsx(Panel, { position: "bottom-right", children: /* @__PURE__ */ jsxs(ButtonGroup, { className: "flex items-center justify-end gap-2", size: "sm", children: [
@@ -33987,7 +35434,7 @@ const FieldSectionConditionalItem = memo((props) => {
33987
35434
  /* @__PURE__ */ jsx(LuIcon, { icon: fieldIcons.section }),
33988
35435
  sourceFieldSection.label ?? UNLABELLED_SECTION_LABEL
33989
35436
  ] }),
33990
- /* @__PURE__ */ jsx(IconButton, { type: "button", onClick: handleDelete, variant: "ghost", children: /* @__PURE__ */ jsx(LuIcon, { icon: "trash" }) })
35437
+ /* @__PURE__ */ jsx(IconButton, { type: "button", onClick: handleDelete, variant: "ghost", children: /* @__PURE__ */ jsx(LuIcon, { icon: Trash }) })
33991
35438
  ] }),
33992
35439
  /* @__PURE__ */ jsxs("div", { className: "flex h-max w-full flex-wrap gap-2", children: [
33993
35440
  conditions.map((condition) => {
@@ -33995,7 +35442,7 @@ const FieldSectionConditionalItem = memo((props) => {
33995
35442
  onRemove: handleDeleteCondition
33996
35443
  });
33997
35444
  }),
33998
- /* @__PURE__ */ jsx(FieldDropdownMenu, { fields: sourceFieldSection.fields, onSelectField: handleSelectField, align: "start", children: /* @__PURE__ */ jsx(IconButton, { type: "button", size: "sm", variant: "soft", accentColor: "base", children: /* @__PURE__ */ jsx(LuIcon, { icon: "plus" }) }) })
35445
+ /* @__PURE__ */ jsx(FieldDropdownMenu, { fields: sourceFieldSection.fields, onSelectField: handleSelectField, align: "start", children: /* @__PURE__ */ jsx(IconButton, { type: "button", size: "sm", variant: "soft", accentColor: "base", children: /* @__PURE__ */ jsx(LuIcon, { icon: Plus }) }) })
33999
35446
  ] })
34000
35447
  ] });
34001
35448
  });
@@ -34057,7 +35504,7 @@ const FieldSectionBuilder = memo((props) => {
34057
35504
  fieldSections: validFieldSections,
34058
35505
  onSelectFieldCondition: handleAddConditional,
34059
35506
  children: /* @__PURE__ */ jsxs(Button, { type: "button", variant: "soft", size: "sm", className: "w-max", children: [
34060
- /* @__PURE__ */ jsx(LuIcon, { icon: "plus" }),
35507
+ /* @__PURE__ */ jsx(LuIcon, { icon: Plus }),
34061
35508
  "Add condition"
34062
35509
  ] })
34063
35510
  }
@@ -34077,15 +35524,9 @@ const FieldSectionBuilder = memo((props) => {
34077
35524
  });
34078
35525
  FieldSectionBuilder.displayName = "FieldSectionBuilder";
34079
35526
  const FieldSectionWithActions = memo((props) => {
34080
- const { fieldSection, index: sectionIndex } = props;
35527
+ const { fieldSection, sectionIndex } = props;
34081
35528
  const fieldSchema = use(FieldSchemaContext);
34082
- const removeField = useCallback(
34083
- (field) => {
34084
- fieldSection.removeField(field);
34085
- },
34086
- [fieldSection]
34087
- );
34088
- const removeSection = useCallback(() => {
35529
+ const handleRemoveSection = useCallback(() => {
34089
35530
  fieldSchema.removeFieldSection(fieldSection);
34090
35531
  }, [fieldSchema, fieldSection]);
34091
35532
  const moveSection = useCallback(
@@ -34098,7 +35539,7 @@ const FieldSectionWithActions = memo((props) => {
34098
35539
  const duplicateSection = useCallback(() => {
34099
35540
  fieldSchema.addFieldSection(fieldSection.duplicate(v4()));
34100
35541
  }, [fieldSchema, fieldSection]);
34101
- const handleCreateField = useCallback(
35542
+ const handleAddField = useCallback(
34102
35543
  (type) => {
34103
35544
  fieldSection.addField(createField(type));
34104
35545
  },
@@ -34110,42 +35551,34 @@ const FieldSectionWithActions = memo((props) => {
34110
35551
  const handleMoveDown = useCallback(() => {
34111
35552
  moveSection("down");
34112
35553
  }, [moveSection]);
34113
- const fieldTypeItems = useFieldTypeItems(handleCreateField);
34114
35554
  return /* @__PURE__ */ jsxs(Card, { variant: "outline", className: "flex items-center justify-between gap-4 w-full", children: [
34115
35555
  /* @__PURE__ */ jsxs("div", { className: "flex grow flex-col gap-4 w-full", children: [
34116
35556
  /* @__PURE__ */ jsx(FieldSectionBuilder, { fieldSection }),
34117
35557
  /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2 w-full", children: [
34118
35558
  /* @__PURE__ */ jsxs("div", { className: "flex gap-2 justify-between", children: [
34119
35559
  /* @__PURE__ */ jsx(Text, { accentColor: "base", size: "md", children: "Fields" }),
34120
- /* @__PURE__ */ jsxs(Menu.Root, { children: [
34121
- /* @__PURE__ */ jsx(Menu.ClickTrigger, { children: /* @__PURE__ */ jsxs(Button, { type: "button", variant: "soft", size: "sm", children: [
34122
- /* @__PURE__ */ jsx(LuIcon, { icon: "plus" }),
34123
- " Add field"
34124
- ] }) }),
34125
- /* @__PURE__ */ jsx(Menu.Content, { children: /* @__PURE__ */ jsx(Menu.Scroll, { children: fieldTypeItems.flat().map((item) => /* @__PURE__ */ jsxs(Menu.Item, { onSelect: item.onSelect, children: [
34126
- item.icon,
34127
- item.children
34128
- ] }, item.value)) }) })
34129
- ] })
35560
+ /* @__PURE__ */ jsx(CreateFieldDropdownMenu, { onSelectFieldType: handleAddField, children: /* @__PURE__ */ jsxs(Button, { type: "button", variant: "soft", size: "sm", children: [
35561
+ /* @__PURE__ */ jsx(LuIcon, { icon: Plus }),
35562
+ " Add field"
35563
+ ] }) })
34130
35564
  ] }),
34131
35565
  fieldSection.fields.map((child, index) => /* @__PURE__ */ jsx(
34132
- FieldWithActions,
35566
+ FieldBuilderWithActions,
34133
35567
  {
34134
35568
  field: child,
34135
35569
  fieldSection,
34136
- index,
34137
- sectionIndex,
34138
- remove: removeField
35570
+ fieldIndex: index,
35571
+ sectionIndex
34139
35572
  },
34140
35573
  child.identifier
34141
35574
  ))
34142
35575
  ] })
34143
35576
  ] }),
34144
35577
  /* @__PURE__ */ jsxs(ButtonGroup, { className: "flex-col gap-0.5 flex", variant: "ghost", accentColor: "base", size: "sm", children: [
34145
- /* @__PURE__ */ jsx(IconButton, { type: "button", onClick: handleMoveUp, children: /* @__PURE__ */ jsx(LuIcon, { icon: "move-up" }) }),
34146
- /* @__PURE__ */ jsx(IconButton, { type: "button", onClick: handleMoveDown, children: /* @__PURE__ */ jsx(LuIcon, { icon: "move-down" }) }),
34147
- /* @__PURE__ */ jsx(IconButton, { type: "button", onClick: duplicateSection, children: /* @__PURE__ */ jsx(LuIcon, { icon: "copy" }) }),
34148
- /* @__PURE__ */ jsx(IconButton, { type: "button", onClick: removeSection, children: /* @__PURE__ */ jsx(LuIcon, { icon: "trash" }) })
35578
+ /* @__PURE__ */ jsx(IconButton, { type: "button", onClick: handleMoveUp, children: /* @__PURE__ */ jsx(LuIcon, { icon: MoveUp }) }),
35579
+ /* @__PURE__ */ jsx(IconButton, { type: "button", onClick: handleMoveDown, children: /* @__PURE__ */ jsx(LuIcon, { icon: MoveDown }) }),
35580
+ /* @__PURE__ */ jsx(IconButton, { type: "button", onClick: duplicateSection, children: /* @__PURE__ */ jsx(LuIcon, { icon: Copy }) }),
35581
+ /* @__PURE__ */ jsx(IconButton, { type: "button", onClick: handleRemoveSection, children: /* @__PURE__ */ jsx(LuIcon, { icon: Trash }) })
34149
35582
  ] })
34150
35583
  ] });
34151
35584
  });
@@ -34194,7 +35627,14 @@ const FormBuilderListBuilder = memo(() => {
34194
35627
  }
34195
35628
  ),
34196
35629
  /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-4", children: [
34197
- fieldSchema.fieldSections.map((fieldSection, index) => /* @__PURE__ */ jsx(FieldSectionWithActions, { fieldSection, index }, fieldSection.identifier)),
35630
+ fieldSchema.fieldSections.map((fieldSection, index) => /* @__PURE__ */ jsx(
35631
+ FieldSectionWithActions,
35632
+ {
35633
+ fieldSection,
35634
+ sectionIndex: index
35635
+ },
35636
+ fieldSection.identifier
35637
+ )),
34198
35638
  /* @__PURE__ */ jsxs(
34199
35639
  Button,
34200
35640
  {
@@ -34205,7 +35645,7 @@ const FormBuilderListBuilder = memo(() => {
34205
35645
  size: "sm",
34206
35646
  onClick: handleCreateEmptySection,
34207
35647
  children: [
34208
- /* @__PURE__ */ jsx(LuIcon, { icon: "plus" }),
35648
+ /* @__PURE__ */ jsx(LuIcon, { icon: Plus }),
34209
35649
  " Add section"
34210
35650
  ]
34211
35651
  }
@@ -34241,53 +35681,28 @@ const validateFields = (fields, values) => {
34241
35681
  }
34242
35682
  if (Object.keys(errors).length > 0) return errors;
34243
35683
  };
34244
- const initializeFieldValues = (fields, values) => {
34245
- const ret = {};
34246
- for (const field of fields) {
34247
- const value = values[field.identifier];
34248
- ret[field.identifier] = value !== void 0 ? value : field.blankValue();
34249
- }
34250
- return ret;
34251
- };
34252
- const changedFieldValues = (fields, values1, values2) => {
34253
- const ret = {};
34254
- for (const field of fields) {
34255
- const value1 = values1[field.identifier];
34256
- const value2 = values2[field.identifier];
34257
- if (field.areValuesEqual(value1, value2)) continue;
34258
- ret[field.identifier] = value2;
34259
- }
34260
- return ret;
34261
- };
34262
- const unchangedFieldValues = (fields, values1, values2) => {
34263
- const ret = {};
35684
+ const cleanFields = (fields, values) => {
35685
+ const errors = {};
35686
+ const sectionElements = fields.filter((f) => f instanceof FieldSection);
34264
35687
  for (const field of fields) {
34265
- const value1 = values1[field.identifier];
34266
- const value2 = values2[field.identifier];
34267
- if (!field.areValuesEqual(value1, value2)) continue;
34268
- ret[field.identifier] = value2;
35688
+ if (field instanceof FieldSection) {
35689
+ const conditionalSections = sectionElements.filter((section) => field.identifier in section.conditions);
35690
+ const conditionMet = conditionalSections.length > 0 ? conditionalSections.some(
35691
+ (conditionalSection) => applyConditions(conditionalSection.getConditions(field.identifier), values)
35692
+ ) : true;
35693
+ if (conditionMet) continue;
35694
+ } else {
35695
+ if (!(field instanceof BaseField)) {
35696
+ throw new Error("Invalid field type");
35697
+ }
35698
+ const id = field.identifier;
35699
+ const error = field.getError(get(values, id));
35700
+ if (error) set(errors, id, error);
35701
+ }
34269
35702
  }
34270
- return ret;
34271
- };
34272
- const isArrayOfFiles = (value) => {
34273
- return Array.isArray(value) && value[0] instanceof File;
34274
- };
34275
- const separateFilesFromFieldValues = (values) => {
34276
- const files = {};
34277
- const newValues = {};
34278
- for (const key in values) {
34279
- const value = values[key];
34280
- if (value instanceof File) {
34281
- files[key] = [value];
34282
- } else if (isArrayOfFiles(value)) {
34283
- files[key] = value;
34284
- } else if (value !== void 0) {
34285
- newValues[key] = value;
34286
- }
34287
- }
34288
- return { values: newValues, files };
35703
+ if (Object.keys(errors).length > 0) return errors;
34289
35704
  };
34290
- const separateFilesFromFields = async (fields) => {
35705
+ const separateImagesFromFields = async (fields) => {
34291
35706
  const images = {};
34292
35707
  const newFields = [];
34293
35708
  for (const section of fields) {
@@ -34315,16 +35730,12 @@ const separateFilesFromFields = async (fields) => {
34315
35730
  }
34316
35731
  return { fields: newFields, images };
34317
35732
  };
34318
- async function awaitPromisesFromFieldValues(values) {
34319
- const valuesWithoutFiles = {};
35733
+ async function awaitFilesAndPromises(values) {
35734
+ const ret = {};
34320
35735
  for (const [key, value] of Object.entries(values)) {
34321
- if (Array.isArray(value) && value.some((item) => item instanceof UUIDPromise)) {
34322
- valuesWithoutFiles[key] = await Promise.all(value);
34323
- } else {
34324
- valuesWithoutFiles[key] = value;
34325
- }
35736
+ ret[key] = await Promise.all(value);
34326
35737
  }
34327
- return valuesWithoutFiles;
35738
+ return ret;
34328
35739
  }
34329
35740
  const FormRenderer = memo(
34330
35741
  forwardRef((props, ref) => {
@@ -34420,13 +35831,13 @@ const FormRenderer = memo(
34420
35831
  variant: "soft",
34421
35832
  onClick: onCancel,
34422
35833
  children: [
34423
- /* @__PURE__ */ jsx(LuIcon, { icon: "x" }),
35834
+ /* @__PURE__ */ jsx(LuIcon, { icon: X }),
34424
35835
  cancelText
34425
35836
  ]
34426
35837
  }
34427
35838
  ),
34428
35839
  /* @__PURE__ */ jsxs(Button, { ...buttonProps, type: "submit", accentColor: "primary", variant: "surface", children: [
34429
- /* @__PURE__ */ jsx(LuIcon, { icon: "check" }),
35840
+ /* @__PURE__ */ jsx(LuIcon, { icon: Check }),
34430
35841
  submitText
34431
35842
  ] })
34432
35843
  ] })
@@ -34562,6 +35973,7 @@ export {
34562
35973
  CheckboxListFieldCondition,
34563
35974
  CheckboxListFieldConditionCell,
34564
35975
  CheckboxListInput,
35976
+ ConditionManager,
34565
35977
  DateAfterConditionModifier,
34566
35978
  DateBeforeConditionModifier,
34567
35979
  DateEqualsConditionModifier,
@@ -34612,10 +36024,23 @@ export {
34612
36024
  OTPFieldCondition,
34613
36025
  OTPFieldConditionCell,
34614
36026
  OTPInput,
36027
+ Observable,
36028
+ PassFailArrayExcludesConditionModifier,
36029
+ PassFailArrayIncludesConditionModifier,
36030
+ PassFailEqualsConditionModifier,
36031
+ PassFailField,
36032
+ PassFailFieldCondition,
36033
+ PassFailFieldConditionCell,
36034
+ PassFailInput,
36035
+ PassFailNotEqualsConditionModifier,
34615
36036
  RadioField,
34616
36037
  RadioFieldCondition,
34617
36038
  RadioFieldConditionCell,
34618
36039
  RadioInput,
36040
+ RatingField,
36041
+ RatingFieldCondition,
36042
+ RatingFieldConditionCell,
36043
+ RatingInput,
34619
36044
  SEVERITY_COLOR_MAPPING,
34620
36045
  SHORT_TEXT_FIELD_MAX_LENGTH,
34621
36046
  ScanField,
@@ -34647,15 +36072,19 @@ export {
34647
36072
  TextFieldCondition,
34648
36073
  TextFieldConditionCell,
34649
36074
  TextInput,
36075
+ UUIDFile,
34650
36076
  UUIDPromise,
34651
36077
  UploadField,
34652
36078
  UploadFieldCondition,
34653
36079
  UploadFieldConditionCell,
34654
36080
  UploadInput,
34655
36081
  applyConditions,
34656
- awaitPromisesFromFieldValues,
36082
+ areFileAndPromiseArraysEqual,
36083
+ arePassFieldValuesEqual,
36084
+ awaitFilesAndPromises,
34657
36085
  changedFieldValues,
34658
36086
  cleanFieldValues,
36087
+ cleanFields,
34659
36088
  cleanSerializedFieldValues,
34660
36089
  createCondition,
34661
36090
  createConditionModifierConfig,
@@ -34667,18 +36096,28 @@ export {
34667
36096
  deserializeFieldValues,
34668
36097
  deserializeFields,
34669
36098
  deserializeOnlyFields,
36099
+ deserializePassFailFieldValue,
36100
+ extractFilesAndPromisesFromFieldValues,
34670
36101
  fieldIcons,
34671
36102
  flattenFields,
34672
36103
  getFieldsMapping,
34673
36104
  initializeFieldValues,
36105
+ insertFilesAndPromisesToFieldValues,
36106
+ isFileAndPromiseArray,
36107
+ isPassFailFieldStatus,
36108
+ isPassFailFieldValue,
36109
+ isSerializedPassFailFieldValue,
34674
36110
  isStringArray,
34675
36111
  maxFileSizeB,
34676
36112
  maxFileSizeKB,
34677
36113
  maxFileSizeMB,
34678
- separateFilesFromFieldValues,
34679
- separateFilesFromFields,
36114
+ passFailFieldStatusMapping,
36115
+ passFailFieldStatuses,
36116
+ separateImagesFromFields,
34680
36117
  serializeFieldValues,
36118
+ serializePassFailFieldValue,
34681
36119
  unchangedFieldValues,
36120
+ useConditionManager,
34682
36121
  useFieldInput,
34683
36122
  useFieldInputs,
34684
36123
  useFormikInput,