diff --git a/dashboard/src/app/(authenticated)/(diagram)/components/Forms/WfRunForm.tsx b/dashboard/src/app/(authenticated)/(diagram)/components/Forms/WfRunForm.tsx index b4663c7311..7890919c40 100644 --- a/dashboard/src/app/(authenticated)/(diagram)/components/Forms/WfRunForm.tsx +++ b/dashboard/src/app/(authenticated)/(diagram)/components/Forms/WfRunForm.tsx @@ -14,33 +14,39 @@ type Prop = { onSubmit: (data: FormValues) => void } -// eslint-disable-next-line react/display-name export const WfRunForm = forwardRef(({ wfSpecVariables, onSubmit }, ref) => { const methods = useForm() const { register, handleSubmit, formState } = methods - const onSubmitForm = (data: FormValues) => { - onSubmit(data) - } - return ( -
+
- +
+ +
+ {!!wfSpecVariables?.length && wfSpecVariables.map((variable: ThreadVarDef) => ( - + ))}
) }) + +WfRunForm.displayName = 'WfRunForm' diff --git a/dashboard/src/app/(authenticated)/(diagram)/components/Forms/components/BaseFormField.tsx b/dashboard/src/app/(authenticated)/(diagram)/components/Forms/components/BaseFormField.tsx new file mode 100644 index 0000000000..86d28b36a2 --- /dev/null +++ b/dashboard/src/app/(authenticated)/(diagram)/components/Forms/components/BaseFormField.tsx @@ -0,0 +1,61 @@ +import { getVariableValue } from '@/app/utils' +import { Label } from '@/components/ui/label' +import { FormFieldProp } from '@/types' +import { WfRunVariableAccessLevel } from 'littlehorse-client/proto' +import { CircleAlert } from 'lucide-react' +import { useFormContext } from 'react-hook-form' + +export const accessLevels: { [key in WfRunVariableAccessLevel]: string } = { + PUBLIC_VAR: 'Public', + INHERITED_VAR: 'Inherited', + PRIVATE_VAR: 'Private', + UNRECOGNIZED: '', +} + +type FormFieldWrapperProps = { + variables: FormFieldProp['variable'] + children: React.ReactNode +} + +export const BaseFormField = ({ variables, children }: FormFieldWrapperProps) => { + const { + formState: { errors }, + } = useFormContext() + + if (!variables?.varDef?.name) return null + + const { + varDef: { name, defaultValue }, + required, + accessLevel, + } = variables + + const hasDefaultValue = !!defaultValue + + return ( +
+
+ +
+ +
{children}
+ {errors[name] && ( +

+ + {errors[name]?.message?.toString()} +

+ )} +
+ ) +} diff --git a/dashboard/src/app/(authenticated)/(diagram)/components/Forms/components/FormFields.tsx b/dashboard/src/app/(authenticated)/(diagram)/components/Forms/components/FormFields.tsx index 75aa5d072c..9d492fc8fe 100644 --- a/dashboard/src/app/(authenticated)/(diagram)/components/Forms/components/FormFields.tsx +++ b/dashboard/src/app/(authenticated)/(diagram)/components/Forms/components/FormFields.tsx @@ -1,16 +1,10 @@ -import React, { FC } from 'react' +import { FormFieldProp } from '@/types' +import { FC } from 'react' import { FormComponent } from './formType' -import { VariableType, ThreadVarDef } from 'littlehorse-client/proto' -import { FieldValues, UseFormRegister, FormState } from 'react-hook-form' -type Prop = { - variables: ThreadVarDef - register: UseFormRegister - formState: FormState -} -export const FormFields: FC = props => { - const type = props.variables?.varDef?.type as VariableType - if (!type) return - const Component = FormComponent[type] - return +export const FormFields: FC = ({ variable: variables, register, formState }) => { + if (!variables?.varDef?.type) return null + + const Component = FormComponent[variables.varDef.type] + return } diff --git a/dashboard/src/app/(authenticated)/(diagram)/components/Forms/components/FormInput.tsx b/dashboard/src/app/(authenticated)/(diagram)/components/Forms/components/FormInput.tsx index e2ba9a1783..ae5b3c445a 100644 --- a/dashboard/src/app/(authenticated)/(diagram)/components/Forms/components/FormInput.tsx +++ b/dashboard/src/app/(authenticated)/(diagram)/components/Forms/components/FormInput.tsx @@ -1,77 +1,43 @@ import { VARIABLE_TYPES } from '@/app/constants' import { Input } from '@/components/ui/input' -import { Label } from '@/components/ui/label' import { FormFieldProp } from '@/types' import { VariableType } from 'littlehorse-client/proto' -import { CircleAlert } from 'lucide-react' -import { FC, useState } from 'react' -import { accessLevels } from '../../../wfSpec/[...props]/components/Variables' +import { FC } from 'react' +import { useFormContext } from 'react-hook-form' +import { BaseFormField } from './BaseFormField' export const FormInput: FC = props => { - const [isDisabled, setIsDisabled] = useState(false) - if (!props.variables?.varDef?.name) return null + const { register } = useFormContext() + + if (!props.variable?.varDef?.name) return null const { - variables: { + variable: { varDef: { type, name }, required, - accessLevel, }, - register, - formState: { errors }, } = props - const variableToType = (variable: VariableType) => { - switch (variable) { - case VariableType.INT: - return 'number' - case VariableType.DOUBLE: - return 'number' - case VariableType.BYTES: - return 'number' - case VariableType.STR: - return 'text' - default: - return 'text' - } - } - - const setValue = (value: number | string) => { - if (value === null) return value - return variableToType(type) === 'number' ? parseFloat(value?.toString()) || undefined : value || undefined - } - return ( -
-
- -
+ { + if (value === '') return undefined + + if ((type === VariableType.DOUBLE || type === VariableType.INT) && value) { + return parseFloat(value) + } + + return value + }, })} /> - {errors[name] && ( -

- - {errors[name]?.message} -

- )} -
+ ) } diff --git a/dashboard/src/app/(authenticated)/(diagram)/components/Forms/components/FormSelect.tsx b/dashboard/src/app/(authenticated)/(diagram)/components/Forms/components/FormSelect.tsx index c3ba897fae..42b73e3dcb 100644 --- a/dashboard/src/app/(authenticated)/(diagram)/components/Forms/components/FormSelect.tsx +++ b/dashboard/src/app/(authenticated)/(diagram)/components/Forms/components/FormSelect.tsx @@ -1,33 +1,25 @@ -import { Label } from '@/components/ui/label' import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select' import { FormFieldProp } from '@/types' -import { CircleAlert } from 'lucide-react' import { FC, useState } from 'react' import { useFormContext } from 'react-hook-form' -import { accessLevels } from '../../../wfSpec/[...props]/components/Variables' +import { BaseFormField } from './BaseFormField' -export const FormSelect: FC = props => { - const { - register, - setValue, - formState: { errors }, - getValues, - trigger, - } = useFormContext() - const [isDisabled, setIsDisabled] = useState(false) +export const FormSelect: FC = (props) => { + const { register, setValue, getValues, trigger } = useFormContext() + const [isDisabled] = useState(false) - if (!props.variables?.varDef?.name) return null + if (!props.variable?.varDef?.name) return null const { - variables: { + variable: { varDef: { name }, required, - accessLevel, }, } = props - const handleChange = (value: string) => { - if (value === 'none') setValue(name, undefined) + const handleChange = (value: string | null) => { + if (value === null) setValue(name, null) + else if (value === 'none') setValue(name, undefined) else { const booleanValue = value === 'true' setValue(name, booleanValue) @@ -38,25 +30,14 @@ export const FormSelect: FC = props => { const value = getValues(name) return ( -
-
- -
+ - {errors[name]?.message && ( -

- - {String(errors[name]?.message)} -

- )} -
+ ) } diff --git a/dashboard/src/app/(authenticated)/(diagram)/components/Forms/components/FormTextarea.tsx b/dashboard/src/app/(authenticated)/(diagram)/components/Forms/components/FormTextarea.tsx index adebb0dce4..709522d0ea 100644 --- a/dashboard/src/app/(authenticated)/(diagram)/components/Forms/components/FormTextarea.tsx +++ b/dashboard/src/app/(authenticated)/(diagram)/components/Forms/components/FormTextarea.tsx @@ -1,63 +1,38 @@ -import { Label } from '@/components/ui/label' +import { VARIABLE_TYPES } from '@/app/constants' import { Textarea } from '@/components/ui/textarea' import { FormFieldProp } from '@/types' -import { FC, useState } from 'react' - -import { VARIABLE_TYPES } from '@/app/constants' -import { CircleAlert } from 'lucide-react' +import { FC } from 'react' import { useFormContext } from 'react-hook-form' -import { accessLevels } from '../../../wfSpec/[...props]/components/Variables' +import { BaseFormField } from './BaseFormField' import { getValidation } from './validation' -export const FormTextarea: FC = props => { - const [isDisabled, setIsDisabled] = useState(false) - const { setValue, trigger } = useFormContext() +export const FormTextarea: FC = (props) => { + const { setValue, trigger, register } = useFormContext() + + if (!props.variable?.varDef?.name) return null - if (!props.variables?.varDef?.name) return const { - variables: { + variable: { varDef: { type, name }, - accessLevel, required, }, - register, - formState: { errors }, } = props return ( -
-
- -
+