Merge remote-tracking branch 'origin/feat/rag-2' into feat/rag-2

This commit is contained in:
jyong
2025-08-07 11:13:10 +08:00
5 changed files with 94 additions and 15 deletions

View File

@@ -51,8 +51,9 @@ const Toast = ({
return <div className={cn(
className,
'fixed z-[9999] mx-8 my-4 w-[360px] grow overflow-hidden rounded-xl',
size === 'md' ? 'p-3' : 'p-2',
'border border-components-panel-border-subtle bg-components-panel-bg-blur shadow-sm',
'top-0',
'right-0',
size === 'md' ? 'p-3' : 'p-2',
className,
)}>

View File

@@ -1,11 +1,13 @@
import { RiCloseLine } from '@remixicon/react'
import InputFieldForm from './form'
import { convertFormDataToINputField, convertToInputFieldFormData } from './utils'
import { useCallback } from 'react'
import { useCallback, useMemo } from 'react'
import { useTranslation } from 'react-i18next'
import type { InputVar } from '@/models/pipeline'
import type { FormData } from './form/types'
import type { MoreInfo } from '@/app/components/workflow/types'
import { useFloatingRight } from '../hooks'
import cn from '@/utils/classnames'
export type InputFieldEditorProps = {
onClose: () => void
@@ -19,7 +21,12 @@ const InputFieldEditorPanel = ({
initialData,
}: InputFieldEditorProps) => {
const { t } = useTranslation()
const formData = convertToInputFieldFormData(initialData)
const { floatingRight, floatingRightWidth } = useFloatingRight(400)
const formData = useMemo(() => {
return convertToInputFieldFormData(initialData)
}, [initialData])
const handleSubmit = useCallback((value: FormData, moreInfo?: MoreInfo) => {
const inputFieldData = convertFormDataToINputField(value)
@@ -27,7 +34,16 @@ const InputFieldEditorPanel = ({
}, [onSubmit])
return (
<div className='relative mr-1 flex h-fit max-h-full w-[400px] flex-col overflow-y-auto rounded-2xl border-[0.5px] border-components-panel-border bg-components-panel-bg shadow-2xl shadow-shadow-shadow-9'>
<div
className={cn(
'relative mr-1 flex h-fit max-h-full w-[400px] flex-col overflow-y-auto rounded-2xl border-[0.5px] border-components-panel-border bg-components-panel-bg shadow-2xl shadow-shadow-shadow-9',
'transition-all duration-300 ease-in-out',
floatingRight && 'absolute right-0 z-[100]',
)}
style={{
width: `${floatingRightWidth}px`,
}}
>
<div className='system-xl-semibold flex items-center pb-1 pl-4 pr-11 pt-3.5 text-text-primary'>
{initialData ? t('datasetPipeline.inputFieldPanel.editInputField') : t('datasetPipeline.inputFieldPanel.addInputField')}
</div>

View File

@@ -0,0 +1,39 @@
import { useEffect, useMemo, useState } from 'react'
import { useStore } from '@/app/components/workflow/store'
import { useStore as useReactflow } from 'reactflow'
import { useShallow } from 'zustand/react/shallow'
export const useFloatingRight = (targetElementWidth: number) => {
const [floatingRight, setFloatingRight] = useState(false)
const nodePanelWidth = useStore(state => state.nodePanelWidth)
const workflowCanvasWidth = useStore(state => state.workflowCanvasWidth)
const otherPanelWidth = useStore(state => state.otherPanelWidth)
const selectedNodeId = useReactflow(useShallow((s) => {
const nodes = s.getNodes()
const currentNode = nodes.find(node => node.data.selected)
if (currentNode)
return currentNode.id
}))
useEffect(() => {
if (typeof workflowCanvasWidth === 'number') {
const inputFieldPanelWidth = 400
const marginRight = 4
const leftWidth = workflowCanvasWidth - (selectedNodeId ? nodePanelWidth : 0) - otherPanelWidth - inputFieldPanelWidth - marginRight
setFloatingRight(leftWidth < targetElementWidth + marginRight)
}
}, [workflowCanvasWidth, nodePanelWidth, otherPanelWidth, selectedNodeId, targetElementWidth])
const floatingRightWidth = useMemo(() => {
if (!floatingRight) return targetElementWidth
const width = Math.min(targetElementWidth, (selectedNodeId ? nodePanelWidth : 0) + otherPanelWidth)
return width
}, [floatingRight, selectedNodeId, nodePanelWidth, otherPanelWidth, targetElementWidth])
return {
floatingRight,
floatingRightWidth,
}
}

View File

@@ -7,18 +7,31 @@ import Divider from '@/app/components/base/divider'
import ProcessDocuments from './process-documents'
import type { Datasource } from '../../test-run/types'
import { useInputFieldPanel } from '@/app/components/rag-pipeline/hooks'
import cn from '@/utils/classnames'
import { useFloatingRight } from '../hooks'
const PreviewPanel = () => {
const { t } = useTranslation()
const [datasource, setDatasource] = useState<Datasource>()
const { toggleInputFieldPreviewPanel } = useInputFieldPanel()
const { floatingRight, floatingRightWidth } = useFloatingRight(480)
const handleClosePreviewPanel = useCallback(() => {
toggleInputFieldPreviewPanel()
}, [toggleInputFieldPreviewPanel])
return (
<div className='mr-1 flex h-full w-[480px] flex-col overflow-y-auto rounded-2xl border-y-[0.5px] border-l-[0.5px] border-components-panel-border bg-components-panel-bg shadow-xl shadow-shadow-shadow-5'>
<div
className={cn(
'mr-1 flex h-full flex-col overflow-y-auto rounded-2xl border-y-[0.5px] border-l-[0.5px] border-components-panel-border bg-components-panel-bg shadow-xl shadow-shadow-shadow-5',
'transition-all duration-300 ease-in-out',
floatingRight && 'absolute right-0 z-[100]',
)}
style={{
width: `${floatingRightWidth}px`,
}}
>
<div className='flex items-center gap-x-2 px-4 pt-1'>
<div className='grow py-1'>
<Badge className='border-text-accent-secondary bg-components-badge-bg-dimm text-text-accent-secondary'>

View File

@@ -15,6 +15,7 @@ import StructureOutputItem from '@/app/components/workflow/nodes/_base/component
import TagInput from '@/app/components/base/tag-input'
import { useNodesReadOnly } from '@/app/components/workflow/hooks'
import { useConfig } from './hooks/use-config'
import type { StructuredOutput } from '@/app/components/workflow/nodes/llm/types'
import { Type } from '@/app/components/workflow/nodes/llm/types'
import {
COMMON_OUTPUT,
@@ -48,7 +49,24 @@ const Panel: FC<NodePanelProps<DataSourceNodeType>> = ({ id, data }) => {
const pipelineId = useStore(s => s.pipelineId)
const setShowInputFieldPanel = useStore(s => s.setShowInputFieldPanel)
const wrapStructuredVarItem = (outputItem: any): StructuredOutput => {
const dataType = outputItem.value?.properties?.dify_builtin_type ? outputItem.value?.properties?.dify_builtin_type.enum[0] : Type.object
const properties = Object.fromEntries(
Object.entries(outputItem.value?.properties || {}).filter(([key]) => key !== 'dify_builtin_type'),
) as Record<string, any>
return {
schema: {
type: dataType,
properties: {
[outputItem.name]: {
...outputItem.value,
properties,
},
},
additionalProperties: false,
},
}
}
return (
<div >
{
@@ -123,15 +141,7 @@ const Panel: FC<NodePanelProps<DataSourceNodeType>> = ({ id, data }) => {
{outputItem.value?.type === 'object' ? (
<StructureOutputItem
rootClassName='code-sm-semibold text-text-secondary'
payload={{
schema: {
type: Type.object,
properties: {
[outputItem.name]: outputItem.value,
},
additionalProperties: false,
},
}} />
payload={wrapStructuredVarItem(outputItem)} />
) : (
<VarItem
name={outputItem.name}