feat: support show global vars

This commit is contained in:
Joel
2025-10-21 17:59:25 +08:00
parent 2793ede875
commit 04b55177b5
9 changed files with 108 additions and 22 deletions

View File

@ -35,7 +35,12 @@ export const NODE_LAYOUT_HORIZONTAL_PADDING = 60
export const NODE_LAYOUT_VERTICAL_PADDING = 60
export const NODE_LAYOUT_MIN_DISTANCE = 100
export const isInWorkflowPage = () => {
const pathname = globalThis.location.pathname
return /^\/app\/[^/]+\/workflow$/.test(pathname) || /^\/workflow\/[^/]+$/.test(pathname)
}
export const getGlobalVars = (isChatMode: boolean): Var[] => {
const isInWorkflow = isInWorkflowPage()
const vars: Var[] = [
...(isChatMode ? [
{
@ -63,6 +68,12 @@ export const getGlobalVars = (isChatMode: boolean): Var[] => {
variable: 'sys.workflow_run_id',
type: VarType.string,
},
...(isInWorkflow ? [
{
variable: 'sys.trigger_timestamp',
type: VarType.string,
},
] : []),
]
return vars
}

View File

@ -11,7 +11,7 @@ const GlobalVariableButton = ({ disabled }: { disabled: boolean }) => {
}
return (
<Button className='p-2' disabled={disabled} onClick={handleClick}>
<Button className='p-2' disabled={disabled} onClick={handleClick} variant='ghost'>
<GlobalVariable className='h-4 w-4 text-components-button-secondary-text' />
</Button>
)

View File

@ -20,6 +20,7 @@ import EnvButton from './env-button'
import VersionHistoryButton from './version-history-button'
import { useInputFieldPanel } from '@/app/components/rag-pipeline/hooks'
import ScrollToSelectedNodeButton from './scroll-to-selected-node-button'
import GlobalVariableButton from './global-variable-button'
export type HeaderInNormalProps = {
components?: {
@ -72,9 +73,10 @@ const HeaderInNormal = ({
{components?.left}
<Divider type='vertical' className='mx-auto h-3.5' />
<RunAndHistory {...runAndHistoryProps} />
<div className='cursor-pointer rounded-lg border-[0.5px] border-components-button-secondary-border bg-components-button-secondary-bg shadow-xs backdrop-blur-[10px]'>
<div className='shrink-0 cursor-pointer rounded-lg border-[0.5px] border-components-button-secondary-border bg-components-button-secondary-bg shadow-xs backdrop-blur-[10px]'>
{components?.chatVariableTrigger}
<EnvButton disabled={nodesReadOnly} />
<GlobalVariableButton disabled={nodesReadOnly} />
</div>
{components?.middle}
<VersionHistoryButton onClick={onStartRestoring} />

View File

@ -8,16 +8,53 @@ import Item from './item'
import { useStore } from '@/app/components/workflow/store'
import cn from '@/utils/classnames'
import { useTranslation } from 'react-i18next'
import { useIsChatMode } from '../../hooks'
import { isInWorkflowPage } from '../../constants'
const Panel = () => {
const { t } = useTranslation()
const isChatMode = useIsChatMode()
const setShowPanel = useStore(s => s.setShowGlobalVariablePanel)
const isWorkflowPage = isInWorkflowPage()
const globalVariableList: GlobalVariable[] = [
{
...(isChatMode ? [{
name: 'conversation_id',
value_type: 'string',
description: 'conversation id',
value_type: 'string' as const,
description: t('workflow.globalVar.fieldsDescription.conversationId'),
},
{
name: 'dialog_count',
value_type: 'number' as const,
description: t('workflow.globalVar.fieldsDescription.dialogCount'),
}] : []),
{
name: 'user_id',
value_type: 'string',
description: t('workflow.globalVar.fieldsDescription.userId'),
},
{
name: 'app_id',
value_type: 'string',
description: t('workflow.globalVar.fieldsDescription.appId'),
},
{
name: 'workflow_id',
value_type: 'string',
description: t('workflow.globalVar.fieldsDescription.workflowId'),
},
{
name: 'workflow_run_id',
value_type: 'string',
description: t('workflow.globalVar.fieldsDescription.workflowRunId'),
},
// is workflow
...(isWorkflowPage ? [{
name: 'trigger_timestamp',
value_type: 'string' as const,
description: t('workflow.globalVar.fieldsDescription.triggerTimestamp'),
}] : []),
]
return (
@ -27,7 +64,7 @@ const Panel = () => {
)}
>
<div className='system-xl-semibold flex shrink-0 items-center justify-between p-4 pb-0 text-text-primary'>
Global Variables(Current not show)
{t('workflow.globalVar.title')}
<div className='flex items-center'>
<div
className='flex h-6 w-6 cursor-pointer items-center justify-center'
@ -37,9 +74,9 @@ const Panel = () => {
</div>
</div>
</div>
<div className='system-sm-regular shrink-0 px-4 py-1 text-text-tertiary'>...</div>
<div className='system-sm-regular shrink-0 px-4 py-1 text-text-tertiary'>{t('workflow.globalVar.description')}</div>
<div className='grow overflow-y-auto rounded-b-2xl px-4'>
<div className='mt-4 grow overflow-y-auto rounded-b-2xl px-4'>
{globalVariableList.map(item => (
<Item
key={item.name}

View File

@ -1,6 +1,7 @@
import { memo } from 'react'
import { capitalize } from 'lodash-es'
import { Env } from '@/app/components/base/icons/src/vender/line/others'
import { GlobalVariable as GlobalVariableIcon } from '@/app/components/base/icons/src/vender/line/others'
import type { GlobalVariable } from '@/app/components/workflow/types'
import cn from '@/utils/classnames'
@ -17,12 +18,15 @@ const Item = ({
)}>
<div className='flex items-center justify-between'>
<div className='flex grow items-center gap-1'>
<Env className='h-4 w-4 text-util-colors-violet-violet-600' />
<div className='system-sm-medium text-text-primary'>{payload.name}</div>
<GlobalVariableIcon className='h-4 w-4 text-util-colors-orange-orange-600' />
<div className='system-sm-medium text-text-primary'>
<span className='text-text-tertiary'>sys.</span>
{payload.name}
</div>
<div className='system-xs-medium text-text-tertiary'>{capitalize(payload.value_type)}</div>
</div>
</div>
<div className='system-xs-regular truncate text-text-tertiary'>{payload.description}</div>
<div className='system-xs-regular mt-1.5 truncate text-text-tertiary'>{payload.description}</div>
</div>
)
}

View File

@ -20,7 +20,12 @@ export const createChatVariableSlice: StateCreator<ChatVariableSliceShape> = (se
return ({
showChatVariablePanel: false,
setShowChatVariablePanel: showChatVariablePanel => set(() => ({ showChatVariablePanel })),
setShowChatVariablePanel: showChatVariablePanel => set(() => {
if (showChatVariablePanel)
return { ...hideAllPanel, showChatVariablePanel: true }
else
return { showChatVariablePanel: false }
}),
showGlobalVariablePanel: false,
setShowGlobalVariablePanel: showGlobalVariablePanel => set(() => {
if (showGlobalVariablePanel)

View File

@ -10,11 +10,24 @@ export type EnvVariableSliceShape = {
setEnvSecrets: (envSecrets: Record<string, string>) => void
}
export const createEnvVariableSlice: StateCreator<EnvVariableSliceShape> = set => ({
showEnvPanel: false,
setShowEnvPanel: showEnvPanel => set(() => ({ showEnvPanel })),
environmentVariables: [],
setEnvironmentVariables: environmentVariables => set(() => ({ environmentVariables })),
envSecrets: {},
setEnvSecrets: envSecrets => set(() => ({ envSecrets })),
})
export const createEnvVariableSlice: StateCreator<EnvVariableSliceShape> = (set) => {
const hideAllPanel = {
showDebugAndPreviewPanel: false,
showEnvPanel: false,
showChatVariablePanel: false,
showGlobalVariablePanel: false,
}
return ({
showEnvPanel: false,
setShowEnvPanel: showEnvPanel => set(() => {
if (showEnvPanel)
return { ...hideAllPanel, showEnvPanel: true }
else
return { showEnvPanel: false }
}),
environmentVariables: [],
setEnvironmentVariables: environmentVariables => set(() => ({ environmentVariables })),
envSecrets: {},
setEnvSecrets: envSecrets => set(() => ({ envSecrets })),
})
}