@evenicanpm/admin-integrate 1.8.0 → 2.0.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.
Files changed (71) hide show
  1. package/documents/ProcessTask/fragments.ts +4 -0
  2. package/documents/ProcessTemplate/fragments.ts +30 -0
  3. package/documents/ProcessTemplate/list.ts +29 -0
  4. package/package.json +2 -2
  5. package/src/api/process-config/mutation/process-config-import.mutation.ts +1 -1
  6. package/src/api/templates/queries/get-field-values.query.ts +48 -0
  7. package/src/api/templates/queries/get-field-values.server.ts +9 -0
  8. package/src/api/templates/queries/index.ts +4 -0
  9. package/src/api/templates/queries/types.ts +2 -2
  10. package/src/api/templates/queries/validate-field-on-check.query.ts +22 -0
  11. package/src/api/templates/queries/validate-field-on-check.server.ts +30 -0
  12. package/src/api/templates/queries/validate-field-on-submit.server.ts +18 -0
  13. package/src/components/data-table/table-row.tsx +1 -1
  14. package/src/components/icons/up-down.tsx +1 -0
  15. package/src/components/integration-view/integration-view.tsx +10 -15
  16. package/src/components/integration-view/nodes/task-node.tsx +1 -1
  17. package/src/components/integration-view/utils/mapping.ts +10 -11
  18. package/src/components/list-filter/list-filter.tsx +2 -0
  19. package/src/components/templatesV2/inputs/FormikPageBody.tsx +191 -0
  20. package/src/components/templatesV2/inputs/context/FormModeContext.tsx +31 -0
  21. package/src/components/templatesV2/inputs/context/TemplateContext.tsx +37 -0
  22. package/src/components/templatesV2/inputs/field-names.ts +8 -0
  23. package/src/components/templatesV2/inputs/form-type.ts +48 -0
  24. package/src/components/templatesV2/inputs/index.tsx +33 -0
  25. package/src/components/templatesV2/inputs/input-type.ts +23 -0
  26. package/src/components/templatesV2/inputs/primitives/CheckboxInput.tsx +45 -0
  27. package/src/components/templatesV2/inputs/primitives/NumberInput.tsx +58 -0
  28. package/src/components/templatesV2/inputs/primitives/SelectorInput.tsx +111 -0
  29. package/src/components/templatesV2/inputs/primitives/TextInput.tsx +55 -0
  30. package/src/components/templatesV2/inputs/primitives/TextWithQueryInput.tsx +292 -0
  31. package/src/components/templatesV2/inputs/primitives/index.ts +10 -0
  32. package/src/components/templatesV2/inputs/renderers/index.ts +2 -0
  33. package/src/components/templatesV2/inputs/renderers/renderFormControl.tsx +376 -0
  34. package/src/components/templatesV2/inputs/renderers/renderSearchInput.tsx +129 -0
  35. package/src/components/templatesV2/inputs/search/MultiTextSearchInput.tsx +87 -0
  36. package/src/components/templatesV2/inputs/search/SearchInputWrapper.tsx +113 -0
  37. package/src/components/templatesV2/inputs/search/TextSearchInput.tsx +309 -0
  38. package/src/components/templatesV2/inputs/search/index.ts +4 -0
  39. package/src/components/templatesV2/inputs/search/search-query-key.ts +23 -0
  40. package/src/components/templatesV2/inputs/search/useFieldValuesOptions.ts +58 -0
  41. package/src/components/templatesV2/inputs/search/useSearchInput.ts +74 -0
  42. package/src/components/templatesV2/inputs/table/InputTable.tsx +259 -0
  43. package/src/components/templatesV2/inputs/table/index.ts +1 -0
  44. package/src/components/templatesV2/inputs/utils/applyTemplateConfig.ts +28 -0
  45. package/src/components/templatesV2/inputs/utils/arrangeInputs.ts +51 -0
  46. package/src/components/templatesV2/inputs/utils/index.ts +6 -0
  47. package/src/components/templatesV2/inputs/utils/parseQueryName.ts +20 -0
  48. package/src/components/templatesV2/inputs/utils/renderReadOnlyText.tsx +26 -0
  49. package/src/components/templatesV2/inputs/utils/selectors.ts +69 -0
  50. package/src/components/templatesV2/inputs/utils/toStringArray.ts +23 -0
  51. package/src/components/templatesV2/pageForm.tsx +151 -0
  52. package/src/components/{templates → templatesV2}/templates-list/templates-list-row.tsx +2 -1
  53. package/src/components/{templates → templatesV2}/templates-list/templates-list-table.tsx +2 -2
  54. package/src/components/{templates → templatesV2}/templates-list/templates-list.tsx +19 -28
  55. package/src/components/{templates → templatesV2}/types.tsx +12 -12
  56. package/src/components/templatesV2/validation/buildZodSchema.ts +216 -0
  57. package/src/components/templatesV2/validation/zodFormikValidate.ts +17 -0
  58. package/src/components/templatesV2/wizard.tsx +744 -0
  59. package/src/pages/integration-create/integration-create-steps.ts +8 -0
  60. package/src/pages/integration-create/integration-create.tsx +61 -14
  61. package/src/pages/integration-create/select-step.tsx +3 -3
  62. package/src/pages/integration-create/template-list-step.tsx +28 -3
  63. package/src/pages/integration-create/template-options-step.tsx +119 -0
  64. package/src/pages/integration-create/wizard-step.tsx +5 -4
  65. package/src/pages/integration-details/task-drawer/add-task.tsx +4 -4
  66. package/src/pages/integration-details/task-drawer/edit-task.tsx +3 -3
  67. package/src/components/templates/inputs/index.tsx +0 -1392
  68. package/src/components/templates/wizard.tsx +0 -737
  69. /package/src/components/{templates → templatesV2}/index.ts +0 -0
  70. /package/src/components/{templates → templatesV2}/template-filter.ts +0 -0
  71. /package/src/components/{templates → templatesV2}/templates-list/index.ts +0 -0
@@ -0,0 +1,292 @@
1
+ "use client";
2
+
3
+ import type { SxProps, Theme } from "@mui/material";
4
+ import { Box } from "@mui/material";
5
+ import * as React from "react";
6
+ import { validateFieldOnCheck } from "../../../../api/templates/queries/validate-field-on-check.server";
7
+ import { InputType } from "../input-type";
8
+ import { renderReadOnlyText } from "../utils/renderReadOnlyText";
9
+ import { CheckboxInput } from "./CheckboxInput";
10
+ import { NumberInput } from "./NumberInput";
11
+ import type { SelectorOption } from "./SelectorInput";
12
+ import { SelectorInput } from "./SelectorInput";
13
+ import { TextInput } from "./TextInput";
14
+
15
+ export type TextWithQueryInputType =
16
+ | InputType.TEXT
17
+ | InputType.NUMBER
18
+ | InputType.SELECTOR
19
+ | InputType.CHECKBOX;
20
+
21
+ export type TextWithQueryValue = string | number | boolean;
22
+
23
+ function valueToString(value: TextWithQueryValue): string {
24
+ if (value === "" || value == null) return "";
25
+ if (typeof value === "boolean") return value ? "true" : "false";
26
+ return String(value).trim();
27
+ }
28
+
29
+ function getEffectiveValidation(
30
+ submitValidationResult:
31
+ | { isValid: boolean; message: string }
32
+ | null
33
+ | undefined,
34
+ validation: { isValid: boolean; message: string } | null,
35
+ ): { isValid: boolean; message: string } | null {
36
+ if (submitValidationResult != null) {
37
+ return {
38
+ isValid: submitValidationResult.isValid,
39
+ message: submitValidationResult.message,
40
+ };
41
+ }
42
+ return validation;
43
+ }
44
+
45
+ function getDisplayError(
46
+ validating: boolean,
47
+ isError: boolean,
48
+ helperMessage: string,
49
+ ): string | undefined {
50
+ if (validating) return undefined;
51
+ if (isError) return helperMessage;
52
+ return undefined;
53
+ }
54
+
55
+ function formatReadOnlyValue(
56
+ value: TextWithQueryValue,
57
+ ): string | number | boolean {
58
+ if (typeof value === "boolean") return value ? "Yes" : "No";
59
+ return value;
60
+ }
61
+
62
+ interface DisplayStateInput {
63
+ error?: string | null;
64
+ validation: { isValid: boolean; message: string } | null;
65
+ submitValidationResult?: { isValid: boolean; message: string } | null;
66
+ helpText?: string | null;
67
+ validating: boolean;
68
+ readOnly?: boolean;
69
+ }
70
+
71
+ function getInputDisplayState({
72
+ error,
73
+ validation,
74
+ submitValidationResult,
75
+ helpText,
76
+ validating,
77
+ readOnly,
78
+ }: DisplayStateInput): {
79
+ displayError: string | undefined;
80
+ displayHelpText: string;
81
+ formHelperTextSx: SxProps<Theme>;
82
+ isDisabled: boolean;
83
+ } {
84
+ const showError = Boolean(error);
85
+ const effectiveValidation = getEffectiveValidation(
86
+ submitValidationResult,
87
+ validation,
88
+ );
89
+ const helperMessage =
90
+ showError && error
91
+ ? error
92
+ : (effectiveValidation?.message ?? helpText ?? "");
93
+ const isSuccess = effectiveValidation?.isValid === true && !showError;
94
+ const isError = showError || effectiveValidation?.isValid === false;
95
+ const displayError = getDisplayError(validating, isError, helperMessage);
96
+ const displayHelpText = validating ? "Checking…" : helperMessage;
97
+ const isDisabled = Boolean(readOnly || validating);
98
+ const formHelperTextSx: SxProps<Theme> = {
99
+ ...(validating && { color: "text.secondary" }),
100
+ ...(isSuccess && !validating && { color: "success.main" }),
101
+ ...(isError && !validating && { color: "error.main" }),
102
+ };
103
+ return {
104
+ displayError,
105
+ displayHelpText,
106
+ formHelperTextSx,
107
+ isDisabled,
108
+ };
109
+ }
110
+
111
+ export type SubmitValidationResult = { isValid: boolean; message: string };
112
+
113
+ export interface TextWithQueryInputProps {
114
+ inputType: TextWithQueryInputType;
115
+ label: string;
116
+ value: TextWithQueryValue;
117
+ setValue: (v: TextWithQueryValue) => void;
118
+ error?: string | null;
119
+ helpText?: string | null;
120
+ readOnly?: boolean;
121
+ onBlur?: () => void;
122
+ fieldName: string;
123
+ validationQuery: string;
124
+ fieldId: string;
125
+ validateFormikBeforeApi?: () => Promise<boolean>;
126
+ setFieldValidationInProgress?: (inProgress: boolean) => void;
127
+ placeholder?: string | null;
128
+ options?: SelectorOption[];
129
+ /** Result from validateFieldOnSubmit (on Next click); shown below field. */
130
+ submitValidationResult?: SubmitValidationResult | null;
131
+ }
132
+
133
+ export function TextWithQueryInput({
134
+ inputType,
135
+ label,
136
+ value,
137
+ setValue,
138
+ error,
139
+ helpText,
140
+ readOnly,
141
+ onBlur,
142
+ fieldName,
143
+ validationQuery,
144
+ fieldId,
145
+ validateFormikBeforeApi,
146
+ setFieldValidationInProgress,
147
+ placeholder,
148
+ options = [],
149
+ submitValidationResult,
150
+ }: Readonly<TextWithQueryInputProps>) {
151
+ const [validation, setValidation] = React.useState<{
152
+ isValid: boolean;
153
+ message: string;
154
+ } | null>(null);
155
+ const [validating, setValidating] = React.useState(false);
156
+
157
+ const handleBlur = React.useCallback(async () => {
158
+ onBlur?.();
159
+ const strValue = valueToString(value);
160
+ if (!strValue && inputType !== InputType.CHECKBOX) {
161
+ setValidation(null);
162
+ return;
163
+ }
164
+ const formikValid = await (validateFormikBeforeApi?.() ??
165
+ Promise.resolve(true));
166
+ if (!formikValid) return;
167
+ setValidating(true);
168
+ setValidation(null);
169
+ setFieldValidationInProgress?.(true);
170
+ try {
171
+ const result = await validateFieldOnCheck({
172
+ input: {
173
+ fieldName,
174
+ fieldId,
175
+ value: strValue,
176
+ },
177
+ });
178
+ if (result) {
179
+ setValidation({
180
+ isValid: result.isValid ?? false,
181
+ message: result.message ?? "",
182
+ });
183
+ }
184
+ } catch {
185
+ setValidation({ isValid: false, message: "Validation failed" });
186
+ } finally {
187
+ setValidating(false);
188
+ setFieldValidationInProgress?.(false);
189
+ }
190
+ }, [
191
+ value,
192
+ inputType,
193
+ fieldName,
194
+ validationQuery,
195
+ onBlur,
196
+ validateFormikBeforeApi,
197
+ setFieldValidationInProgress,
198
+ ]);
199
+
200
+ if (readOnly) {
201
+ const formattedValue = formatReadOnlyValue(value);
202
+ const readOnlyValue =
203
+ typeof formattedValue === "string" ||
204
+ typeof formattedValue === "number" ||
205
+ (Array.isArray(formattedValue) &&
206
+ formattedValue.every((v) => typeof v === "string"))
207
+ ? formattedValue
208
+ : "";
209
+ return renderReadOnlyText(label, readOnlyValue);
210
+ }
211
+
212
+ const display = getInputDisplayState({
213
+ error,
214
+ validation,
215
+ submitValidationResult,
216
+ helpText,
217
+ validating,
218
+ readOnly,
219
+ });
220
+
221
+ const clearValidationAndSet = (v: TextWithQueryValue) => {
222
+ setValidation(null);
223
+ setValue(v);
224
+ };
225
+
226
+ if (inputType === InputType.TEXT) {
227
+ return (
228
+ <TextInput
229
+ label={label}
230
+ placeholder={placeholder}
231
+ value={(value as string) ?? ""}
232
+ setValue={clearValidationAndSet}
233
+ error={display.displayError}
234
+ helpText={display.displayHelpText}
235
+ readOnly={readOnly}
236
+ disabled={display.isDisabled}
237
+ onBlur={handleBlur}
238
+ formHelperTextSx={display.formHelperTextSx}
239
+ />
240
+ );
241
+ }
242
+ if (inputType === InputType.NUMBER) {
243
+ return (
244
+ <NumberInput
245
+ label={label}
246
+ placeholder={placeholder}
247
+ value={value === "" || value == null ? "" : (value as number)}
248
+ setValue={clearValidationAndSet}
249
+ error={display.displayError}
250
+ helpText={display.displayHelpText}
251
+ readOnly={readOnly}
252
+ disabled={display.isDisabled}
253
+ onBlur={handleBlur}
254
+ formHelperTextSx={display.formHelperTextSx}
255
+ />
256
+ );
257
+ }
258
+ if (inputType === InputType.SELECTOR) {
259
+ return (
260
+ <SelectorInput
261
+ fieldName={fieldName}
262
+ label={label}
263
+ value={(value as string) ?? ""}
264
+ setValue={clearValidationAndSet}
265
+ helpText={display.displayHelpText}
266
+ error={display.displayError}
267
+ options={options}
268
+ readOnly={readOnly}
269
+ disabled={display.isDisabled}
270
+ onBlur={handleBlur}
271
+ formHelperTextSx={display.formHelperTextSx}
272
+ />
273
+ );
274
+ }
275
+ if (inputType === InputType.CHECKBOX) {
276
+ return (
277
+ <Box onBlur={handleBlur}>
278
+ <CheckboxInput
279
+ label={label}
280
+ checked={Boolean(value)}
281
+ setChecked={clearValidationAndSet}
282
+ helpText={display.displayHelpText}
283
+ readOnly={readOnly}
284
+ disabled={display.isDisabled}
285
+ formHelperTextSx={display.formHelperTextSx}
286
+ />
287
+ </Box>
288
+ );
289
+ }
290
+
291
+ return null;
292
+ }
@@ -0,0 +1,10 @@
1
+ export { CheckboxInput } from "./CheckboxInput";
2
+ export { NumberInput } from "./NumberInput";
3
+ export { SelectorInput } from "./SelectorInput";
4
+ export { TextInput } from "./TextInput";
5
+ export {
6
+ TextWithQueryInput,
7
+ type TextWithQueryInputProps,
8
+ type TextWithQueryInputType,
9
+ type TextWithQueryValue,
10
+ } from "./TextWithQueryInput";
@@ -0,0 +1,2 @@
1
+ export { renderFormControl } from "./renderFormControl";
2
+ export { renderSearchInput } from "./renderSearchInput";
@@ -0,0 +1,376 @@
1
+ "use client";
2
+
3
+ import { Box, FormHelperText, Typography } from "@mui/material";
4
+ import { Field } from "formik";
5
+ import type * as React from "react";
6
+ import type {
7
+ ErrorState,
8
+ FieldValue,
9
+ FormState,
10
+ ProcessTemplateInput,
11
+ ProcessTemplateInputSchema,
12
+ } from "../../types";
13
+ import { templateFieldKey } from "../../types";
14
+ import { InputType } from "../input-type";
15
+ import { CheckboxInput } from "../primitives/CheckboxInput";
16
+ import { NumberInput } from "../primitives/NumberInput";
17
+ import { SelectorInput } from "../primitives/SelectorInput";
18
+ import { TextInput } from "../primitives/TextInput";
19
+ import type { TextWithQueryInputType } from "../primitives/TextWithQueryInput";
20
+ import { TextWithQueryInput } from "../primitives/TextWithQueryInput";
21
+ import { InputTable } from "../table/InputTable";
22
+ import {
23
+ getSelectorOptionsFromInput,
24
+ getTableRowErrors,
25
+ } from "../utils/selectors";
26
+ import { renderSearchInput } from "./renderSearchInput";
27
+
28
+ const QUERY_NAME_INPUT_TYPES = [
29
+ InputType.TEXT,
30
+ InputType.TEXT_UNIQUE_IDENTIFIER,
31
+ InputType.NUMBER,
32
+ InputType.SELECTOR,
33
+ InputType.CHECKBOX,
34
+ ] as const;
35
+
36
+ function isHiddenInput(input: ProcessTemplateInput): boolean {
37
+ return (
38
+ input.inputType === InputType.HIDDEN ||
39
+ input.inputType === InputType.HIDDEN_NUMBER ||
40
+ input.inputType === InputType.HIDDEN_NUMBER_OR_NULL
41
+ );
42
+ }
43
+
44
+ function isFieldTouched(
45
+ touched: Record<string, boolean> | undefined,
46
+ fieldKey: string,
47
+ ): boolean {
48
+ return (
49
+ typeof touched === "object" &&
50
+ touched !== null &&
51
+ touched[fieldKey] === true
52
+ );
53
+ }
54
+
55
+ function getValidationQueryOnCheckIfSupported(
56
+ input: ProcessTemplateInput,
57
+ ): string | null {
58
+ const validationQueryOnCheck = (input as { validationQueryOnCheck?: string })
59
+ .validationQueryOnCheck;
60
+ if (!validationQueryOnCheck) return null;
61
+ const hasSupportedType = QUERY_NAME_INPUT_TYPES.includes(
62
+ input.inputType as (typeof QUERY_NAME_INPUT_TYPES)[number],
63
+ );
64
+ return hasSupportedType ? validationQueryOnCheck : null;
65
+ }
66
+
67
+ function queryInputType(
68
+ inputType: string | null | undefined,
69
+ ): TextWithQueryInputType {
70
+ if (inputType === InputType.NUMBER) return InputType.NUMBER;
71
+ if (inputType === InputType.SELECTOR) return InputType.SELECTOR;
72
+ if (inputType === InputType.CHECKBOX) return InputType.CHECKBOX;
73
+ return InputType.TEXT;
74
+ }
75
+
76
+ function normalizeInputTableRows(
77
+ value: unknown,
78
+ input: ProcessTemplateInput,
79
+ ): Array<Record<string, unknown>> {
80
+ const rows: Array<Record<string, unknown>> = Array.isArray(value)
81
+ ? (value as Array<Record<string, unknown>>)
82
+ : [];
83
+ if (!value || rows.length > 0 || (input.schemas?.length ?? 0) !== 2) {
84
+ return rows;
85
+ }
86
+ const valueRecord = value as Record<string, string>;
87
+ for (const schemaKey of Object.keys(valueRecord)) {
88
+ const schema0 = input.schemas?.[0];
89
+ const schema1 = input.schemas?.[1];
90
+ if (schema0?.fieldKey && schema1?.fieldKey) {
91
+ rows.push({
92
+ [schema0.fieldKey]: schemaKey,
93
+ [schema1.fieldKey]: valueRecord[schemaKey],
94
+ });
95
+ }
96
+ }
97
+ return rows;
98
+ }
99
+
100
+ function renderInputTable({
101
+ input,
102
+ k,
103
+ values,
104
+ errors,
105
+ showError,
106
+ err,
107
+ templateId,
108
+ handleFieldChange,
109
+ finalReadOnly,
110
+ readOnly,
111
+ setFieldTouched,
112
+ validateForm,
113
+ }: {
114
+ input: ProcessTemplateInput;
115
+ k: string;
116
+ values: FormState;
117
+ errors: ErrorState;
118
+ showError: boolean;
119
+ err: string | null;
120
+ templateId: string;
121
+ handleFieldChange: (
122
+ templateId: string,
123
+ fieldName: string,
124
+ value: FieldValue,
125
+ ) => void;
126
+ finalReadOnly: boolean;
127
+ readOnly?: boolean;
128
+ setFieldTouched?: (field: string, value: boolean) => void;
129
+ validateForm?: () => Promise<Record<string, unknown>>;
130
+ }): React.ReactNode {
131
+ const value = values[k];
132
+ const rows = normalizeInputTableRows(value, input);
133
+ const tableRowErrors = getTableRowErrors(errors, k);
134
+ const hasRowErrors = tableRowErrors.length > 0;
135
+ const tableErrorToShow = showError ? err : undefined;
136
+ const rowErrorsToShow =
137
+ showError && hasRowErrors ? tableRowErrors : undefined;
138
+ const hasError = Boolean(tableErrorToShow ?? rowErrorsToShow?.length);
139
+ const showHelpText = Boolean(
140
+ !readOnly && input.helpText && !tableErrorToShow,
141
+ );
142
+
143
+ return (
144
+ <Box>
145
+ <Typography
146
+ variant="subtitle2"
147
+ sx={{ mb: 1, color: hasError ? "error.main" : "main.900" }}
148
+ >
149
+ {input.label}
150
+ </Typography>
151
+ <InputTable
152
+ rows={rows}
153
+ setRows={(newRows) =>
154
+ handleFieldChange(templateId, input.fieldName ?? "", newRows)
155
+ }
156
+ schemas={(input.schemas as ProcessTemplateInputSchema[]) ?? []}
157
+ tableError={tableErrorToShow ?? null}
158
+ rowErrors={rowErrorsToShow}
159
+ readOnly={finalReadOnly}
160
+ onCellBlur={() => {
161
+ setFieldTouched?.(k, true);
162
+ validateForm?.();
163
+ }}
164
+ />
165
+ {showHelpText ? (
166
+ <FormHelperText sx={{ my: 1, ml: 2 }}>
167
+ {input.helpText ?? ""}
168
+ </FormHelperText>
169
+ ) : null}
170
+ {tableErrorToShow ? (
171
+ <FormHelperText
172
+ error
173
+ sx={{ my: 1, ml: 2, whiteSpace: "pre-wrap", fontFamily: "inherit" }}
174
+ >
175
+ {String(tableErrorToShow)}
176
+ </FormHelperText>
177
+ ) : null}
178
+ </Box>
179
+ );
180
+ }
181
+
182
+ export function renderFormControl({
183
+ input,
184
+ templateId,
185
+ values,
186
+ errors,
187
+ touched,
188
+ handleFieldChange,
189
+ setFieldTouched,
190
+ validateForm,
191
+ readOnly,
192
+ disabledFields,
193
+ setFieldValidationInProgress,
194
+ submitValidationResults,
195
+ }: {
196
+ input: ProcessTemplateInput;
197
+ templateId: string;
198
+ values: FormState;
199
+ errors: ErrorState;
200
+ touched?: Record<string, boolean>;
201
+ handleFieldChange: (
202
+ templateId: string,
203
+ fieldName: string,
204
+ value: FieldValue,
205
+ ) => void;
206
+ setFieldTouched?: (field: string, value: boolean) => void;
207
+ validateField?: (field: string) => void | Promise<unknown>;
208
+ validateForm?: () => Promise<Record<string, unknown>>;
209
+ readOnly?: boolean;
210
+ disabledFields?: Set<string>;
211
+ setFieldValidationInProgress?: (inProgress: boolean) => void;
212
+ submitValidationResults?: Record<
213
+ string,
214
+ { isValid: boolean; message: string }
215
+ >;
216
+ }) {
217
+ const k = templateFieldKey(templateId, input.fieldName ?? "");
218
+ const err = errors[k] ?? null;
219
+ const showError = isFieldTouched(touched, k);
220
+ const isFieldDisabled = disabledFields?.has(k) ?? false;
221
+ const finalReadOnly = readOnly || isFieldDisabled;
222
+
223
+ if (isHiddenInput(input)) {
224
+ return null;
225
+ }
226
+
227
+ const validationQueryOnCheck = getValidationQueryOnCheckIfSupported(input);
228
+ if (validationQueryOnCheck) {
229
+ const queryInputTypeVal = queryInputType(input.inputType);
230
+ const submitValidationResult = submitValidationResults?.[k] ?? null;
231
+ return (
232
+ <Field name={k}>
233
+ {({ field, form, meta }: any) => (
234
+ <TextWithQueryInput
235
+ inputType={queryInputTypeVal}
236
+ label={input.label ?? ""}
237
+ value={
238
+ field.value ??
239
+ (queryInputTypeVal === InputType.CHECKBOX ? false : "")
240
+ }
241
+ setValue={(v) => form.setFieldValue(k, v)}
242
+ placeholder={input.placeholder ?? ""}
243
+ helpText={input.helpText ?? ""}
244
+ error={showError ? (meta.error ?? err) : undefined}
245
+ readOnly={finalReadOnly}
246
+ onBlur={() => form.setFieldTouched(k, true)}
247
+ fieldName={input.fieldName ?? ""}
248
+ validationQuery={validationQueryOnCheck}
249
+ fieldId={input.id ?? ""}
250
+ validateFormikBeforeApi={() =>
251
+ form
252
+ .validateForm()
253
+ .then((errors: Record<string, unknown>) => !errors[k])
254
+ }
255
+ setFieldValidationInProgress={setFieldValidationInProgress}
256
+ options={getSelectorOptionsFromInput(input)}
257
+ submitValidationResult={submitValidationResult}
258
+ />
259
+ )}
260
+ </Field>
261
+ );
262
+ }
263
+
264
+ if (input.inputType === InputType.CHECKBOX) {
265
+ return (
266
+ <Field name={k}>
267
+ {({ field, form }: any) => (
268
+ <CheckboxInput
269
+ label={input.label ?? ""}
270
+ checked={Boolean(field.value ?? false)}
271
+ setChecked={(v) => form.setFieldValue(k, v)}
272
+ helpText={input.helpText ?? ""}
273
+ readOnly={finalReadOnly}
274
+ />
275
+ )}
276
+ </Field>
277
+ );
278
+ }
279
+
280
+ if (input.inputType === InputType.NUMBER) {
281
+ return (
282
+ <Field name={k}>
283
+ {({ field, form, meta }: any) => (
284
+ <NumberInput
285
+ label={input.label ?? ""}
286
+ value={(field.value as number) ?? ""}
287
+ setValue={(v) => form.setFieldValue(k, v)}
288
+ placeholder={input.placeholder ?? ""}
289
+ helpText={input.helpText ?? ""}
290
+ error={showError ? (meta.error ?? err) : undefined}
291
+ readOnly={finalReadOnly}
292
+ onBlur={() => form.setFieldTouched(k, true)}
293
+ />
294
+ )}
295
+ </Field>
296
+ );
297
+ }
298
+
299
+ if (input.inputType === InputType.SELECTOR) {
300
+ return (
301
+ <Field name={k}>
302
+ {({ field, form, meta }: any) => (
303
+ <SelectorInput
304
+ fieldName={input.fieldName ?? ""}
305
+ label={input.label ?? ""}
306
+ value={(field.value as string) ?? ""}
307
+ setValue={(v) => form.setFieldValue(k, v)}
308
+ helpText={input.helpText ?? ""}
309
+ error={showError ? (meta.error ?? err) : undefined}
310
+ options={getSelectorOptionsFromInput(input)}
311
+ readOnly={finalReadOnly}
312
+ onBlur={() => form.setFieldTouched(k, true)}
313
+ />
314
+ )}
315
+ </Field>
316
+ );
317
+ }
318
+
319
+ if (input.inputType === InputType.MULTI_TEXT_SEARCH) {
320
+ return renderSearchInput({
321
+ input,
322
+ k,
323
+ templateId,
324
+ err,
325
+ showError,
326
+ handleFieldChange,
327
+ onBlur: () => setFieldTouched?.(k, true),
328
+ });
329
+ }
330
+
331
+ if (input.inputType === InputType.TEXT_SEARCH) {
332
+ return renderSearchInput({
333
+ input,
334
+ k,
335
+ templateId,
336
+ err,
337
+ showError,
338
+ handleFieldChange,
339
+ onBlur: () => setFieldTouched?.(k, true),
340
+ });
341
+ }
342
+
343
+ if (input.inputType === InputType.INPUT_TABLE) {
344
+ return renderInputTable({
345
+ input,
346
+ k,
347
+ values,
348
+ errors,
349
+ showError,
350
+ err,
351
+ templateId,
352
+ handleFieldChange,
353
+ finalReadOnly,
354
+ readOnly,
355
+ setFieldTouched,
356
+ validateForm,
357
+ });
358
+ }
359
+
360
+ return (
361
+ <Field name={k}>
362
+ {({ field, form, meta }: any) => (
363
+ <TextInput
364
+ label={input.label ?? ""}
365
+ value={(field.value as string) ?? ""}
366
+ setValue={(v) => form.setFieldValue(k, v)}
367
+ placeholder={input.placeholder ?? ""}
368
+ helpText={input.helpText ?? ""}
369
+ error={showError ? (meta.error ?? err) : undefined}
370
+ readOnly={finalReadOnly}
371
+ onBlur={() => form.setFieldTouched(k, true)}
372
+ />
373
+ )}
374
+ </Field>
375
+ );
376
+ }