### What problem does this PR solve? Feat: Modify the background color of the agent canvas #3221 ### Type of change - [x] New Feature (non-breaking change which adds functionality)tags/v0.20.0
| @@ -17,7 +17,7 @@ export function Collapse({ | |||
| children, | |||
| rightContent, | |||
| open, | |||
| defaultOpen = true, | |||
| defaultOpen = false, | |||
| onOpenChange, | |||
| disabled, | |||
| }: CollapseProps) { | |||
| @@ -57,6 +57,7 @@ export const CrossLanguageFormField = ({ | |||
| maxCount={100} | |||
| {...field} | |||
| onValueChange={field.onChange} | |||
| defaultValue={field.value} | |||
| modalPopover | |||
| /> | |||
| </FormControl> | |||
| @@ -2,7 +2,7 @@ import { PropsWithChildren } from 'react'; | |||
| export function PageHeader({ children }: PropsWithChildren) { | |||
| return ( | |||
| <header className="flex justify-between items-center border-b bg-background-header-bar p-5"> | |||
| <header className="flex justify-between items-center border-b bg-text-title-invert p-5"> | |||
| {children} | |||
| </header> | |||
| ); | |||
| @@ -21,7 +21,7 @@ const SheetOverlay = React.forwardRef< | |||
| >(({ className, ...props }, ref) => ( | |||
| <SheetPrimitive.Overlay | |||
| className={cn( | |||
| 'fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0', | |||
| 'fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0', | |||
| className, | |||
| )} | |||
| {...props} | |||
| @@ -31,7 +31,7 @@ const SheetOverlay = React.forwardRef< | |||
| SheetOverlay.displayName = SheetPrimitive.Overlay.displayName; | |||
| const sheetVariants = cva( | |||
| 'fixed z-50 gap-4 bg-background p-6 shadow-lg transition ease-in-out data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:duration-300 data-[state=open]:duration-500', | |||
| 'fixed z-50 gap-4 bg-text-title-invert rounded-lg p-6 shadow-lg transition ease-in-out data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:duration-300 data-[state=open]:duration-500', | |||
| { | |||
| variants: { | |||
| side: { | |||
| @@ -7,7 +7,7 @@ export function NodeWrapper({ children, className, selected }: IProps) { | |||
| return ( | |||
| <section | |||
| className={cn( | |||
| 'bg-background-header-bar p-2.5 rounded-md w-[200px] text-xs', | |||
| 'bg-text-title-invert p-2.5 rounded-md w-[200px] text-xs', | |||
| { 'border border-background-checked': selected }, | |||
| className, | |||
| )} | |||
| @@ -18,12 +18,16 @@ import { useTranslation } from 'react-i18next'; | |||
| import { z } from 'zod'; | |||
| import { NodeWrapper } from '../node-wrapper'; | |||
| import { ResizeIcon, controlStyle } from '../resize-icon'; | |||
| import { useChangeName, useWatchFormChange } from './use-watch-change'; | |||
| import { useWatchFormChange, useWatchNameFormChange } from './use-watch-change'; | |||
| const FormSchema = z.object({ | |||
| text: z.string(), | |||
| }); | |||
| const NameFormSchema = z.object({ | |||
| name: z.string(), | |||
| }); | |||
| function NoteNode({ data, id, selected }: NodeProps<INoteNode>) { | |||
| const { t } = useTranslation(); | |||
| @@ -32,10 +36,15 @@ function NoteNode({ data, id, selected }: NodeProps<INoteNode>) { | |||
| defaultValues: data.form, | |||
| }); | |||
| const { handleChangeName } = useChangeName(id); | |||
| const nameForm = useForm<z.infer<typeof NameFormSchema>>({ | |||
| resolver: zodResolver(NameFormSchema), | |||
| defaultValues: { name: data.name }, | |||
| }); | |||
| useWatchFormChange(id, form); | |||
| useWatchNameFormChange(id, nameForm); | |||
| return ( | |||
| <NodeWrapper | |||
| className="p-0 w-full h-full flex flex-col rounded-md " | |||
| @@ -46,14 +55,29 @@ function NoteNode({ data, id, selected }: NodeProps<INoteNode>) { | |||
| </NodeResizeControl> | |||
| <section className="px-1 py-2 flex gap-2 bg-background-highlight items-center note-drag-handle rounded-s-md"> | |||
| <NotebookPen className="size-4" /> | |||
| <Input | |||
| type="text" | |||
| defaultValue={data.name} | |||
| onChange={handleChangeName} | |||
| ></Input> | |||
| <Form {...nameForm}> | |||
| <form> | |||
| <FormField | |||
| control={nameForm.control} | |||
| name="name" | |||
| render={({ field }) => ( | |||
| <FormItem className="h-full"> | |||
| <FormControl> | |||
| <Input | |||
| placeholder={t('flow.notePlaceholder')} | |||
| {...field} | |||
| type="text" | |||
| /> | |||
| </FormControl> | |||
| <FormMessage /> | |||
| </FormItem> | |||
| )} | |||
| /> | |||
| </form> | |||
| </Form> | |||
| </section> | |||
| <Form {...form}> | |||
| <form className="flex-1"> | |||
| <form className="flex-1 p-1"> | |||
| <FormField | |||
| control={form.control} | |||
| name="text" | |||
| @@ -62,7 +86,7 @@ function NoteNode({ data, id, selected }: NodeProps<INoteNode>) { | |||
| <FormControl> | |||
| <Textarea | |||
| placeholder={t('flow.notePlaceholder')} | |||
| className="resize-none rounded-none p-1 h-full overflow-auto bg-background-header-bar" | |||
| className="resize-none rounded-none p-1 h-full overflow-auto bg-background-header-bar focus-visible:ring-0 border-none" | |||
| {...field} | |||
| /> | |||
| </FormControl> | |||
| @@ -1,5 +1,5 @@ | |||
| import useGraphStore from '@/pages/agent/store'; | |||
| import { useCallback, useEffect } from 'react'; | |||
| import { useEffect } from 'react'; | |||
| import { UseFormReturn, useWatch } from 'react-hook-form'; | |||
| export function useWatchFormChange(id?: string, form?: UseFormReturn<any>) { | |||
| @@ -17,15 +17,14 @@ export function useWatchFormChange(id?: string, form?: UseFormReturn<any>) { | |||
| }, [id, updateNodeForm, values]); | |||
| } | |||
| export function useChangeName(id: string) { | |||
| export function useWatchNameFormChange(id?: string, form?: UseFormReturn<any>) { | |||
| let values = useWatch({ control: form?.control }); | |||
| const updateNodeName = useGraphStore((state) => state.updateNodeName); | |||
| const handleChangeName = useCallback( | |||
| (e: React.ChangeEvent<HTMLInputElement>) => { | |||
| updateNodeName(id, e.target.value.trim()); | |||
| }, | |||
| [id, updateNodeName], | |||
| ); | |||
| return { handleChangeName }; | |||
| useEffect(() => { | |||
| // Manually triggered form updates are synchronized to the canvas | |||
| if (id) { | |||
| updateNodeName(id, values.name); | |||
| } | |||
| }, [id, updateNodeName, values]); | |||
| } | |||
| @@ -105,7 +105,6 @@ const AgentChatBox = () => { | |||
| <div ref={ref} /> | |||
| </div> | |||
| <MessageInput | |||
| showUploadIcon={false} | |||
| value={value} | |||
| sendLoading={sendLoading} | |||
| disabled={false} | |||
| @@ -2,6 +2,6 @@ import { Background } from '@xyflow/react'; | |||
| export function AgentBackground() { | |||
| return ( | |||
| <Background color="rgba(255,255,255,0.15)" bgColor="rgba(22, 22, 24, 1)" /> | |||
| <Background color="rgba(255,255,255,0.15)" bgColor="rgba(11, 11, 12, 1)" /> | |||
| ); | |||
| } | |||
| @@ -65,7 +65,7 @@ const FormSheet = ({ | |||
| return ( | |||
| <Sheet open={visible} modal={false}> | |||
| <SheetContent | |||
| className={cn('top-20 p-0 flex flex-col pb-20', { | |||
| className={cn('top-20 p-0 flex flex-col pb-20 ', { | |||
| 'right-[620px]': chatVisible, | |||
| })} | |||
| closeIcon={false} | |||
| @@ -22,6 +22,7 @@ import { z } from 'zod'; | |||
| import { initialRetrievalValues } from '../../constant'; | |||
| import { useWatchFormChange } from '../../hooks/use-watch-form-change'; | |||
| import { INextOperatorForm } from '../../interface'; | |||
| import { FormWrapper } from '../components/form-wrapper'; | |||
| import { Output } from '../components/output'; | |||
| import { QueryVariable } from '../components/query-variable'; | |||
| import { useValues } from './use-values'; | |||
| @@ -92,12 +93,7 @@ function RetrievalForm({ node }: INextOperatorForm) { | |||
| return ( | |||
| <Form {...form}> | |||
| <form | |||
| className="space-y-6 p-4" | |||
| onSubmit={(e) => { | |||
| e.preventDefault(); | |||
| }} | |||
| > | |||
| <FormWrapper> | |||
| <FormContainer> | |||
| <QueryVariable></QueryVariable> | |||
| <KnowledgeBaseFormField></KnowledgeBaseFormField> | |||
| @@ -114,7 +110,7 @@ function RetrievalForm({ node }: INextOperatorForm) { | |||
| <UseKnowledgeGraphFormField name="use_kg"></UseKnowledgeGraphFormField> | |||
| </FormContainer> | |||
| <Output list={outputList}></Output> | |||
| </form> | |||
| </FormWrapper> | |||
| </Form> | |||
| ); | |||
| } | |||
| @@ -32,8 +32,8 @@ export default function Agent() { | |||
| ); | |||
| return ( | |||
| <section> | |||
| <div className="px-8 pt-8"> | |||
| <section className="flex flex-col w-full flex-1"> | |||
| <div className="px-8 pt-8 "> | |||
| <ListFilterBar | |||
| title="Agents" | |||
| searchString={searchString} | |||
| @@ -45,18 +45,20 @@ export default function Agent() { | |||
| </Button> | |||
| </ListFilterBar> | |||
| </div> | |||
| <div className="flex flex-wrap gap-4 max-h-[78vh] overflow-auto px-8"> | |||
| {data.map((x) => { | |||
| return ( | |||
| <AgentCard | |||
| key={x.id} | |||
| data={x} | |||
| showAgentRenameModal={showAgentRenameModal} | |||
| ></AgentCard> | |||
| ); | |||
| })} | |||
| <div className="flex-1 overflow-auto"> | |||
| <div className="flex flex-wrap gap-4 px-8"> | |||
| {data.map((x) => { | |||
| return ( | |||
| <AgentCard | |||
| key={x.id} | |||
| data={x} | |||
| showAgentRenameModal={showAgentRenameModal} | |||
| ></AgentCard> | |||
| ); | |||
| })} | |||
| </div> | |||
| </div> | |||
| <div className="mt-8 px-8"> | |||
| <div className="mt-8 px-8 pb-8"> | |||
| <RAGFlowPagination | |||
| {...pick(pagination, 'current', 'pageSize')} | |||
| total={pagination.total} | |||
| @@ -52,7 +52,6 @@ module.exports = { | |||
| 'background-card': 'var(--background-card)', | |||
| 'background-checked': 'var(--background-checked)', | |||
| 'background-highlight': 'var(--background-highlight)', | |||
| 'background-agent': 'var(--background-agent)', | |||
| 'input-border': 'var(--input-border)', | |||
| 'dot-green': 'var(--dot-green)', | |||
| @@ -199,7 +199,6 @@ | |||
| --background-checked: rgba(76, 164, 231, 1); | |||
| --background-highlight: rgba(76, 164, 231, 0.1); | |||
| --background-agent: rgba(22, 22, 24, 1); | |||
| --input-border: rgba(255, 255, 255, 0.2); | |||