impact-nova 2.3.0 → 2.4.0
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/filter-shell/index.d.ts +12 -0
- package/dist/filter-shell/index.js +9 -0
- package/dist/filter-shell/utils/buildFilterFieldValidationRules.d.ts +1 -0
- package/dist/filter-shell/utils/validateVisibleRequiredFilterFields.d.ts +1 -0
- package/dist/filter-shell/utils/validationNavigation.utils.d.ts +26 -0
- package/dist/filter-shell/utils/validationNavigation.utils.js +38 -0
- package/dist/form-engine/field-dependency-graph.d.ts +17 -0
- package/dist/form-engine/field-dependency-graph.js +90 -0
- package/dist/form-engine/index.d.ts +9 -0
- package/dist/form-engine/index.js +16 -0
- package/dist/form-engine/is-empty-value.d.ts +1 -0
- package/dist/form-engine/is-empty-value.js +8 -0
- package/dist/form-engine/types.d.ts +17 -0
- package/dist/form-react/Fields/ButtonsGroupField.d.ts +3 -0
- package/dist/form-react/Fields/ButtonsGroupField.js +52 -0
- package/dist/form-react/Fields/CheckboxField.d.ts +3 -0
- package/dist/form-react/Fields/CheckboxField.js +46 -0
- package/dist/form-react/Fields/ChipsField.d.ts +3 -0
- package/dist/form-react/Fields/ChipsField.js +146 -0
- package/dist/form-react/Fields/DateInputField.d.ts +8 -0
- package/dist/form-react/Fields/DateInputField.js +134 -0
- package/dist/form-react/Fields/DateRangeField.d.ts +8 -0
- package/dist/form-react/Fields/DateRangeField.js +57 -0
- package/dist/form-react/Fields/DividerField.d.ts +3 -0
- package/dist/form-react/Fields/DividerField.js +9 -0
- package/dist/form-react/Fields/DividerWithLabelField.d.ts +3 -0
- package/dist/form-react/Fields/DividerWithLabelField.js +31 -0
- package/dist/form-react/Fields/FileUploadField.d.ts +3 -0
- package/dist/form-react/Fields/FileUploadField.js +42 -0
- package/dist/form-react/Fields/FillFormByFileUploadField.d.ts +3 -0
- package/dist/form-react/Fields/FillFormByFileUploadField.js +65 -0
- package/dist/form-react/Fields/FillFormByPasteField.d.ts +3 -0
- package/dist/form-react/Fields/FillFormByPasteField.js +106 -0
- package/dist/form-react/Fields/LabelField.d.ts +3 -0
- package/dist/form-react/Fields/LabelField.js +14 -0
- package/dist/form-react/Fields/MonthRangeField.d.ts +8 -0
- package/dist/form-react/Fields/MonthRangeField.js +72 -0
- package/dist/form-react/Fields/MultiMonthPickerField.d.ts +8 -0
- package/dist/form-react/Fields/MultiMonthPickerField.js +46 -0
- package/dist/form-react/Fields/MultiWeekPickerField.d.ts +8 -0
- package/dist/form-react/Fields/MultiWeekPickerField.js +47 -0
- package/dist/form-react/Fields/NumericComboboxField.d.ts +18 -0
- package/dist/form-react/Fields/NumericComboboxField.js +51 -0
- package/dist/form-react/Fields/RadioField.d.ts +3 -0
- package/dist/form-react/Fields/RadioField.js +68 -0
- package/dist/form-react/Fields/SelectField.d.ts +3 -0
- package/dist/form-react/Fields/SelectField.js +76 -0
- package/dist/form-react/Fields/SwitchField.d.ts +3 -0
- package/dist/form-react/Fields/SwitchField.js +47 -0
- package/dist/form-react/Fields/TextAreaField.d.ts +3 -0
- package/dist/form-react/Fields/TextAreaField.js +41 -0
- package/dist/form-react/Fields/TextField.d.ts +3 -0
- package/dist/form-react/Fields/TextField.js +75 -0
- package/dist/form-react/Fields/TextFieldWithBackendValidation.d.ts +3 -0
- package/dist/form-react/Fields/TextFieldWithBackendValidation.js +117 -0
- package/dist/form-react/Fields/WeekRangePicker.d.ts +8 -0
- package/dist/form-react/Fields/WeekRangePicker.js +71 -0
- package/dist/form-react/ReactHooksForm.d.ts +3 -0
- package/dist/form-react/ReactHooksForm.js +132 -0
- package/dist/form-react/components/ArrayFieldRenderer.d.ts +13 -0
- package/dist/form-react/components/ArrayFieldRenderer.js +90 -0
- package/dist/form-react/components/FieldRenderer.d.ts +16 -0
- package/dist/form-react/components/FieldRenderer.js +68 -0
- package/dist/form-react/components/FormFieldRow.d.ts +13 -0
- package/dist/form-react/components/FormFieldRow.js +47 -0
- package/dist/form-react/components/FormFileUploadWrapper.d.ts +22 -0
- package/dist/form-react/components/FormFileUploadWrapper.js +88 -0
- package/dist/form-react/components/ObjectFieldRenderer.d.ts +13 -0
- package/dist/form-react/components/ObjectFieldRenderer.js +46 -0
- package/dist/form-react/components/SetToEmptyWrapper.d.ts +16 -0
- package/dist/form-react/components/SetToEmptyWrapper.js +49 -0
- package/dist/form-react/fields.d.ts +23 -0
- package/dist/form-react/fields.js +40 -0
- package/dist/form-react/hooks/useCascadingForm.d.ts +17 -0
- package/dist/form-react/hooks/useCascadingForm.js +122 -0
- package/dist/form-react/hooks/useFieldVisibility.d.ts +14 -0
- package/dist/form-react/hooks/useFieldVisibility.js +60 -0
- package/dist/form-react/hooks/useFillFormByFileUpload.d.ts +33 -0
- package/dist/form-react/hooks/useFillFormByFileUpload.js +199 -0
- package/dist/form-react/hooks/useFillFormByPaste.d.ts +33 -0
- package/dist/form-react/hooks/useFillFormByPaste.js +104 -0
- package/dist/form-react/hooks/useFormFieldChangeSubscription.d.ts +13 -0
- package/dist/form-react/hooks/useFormFieldChangeSubscription.js +42 -0
- package/dist/form-react/hooks/useReactHookForm.d.ts +3 -0
- package/dist/form-react/hooks/useReactHookForm.js +161 -0
- package/dist/form-react/hooks/useSelectOptions.d.ts +8 -0
- package/dist/form-react/hooks/useSelectOptions.js +116 -0
- package/dist/form-react/index.d.ts +62 -0
- package/dist/form-react/index.js +97 -0
- package/dist/form-react/registry/defaultFieldRegistrations.d.ts +2 -0
- package/dist/form-react/registry/defaultFieldRegistrations.js +30 -0
- package/dist/form-react/registry/fieldRegistry.d.ts +14 -0
- package/dist/form-react/registry/fieldRegistry.js +19 -0
- package/dist/form-react/registry/resolveFieldComponent.d.ts +10 -0
- package/dist/form-react/registry/resolveFieldComponent.js +137 -0
- package/dist/form-react/types/fields.types.d.ts +402 -0
- package/dist/form-react/types/fieldsOutput.types.d.ts +73 -0
- package/dist/form-react/types/reactHookForm.types.d.ts +196 -0
- package/dist/form-react/utils/batchFormFieldUpdates.d.ts +14 -0
- package/dist/form-react/utils/batchFormFieldUpdates.js +13 -0
- package/dist/form-react/utils/buildFieldValidationRules.d.ts +6 -0
- package/dist/form-react/utils/buildFieldValidationRules.js +13 -0
- package/dist/form-react/utils/buildSelectRemountKey.d.ts +14 -0
- package/dist/form-react/utils/buildSelectRemountKey.js +14 -0
- package/dist/form-react/utils/calendar-boundary.d.ts +3 -0
- package/dist/form-react/utils/calendar-boundary.js +33 -0
- package/dist/form-react/utils/date.utils.d.ts +31 -0
- package/dist/form-react/utils/date.utils.js +86 -0
- package/dist/form-react/utils/evaluateFieldValidation.d.ts +19 -0
- package/dist/form-react/utils/evaluateFieldValidation.js +53 -0
- package/dist/form-react/utils/fieldDefaults.utils.d.ts +6 -0
- package/dist/form-react/utils/fieldDefaults.utils.js +25 -0
- package/dist/form-react/utils/fieldPath.utils.d.ts +23 -0
- package/dist/form-react/utils/fieldPath.utils.js +26 -0
- package/dist/form-react/utils/fieldRangeValidation.utils.d.ts +3 -0
- package/dist/form-react/utils/fieldRangeValidation.utils.js +24 -0
- package/dist/form-react/utils/fieldRendererUtils.d.ts +10 -0
- package/dist/form-react/utils/fieldRendererUtils.js +47 -0
- package/dist/form-react/utils/fieldTestIds.d.ts +3 -0
- package/dist/form-react/utils/fieldTestIds.js +13 -0
- package/dist/form-react/utils/formDate.utils.d.ts +13 -0
- package/dist/form-react/utils/formDate.utils.js +9 -0
- package/dist/form-react/utils/formValidationFeedback.utils.d.ts +32 -0
- package/dist/form-react/utils/formValidationFeedback.utils.js +153 -0
- package/dist/form-react/utils/icons.d.ts +5 -0
- package/dist/form-react/utils/icons.js +10 -0
- package/dist/form-react/utils/optionFlag.d.ts +11 -0
- package/dist/form-react/utils/optionFlag.js +17 -0
- package/dist/form-react/utils/pastedValues.d.ts +1 -0
- package/dist/form-react/utils/resolveFormSubmittable.d.ts +18 -0
- package/dist/form-react/utils/resolveFormSubmittable.js +32 -0
- package/dist/form-react/utils/select-option-filter-values.d.ts +5 -0
- package/dist/form-react/utils/select-option-filter-values.js +30 -0
- package/dist/form-react/utils/serializeFormStateForQueryKey.d.ts +1 -0
- package/dist/form-react/utils/serializeFormStateForQueryKey.js +21 -0
- package/dist/form-react/utils/stableSerialize.d.ts +5 -0
- package/dist/form-react/utils/stableSerialize.js +11 -0
- package/dist/form-react/utils/validateVisibleRequiredFormFields.d.ts +21 -0
- package/dist/form-react/utils/validateVisibleRequiredFormFields.js +64 -0
- package/dist/form-react/utils/validationUtils.d.ts +3 -0
- package/dist/form-react/utils/validationUtils.js +77 -0
- package/dist/impact-nova.css +1 -1
- package/dist/lib/primitives/use-field-chrome.js +16 -16
- package/dist/llms/rules/installation.js +1 -1
- package/dist/llms/rules/real-world-patterns.js +1 -1
- package/dist/llms/rules/requirements.js +1 -1
- package/package.json +21 -2
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { UseFormReturn } from 'react-hook-form';
|
|
2
|
+
import { IFormConfig, FieldVisibilityBase, ReactHookFormState } from '../types/reactHookForm.types';
|
|
3
|
+
interface UseFieldVisibilityParams {
|
|
4
|
+
form: UseFormReturn<ReactHookFormState>;
|
|
5
|
+
formConfig: IFormConfig;
|
|
6
|
+
isCascadingDisabled: (field: FieldVisibilityBase) => boolean;
|
|
7
|
+
}
|
|
8
|
+
export interface UseFieldVisibilityReturn {
|
|
9
|
+
isFieldVisible: (field: FieldVisibilityBase) => boolean;
|
|
10
|
+
isFieldDisabled: (field: FieldVisibilityBase) => boolean;
|
|
11
|
+
isFieldDisabledForSubmitValidation: (field: FieldVisibilityBase) => boolean;
|
|
12
|
+
}
|
|
13
|
+
export declare function useFieldVisibility({ form, formConfig, isCascadingDisabled, }: UseFieldVisibilityParams): UseFieldVisibilityReturn;
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { useCallback as c, useRef as y, useEffect as I } from "react";
|
|
2
|
+
import { getFieldDefaultValue as g } from "../utils/fieldDefaults.utils.js";
|
|
3
|
+
import { computeIsFieldVisible as w, computeIsFieldDisabled as a } from "../../form-engine/field-dependency-graph.js";
|
|
4
|
+
function R({
|
|
5
|
+
form: e,
|
|
6
|
+
formConfig: u,
|
|
7
|
+
isCascadingDisabled: n
|
|
8
|
+
}) {
|
|
9
|
+
const p = c(
|
|
10
|
+
(t) => w(t, e.getValues()),
|
|
11
|
+
[e]
|
|
12
|
+
), D = c(
|
|
13
|
+
(t) => a(t, e.getValues(), {
|
|
14
|
+
isCascadingDisabled: n
|
|
15
|
+
}),
|
|
16
|
+
[e, n]
|
|
17
|
+
), F = c(
|
|
18
|
+
(t) => a(t, e.getValues(), {
|
|
19
|
+
isCascadingDisabled: () => !1
|
|
20
|
+
}),
|
|
21
|
+
[e]
|
|
22
|
+
), r = y(/* @__PURE__ */ new Set());
|
|
23
|
+
return I(() => {
|
|
24
|
+
const t = u.fields.filter(
|
|
25
|
+
(i) => i.disableDependency && i.disableDependency.length > 0
|
|
26
|
+
);
|
|
27
|
+
if (t.length === 0)
|
|
28
|
+
return;
|
|
29
|
+
const o = (i) => {
|
|
30
|
+
const d = /* @__PURE__ */ new Set();
|
|
31
|
+
for (const l of t)
|
|
32
|
+
a(l, i ?? e.getValues(), {
|
|
33
|
+
isCascadingDisabled: n
|
|
34
|
+
}) && d.add(l.id);
|
|
35
|
+
return d;
|
|
36
|
+
};
|
|
37
|
+
r.current = o(void 0);
|
|
38
|
+
const V = e.watch((i, d) => {
|
|
39
|
+
if (!d.name)
|
|
40
|
+
return;
|
|
41
|
+
const l = o(i), f = [];
|
|
42
|
+
for (const s of l)
|
|
43
|
+
r.current.has(s) || f.push(s);
|
|
44
|
+
r.current = l;
|
|
45
|
+
for (const s of f) {
|
|
46
|
+
const b = u.fields.find(
|
|
47
|
+
(h) => h.id === s
|
|
48
|
+
);
|
|
49
|
+
b && (e.setValue(s, g(b), {
|
|
50
|
+
shouldValidate: !1,
|
|
51
|
+
shouldDirty: !0
|
|
52
|
+
}), e.clearErrors(s));
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
return () => V.unsubscribe();
|
|
56
|
+
}, [e, u.fields, n]), { isFieldVisible: p, isFieldDisabled: D, isFieldDisabledForSubmitValidation: F };
|
|
57
|
+
}
|
|
58
|
+
export {
|
|
59
|
+
R as useFieldVisibility
|
|
60
|
+
};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { UseReactHookFormReturn } from './useReactHookForm';
|
|
2
|
+
import { IField, FillFormByFileUploadField } from '../types/fields.types';
|
|
3
|
+
import { IFormConfig, UploadedFileValidationResult } from '../types/reactHookForm.types';
|
|
4
|
+
interface UseFillFormByFileUploadProps {
|
|
5
|
+
field: IField;
|
|
6
|
+
formHelpers: UseReactHookFormReturn;
|
|
7
|
+
formConfig: IFormConfig;
|
|
8
|
+
/** Callbacks for this field, already narrowed by the caller. */
|
|
9
|
+
fieldSupportedValues?: FillFormByFileUploadSupportedValues;
|
|
10
|
+
}
|
|
11
|
+
interface ValidationResult {
|
|
12
|
+
message: string;
|
|
13
|
+
hasValidValues: boolean;
|
|
14
|
+
validCount: number;
|
|
15
|
+
invalidCount: number;
|
|
16
|
+
}
|
|
17
|
+
export interface FillFormByFileUploadSupportedValues {
|
|
18
|
+
onValidationStart?: () => void;
|
|
19
|
+
onValidationComplete?: (response: UploadedFileValidationResult) => void;
|
|
20
|
+
disableDefaultTemplateFetch?: boolean;
|
|
21
|
+
}
|
|
22
|
+
interface UseFillFormByFileUploadReturn {
|
|
23
|
+
fileList: File[];
|
|
24
|
+
isValidating: boolean;
|
|
25
|
+
validationResult: ValidationResult | null;
|
|
26
|
+
fillFormField: FillFormByFileUploadField | null;
|
|
27
|
+
handleFileChange: (newFileList: File[]) => void;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Custom hook for managing fill form by file upload field state and logic
|
|
31
|
+
*/
|
|
32
|
+
export declare const useFillFormByFileUpload: ({ field, formHelpers, formConfig, fieldSupportedValues, }: UseFillFormByFileUploadProps) => UseFillFormByFileUploadReturn;
|
|
33
|
+
export {};
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import { useState as w, useCallback as g } from "react";
|
|
2
|
+
import { isEmptyValue as R } from "../../form-engine/is-empty-value.js";
|
|
3
|
+
const U = (c) => c.map((l) => ({
|
|
4
|
+
label: String(l.label),
|
|
5
|
+
value: l.value
|
|
6
|
+
})), N = (c) => c.map((l) => {
|
|
7
|
+
if (typeof l == "object" && l !== null && "value" in l)
|
|
8
|
+
return l;
|
|
9
|
+
const d = String(l);
|
|
10
|
+
return { label: d, value: d };
|
|
11
|
+
}), m = (c, l) => {
|
|
12
|
+
const d = c.options || [], v = new Set(d.map((h) => h.value)), a = l.filter(
|
|
13
|
+
(h) => !v.has(h.value)
|
|
14
|
+
);
|
|
15
|
+
a.length > 0 && (c.options = [...d, ...a]);
|
|
16
|
+
}, q = ({
|
|
17
|
+
field: c,
|
|
18
|
+
formHelpers: l,
|
|
19
|
+
formConfig: d,
|
|
20
|
+
fieldSupportedValues: v
|
|
21
|
+
}) => {
|
|
22
|
+
const a = c.fieldType === "fill_form_by_file_upload" ? c : null, [h, x] = w([]), [A, _] = w(!1), [$, f] = w(null), S = g(
|
|
23
|
+
(t, e) => {
|
|
24
|
+
const n = l.getValues()[t] || [], i = new Set(n.map((s) => s.value)), o = e.filter(
|
|
25
|
+
(s) => !i.has(s.value)
|
|
26
|
+
);
|
|
27
|
+
o.length > 0 && l.setValue(t, [...n, ...o]);
|
|
28
|
+
},
|
|
29
|
+
[l]
|
|
30
|
+
), y = g(
|
|
31
|
+
(t, e) => {
|
|
32
|
+
e.length > 0 && l.setValue(t, [e[0]]);
|
|
33
|
+
},
|
|
34
|
+
[l]
|
|
35
|
+
), C = g(
|
|
36
|
+
(t, e, n) => {
|
|
37
|
+
const i = U(n);
|
|
38
|
+
m(e, i), e.isMultiSelect ?? !1 ? S(t, i) : y(t, i);
|
|
39
|
+
},
|
|
40
|
+
[S, y]
|
|
41
|
+
), F = g(
|
|
42
|
+
(t, e, n) => {
|
|
43
|
+
const i = N(n);
|
|
44
|
+
m(e, i), e.isMultiSelect ?? !1 ? S(t, i) : y(t, i);
|
|
45
|
+
},
|
|
46
|
+
[S, y]
|
|
47
|
+
), b = g(
|
|
48
|
+
(t, e, n) => {
|
|
49
|
+
const i = e.options || [], o = i.find(
|
|
50
|
+
(s) => s.value === n || s.label === n
|
|
51
|
+
);
|
|
52
|
+
if (o)
|
|
53
|
+
if (e.isMultiSelect ?? !1) {
|
|
54
|
+
const r = l.getValues()[t] || [];
|
|
55
|
+
r.some(
|
|
56
|
+
(V) => V.value === o.value
|
|
57
|
+
) || l.setValue(t, [
|
|
58
|
+
...r,
|
|
59
|
+
o
|
|
60
|
+
]);
|
|
61
|
+
} else
|
|
62
|
+
l.setValue(t, [o]);
|
|
63
|
+
else {
|
|
64
|
+
const s = { label: n, value: n };
|
|
65
|
+
if (e.options = [...i, s], e.isMultiSelect ?? !1) {
|
|
66
|
+
const u = l.getValues()[t] || [];
|
|
67
|
+
l.setValue(t, [...u, s]);
|
|
68
|
+
} else
|
|
69
|
+
l.setValue(t, [s]);
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
[l]
|
|
73
|
+
), M = g(
|
|
74
|
+
(t, e) => {
|
|
75
|
+
if (R(e))
|
|
76
|
+
return;
|
|
77
|
+
const n = d.fields.find(
|
|
78
|
+
(i) => i.id === t
|
|
79
|
+
);
|
|
80
|
+
if (n)
|
|
81
|
+
if (n.fieldType === "select") {
|
|
82
|
+
const i = n;
|
|
83
|
+
if (Array.isArray(e) && e.length > 0 && typeof e[0] == "object" && e[0] !== null && "value" in e[0] && "label" in e[0] && "label" in e[0]) {
|
|
84
|
+
C(
|
|
85
|
+
t,
|
|
86
|
+
i,
|
|
87
|
+
e
|
|
88
|
+
);
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
Array.isArray(e) ? F(t, i, e) : typeof e == "string" && b(t, i, e);
|
|
92
|
+
} else
|
|
93
|
+
l.setValue(t, e);
|
|
94
|
+
},
|
|
95
|
+
[
|
|
96
|
+
l,
|
|
97
|
+
d.fields,
|
|
98
|
+
C,
|
|
99
|
+
F,
|
|
100
|
+
b
|
|
101
|
+
]
|
|
102
|
+
), O = g(
|
|
103
|
+
async (t) => {
|
|
104
|
+
if (!(!t || !a)) {
|
|
105
|
+
_(!0), f(null), v?.onValidationStart?.();
|
|
106
|
+
try {
|
|
107
|
+
const e = a.handlerName ? l.formContext?.functions?.[a.handlerName] : void 0, n = a.validationConfig?.apiEndpoint;
|
|
108
|
+
if (!e && !n) {
|
|
109
|
+
f({
|
|
110
|
+
message: "API endpoint not configured",
|
|
111
|
+
hasValidValues: !1,
|
|
112
|
+
validCount: 0,
|
|
113
|
+
invalidCount: 0
|
|
114
|
+
});
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
const i = e ? await e({
|
|
118
|
+
formHelpers: l,
|
|
119
|
+
fieldId: a.id,
|
|
120
|
+
newValue: l.form.getValues(a.id),
|
|
121
|
+
oldValue: l.getPreviousFieldValue(a.id),
|
|
122
|
+
payload: { file: t }
|
|
123
|
+
}) : await l.formContext?.transport?.validateUploadedFile?.({
|
|
124
|
+
apiEndpoint: n,
|
|
125
|
+
file: t
|
|
126
|
+
});
|
|
127
|
+
if (!i)
|
|
128
|
+
throw new Error(
|
|
129
|
+
"formContext.transport.validateUploadedFile is required for fill_form_by_file_upload fields"
|
|
130
|
+
);
|
|
131
|
+
v?.onValidationComplete?.(i);
|
|
132
|
+
const o = i && i.filtered_values && Object.keys(i.filtered_values).length > 0, s = !!i.session_id, r = i.valid_rows_count || 0, u = i.invalid_rows_count || 0;
|
|
133
|
+
if (o) {
|
|
134
|
+
Object.entries(i.filtered_values).forEach(
|
|
135
|
+
([j, p]) => {
|
|
136
|
+
p && p.length > 0 && M(j, p);
|
|
137
|
+
}
|
|
138
|
+
);
|
|
139
|
+
const V = Object.keys(
|
|
140
|
+
i.filtered_values
|
|
141
|
+
).length, T = i.message || `Successfully updated ${V} field(s) with ${r} valid row(s).${u > 0 ? ` ${u} row(s) were invalid.` : ""}`;
|
|
142
|
+
f({
|
|
143
|
+
message: T,
|
|
144
|
+
hasValidValues: r > 0,
|
|
145
|
+
validCount: r,
|
|
146
|
+
invalidCount: u
|
|
147
|
+
});
|
|
148
|
+
} else if (s) {
|
|
149
|
+
const V = i.message || `Successfully validated ${r} row(s).${u > 0 ? ` ${u} row(s) were invalid.` : ""}`;
|
|
150
|
+
f({
|
|
151
|
+
message: V,
|
|
152
|
+
hasValidValues: !0,
|
|
153
|
+
validCount: r,
|
|
154
|
+
invalidCount: u
|
|
155
|
+
});
|
|
156
|
+
} else {
|
|
157
|
+
const V = i?.message || "No valid values found in the uploaded file.";
|
|
158
|
+
f({
|
|
159
|
+
message: V,
|
|
160
|
+
hasValidValues: !1,
|
|
161
|
+
validCount: 0,
|
|
162
|
+
invalidCount: u
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
} catch (e) {
|
|
166
|
+
console.error("File validation error:", e);
|
|
167
|
+
const n = e instanceof Error ? e.message : "Failed to validate file. Please try again.";
|
|
168
|
+
f({
|
|
169
|
+
message: n,
|
|
170
|
+
hasValidValues: !1,
|
|
171
|
+
validCount: 0,
|
|
172
|
+
invalidCount: 0
|
|
173
|
+
});
|
|
174
|
+
} finally {
|
|
175
|
+
_(!1);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
},
|
|
179
|
+
[a, l, M, v]
|
|
180
|
+
), E = g(
|
|
181
|
+
(t) => {
|
|
182
|
+
if (x(t), f(null), t.length > 0) {
|
|
183
|
+
const e = t[0];
|
|
184
|
+
e instanceof File && O(e);
|
|
185
|
+
} else t.length === 0 && f(null);
|
|
186
|
+
},
|
|
187
|
+
[O]
|
|
188
|
+
);
|
|
189
|
+
return {
|
|
190
|
+
fileList: h,
|
|
191
|
+
isValidating: A,
|
|
192
|
+
validationResult: $,
|
|
193
|
+
fillFormField: a,
|
|
194
|
+
handleFileChange: E
|
|
195
|
+
};
|
|
196
|
+
};
|
|
197
|
+
export {
|
|
198
|
+
q as useFillFormByFileUpload
|
|
199
|
+
};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { UseReactHookFormReturn } from './useReactHookForm';
|
|
2
|
+
import { IField, CopyPasteField } from '../types/fields.types';
|
|
3
|
+
import { IFormConfig } from '../types/reactHookForm.types';
|
|
4
|
+
import { Option, ActionMeta } from '../../components/forms/select';
|
|
5
|
+
interface UseFillFormByPasteProps {
|
|
6
|
+
field: IField;
|
|
7
|
+
formHelpers: UseReactHookFormReturn;
|
|
8
|
+
formConfig: IFormConfig;
|
|
9
|
+
}
|
|
10
|
+
interface ValidationResult {
|
|
11
|
+
message: string;
|
|
12
|
+
hasValidValues: boolean;
|
|
13
|
+
validCount: number;
|
|
14
|
+
invalidCount: number;
|
|
15
|
+
}
|
|
16
|
+
interface UseFillFormByPasteReturn {
|
|
17
|
+
selectedOption: Option[] | null;
|
|
18
|
+
textareaValue: string;
|
|
19
|
+
isValidating: boolean;
|
|
20
|
+
validationResult: ValidationResult | null;
|
|
21
|
+
copyPasteField: CopyPasteField | null;
|
|
22
|
+
handleSelectionChange: (newValue: Option[] | null, actionMeta?: ActionMeta<Option>) => void;
|
|
23
|
+
handleClearAll: () => void;
|
|
24
|
+
handleTextareaChange: (value: string) => void;
|
|
25
|
+
handleValidate: () => void;
|
|
26
|
+
canValidate: boolean;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Custom hook for managing fill form by paste field state and logic
|
|
30
|
+
* Handles validation, target field updates, and form state management
|
|
31
|
+
*/
|
|
32
|
+
export declare const useFillFormByPaste: ({ field, formHelpers, formConfig, }: UseFillFormByPasteProps) => UseFillFormByPasteReturn;
|
|
33
|
+
export {};
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { useState as V, useCallback as d } from "react";
|
|
2
|
+
const F = ({
|
|
3
|
+
field: g,
|
|
4
|
+
formHelpers: a,
|
|
5
|
+
formConfig: C
|
|
6
|
+
}) => {
|
|
7
|
+
const t = g.fieldType === "fill_form_by_paste" ? g : null, [c, m] = V(null), [r, f] = V(""), [y, v] = V(!1), [T, i] = V(null), x = d(
|
|
8
|
+
(e, u) => {
|
|
9
|
+
const s = C.fields.find(
|
|
10
|
+
(n) => n.id === e
|
|
11
|
+
);
|
|
12
|
+
if (!s || s.fieldType !== "select") return;
|
|
13
|
+
const l = u.map((n) => ({
|
|
14
|
+
label: n.label,
|
|
15
|
+
value: n.value
|
|
16
|
+
}));
|
|
17
|
+
if (s.isMultiSelect ?? !1) {
|
|
18
|
+
const n = a.getValues()?.[e] || [], h = new Set(n.map((p) => p.value)), S = l.filter(
|
|
19
|
+
(p) => !h.has(p.value)
|
|
20
|
+
);
|
|
21
|
+
S.length > 0 && a.setValue(e, [
|
|
22
|
+
...n,
|
|
23
|
+
...S
|
|
24
|
+
]);
|
|
25
|
+
} else
|
|
26
|
+
l.length > 0 && a.setValue(e, [l[0]]);
|
|
27
|
+
},
|
|
28
|
+
[a, C]
|
|
29
|
+
), _ = d(
|
|
30
|
+
async (e, u) => {
|
|
31
|
+
if (!e.trim() || !u || !t) return;
|
|
32
|
+
v(!0), i(null);
|
|
33
|
+
const s = t.handlerName ? a.formContext?.functions?.[t.handlerName] : void 0;
|
|
34
|
+
if (!s && !t.validationConfig?.apiEndpoint) {
|
|
35
|
+
i({
|
|
36
|
+
message: "Validation endpoint is not configured.",
|
|
37
|
+
hasValidValues: !1,
|
|
38
|
+
validCount: 0,
|
|
39
|
+
invalidCount: 0
|
|
40
|
+
}), v(!1);
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
try {
|
|
44
|
+
const l = s ? await s({
|
|
45
|
+
formHelpers: a,
|
|
46
|
+
fieldId: t.id,
|
|
47
|
+
newValue: a.form.getValues(t.id),
|
|
48
|
+
oldValue: a.getPreviousFieldValue(t.id),
|
|
49
|
+
payload: { pastedText: e, targetFieldId: u }
|
|
50
|
+
}) : await a.formContext?.transport?.validatePastedValues?.({
|
|
51
|
+
apiEndpoint: t.validationConfig.apiEndpoint,
|
|
52
|
+
values: e,
|
|
53
|
+
targetFieldId: u
|
|
54
|
+
});
|
|
55
|
+
if (!l)
|
|
56
|
+
throw new Error(
|
|
57
|
+
"formContext.transport.validatePastedValues is required for fill_form_by_paste fields"
|
|
58
|
+
);
|
|
59
|
+
const { valid_values: o, invalid_values: n, message: h } = l;
|
|
60
|
+
o.length > 0 && x(u, o), i({
|
|
61
|
+
message: h || "Validation completed",
|
|
62
|
+
hasValidValues: o.length > 0,
|
|
63
|
+
validCount: o.length,
|
|
64
|
+
invalidCount: n.length
|
|
65
|
+
});
|
|
66
|
+
} catch (l) {
|
|
67
|
+
const o = l instanceof Error ? l.message : "Failed to validate pasted values. Please try again.";
|
|
68
|
+
i({
|
|
69
|
+
message: o,
|
|
70
|
+
hasValidValues: !1,
|
|
71
|
+
validCount: 0,
|
|
72
|
+
invalidCount: 0
|
|
73
|
+
});
|
|
74
|
+
} finally {
|
|
75
|
+
v(!1);
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
[t, a, x]
|
|
79
|
+
), w = d((e) => {
|
|
80
|
+
m(e), f(""), i(null);
|
|
81
|
+
}, []), P = d(() => {
|
|
82
|
+
m(null), f(""), i(null);
|
|
83
|
+
}, []), b = d((e) => {
|
|
84
|
+
f(e), i(null);
|
|
85
|
+
}, []), E = d(() => {
|
|
86
|
+
const e = c?.[0]?.value;
|
|
87
|
+
e && _(r, e);
|
|
88
|
+
}, [c, r, _]), M = !!c?.[0]?.value && !!r && !y;
|
|
89
|
+
return {
|
|
90
|
+
selectedOption: c,
|
|
91
|
+
textareaValue: r,
|
|
92
|
+
isValidating: y,
|
|
93
|
+
validationResult: T,
|
|
94
|
+
copyPasteField: t,
|
|
95
|
+
handleSelectionChange: w,
|
|
96
|
+
handleClearAll: P,
|
|
97
|
+
handleTextareaChange: b,
|
|
98
|
+
handleValidate: E,
|
|
99
|
+
canValidate: M
|
|
100
|
+
};
|
|
101
|
+
};
|
|
102
|
+
export {
|
|
103
|
+
F as useFillFormByPaste
|
|
104
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { RefObject } from 'react';
|
|
2
|
+
import { UseFormReturn } from 'react-hook-form';
|
|
3
|
+
import { FormContext, IFormConfig, ReactHookFormState, UseReactHookFormReturn } from '../types/reactHookForm.types';
|
|
4
|
+
interface UseFormFieldChangeSubscriptionOptions {
|
|
5
|
+
form: UseFormReturn<ReactHookFormState>;
|
|
6
|
+
formConfig: IFormConfig;
|
|
7
|
+
formContext?: FormContext;
|
|
8
|
+
previousValuesRef: RefObject<ReactHookFormState>;
|
|
9
|
+
formHelpersRef: RefObject<UseReactHookFormReturn | null>;
|
|
10
|
+
}
|
|
11
|
+
/** Subscribes to RHF value changes for onFieldChange + named handlers. */
|
|
12
|
+
export declare function useFormFieldChangeSubscription({ form, formConfig, formContext, previousValuesRef, formHelpersRef, }: UseFormFieldChangeSubscriptionOptions): void;
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { useEffect as h } from "react";
|
|
2
|
+
import { findFieldByPath as p } from "../utils/fieldPath.utils.js";
|
|
3
|
+
import { isFieldValueValid as F } from "../utils/buildFieldValidationRules.js";
|
|
4
|
+
import { buildEvaluateFieldValidationOptions as b } from "../utils/evaluateFieldValidation.js";
|
|
5
|
+
function N({
|
|
6
|
+
form: n,
|
|
7
|
+
formConfig: l,
|
|
8
|
+
formContext: t,
|
|
9
|
+
previousValuesRef: a,
|
|
10
|
+
formHelpersRef: d
|
|
11
|
+
}) {
|
|
12
|
+
h(() => {
|
|
13
|
+
const m = n.watch((g, s) => {
|
|
14
|
+
if (!s.name)
|
|
15
|
+
return;
|
|
16
|
+
const e = s.name, c = n.getValues(e), f = a.current[e];
|
|
17
|
+
a.current = n.getValues();
|
|
18
|
+
const r = d.current;
|
|
19
|
+
if (!r)
|
|
20
|
+
return;
|
|
21
|
+
const u = {
|
|
22
|
+
formHelpers: r,
|
|
23
|
+
fieldId: e,
|
|
24
|
+
newValue: c,
|
|
25
|
+
oldValue: f
|
|
26
|
+
};
|
|
27
|
+
t?.onFieldChange?.(u);
|
|
28
|
+
const i = p(l.fields, e);
|
|
29
|
+
i && F(
|
|
30
|
+
i,
|
|
31
|
+
c,
|
|
32
|
+
b(r, e)
|
|
33
|
+
) && n.clearErrors(e);
|
|
34
|
+
const o = i?.handlerName ? t?.functions?.[i.handlerName] : void 0;
|
|
35
|
+
o && o(u);
|
|
36
|
+
});
|
|
37
|
+
return () => m.unsubscribe();
|
|
38
|
+
}, [n, l.fields, t, d, a]);
|
|
39
|
+
}
|
|
40
|
+
export {
|
|
41
|
+
N as useFormFieldChangeSubscription
|
|
42
|
+
};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { FormContext, IFormConfig, ReactHookFormState, UseReactHookFormReturn } from '../types/reactHookForm.types';
|
|
2
|
+
export type { ReactHookFormState, UseReactHookFormReturn, } from '../types/reactHookForm.types';
|
|
3
|
+
export declare const useReactHookForm: (formConfig: IFormConfig, formInitialState?: Record<string, unknown>, externalOnSubmitCallback?: (data: ReactHookFormState) => void, externalOnCancelCallback?: (data: ReactHookFormState) => void, externalOnResetCallback?: (data: ReactHookFormState) => void, formContext?: FormContext) => UseReactHookFormReturn;
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import { useCallback as l, useMemo as P, useRef as c, useEffect as b, useState as z } from "react";
|
|
2
|
+
import { useForm as X } from "react-hook-form";
|
|
3
|
+
import { isEmptyValue as A } from "../../form-engine/is-empty-value.js";
|
|
4
|
+
import { useCascadingForm as Y } from "./useCascadingForm.js";
|
|
5
|
+
import { useFieldVisibility as Z } from "./useFieldVisibility.js";
|
|
6
|
+
import { useFormFieldChangeSubscription as _ } from "./useFormFieldChangeSubscription.js";
|
|
7
|
+
import { getFieldDefaultValue as m } from "../utils/fieldDefaults.utils.js";
|
|
8
|
+
import { focusFirstFormValidationError as $ } from "../utils/formValidationFeedback.utils.js";
|
|
9
|
+
import { getFieldTestId as k } from "../utils/fieldTestIds.js";
|
|
10
|
+
import { buildEvaluateFieldValidationOptions as x } from "../utils/evaluateFieldValidation.js";
|
|
11
|
+
const de = (i, u, a, f, S, v) => {
|
|
12
|
+
const y = l(() => {
|
|
13
|
+
const e = {};
|
|
14
|
+
return i.fields.forEach((t) => {
|
|
15
|
+
e[t.id] = m(t);
|
|
16
|
+
}), e;
|
|
17
|
+
}, [i]), T = l(() => {
|
|
18
|
+
const e = {};
|
|
19
|
+
return Object.entries(u ?? {}).forEach(([t, s]) => {
|
|
20
|
+
e[t] = s;
|
|
21
|
+
}), e;
|
|
22
|
+
}, [u]), D = P(() => {
|
|
23
|
+
const e = new Set(i.fields.map((t) => t.id));
|
|
24
|
+
return Object.keys(u ?? {}).filter(
|
|
25
|
+
(t) => !e.has(t)
|
|
26
|
+
);
|
|
27
|
+
}, [i.fields, u]), d = P(() => {
|
|
28
|
+
const e = y(), t = T();
|
|
29
|
+
return { ...e, ...t };
|
|
30
|
+
}, [y, T]), r = X({
|
|
31
|
+
defaultValues: d,
|
|
32
|
+
mode: "onTouched",
|
|
33
|
+
reValidateMode: "onChange"
|
|
34
|
+
}), I = c(d), R = c(null), w = c(() => {
|
|
35
|
+
}), K = l((e) => I.current[e], []), H = c(
|
|
36
|
+
new Set(i.fields.map((e) => e.id))
|
|
37
|
+
);
|
|
38
|
+
b(() => {
|
|
39
|
+
const e = new Set(i.fields.map((s) => s.id)), t = r.getValues();
|
|
40
|
+
for (const s of i.fields)
|
|
41
|
+
!H.current.has(s.id) && t[s.id] === void 0 && r.setValue(s.id, m(s));
|
|
42
|
+
H.current = e;
|
|
43
|
+
}, [i.fields, r]);
|
|
44
|
+
const [F, j] = z(!1), [V, M] = z(/* @__PURE__ */ new Set()), N = l(
|
|
45
|
+
(e) => {
|
|
46
|
+
r.setValue(e, null), r.clearErrors(e), M((t) => new Set(t).add(e));
|
|
47
|
+
},
|
|
48
|
+
[r]
|
|
49
|
+
), O = l(
|
|
50
|
+
(e) => {
|
|
51
|
+
r.setValue(e, m(
|
|
52
|
+
i.fields.find((t) => t.id === e)
|
|
53
|
+
)), M((t) => {
|
|
54
|
+
const s = new Set(t);
|
|
55
|
+
return s.delete(e), s;
|
|
56
|
+
});
|
|
57
|
+
},
|
|
58
|
+
[r, i.fields]
|
|
59
|
+
), p = l(() => {
|
|
60
|
+
$({
|
|
61
|
+
fieldErrors: r.formState.errors,
|
|
62
|
+
fieldsInOrder: i.fields,
|
|
63
|
+
getFieldTestId: k
|
|
64
|
+
});
|
|
65
|
+
}, [r.formState.errors, i.fields]);
|
|
66
|
+
b(() => {
|
|
67
|
+
F && p();
|
|
68
|
+
}, [F, p]);
|
|
69
|
+
const { isCascadingDisabled: W, getEarlierFieldsIds: g, setValueWithCascading: q } = Y(r, i, {
|
|
70
|
+
getFieldDefaultValue: m,
|
|
71
|
+
resolveFieldValidationEvaluationOptions: (e) => w.current(e)
|
|
72
|
+
}), { isFieldVisible: E, isFieldDisabled: B, isFieldDisabledForSubmitValidation: G } = Z({
|
|
73
|
+
form: r,
|
|
74
|
+
formConfig: i,
|
|
75
|
+
isCascadingDisabled: W
|
|
76
|
+
});
|
|
77
|
+
_({
|
|
78
|
+
form: r,
|
|
79
|
+
formConfig: i,
|
|
80
|
+
formContext: v,
|
|
81
|
+
previousValuesRef: I,
|
|
82
|
+
formHelpersRef: R
|
|
83
|
+
});
|
|
84
|
+
const n = l(
|
|
85
|
+
(e) => {
|
|
86
|
+
const t = {};
|
|
87
|
+
return i.fields.forEach((s) => {
|
|
88
|
+
if (V.has(s.id)) {
|
|
89
|
+
t[s.id] = null;
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
const o = e[s.id];
|
|
93
|
+
if (!s.doNotIncludeInSubmit) {
|
|
94
|
+
if (s.fieldType === "object" || s.fieldType === "array") {
|
|
95
|
+
A(o) || (t[s.id] = o);
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
A(o) || i.includeOnlyVisibleFieldsInSubmit && !E(s) || (t[s.id] = o);
|
|
99
|
+
}
|
|
100
|
+
}), D.forEach((s) => {
|
|
101
|
+
const o = e[s];
|
|
102
|
+
o !== void 0 && (t[s] = o);
|
|
103
|
+
}), t;
|
|
104
|
+
},
|
|
105
|
+
[i, E, D, V]
|
|
106
|
+
), J = l(
|
|
107
|
+
(e) => r.handleSubmit(
|
|
108
|
+
(t) => {
|
|
109
|
+
j(!1);
|
|
110
|
+
const s = n(t);
|
|
111
|
+
e?.(s), a?.(s);
|
|
112
|
+
},
|
|
113
|
+
() => {
|
|
114
|
+
j(!0);
|
|
115
|
+
}
|
|
116
|
+
),
|
|
117
|
+
[r, n, a]
|
|
118
|
+
), L = l(
|
|
119
|
+
(e) => {
|
|
120
|
+
const t = e || d;
|
|
121
|
+
r.reset(t), S?.(t);
|
|
122
|
+
},
|
|
123
|
+
[r, d, S]
|
|
124
|
+
), Q = l(() => {
|
|
125
|
+
const e = r.getValues();
|
|
126
|
+
f?.(e);
|
|
127
|
+
}, [r, f]), U = l(
|
|
128
|
+
(e) => {
|
|
129
|
+
const t = r.getValues(), s = n(t);
|
|
130
|
+
e?.(s), a?.(s);
|
|
131
|
+
},
|
|
132
|
+
[r, n, a]
|
|
133
|
+
), h = {
|
|
134
|
+
formId: i.formId,
|
|
135
|
+
formConfig: i,
|
|
136
|
+
highlightFirstError: F,
|
|
137
|
+
form: r,
|
|
138
|
+
getValues: r.getValues,
|
|
139
|
+
setValue: q,
|
|
140
|
+
resetForm: L,
|
|
141
|
+
handleSubmit: J,
|
|
142
|
+
handleCancel: Q,
|
|
143
|
+
isFieldVisible: E,
|
|
144
|
+
isFieldDisabled: B,
|
|
145
|
+
isFieldDisabledForSubmitValidation: G,
|
|
146
|
+
submitValidatedForm: U,
|
|
147
|
+
getEarlierFieldsIds: g,
|
|
148
|
+
scrollToFirstError: p,
|
|
149
|
+
setToEmptyFields: V,
|
|
150
|
+
markFieldAsEmpty: N,
|
|
151
|
+
undoSetToEmpty: O,
|
|
152
|
+
getPreviousFieldValue: K,
|
|
153
|
+
formContext: v
|
|
154
|
+
};
|
|
155
|
+
return b(() => {
|
|
156
|
+
R.current = h, w.current = (e) => x(h, e);
|
|
157
|
+
}), h;
|
|
158
|
+
};
|
|
159
|
+
export {
|
|
160
|
+
de as useReactHookForm
|
|
161
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Option } from '../../components/forms/select';
|
|
2
|
+
import { UseSelectOptionsProps } from '../types/reactHookForm.types';
|
|
3
|
+
export declare const useSelectOptions: ({ apiConfig, formHelpers, formConfig, initialOptions, id, isEnabled, getSelectOptionsName, fieldSupportedValues, }: UseSelectOptionsProps) => {
|
|
4
|
+
options: Option[];
|
|
5
|
+
isLoading: boolean;
|
|
6
|
+
error: Error | null;
|
|
7
|
+
refetch: () => Promise<Option[]>;
|
|
8
|
+
};
|