@overmap-ai/forms 1.0.32-react-flow-david-fixes.11 → 1.0.32-react-flow-david-fixes.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/form/builder/components/FieldBuilder.d.ts +1 -2
- package/dist/form/builder/components/index.d.ts +1 -2
- package/dist/form/conditions/DateFieldCondition/DateFieldCondition.d.ts +6 -6
- package/dist/form/conditions/NumberFieldCondition/NumberFieldCondition.d.ts +16 -16
- package/dist/form/conditions/OTPFieldCondition/OTPFieldCondition.d.ts +1 -1
- package/dist/form/conditions/OTPFieldCondition/typings.d.ts +1 -2
- package/dist/form/conditions/RadioFieldCondition/RadioFieldCondition.d.ts +4 -4
- package/dist/form/conditions/SelectFieldCondition/SelectFieldCondition.d.ts +4 -4
- package/dist/form/conditions/components/RemoveConditionButton.d.ts +1 -1
- package/dist/form/fields/BaseField/BaseField.d.ts +7 -5
- package/dist/form/fields/BaseField/index.d.ts +0 -1
- package/dist/form/fields/BaseField/typings.d.ts +2 -1
- package/dist/form/fields/BaseFormElement/BaseFormElement.d.ts +1 -2
- package/dist/form/fields/BaseFormElement/typings.d.ts +8 -2
- package/dist/form/fields/BaseStringField/BaseStringField.d.ts +5 -2
- package/dist/form/fields/BooleanField/BooleanField.d.ts +6 -2
- package/dist/form/fields/BooleanField/BooleanInput.d.ts +1 -1
- package/dist/form/fields/CheckboxListField/CheckboxListField.d.ts +5 -1
- package/dist/form/fields/CheckboxListField/CheckboxListInput.d.ts +1 -1
- package/dist/form/fields/DateField/DateField.d.ts +9 -6
- package/dist/form/fields/DateField/DateInput.d.ts +1 -1
- package/dist/form/fields/FieldSection/FieldSection.d.ts +3 -4
- package/dist/form/fields/FieldSection/FieldSectionLayout.d.ts +1 -1
- package/dist/form/fields/FieldSection/typings.d.ts +1 -1
- package/dist/form/fields/MultiSelectField/MultiSelectField.d.ts +5 -3
- package/dist/form/fields/MultiSelectField/MultiSelectInput.d.ts +1 -1
- package/dist/form/fields/MultiStringField/MultiStringField.d.ts +6 -4
- package/dist/form/fields/MultiStringField/MultiStringInput.d.ts +1 -1
- package/dist/form/fields/NumberField/NumberField.d.ts +11 -7
- package/dist/form/fields/NumberField/NumberInput.d.ts +1 -1
- package/dist/form/fields/OneTimePasswordField/OTPField.d.ts +6 -2
- package/dist/form/fields/OneTimePasswordField/OTPInput.d.ts +1 -1
- package/dist/form/fields/RadioField/RadioField.d.ts +9 -5
- package/dist/form/fields/RadioField/RadioInput.d.ts +1 -1
- package/dist/form/fields/ScanField/ScanField.d.ts +5 -1
- package/dist/form/fields/ScanField/ScanInput.d.ts +1 -1
- package/dist/form/fields/SelectField/SelectField.d.ts +9 -5
- package/dist/form/fields/SelectField/SelectInput.d.ts +1 -1
- package/dist/form/fields/StringField/StringField.d.ts +1 -1
- package/dist/form/fields/StringField/StringInput.d.ts +1 -1
- package/dist/form/fields/TextField/TextField.d.ts +1 -1
- package/dist/form/fields/TextField/TextInput.d.ts +1 -1
- package/dist/form/fields/UploadField/UploadField.d.ts +6 -4
- package/dist/form/fields/UploadField/UploadInput.d.ts +1 -1
- package/dist/form/fields/UploadField/utils.d.ts +2 -0
- package/dist/form/fields/_utils.d.ts +2 -0
- package/dist/form/fields/hooks.d.ts +398 -2
- package/dist/form/fields/index.d.ts +2 -0
- package/dist/form/fields/typings.d.ts +2 -10
- package/dist/form/fields/utils.d.ts +3 -1
- package/dist/form/index.d.ts +1 -1
- package/dist/form/typings.d.ts +1 -1
- package/dist/form/utils.d.ts +6 -7
- package/dist/forms.js +698 -567
- package/dist/forms.umd.cjs +698 -567
- package/package.json +1 -1
- package/dist/form/fields/BaseField/hooks.d.ts +0 -397
- /package/dist/form/builder/{components → list}/FieldSectionBuilder.d.ts +0 -0
- /package/dist/form/builder/{components → list}/FieldSectionWithActions.d.ts +0 -0
package/dist/forms.js
CHANGED
|
@@ -5,7 +5,7 @@ import { jsxs, jsx, Fragment } from "react/jsx-runtime";
|
|
|
5
5
|
import { Card, LuIcon, Text, Spinner, ButtonGroup, Tooltip, IconButton, Separator, Input, Badge, Checkbox, CheckboxGroup, Popover, Button, DayPicker, Menu, OneTimePasswordField, RadioGroup, TextArea, useToast, stopPropagation, Heading, HoverCard, ToggleGroup } from "@overmap-ai/blocks";
|
|
6
6
|
import { cx } from "class-variance-authority";
|
|
7
7
|
import * as React from "react";
|
|
8
|
-
import { memo, forwardRef,
|
|
8
|
+
import { memo, forwardRef, createContext, useContext, useState, useRef, useCallback, useMemo, useEffect, Fragment as Fragment$1, use, useLayoutEffect, useId as useId$1 } from "react";
|
|
9
9
|
import "@xyflow/react/dist/style.css";
|
|
10
10
|
import { getBezierPath, BaseEdge, EdgeLabelRenderer, NodeToolbar, Position, Handle, MarkerType, useNodesState, useEdgesState, ReactFlow, Panel } from "@xyflow/react";
|
|
11
11
|
import { useField, useFormikContext, useFormik, FormikProvider } from "formik";
|
|
@@ -19,8 +19,8 @@ import ReactDOM__default from "react-dom";
|
|
|
19
19
|
import { saveAs } from "file-saver";
|
|
20
20
|
import { DecodeHintType as DecodeHintType$2, useZxing } from "react-zxing";
|
|
21
21
|
import get from "lodash.get";
|
|
22
|
-
import set from "lodash.set";
|
|
23
22
|
import Dagre from "@dagrejs/dagre";
|
|
23
|
+
import set from "lodash.set";
|
|
24
24
|
const FileCard = memo(
|
|
25
25
|
forwardRef((props, ref) => {
|
|
26
26
|
const { file, className, error, rightSlot, ...rest } = props;
|
|
@@ -38,6 +38,14 @@ const SEVERITY_COLOR_MAPPING = {
|
|
|
38
38
|
info: "base",
|
|
39
39
|
success: "success"
|
|
40
40
|
};
|
|
41
|
+
function isStringArray(value) {
|
|
42
|
+
if (!Array.isArray(value)) return false;
|
|
43
|
+
return value.every((item) => typeof item === "string");
|
|
44
|
+
}
|
|
45
|
+
function isFilePromiseArray(value) {
|
|
46
|
+
if (!Array.isArray(value)) return false;
|
|
47
|
+
return value.every((item) => item instanceof Promise || item instanceof File);
|
|
48
|
+
}
|
|
41
49
|
class Observable {
|
|
42
50
|
constructor() {
|
|
43
51
|
__publicField(this, "observers", /* @__PURE__ */ new Set());
|
|
@@ -99,14 +107,8 @@ class BaseField extends BaseFormElement {
|
|
|
99
107
|
this.image = image;
|
|
100
108
|
this.fieldValidators = fieldValidators;
|
|
101
109
|
}
|
|
102
|
-
isBlank(value) {
|
|
103
|
-
return value === void 0;
|
|
104
|
-
}
|
|
105
|
-
isEqual(value1, value2) {
|
|
106
|
-
return value1 === value2;
|
|
107
|
-
}
|
|
108
110
|
getError(value) {
|
|
109
|
-
if (this.required && this.
|
|
111
|
+
if (this.required && this.isValueBlank(value)) {
|
|
110
112
|
return "This field is required.";
|
|
111
113
|
}
|
|
112
114
|
for (const validator of this.getFieldValidators()) {
|
|
@@ -142,59 +144,15 @@ class BaseField extends BaseFormElement {
|
|
|
142
144
|
this.fieldValidators = fieldValidators ?? this.fieldValidators;
|
|
143
145
|
super.setOptions(base);
|
|
144
146
|
}
|
|
147
|
+
isValueBlank(value) {
|
|
148
|
+
return this.areValuesEqual(value, this.blankValue());
|
|
149
|
+
}
|
|
145
150
|
getFieldValidators() {
|
|
146
151
|
return [...this.fieldValidators];
|
|
147
152
|
}
|
|
148
153
|
}
|
|
149
154
|
__publicField(BaseField, "fieldTypeName");
|
|
150
155
|
__publicField(BaseField, "fieldTypeDescription");
|
|
151
|
-
const useFormikInput = (props) => {
|
|
152
|
-
const { field, size, showInputOnly, onValuesChange, ...rest } = props;
|
|
153
|
-
const [fieldProps, meta, helpers] = useField(field.identifier);
|
|
154
|
-
const { touched } = meta;
|
|
155
|
-
const helpText = meta.error ?? field.description;
|
|
156
|
-
const severity = meta.error ? "danger" : void 0;
|
|
157
|
-
const inputId = field.identifier;
|
|
158
|
-
const labelId = `${inputId}-label`;
|
|
159
|
-
const label = field.required ? `${field.label} *` : field.label;
|
|
160
|
-
const fieldPropsWithValidation = useMemo(() => {
|
|
161
|
-
const handleChange = (value) => {
|
|
162
|
-
helpers.setValue(value, false).then();
|
|
163
|
-
onValuesChange == null ? void 0 : onValuesChange(field.identifier, value);
|
|
164
|
-
if (touched || !field.onlyValidateAfterTouched) {
|
|
165
|
-
helpers.setError(field.getError(value));
|
|
166
|
-
}
|
|
167
|
-
};
|
|
168
|
-
const handleBlur = (value) => {
|
|
169
|
-
void helpers.setTouched(true, false).then();
|
|
170
|
-
helpers.setError(field.getError(value));
|
|
171
|
-
};
|
|
172
|
-
return {
|
|
173
|
-
...fieldProps,
|
|
174
|
-
// name and value not being overridden
|
|
175
|
-
onChange: handleChange,
|
|
176
|
-
onBlur: handleBlur
|
|
177
|
-
};
|
|
178
|
-
}, [field, fieldProps, helpers, onValuesChange, touched]);
|
|
179
|
-
return [
|
|
180
|
-
{
|
|
181
|
-
helpText,
|
|
182
|
-
size,
|
|
183
|
-
severity,
|
|
184
|
-
inputId,
|
|
185
|
-
labelId,
|
|
186
|
-
label,
|
|
187
|
-
showInputOnly,
|
|
188
|
-
fieldProps: fieldPropsWithValidation,
|
|
189
|
-
helpers,
|
|
190
|
-
field,
|
|
191
|
-
touched
|
|
192
|
-
},
|
|
193
|
-
/* Props that should be spread on the html element representing the field */
|
|
194
|
-
{ ...rest, "aria-labelledby": labelId }
|
|
195
|
-
];
|
|
196
|
-
};
|
|
197
|
-
const EMPTY_ARRAY = [];
|
|
198
156
|
const InputWithHelpText = (props) => {
|
|
199
157
|
const { helpText, children, severity } = props;
|
|
200
158
|
const color = severity ? SEVERITY_COLOR_MAPPING[severity] : "base";
|
|
@@ -2304,14 +2262,70 @@ const InputWithLabelAndHelpText = (props) => {
|
|
|
2304
2262
|
const { children, ...restProps } = props;
|
|
2305
2263
|
return /* @__PURE__ */ jsx(InputWithHelpText, { ...restProps, children });
|
|
2306
2264
|
};
|
|
2265
|
+
const useFieldInput = (field, props) => {
|
|
2266
|
+
return useMemo(() => {
|
|
2267
|
+
if (!props || !field) return null;
|
|
2268
|
+
return field.render(props);
|
|
2269
|
+
}, [field, props]);
|
|
2270
|
+
};
|
|
2271
|
+
const useFieldInputs = (fields, props) => {
|
|
2272
|
+
return /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-4", children: fields.map((field) => {
|
|
2273
|
+
return /* @__PURE__ */ jsx(Fragment$1, { children: field.render(props) }, field.identifier);
|
|
2274
|
+
}) });
|
|
2275
|
+
};
|
|
2276
|
+
const useFormikInput = (props) => {
|
|
2277
|
+
const { field, size, showInputOnly, onValuesChange, ...rest } = props;
|
|
2278
|
+
const [fieldProps, meta, helpers] = useField(field.identifier);
|
|
2279
|
+
const { touched } = meta;
|
|
2280
|
+
const helpText = meta.error ?? field.description;
|
|
2281
|
+
const severity = meta.error ? "danger" : void 0;
|
|
2282
|
+
const inputId = field.identifier;
|
|
2283
|
+
const labelId = `${inputId}-label`;
|
|
2284
|
+
const label = field.required ? `${field.label} *` : field.label;
|
|
2285
|
+
const fieldPropsWithValidation = useMemo(() => {
|
|
2286
|
+
const handleChange = (value) => {
|
|
2287
|
+
helpers.setValue(value, false).then();
|
|
2288
|
+
onValuesChange == null ? void 0 : onValuesChange(field.identifier, value);
|
|
2289
|
+
if (touched || !field.onlyValidateAfterTouched) {
|
|
2290
|
+
helpers.setError(field.getError(value));
|
|
2291
|
+
}
|
|
2292
|
+
};
|
|
2293
|
+
const handleBlur = (value) => {
|
|
2294
|
+
void helpers.setTouched(true, false).then();
|
|
2295
|
+
helpers.setError(field.getError(value));
|
|
2296
|
+
};
|
|
2297
|
+
return {
|
|
2298
|
+
...fieldProps,
|
|
2299
|
+
// name and value not being overridden
|
|
2300
|
+
onChange: handleChange,
|
|
2301
|
+
onBlur: handleBlur
|
|
2302
|
+
};
|
|
2303
|
+
}, [field, fieldProps, helpers, onValuesChange, touched]);
|
|
2304
|
+
return [
|
|
2305
|
+
{
|
|
2306
|
+
helpText,
|
|
2307
|
+
size,
|
|
2308
|
+
severity,
|
|
2309
|
+
inputId,
|
|
2310
|
+
labelId,
|
|
2311
|
+
label,
|
|
2312
|
+
showInputOnly,
|
|
2313
|
+
fieldProps: fieldPropsWithValidation,
|
|
2314
|
+
helpers,
|
|
2315
|
+
field,
|
|
2316
|
+
touched
|
|
2317
|
+
},
|
|
2318
|
+
/* Props that should be spread on the html element representing the field */
|
|
2319
|
+
{ ...rest, "aria-labelledby": labelId }
|
|
2320
|
+
];
|
|
2321
|
+
};
|
|
2307
2322
|
const MultiStringInput = memo((props) => {
|
|
2308
2323
|
const [{ inputId, labelId, size, severity, showInputOnly, field, helpText, label, fieldProps }, rest] = useFormikInput(props);
|
|
2309
2324
|
const computedHelpText = showInputOnly ? null : helpText;
|
|
2310
2325
|
const computedLabel = showInputOnly ? "" : label;
|
|
2311
|
-
const { name, onChange, onBlur } = fieldProps;
|
|
2326
|
+
const { value, name, onChange, onBlur } = fieldProps;
|
|
2312
2327
|
const droppableId = `${inputId}-droppable`;
|
|
2313
2328
|
const { disabled } = rest;
|
|
2314
|
-
const value = fieldProps.value ?? EMPTY_ARRAY;
|
|
2315
2329
|
const [intermediateValue, setIntermediateValue] = useState("");
|
|
2316
2330
|
const [internalError, setInternalError] = useState("");
|
|
2317
2331
|
const updatedHelpText = internalError || computedHelpText;
|
|
@@ -2525,14 +2539,6 @@ const _MultiStringField = class _MultiStringField extends BaseField {
|
|
|
2525
2539
|
deserializeValue(value) {
|
|
2526
2540
|
return value;
|
|
2527
2541
|
}
|
|
2528
|
-
isBlank(value) {
|
|
2529
|
-
return super.isBlank(value) || (value == null ? void 0 : value.length) === 0;
|
|
2530
|
-
}
|
|
2531
|
-
isEqual(value1, value2) {
|
|
2532
|
-
if (value1 === void 0 && value2 === void 0) return true;
|
|
2533
|
-
if (value1 === void 0 || value2 === void 0) return false;
|
|
2534
|
-
return value1.every((v) => value2.includes(v)) && value2.every((v) => value1.includes(v));
|
|
2535
|
-
}
|
|
2536
2542
|
getFieldValidators() {
|
|
2537
2543
|
const validators = super.getFieldValidators();
|
|
2538
2544
|
validators.push((value) => {
|
|
@@ -2550,6 +2556,18 @@ const _MultiStringField = class _MultiStringField extends BaseField {
|
|
|
2550
2556
|
static deserialize(data) {
|
|
2551
2557
|
return new _MultiStringField(data);
|
|
2552
2558
|
}
|
|
2559
|
+
isSerializedValueValid(value) {
|
|
2560
|
+
return isStringArray(value);
|
|
2561
|
+
}
|
|
2562
|
+
isValueValid(value) {
|
|
2563
|
+
return isStringArray(value);
|
|
2564
|
+
}
|
|
2565
|
+
blankValue() {
|
|
2566
|
+
return [];
|
|
2567
|
+
}
|
|
2568
|
+
areValuesEqual(value1, value2) {
|
|
2569
|
+
return value1.every((v) => value2.includes(v)) && value2.every((v) => value1.includes(v));
|
|
2570
|
+
}
|
|
2553
2571
|
};
|
|
2554
2572
|
__publicField(_MultiStringField, "fieldTypeName", "Multi-string");
|
|
2555
2573
|
__publicField(_MultiStringField, "fieldTypeDescription", "Allows the user to provide multiple unique strings.");
|
|
@@ -2655,10 +2673,6 @@ const _BooleanField = class _BooleanField extends BaseField {
|
|
|
2655
2673
|
__publicField(this, "type", "boolean");
|
|
2656
2674
|
__publicField(this, "onlyValidateAfterTouched", false);
|
|
2657
2675
|
}
|
|
2658
|
-
// if a BooleanField is required, `false` is considered blank
|
|
2659
|
-
isBlank(value) {
|
|
2660
|
-
return this.required && !value;
|
|
2661
|
-
}
|
|
2662
2676
|
serialize() {
|
|
2663
2677
|
return super.serialize();
|
|
2664
2678
|
}
|
|
@@ -2687,6 +2701,18 @@ const _BooleanField = class _BooleanField extends BaseField {
|
|
|
2687
2701
|
render(props) {
|
|
2688
2702
|
return /* @__PURE__ */ jsx(BooleanInput, { ...props, field: this });
|
|
2689
2703
|
}
|
|
2704
|
+
isSerializedValueValid(value) {
|
|
2705
|
+
return typeof value === "boolean";
|
|
2706
|
+
}
|
|
2707
|
+
isValueValid(value) {
|
|
2708
|
+
return typeof value === "boolean";
|
|
2709
|
+
}
|
|
2710
|
+
blankValue() {
|
|
2711
|
+
return false;
|
|
2712
|
+
}
|
|
2713
|
+
areValuesEqual(value1, value2) {
|
|
2714
|
+
return value1 === value2;
|
|
2715
|
+
}
|
|
2690
2716
|
};
|
|
2691
2717
|
__publicField(_BooleanField, "fieldTypeName", "Checkbox");
|
|
2692
2718
|
__publicField(_BooleanField, "fieldTypeDescription", "Perfect for both optional and required yes/no questions.");
|
|
@@ -2699,14 +2725,14 @@ const NumberInput = memo((props) => {
|
|
|
2699
2725
|
const { name, onBlur, onChange, value } = fieldProps;
|
|
2700
2726
|
const computedHelpText = showInputOnly ? null : helpText;
|
|
2701
2727
|
const computedLabel = showInputOnly ? "" : label;
|
|
2702
|
-
const [internalValue, setInternalValue] = useState(
|
|
2728
|
+
const [internalValue, setInternalValue] = useState(null);
|
|
2703
2729
|
useEffect(() => {
|
|
2704
2730
|
setInternalValue(value);
|
|
2705
2731
|
}, [value]);
|
|
2706
2732
|
const handleChange = useCallback(
|
|
2707
2733
|
(e) => {
|
|
2708
2734
|
const number = e.target.valueAsNumber;
|
|
2709
|
-
const value2 =
|
|
2735
|
+
const value2 = !isNaN(number) ? number : null;
|
|
2710
2736
|
setInternalValue(value2);
|
|
2711
2737
|
if (touched || !field.onlyValidateAfterTouched) {
|
|
2712
2738
|
helpers.setError(field.getError(value2));
|
|
@@ -2874,6 +2900,18 @@ const _NumberField = class _NumberField extends BaseField {
|
|
|
2874
2900
|
render(props) {
|
|
2875
2901
|
return /* @__PURE__ */ jsx(NumberInput, { field: this, ...props });
|
|
2876
2902
|
}
|
|
2903
|
+
isSerializedValueValid(value) {
|
|
2904
|
+
return typeof value === "number" || value === null;
|
|
2905
|
+
}
|
|
2906
|
+
isValueValid(value) {
|
|
2907
|
+
return typeof value === "number" || value === null;
|
|
2908
|
+
}
|
|
2909
|
+
areValuesEqual(value1, value2) {
|
|
2910
|
+
return value1 === value2;
|
|
2911
|
+
}
|
|
2912
|
+
blankValue() {
|
|
2913
|
+
return null;
|
|
2914
|
+
}
|
|
2877
2915
|
};
|
|
2878
2916
|
__publicField(_NumberField, "fieldTypeName", "Number");
|
|
2879
2917
|
__publicField(_NumberField, "fieldTypeDescription", "Allows specifying a number within a given range.");
|
|
@@ -2971,18 +3009,28 @@ class BaseStringField extends BaseField {
|
|
|
2971
3009
|
deserializeValue(value) {
|
|
2972
3010
|
return value;
|
|
2973
3011
|
}
|
|
3012
|
+
isSerializedValueValid(value) {
|
|
3013
|
+
return typeof value === "string";
|
|
3014
|
+
}
|
|
3015
|
+
isValueValid(value) {
|
|
3016
|
+
return typeof value === "string";
|
|
3017
|
+
}
|
|
3018
|
+
blankValue() {
|
|
3019
|
+
return "";
|
|
3020
|
+
}
|
|
3021
|
+
areValuesEqual(value1, value2) {
|
|
3022
|
+
return value1 === value2;
|
|
3023
|
+
}
|
|
2974
3024
|
}
|
|
2975
3025
|
const CheckboxListInput = memo((props) => {
|
|
2976
3026
|
const [{ inputId, labelId, size, severity, field, showInputOnly, helpText, label, fieldProps }, rest] = useFormikInput(props);
|
|
2977
|
-
const { name, onChange, onBlur } = fieldProps;
|
|
3027
|
+
const { value, name, onChange, onBlur } = fieldProps;
|
|
2978
3028
|
const computedHelpText = showInputOnly ? null : helpText;
|
|
2979
3029
|
const computedLabel = showInputOnly ? "" : label;
|
|
2980
|
-
const value = fieldProps.value ?? EMPTY_ARRAY;
|
|
2981
3030
|
const handleChange = useCallback(
|
|
2982
3031
|
(value2) => {
|
|
2983
|
-
|
|
2984
|
-
|
|
2985
|
-
onBlur(newValue);
|
|
3032
|
+
onChange(value2);
|
|
3033
|
+
onBlur(value2);
|
|
2986
3034
|
},
|
|
2987
3035
|
[onBlur, onChange]
|
|
2988
3036
|
);
|
|
@@ -3047,20 +3095,31 @@ const _CheckboxListField = class _CheckboxListField extends BaseOptionsField {
|
|
|
3047
3095
|
render(props) {
|
|
3048
3096
|
return /* @__PURE__ */ jsx(CheckboxListInput, { field: this, ...props });
|
|
3049
3097
|
}
|
|
3098
|
+
isSerializedValueValid(value) {
|
|
3099
|
+
return isStringArray(value);
|
|
3100
|
+
}
|
|
3101
|
+
isValueValid(value) {
|
|
3102
|
+
return isStringArray(value);
|
|
3103
|
+
}
|
|
3104
|
+
blankValue() {
|
|
3105
|
+
return [];
|
|
3106
|
+
}
|
|
3107
|
+
areValuesEqual(value1, value2) {
|
|
3108
|
+
return value1.every((v) => value2.includes(v)) && value2.every((v) => value1.includes(v));
|
|
3109
|
+
}
|
|
3050
3110
|
};
|
|
3051
3111
|
__publicField(_CheckboxListField, "fieldTypeName", "Checkbox list");
|
|
3052
3112
|
__publicField(_CheckboxListField, "fieldTypeDescription", "Allows the user to select a multiple options from a list.");
|
|
3053
3113
|
let CheckboxListField = _CheckboxListField;
|
|
3054
3114
|
const DateInput = memo((props) => {
|
|
3055
3115
|
const [{ inputId, labelId, size, severity, showInputOnly, field, helpText, label, fieldProps }, rest] = useFormikInput(props);
|
|
3056
|
-
const { name, onChange, onBlur } = fieldProps;
|
|
3116
|
+
const { value, name, onChange, onBlur } = fieldProps;
|
|
3057
3117
|
const [popoverOpen, setPopoverOpen] = useState(false);
|
|
3058
3118
|
const computedHelpText = showInputOnly ? null : helpText;
|
|
3059
3119
|
const computedLabel = showInputOnly ? "" : label;
|
|
3060
|
-
const value = fieldProps.value ? new Date(fieldProps.value) : void 0;
|
|
3061
3120
|
const handleValueChange = useCallback(
|
|
3062
3121
|
(date) => {
|
|
3063
|
-
onChange(date);
|
|
3122
|
+
onChange(date ?? null);
|
|
3064
3123
|
setPopoverOpen(false);
|
|
3065
3124
|
},
|
|
3066
3125
|
[onChange]
|
|
@@ -3109,7 +3168,7 @@ const DateInput = memo((props) => {
|
|
|
3109
3168
|
required: false,
|
|
3110
3169
|
mode: "single",
|
|
3111
3170
|
variant: "solid",
|
|
3112
|
-
selected: value,
|
|
3171
|
+
selected: value ?? void 0,
|
|
3113
3172
|
onSelect: handleValueChange
|
|
3114
3173
|
}
|
|
3115
3174
|
) })
|
|
@@ -3143,34 +3202,41 @@ const _DateField = class _DateField extends BaseField {
|
|
|
3143
3202
|
super.setOptions(options);
|
|
3144
3203
|
}
|
|
3145
3204
|
serializeValue(value) {
|
|
3146
|
-
return value.toISOString();
|
|
3205
|
+
return value ? value.toISOString() : null;
|
|
3147
3206
|
}
|
|
3148
3207
|
deserializeValue(value) {
|
|
3149
|
-
return new Date(value);
|
|
3150
|
-
}
|
|
3151
|
-
isEqual(value1, value2) {
|
|
3152
|
-
if (value1 === void 0 && value2 === void 0) return true;
|
|
3153
|
-
if (!value1 || !value2) return false;
|
|
3154
|
-
return value1.getTime() === value2.getTime();
|
|
3208
|
+
return value ? new Date(value) : null;
|
|
3155
3209
|
}
|
|
3156
3210
|
render(props) {
|
|
3157
3211
|
return /* @__PURE__ */ jsx(DateInput, { field: this, ...props });
|
|
3158
3212
|
}
|
|
3213
|
+
isSerializedValueValid(value) {
|
|
3214
|
+
return typeof value === "string" || value === null;
|
|
3215
|
+
}
|
|
3216
|
+
isValueValid(value) {
|
|
3217
|
+
return value instanceof Date || value === null;
|
|
3218
|
+
}
|
|
3219
|
+
blankValue() {
|
|
3220
|
+
return null;
|
|
3221
|
+
}
|
|
3222
|
+
areValuesEqual(value1, value2) {
|
|
3223
|
+
if (!value1 && !value2) return true;
|
|
3224
|
+
if (!value1 || !value2) return false;
|
|
3225
|
+
return value1.getTime() === value2.getTime();
|
|
3226
|
+
}
|
|
3159
3227
|
};
|
|
3160
3228
|
__publicField(_DateField, "fieldTypeName", "Date");
|
|
3161
3229
|
__publicField(_DateField, "fieldTypeDescription", "Allows specifying a date.");
|
|
3162
3230
|
let DateField = _DateField;
|
|
3163
3231
|
const MultiSelectInput = memo((props) => {
|
|
3164
3232
|
const [{ inputId, labelId, size, severity, showInputOnly, field, helpText, label, fieldProps }, rest] = useFormikInput(props);
|
|
3165
|
-
const { name, onChange, onBlur } = fieldProps;
|
|
3233
|
+
const { value, name, onChange, onBlur } = fieldProps;
|
|
3166
3234
|
const computedHelpText = showInputOnly ? null : helpText;
|
|
3167
3235
|
const computedLabel = showInputOnly ? "" : label;
|
|
3168
|
-
const value = fieldProps.value ?? EMPTY_ARRAY;
|
|
3169
3236
|
const handleChange = useCallback(
|
|
3170
3237
|
(value2) => {
|
|
3171
|
-
|
|
3172
|
-
|
|
3173
|
-
onBlur(newValue);
|
|
3238
|
+
onChange(value2);
|
|
3239
|
+
onBlur(value2);
|
|
3174
3240
|
},
|
|
3175
3241
|
[onBlur, onChange]
|
|
3176
3242
|
);
|
|
@@ -3237,14 +3303,6 @@ const _MultiSelectField = class _MultiSelectField extends BaseOptionsField {
|
|
|
3237
3303
|
__publicField(this, "placeholder");
|
|
3238
3304
|
this.placeholder = placeholder;
|
|
3239
3305
|
}
|
|
3240
|
-
isBlank(value) {
|
|
3241
|
-
return super.isBlank(value) || (value == null ? void 0 : value.length) === 0;
|
|
3242
|
-
}
|
|
3243
|
-
isEqual(value1, value2) {
|
|
3244
|
-
if (value1 === void 0 && value2 === void 0) return true;
|
|
3245
|
-
if (value1 === void 0 || value2 === void 0) return false;
|
|
3246
|
-
return value1.every((v) => value2.includes(v)) && value2.every((v) => value1.includes(v));
|
|
3247
|
-
}
|
|
3248
3306
|
serialize() {
|
|
3249
3307
|
return super.serialize();
|
|
3250
3308
|
}
|
|
@@ -3277,6 +3335,18 @@ const _MultiSelectField = class _MultiSelectField extends BaseOptionsField {
|
|
|
3277
3335
|
render(props) {
|
|
3278
3336
|
return /* @__PURE__ */ jsx(MultiSelectInput, { field: this, ...props });
|
|
3279
3337
|
}
|
|
3338
|
+
isSerializedValueValid(value) {
|
|
3339
|
+
return isStringArray(value);
|
|
3340
|
+
}
|
|
3341
|
+
isValueValid(value) {
|
|
3342
|
+
return isStringArray(value);
|
|
3343
|
+
}
|
|
3344
|
+
blankValue() {
|
|
3345
|
+
return [];
|
|
3346
|
+
}
|
|
3347
|
+
areValuesEqual(value1, value2) {
|
|
3348
|
+
return value1.every((v) => value2.includes(v)) && value2.every((v) => value1.includes(v));
|
|
3349
|
+
}
|
|
3280
3350
|
};
|
|
3281
3351
|
__publicField(_MultiSelectField, "fieldTypeName", "Multi-select");
|
|
3282
3352
|
__publicField(_MultiSelectField, "fieldTypeDescription", "Allows the user to select a multiple options from a list of options.");
|
|
@@ -3288,8 +3358,8 @@ const SelectInput = memo((props) => {
|
|
|
3288
3358
|
const computedLabel = showInputOnly ? "" : label;
|
|
3289
3359
|
const handleChange = useCallback(
|
|
3290
3360
|
(value2) => {
|
|
3291
|
-
onChange(value2);
|
|
3292
|
-
onBlur(value2);
|
|
3361
|
+
onChange(value2 ?? null);
|
|
3362
|
+
onBlur(value2 ?? null);
|
|
3293
3363
|
},
|
|
3294
3364
|
[onBlur, onChange]
|
|
3295
3365
|
);
|
|
@@ -3372,6 +3442,18 @@ const _SelectField = class _SelectField extends BaseOptionsField {
|
|
|
3372
3442
|
render(props) {
|
|
3373
3443
|
return /* @__PURE__ */ jsx(SelectInput, { field: this, ...props });
|
|
3374
3444
|
}
|
|
3445
|
+
isSerializedValueValid(value) {
|
|
3446
|
+
return typeof value === "string" || value === null;
|
|
3447
|
+
}
|
|
3448
|
+
isValueValid(value) {
|
|
3449
|
+
return typeof value === "string" || value === null;
|
|
3450
|
+
}
|
|
3451
|
+
blankValue() {
|
|
3452
|
+
return null;
|
|
3453
|
+
}
|
|
3454
|
+
areValuesEqual(value1, value2) {
|
|
3455
|
+
return value1 === value2;
|
|
3456
|
+
}
|
|
3375
3457
|
};
|
|
3376
3458
|
__publicField(_SelectField, "fieldTypeName", "Dropdown");
|
|
3377
3459
|
__publicField(_SelectField, "fieldTypeDescription", "Allows the user to select a single option from a list of options.");
|
|
@@ -3384,16 +3466,16 @@ const OTPInput = memo((props) => {
|
|
|
3384
3466
|
const { name, onBlur, onChange, value } = fieldProps;
|
|
3385
3467
|
const computedHelpText = showInputOnly ? null : helpText;
|
|
3386
3468
|
const computedLabel = showInputOnly ? "" : label;
|
|
3387
|
-
const [internalValue, setInternalValue] = useState();
|
|
3469
|
+
const [internalValue, setInternalValue] = useState("");
|
|
3388
3470
|
const inputUuids = useMemo(() => Array.from({ length: field.length }, () => v4()), [field.length]);
|
|
3389
3471
|
useEffect(() => {
|
|
3390
3472
|
setInternalValue(value);
|
|
3391
3473
|
}, [value]);
|
|
3392
3474
|
const handleChange = useCallback(
|
|
3393
3475
|
(value2) => {
|
|
3394
|
-
setInternalValue(value2
|
|
3476
|
+
setInternalValue(value2);
|
|
3395
3477
|
if (touched || !field.onlyValidateAfterTouched) {
|
|
3396
|
-
helpers.setError(field.getError(value2
|
|
3478
|
+
helpers.setError(field.getError(value2));
|
|
3397
3479
|
}
|
|
3398
3480
|
},
|
|
3399
3481
|
[field, helpers, touched]
|
|
@@ -3423,7 +3505,7 @@ const OTPInput = memo((props) => {
|
|
|
3423
3505
|
{
|
|
3424
3506
|
id: inputId,
|
|
3425
3507
|
name,
|
|
3426
|
-
value: internalValue
|
|
3508
|
+
value: internalValue,
|
|
3427
3509
|
onValueChange: handleChange,
|
|
3428
3510
|
validationType: field.validationType,
|
|
3429
3511
|
form: formId2,
|
|
@@ -3506,7 +3588,7 @@ const _OTPField = class _OTPField extends BaseField {
|
|
|
3506
3588
|
const validators = super.getFieldValidators();
|
|
3507
3589
|
const length = this.length;
|
|
3508
3590
|
validators.push((value) => {
|
|
3509
|
-
if (
|
|
3591
|
+
if (!this.isValueBlank(value) && (value.length < length || value.length > length)) {
|
|
3510
3592
|
return `Must be ${length} characters.`;
|
|
3511
3593
|
}
|
|
3512
3594
|
});
|
|
@@ -3550,6 +3632,18 @@ const _OTPField = class _OTPField extends BaseField {
|
|
|
3550
3632
|
render(props) {
|
|
3551
3633
|
return /* @__PURE__ */ jsx(OTPInput, { field: this, ...props });
|
|
3552
3634
|
}
|
|
3635
|
+
isSerializedValueValid(value) {
|
|
3636
|
+
return typeof value === "string";
|
|
3637
|
+
}
|
|
3638
|
+
isValueValid(value) {
|
|
3639
|
+
return typeof value === "string";
|
|
3640
|
+
}
|
|
3641
|
+
blankValue() {
|
|
3642
|
+
return "";
|
|
3643
|
+
}
|
|
3644
|
+
areValuesEqual(value1, value2) {
|
|
3645
|
+
return value1 === value2;
|
|
3646
|
+
}
|
|
3553
3647
|
};
|
|
3554
3648
|
__publicField(_OTPField, "fieldTypeName", "OTP");
|
|
3555
3649
|
__publicField(_OTPField, "fieldTypeDescription", "Allows specifying a number within a given range.");
|
|
@@ -3561,14 +3655,14 @@ const RadioInput = memo((props) => {
|
|
|
3561
3655
|
const computedLabel = showInputOnly ? "" : label;
|
|
3562
3656
|
const handleChange = useCallback(
|
|
3563
3657
|
(value2) => {
|
|
3564
|
-
onChange(value2
|
|
3565
|
-
onBlur(value2
|
|
3658
|
+
onChange(value2);
|
|
3659
|
+
onBlur(value2);
|
|
3566
3660
|
},
|
|
3567
3661
|
[onBlur, onChange]
|
|
3568
3662
|
);
|
|
3569
3663
|
const handleClear = useCallback(() => {
|
|
3570
|
-
onChange(
|
|
3571
|
-
onBlur(
|
|
3664
|
+
onChange(null);
|
|
3665
|
+
onBlur(null);
|
|
3572
3666
|
}, [onBlur, onChange]);
|
|
3573
3667
|
return /* @__PURE__ */ jsx(InputWithLabelAndHelpText, { helpText: computedHelpText, severity, children: /* @__PURE__ */ jsx(
|
|
3574
3668
|
InputWithLabel,
|
|
@@ -3651,6 +3745,18 @@ const _RadioField = class _RadioField extends BaseOptionsField {
|
|
|
3651
3745
|
render(props) {
|
|
3652
3746
|
return /* @__PURE__ */ jsx(RadioInput, { field: this, ...props });
|
|
3653
3747
|
}
|
|
3748
|
+
isSerializedValueValid(value) {
|
|
3749
|
+
return typeof value === "string" || value === "null";
|
|
3750
|
+
}
|
|
3751
|
+
isValueValid(value) {
|
|
3752
|
+
return typeof value === "string" || value === "null";
|
|
3753
|
+
}
|
|
3754
|
+
blankValue() {
|
|
3755
|
+
return null;
|
|
3756
|
+
}
|
|
3757
|
+
areValuesEqual(value1, value2) {
|
|
3758
|
+
return value1 === value2;
|
|
3759
|
+
}
|
|
3654
3760
|
};
|
|
3655
3761
|
__publicField(_RadioField, "fieldTypeName", "Option list");
|
|
3656
3762
|
__publicField(_RadioField, "fieldTypeDescription", "Allows the user to select a single option from a list of options.");
|
|
@@ -31751,15 +31857,16 @@ const ScanInput = memo((props) => {
|
|
|
31751
31857
|
const [showScanner, setShowScanner] = useState(false);
|
|
31752
31858
|
const computedHelpText = showInputOnly ? null : helpText;
|
|
31753
31859
|
const computedLabel = showInputOnly ? "" : label;
|
|
31754
|
-
const [internalValue, setInternalValue] = useState(
|
|
31860
|
+
const [internalValue, setInternalValue] = useState("");
|
|
31755
31861
|
useEffect(() => {
|
|
31756
31862
|
setInternalValue(value);
|
|
31757
31863
|
}, [value]);
|
|
31758
31864
|
const handleChange = useCallback(
|
|
31759
31865
|
(e) => {
|
|
31760
|
-
|
|
31866
|
+
const value2 = e.target.value;
|
|
31867
|
+
setInternalValue(value2);
|
|
31761
31868
|
if (touched || !field.onlyValidateAfterTouched) {
|
|
31762
|
-
helpers.setError(field.getError(
|
|
31869
|
+
helpers.setError(field.getError(value2));
|
|
31763
31870
|
}
|
|
31764
31871
|
},
|
|
31765
31872
|
[field, helpers, touched]
|
|
@@ -31804,7 +31911,7 @@ const ScanInput = memo((props) => {
|
|
|
31804
31911
|
size: "sm",
|
|
31805
31912
|
id: inputId,
|
|
31806
31913
|
name,
|
|
31807
|
-
value: internalValue
|
|
31914
|
+
value: internalValue,
|
|
31808
31915
|
placeholder: "Enter a qr or barcode",
|
|
31809
31916
|
onChange: handleChange,
|
|
31810
31917
|
onBlur: handleBlur,
|
|
@@ -31909,6 +32016,18 @@ const _ScanField = class _ScanField extends BaseField {
|
|
|
31909
32016
|
render(props) {
|
|
31910
32017
|
return /* @__PURE__ */ jsx(ScanInput, { ...props, field: this });
|
|
31911
32018
|
}
|
|
32019
|
+
isSerializedValueValid(value) {
|
|
32020
|
+
return typeof value === "string";
|
|
32021
|
+
}
|
|
32022
|
+
isValueValid(value) {
|
|
32023
|
+
return typeof value === "string";
|
|
32024
|
+
}
|
|
32025
|
+
blankValue() {
|
|
32026
|
+
return "";
|
|
32027
|
+
}
|
|
32028
|
+
areValuesEqual(value1, value2) {
|
|
32029
|
+
return value1 === value2;
|
|
32030
|
+
}
|
|
31912
32031
|
};
|
|
31913
32032
|
__publicField(_ScanField, "fieldTypeName", "Scan");
|
|
31914
32033
|
__publicField(_ScanField, "fieldTypeDescription", "Used for scanning/reading QR and barcodes.");
|
|
@@ -31922,15 +32041,16 @@ const StringInput = memo((props) => {
|
|
|
31922
32041
|
const { name, onBlur, onChange, value } = fieldProps;
|
|
31923
32042
|
const computedHelpText = showInputOnly ? null : helpText;
|
|
31924
32043
|
const computedLabel = showInputOnly ? "" : label;
|
|
31925
|
-
const [internalValue, setInternalValue] = useState(
|
|
32044
|
+
const [internalValue, setInternalValue] = useState("");
|
|
31926
32045
|
useEffect(() => {
|
|
31927
32046
|
setInternalValue(value);
|
|
31928
32047
|
}, [value]);
|
|
31929
32048
|
const handleChange = useCallback(
|
|
31930
32049
|
(e) => {
|
|
31931
|
-
|
|
32050
|
+
const value2 = e.target.value;
|
|
32051
|
+
setInternalValue(value2);
|
|
31932
32052
|
if (touched || !field.onlyValidateAfterTouched) {
|
|
31933
|
-
helpers.setError(field.getError(
|
|
32053
|
+
helpers.setError(field.getError(value2));
|
|
31934
32054
|
}
|
|
31935
32055
|
},
|
|
31936
32056
|
[field, helpers, touched]
|
|
@@ -31954,7 +32074,7 @@ const StringInput = memo((props) => {
|
|
|
31954
32074
|
id: inputId,
|
|
31955
32075
|
className: "truncate",
|
|
31956
32076
|
name,
|
|
31957
|
-
value: internalValue
|
|
32077
|
+
value: internalValue,
|
|
31958
32078
|
type: "text",
|
|
31959
32079
|
placeholder: field.placeholder,
|
|
31960
32080
|
onChange: handleChange,
|
|
@@ -32014,15 +32134,16 @@ const TextInput = memo((props) => {
|
|
|
32014
32134
|
const { name, onBlur, onChange, value } = fieldProps;
|
|
32015
32135
|
const computedHelpText = showInputOnly ? null : helpText;
|
|
32016
32136
|
const computedLabel = showInputOnly ? "" : label;
|
|
32017
|
-
const [internalValue, setInternalValue] = useState(
|
|
32137
|
+
const [internalValue, setInternalValue] = useState("");
|
|
32018
32138
|
useEffect(() => {
|
|
32019
32139
|
setInternalValue(value);
|
|
32020
32140
|
}, [value]);
|
|
32021
32141
|
const handleChange = useCallback(
|
|
32022
32142
|
(e) => {
|
|
32023
|
-
|
|
32143
|
+
const value2 = e.target.value;
|
|
32144
|
+
setInternalValue(value2);
|
|
32024
32145
|
if (touched || !field.onlyValidateAfterTouched) {
|
|
32025
|
-
helpers.setError(field.getError(
|
|
32146
|
+
helpers.setError(field.getError(value2));
|
|
32026
32147
|
}
|
|
32027
32148
|
},
|
|
32028
32149
|
[field, helpers, touched]
|
|
@@ -32044,7 +32165,7 @@ const TextInput = memo((props) => {
|
|
|
32044
32165
|
TextArea,
|
|
32045
32166
|
{
|
|
32046
32167
|
id: inputId,
|
|
32047
|
-
value: internalValue
|
|
32168
|
+
value: internalValue,
|
|
32048
32169
|
name,
|
|
32049
32170
|
onChange: handleChange,
|
|
32050
32171
|
onBlur: handleBlur,
|
|
@@ -32152,11 +32273,25 @@ const convertBytesToLargestUnit = (bytes) => {
|
|
|
32152
32273
|
});
|
|
32153
32274
|
return formatter.format(sizeInUnit);
|
|
32154
32275
|
};
|
|
32276
|
+
function areFilesEqual(file1, file2) {
|
|
32277
|
+
return file1.name === file2.name && file1.size === file2.size && file1.type === file2.type;
|
|
32278
|
+
}
|
|
32279
|
+
function seprateFilesFromPromises(filesOrPromises) {
|
|
32280
|
+
const files = [];
|
|
32281
|
+
const promises = [];
|
|
32282
|
+
for (const fileOrPromise of filesOrPromises) {
|
|
32283
|
+
if (fileOrPromise instanceof Promise) {
|
|
32284
|
+
promises.push(fileOrPromise);
|
|
32285
|
+
} else {
|
|
32286
|
+
files.push(fileOrPromise);
|
|
32287
|
+
}
|
|
32288
|
+
}
|
|
32289
|
+
return [files, promises];
|
|
32290
|
+
}
|
|
32155
32291
|
const UploadInput = memo((props) => {
|
|
32156
32292
|
var _a2;
|
|
32157
32293
|
const [{ inputId, labelId, label, size, severity, helpText, showInputOnly, field, fieldProps }, rest] = useFormikInput(props);
|
|
32158
|
-
const { name, onChange, onBlur } = fieldProps;
|
|
32159
|
-
const value = fieldProps.value ?? EMPTY_ARRAY;
|
|
32294
|
+
const { value, name, onChange, onBlur } = fieldProps;
|
|
32160
32295
|
const input = useRef(null);
|
|
32161
32296
|
const updatedHelpText = useMemo(() => {
|
|
32162
32297
|
if (showInputOnly) return null;
|
|
@@ -32186,7 +32321,7 @@ const UploadInput = memo((props) => {
|
|
|
32186
32321
|
(index) => {
|
|
32187
32322
|
const files = [...value];
|
|
32188
32323
|
files.splice(index, 1);
|
|
32189
|
-
onChange(files
|
|
32324
|
+
onChange(files);
|
|
32190
32325
|
},
|
|
32191
32326
|
[value, onChange]
|
|
32192
32327
|
);
|
|
@@ -32196,7 +32331,7 @@ const UploadInput = memo((props) => {
|
|
|
32196
32331
|
input.current.addEventListener(
|
|
32197
32332
|
"cancel",
|
|
32198
32333
|
() => {
|
|
32199
|
-
onBlur(
|
|
32334
|
+
onBlur([...value]);
|
|
32200
32335
|
},
|
|
32201
32336
|
{
|
|
32202
32337
|
signal: abortController.signal
|
|
@@ -32355,21 +32490,6 @@ const DisplayFile = memo((props) => {
|
|
|
32355
32490
|
) : /* @__PURE__ */ jsx(FileCard, { file: resolvedFile, error: error ?? void 0, rightSlot: rightSlotContent });
|
|
32356
32491
|
});
|
|
32357
32492
|
DisplayFile.displayName = "DisplayFile";
|
|
32358
|
-
function areFilesEqual(file1, file2) {
|
|
32359
|
-
return file1.name === file2.name && file1.size === file2.size && file1.type === file2.type;
|
|
32360
|
-
}
|
|
32361
|
-
function seprateFilesFromPromises(filesOrPromises) {
|
|
32362
|
-
const files = [];
|
|
32363
|
-
const promises = [];
|
|
32364
|
-
for (const fileOrPromise of filesOrPromises) {
|
|
32365
|
-
if (fileOrPromise instanceof Promise) {
|
|
32366
|
-
promises.push(fileOrPromise);
|
|
32367
|
-
} else {
|
|
32368
|
-
files.push(fileOrPromise);
|
|
32369
|
-
}
|
|
32370
|
-
}
|
|
32371
|
-
return [files, promises];
|
|
32372
|
-
}
|
|
32373
32493
|
const _UploadField = class _UploadField extends BaseField {
|
|
32374
32494
|
constructor(options) {
|
|
32375
32495
|
const { extensions, maximum_files, maximum_size, ...base } = options;
|
|
@@ -32383,20 +32503,6 @@ const _UploadField = class _UploadField extends BaseField {
|
|
|
32383
32503
|
this.maxFiles = Math.max(typeof maximum_files === "number" ? maximum_files : 1, 1);
|
|
32384
32504
|
this.extensions = extensions;
|
|
32385
32505
|
}
|
|
32386
|
-
isBlank(value) {
|
|
32387
|
-
return super.isBlank(value) || (value == null ? void 0 : value.length) === 0;
|
|
32388
|
-
}
|
|
32389
|
-
isEqual(value1, value2) {
|
|
32390
|
-
if (value1 === void 0 && value2 === void 0) return true;
|
|
32391
|
-
if (value1 === void 0 || value2 === void 0) return false;
|
|
32392
|
-
const [files1, promises1] = seprateFilesFromPromises(value1);
|
|
32393
|
-
const [files2, promises2] = seprateFilesFromPromises(value2);
|
|
32394
|
-
if (!files1.every((file1) => files2.some((file2) => areFilesEqual(file1, file2)))) return false;
|
|
32395
|
-
if (!files2.every((file2) => files1.some((file1) => areFilesEqual(file1, file2)))) return false;
|
|
32396
|
-
if (!promises1.every((promise1) => promises2.some((promise2) => promise1 === promise2))) return false;
|
|
32397
|
-
if (!promises2.every((promise2) => promises1.some((promise1) => promise1 === promise2))) return false;
|
|
32398
|
-
return true;
|
|
32399
|
-
}
|
|
32400
32506
|
static getFieldCreationSchema(parentPath = "") {
|
|
32401
32507
|
const path = parentPath && `${parentPath}.`;
|
|
32402
32508
|
return [
|
|
@@ -32515,6 +32621,24 @@ const _UploadField = class _UploadField extends BaseField {
|
|
|
32515
32621
|
render(props) {
|
|
32516
32622
|
return /* @__PURE__ */ jsx(UploadInput, { field: this, ...props });
|
|
32517
32623
|
}
|
|
32624
|
+
isSerializedValueValid(value) {
|
|
32625
|
+
return Array.isArray(value) && value.length === 0;
|
|
32626
|
+
}
|
|
32627
|
+
isValueValid(value) {
|
|
32628
|
+
return isFilePromiseArray(value);
|
|
32629
|
+
}
|
|
32630
|
+
areValuesEqual(value1, value2) {
|
|
32631
|
+
const [files1, promises1] = seprateFilesFromPromises(value1);
|
|
32632
|
+
const [files2, promises2] = seprateFilesFromPromises(value2);
|
|
32633
|
+
if (!files1.every((file1) => files2.some((file2) => areFilesEqual(file1, file2)))) return false;
|
|
32634
|
+
if (!files2.every((file2) => files1.some((file1) => areFilesEqual(file1, file2)))) return false;
|
|
32635
|
+
if (!promises1.every((promise1) => promises2.some((promise2) => promise1 === promise2))) return false;
|
|
32636
|
+
if (!promises2.every((promise2) => promises1.some((promise1) => promise1 === promise2))) return false;
|
|
32637
|
+
return true;
|
|
32638
|
+
}
|
|
32639
|
+
blankValue() {
|
|
32640
|
+
return [];
|
|
32641
|
+
}
|
|
32518
32642
|
};
|
|
32519
32643
|
__publicField(_UploadField, "fieldTypeName", "Upload");
|
|
32520
32644
|
__publicField(_UploadField, "fieldTypeDescription", "Allows a file to be uploaded.");
|
|
@@ -32553,60 +32677,6 @@ const fieldIcons = {
|
|
|
32553
32677
|
const maxFileSizeMB = 50;
|
|
32554
32678
|
const maxFileSizeKB = maxFileSizeMB * 1e3;
|
|
32555
32679
|
const maxFileSizeB = maxFileSizeKB * 1e3;
|
|
32556
|
-
class BaseCondition extends Observable {
|
|
32557
|
-
constructor(config) {
|
|
32558
|
-
const { id, field, conditionValue, conditionModifier } = config;
|
|
32559
|
-
super();
|
|
32560
|
-
__publicField(this, "id");
|
|
32561
|
-
__publicField(this, "conditionValue");
|
|
32562
|
-
__publicField(this, "conditionModifier");
|
|
32563
|
-
__publicField(this, "field");
|
|
32564
|
-
__publicField(this, "getConditionValue", () => {
|
|
32565
|
-
return this.conditionValue;
|
|
32566
|
-
});
|
|
32567
|
-
__publicField(this, "setConditionValue", (conditionValue) => {
|
|
32568
|
-
const modifier = this.modifiers[this.conditionModifier];
|
|
32569
|
-
if (conditionValue !== void 0 && !modifier.isConditionValueValid(conditionValue)) return;
|
|
32570
|
-
this.conditionValue = conditionValue;
|
|
32571
|
-
this.notify(this);
|
|
32572
|
-
});
|
|
32573
|
-
__publicField(this, "getConditionModifier", () => {
|
|
32574
|
-
return this.conditionModifier;
|
|
32575
|
-
});
|
|
32576
|
-
__publicField(this, "setConditionModifier", (modifier) => {
|
|
32577
|
-
const foundModifier = this.modifiers[modifier];
|
|
32578
|
-
const filterValue = this.getConditionValue();
|
|
32579
|
-
if (filterValue && !foundModifier.isConditionValueValid(filterValue)) {
|
|
32580
|
-
this.conditionValue = void 0;
|
|
32581
|
-
}
|
|
32582
|
-
this.conditionModifier = modifier;
|
|
32583
|
-
this.notify(this);
|
|
32584
|
-
});
|
|
32585
|
-
__publicField(this, "getConditionModifiers", () => {
|
|
32586
|
-
return Object.entries(this.modifiers);
|
|
32587
|
-
});
|
|
32588
|
-
__publicField(this, "apply", (value) => {
|
|
32589
|
-
const modifier = this.modifiers[this.conditionModifier];
|
|
32590
|
-
const conditionValue = this.getConditionValue();
|
|
32591
|
-
if (conditionValue === void 0 || !modifier.isConditionValueValid(conditionValue)) return true;
|
|
32592
|
-
if (!modifier.isValueValid(value)) return false;
|
|
32593
|
-
return modifier.modifier.modifierFn(value, conditionValue);
|
|
32594
|
-
});
|
|
32595
|
-
this.id = id;
|
|
32596
|
-
this.field = field;
|
|
32597
|
-
this.conditionValue = conditionValue;
|
|
32598
|
-
this.conditionModifier = conditionModifier;
|
|
32599
|
-
}
|
|
32600
|
-
serialize() {
|
|
32601
|
-
return {
|
|
32602
|
-
id: this.id,
|
|
32603
|
-
type: this.field.type,
|
|
32604
|
-
fieldId: this.field.identifier,
|
|
32605
|
-
conditionValue: this.modifiers[this.conditionModifier].modifier.serialize(this.conditionValue),
|
|
32606
|
-
conditionModifier: this.conditionModifier
|
|
32607
|
-
};
|
|
32608
|
-
}
|
|
32609
|
-
}
|
|
32610
32680
|
class ConditionModifier {
|
|
32611
32681
|
constructor(config) {
|
|
32612
32682
|
__publicField(this, "id");
|
|
@@ -32913,6 +32983,60 @@ const StringArrayNotEqualsConditionModifier = ConditionModifier.create({
|
|
|
32913
32983
|
deserialize: (filterValue) => filterValue
|
|
32914
32984
|
});
|
|
32915
32985
|
const createConditionModifierConfig = (conifg) => conifg;
|
|
32986
|
+
class BaseCondition extends Observable {
|
|
32987
|
+
constructor(config) {
|
|
32988
|
+
const { id, field, conditionValue, conditionModifier } = config;
|
|
32989
|
+
super();
|
|
32990
|
+
__publicField(this, "id");
|
|
32991
|
+
__publicField(this, "conditionValue");
|
|
32992
|
+
__publicField(this, "conditionModifier");
|
|
32993
|
+
__publicField(this, "field");
|
|
32994
|
+
__publicField(this, "getConditionValue", () => {
|
|
32995
|
+
return this.conditionValue;
|
|
32996
|
+
});
|
|
32997
|
+
__publicField(this, "setConditionValue", (conditionValue) => {
|
|
32998
|
+
const modifier = this.modifiers[this.conditionModifier];
|
|
32999
|
+
if (conditionValue !== void 0 && !modifier.isConditionValueValid(conditionValue)) return;
|
|
33000
|
+
this.conditionValue = conditionValue;
|
|
33001
|
+
this.notify(this);
|
|
33002
|
+
});
|
|
33003
|
+
__publicField(this, "getConditionModifier", () => {
|
|
33004
|
+
return this.conditionModifier;
|
|
33005
|
+
});
|
|
33006
|
+
__publicField(this, "setConditionModifier", (modifier) => {
|
|
33007
|
+
const foundModifier = this.modifiers[modifier];
|
|
33008
|
+
const filterValue = this.getConditionValue();
|
|
33009
|
+
if (filterValue && !foundModifier.isConditionValueValid(filterValue)) {
|
|
33010
|
+
this.conditionValue = void 0;
|
|
33011
|
+
}
|
|
33012
|
+
this.conditionModifier = modifier;
|
|
33013
|
+
this.notify(this);
|
|
33014
|
+
});
|
|
33015
|
+
__publicField(this, "getConditionModifiers", () => {
|
|
33016
|
+
return Object.entries(this.modifiers);
|
|
33017
|
+
});
|
|
33018
|
+
__publicField(this, "apply", (value) => {
|
|
33019
|
+
const modifier = this.modifiers[this.conditionModifier];
|
|
33020
|
+
const conditionValue = this.getConditionValue();
|
|
33021
|
+
if (conditionValue === void 0 || !modifier.isConditionValueValid(conditionValue)) return true;
|
|
33022
|
+
if (!modifier.isValueValid(value)) return false;
|
|
33023
|
+
return modifier.modifier.modifierFn(value, conditionValue);
|
|
33024
|
+
});
|
|
33025
|
+
this.id = id;
|
|
33026
|
+
this.field = field;
|
|
33027
|
+
this.conditionValue = conditionValue;
|
|
33028
|
+
this.conditionModifier = conditionModifier;
|
|
33029
|
+
}
|
|
33030
|
+
serialize() {
|
|
33031
|
+
return {
|
|
33032
|
+
id: this.id,
|
|
33033
|
+
type: this.field.type,
|
|
33034
|
+
fieldId: this.field.identifier,
|
|
33035
|
+
conditionValue: this.modifiers[this.conditionModifier].modifier.serialize(this.conditionValue),
|
|
33036
|
+
conditionModifier: this.conditionModifier
|
|
33037
|
+
};
|
|
33038
|
+
}
|
|
33039
|
+
}
|
|
32916
33040
|
const formId = "form-builder";
|
|
32917
33041
|
const UNLABELLED_FIELD_LABEL = "Unlabelled";
|
|
32918
33042
|
const UNLABELLED_SECTION_LABEL = "Unlabelled";
|
|
@@ -33653,19 +33777,19 @@ const NumberFieldConditionCell = (props) => {
|
|
|
33653
33777
|
const modifiers$7 = {
|
|
33654
33778
|
equals: createConditionModifierConfig({
|
|
33655
33779
|
modifier: NumberEqualsConditionModifier,
|
|
33656
|
-
isValueValid: (
|
|
33780
|
+
isValueValid: (value) => typeof value === "number",
|
|
33657
33781
|
isConditionValueValid: (conditionValue) => typeof conditionValue === "number",
|
|
33658
33782
|
isSerializedValueValid: (conditionValue) => typeof conditionValue === "number"
|
|
33659
33783
|
}),
|
|
33660
33784
|
notEquals: createConditionModifierConfig({
|
|
33661
33785
|
modifier: NumberNotEqualsConditionModifier,
|
|
33662
|
-
isValueValid: (
|
|
33786
|
+
isValueValid: (value) => typeof value === "number",
|
|
33663
33787
|
isConditionValueValid: (conditionValue) => typeof conditionValue === "number",
|
|
33664
33788
|
isSerializedValueValid: (conditionValue) => typeof conditionValue === "number"
|
|
33665
33789
|
}),
|
|
33666
33790
|
lessThan: createConditionModifierConfig({
|
|
33667
33791
|
modifier: NumberLessThanConditionModifier,
|
|
33668
|
-
isValueValid: (
|
|
33792
|
+
isValueValid: (value) => typeof value === "number",
|
|
33669
33793
|
isConditionValueValid: (conditionValue) => typeof conditionValue === "number",
|
|
33670
33794
|
isSerializedValueValid: (conditionValue) => typeof conditionValue === "number"
|
|
33671
33795
|
}),
|
|
@@ -33876,25 +34000,25 @@ const RadioFieldConditionCell = (props) => {
|
|
|
33876
34000
|
const modifiers$5 = {
|
|
33877
34001
|
equals: createConditionModifierConfig({
|
|
33878
34002
|
modifier: StringEqualsConditionModifier,
|
|
33879
|
-
isValueValid: (
|
|
34003
|
+
isValueValid: (value) => typeof value === "string",
|
|
33880
34004
|
isConditionValueValid: (conditionValue) => !Array.isArray(conditionValue),
|
|
33881
34005
|
isSerializedValueValid: (serializedConditionValue) => !Array.isArray(serializedConditionValue)
|
|
33882
34006
|
}),
|
|
33883
34007
|
notEquals: createConditionModifierConfig({
|
|
33884
34008
|
modifier: StringNotEqualsConditionModifier,
|
|
33885
|
-
isValueValid: (
|
|
34009
|
+
isValueValid: (value) => typeof value === "string",
|
|
33886
34010
|
isConditionValueValid: (conditionValue) => !Array.isArray(conditionValue),
|
|
33887
34011
|
isSerializedValueValid: (serializedConditionValue) => !Array.isArray(serializedConditionValue)
|
|
33888
34012
|
}),
|
|
33889
34013
|
includes: createConditionModifierConfig({
|
|
33890
34014
|
modifier: StringArrayIncludesConditionModifier,
|
|
33891
|
-
isValueValid: (
|
|
34015
|
+
isValueValid: (value) => typeof value === "string",
|
|
33892
34016
|
isConditionValueValid: (conditionValue) => Array.isArray(conditionValue),
|
|
33893
34017
|
isSerializedValueValid: (serializedConditionValue) => Array.isArray(serializedConditionValue)
|
|
33894
34018
|
}),
|
|
33895
34019
|
excludes: createConditionModifierConfig({
|
|
33896
34020
|
modifier: StringArrayExcludesConditionModifier,
|
|
33897
|
-
isValueValid: (
|
|
34021
|
+
isValueValid: (value) => typeof value === "string",
|
|
33898
34022
|
isConditionValueValid: (conditionValue) => Array.isArray(conditionValue),
|
|
33899
34023
|
isSerializedValueValid: (serializedConditionValue) => Array.isArray(serializedConditionValue)
|
|
33900
34024
|
})
|
|
@@ -34075,25 +34199,25 @@ const SelectFieldConditionCell = (props) => {
|
|
|
34075
34199
|
const modifiers$3 = {
|
|
34076
34200
|
equals: createConditionModifierConfig({
|
|
34077
34201
|
modifier: StringEqualsConditionModifier,
|
|
34078
|
-
isValueValid: (
|
|
34202
|
+
isValueValid: (value) => typeof value === "string",
|
|
34079
34203
|
isConditionValueValid: (conditionValue) => !Array.isArray(conditionValue),
|
|
34080
34204
|
isSerializedValueValid: (serializedConditionValue) => !Array.isArray(serializedConditionValue)
|
|
34081
34205
|
}),
|
|
34082
34206
|
notEquals: createConditionModifierConfig({
|
|
34083
34207
|
modifier: StringNotEqualsConditionModifier,
|
|
34084
|
-
isValueValid: (
|
|
34208
|
+
isValueValid: (value) => typeof value === "string",
|
|
34085
34209
|
isConditionValueValid: (conditionValue) => !Array.isArray(conditionValue),
|
|
34086
34210
|
isSerializedValueValid: (serializedConditionValue) => !Array.isArray(serializedConditionValue)
|
|
34087
34211
|
}),
|
|
34088
34212
|
includes: createConditionModifierConfig({
|
|
34089
34213
|
modifier: StringArrayIncludesConditionModifier,
|
|
34090
|
-
isValueValid: (
|
|
34214
|
+
isValueValid: (value) => typeof value === "string",
|
|
34091
34215
|
isConditionValueValid: (conditionValue) => Array.isArray(conditionValue),
|
|
34092
34216
|
isSerializedValueValid: (serializedConditionValue) => Array.isArray(serializedConditionValue)
|
|
34093
34217
|
}),
|
|
34094
34218
|
excludes: createConditionModifierConfig({
|
|
34095
34219
|
modifier: StringArrayExcludesConditionModifier,
|
|
34096
|
-
isValueValid: (
|
|
34220
|
+
isValueValid: (value) => typeof value === "string",
|
|
34097
34221
|
isConditionValueValid: (conditionValue) => Array.isArray(conditionValue),
|
|
34098
34222
|
isSerializedValueValid: (serializedConditionValue) => Array.isArray(serializedConditionValue)
|
|
34099
34223
|
})
|
|
@@ -34416,15 +34540,15 @@ const deserializeField = (serializedField) => {
|
|
|
34416
34540
|
return OTPField.deserialize(serializedField);
|
|
34417
34541
|
}
|
|
34418
34542
|
};
|
|
34543
|
+
function deserializeFields(fields) {
|
|
34544
|
+
return fields.map(deserialize);
|
|
34545
|
+
}
|
|
34419
34546
|
const deserialize = (serialized) => {
|
|
34420
34547
|
if (serialized.type === "section") {
|
|
34421
34548
|
return FieldSection.deserialize(serialized);
|
|
34422
34549
|
}
|
|
34423
34550
|
return deserializeField(serialized);
|
|
34424
34551
|
};
|
|
34425
|
-
function deserializeFields(fields) {
|
|
34426
|
-
return fields.map(deserialize);
|
|
34427
|
-
}
|
|
34428
34552
|
function deserializeOnlyFields(fields) {
|
|
34429
34553
|
return fields.map(deserializeField);
|
|
34430
34554
|
}
|
|
@@ -34450,33 +34574,44 @@ function getFieldsMapping(fields) {
|
|
|
34450
34574
|
return result;
|
|
34451
34575
|
}
|
|
34452
34576
|
function serializeFieldValues(fields, values) {
|
|
34577
|
+
const cleanValues = cleanFieldValues(fields, values);
|
|
34453
34578
|
const ret = {};
|
|
34454
34579
|
for (const field of fields) {
|
|
34455
|
-
const value =
|
|
34580
|
+
const value = cleanValues[field.identifier];
|
|
34581
|
+
if (!field.isValueValid(value)) continue;
|
|
34456
34582
|
ret[field.identifier] = field.serializeValue(value);
|
|
34457
34583
|
}
|
|
34458
34584
|
return ret;
|
|
34459
34585
|
}
|
|
34460
34586
|
function deserializeFieldValues(fields, values) {
|
|
34587
|
+
const cleanValues = cleanSerializedFieldValues(fields, values);
|
|
34461
34588
|
const ret = {};
|
|
34462
34589
|
for (const field of fields) {
|
|
34463
|
-
const value =
|
|
34590
|
+
const value = cleanValues[field.identifier];
|
|
34591
|
+
if (!field.isSerializedValueValid(value)) continue;
|
|
34464
34592
|
ret[field.identifier] = field.deserializeValue(value);
|
|
34465
34593
|
}
|
|
34466
34594
|
return ret;
|
|
34467
34595
|
}
|
|
34596
|
+
function cleanFieldValues(fields, values) {
|
|
34597
|
+
const ret = {};
|
|
34598
|
+
for (const field of fields) {
|
|
34599
|
+
const value = values[field.identifier];
|
|
34600
|
+
if (!field.isSerializedValueValid(value)) continue;
|
|
34601
|
+
ret[field.identifier] = value;
|
|
34602
|
+
}
|
|
34603
|
+
return ret;
|
|
34604
|
+
}
|
|
34605
|
+
function cleanSerializedFieldValues(fields, values) {
|
|
34606
|
+
const ret = {};
|
|
34607
|
+
for (const field of fields) {
|
|
34608
|
+
const value = values[field.identifier];
|
|
34609
|
+
if (!field.isSerializedValueValid(value)) continue;
|
|
34610
|
+
ret[field.identifier] = value;
|
|
34611
|
+
}
|
|
34612
|
+
return ret;
|
|
34613
|
+
}
|
|
34468
34614
|
const RendererContext = createContext({});
|
|
34469
|
-
const useFieldInput = (field, props) => {
|
|
34470
|
-
return useMemo(() => {
|
|
34471
|
-
if (!props || !field) return null;
|
|
34472
|
-
return field.render(props);
|
|
34473
|
-
}, [field, props]);
|
|
34474
|
-
};
|
|
34475
|
-
const useFieldInputs = (fields, props) => {
|
|
34476
|
-
return /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-4", children: fields.map((field) => {
|
|
34477
|
-
return /* @__PURE__ */ jsx(Fragment$1, { children: field.render(props) }, field.identifier);
|
|
34478
|
-
}) });
|
|
34479
|
-
};
|
|
34480
34615
|
const FieldSectionLayout = memo((props) => {
|
|
34481
34616
|
const { fieldSection: section, ...rest } = props;
|
|
34482
34617
|
const { label, description } = section;
|
|
@@ -34583,13 +34718,12 @@ const _FieldSection = class _FieldSection extends BaseFormElement {
|
|
|
34583
34718
|
this.conditions = conditions || this.conditions;
|
|
34584
34719
|
super.setOptions(base);
|
|
34585
34720
|
}
|
|
34586
|
-
getErrors(
|
|
34721
|
+
getErrors(values) {
|
|
34587
34722
|
const errors = {};
|
|
34588
34723
|
for (const field of this.fields) {
|
|
34589
|
-
const
|
|
34590
|
-
const error = field.getError(get(allValues, id));
|
|
34724
|
+
const error = field.getError(values[field.identifier]);
|
|
34591
34725
|
if (error) {
|
|
34592
|
-
|
|
34726
|
+
errors[field.identifier] = error;
|
|
34593
34727
|
}
|
|
34594
34728
|
}
|
|
34595
34729
|
return errors;
|
|
@@ -34744,124 +34878,6 @@ class FieldSchema extends Observable {
|
|
|
34744
34878
|
}
|
|
34745
34879
|
const FieldSchemaContext = createContext(new FieldSchema([]));
|
|
34746
34880
|
const FormBuilderContext = createContext({});
|
|
34747
|
-
const hasKeys = (errors) => {
|
|
34748
|
-
return Object.keys(errors).length > 0;
|
|
34749
|
-
};
|
|
34750
|
-
const validateFields = (fields, values) => {
|
|
34751
|
-
const errors = {};
|
|
34752
|
-
const sectionElements = fields.filter((f) => f instanceof FieldSection);
|
|
34753
|
-
for (const field of fields) {
|
|
34754
|
-
if (field instanceof FieldSection) {
|
|
34755
|
-
const conditionalSections = sectionElements.filter((section) => field.identifier in section.conditions);
|
|
34756
|
-
const conditionMet = conditionalSections.length > 0 ? conditionalSections.some(
|
|
34757
|
-
(conditionalSection) => applyConditions(conditionalSection.getConditions(field.identifier), values)
|
|
34758
|
-
) : true;
|
|
34759
|
-
if (!conditionMet) continue;
|
|
34760
|
-
Object.assign(errors, field.getErrors(values));
|
|
34761
|
-
} else {
|
|
34762
|
-
if (!(field instanceof BaseField)) {
|
|
34763
|
-
throw new Error("Invalid field type");
|
|
34764
|
-
}
|
|
34765
|
-
const id = field.identifier;
|
|
34766
|
-
const error = field.getError(get(values, id));
|
|
34767
|
-
if (error) set(errors, id, error);
|
|
34768
|
-
}
|
|
34769
|
-
}
|
|
34770
|
-
if (hasKeys(errors)) return errors;
|
|
34771
|
-
};
|
|
34772
|
-
const initializeFieldValues = (fields, values) => {
|
|
34773
|
-
return fields.reduce((acc, field) => {
|
|
34774
|
-
if (field instanceof FieldSection) {
|
|
34775
|
-
return { ...acc, ...initializeFieldValues(field.fields, values) };
|
|
34776
|
-
}
|
|
34777
|
-
const identifier = field.identifier;
|
|
34778
|
-
const value = acc[identifier];
|
|
34779
|
-
switch (value) {
|
|
34780
|
-
case "":
|
|
34781
|
-
acc[identifier] = void 0;
|
|
34782
|
-
break;
|
|
34783
|
-
case []:
|
|
34784
|
-
acc[identifier] = void 0;
|
|
34785
|
-
break;
|
|
34786
|
-
default:
|
|
34787
|
-
acc[identifier] = value ?? void 0;
|
|
34788
|
-
}
|
|
34789
|
-
return acc;
|
|
34790
|
-
}, values);
|
|
34791
|
-
};
|
|
34792
|
-
const changedFieldValues = (fields, values1, values2) => {
|
|
34793
|
-
return fields.reduce((acc, field) => {
|
|
34794
|
-
if (field instanceof FieldSection) {
|
|
34795
|
-
return { ...acc, ...changedFieldValues(field.fields, values1, values2) };
|
|
34796
|
-
}
|
|
34797
|
-
if (field instanceof BaseField) {
|
|
34798
|
-
const identifier = field.identifier;
|
|
34799
|
-
const value1 = values1[identifier];
|
|
34800
|
-
const value2 = values2[identifier];
|
|
34801
|
-
if (!field.isEqual(value1, value2)) {
|
|
34802
|
-
acc[identifier] = value2;
|
|
34803
|
-
}
|
|
34804
|
-
}
|
|
34805
|
-
return acc;
|
|
34806
|
-
}, {});
|
|
34807
|
-
};
|
|
34808
|
-
const isArrayOfFiles = (value) => {
|
|
34809
|
-
return Array.isArray(value) && value[0] instanceof File;
|
|
34810
|
-
};
|
|
34811
|
-
const separateFilesFromFieldValues = (values) => {
|
|
34812
|
-
const files = {};
|
|
34813
|
-
const newValues = {};
|
|
34814
|
-
for (const key in values) {
|
|
34815
|
-
const value = values[key];
|
|
34816
|
-
if (value instanceof File) {
|
|
34817
|
-
files[key] = [value];
|
|
34818
|
-
} else if (isArrayOfFiles(value)) {
|
|
34819
|
-
files[key] = value;
|
|
34820
|
-
} else if (value !== void 0) {
|
|
34821
|
-
newValues[key] = value;
|
|
34822
|
-
}
|
|
34823
|
-
}
|
|
34824
|
-
return { values: newValues, files };
|
|
34825
|
-
};
|
|
34826
|
-
const separateFilesFromFields = async (fields) => {
|
|
34827
|
-
const images = {};
|
|
34828
|
-
const newFields = [];
|
|
34829
|
-
for (const section of fields) {
|
|
34830
|
-
if (section.type !== "section") {
|
|
34831
|
-
throw new Error(`Expected ISerializedField type to be a section. Got ${section.type} instead.`);
|
|
34832
|
-
}
|
|
34833
|
-
const { fields: sectionFields } = section;
|
|
34834
|
-
const newSectionFields = [];
|
|
34835
|
-
for (const field of sectionFields) {
|
|
34836
|
-
if (field.image) {
|
|
34837
|
-
if (field.image instanceof Promise) {
|
|
34838
|
-
try {
|
|
34839
|
-
images[field.identifier] = await field.image;
|
|
34840
|
-
} catch (e) {
|
|
34841
|
-
console.error("Failed to get image from promise", e);
|
|
34842
|
-
}
|
|
34843
|
-
} else {
|
|
34844
|
-
images[field.identifier] = field.image;
|
|
34845
|
-
}
|
|
34846
|
-
delete field.image;
|
|
34847
|
-
}
|
|
34848
|
-
newSectionFields.push(field);
|
|
34849
|
-
}
|
|
34850
|
-
newFields.push({ ...section, fields: newSectionFields });
|
|
34851
|
-
}
|
|
34852
|
-
return { fields: newFields, images };
|
|
34853
|
-
};
|
|
34854
|
-
async function awaitPromisesFromFieldValues(values) {
|
|
34855
|
-
const valuesWithoutFiles = {};
|
|
34856
|
-
for (const [key, value] of Object.entries(values)) {
|
|
34857
|
-
if (Array.isArray(value) && value.every((item) => item instanceof Promise)) {
|
|
34858
|
-
valuesWithoutFiles[key] = await Promise.all(value);
|
|
34859
|
-
} else {
|
|
34860
|
-
valuesWithoutFiles[key] = value;
|
|
34861
|
-
}
|
|
34862
|
-
}
|
|
34863
|
-
return valuesWithoutFiles;
|
|
34864
|
-
}
|
|
34865
34881
|
const createField = (type) => {
|
|
34866
34882
|
switch (type) {
|
|
34867
34883
|
case "text":
|
|
@@ -35134,7 +35150,7 @@ const FieldBuilder = memo((props) => {
|
|
|
35134
35150
|
const showPopoverInputs = popoverFields.length > 0;
|
|
35135
35151
|
const popoverHasErrors = popoverFields.some((field2) => {
|
|
35136
35152
|
const error = get(errors, field2.identifier);
|
|
35137
|
-
return error && (typeof error !== "object" ||
|
|
35153
|
+
return error && (typeof error !== "object" || Object.values(error).length > 0);
|
|
35138
35154
|
});
|
|
35139
35155
|
const previewInput = useFieldInput(field, { formId, showInputOnly: false });
|
|
35140
35156
|
const handleFieldImageClick = useCallback(() => {
|
|
@@ -35238,45 +35254,6 @@ const FieldDropdownMenu = memo((props) => {
|
|
|
35238
35254
|
] });
|
|
35239
35255
|
});
|
|
35240
35256
|
FieldDropdownMenu.displayName = "IssueDataFilterMenu";
|
|
35241
|
-
const FieldSectionConditionalItem = memo((props) => {
|
|
35242
|
-
const { sourceFieldSection, targetFieldSection } = props;
|
|
35243
|
-
const conditions = useMemo(() => {
|
|
35244
|
-
return sourceFieldSection.getConditions(targetFieldSection.identifier);
|
|
35245
|
-
}, [sourceFieldSection, targetFieldSection.identifier]);
|
|
35246
|
-
const handleDelete = useCallback(() => {
|
|
35247
|
-
sourceFieldSection.removeConditional(targetFieldSection.identifier);
|
|
35248
|
-
}, [sourceFieldSection, targetFieldSection.identifier]);
|
|
35249
|
-
const handleSelectField = useCallback(
|
|
35250
|
-
(field) => {
|
|
35251
|
-
sourceFieldSection.addCondition(targetFieldSection.identifier, createCondition(field));
|
|
35252
|
-
},
|
|
35253
|
-
[sourceFieldSection, targetFieldSection.identifier]
|
|
35254
|
-
);
|
|
35255
|
-
const handleDeleteCondition = useCallback(
|
|
35256
|
-
(condition) => {
|
|
35257
|
-
sourceFieldSection.removeCondition(targetFieldSection.identifier, condition);
|
|
35258
|
-
},
|
|
35259
|
-
[sourceFieldSection, targetFieldSection.identifier]
|
|
35260
|
-
);
|
|
35261
|
-
return /* @__PURE__ */ jsxs(Card, { className: "flex flex-col gap-2", children: [
|
|
35262
|
-
/* @__PURE__ */ jsxs(ButtonGroup, { className: "justify-between gap-2 flex", size: "sm", accentColor: "base", variant: "soft", children: [
|
|
35263
|
-
/* @__PURE__ */ jsxs(Badge, { accentColor: "base", variant: "soft", size: "sm", children: [
|
|
35264
|
-
/* @__PURE__ */ jsx(LuIcon, { icon: fieldIcons.section }),
|
|
35265
|
-
sourceFieldSection.label ?? UNLABELLED_SECTION_LABEL
|
|
35266
|
-
] }),
|
|
35267
|
-
/* @__PURE__ */ jsx(IconButton, { type: "button", onClick: handleDelete, variant: "ghost", children: /* @__PURE__ */ jsx(LuIcon, { icon: "trash" }) })
|
|
35268
|
-
] }),
|
|
35269
|
-
/* @__PURE__ */ jsxs("div", { className: "flex h-max w-full flex-wrap gap-2", children: [
|
|
35270
|
-
conditions.map((condition) => {
|
|
35271
|
-
return condition.render({
|
|
35272
|
-
onRemove: handleDeleteCondition
|
|
35273
|
-
});
|
|
35274
|
-
}),
|
|
35275
|
-
/* @__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" }) }) })
|
|
35276
|
-
] })
|
|
35277
|
-
] });
|
|
35278
|
-
});
|
|
35279
|
-
FieldSectionConditionalItem.displayName = "FieldSectionConditionalItem";
|
|
35280
35257
|
const FieldSectionDropdownMenu = memo((props) => {
|
|
35281
35258
|
const { children, variant, size, accentColor, fieldSections, onSelectFieldCondition, ...rest } = props;
|
|
35282
35259
|
return /* @__PURE__ */ jsxs(Menu.Root, { ...rest, children: [
|
|
@@ -35290,169 +35267,6 @@ const FieldSectionDropdownMenu = memo((props) => {
|
|
|
35290
35267
|
] });
|
|
35291
35268
|
});
|
|
35292
35269
|
FieldSectionDropdownMenu.displayName = "IssueDataFilterMenu";
|
|
35293
|
-
const FieldSectionBuilder = memo((props) => {
|
|
35294
|
-
const { fieldSection } = props;
|
|
35295
|
-
const fieldSchema = use(FieldSchemaContext);
|
|
35296
|
-
const conditionalSections = useMemo(() => {
|
|
35297
|
-
return fieldSchema.fields.filter((section) => fieldSection.identifier in section.conditions);
|
|
35298
|
-
}, [fieldSchema.fields, fieldSection.identifier]);
|
|
35299
|
-
const handleAddConditional = useCallback(
|
|
35300
|
-
(conditionalSection) => {
|
|
35301
|
-
conditionalSection.addConditional(fieldSection.identifier);
|
|
35302
|
-
},
|
|
35303
|
-
[fieldSection.identifier]
|
|
35304
|
-
);
|
|
35305
|
-
const validFieldSections = useMemo(() => {
|
|
35306
|
-
const graph = new DirectedGraph({});
|
|
35307
|
-
for (const sourceSection of fieldSchema.fields) {
|
|
35308
|
-
for (const targetSectionId of Object.keys(sourceSection.conditions)) {
|
|
35309
|
-
graph.mergeEdge(sourceSection.identifier, targetSectionId);
|
|
35310
|
-
}
|
|
35311
|
-
}
|
|
35312
|
-
return fieldSchema.fields.filter(
|
|
35313
|
-
(sourceSection) => !willCreateCycle(graph, sourceSection.identifier, fieldSection.identifier)
|
|
35314
|
-
);
|
|
35315
|
-
}, [fieldSchema.fields, fieldSection.identifier]);
|
|
35316
|
-
return /* @__PURE__ */ jsxs("div", { className: "flex grow w-full flex-col gap-4", children: [
|
|
35317
|
-
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2 w-full overflow-hidden", children: [
|
|
35318
|
-
/* @__PURE__ */ jsx(Input.Root, { variant: "outline", size: "md", children: /* @__PURE__ */ jsx(
|
|
35319
|
-
Input.Field,
|
|
35320
|
-
{
|
|
35321
|
-
placeholder: "Enter a section label (optional)",
|
|
35322
|
-
value: fieldSection.label ?? "",
|
|
35323
|
-
onChange: (event) => fieldSection.setOptions({ label: event.target.value }),
|
|
35324
|
-
maxLength: 200
|
|
35325
|
-
}
|
|
35326
|
-
) }),
|
|
35327
|
-
/* @__PURE__ */ jsx(
|
|
35328
|
-
TextArea,
|
|
35329
|
-
{
|
|
35330
|
-
className: "field-sizing-content",
|
|
35331
|
-
placeholder: "Enter a section description (optional)",
|
|
35332
|
-
value: fieldSection.description ?? "",
|
|
35333
|
-
onChange: (event) => fieldSection.setOptions({ description: event.target.value }),
|
|
35334
|
-
maxLength: 1e3,
|
|
35335
|
-
resize: "vertical",
|
|
35336
|
-
size: "md"
|
|
35337
|
-
}
|
|
35338
|
-
)
|
|
35339
|
-
] }),
|
|
35340
|
-
/* @__PURE__ */ jsx(Separator, { size: "full" }),
|
|
35341
|
-
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
|
|
35342
|
-
/* @__PURE__ */ jsxs("div", { className: "flex gap-2 justify-between", children: [
|
|
35343
|
-
/* @__PURE__ */ jsx(Text, { accentColor: "base", children: "Conditions" }),
|
|
35344
|
-
/* @__PURE__ */ jsx(
|
|
35345
|
-
FieldSectionDropdownMenu,
|
|
35346
|
-
{
|
|
35347
|
-
fieldSections: validFieldSections,
|
|
35348
|
-
onSelectFieldCondition: handleAddConditional,
|
|
35349
|
-
children: /* @__PURE__ */ jsxs(Button, { type: "button", variant: "soft", size: "sm", className: "w-max", children: [
|
|
35350
|
-
/* @__PURE__ */ jsx(LuIcon, { icon: "plus" }),
|
|
35351
|
-
"Add condition"
|
|
35352
|
-
] })
|
|
35353
|
-
}
|
|
35354
|
-
)
|
|
35355
|
-
] }),
|
|
35356
|
-
conditionalSections.map((section) => /* @__PURE__ */ jsx(
|
|
35357
|
-
FieldSectionConditionalItem,
|
|
35358
|
-
{
|
|
35359
|
-
sourceFieldSection: section,
|
|
35360
|
-
targetFieldSection: fieldSection
|
|
35361
|
-
},
|
|
35362
|
-
section.identifier
|
|
35363
|
-
))
|
|
35364
|
-
] }),
|
|
35365
|
-
/* @__PURE__ */ jsx(Separator, { size: "full" })
|
|
35366
|
-
] });
|
|
35367
|
-
});
|
|
35368
|
-
FieldSectionBuilder.displayName = "FieldSectionBuilder";
|
|
35369
|
-
const useFieldTypeItems = (onSelect = () => null) => {
|
|
35370
|
-
return useMemo(() => {
|
|
35371
|
-
const entries = Object.entries(FieldTypeToClsMapping);
|
|
35372
|
-
return entries.map(([type, fieldClass]) => ({
|
|
35373
|
-
children: fieldClass.fieldTypeName,
|
|
35374
|
-
icon: /* @__PURE__ */ jsx(LuIcon, { icon: fieldIcons[type] }),
|
|
35375
|
-
value: type,
|
|
35376
|
-
onSelect: () => {
|
|
35377
|
-
onSelect(type);
|
|
35378
|
-
}
|
|
35379
|
-
}));
|
|
35380
|
-
}, [onSelect]);
|
|
35381
|
-
};
|
|
35382
|
-
const FieldSectionWithActions = memo((props) => {
|
|
35383
|
-
const { fieldSection, index: sectionIndex } = props;
|
|
35384
|
-
const fieldSchema = use(FieldSchemaContext);
|
|
35385
|
-
const removeField = useCallback(
|
|
35386
|
-
(field) => {
|
|
35387
|
-
fieldSection.removeField(field);
|
|
35388
|
-
},
|
|
35389
|
-
[fieldSection]
|
|
35390
|
-
);
|
|
35391
|
-
const removeSection = useCallback(() => {
|
|
35392
|
-
fieldSchema.removeField(fieldSection);
|
|
35393
|
-
}, [fieldSchema, fieldSection]);
|
|
35394
|
-
const moveSection = useCallback(
|
|
35395
|
-
(direction) => {
|
|
35396
|
-
const targetIndex = direction === "up" ? sectionIndex - 1 : sectionIndex + 1;
|
|
35397
|
-
fieldSchema.moveField(sectionIndex, targetIndex);
|
|
35398
|
-
},
|
|
35399
|
-
[fieldSchema, sectionIndex]
|
|
35400
|
-
);
|
|
35401
|
-
const duplicateSection = useCallback(() => {
|
|
35402
|
-
fieldSchema.addField(fieldSection.duplicate(v4()));
|
|
35403
|
-
}, [fieldSchema, fieldSection]);
|
|
35404
|
-
const handleCreateField = useCallback(
|
|
35405
|
-
(type) => {
|
|
35406
|
-
fieldSection.addField(createField(type));
|
|
35407
|
-
},
|
|
35408
|
-
[fieldSection]
|
|
35409
|
-
);
|
|
35410
|
-
const handleMoveUp = useCallback(() => {
|
|
35411
|
-
moveSection("up");
|
|
35412
|
-
}, [moveSection]);
|
|
35413
|
-
const handleMoveDown = useCallback(() => {
|
|
35414
|
-
moveSection("down");
|
|
35415
|
-
}, [moveSection]);
|
|
35416
|
-
const fieldTypeItems = useFieldTypeItems(handleCreateField);
|
|
35417
|
-
return /* @__PURE__ */ jsxs(Card, { variant: "outline", className: "flex items-center justify-between gap-4 w-full", children: [
|
|
35418
|
-
/* @__PURE__ */ jsxs("div", { className: "flex grow flex-col gap-4 w-full", children: [
|
|
35419
|
-
/* @__PURE__ */ jsx(FieldSectionBuilder, { fieldSection }),
|
|
35420
|
-
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2 w-full", children: [
|
|
35421
|
-
/* @__PURE__ */ jsxs("div", { className: "flex gap-2 justify-between", children: [
|
|
35422
|
-
/* @__PURE__ */ jsx(Text, { accentColor: "base", size: "md", children: "Fields" }),
|
|
35423
|
-
/* @__PURE__ */ jsxs(Menu.Root, { children: [
|
|
35424
|
-
/* @__PURE__ */ jsx(Menu.ClickTrigger, { children: /* @__PURE__ */ jsxs(Button, { type: "button", variant: "soft", size: "sm", children: [
|
|
35425
|
-
/* @__PURE__ */ jsx(LuIcon, { icon: "plus" }),
|
|
35426
|
-
" Add field"
|
|
35427
|
-
] }) }),
|
|
35428
|
-
/* @__PURE__ */ jsx(Menu.Content, { children: /* @__PURE__ */ jsx(Menu.Scroll, { children: fieldTypeItems.flat().map((item) => /* @__PURE__ */ jsxs(Menu.Item, { onSelect: item.onSelect, children: [
|
|
35429
|
-
item.icon,
|
|
35430
|
-
item.children
|
|
35431
|
-
] }, item.value)) }) })
|
|
35432
|
-
] })
|
|
35433
|
-
] }),
|
|
35434
|
-
fieldSection.fields.map((child, index) => /* @__PURE__ */ jsx(
|
|
35435
|
-
FieldWithActions,
|
|
35436
|
-
{
|
|
35437
|
-
field: child,
|
|
35438
|
-
fieldSection,
|
|
35439
|
-
index,
|
|
35440
|
-
sectionIndex,
|
|
35441
|
-
remove: removeField
|
|
35442
|
-
},
|
|
35443
|
-
child.identifier
|
|
35444
|
-
))
|
|
35445
|
-
] })
|
|
35446
|
-
] }),
|
|
35447
|
-
/* @__PURE__ */ jsxs(ButtonGroup, { className: "flex-col gap-0.5 flex", variant: "ghost", accentColor: "base", size: "sm", children: [
|
|
35448
|
-
/* @__PURE__ */ jsx(IconButton, { type: "button", onClick: handleMoveUp, children: /* @__PURE__ */ jsx(LuIcon, { icon: "move-up" }) }),
|
|
35449
|
-
/* @__PURE__ */ jsx(IconButton, { type: "button", onClick: handleMoveDown, children: /* @__PURE__ */ jsx(LuIcon, { icon: "move-down" }) }),
|
|
35450
|
-
/* @__PURE__ */ jsx(IconButton, { type: "button", onClick: duplicateSection, children: /* @__PURE__ */ jsx(LuIcon, { icon: "copy" }) }),
|
|
35451
|
-
/* @__PURE__ */ jsx(IconButton, { type: "button", onClick: removeSection, children: /* @__PURE__ */ jsx(LuIcon, { icon: "trash" }) })
|
|
35452
|
-
] })
|
|
35453
|
-
] });
|
|
35454
|
-
});
|
|
35455
|
-
FieldSectionWithActions.displayName = "FieldSectionWithActions";
|
|
35456
35270
|
const FieldWithActions = memo((props) => {
|
|
35457
35271
|
const { field, fieldSection, index, sectionIndex, remove } = props;
|
|
35458
35272
|
const { showError } = useToast();
|
|
@@ -35594,6 +35408,19 @@ const FieldSectionConditionEdgeComponent = memo((props) => {
|
|
|
35594
35408
|
] });
|
|
35595
35409
|
});
|
|
35596
35410
|
FieldSectionConditionEdgeComponent.displayName = "FieldSectionConditionEdgeComponent";
|
|
35411
|
+
const useFieldTypeItems = (onSelect = () => null) => {
|
|
35412
|
+
return useMemo(() => {
|
|
35413
|
+
const entries = Object.entries(FieldTypeToClsMapping);
|
|
35414
|
+
return entries.map(([type, fieldClass]) => ({
|
|
35415
|
+
children: fieldClass.fieldTypeName,
|
|
35416
|
+
icon: /* @__PURE__ */ jsx(LuIcon, { icon: fieldIcons[type] }),
|
|
35417
|
+
value: type,
|
|
35418
|
+
onSelect: () => {
|
|
35419
|
+
onSelect(type);
|
|
35420
|
+
}
|
|
35421
|
+
}));
|
|
35422
|
+
}, [onSelect]);
|
|
35423
|
+
};
|
|
35597
35424
|
const FieldSectionNodeComponent = memo((props) => {
|
|
35598
35425
|
const { data, selected } = props;
|
|
35599
35426
|
const { fieldSection, index: sectionIndex, layoutDirection } = data;
|
|
@@ -35940,6 +35767,195 @@ const FormBuilderFlowBuilder = memo(() => {
|
|
|
35940
35767
|
] });
|
|
35941
35768
|
});
|
|
35942
35769
|
FormBuilderFlowBuilder.displayName = "FormBuilderFlowBuilder";
|
|
35770
|
+
const FieldSectionConditionalItem = memo((props) => {
|
|
35771
|
+
const { sourceFieldSection, targetFieldSection } = props;
|
|
35772
|
+
const conditions = useMemo(() => {
|
|
35773
|
+
return sourceFieldSection.getConditions(targetFieldSection.identifier);
|
|
35774
|
+
}, [sourceFieldSection, targetFieldSection.identifier]);
|
|
35775
|
+
const handleDelete = useCallback(() => {
|
|
35776
|
+
sourceFieldSection.removeConditional(targetFieldSection.identifier);
|
|
35777
|
+
}, [sourceFieldSection, targetFieldSection.identifier]);
|
|
35778
|
+
const handleSelectField = useCallback(
|
|
35779
|
+
(field) => {
|
|
35780
|
+
sourceFieldSection.addCondition(targetFieldSection.identifier, createCondition(field));
|
|
35781
|
+
},
|
|
35782
|
+
[sourceFieldSection, targetFieldSection.identifier]
|
|
35783
|
+
);
|
|
35784
|
+
const handleDeleteCondition = useCallback(
|
|
35785
|
+
(condition) => {
|
|
35786
|
+
sourceFieldSection.removeCondition(targetFieldSection.identifier, condition);
|
|
35787
|
+
},
|
|
35788
|
+
[sourceFieldSection, targetFieldSection.identifier]
|
|
35789
|
+
);
|
|
35790
|
+
return /* @__PURE__ */ jsxs(Card, { className: "flex flex-col gap-2", children: [
|
|
35791
|
+
/* @__PURE__ */ jsxs(ButtonGroup, { className: "justify-between gap-2 flex", size: "sm", accentColor: "base", variant: "soft", children: [
|
|
35792
|
+
/* @__PURE__ */ jsxs(Badge, { accentColor: "base", variant: "soft", size: "sm", children: [
|
|
35793
|
+
/* @__PURE__ */ jsx(LuIcon, { icon: fieldIcons.section }),
|
|
35794
|
+
sourceFieldSection.label ?? UNLABELLED_SECTION_LABEL
|
|
35795
|
+
] }),
|
|
35796
|
+
/* @__PURE__ */ jsx(IconButton, { type: "button", onClick: handleDelete, variant: "ghost", children: /* @__PURE__ */ jsx(LuIcon, { icon: "trash" }) })
|
|
35797
|
+
] }),
|
|
35798
|
+
/* @__PURE__ */ jsxs("div", { className: "flex h-max w-full flex-wrap gap-2", children: [
|
|
35799
|
+
conditions.map((condition) => {
|
|
35800
|
+
return condition.render({
|
|
35801
|
+
onRemove: handleDeleteCondition
|
|
35802
|
+
});
|
|
35803
|
+
}),
|
|
35804
|
+
/* @__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" }) }) })
|
|
35805
|
+
] })
|
|
35806
|
+
] });
|
|
35807
|
+
});
|
|
35808
|
+
FieldSectionConditionalItem.displayName = "FieldSectionConditionalItem";
|
|
35809
|
+
const FieldSectionBuilder = memo((props) => {
|
|
35810
|
+
const { fieldSection } = props;
|
|
35811
|
+
const fieldSchema = use(FieldSchemaContext);
|
|
35812
|
+
const conditionalSections = useMemo(() => {
|
|
35813
|
+
return fieldSchema.fields.filter((section) => fieldSection.identifier in section.conditions);
|
|
35814
|
+
}, [fieldSchema.fields, fieldSection.identifier]);
|
|
35815
|
+
const handleAddConditional = useCallback(
|
|
35816
|
+
(conditionalSection) => {
|
|
35817
|
+
conditionalSection.addConditional(fieldSection.identifier);
|
|
35818
|
+
},
|
|
35819
|
+
[fieldSection.identifier]
|
|
35820
|
+
);
|
|
35821
|
+
const validFieldSections = useMemo(() => {
|
|
35822
|
+
const graph = new DirectedGraph({});
|
|
35823
|
+
for (const sourceSection of fieldSchema.fields) {
|
|
35824
|
+
for (const targetSectionId of Object.keys(sourceSection.conditions)) {
|
|
35825
|
+
graph.mergeEdge(sourceSection.identifier, targetSectionId);
|
|
35826
|
+
}
|
|
35827
|
+
}
|
|
35828
|
+
return fieldSchema.fields.filter(
|
|
35829
|
+
(sourceSection) => !willCreateCycle(graph, sourceSection.identifier, fieldSection.identifier)
|
|
35830
|
+
);
|
|
35831
|
+
}, [fieldSchema.fields, fieldSection.identifier]);
|
|
35832
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex grow w-full flex-col gap-4", children: [
|
|
35833
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2 w-full overflow-hidden", children: [
|
|
35834
|
+
/* @__PURE__ */ jsx(Input.Root, { variant: "outline", size: "md", children: /* @__PURE__ */ jsx(
|
|
35835
|
+
Input.Field,
|
|
35836
|
+
{
|
|
35837
|
+
placeholder: "Enter a section label (optional)",
|
|
35838
|
+
value: fieldSection.label ?? "",
|
|
35839
|
+
onChange: (event) => fieldSection.setOptions({ label: event.target.value }),
|
|
35840
|
+
maxLength: 200
|
|
35841
|
+
}
|
|
35842
|
+
) }),
|
|
35843
|
+
/* @__PURE__ */ jsx(
|
|
35844
|
+
TextArea,
|
|
35845
|
+
{
|
|
35846
|
+
className: "field-sizing-content",
|
|
35847
|
+
placeholder: "Enter a section description (optional)",
|
|
35848
|
+
value: fieldSection.description ?? "",
|
|
35849
|
+
onChange: (event) => fieldSection.setOptions({ description: event.target.value }),
|
|
35850
|
+
maxLength: 1e3,
|
|
35851
|
+
resize: "vertical",
|
|
35852
|
+
size: "md"
|
|
35853
|
+
}
|
|
35854
|
+
)
|
|
35855
|
+
] }),
|
|
35856
|
+
/* @__PURE__ */ jsx(Separator, { size: "full" }),
|
|
35857
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
|
|
35858
|
+
/* @__PURE__ */ jsxs("div", { className: "flex gap-2 justify-between", children: [
|
|
35859
|
+
/* @__PURE__ */ jsx(Text, { accentColor: "base", children: "Conditions" }),
|
|
35860
|
+
/* @__PURE__ */ jsx(
|
|
35861
|
+
FieldSectionDropdownMenu,
|
|
35862
|
+
{
|
|
35863
|
+
fieldSections: validFieldSections,
|
|
35864
|
+
onSelectFieldCondition: handleAddConditional,
|
|
35865
|
+
children: /* @__PURE__ */ jsxs(Button, { type: "button", variant: "soft", size: "sm", className: "w-max", children: [
|
|
35866
|
+
/* @__PURE__ */ jsx(LuIcon, { icon: "plus" }),
|
|
35867
|
+
"Add condition"
|
|
35868
|
+
] })
|
|
35869
|
+
}
|
|
35870
|
+
)
|
|
35871
|
+
] }),
|
|
35872
|
+
conditionalSections.map((section) => /* @__PURE__ */ jsx(
|
|
35873
|
+
FieldSectionConditionalItem,
|
|
35874
|
+
{
|
|
35875
|
+
sourceFieldSection: section,
|
|
35876
|
+
targetFieldSection: fieldSection
|
|
35877
|
+
},
|
|
35878
|
+
section.identifier
|
|
35879
|
+
))
|
|
35880
|
+
] }),
|
|
35881
|
+
/* @__PURE__ */ jsx(Separator, { size: "full" })
|
|
35882
|
+
] });
|
|
35883
|
+
});
|
|
35884
|
+
FieldSectionBuilder.displayName = "FieldSectionBuilder";
|
|
35885
|
+
const FieldSectionWithActions = memo((props) => {
|
|
35886
|
+
const { fieldSection, index: sectionIndex } = props;
|
|
35887
|
+
const fieldSchema = use(FieldSchemaContext);
|
|
35888
|
+
const removeField = useCallback(
|
|
35889
|
+
(field) => {
|
|
35890
|
+
fieldSection.removeField(field);
|
|
35891
|
+
},
|
|
35892
|
+
[fieldSection]
|
|
35893
|
+
);
|
|
35894
|
+
const removeSection = useCallback(() => {
|
|
35895
|
+
fieldSchema.removeField(fieldSection);
|
|
35896
|
+
}, [fieldSchema, fieldSection]);
|
|
35897
|
+
const moveSection = useCallback(
|
|
35898
|
+
(direction) => {
|
|
35899
|
+
const targetIndex = direction === "up" ? sectionIndex - 1 : sectionIndex + 1;
|
|
35900
|
+
fieldSchema.moveField(sectionIndex, targetIndex);
|
|
35901
|
+
},
|
|
35902
|
+
[fieldSchema, sectionIndex]
|
|
35903
|
+
);
|
|
35904
|
+
const duplicateSection = useCallback(() => {
|
|
35905
|
+
fieldSchema.addField(fieldSection.duplicate(v4()));
|
|
35906
|
+
}, [fieldSchema, fieldSection]);
|
|
35907
|
+
const handleCreateField = useCallback(
|
|
35908
|
+
(type) => {
|
|
35909
|
+
fieldSection.addField(createField(type));
|
|
35910
|
+
},
|
|
35911
|
+
[fieldSection]
|
|
35912
|
+
);
|
|
35913
|
+
const handleMoveUp = useCallback(() => {
|
|
35914
|
+
moveSection("up");
|
|
35915
|
+
}, [moveSection]);
|
|
35916
|
+
const handleMoveDown = useCallback(() => {
|
|
35917
|
+
moveSection("down");
|
|
35918
|
+
}, [moveSection]);
|
|
35919
|
+
const fieldTypeItems = useFieldTypeItems(handleCreateField);
|
|
35920
|
+
return /* @__PURE__ */ jsxs(Card, { variant: "outline", className: "flex items-center justify-between gap-4 w-full", children: [
|
|
35921
|
+
/* @__PURE__ */ jsxs("div", { className: "flex grow flex-col gap-4 w-full", children: [
|
|
35922
|
+
/* @__PURE__ */ jsx(FieldSectionBuilder, { fieldSection }),
|
|
35923
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2 w-full", children: [
|
|
35924
|
+
/* @__PURE__ */ jsxs("div", { className: "flex gap-2 justify-between", children: [
|
|
35925
|
+
/* @__PURE__ */ jsx(Text, { accentColor: "base", size: "md", children: "Fields" }),
|
|
35926
|
+
/* @__PURE__ */ jsxs(Menu.Root, { children: [
|
|
35927
|
+
/* @__PURE__ */ jsx(Menu.ClickTrigger, { children: /* @__PURE__ */ jsxs(Button, { type: "button", variant: "soft", size: "sm", children: [
|
|
35928
|
+
/* @__PURE__ */ jsx(LuIcon, { icon: "plus" }),
|
|
35929
|
+
" Add field"
|
|
35930
|
+
] }) }),
|
|
35931
|
+
/* @__PURE__ */ jsx(Menu.Content, { children: /* @__PURE__ */ jsx(Menu.Scroll, { children: fieldTypeItems.flat().map((item) => /* @__PURE__ */ jsxs(Menu.Item, { onSelect: item.onSelect, children: [
|
|
35932
|
+
item.icon,
|
|
35933
|
+
item.children
|
|
35934
|
+
] }, item.value)) }) })
|
|
35935
|
+
] })
|
|
35936
|
+
] }),
|
|
35937
|
+
fieldSection.fields.map((child, index) => /* @__PURE__ */ jsx(
|
|
35938
|
+
FieldWithActions,
|
|
35939
|
+
{
|
|
35940
|
+
field: child,
|
|
35941
|
+
fieldSection,
|
|
35942
|
+
index,
|
|
35943
|
+
sectionIndex,
|
|
35944
|
+
remove: removeField
|
|
35945
|
+
},
|
|
35946
|
+
child.identifier
|
|
35947
|
+
))
|
|
35948
|
+
] })
|
|
35949
|
+
] }),
|
|
35950
|
+
/* @__PURE__ */ jsxs(ButtonGroup, { className: "flex-col gap-0.5 flex", variant: "ghost", accentColor: "base", size: "sm", children: [
|
|
35951
|
+
/* @__PURE__ */ jsx(IconButton, { type: "button", onClick: handleMoveUp, children: /* @__PURE__ */ jsx(LuIcon, { icon: "move-up" }) }),
|
|
35952
|
+
/* @__PURE__ */ jsx(IconButton, { type: "button", onClick: handleMoveDown, children: /* @__PURE__ */ jsx(LuIcon, { icon: "move-down" }) }),
|
|
35953
|
+
/* @__PURE__ */ jsx(IconButton, { type: "button", onClick: duplicateSection, children: /* @__PURE__ */ jsx(LuIcon, { icon: "copy" }) }),
|
|
35954
|
+
/* @__PURE__ */ jsx(IconButton, { type: "button", onClick: removeSection, children: /* @__PURE__ */ jsx(LuIcon, { icon: "trash" }) })
|
|
35955
|
+
] })
|
|
35956
|
+
] });
|
|
35957
|
+
});
|
|
35958
|
+
FieldSectionWithActions.displayName = "FieldSectionWithActions";
|
|
35943
35959
|
const FormBuilderListBuilder = memo(() => {
|
|
35944
35960
|
const { handleSubmit, errors } = useFormikContext();
|
|
35945
35961
|
const { hideTitle, hideDescription, onCancel } = use(FormBuilderContext);
|
|
@@ -36009,6 +36025,113 @@ const FormBuilderListBuilder = memo(() => {
|
|
|
36009
36025
|
] });
|
|
36010
36026
|
});
|
|
36011
36027
|
FormBuilderListBuilder.displayName = "FormBuilderListBuilder";
|
|
36028
|
+
const validateFields = (fields, values) => {
|
|
36029
|
+
const errors = {};
|
|
36030
|
+
const sectionElements = fields.filter((f) => f instanceof FieldSection);
|
|
36031
|
+
for (const field of fields) {
|
|
36032
|
+
if (field instanceof FieldSection) {
|
|
36033
|
+
const conditionalSections = sectionElements.filter((section) => field.identifier in section.conditions);
|
|
36034
|
+
const conditionMet = conditionalSections.length > 0 ? conditionalSections.some(
|
|
36035
|
+
(conditionalSection) => applyConditions(conditionalSection.getConditions(field.identifier), values)
|
|
36036
|
+
) : true;
|
|
36037
|
+
if (!conditionMet) continue;
|
|
36038
|
+
Object.assign(errors, field.getErrors(values));
|
|
36039
|
+
} else {
|
|
36040
|
+
if (!(field instanceof BaseField)) {
|
|
36041
|
+
throw new Error("Invalid field type");
|
|
36042
|
+
}
|
|
36043
|
+
const id = field.identifier;
|
|
36044
|
+
const error = field.getError(get(values, id));
|
|
36045
|
+
if (error) set(errors, id, error);
|
|
36046
|
+
}
|
|
36047
|
+
}
|
|
36048
|
+
if (Object.keys(errors).length > 0) return errors;
|
|
36049
|
+
};
|
|
36050
|
+
const initializeFieldValues = (fields, values) => {
|
|
36051
|
+
const ret = {};
|
|
36052
|
+
for (const field of fields) {
|
|
36053
|
+
const value = values[field.identifier];
|
|
36054
|
+
ret[field.identifier] = value !== void 0 ? value : field.blankValue();
|
|
36055
|
+
}
|
|
36056
|
+
return ret;
|
|
36057
|
+
};
|
|
36058
|
+
const changedFieldValues = (fields, values1, values2) => {
|
|
36059
|
+
const ret = {};
|
|
36060
|
+
for (const field of fields) {
|
|
36061
|
+
const value1 = values1[field.identifier];
|
|
36062
|
+
const value2 = values2[field.identifier];
|
|
36063
|
+
if (field.areValuesEqual(value1, value2)) continue;
|
|
36064
|
+
ret[field.identifier] = value2;
|
|
36065
|
+
}
|
|
36066
|
+
return ret;
|
|
36067
|
+
};
|
|
36068
|
+
const unchangedFieldValues = (fields, values1, values2) => {
|
|
36069
|
+
const ret = {};
|
|
36070
|
+
for (const field of fields) {
|
|
36071
|
+
const value1 = values1[field.identifier];
|
|
36072
|
+
const value2 = values2[field.identifier];
|
|
36073
|
+
if (!field.areValuesEqual(value1, value2)) continue;
|
|
36074
|
+
ret[field.identifier] = value2;
|
|
36075
|
+
}
|
|
36076
|
+
return ret;
|
|
36077
|
+
};
|
|
36078
|
+
const isArrayOfFiles = (value) => {
|
|
36079
|
+
return Array.isArray(value) && value[0] instanceof File;
|
|
36080
|
+
};
|
|
36081
|
+
const separateFilesFromFieldValues = (values) => {
|
|
36082
|
+
const files = {};
|
|
36083
|
+
const newValues = {};
|
|
36084
|
+
for (const key in values) {
|
|
36085
|
+
const value = values[key];
|
|
36086
|
+
if (value instanceof File) {
|
|
36087
|
+
files[key] = [value];
|
|
36088
|
+
} else if (isArrayOfFiles(value)) {
|
|
36089
|
+
files[key] = value;
|
|
36090
|
+
} else if (value !== void 0) {
|
|
36091
|
+
newValues[key] = value;
|
|
36092
|
+
}
|
|
36093
|
+
}
|
|
36094
|
+
return { values: newValues, files };
|
|
36095
|
+
};
|
|
36096
|
+
const separateFilesFromFields = async (fields) => {
|
|
36097
|
+
const images = {};
|
|
36098
|
+
const newFields = [];
|
|
36099
|
+
for (const section of fields) {
|
|
36100
|
+
if (section.type !== "section") {
|
|
36101
|
+
throw new Error(`Expected ISerializedField type to be a section. Got ${section.type} instead.`);
|
|
36102
|
+
}
|
|
36103
|
+
const { fields: sectionFields } = section;
|
|
36104
|
+
const newSectionFields = [];
|
|
36105
|
+
for (const field of sectionFields) {
|
|
36106
|
+
if (field.image) {
|
|
36107
|
+
if (field.image instanceof Promise) {
|
|
36108
|
+
try {
|
|
36109
|
+
images[field.identifier] = await field.image;
|
|
36110
|
+
} catch (e) {
|
|
36111
|
+
console.error("Failed to get image from promise", e);
|
|
36112
|
+
}
|
|
36113
|
+
} else {
|
|
36114
|
+
images[field.identifier] = field.image;
|
|
36115
|
+
}
|
|
36116
|
+
delete field.image;
|
|
36117
|
+
}
|
|
36118
|
+
newSectionFields.push(field);
|
|
36119
|
+
}
|
|
36120
|
+
newFields.push({ ...section, fields: newSectionFields });
|
|
36121
|
+
}
|
|
36122
|
+
return { fields: newFields, images };
|
|
36123
|
+
};
|
|
36124
|
+
async function awaitPromisesFromFieldValues(values) {
|
|
36125
|
+
const valuesWithoutFiles = {};
|
|
36126
|
+
for (const [key, value] of Object.entries(values)) {
|
|
36127
|
+
if (Array.isArray(value) && value.every((item) => item instanceof Promise)) {
|
|
36128
|
+
valuesWithoutFiles[key] = await Promise.all(value);
|
|
36129
|
+
} else {
|
|
36130
|
+
valuesWithoutFiles[key] = value;
|
|
36131
|
+
}
|
|
36132
|
+
}
|
|
36133
|
+
return valuesWithoutFiles;
|
|
36134
|
+
}
|
|
36012
36135
|
const FormRenderer = memo(
|
|
36013
36136
|
forwardRef((props, ref) => {
|
|
36014
36137
|
const {
|
|
@@ -36032,11 +36155,13 @@ const FormRenderer = memo(
|
|
|
36032
36155
|
const { readonly } = schema.meta;
|
|
36033
36156
|
const formId2 = useId$1();
|
|
36034
36157
|
const initialValues = useMemo(() => {
|
|
36035
|
-
return initializeFieldValues(schema.fields, values);
|
|
36158
|
+
return initializeFieldValues(flattenFields(schema.fields), values);
|
|
36036
36159
|
}, [schema.fields, values]);
|
|
36037
36160
|
const handleSubmit = useCallback(
|
|
36038
36161
|
(values2) => {
|
|
36039
|
-
onSubmit == null ? void 0 : onSubmit(
|
|
36162
|
+
onSubmit == null ? void 0 : onSubmit(
|
|
36163
|
+
excludeUnchangedFields ? changedFieldValues(flattenFields(schema.fields), initialValues, values2) : values2
|
|
36164
|
+
);
|
|
36040
36165
|
},
|
|
36041
36166
|
[excludeUnchangedFields, initialValues, onSubmit, schema.fields]
|
|
36042
36167
|
);
|
|
@@ -36060,7 +36185,7 @@ const FormRenderer = memo(
|
|
|
36060
36185
|
const handleValuesChange = useCallback(
|
|
36061
36186
|
(identifier, value) => {
|
|
36062
36187
|
const field = getFieldsMapping(schema.fields)[identifier];
|
|
36063
|
-
if (field.
|
|
36188
|
+
if (field.areValuesEqual(initialValues[identifier], value)) return;
|
|
36064
36189
|
onValuesChange == null ? void 0 : onValuesChange({ ...formik.values, [identifier]: value }, { [identifier]: value });
|
|
36065
36190
|
},
|
|
36066
36191
|
[formik.values, initialValues, onValuesChange, schema.fields]
|
|
@@ -36173,7 +36298,7 @@ const FormBuilderRoot = memo((props) => {
|
|
|
36173
36298
|
if (fieldErrors) {
|
|
36174
36299
|
errors.fields = fieldErrors.fields;
|
|
36175
36300
|
}
|
|
36176
|
-
if (
|
|
36301
|
+
if (Object.keys(errors).length > 0) {
|
|
36177
36302
|
showError({
|
|
36178
36303
|
title: "Some form settings are invalid",
|
|
36179
36304
|
description: "Please check settings highlighted in red."
|
|
@@ -36333,6 +36458,9 @@ export {
|
|
|
36333
36458
|
UploadInput,
|
|
36334
36459
|
applyConditions,
|
|
36335
36460
|
awaitPromisesFromFieldValues,
|
|
36461
|
+
changedFieldValues,
|
|
36462
|
+
cleanFieldValues,
|
|
36463
|
+
cleanSerializedFieldValues,
|
|
36336
36464
|
createCondition,
|
|
36337
36465
|
createConditionModifierConfig,
|
|
36338
36466
|
createField,
|
|
@@ -36347,12 +36475,15 @@ export {
|
|
|
36347
36475
|
flattenFields,
|
|
36348
36476
|
getFieldsMapping,
|
|
36349
36477
|
initializeFieldValues,
|
|
36478
|
+
isFilePromiseArray,
|
|
36479
|
+
isStringArray,
|
|
36350
36480
|
maxFileSizeB,
|
|
36351
36481
|
maxFileSizeKB,
|
|
36352
36482
|
maxFileSizeMB,
|
|
36353
36483
|
separateFilesFromFieldValues,
|
|
36354
36484
|
separateFilesFromFields,
|
|
36355
36485
|
serializeFieldValues,
|
|
36486
|
+
unchangedFieldValues,
|
|
36356
36487
|
useFieldInput,
|
|
36357
36488
|
useFieldInputs,
|
|
36358
36489
|
useFormikInput,
|