Skip to content

Commit 5b44f46

Browse files
Enforce form validation schema in Test run limits dialog (#1918)
Fixes OPS-3482. https://www.loom.com/share/cb3fbc3bdf574c67b9a4a48fb2fd25f3
1 parent 4ef9473 commit 5b44f46

File tree

2 files changed

+64
-20
lines changed

2 files changed

+64
-20
lines changed

packages/ui-components/src/components/test-run-limits-form/test-run-limits-form.tsx

Lines changed: 57 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1+
import { typeboxResolver } from '@hookform/resolvers/typebox';
12
import { TestRunLimitSettings } from '@openops/shared';
3+
import { Type } from '@sinclair/typebox';
24
import { t } from 'i18next';
35
import React, { useEffect, useMemo } from 'react';
46
import { useForm } from 'react-hook-form';
@@ -96,6 +98,23 @@ type TestRunLimitsFormProps = {
9698
max?: number;
9799
};
98100

101+
function createTestRunLimitsSchema(min: number, max: number) {
102+
return Type.Object({
103+
isEnabled: Type.Boolean(),
104+
limits: Type.Array(
105+
Type.Object({
106+
blockName: Type.String(),
107+
actionName: Type.String(),
108+
isEnabled: Type.Boolean(),
109+
limit: Type.Number({
110+
minimum: min,
111+
maximum: max,
112+
}),
113+
}),
114+
),
115+
});
116+
}
117+
99118
function TestRunLimitsForm({
100119
value,
101120
onSave,
@@ -105,14 +124,22 @@ function TestRunLimitsForm({
105124
min = 1,
106125
max = 99,
107126
}: TestRunLimitsFormProps) {
127+
const schema = useMemo(() => createTestRunLimitsSchema(min, max), [min, max]);
128+
108129
const form = useForm<TestRunLimitSettings>({
130+
resolver: typeboxResolver(schema),
109131
defaultValues: {
110132
isEnabled: value?.isEnabled ?? false,
111133
limits: value?.limits ?? [],
112134
},
113135
mode: 'onChange',
114136
});
115137

138+
useEffect(() => {
139+
form.trigger();
140+
// eslint-disable-next-line react-hooks/exhaustive-deps
141+
}, [schema]);
142+
116143
useEffect(() => {
117144
form.reset({
118145
isEnabled: value?.isEnabled ?? false,
@@ -293,23 +320,35 @@ function TestRunLimitsForm({
293320
<FormField
294321
control={form.control}
295322
name={`limits.${index}.limit` as const}
296-
render={({ field }) => (
297-
<FormItem>
298-
<FormControl>
299-
<NumericInput
300-
min={min}
301-
max={max}
302-
value={field.value}
303-
onChange={(number) => {
304-
field.onChange(number ?? min);
305-
}}
306-
disabled={!isEnabled}
307-
integerOnly={true}
308-
className="h-8 w-[64px] outline-none"
309-
/>
310-
</FormControl>
311-
</FormItem>
312-
)}
323+
render={({ field }) => {
324+
const isInvalid =
325+
!!form.formState.errors.limits?.[index]
326+
?.limit;
327+
328+
return (
329+
<FormItem>
330+
<FormControl>
331+
<NumericInput
332+
value={field.value}
333+
onChange={(number) => {
334+
field.onChange(number ?? min);
335+
}}
336+
disabled={!isEnabled}
337+
integerOnly={true}
338+
min={min}
339+
max={max}
340+
className={cn(
341+
'h-8 w-[64px] outline-none',
342+
{
343+
'border-red-500 focus-visible:ring-red-500':
344+
isInvalid,
345+
},
346+
)}
347+
/>
348+
</FormControl>
349+
</FormItem>
350+
);
351+
}}
313352
/>
314353
</div>
315354
))}
@@ -326,7 +365,7 @@ function TestRunLimitsForm({
326365
<Button
327366
size={'lg'}
328367
loading={!!isLoading}
329-
disabled={!limits.length}
368+
disabled={!limits.length || !form.formState.isValid}
330369
onClick={() => onSave(form.getValues())}
331370
>
332371
{t('Save')}

packages/ui-components/src/ui/numeric-input.tsx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,12 @@ const NumericInput = forwardRef<HTMLInputElement, NumericInputProps>(
5656
setInternalValue(newValue);
5757

5858
if (newValue === '') {
59-
onChange?.(undefined);
59+
if (min !== undefined) {
60+
setInternalValue(String(min));
61+
onChange?.(min);
62+
} else {
63+
onChange?.(undefined);
64+
}
6065
return;
6166
}
6267

@@ -67,7 +72,7 @@ const NumericInput = forwardRef<HTMLInputElement, NumericInputProps>(
6772
onChange?.(numValue);
6873
}
6974
},
70-
[onChange, integerOnly],
75+
[onChange, integerOnly, min],
7176
);
7277

7378
const handleIncrement = useCallback(() => {

0 commit comments

Comments
 (0)