Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 38 additions & 13 deletions web/app/components/app/configuration/config-var/index.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
'use client'
import type { FC } from 'react'
import React, { useState } from 'react'
import React, { useMemo, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { useBoolean } from 'ahooks'
import { useContext } from 'use-context-selector'
import produce from 'immer'
import { v4 as uuid4 } from 'uuid'
import { ReactSortable } from 'react-sortablejs'
import Panel from '../base/feature-panel'
import EditModal from './config-modal'
import VarItem from './var-item'
Expand All @@ -22,6 +24,7 @@ import { useModalContext } from '@/context/modal-context'
import { useEventEmitterContextContext } from '@/context/event-emitter'
import type { InputVar } from '@/app/components/workflow/types'
import { InputVarType } from '@/app/components/workflow/types'
import cn from '@/utils/classnames'

export const ADD_EXTERNAL_DATA_TOOL = 'ADD_EXTERNAL_DATA_TOOL'

Expand Down Expand Up @@ -218,6 +221,17 @@ const ConfigVar: FC<IConfigVarProps> = ({ promptVariables, readonly, onPromptVar

showEditModal()
}

const promptVariablesWithIds = useMemo(() => promptVariables.map((item) => {
const id = uuid4()
return {
id,
variable: { ...item },
}
}), [promptVariables])

const canDrag = !readonly && promptVariables.length > 1

return (
<Panel
className="mt-2"
Expand Down Expand Up @@ -245,18 +259,29 @@ const ConfigVar: FC<IConfigVarProps> = ({ promptVariables, readonly, onPromptVar
)}
{hasVar && (
<div className='mt-1 px-3 pb-3'>
{promptVariables.map(({ key, name, type, required, config, icon, icon_background }, index) => (
<VarItem
key={index}
readonly={readonly}
name={key}
label={name}
required={!!required}
type={type}
onEdit={() => handleConfig({ type, key, index, name, config, icon, icon_background })}
onRemove={() => handleRemoveVar(index)}
/>
))}
<ReactSortable
className='space-y-1'
list={promptVariablesWithIds}
setList={(list) => { onPromptVariablesChange(list.map(item => item.variable)) }}
handle='.handle'
ghostClass='opacity-50'
animation={150}
>
{promptVariables.map(({ key, name, type, required, config, icon, icon_background }, index) => (
<VarItem
className={cn(canDrag && 'handle')}
key={index}
readonly={readonly}
name={key}
label={name}
required={!!required}
type={type}
onEdit={() => handleConfig({ type, key, index, name, config, icon, icon_background })}
onRemove={() => handleRemoveVar(index)}
canDrag={canDrag}
/>
))}
</ReactSortable>
</div>
)}

Expand Down
12 changes: 10 additions & 2 deletions web/app/components/app/configuration/config-var/var-item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import type { FC } from 'react'
import React, { useState } from 'react'
import {
RiDeleteBinLine,
RiDraggable,
RiEditLine,
} from '@remixicon/react'
import type { IInputTypeIconProps } from './input-type-icon'
Expand All @@ -12,29 +13,36 @@ import Badge from '@/app/components/base/badge'
import cn from '@/utils/classnames'

type ItemProps = {
className?: string
readonly?: boolean
name: string
label: string
required: boolean
type: string
onEdit: () => void
onRemove: () => void
canDrag?: boolean
}

const VarItem: FC<ItemProps> = ({
className,
readonly,
name,
label,
required,
type,
onEdit,
onRemove,
canDrag,
}) => {
const [isDeleting, setIsDeleting] = useState(false)

return (
<div className={cn('group relative mb-1 flex h-[34px] w-full items-center rounded-lg border-[0.5px] border-components-panel-border-subtle bg-components-panel-on-panel-item-bg pl-2.5 pr-3 shadow-xs last-of-type:mb-0 hover:bg-components-panel-on-panel-item-bg-hover hover:shadow-sm', isDeleting && 'border-state-destructive-border hover:bg-state-destructive-hover', readonly && 'cursor-not-allowed opacity-30')}>
<VarIcon className='mr-1 h-4 w-4 shrink-0 text-text-accent' />
<div className={cn('group relative mb-1 flex h-[34px] w-full items-center rounded-lg border-[0.5px] border-components-panel-border-subtle bg-components-panel-on-panel-item-bg pl-2.5 pr-3 shadow-xs last-of-type:mb-0 hover:bg-components-panel-on-panel-item-bg-hover hover:shadow-sm', isDeleting && 'border-state-destructive-border hover:bg-state-destructive-hover', readonly && 'cursor-not-allowed opacity-30', className)}>
<VarIcon className={cn('mr-1 h-4 w-4 shrink-0 text-text-accent', canDrag && 'group-hover:opacity-0')} />
{canDrag && (
<RiDraggable className='absolute left-3 top-3 hidden h-3 w-3 cursor-pointer text-text-tertiary group-hover:block' />
)}
<div className='flex w-0 grow items-center'>
<div className='truncate' title={`${name} · ${label}`}>
<span className='system-sm-medium text-text-secondary'>{name}</span>
Expand Down
43 changes: 19 additions & 24 deletions web/app/components/workflow/nodes/start/components/var-list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@ const VarList: FC<Props> = ({
)
}

const canDrag = !readonly && varCount > 1

return (
<ReactSortable
className='space-y-1'
Expand All @@ -97,30 +99,23 @@ const VarList: FC<Props> = ({
ghostClass='opacity-50'
animation={150}
>
{list.map((item, index) => {
const canDrag = (() => {
if (readonly)
return false
return varCount > 1
})()
return (
<div key={index} className='group relative'>
<VarItem
className={cn(canDrag && 'handle')}
readonly={readonly}
payload={item}
onChange={handleVarChange(index)}
onRemove={handleVarRemove(index)}
varKeys={list.map(item => item.variable)}
canDrag={canDrag}
/>
{canDrag && <RiDraggable className={cn(
'handle absolute left-3 top-2.5 hidden h-3 w-3 cursor-pointer text-text-tertiary',
'group-hover:block',
)} />}
</div>
)
})}
{list.map((item, index) => (
<div key={index} className='group relative'>
<VarItem
className={cn(canDrag && 'handle')}
readonly={readonly}
payload={item}
onChange={handleVarChange(index)}
onRemove={handleVarRemove(index)}
varKeys={list.map(item => item.variable)}
canDrag={canDrag}
/>
{canDrag && <RiDraggable className={cn(
'handle absolute left-3 top-2.5 hidden h-3 w-3 cursor-pointer text-text-tertiary',
'group-hover:block',
)} />}
</div>
))}
</ReactSortable>
)
}
Expand Down
Loading