FEAT: NEW WORKFLOW ENGINE (#3160)

Co-authored-by: Joel <iamjoel007@gmail.com>
Co-authored-by: Yeuoly <admin@srmxy.cn>
Co-authored-by: JzoNg <jzongcode@gmail.com>
Co-authored-by: StyleZhang <jasonapring2015@outlook.com>
Co-authored-by: jyong <jyong@dify.ai>
Co-authored-by: nite-knite <nkCoding@gmail.com>
Co-authored-by: jyong <718720800@qq.com>
This commit is contained in:
takatost
2024-04-08 18:51:46 +08:00
committed by GitHub
parent 2fb9850af5
commit 7753ba2d37
1161 changed files with 103836 additions and 10327 deletions

View File

@@ -0,0 +1,57 @@
'use client'
import type { FC } from 'react'
import React from 'react'
import { useTranslation } from 'react-i18next'
import TextEditor from '../../_base/components/editor/text-editor'
import MemoryConfig from '../../_base/components/memory-config'
import type { Memory } from '@/app/components/workflow/types'
const i18nPrefix = 'workflow.nodes.questionClassifiers'
type Props = {
instruction: string
onInstructionChange: (instruction: string) => void
hideMemorySetting: boolean
memory?: Memory
onMemoryChange: (memory?: Memory) => void
readonly?: boolean
}
const AdvancedSetting: FC<Props> = ({
instruction,
onInstructionChange,
hideMemorySetting,
memory,
onMemoryChange,
readonly,
}) => {
const { t } = useTranslation()
return (
<>
<TextEditor
title={t(`${i18nPrefix}.instruction`)!}
value={instruction}
onChange={onInstructionChange}
minHeight={160}
placeholder={t(`${i18nPrefix}.instructionPlaceholder`)!}
headerRight={(
<div className='flex items-center h-full'>
<div className='text-xs font-medium text-gray-500'>{instruction?.length || 0}</div>
<div className='mx-3 h-3 w-px bg-gray-200'></div>
</div>
)}
readonly={readonly}
/>
{!hideMemorySetting && (
<MemoryConfig
className='mt-4'
readonly={false}
config={{ data: memory }}
onChange={onMemoryChange}
canSetRoleName={false}
/>
)}
</>
)
}
export default React.memo(AdvancedSetting)

View File

@@ -0,0 +1,63 @@
'use client'
import type { FC } from 'react'
import React, { useCallback } from 'react'
import { useTranslation } from 'react-i18next'
import type { Topic } from '../types'
import TextEditor from '../../_base/components/editor/text-editor'
import { Trash03 } from '@/app/components/base/icons/src/vender/line/general'
const i18nPrefix = 'workflow.nodes.questionClassifiers'
type Props = {
payload: Topic
onChange: (payload: Topic) => void
onRemove: () => void
index: number
readonly?: boolean
}
const ClassItem: FC<Props> = ({
payload,
onChange,
onRemove,
index,
readonly,
}) => {
const { t } = useTranslation()
const handleNameChange = useCallback((value: string) => {
onChange({ ...payload, name: value })
}, [onChange, payload])
return (
<TextEditor
title={<div>
<div className='w-[200px]'>
<div
className='leading-4 text-xs font-semibold text-gray-700'
>
{`${t(`${i18nPrefix}.class`)} ${index}`}
</div>
</div>
</div>}
value={payload.name}
onChange={handleNameChange}
placeholder={t(`${i18nPrefix}.topicPlaceholder`)!}
headerRight={(
<div className='flex items-center h-full'>
<div className='text-xs font-medium text-gray-500'>{payload.name.length}</div>
<div className='mx-3 h-3 w-px bg-gray-200'></div>
{!readonly && (
<Trash03
className='mr-1 w-3.5 h-3.5 text-gray-500 cursor-pointer'
onClick={onRemove}
/>
)}
</div>
)}
readonly={readonly}
minHeight={64}
/>
)
}
export default React.memo(ClassItem)

View File

@@ -0,0 +1,82 @@
'use client'
import type { FC } from 'react'
import React, { useCallback } from 'react'
import produce from 'immer'
import { useTranslation } from 'react-i18next'
import { useEdgesInteractions } from '../../../hooks'
import AddButton from '../../_base/components/add-button'
import Item from './class-item'
import type { Topic } from '@/app/components/workflow/nodes/question-classifier/types'
const i18nPrefix = 'workflow.nodes.questionClassifiers'
type Props = {
id: string
list: Topic[]
onChange: (list: Topic[]) => void
readonly?: boolean
}
const ClassList: FC<Props> = ({
id,
list,
onChange,
readonly,
}) => {
const { t } = useTranslation()
const { handleEdgeDeleteByDeleteBranch } = useEdgesInteractions()
const handleClassChange = useCallback((index: number) => {
return (value: Topic) => {
const newList = produce(list, (draft) => {
draft[index] = value
})
onChange(newList)
}
}, [list, onChange])
const handleAddClass = useCallback(() => {
const newList = produce(list, (draft) => {
draft.push({ id: `${Date.now()}`, name: '' })
})
onChange(newList)
}, [list, onChange])
const handleRemoveClass = useCallback((index: number) => {
return () => {
handleEdgeDeleteByDeleteBranch(id, list[index].id)
const newList = produce(list, (draft) => {
draft.splice(index, 1)
})
onChange(newList)
}
}, [list, onChange, handleEdgeDeleteByDeleteBranch, id])
// Todo Remove; edit topic name
return (
<div className='space-y-2'>
{
list.map((item, index) => {
return (
<Item
key={index}
payload={item}
onChange={handleClassChange(index)}
onRemove={handleRemoveClass(index)}
index={index + 1}
readonly={readonly}
/>
)
})
}
{!readonly && (
<AddButton
onClick={handleAddClass}
text={t(`${i18nPrefix}.addClass`)}
/>
)}
</div>
)
}
export default React.memo(ClassList)