diff --git a/web/app/components/workflow/variable-inspect/group.tsx b/web/app/components/workflow/variable-inspect/group.tsx
new file mode 100644
index 0000000000..67a06e331d
--- /dev/null
+++ b/web/app/components/workflow/variable-inspect/group.tsx
@@ -0,0 +1,128 @@
+import { useState } from 'react'
+import { useTranslation } from 'react-i18next'
+import {
+ RiArrowRightSLine,
+ // RiErrorWarningFill,
+ // RiLoader2Line,
+} from '@remixicon/react'
+import { useStore } from '../store'
+// import { BlockEnum } from '../types'
+// import Button from '@/app/components/base/button'
+// import ActionButton from '@/app/components/base/action-button'
+// import Tooltip from '@/app/components/base/tooltip'
+// import BlockIcon from '@/app/components/workflow/block-icon'
+import {
+ // BubbleX,
+ Env,
+} from '@/app/components/base/icons/src/vender/line/others'
+// import { Variable02 } from '@/app/components/base/icons/src/vender/solid/development'
+// import useCurrentVars from '../hooks/use-inspect-vars-crud'
+import type { currentVarType } from './panel'
+import cn from '@/utils/classnames'
+
+type Props = {
+ isEnv?: boolean
+ isChatVar?: boolean
+ isSystem?: boolean
+ currentVar?: currentVarType
+ handleSelect: (state: any) => void
+}
+
+const Group = ({
+ isEnv,
+ isChatVar,
+ isSystem,
+ currentVar,
+ handleSelect,
+}: Props) => {
+ const { t } = useTranslation()
+
+ const environmentVariables = useStore(s => s.environmentVariables)
+ // const {
+ // conversationVars,
+ // systemVars,
+ // nodesWithInspectVars,
+ // } = useCurrentVars()
+
+ const [isCollapsed, setIsCollapsed] = useState(false)
+
+ const handleSelectVar = (varItem: any, type?: string) => {
+ if (type === 'env') {
+ handleSelect({
+ nodeId: 'env',
+ nodeTitle: 'env',
+ nodeType: 'env',
+ var: {
+ ...varItem,
+ type: 'env',
+ ...(varItem.value_type === 'secret' ? { value: '******************' } : {}),
+ },
+ })
+ return
+ }
+ if (type === 'chat') {
+ handleSelect({
+ nodeId: 'conversation',
+ nodeTitle: 'conversation',
+ nodeType: 'conversation',
+ var: {
+ ...varItem,
+ type: 'conversation',
+ },
+ })
+ return
+ }
+ if (type === 'system') {
+ handleSelect({
+ nodeId: 'sys',
+ nodeTitle: 'sys',
+ nodeType: 'sys',
+ var: varItem,
+ })
+ return
+ }
+ handleSelect({
+ nodeId: varItem.nodeId,
+ nodeTitle: varItem.nodeTitle,
+ nodeType: varItem.nodeType,
+ var: varItem.var,
+ })
+ }
+
+ return (
+
+ {/* node item */}
+
+
+
setIsCollapsed(!isCollapsed)}>
+
+ {isEnv && t('workflow.debug.variableInspect.envNode')}
+ {isChatVar && t('workflow.debug.variableInspect.chatNode')}
+ {isSystem && t('workflow.debug.variableInspect.systemNode')}
+
+
+
+ {/* var item list */}
+ {!isCollapsed && (
+
+ {environmentVariables.length > 0 && environmentVariables.map(env => (
+
handleSelectVar(env, 'env')}
+ >
+
+
{env.name}
+
{env.value_type}
+
+ ))}
+
+ )}
+
+ )
+}
+
+export default Group
diff --git a/web/app/components/workflow/variable-inspect/left.tsx b/web/app/components/workflow/variable-inspect/left.tsx
index e9538e8e0b..045a1e859b 100644
--- a/web/app/components/workflow/variable-inspect/left.tsx
+++ b/web/app/components/workflow/variable-inspect/left.tsx
@@ -5,27 +5,35 @@ import {
RiErrorWarningFill,
RiLoader2Line,
} from '@remixicon/react'
-// import { useStore } from '../store'
+import { useStore } from '../store'
import { BlockEnum } from '../types'
import Button from '@/app/components/base/button'
-// import ActionButton from '@/app/components/base/action-button'
-// import Tooltip from '@/app/components/base/tooltip'
+// import ActionButton from '@/app/components/base/action-button'
+// import Tooltip from '@/app/components/base/tooltip'
import BlockIcon from '@/app/components/workflow/block-icon'
-import { BubbleX, Env } from '@/app/components/base/icons/src/vender/line/others'
+import { BubbleX } from '@/app/components/base/icons/src/vender/line/others'
import { Variable02 } from '@/app/components/base/icons/src/vender/solid/development'
+import Group from './group'
import useCurrentVars from '../hooks/use-inspect-vars-crud'
+import type { currentVarType } from './panel'
import cn from '@/utils/classnames'
type Props = {
- handleMenuClick: (state: any) => void
+ currentNodeVar?: currentVarType
+ handleVarSelect: (state: any) => void
}
-const Left = ({ handleMenuClick }: Props) => {
+const Left = ({
+ currentNodeVar,
+ handleVarSelect,
+}: Props) => {
const { t } = useTranslation()
- // const bottomPanelWidth = useStore(s => s.bottomPanelWidth)
- // const setShowVariableInspectPanel = useStore(s => s.setShowVariableInspectPanel)
+ const environmentVariables = useStore(s => s.environmentVariables)
const {
+ conversationVars,
+ systemVars,
+ nodesWithInspectVars,
deleteAllInspectorVars,
} = useCurrentVars()
@@ -42,29 +50,13 @@ const Left = ({ handleMenuClick }: Props) => {
{/* content */}
{/* group ENV */}
-
- {/* node item */}
-
-
-
-
{t('workflow.env.envPanelTitle')}
-
-
- {/* var item list */}
-
-
-
-
SECRET_KEY
-
string
-
-
- {selectedNode &&
}
-
-
PORT
-
number
-
-
-
+ {environmentVariables.length > 0 && (
+
+ )}
{/* group CHAT VAR */}
{/* node item */}
diff --git a/web/app/components/workflow/variable-inspect/panel.tsx b/web/app/components/workflow/variable-inspect/panel.tsx
index 46d8ca8607..4c6a86d990 100644
--- a/web/app/components/workflow/variable-inspect/panel.tsx
+++ b/web/app/components/workflow/variable-inspect/panel.tsx
@@ -10,14 +10,23 @@ import Empty from './empty'
import Left from './left'
import Right from './right'
import ActionButton from '@/app/components/base/action-button'
+import type { VarInInspect } from '@/types/workflow'
import cn from '@/utils/classnames'
+export type currentVarType = {
+ nodeId: string
+ nodeTitle: string
+ nodeType: string
+ var: VarInInspect
+}
+
const Panel: FC = () => {
const { t } = useTranslation()
const bottomPanelWidth = useStore(s => s.bottomPanelWidth)
const setShowVariableInspectPanel = useStore(s => s.setShowVariableInspectPanel)
const [showLeftPanel, setShowLeftPanel] = useState(true)
+ const [currentNodeVar, setCurrentNodeVar] = useState()
const environmentVariables = useStore(s => s.environmentVariables)
const {
@@ -60,11 +69,17 @@ const Panel: FC = () => {
: 'block',
)}
>
-
+
{/* right */}
- setShowLeftPanel(true)} />
+ setShowLeftPanel(true)}
+ />
)
diff --git a/web/app/components/workflow/variable-inspect/right.tsx b/web/app/components/workflow/variable-inspect/right.tsx
index 2ce95044b8..58e59bbee5 100644
--- a/web/app/components/workflow/variable-inspect/right.tsx
+++ b/web/app/components/workflow/variable-inspect/right.tsx
@@ -6,7 +6,7 @@ import {
RiMenuLine,
} from '@remixicon/react'
import { useStore } from '../store'
-import { BlockEnum } from '../types'
+import type { BlockEnum } from '../types'
import useCurrentVars from '../hooks/use-inspect-vars-crud'
import Empty from './empty'
import ValueContent from './value-content'
@@ -16,43 +16,29 @@ import CopyFeedback from '@/app/components/base/copy-feedback'
import Tooltip from '@/app/components/base/tooltip'
import BlockIcon from '@/app/components/workflow/block-icon'
import { BubbleX, Env } from '@/app/components/base/icons/src/vender/line/others'
+import type { currentVarType } from './panel'
import cn from '@/utils/classnames'
-export const currentVar = {
- id: 'var-jfkldjjfkldaf-dfhekdfj',
- type: 'node',
- // type: 'conversation',
- // type: 'environment',
- name: 'out_put',
- var_type: 'string',
- // var_type: 'number',
- // var_type: 'object',
- // var_type: 'array[string]',
- // var_type: 'array[number]',
- // var_type: 'array[object]',
- // var_type: 'file',
- // var_type: 'array[file]',
- value: 'tuituitui',
- edited: true,
-}
-
type Props = {
+ currentNodeVar?: currentVarType
handleOpenMenu: () => void
}
-const Right = ({ handleOpenMenu }: Props) => {
+const Right = ({
+ currentNodeVar,
+ handleOpenMenu,
+}: Props) => {
const { t } = useTranslation()
const bottomPanelWidth = useStore(s => s.bottomPanelWidth)
const setShowVariableInspectPanel = useStore(s => s.setShowVariableInspectPanel)
- const current = currentVar
-
const {
resetToLastRunVar,
} = useCurrentVars()
const resetValue = () => {
- resetToLastRunVar('node_id', current.name)
+ if (!currentNodeVar) return
+ resetToLastRunVar(currentNodeVar.nodeId, currentNodeVar.var.name)
}
return (
@@ -65,48 +51,48 @@ const Right = ({ handleOpenMenu }: Props) => {
)}
- {current && (
+ {currentNodeVar && (
<>
- {current.type === 'environment' && (
+ {currentNodeVar.nodeType === 'env' && (
)}
- {current.type === 'conversation' && (
+ {currentNodeVar.nodeType === 'conversation' && (
)}
- {current.type === 'node' && (
+ {currentNodeVar.nodeType !== 'env' && currentNodeVar.nodeType !== 'conversation' && currentNodeVar.nodeType !== 'sys' && (
<>
-
LLM
+
{currentNodeVar.nodeTitle}
/
>
)}
-
{current.name}
-
{current.var_type}
+
{currentNodeVar.var.name}
+
{currentNodeVar.var.value_type}
>
)}
- {current && (
+ {currentNodeVar && (
<>
- {current.edited && (
+ {currentNodeVar.var.edited && (
{t('workflow.debug.variableInspect.edited')}
)}
- {current.edited && (
+ {currentNodeVar.var.edited && (
)}
- {(current.type !== 'environment' || current.var_type !== 'secret') && (
-
+ {currentNodeVar.var.value_type !== 'secret' && (
+
)}
>
)}
@@ -117,8 +103,8 @@ const Right = ({ handleOpenMenu }: Props) => {
{/* content */}
- {!current && }
- {current && }
+ {!currentNodeVar && }
+ {currentNodeVar && }
)
diff --git a/web/app/components/workflow/variable-inspect/value-content.tsx b/web/app/components/workflow/variable-inspect/value-content.tsx
index ee75912702..132d299c82 100644
--- a/web/app/components/workflow/variable-inspect/value-content.tsx
+++ b/web/app/components/workflow/variable-inspect/value-content.tsx
@@ -19,22 +19,24 @@ import { JSON_SCHEMA_MAX_DEPTH } from '@/config'
import { TransferMethod } from '@/types/app'
import { FILE_EXTS } from '@/app/components/base/prompt-editor/constants'
import { SupportUploadFileTypes } from '@/app/components/workflow/types'
+import type { VarInInspect } from '@/types/workflow'
+import { VarInInspectType } from '@/types/workflow'
import cn from '@/utils/classnames'
-export const currentVar = {
+export const MOCK_DATA = {
id: 'var-jfkldjjfkldaf-dfhekdfj',
type: 'node',
// type: 'conversation',
// type: 'environment',
name: 'out_put',
- // var_type: 'string',
- // var_type: 'number',
- // var_type: 'object',
- // var_type: 'array[string]',
- // var_type: 'array[number]',
- // var_type: 'array[object]',
- // var_type: 'file',
- var_type: 'array[file]',
+ // value_type: 'string',
+ // value_type: 'number',
+ // value_type: 'object',
+ // value_type: 'array[string]',
+ // value_type: 'array[number]',
+ // value_type: 'array[object]',
+ // value_type: 'file',
+ value_type: 'array[file]',
// value: 'tuituitui',
// value: ['aaa', 'bbb', 'ccc'],
// value: {
@@ -46,34 +48,62 @@ export const currentVar = {
edited: true,
}
-const ValueContent = () => {
- const current = currentVar
+type Props = {
+ currentVar: VarInInspect
+}
+
+const ValueContent = ({
+ // currentVar = MOCK_DATA as any, // TODO remove this line
+ currentVar,
+}: Props) => {
const contentContainerRef = useRef(null)
const errorMessageRef = useRef(null)
const [editorHeight, setEditorHeight] = useState(0)
- const showTextEditor = current.var_type === 'secret' || current.var_type === 'string' || current.var_type === 'number'
- const showJSONEditor = current.var_type === 'object' || current.var_type === 'array[string]' || current.var_type === 'array[number]' || current.var_type === 'array[object]'
- const showFileEditor = current.var_type === 'file' || current.var_type === 'array[file]'
+ const showTextEditor = currentVar.value_type === 'secret' || currentVar.value_type === 'string' || currentVar.value_type === 'number'
+ const showJSONEditor = currentVar.value_type === 'object' || currentVar.value_type === 'array[string]' || currentVar.value_type === 'array[number]' || currentVar.value_type === 'array[object]'
+ const showFileEditor = currentVar.value_type === 'file' || currentVar.value_type === 'array[file]'
- const [value, setValue] = useState(current.value ? JSON.stringify(current.value) : '')
- const [jsonSchema, setJsonSchema] = useState(current.value || null)
- const [json, setJson] = useState(JSON.stringify(jsonSchema, null, 2))
+ const [value, setValue] = useState()
+ const [jsonSchema, setJsonSchema] = useState()
+ const [json, setJson] = useState('')
const [parseError, setParseError] = useState(null)
const [validationError, setValidationError] = useState('')
const fileFeature = useFeatures(s => s.features.file)
const [fileValue, setFileValue] = useState(
- current.var_type === 'array[file]'
- ? current.value || []
- : current.value
- ? [current.value]
+ currentVar.value_type === 'array[file]'
+ ? currentVar.value || []
+ : currentVar.value
+ ? [currentVar.value]
: [],
)
+ // update default value when id changed
+ useEffect(() => {
+ if (showTextEditor) {
+ if (!currentVar.value)
+ return setValue('')
+ if (currentVar.value_type === 'number')
+ return setValue(JSON.stringify(currentVar.value))
+ setValue(currentVar.value)
+ }
+ if (showJSONEditor) {
+ setJsonSchema(currentVar.value || null)
+ setJson(currentVar.value ? JSON.stringify(currentVar.value, null, 2) : '')
+ }
+ if (showFileEditor) {
+ setFileValue(currentVar.value_type === 'array[file]'
+ ? currentVar.value || []
+ : currentVar.value
+ ? [currentVar.value]
+ : [])
+ }
+ }, [currentVar, showTextEditor, showJSONEditor, showFileEditor])
+
const handleTextChange = (value: string) => {
- if (current.var_type === 'string')
+ if (currentVar.value_type === 'string')
setValue(value)
- if (current.var_type === 'number') {
+ if (currentVar.value_type === 'number') {
if (/^-?\d+(\.)?(\d+)?$/.test(value))
setValue(value)
}
@@ -119,7 +149,7 @@ const ValueContent = () => {
const handleEditorChange = (value: string) => {
setJson(value)
- if (jsonValueValidate(value, current.var_type)) {
+ if (jsonValueValidate(value, currentVar.value_type)) {
const parsed = JSON.parse(value)
setJsonSchema(parsed)
// TODO call api of value update
@@ -131,10 +161,10 @@ const ValueContent = () => {
setFileValue(value)
// TODO check every file upload progress
// invoke update api after every file uploaded
- if (current.var_type === 'file') {
+ if (currentVar.value_type === 'file') {
// TODO call api of value update
}
- if (current.var_type === 'array[file]') {
+ if (currentVar.value_type === 'array[file]') {
// TODO call api of value update
}
}
@@ -164,8 +194,8 @@ const ValueContent = () => {
{showTextEditor && (