### What problem does this PR solve? Feat: Add FormSheet. #3221 ### Type of change - [x] New Feature (non-breaking change which adds functionality)tags/v0.17.0
| @@ -92,7 +92,6 @@ function RerankFormField() { | |||
| <FormControl> | |||
| <Select onValueChange={field.onChange} {...field}> | |||
| <SelectTrigger | |||
| className="w-[280px]" | |||
| value={field.value} | |||
| onReset={() => { | |||
| form.resetField(RerankId); | |||
| @@ -40,7 +40,7 @@ const sheetVariants = cva( | |||
| 'inset-x-0 bottom-0 border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom', | |||
| left: 'inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm', | |||
| right: | |||
| 'inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm', | |||
| 'inset-y-0 right-0 h-full border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right w-1/3 max-w-[600px]', | |||
| }, | |||
| }, | |||
| defaultVariants: { | |||
| @@ -51,27 +51,36 @@ const sheetVariants = cva( | |||
| interface SheetContentProps | |||
| extends React.ComponentPropsWithoutRef<typeof SheetPrimitive.Content>, | |||
| VariantProps<typeof sheetVariants> {} | |||
| VariantProps<typeof sheetVariants> { | |||
| closeIcon?: boolean; | |||
| } | |||
| const SheetContent = React.forwardRef< | |||
| React.ElementRef<typeof SheetPrimitive.Content>, | |||
| SheetContentProps | |||
| >(({ side = 'right', className, children, ...props }, ref) => ( | |||
| <SheetPortal> | |||
| <SheetOverlay /> | |||
| <SheetPrimitive.Content | |||
| ref={ref} | |||
| className={cn(sheetVariants({ side }), className)} | |||
| {...props} | |||
| > | |||
| {children} | |||
| <SheetPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-secondary"> | |||
| <X className="h-4 w-4" /> | |||
| <span className="sr-only">Close</span> | |||
| </SheetPrimitive.Close> | |||
| </SheetPrimitive.Content> | |||
| </SheetPortal> | |||
| )); | |||
| >( | |||
| ( | |||
| { side = 'right', className, children, closeIcon = true, ...props }, | |||
| ref, | |||
| ) => ( | |||
| <SheetPortal> | |||
| <SheetOverlay /> | |||
| <SheetPrimitive.Content | |||
| ref={ref} | |||
| className={cn(sheetVariants({ side }), className)} | |||
| {...props} | |||
| > | |||
| {children} | |||
| {closeIcon ? ( | |||
| <SheetPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-secondary "> | |||
| <X className="h-4 w-4 " /> | |||
| <span className="sr-only">Close</span> | |||
| </SheetPrimitive.Close> | |||
| ) : null} | |||
| </SheetPrimitive.Content> | |||
| </SheetPortal> | |||
| ), | |||
| ); | |||
| SheetContent.displayName = SheetPrimitive.Content.displayName; | |||
| const SheetHeader = ({ | |||
| @@ -6,7 +6,7 @@ import { | |||
| } from '@xyflow/react'; | |||
| import '@xyflow/react/dist/style.css'; | |||
| // import ChatDrawer from '../chat/drawer'; | |||
| import FormDrawer from '../form-drawer/next'; | |||
| import FormSheet from '../form-sheet/next'; | |||
| import { | |||
| useHandleDrop, | |||
| useSelectCanvasData, | |||
| @@ -154,14 +154,14 @@ function FlowCanvas({ drawerVisible, hideDrawer }: IProps) { | |||
| <Background /> | |||
| </ReactFlow> | |||
| {formDrawerVisible && ( | |||
| <FormDrawer | |||
| <FormSheet | |||
| node={clickedNode} | |||
| visible={formDrawerVisible} | |||
| hideModal={hideFormDrawer} | |||
| singleDebugDrawerVisible={singleDebugDrawerVisible} | |||
| hideSingleDebugDrawer={hideSingleDebugDrawer} | |||
| showSingleDebugDrawer={showSingleDebugDrawer} | |||
| ></FormDrawer> | |||
| ></FormSheet> | |||
| )} | |||
| {/* {chatVisible && ( | |||
| <ChatDrawer | |||
| @@ -1,11 +1,16 @@ | |||
| import { Input } from '@/components/ui/input'; | |||
| import { Sheet, SheetContent, SheetHeader } from '@/components/ui/sheet'; | |||
| import { useTranslate } from '@/hooks/common-hooks'; | |||
| import { IModalProps } from '@/interfaces/common'; | |||
| import { CloseOutlined } from '@ant-design/icons'; | |||
| import { Flex, Input } from 'antd'; | |||
| import { RAGFlowNodeType } from '@/interfaces/database/flow'; | |||
| import { zodResolver } from '@hookform/resolvers/zod'; | |||
| import { get, isPlainObject, lowerFirst } from 'lodash'; | |||
| import { Play } from 'lucide-react'; | |||
| import { Play, X } from 'lucide-react'; | |||
| import { useEffect, useRef } from 'react'; | |||
| import { useForm } from 'react-hook-form'; | |||
| import { BeginId, Operator, operatorMap } from '../constant'; | |||
| import { FlowFormContext } from '../context'; | |||
| import { RunTooltip } from '../flow-tooltip'; | |||
| import { useHandleFormValuesChange, useHandleNodeNameChange } from '../hooks'; | |||
| import OperatorIcon from '../operator-icon'; | |||
| import { | |||
| @@ -13,14 +18,6 @@ import { | |||
| needsSingleStepDebugging, | |||
| } from '../utils'; | |||
| import SingleDebugDrawer from './single-debug-drawer'; | |||
| import { Sheet, SheetContent, SheetHeader } from '@/components/ui/sheet'; | |||
| import { RAGFlowNodeType } from '@/interfaces/database/flow'; | |||
| import { FlowFormContext } from '../context'; | |||
| import { RunTooltip } from '../flow-tooltip'; | |||
| import { zodResolver } from '@hookform/resolvers/zod'; | |||
| import { useForm } from 'react-hook-form'; | |||
| import { useFormConfigMap } from './use-form-config-map'; | |||
| interface IProps { | |||
| @@ -32,7 +29,7 @@ interface IProps { | |||
| const EmptyContent = () => <div></div>; | |||
| const FormDrawer = ({ | |||
| const FormSheet = ({ | |||
| visible, | |||
| hideModal, | |||
| node, | |||
| @@ -90,16 +87,16 @@ const FormDrawer = ({ | |||
| }, [visible, form, node?.data?.form, node?.id, node, operatorName]); | |||
| return ( | |||
| <Sheet onOpenChange={hideModal} open={visible}> | |||
| <SheetContent className="bg-white"> | |||
| <Sheet onOpenChange={hideModal} open={visible} modal={false}> | |||
| <SheetContent className="bg-white top-20" closeIcon={false}> | |||
| <SheetHeader> | |||
| <Flex vertical> | |||
| <Flex gap={'middle'} align="center"> | |||
| <section className="flex-col border-b pb-2"> | |||
| <div className="flex items-center gap-2 pb-3"> | |||
| <OperatorIcon | |||
| name={operatorName} | |||
| color={operatorMap[operatorName]?.color} | |||
| ></OperatorIcon> | |||
| <Flex align="center" gap={'small'} flex={1}> | |||
| <div className="flex items-center gap-1 flex-1"> | |||
| <label htmlFor="">{t('title')}</label> | |||
| {node?.id === BeginId ? ( | |||
| <span>{t(BeginId)}</span> | |||
| @@ -110,7 +107,7 @@ const FormDrawer = ({ | |||
| onChange={handleNameChange} | |||
| ></Input> | |||
| )} | |||
| </Flex> | |||
| </div> | |||
| {needsSingleStepDebugging(operatorName) && ( | |||
| <RunTooltip> | |||
| @@ -120,10 +117,10 @@ const FormDrawer = ({ | |||
| /> | |||
| </RunTooltip> | |||
| )} | |||
| <CloseOutlined onClick={hideModal} /> | |||
| </Flex> | |||
| <X onClick={hideModal} /> | |||
| </div> | |||
| <span>{t(`${lowerFirst(operatorName)}Description`)}</span> | |||
| </Flex> | |||
| </section> | |||
| </SheetHeader> | |||
| <section> | |||
| {visible && ( | |||
| @@ -148,4 +145,4 @@ const FormDrawer = ({ | |||
| ); | |||
| }; | |||
| export default FormDrawer; | |||
| export default FormSheet; | |||
| @@ -58,7 +58,6 @@ export function DynamicVariableForm({ node }: IProps) { | |||
| name={typeField} | |||
| render={({ field }) => ( | |||
| <FormItem className="w-2/5"> | |||
| {/* <FormLabel>City</FormLabel> */} | |||
| <FormDescription /> | |||
| <FormControl> | |||
| <RAGFlowSelect | |||
| @@ -75,8 +74,7 @@ export function DynamicVariableForm({ node }: IProps) { | |||
| control={form.control} | |||
| name={`query.${index}.${getVariableName(typeValue)}`} | |||
| render={({ field }) => ( | |||
| <FormItem> | |||
| {/* <FormLabel>State</FormLabel> */} | |||
| <FormItem className="flex-1"> | |||
| <FormDescription /> | |||
| <FormControl> | |||
| {typeValue === VariableType.Reference ? ( | |||
| @@ -11,37 +11,44 @@ import { | |||
| FormMessage, | |||
| } from '@/components/ui/form'; | |||
| import { Textarea } from '@/components/ui/textarea'; | |||
| import { useTranslate } from '@/hooks/common-hooks'; | |||
| import { useTranslation } from 'react-i18next'; | |||
| import { INextOperatorForm } from '../../interface'; | |||
| import { DynamicVariableForm } from '../components/next-dynamic-input-variable'; | |||
| const RetrievalForm = ({ form, node }: INextOperatorForm) => { | |||
| const { t } = useTranslate('flow'); | |||
| const { t } = useTranslation(); | |||
| return ( | |||
| <Form {...form}> | |||
| <DynamicVariableForm></DynamicVariableForm> | |||
| <SimilaritySliderFormField name="keywords_similarity_weight"></SimilaritySliderFormField> | |||
| <TopNFormField></TopNFormField> | |||
| <RerankFormFields></RerankFormFields> | |||
| <KnowledgeBaseFormField></KnowledgeBaseFormField> | |||
| <FormField | |||
| control={form.control} | |||
| name="empty_response" | |||
| render={({ field }) => ( | |||
| <FormItem> | |||
| <FormLabel>{t('chat.emptyResponse')}</FormLabel> | |||
| <FormControl> | |||
| <Textarea | |||
| placeholder={t('common.namePlaceholder')} | |||
| {...field} | |||
| autoComplete="off" | |||
| rows={4} | |||
| /> | |||
| </FormControl> | |||
| <FormMessage /> | |||
| </FormItem> | |||
| )} | |||
| /> | |||
| <form | |||
| className="space-y-6" | |||
| onSubmit={(e) => { | |||
| e.preventDefault(); | |||
| }} | |||
| > | |||
| <DynamicVariableForm></DynamicVariableForm> | |||
| <SimilaritySliderFormField name="keywords_similarity_weight"></SimilaritySliderFormField> | |||
| <TopNFormField></TopNFormField> | |||
| <RerankFormFields></RerankFormFields> | |||
| <KnowledgeBaseFormField></KnowledgeBaseFormField> | |||
| <FormField | |||
| control={form.control} | |||
| name="empty_response" | |||
| render={({ field }) => ( | |||
| <FormItem> | |||
| <FormLabel>{t('chat.emptyResponse')}</FormLabel> | |||
| <FormControl> | |||
| <Textarea | |||
| placeholder={t('common.namePlaceholder')} | |||
| {...field} | |||
| autoComplete="off" | |||
| rows={4} | |||
| /> | |||
| </FormControl> | |||
| <FormMessage /> | |||
| </FormItem> | |||
| )} | |||
| /> | |||
| </form> | |||
| </Form> | |||
| ); | |||
| }; | |||