Skip to content

Commit

Permalink
wip: form interface form
Browse files Browse the repository at this point in the history
  • Loading branch information
breeg554 committed Nov 29, 2024
1 parent 537245c commit 3dae089
Show file tree
Hide file tree
Showing 14 changed files with 731 additions and 137 deletions.
100 changes: 65 additions & 35 deletions apps/web-remix/app/api/pipeline/pipeline.contracts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,38 @@ import {
ExtendedBlockConfig,
UpdateBlockConfig,
} from '~/api/blockType/blockType.contracts';
import type { IInterfaceConfigFormProperty } from '~/components/pages/pipelines/pipeline.types';
import type {
IInterfaceConfigFormOutputProperty,
IInterfaceConfigFormProperty,
IInterfaceConfigProperty,
} from '~/components/pages/pipelines/pipeline.types';
import { PaginationMeta } from '~/components/pagination/pagination.types';

export const InterfaceConfigFormProperty = z.object({
export const InterfaceConfigProperty = z.object({
name: z.string(),
type: z.string(),
});
export const InterfaceConfigForm = z.object({

export const InterfaceConfigFormProperty = InterfaceConfigProperty.extend({
label: z.string().optional().default(''),
description: z.string().optional().default(''),
required: z
.union([z.boolean(), z.string().transform((v) => v === 'on')])
.optional()
.default(false),
});

export const InterfaceConfigFormOutputProperty =
InterfaceConfigFormProperty.omit({ required: true });

export const CommonInterfaceConfigForm = z.object({
public: z
.union([z.boolean(), z.string().transform((v) => v === 'on')])
.optional()
.default(false),
});

export const InterfaceFormConfigForm = CommonInterfaceConfigForm.extend({
inputs: z
.union([
z
Expand All @@ -32,56 +56,64 @@ export const InterfaceConfigForm = z.object({
.transform(
(value) => JSON.parse(value) as IInterfaceConfigFormProperty[],
),
z.array(InterfaceConfigFormProperty),
z.array(InterfaceConfigFormOutputProperty),
])
.default([]),
public: z
.union([z.boolean(), z.string().transform((v) => v === 'on')])
.optional()
.default(false),
});

export const InterfaceWebchatConfigForm = InterfaceConfigForm.extend({
export const InterfaceWebchatConfigForm = CommonInterfaceConfigForm.extend({
description: z
.string()
.optional()
.default('Hello. How can I help you today?'),
suggested_messages: z.array(z.string()).optional().default([]),
inputs: z
.union([
z
.string()
.transform((value) => JSON.parse(value) as IInterfaceConfigProperty[]),
z.array(InterfaceConfigProperty),
])
.default([]),
outputs: z
.union([
z
.string()
.transform((value) => JSON.parse(value) as IInterfaceConfigProperty[]),
z.array(InterfaceConfigProperty),
])
.default([]),
audio_inputs: z
.union([
z
.string()
.transform(
(value) => JSON.parse(value) as IInterfaceConfigFormProperty[],
),
z.array(InterfaceConfigFormProperty),
.transform((value) => JSON.parse(value) as IInterfaceConfigProperty[]),
z.array(InterfaceConfigProperty),
])
.default([]),
audio_outputs: z
.union([
z
.string()
.transform(
(value) => JSON.parse(value) as IInterfaceConfigFormProperty[],
),
z.array(InterfaceConfigFormProperty),
.transform((value) => JSON.parse(value) as IInterfaceConfigProperty[]),
z.array(InterfaceConfigProperty),
])
.default([]),
});

export const InterfaceConfig = z.object({
webchat: InterfaceWebchatConfigForm.optional().default({
inputs: [] as IInterfaceConfigFormProperty[],
outputs: [] as IInterfaceConfigFormProperty[],
audio_inputs: [] as IInterfaceConfigFormProperty[],
audio_outputs: [] as IInterfaceConfigFormProperty[],
inputs: [] as IInterfaceConfigProperty[],
outputs: [] as IInterfaceConfigProperty[],
audio_inputs: [] as IInterfaceConfigProperty[],
audio_outputs: [] as IInterfaceConfigProperty[],
description: 'Hello. How can I help you today?',
suggested_messages: [] as string[],
public: false,
}),
form: InterfaceConfigForm.optional().default({
form: InterfaceFormConfigForm.optional().default({
inputs: [] as IInterfaceConfigFormProperty[],
outputs: [] as IInterfaceConfigFormProperty[],
outputs: [] as IInterfaceConfigFormOutputProperty[],
public: false,
}),
});
Expand All @@ -93,34 +125,34 @@ export const SafeInterfaceConfig = z
? c
: {
webchat: {
inputs: [] as IInterfaceConfigFormProperty[],
outputs: [] as IInterfaceConfigFormProperty[],
audio_outputs: [] as IInterfaceConfigFormProperty[],
audio_inputs: [] as IInterfaceConfigFormProperty[],
inputs: [] as IInterfaceConfigProperty[],
outputs: [] as IInterfaceConfigProperty[],
audio_outputs: [] as IInterfaceConfigProperty[],
audio_inputs: [] as IInterfaceConfigProperty[],
description: 'Hello. How can I help you today?',
suggested_messages: [] as string[],
public: false,
},
form: {
inputs: [] as IInterfaceConfigFormProperty[],
outputs: [] as IInterfaceConfigFormProperty[],
outputs: [] as IInterfaceConfigFormOutputProperty[],
public: false,
},
},
)
.default({
webchat: {
inputs: [] as IInterfaceConfigFormProperty[],
outputs: [] as IInterfaceConfigFormProperty[],
audio_outputs: [] as IInterfaceConfigFormProperty[],
audio_inputs: [] as IInterfaceConfigFormProperty[],
inputs: [] as IInterfaceConfigProperty[],
outputs: [] as IInterfaceConfigProperty[],
audio_outputs: [] as IInterfaceConfigProperty[],
audio_inputs: [] as IInterfaceConfigProperty[],
description: 'Hello. How can I help you today?',
suggested_messages: [] as string[],
public: false,
},
form: {
inputs: [] as IInterfaceConfigFormProperty[],
outputs: [] as IInterfaceConfigFormProperty[],
outputs: [] as IInterfaceConfigFormOutputProperty[],
public: false,
},
});
Expand Down Expand Up @@ -352,5 +384,3 @@ export const PipelineRunLogsResponse = z.object({

export type IPipelineRunLogsResponse = z.TypeOf<typeof PipelineRunLogsResponse>;
export type IPipelineRunLog = z.TypeOf<typeof PipelineRunLog>;


2 changes: 1 addition & 1 deletion apps/web-remix/app/components/form/fields/select.field.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export const SelectField = ({
}
{...getInputProps()}
/>
<FieldLabel>{label}</FieldLabel>
{label ? <FieldLabel>{label}</FieldLabel> : null}
<SelectInput
id={name}
options={options}
Expand Down
4 changes: 2 additions & 2 deletions apps/web-remix/app/components/form/fields/text.field.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export const TextInputField = ({
...props
}: Partial<TextInputFieldProps> & {
validationBehavior?: Partial<ValidationBehaviorOptions>;
ref?: React.RefObject<HTMLInputElement | null>;
ref?: React.RefObject<HTMLInputElement | null> | null;
}) => {
const { name, getInputProps, error } = useFieldContext({
validationBehavior,
Expand Down Expand Up @@ -58,7 +58,7 @@ export function ResettableTextInputField({
size,
...props
}: Partial<TextInputFieldProps> & { label: string }) {
const inputRef = useRef<HTMLInputElement>(null);
const inputRef = useRef<HTMLInputElement | null>(null);
const { name } = useFieldContext({
validationBehavior: {
initial: 'onChange',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
}

.rc-select .rc-select-selector .rc-select-selection-search-input {
@apply !bg-white !shadow-none !ring-0 !text-foreground !text-sm !h-[40px] !outline-none;
@apply !bg-white !shadow-none !ring-0 !text-foreground !text-sm !h-[36px] !outline-none;
}

.rc-select .rc-select-selection-placeholder {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export const SelectInput: React.FC<SelectInputProps> = ({ ...props }) => {
return (
<ClientOnly
fallback={
<div className="w-full h-[44px] rounded-lg border-[1.5px] border-input bg-white" />
<div className="w-full h-[40px] rounded-lg border-[1.5px] border-input bg-white" />
}
>
{() => <AsyncSelectInputComponent {...props} />}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,14 @@ type PropertyValue =
| null
| undefined;

// todo refactor this form after bum to rmv

type State = {
formValues: {
[key: string]: PropertyValue;
};
formErrors: Record<string, string[]>;

isSubmitting?: boolean;
};

Expand Down Expand Up @@ -89,8 +92,10 @@ export const FormContext = React.createContext<{
export function useForm({
defaultValues,
onSubmit,
requiredFields,
}: {
defaultValues?: State['formValues'];
requiredFields?: string[];
onSubmit?: (
data: State['formValues'],
e: React.FormEvent<HTMLFormElement>,
Expand All @@ -104,11 +109,14 @@ export function useForm({

const validate = () => {
const errors: Record<string, string[]> = {};
Object.entries(state.formValues).forEach(([key, value]) => {
if (!value) {
errors[key] = ['This field is required'];
}
});

if (requiredFields) {
requiredFields.forEach((field) => {
if (!state.formValues[field]) {
errors[field] = ['This field is required'];
}
});
}

dispatch({ type: 'SET_ERRORS', payload: errors });

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,16 @@ export function formInterfaceReducer(
case 'DONE':
return {
...state,
outputs: Object.keys(state.outputs).reduce(
(acc, key) => {
acc[key] = {
...state.outputs[key],
isCompleted: true,
};
return acc;
},
{} as Record<string, Output>,
),
isWaitingForOutputs: false,
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ import { MessageCircle } from 'lucide-react';

import { IconButton, IconButtonProps } from '~/components/iconButton';
import { BasicLink } from '~/components/link/BasicLink';
import { IInterfaceConfigForm } from '~/components/pages/pipelines/pipeline.types';
import { IInterfaceWebchatConfigForm } from '~/components/pages/pipelines/pipeline.types';
import { useOrganizationId } from '~/hooks/useOrganizationId';
import { usePipelineId } from '~/hooks/usePipelineId';
import { cn } from '~/utils/cn';
import { routes } from '~/utils/routes.utils';

export interface FloatingChatProps {
config: IInterfaceConfigForm;
config: IInterfaceWebchatConfigForm;
chatUrl: string;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ import type {
IBlockConfig,
IConfigConnection,
IInterfaceConfig,
IInterfaceConfigProperty,
INode,
IPipeline,
} from '~/components/pages/pipelines/pipeline.types';
import { IInterfaceConfigFormProperty } from '~/components/pages/pipelines/pipeline.types';
import {
getEdges,
getNodes,
Expand Down Expand Up @@ -211,8 +211,8 @@ function validateInterfaceConfigs(
}

function validateInterfaceProperty(updated: IExtendedBlockConfig) {
return (property: IInterfaceConfigFormProperty) => {
const updatedProperty: IInterfaceConfigFormProperty = { ...property };
return (property: IInterfaceConfigProperty) => {
const updatedProperty: IInterfaceConfigProperty = { ...property };

if (property.name === updated.oldName) {
updatedProperty.name = updated.name;
Expand Down
Loading

0 comments on commit 3dae089

Please sign in to comment.