Feat: dark mode of app configure (#13010)

This commit is contained in:
KVOJJJin 2025-01-24 14:16:35 +08:00 committed by GitHub
parent 899df30bf6
commit c966bf1474
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
55 changed files with 323 additions and 720 deletions

View File

@ -143,22 +143,19 @@ const AppPublisher = ({
</Button>
</PortalToFollowElemTrigger>
<PortalToFollowElemContent className='z-[11]'>
<div className='w-[336px] bg-white rounded-2xl border-[0.5px] border-gray-200 shadow-xl'>
<div className='w-[336px] bg-components-panel-bg rounded-2xl border-[0.5px] border-components-panel-border shadow-xl'>
<div className='p-4 pt-3'>
<div className='flex items-center h-6 text-xs font-medium text-gray-500 uppercase'>
<div className='flex items-center h-6 system-xs-medium-uppercase text-text-tertiary'>
{publishedAt ? t('workflow.common.latestPublished') : t('workflow.common.currentDraftUnpublished')}
</div>
{publishedAt
? (
<div className='flex justify-between items-center h-[18px]'>
<div className='flex items-center mt-[3px] mb-[3px] leading-[18px] text-[13px] font-medium text-gray-700'>
<div className='flex items-center mt-[3px] mb-[3px] leading-[18px] text-[13px] font-medium text-text-secondary'>
{t('workflow.common.publishedAt')} {formatTimeFromNow(publishedAt)}
</div>
<Button
className={`
ml-2 px-2 text-primary-600
${published && 'text-primary-300 border-gray-100'}
`}
variant='secondary-accent'
size='small'
onClick={handleRestore}
disabled={published}
@ -168,7 +165,7 @@ const AppPublisher = ({
</div>
)
: (
<div className='flex items-center h-[18px] leading-[18px] text-[13px] font-medium text-gray-700'>
<div className='flex items-center h-[18px] leading-[18px] text-[13px] font-medium text-text-secondary'>
{t('workflow.common.autoSaved')} · {Boolean(draftUpdatedAt) && formatTimeFromNow(draftUpdatedAt!)}
</div>
)}
@ -196,7 +193,7 @@ const AppPublisher = ({
)
}
</div>
<div className='p-4 pt-3 border-t-[0.5px] border-t-black/5'>
<div className='p-4 pt-3 border-t-[0.5px] border-divider-regular'>
<SuggestedAction disabled={!publishedAt} link={appURL} icon={<PlayCircle />}>{t('workflow.common.runApp')}</SuggestedAction>
{appDetail?.mode === 'workflow'
? (

View File

@ -77,21 +77,21 @@ const PublishWithMultipleModel: FC<PublishWithMultipleModelProps> = ({
</Button>
</PortalToFollowElemTrigger>
<PortalToFollowElemContent className='mt-1 w-[288px] z-50'>
<div className='p-1 rounded-lg border-[0.5px] border-gray-200 shadow-lg bg-white'>
<div className='flex items-center px-3 h-[22px] text-xs font-medium text-gray-500'>
<div className='p-1 rounded-lg border-[0.5px] border-components-panel-border shadow-lg bg-components-panel-bg'>
<div className='flex items-center px-3 h-[22px] text-xs font-medium text-text-tertiary'>
{t('appDebug.publishAs')}
</div>
{
validModelConfigs.map((item, index) => (
<div
key={item.id}
className='flex items-center h-8 px-3 text-sm text-gray-500 rounded-lg cursor-pointer hover:bg-gray-100'
className='flex items-center h-8 px-3 text-sm text-text-tertiary rounded-lg cursor-pointer hover:bg-state-base-hover'
onClick={() => handleSelect(item)}
>
<span className='italic min-w-[18px]'>#{index + 1}</span>
<ModelIcon modelName={item.model} provider={item.providerItem} className='ml-2' />
<div
className='ml-1 text-gray-700 truncate'
className='ml-1 text-text-secondary truncate'
title={item.modelItem.label[language]}
>
{item.modelItem.label[language]}

View File

@ -14,8 +14,8 @@ const SuggestedAction = ({ icon, link, disabled, children, className, ...props }
target='_blank'
rel='noreferrer'
className={classNames(
'flex justify-start items-center gap-2 h-[34px] px-2.5 bg-gray-100 rounded-lg transition-colors [&:not(:first-child)]:mt-1',
disabled ? 'shadow-xs opacity-30 cursor-not-allowed' : 'hover:bg-primary-50 hover:text-primary-600 cursor-pointer',
'flex justify-start items-center gap-2 h-[34px] px-2.5 bg-background-section-burn rounded-lg transition-colors text-text-secondary [&:not(:first-child)]:mt-1',
disabled ? 'shadow-xs opacity-30 cursor-not-allowed' : 'hover:bg-state-accent-hover hover:text-text-accent cursor-pointer',
className,
)}
{...props}

View File

@ -23,7 +23,7 @@ const FeaturePanel: FC<IFeaturePanelProps> = ({
children,
}) => {
return (
<div className={cn('rounded-xl border-t-[0.5px] border-l-[0.5px] bg-background-section-burn pb-3', noBodySpacing && 'pb-0', className)}>
<div className={cn('rounded-xl border-t-[0.5px] border-l-[0.5px] border-effects-highlight bg-background-section-burn pb-3', noBodySpacing && 'pb-0', className)}>
{/* Header */}
<div className={cn('px-3 pt-2', hasHeaderBottomBorder && 'border-b border-divider-subtle')}>
<div className='flex justify-between items-center h-8'>

View File

@ -2,7 +2,10 @@
import type { FC } from 'react'
import React from 'react'
import { useTranslation } from 'react-i18next'
import { PlusIcon } from '@heroicons/react/20/solid'
import {
RiAddLine,
RiEditLine,
} from '@remixicon/react'
import cn from '@/utils/classnames'
export type IOperationBtnProps = {
@ -13,11 +16,8 @@ export type IOperationBtnProps = {
}
const iconMap = {
add: <PlusIcon className='w-3.5 h-3.5' />,
edit: (<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M6.99998 11.6666H12.25M1.75 11.6666H2.72682C3.01217 11.6666 3.15485 11.6666 3.28912 11.6344C3.40816 11.6058 3.52196 11.5587 3.62635 11.4947C3.74408 11.4226 3.84497 11.3217 4.04675 11.1199L11.375 3.79164C11.8583 3.30839 11.8583 2.52488 11.375 2.04164C10.8918 1.55839 10.1083 1.55839 9.62501 2.04164L2.29674 9.3699C2.09496 9.57168 1.99407 9.67257 1.92192 9.7903C1.85795 9.89469 1.81081 10.0085 1.78224 10.1275C1.75 10.2618 1.75 10.4045 1.75 10.6898V11.6666Z" stroke="#344054" strokeWidth="1.25" strokeLinecap="round" strokeLinejoin="round" />
</svg>
),
add: <RiAddLine className='w-3.5 h-3.5' />,
edit: <RiEditLine className='w-3.5 h-3.5' />,
}
const OperationBtn: FC<IOperationBtnProps> = ({
@ -29,7 +29,7 @@ const OperationBtn: FC<IOperationBtnProps> = ({
const { t } = useTranslation()
return (
<div
className={cn(className, 'flex items-center rounded-md h-7 px-3 space-x-1 text-gray-700 cursor-pointer hover:bg-gray-200 select-none')}
className={cn('flex items-center rounded-md h-7 px-3 space-x-1 text-text-secondary cursor-pointer hover:bg-state-base-hover select-none', className)}
onClick={onClick}>
<div>
{iconMap[type]}

View File

@ -28,8 +28,8 @@ const EditModal: FC<Props> = ({
isShow={isShow}
onClose={onClose}
>
<div className={'mt-6 font-medium text-sm leading-[21px] text-gray-900'}>{t('appDebug.feature.conversationHistory.editModal.userPrefix')}</div>
<input className={'mt-2 w-full rounded-lg h-10 box-border px-3 text-sm leading-10 bg-gray-100'}
<div className={'mt-6 font-medium text-sm leading-[21px] text-text-primary'}>{t('appDebug.feature.conversationHistory.editModal.userPrefix')}</div>
<input className={'mt-2 w-full rounded-lg h-10 box-border px-3 text-sm leading-10 bg-components-input-bg-normal'}
value={tempData.user_prefix}
onChange={e => setTempData({
...tempData,
@ -37,8 +37,8 @@ const EditModal: FC<Props> = ({
})}
/>
<div className={'mt-6 font-medium text-sm leading-[21px] text-gray-900'}>{t('appDebug.feature.conversationHistory.editModal.assistantPrefix')}</div>
<input className={'mt-2 w-full rounded-lg h-10 box-border px-3 text-sm leading-10 bg-gray-100'}
<div className={'mt-6 font-medium text-sm leading-[21px] text-text-primary'}>{t('appDebug.feature.conversationHistory.editModal.assistantPrefix')}</div>
<input className={'mt-2 w-full rounded-lg h-10 box-border px-3 text-sm leading-10 bg-components-input-bg-normal'}
value={tempData.assistant_prefix}
onChange={e => setTempData({
...tempData,
@ -48,8 +48,8 @@ const EditModal: FC<Props> = ({
/>
<div className='mt-10 flex justify-end'>
<Button className='mr-2 flex-shrink-0' onClick={onClose}>{t('common.operation.cancel')}</Button>
<Button variant='primary' className='flex-shrink-0' onClick={() => onSave(tempData)} loading={saveLoading}>{t('common.operation.save')}</Button>
<Button className='mr-2 shrink-0' onClick={onClose}>{t('common.operation.cancel')}</Button>
<Button variant='primary' className='shrink-0' onClick={() => onSave(tempData)} loading={saveLoading}>{t('common.operation.save')}</Button>
</div>
</Modal>
)

View File

@ -9,7 +9,7 @@ import { MessageClockCircle } from '@/app/components/base/icons/src/vender/solid
import I18n from '@/context/i18n'
import { LanguagesSupported } from '@/i18n/language'
interface Props {
type Props = {
showWarning: boolean
onShowEditModal: () => void
}
@ -30,20 +30,20 @@ const HistoryPanel: FC<Props> = ({
</div>
}
headerIcon={
<div className='p-1 rounded-md bg-white shadow-xs'>
<div className='p-1 rounded-md shadow-xs'>
<MessageClockCircle className='w-4 h-4 text-[#DD2590]' />
</div>}
headerRight={
<div className='flex items-center'>
<div className='text-xs text-gray-500'>{t('appDebug.feature.conversationHistory.description')}</div>
<div className='ml-3 w-[1px] h-[14px] bg-gray-200'></div>
<div className='text-xs text-text-tertiary'>{t('appDebug.feature.conversationHistory.description')}</div>
<div className='ml-3 w-[1px] h-[14px] bg-divider-regular'></div>
<OperationBtn type="edit" onClick={onShowEditModal} />
</div>
}
noBodySpacing
>
{showWarning && (
<div className='flex justify-between py-2 px-3 rounded-b-xl bg-[#FFFAEB] text-xs text-gray-700'>
<div className='flex justify-between py-2 px-3 rounded-b-xl bg-background-section-burn text-xs text-text-secondary'>
<div>{t('appDebug.feature.conversationHistory.tip')}
<a href={`${locale === LanguagesSupported[1]
? 'https://docs.dify.ai/v/zh-hans/guides/application-design/prompt-engineering'

View File

@ -23,7 +23,7 @@ import { DEFAULT_VALUE_MAX_LEN } from '@/config'
const TEXT_MAX_LENGTH = 256
export interface IConfigModalProps {
export type IConfigModalProps = {
isCreate?: boolean
payload?: InputVar
isShow: boolean

View File

@ -5,23 +5,15 @@ import { useTranslation } from 'react-i18next'
import { useBoolean } from 'ahooks'
import { useContext } from 'use-context-selector'
import produce from 'immer'
import {
RiDeleteBinLine,
} from '@remixicon/react'
import Panel from '../base/feature-panel'
import EditModal from './config-modal'
import IconTypeIcon from './input-type-icon'
import type { IInputTypeIconProps } from './input-type-icon'
import s from './style.module.css'
import VarItem from './var-item'
import SelectVarType from './select-var-type'
import { BracketsX as VarIcon } from '@/app/components/base/icons/src/vender/line/development'
import Tooltip from '@/app/components/base/tooltip'
import type { PromptVariable } from '@/models/debug'
import { DEFAULT_VALUE_MAX_LEN, getMaxVarNameLength } from '@/config'
import { checkKeys, getNewVar } from '@/utils/var'
import Switch from '@/app/components/base/switch'
import { DEFAULT_VALUE_MAX_LEN } from '@/config'
import { getNewVar } from '@/utils/var'
import Toast from '@/app/components/base/toast'
import { Settings01 } from '@/app/components/base/icons/src/vender/line/general'
import Confirm from '@/app/components/base/confirm'
import ConfigContext from '@/context/debug-configuration'
import { AppType } from '@/types/app'
@ -33,7 +25,7 @@ import { InputVarType } from '@/app/components/workflow/types'
export const ADD_EXTERNAL_DATA_TOOL = 'ADD_EXTERNAL_DATA_TOOL'
interface ExternalDataToolParams {
type ExternalDataToolParams = {
key: string
type: string
index: number
@ -43,14 +35,12 @@ interface ExternalDataToolParams {
icon_background?: string
}
export interface IConfigVarProps {
export type IConfigVarProps = {
promptVariables: PromptVariable[]
readonly?: boolean
onPromptVariablesChange?: (promptVariables: PromptVariable[]) => void
}
let conflictTimer: number
const ConfigVar: FC<IConfigVarProps> = ({ promptVariables, readonly, onPromptVariablesChange }) => {
const { t } = useTranslation()
const {
@ -60,19 +50,6 @@ const ConfigVar: FC<IConfigVarProps> = ({ promptVariables, readonly, onPromptVar
const { eventEmitter } = useEventEmitterContextContext()
const hasVar = promptVariables.length > 0
const updatePromptVariable = (key: string, updateKey: string, newValue: string | boolean) => {
const newPromptVariables = promptVariables.map((item) => {
if (item.key === key) {
return {
...item,
[updateKey]: newValue,
}
}
return item
})
onPromptVariablesChange?.(newPromptVariables)
}
const [currIndex, setCurrIndex] = useState<number>(-1)
const currItem = currIndex !== -1 ? promptVariables[currIndex] : null
const currItemToEdit: InputVar | null = (() => {
@ -105,55 +82,6 @@ const ConfigVar: FC<IConfigVarProps> = ({ promptVariables, readonly, onPromptVar
onPromptVariablesChange?.(newPromptVariables)
}
const updatePromptKey = (index: number, newKey: string) => {
window.clearTimeout(conflictTimer)
const { isValid, errorKey, errorMessageKey } = checkKeys([newKey], true)
if (!isValid) {
Toast.notify({
type: 'error',
message: t(`appDebug.varKeyError.${errorMessageKey}`, { key: errorKey }),
})
return
}
const newPromptVariables = promptVariables.map((item, i) => {
if (i === index) {
return {
...item,
key: newKey,
}
}
return item
})
conflictTimer = window.setTimeout(() => {
const isKeyExists = promptVariables.some(item => item.key?.trim() === newKey.trim())
if (isKeyExists) {
Toast.notify({
type: 'error',
message: t('appDebug.varKeyError.keyAlreadyExists', { key: newKey }),
})
}
}, 1000)
onPromptVariablesChange?.(newPromptVariables)
}
const updatePromptNameIfNameEmpty = (index: number, newKey: string) => {
if (!newKey)
return
const newPromptVariables = promptVariables.map((item, i) => {
if (i === index && !item.name) {
return {
...item,
name: newKey,
}
}
return item
})
onPromptVariablesChange?.(newPromptVariables)
}
const { setShowExternalDataToolModal } = useModalContext()
@ -272,9 +200,6 @@ const ConfigVar: FC<IConfigVarProps> = ({ promptVariables, readonly, onPromptVar
return (
<Panel
className="mt-2"
headerIcon={
<VarIcon className='w-4 h-4 text-primary-500' />
}
title={
<div className='flex items-center'>
<div className='mr-1'>{t('appDebug.variableTitle')}</div>
@ -290,87 +215,27 @@ const ConfigVar: FC<IConfigVarProps> = ({ promptVariables, readonly, onPromptVar
</div>
}
headerRight={!readonly ? <SelectVarType onChange={handleAddVar} /> : null}
noBodySpacing
>
{!hasVar && (
<div className='pt-2 pb-1 text-xs text-gray-500'>{t('appDebug.notSetVar')}</div>
<div className='mt-1 px-3 pb-3'>
<div className='pt-2 pb-1 text-xs text-text-tertiary'>{t('appDebug.notSetVar')}</div>
</div>
)}
{hasVar && (
<div className='rounded-lg border border-gray-200 bg-white overflow-x-auto'>
<table className={`${s.table} min-w-[440px] w-full max-w-full border-collapse border-0 rounded-lg text-sm`}>
<thead className="border-b border-gray-200 text-gray-500 text-xs font-medium">
<tr className='uppercase'>
<td>{t('appDebug.variableTable.key')}</td>
<td>{t('appDebug.variableTable.name')}</td>
{!readonly && (
<>
<td>{t('appDebug.variableTable.optional')}</td>
<td>{t('appDebug.variableTable.action')}</td>
</>
)}
</tr>
</thead>
<tbody className="text-gray-700">
{promptVariables.map(({ key, name, type, required, config, icon, icon_background }, index) => (
<tr key={index} className="h-9 leading-9">
<td className="w-[160px] border-b border-gray-100 pl-3">
<div className='flex items-center space-x-1'>
<IconTypeIcon type={type as IInputTypeIconProps['type']} className='text-gray-400' />
{!readonly
? (
<input
type="text"
placeholder="key"
value={key}
onChange={e => updatePromptKey(index, e.target.value)}
onBlur={e => updatePromptNameIfNameEmpty(index, e.target.value)}
maxLength={getMaxVarNameLength(name)}
className="h-6 leading-6 block w-full rounded-md border-0 py-1.5 text-gray-900 placeholder:text-gray-400 focus:outline-none focus:ring-1 focus:ring-inset focus:ring-gray-200"
/>
)
: (
<div className='h-6 leading-6 text-[13px] text-gray-700'>{key}</div>
)}
</div>
</td>
<td className="py-1 border-b border-gray-100">
{!readonly
? (
<input
type="text"
placeholder={key}
value={name}
onChange={e => updatePromptVariable(key, 'name', e.target.value)}
maxLength={getMaxVarNameLength(name)}
className="h-6 leading-6 block w-full rounded-md border-0 py-1.5 text-gray-900 placeholder:text-gray-400 focus:outline-none focus:ring-1 focus:ring-inset focus:ring-gray-200"
/>)
: (
<div className='h-6 leading-6 text-[13px] text-gray-700'>{name}</div>
)}
</td>
{!readonly && (
<>
<td className='w-[84px] border-b border-gray-100'>
<div className='flex items-center h-full'>
<Switch defaultValue={!required} size='md' onChange={value => updatePromptVariable(key, 'required', !value)} />
</div>
</td>
<td className='w-20 border-b border-gray-100'>
<div className='flex h-full items-center space-x-1'>
<div className=' p-1 rounded-md hover:bg-black/5 w-6 h-6 cursor-pointer' onClick={() => handleConfig({ type, key, index, name, config, icon, icon_background })}>
<Settings01 className='w-4 h-4 text-gray-500' />
</div>
<div className=' p-1 rounded-md hover:bg-black/5 w-6 h-6 cursor-pointer' onClick={() => handleRemoveVar(index)} >
<RiDeleteBinLine className='w-4 h-4 text-gray-500' />
</div>
</div>
</td>
</>
)}
</tr>
))}
</tbody>
</table>
<div className='flex flex-wrap mt-1 px-3 pb-3 justify-between'>
{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)}
/>
))}
</div>
)}

View File

@ -5,7 +5,7 @@ import { useTranslation } from 'react-i18next'
import cn from '@/utils/classnames'
import type { InputVarType } from '@/app/components/workflow/types'
import InputVarTypeIcon from '@/app/components/workflow/nodes/_base/components/input-var-type-icon'
export interface ISelectTypeItemProps {
export type ISelectTypeItemProps = {
type: InputVarType
selected: boolean
onClick: () => void
@ -27,7 +27,7 @@ const SelectTypeItem: FC<ISelectTypeItemProps> = ({
return (
<div
className={cn(
'flex flex-col justify-center items-center h-[58px] rounded-lg border border-components-option-card-option-border bg-components-option-card-option-bg space-y-1',
'flex flex-col justify-center items-center h-[58px] rounded-lg border border-components-option-card-option-border bg-components-option-card-option-bg space-y-1 text-text-secondary',
selected ? 'border-[1.5px] border-components-option-card-option-selected-border bg-components-option-card-option-selected-bg shadow-xs system-xs-medium' : ' hover:border-components-option-card-option-border-hover hover:bg-components-option-card-option-bg-hover hover:shadow-xs cursor-pointer system-xs-regular')}
onClick={onClick}
>

View File

@ -1,12 +0,0 @@
.table td {
padding-left: 12px;
}
.table thead td {
height: 33px;
line-height: 33px;
}
.table tbody tr:last-child td {
border-bottom: none;
}

View File

@ -0,0 +1,74 @@
'use client'
import type { FC } from 'react'
import React, { useState } from 'react'
import {
RiDeleteBinLine,
RiEditLine,
} from '@remixicon/react'
import type { IInputTypeIconProps } from './input-type-icon'
import IconTypeIcon from './input-type-icon'
import { BracketsX as VarIcon } from '@/app/components/base/icons/src/vender/line/development'
import Badge from '@/app/components/base/badge'
import cn from '@/utils/classnames'
type ItemProps = {
readonly?: boolean
name: string
label: string
required: boolean
type: string
onEdit: () => void
onRemove: () => void
}
const VarItem: FC<ItemProps> = ({
readonly,
name,
label,
required,
type,
onEdit,
onRemove,
}) => {
const [isDeleting, setIsDeleting] = useState(false)
return (
<div className={cn('group relative flex items-center mb-1 last-of-type:mb-0 pl-2.5 py-2 pr-3 w-full rounded-lg bg-components-panel-on-panel-item-bg border-components-panel-border-subtle border-[0.5px] shadow-xs hover:shadow-sm hover:bg-components-panel-on-panel-item-bg-hover', isDeleting && 'hover:bg-state-destructive-hover border-state-destructive-border', readonly && 'cursor-not-allowed opacity-30')}>
<VarIcon className='shrink-0 mr-1 w-4 h-4 text-text-accent' />
<div className='grow'>
<div className='flex items-center h-[18px]'>
<div className='grow truncate' title={name}>
<span className='system-sm-medium text-text-secondary'>{name}</span>
<span className='px-1 system-xs-regular text-text-quaternary'>·</span>
<span className='system-xs-medium text-text-tertiary'>{label}</span>
</div>
<div className='group-hover:hidden flex items-center'>
{required && <Badge text='required' />}
<span className='pl-2 pr-1 system-xs-regular text-text-tertiary'>{type}</span>
<IconTypeIcon type={type as IInputTypeIconProps['type']} className='text-text-tertiary' />
</div>
</div>
</div>
{!readonly && (
<div className='hidden rounded-lg group-hover:flex items-center justify-end absolute right-0 top-0 bottom-0 pr-2 w-[124px]'>
<div
className='flex items-center justify-center mr-1 w-6 h-6 hover:bg-black/5 rounded-md cursor-pointer'
onClick={onEdit}
>
<RiEditLine className='w-4 h-4 text-text-tertiary' />
</div>
<div
className='flex items-center justify-center w-6 h-6 text-text-tertiary cursor-pointer hover:text-text-destructive'
onClick={onRemove}
onMouseOver={() => setIsDeleting(true)}
onMouseLeave={() => setIsDeleting(false)}
>
<RiDeleteBinLine className='w-4 h-4' />
</div>
</div>
)}
</div>
)
}
export default VarItem

View File

@ -57,7 +57,7 @@ const ConfigVision: FC = () => {
return null
return (
<div className='mt-2 flex items-center gap-2 p-2 rounded-xl border-t-[0.5px] border-l-[0.5px] bg-background-section-burn'>
<div className='mt-2 flex items-center gap-2 p-2 rounded-xl border-effects-highlight border-t-[0.5px] border-l-[0.5px] bg-background-section-burn'>
<div className='shrink-0 p-1'>
<div className='p-1 rounded-lg border-[0.5px] border-divider-subtle shadow-xs bg-util-colors-indigo-indigo-600'>
<Vision className='w-4 h-4 text-text-primary-on-surface' />
@ -99,7 +99,7 @@ const ConfigVision: FC = () => {
/>
</div> */}
<ParamConfig />
<div className='ml-1 mr-3 w-[1px] h-3.5 bg-divider-subtle'></div>
<div className='ml-1 mr-3 w-[1px] h-3.5 bg-divider-regular'></div>
<Switch
defaultValue={isImageEnabled}
onChange={handleChange}

View File

@ -41,11 +41,11 @@ const ParamConfigContent: FC = () => {
return (
<div>
<div className='leading-6 text-base font-semibold text-gray-800'>{t('appDebug.vision.visionSettings.title')}</div>
<div className='leading-6 text-base font-semibold text-text-primary'>{t('appDebug.vision.visionSettings.title')}</div>
<div className='pt-3 space-y-6'>
<div>
<div className='mb-2 flex items-center space-x-1'>
<div className='leading-[18px] text-[13px] font-semibold text-gray-800'>{t('appDebug.vision.visionSettings.resolution')}</div>
<div className='leading-[18px] text-[13px] font-semibold text-text-secondary'>{t('appDebug.vision.visionSettings.resolution')}</div>
<Tooltip
popupContent={
<div className='w-[180px]' >
@ -78,7 +78,7 @@ const ParamConfigContent: FC = () => {
</div>
</div>
<div>
<div className='mb-2 leading-[18px] text-[13px] font-semibold text-gray-800'>{t('appDebug.vision.visionSettings.uploadMethod')}</div>
<div className='mb-2 leading-[18px] text-[13px] font-semibold text-text-secondary'>{t('appDebug.vision.visionSettings.uploadMethod')}</div>
<div className='flex items-center gap-1'>
<OptionCard
className='grow'

View File

@ -2,14 +2,15 @@
import type { FC } from 'react'
import { memo, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { RiSettings2Line } from '@remixicon/react'
import ParamConfigContent from './param-config-content'
import cn from '@/utils/classnames'
import { Settings01 } from '@/app/components/base/icons/src/vender/line/general'
import Button from '@/app/components/base/button'
import {
PortalToFollowElem,
PortalToFollowElemContent,
PortalToFollowElemTrigger,
} from '@/app/components/base/portal-to-follow-elem'
import cn from '@/utils/classnames'
const ParamsConfig: FC = () => {
const { t } = useTranslation()
@ -25,13 +26,13 @@ const ParamsConfig: FC = () => {
}}
>
<PortalToFollowElemTrigger onClick={() => setOpen(v => !v)}>
<div className={cn('flex items-center rounded-md h-7 px-3 space-x-1 text-text-tertiary cursor-pointer hover:bg-gray-200', open && 'bg-gray-200')}>
<Settings01 className='w-3.5 h-3.5 ' />
<div className='ml-1 leading-[18px] text-xs font-medium '>{t('appDebug.voice.settings')}</div>
</div>
<Button variant='ghost' size='small' className={cn('')}>
<RiSettings2Line className='w-3.5 h-3.5' />
<div className='ml-1'>{t('appDebug.voice.settings')}</div>
</Button>
</PortalToFollowElemTrigger>
<PortalToFollowElemContent style={{ zIndex: 50 }}>
<div className='w-80 sm:w-[412px] p-4 bg-white rounded-lg border-[0.5px] border-gray-200 shadow-lg space-y-3'>
<div className='w-80 sm:w-[412px] p-4 bg-components-panel-bg rounded-lg border-[0.5px] border-components-panel-border shadow-lg space-y-3'>
<ParamConfigContent />
</div>
</PortalToFollowElemContent>

View File

@ -2,9 +2,9 @@
import type { FC } from 'react'
import React, { useState } from 'react'
import { useTranslation } from 'react-i18next'
import { RiSettings2Line } from '@remixicon/react'
import AgentSetting from './agent/agent-setting'
import Button from '@/app/components/base/button'
import { Settings01 } from '@/app/components/base/icons/src/vender/line/general'
import type { AgentConfig } from '@/models/debug'
type Props = {
@ -26,7 +26,7 @@ const AgentSettingButton: FC<Props> = ({
return (
<>
<Button onClick={() => setIsShowAgentSetting(true)} className='shrink-0 mr-2'>
<Settings01 className='mr-1 w-4 h-4 text-gray-500' />
<RiSettings2Line className='mr-1 w-4 h-4 text-text-tertiary' />
{t('appDebug.agent.setting.name')}
</Button>
{isShowAgentSetting && (

View File

@ -42,10 +42,10 @@ const AgentSetting: FC<Props> = ({
}}
>
<div
className='w-[640px] flex flex-col h-full overflow-hidden bg-white border-[0.5px] border-gray-200 rounded-xl shadow-xl'
className='w-[640px] flex flex-col h-full overflow-hidden bg-components-panel-bg border-[0.5px] border-components-panel-border rounded-xl shadow-xl'
>
<div className='shrink-0 flex justify-between items-center pl-6 pr-5 h-14 border-b border-b-gray-100'>
<div className='flex flex-col text-base font-semibold text-gray-900'>
<div className='shrink-0 flex justify-between items-center pl-6 pr-5 h-14 border-b border-divider-regular'>
<div className='flex flex-col text-base font-semibold text-text-primary'>
<div className='leading-6'>{t('appDebug.agent.setting.name')}</div>
</div>
<div className='flex items-center'>
@ -53,7 +53,7 @@ const AgentSetting: FC<Props> = ({
onClick={onCancel}
className='flex justify-center items-center w-6 h-6 cursor-pointer'
>
<RiCloseLine className='w-4 h-4 text-gray-500' />
<RiCloseLine className='w-4 h-4 text-text-tertiary' />
</div>
</div>
</div>
@ -70,7 +70,7 @@ const AgentSetting: FC<Props> = ({
name={t('appDebug.agent.agentMode')}
description={t('appDebug.agent.agentModeDes')}
>
<div className='leading-[18px] text-[13px] font-medium text-gray-900'>{isFunctionCall ? t('appDebug.agent.agentModeType.functionCall') : t('appDebug.agent.agentModeType.ReACT')}</div>
<div className='leading-[18px] text-[13px] font-medium text-text-primary'>{isFunctionCall ? t('appDebug.agent.agentModeType.functionCall') : t('appDebug.agent.agentModeType.ReACT')}</div>
</ItemPanel>
<ItemPanel
@ -99,10 +99,10 @@ const AgentSetting: FC<Props> = ({
type="number"
min={maxIterationsMin}
max={maxIterationsMax} step={1}
className="block w-11 h-7 leading-7 rounded-lg border-0 pl-1 px-1.5 bg-gray-100 text-gray-900 placeholder:text-gray-400 focus:ring-1 focus:ring-inset focus:ring-primary-600"
className="block w-11 h-7 leading-7 rounded-lg border-0 pl-1 px-1.5 bg-components-input-bg-normal text-text-primary placeholder:text-text-tertiary focus:ring-1 focus:ring-inset focus:ring-primary-600"
value={tempPayload.max_iteration}
onChange={(e) => {
let value = parseInt(e.target.value, 10)
let value = Number.parseInt(e.target.value, 10)
if (value < maxIterationsMin)
value = maxIterationsMin
@ -117,23 +117,20 @@ const AgentSetting: FC<Props> = ({
</ItemPanel>
{!isFunctionCall && (
<div className='py-2 bg-gray-50 rounded-xl shadow-xs'>
<div className='flex items-center h-8 px-4 leading-6 text-sm font-semibold text-gray-700'>{t('tools.builtInPromptTitle')}</div>
<div className='h-[396px] px-4 overflow-y-auto leading-5 text-sm font-normal text-gray-700 whitespace-pre-line'>
<div className='py-2 bg-background-section-burn rounded-xl shadow-xs'>
<div className='flex items-center h-8 px-4 leading-6 text-sm font-semibold text-text-secondary'>{t('tools.builtInPromptTitle')}</div>
<div className='h-[396px] px-4 overflow-y-auto leading-5 text-sm font-normal text-text-secondary whitespace-pre-line'>
{isChatModel ? DEFAULT_AGENT_PROMPT.chat : DEFAULT_AGENT_PROMPT.completion}
</div>
<div className='px-4'>
<div className='inline-flex items-center h-5 px-1 rounded-md bg-gray-100 leading-[18px] text-xs font-medium text-gray-500'>{(isChatModel ? DEFAULT_AGENT_PROMPT.chat : DEFAULT_AGENT_PROMPT.completion).length}</div>
<div className='inline-flex items-center h-5 px-1 bg-components-input-bg-normal rounded-md leading-[18px] text-xs font-medium text-text-tertiary'>{(isChatModel ? DEFAULT_AGENT_PROMPT.chat : DEFAULT_AGENT_PROMPT.completion).length}</div>
</div>
</div>
)}
</div>
<div
className='sticky z-[5] bottom-0 w-full flex justify-end py-4 px-6 border-t bg-white '
style={{
borderColor: 'rgba(0, 0, 0, 0.05)',
}}
className='sticky z-[5] bottom-0 w-full flex justify-end py-4 px-6 border-t bg-background-section-burn border-divider-regular'
>
<Button
onClick={onCancel}

View File

@ -19,10 +19,10 @@ const ItemPanel: FC<Props> = ({
children,
}) => {
return (
<div className={cn(className, 'flex justify-between items-center h-12 px-3 rounded-lg bg-gray-50')}>
<div className={cn(className, 'flex justify-between items-center h-12 px-3 rounded-lg bg-background-section-burn')}>
<div className='flex items-center'>
{icon}
<div className='ml-3 mr-1 leading-6 text-sm font-semibold text-gray-800'>{name}</div>
<div className='ml-3 mr-1 leading-6 text-sm font-semibold text-text-secondary'>{name}</div>
<Tooltip
popupContent={
<div className='w-[180px]'>

View File

@ -8,7 +8,6 @@ import produce from 'immer'
import {
RiDeleteBinLine,
RiEqualizer2Line,
RiHammerFill,
RiInformation2Line,
} from '@remixicon/react'
import { useFormattingChangedDispatcher } from '../../../debug/hooks'
@ -108,9 +107,6 @@ const AgentTools: FC = () => {
<Panel
className={cn('mt-2', tools.length === 0 && 'pb-2')}
noBodySpacing={tools.length === 0}
headerIcon={
<RiHammerFill className='w-4 h-4 text-primary-500' />
}
title={
<div className='flex items-center'>
<div className='mr-1'>{t('appDebug.agent.tools.name')}</div>
@ -125,10 +121,10 @@ const AgentTools: FC = () => {
}
headerRight={
<div className='flex items-center'>
<div className='leading-[18px] text-xs font-normal text-gray-500'>{tools.filter((item: any) => !!item.enabled).length}/{tools.length}&nbsp;{t('appDebug.agent.tools.enabled')}</div>
<div className='leading-[18px] text-xs font-normal text-text-tertiary'>{tools.filter((item: any) => !!item.enabled).length}/{tools.length}&nbsp;{t('appDebug.agent.tools.enabled')}</div>
{tools.length < MAX_TOOLS_NUM && (
<>
<div className='ml-3 mr-1 h-3.5 w-px bg-gray-200'></div>
<div className='ml-3 mr-1 h-3.5 w-px bg-divider-regular'></div>
<ToolPicker
trigger={<OperationBtn type="add" />}
isShow={isShowChooseTool}

View File

@ -16,6 +16,7 @@ import Drawer from '@/app/components/base/drawer'
import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints'
import Badge from '@/app/components/base/badge'
import { useKnowledge } from '@/hooks/use-knowledge'
import cn from '@/utils/classnames'
type ItemProps = {
className?: string
@ -41,8 +42,10 @@ const Item: FC<ItemProps> = ({
setShowSettingsModal(false)
}
const [isDeleting, setIsDeleting] = useState(false)
return (
<div className='group relative flex items-center mb-1 last-of-type:mb-0 pl-2.5 py-2 pr-3 w-full bg-white rounded-lg border-[0.5px] border-gray-200 shadow-xs'>
<div className={cn('group relative flex items-center mb-1 last-of-type:mb-0 pl-2.5 py-2 pr-3 w-full rounded-lg bg-components-panel-on-panel-item-bg border-components-panel-border-subtle border-[0.5px] shadow-xs hover:shadow-sm hover:bg-components-panel-on-panel-item-bg-hover', isDeleting && 'hover:bg-state-destructive-hover border-state-destructive-border')}>
{
config.data_source_type === DataSourceType.FILE && (
<div className='shrink-0 flex items-center justify-center mr-2 w-6 h-6 bg-[#F5F8FF] rounded-md border-[0.5px] border-[#E0EAFF]'>
@ -66,26 +69,30 @@ const Item: FC<ItemProps> = ({
}
<div className='grow'>
<div className='flex items-center h-[18px]'>
<div className='grow text-[13px] font-medium text-gray-800 truncate' title={config.name}>{config.name}</div>
{config.provider === 'external'
? <Badge text={t('dataset.externalTag')}></Badge>
: <Badge
text={formatIndexingTechniqueAndMethod(config.indexing_technique, config.retrieval_model_dict?.search_method)}
/>}
<div className='grow text-[13px] font-medium text-text-secondary truncate' title={config.name}>{config.name}</div>
<div className='group-hover:hidden flex items-center'>
{config.provider === 'external'
? <Badge text={t('dataset.externalTag')}></Badge>
: <Badge
text={formatIndexingTechniqueAndMethod(config.indexing_technique, config.retrieval_model_dict?.search_method)}
/>}
</div>
</div>
</div>
<div className='hidden rounded-lg group-hover:flex items-center justify-end absolute right-0 top-0 bottom-0 pr-2 w-[124px] bg-gradient-to-r from-white/50 to-white to-50%'>
<div className='hidden rounded-lg group-hover:flex items-center justify-end absolute right-0 top-0 bottom-0 pr-2 w-[124px]'>
<div
className='flex items-center justify-center mr-1 w-6 h-6 hover:bg-black/5 rounded-md cursor-pointer'
onClick={() => setShowSettingsModal(true)}
>
<RiEditLine className='w-4 h-4 text-gray-500' />
<RiEditLine className='w-4 h-4 text-text-tertiary' />
</div>
<div
className='group/action flex items-center justify-center w-6 h-6 hover:bg-[#FEE4E2] rounded-md cursor-pointer'
className='flex items-center justify-center w-6 h-6 text-text-tertiary cursor-pointer hover:text-text-destructive'
onClick={() => onRemove(config.id)}
onMouseOver={() => setIsDeleting(true)}
onMouseLeave={() => setIsDeleting(false)}
>
<RiDeleteBinLine className='w-4 h-4 text-gray-500 group-hover/action:text-[#D92D20]' />
<RiDeleteBinLine className='w-4 h-4' />
</div>
</div>
<Drawer isOpen={showSettingsModal} onClose={() => setShowSettingsModal(false)} footer={null} mask={isMobile} panelClassname='mt-16 mx-2 sm:mr-2 mb-3 !p-0 !max-w-[640px] rounded-xl'>

View File

@ -14,12 +14,12 @@ const ContextVar: FC<Props> = (props) => {
const currItem = options.find(item => item.value === value)
const notSetVar = !currItem
return (
<div className={cn(notSetVar ? 'rounded-bl-xl rounded-br-xl bg-[#FEF0C7] border-[#FEF0C7]' : 'border-gray-200', 'flex justify-between items-center h-12 px-3 border-t ')}>
<div className={cn(notSetVar ? 'rounded-bl-xl rounded-br-xl bg-[#FEF0C7] border-[#FEF0C7]' : 'border-components-panel-border-subtle', 'flex justify-between items-center h-12 px-3 border-t ')}>
<div className='flex items-center space-x-1 shrink-0'>
<div className='p-1'>
<BracketsX className='w-4 h-4 text-primary-500' />
<BracketsX className='w-4 h-4 text-text-accent' />
</div>
<div className='mr-1 text-sm font-medium text-gray-800'>{t('appDebug.feature.dataSet.queryVariable.title')}</div>
<div className='mr-1 text-sm font-medium text-text-secondary'>{t('appDebug.feature.dataSet.queryVariable.title')}</div>
<Tooltip
popupContent={
<div className='w-[180px]'>

View File

@ -1,3 +0,0 @@
.trigger:hover .dropdownIcon {
color: #98A2B3;
}

View File

@ -3,7 +3,6 @@ import type { FC } from 'react'
import React, { useState } from 'react'
import { useTranslation } from 'react-i18next'
import { ChevronDownIcon } from '@heroicons/react/24/outline'
import s from './style.module.css'
import cn from '@/utils/classnames'
import {
PortalToFollowElem,
@ -56,10 +55,9 @@ const VarPicker: FC<Props> = ({
>
<PortalToFollowElemTrigger className={cn(triggerClassName)} onClick={() => setOpen(v => !v)}>
<div className={cn(
s.trigger,
className,
notSetVar ? 'bg-[#FFFCF5] border-[#FEDF89] text-[#DC6803]' : ' hover:bg-gray-50 border-gray-200 text-primary-600',
open ? 'bg-gray-50' : 'bg-white',
notSetVar ? 'bg-[#FFFCF5] border-[#FEDF89] text-[#DC6803]' : ' hover:bg-components-button-secondary-bg border-components-button-secondary-border text-text-accent',
open ? 'bg-components-button-secondary-bg' : 'bg-transparent',
`
flex items-center h-8 justify-center px-2 space-x-1 rounded-lg border shadow-xs cursor-pointer
text-[13px] font-medium
@ -73,16 +71,16 @@ const VarPicker: FC<Props> = ({
{notSelectedVarTip || t('appDebug.feature.dataSet.queryVariable.choosePlaceholder')}
</div>)}
</div>
<ChevronDownIcon className={cn(s.dropdownIcon, open && 'rotate-180 text-[#98A2B3]', 'w-3.5 h-3.5')} />
<ChevronDownIcon className={cn(open && 'rotate-180 text-text-tertiary', 'w-3.5 h-3.5')} />
</div>
</PortalToFollowElemTrigger>
<PortalToFollowElemContent style={{ zIndex: 1000 }}>
{options.length > 0
? (<div className='w-[240px] max-h-[50vh] overflow-y-auto p-1 border bg-white border-gray-200 rounded-lg shadow-lg'>
? (<div className='w-[240px] max-h-[50vh] overflow-y-auto p-1 border bg-components-panel-bg border-components-panel-border rounded-lg shadow-lg'>
{options.map(({ name, value, type }, index) => (
<div
key={index}
className='px-3 py-1 flex rounded-lg hover:bg-gray-50 cursor-pointer'
className='px-3 py-1 flex rounded-lg hover:bg-state-base-hover cursor-pointer'
onClick={() => {
onChange(value)
setOpen(false)
@ -93,9 +91,9 @@ const VarPicker: FC<Props> = ({
))}
</div>)
: (
<div className='w-[240px] p-6 bg-white border border-gray-200 rounded-lg shadow-lg'>
<div className='mb-1 text-sm font-medium text-gray-700'>{t('appDebug.feature.dataSet.queryVariable.noVar')}</div>
<div className='text-xs leading-normal text-gray-500'>{t('appDebug.feature.dataSet.queryVariable.noVarTip')}</div>
<div className='w-[240px] p-6 bg-components-panel-bg border border-components-panel-border rounded-lg shadow-lg'>
<div className='mb-1 text-sm font-medium text-text-secondary'>{t('appDebug.feature.dataSet.queryVariable.noVar')}</div>
<div className='text-xs leading-normal text-text-tertiary'>{t('appDebug.feature.dataSet.queryVariable.noVarTip')}</div>
</div>
)}

View File

@ -20,13 +20,6 @@ import {
import { useModelListAndDefaultModelAndCurrentProviderAndModel } from '@/app/components/header/account-setting/model-provider-page/hooks'
import { ModelTypeEnum } from '@/app/components/header/account-setting/model-provider-page/declarations'
const Icon = (
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fillRule="evenodd" clipRule="evenodd" d="M12.6667 5.34368C12.6667 5.32614 12.6667 5.31738 12.6659 5.30147C12.6502 4.97229 12.3607 4.68295 12.0315 4.66737C12.0156 4.66662 12.0104 4.66662 12 4.66663H9.8391C9.30248 4.66662 8.85957 4.66661 8.49878 4.69609C8.12405 4.72671 7.77958 4.79242 7.45603 4.95728C6.95426 5.21294 6.54631 5.62089 6.29065 6.12265C6.12579 6.44621 6.06008 6.79068 6.02946 7.16541C5.99999 7.5262 5.99999 7.96911 6 8.50574V15.4942C5.99999 16.0308 5.99999 16.4737 6.02946 16.8345C6.06008 17.2092 6.12579 17.5537 6.29065 17.8773C6.54631 18.379 6.95426 18.787 7.45603 19.0426C7.77958 19.2075 8.12405 19.2732 8.49878 19.3038C8.85958 19.3333 9.30248 19.3333 9.83912 19.3333H14.1609C14.6975 19.3333 15.1404 19.3333 15.5012 19.3038C15.8759 19.2732 16.2204 19.2075 16.544 19.0426C17.0457 18.787 17.4537 18.379 17.7093 17.8773C17.8742 17.5537 17.9399 17.2092 17.9705 16.8345C18 16.4737 18 16.0308 18 15.4942V10.6666C18 10.6562 18 10.6511 17.9993 10.6352C17.9837 10.306 17.6943 10.0164 17.3651 10.0007C17.3492 9.99997 17.3405 9.99997 17.323 9.99997L14.3787 9.99997C14.2105 9.99999 14.0466 10 13.9078 9.98867C13.7555 9.97622 13.5756 9.94684 13.3947 9.85464C13.1438 9.72681 12.9398 9.52284 12.812 9.27195C12.7198 9.09101 12.6904 8.91118 12.678 8.75879C12.6666 8.62001 12.6666 8.45615 12.6667 8.2879L12.6667 5.34368ZM9.33333 12.6666C8.96514 12.6666 8.66667 12.9651 8.66667 13.3333C8.66667 13.7015 8.96514 14 9.33333 14H14.6667C15.0349 14 15.3333 13.7015 15.3333 13.3333C15.3333 12.9651 15.0349 12.6666 14.6667 12.6666H9.33333ZM9.33333 15.3333C8.96514 15.3333 8.66667 15.6318 8.66667 16C8.66667 16.3681 8.96514 16.6666 9.33333 16.6666H13.3333C13.7015 16.6666 14 16.3681 14 16C14 15.6318 13.7015 15.3333 13.3333 15.3333H9.33333Z" fill="#6938EF" />
<path d="M16.6053 8.66662C16.8011 8.66662 16.8989 8.66663 16.9791 8.61747C17.0923 8.54806 17.16 8.38452 17.129 8.25538C17.107 8.16394 17.0432 8.10018 16.9155 7.97265L14.694 5.75111C14.5664 5.62345 14.5027 5.55962 14.4112 5.53764C14.2821 5.5066 14.1186 5.57429 14.0492 5.68752C14 5.7677 14 5.86557 14 6.06132L14 8.13327C14 8.31994 14 8.41328 14.0363 8.48459C14.0683 8.54731 14.1193 8.5983 14.182 8.63026C14.2533 8.66659 14.3466 8.66659 14.5333 8.66659L16.6053 8.66662Z" fill="#6938EF" />
</svg>
)
const DatasetConfig: FC = () => {
const { t } = useTranslation()
const {
@ -108,7 +101,6 @@ const DatasetConfig: FC = () => {
return (
<FeaturePanel
className='mt-2'
headerIcon={Icon}
title={t('appDebug.feature.dataSet.title')}
headerRight={
<div className='flex items-center gap-1'>
@ -134,7 +126,7 @@ const DatasetConfig: FC = () => {
)
: (
<div className='mt-1 px-3 pb-3'>
<div className='pt-2 pb-1 text-xs text-gray-500'>{t('appDebug.feature.dataSet.noData')}</div>
<div className='pt-2 pb-1 text-xs text-text-tertiary'>{t('appDebug.feature.dataSet.noData')}</div>
</div>
)}

View File

@ -24,6 +24,7 @@ import cn from '@/utils/classnames'
import { useSelectedDatasetsMode } from '@/app/components/workflow/nodes/knowledge-retrieval/hooks'
import Switch from '@/app/components/base/switch'
import Toast from '@/app/components/base/toast'
import Divider from '@/app/components/base/divider'
type Props = {
datasetConfigs: DatasetConfigs
@ -188,7 +189,7 @@ const ConfigContent: FC<Props> = ({
<div className='shrink-0 mr-2 system-xs-semibold-uppercase text-text-secondary'>
{t('dataset.rerankSettings')}
</div>
<div className='grow h-[1px] bg-gradient-to-l from-white to-[rgba(16,24,40,0.08)]'></div>
<Divider bgStyle='gradient' className='!h-px mx-0' />
</div>
{
selectedDatasetsMode.inconsistentEmbeddingModel
@ -352,7 +353,7 @@ const ConfigContent: FC<Props> = ({
{isInWorkflow && type === RETRIEVE_TYPE.oneWay && (
<div className='mt-4'>
<div className='flex items-center space-x-0.5'>
<div className='leading-[32px] text-[13px] font-medium text-gray-900'>{t('common.modelProvider.systemReasoningModel.key')}</div>
<div className='leading-[32px] text-[13px] font-medium text-text-primary'>{t('common.modelProvider.systemReasoningModel.key')}</div>
<Tooltip
popupContent={t('common.modelProvider.systemReasoningModel.tip')}
/>

View File

@ -6,8 +6,6 @@ import { useTranslation } from 'react-i18next'
import Link from 'next/link'
import produce from 'immer'
import TypeIcon from '../type-icon'
import s from './style.module.css'
import cn from '@/utils/classnames'
import Modal from '@/app/components/base/modal'
import type { DataSet } from '@/models/datasets'
import Button from '@/app/components/base/button'
@ -15,6 +13,7 @@ import { fetchDatasets } from '@/service/datasets'
import Loading from '@/app/components/base/loading'
import Badge from '@/app/components/base/badge'
import { useKnowledge } from '@/hooks/use-knowledge'
import cn from '@/utils/classnames'
export type ISelectDataSetProps = {
isShow: boolean
@ -111,8 +110,8 @@ const SelectDataSet: FC<ISelectDataSetProps> = ({
borderColor: 'rgba(0, 0, 0, 0.02',
}}
>
<span className='text-gray-500'>{t('appDebug.feature.dataSet.noDataSet')}</span>
<Link href="/datasets/create" className='font-normal text-[#155EEF]'>{t('appDebug.feature.dataSet.toCreate')}</Link>
<span className='text-text-tertiary'>{t('appDebug.feature.dataSet.noDataSet')}</span>
<Link href="/datasets/create" className='font-normal text-text-accent'>{t('appDebug.feature.dataSet.toCreate')}</Link>
</div>
)}
@ -122,7 +121,11 @@ const SelectDataSet: FC<ISelectDataSetProps> = ({
{datasets.map(item => (
<div
key={item.id}
className={cn(s.item, selected.some(i => i.id === item.id) && s.selected, 'flex justify-between items-center h-10 px-2 rounded-lg bg-white border border-gray-200 cursor-pointer', !item.embedding_available && s.disabled)}
className={cn(
'flex justify-between items-center h-10 px-2 rounded-lg bg-components-panel-on-panel-item-bg border-components-panel-border-subtle border-[0.5px] shadow-xs cursor-pointer hover:border-components-panel-border hover:bg-components-panel-on-panel-item-bg-hover hover:shadow-sm',
selected.some(i => i.id === item.id) && 'border-[1.5px] border-components-option-card-option-selected-border bg-state-accent-hover shadow-xs hover:shadow-xs hover:border-components-option-card-option-selected-border hover:bg-state-accent-hover',
!item.embedding_available && 'hover:border-components-panel-border-subtle hover:bg-components-panel-on-panel-item-bg hover:shadow-xs',
)}
onClick={() => {
if (!item.embedding_available)
return
@ -130,12 +133,12 @@ const SelectDataSet: FC<ISelectDataSetProps> = ({
}}
>
<div className='mr-1 flex items-center'>
<div className={cn('mr-2', !item.embedding_available && 'opacity-50')}>
<div className={cn('mr-2', !item.embedding_available && 'opacity-30')}>
<TypeIcon type="upload_file" size='md' />
</div>
<div className={cn('max-w-[200px] text-[13px] font-medium text-gray-800 overflow-hidden text-ellipsis whitespace-nowrap', !item.embedding_available && 'opacity-50 !max-w-[120px]')}>{item.name}</div>
<div className={cn('max-w-[200px] text-[13px] font-medium text-text-secondary overflow-hidden text-ellipsis whitespace-nowrap', !item.embedding_available && 'opacity-30 !max-w-[120px]')}>{item.name}</div>
{!item.embedding_available && (
<span className='ml-1 shrink-0 px-1 border border-gray-200 rounded-md text-gray-500 text-xs font-normal leading-[18px]'>{t('dataset.unavailable')}</span>
<span className='ml-1 shrink-0 px-1 border border-divider-deep rounded-md text-text-tertiary text-xs font-normal leading-[18px]'>{t('dataset.unavailable')}</span>
)}
</div>
{
@ -157,7 +160,7 @@ const SelectDataSet: FC<ISelectDataSetProps> = ({
)}
{loaded && (
<div className='flex justify-between items-center mt-8'>
<div className='text-sm font-medium text-gray-700'>
<div className='text-sm font-medium text-text-secondary'>
{selected.length > 0 && `${selected.length} ${t('appDebug.feature.dataSet.selected')}`}
</div>
<div className='flex space-x-2'>

View File

@ -1,13 +0,0 @@
.item {
box-shadow: 0px 1px 2px rgba(16, 24, 40, 0.05);
}
.item:hover,
.item.selected {
background: #F5F8FF;
border-color: #528BFF;
}
.item.disabled {
@apply bg-white border-gray-200 cursor-default;
}

View File

@ -172,14 +172,14 @@ const SettingsModal: FC<SettingsModalProps> = ({
return (
<div
className='overflow-hidden w-full flex flex-col bg-white border-[0.5px] border-gray-200 rounded-xl shadow-xl'
className='overflow-hidden w-full flex flex-col bg-components-panel-bg border-[0.5px] border-components-panel-border rounded-xl shadow-xl'
style={{
height: 'calc(100vh - 72px)',
}}
ref={ref}
>
<div className='shrink-0 flex justify-between items-center pl-6 pr-5 h-14 border-b border-b-gray-100'>
<div className='flex flex-col text-base font-semibold text-gray-900'>
<div className='shrink-0 flex justify-between items-center pl-6 pr-5 h-14 border-b border-divider-regular'>
<div className='flex flex-col text-base font-semibold text-text-primary'>
<div className='leading-6'>{t('datasetSettings.title')}</div>
</div>
<div className='flex items-center'>
@ -187,14 +187,12 @@ const SettingsModal: FC<SettingsModalProps> = ({
onClick={onCancel}
className='flex justify-center items-center w-6 h-6 cursor-pointer'
>
<RiCloseLine className='w-4 h-4 text-gray-500' />
<RiCloseLine className='w-4 h-4 text-text-tertiary' />
</div>
</div>
</div>
{/* Body */}
<div className='p-6 pt-5 border-b overflow-y-auto pb-[68px]' style={{
borderBottom: 'rgba(0, 0, 0, 0.05)',
}}>
<div className='p-6 pt-5 border-b border-divider-regular overflow-y-auto pb-[68px]'>
<div className={cn(rowClass, 'items-center')}>
<div className={labelClass}>
<div className='text-text-secondary system-sm-semibold'>{t('datasetSettings.form.name')}</div>
@ -217,7 +215,7 @@ const SettingsModal: FC<SettingsModalProps> = ({
className='resize-none'
placeholder={t('datasetSettings.form.descPlaceholder') || ''}
/>
<a className='mt-2 flex items-center h-[18px] px-3 text-xs text-gray-500' href="https://docs.dify.ai/features/datasets#how-to-write-a-good-dataset-description" target='_blank' rel='noopener noreferrer'>
<a className='mt-2 flex items-center h-[18px] px-3 text-xs text-text-tertiary' href="https://docs.dify.ai/features/datasets#how-to-write-a-good-dataset-description" target='_blank' rel='noopener noreferrer'>
<BookOpenIcon className='w-3 h-[18px] mr-1' />
{t('datasetSettings.form.descWrite')}
</a>
@ -260,7 +258,7 @@ const SettingsModal: FC<SettingsModalProps> = ({
<div className='text-text-secondary system-sm-semibold'>{t('datasetSettings.form.embeddingModel')}</div>
</div>
<div className='w-full'>
<div className='w-full h-9 rounded-lg bg-gray-100 opacity-60'>
<div className='w-full h-8 rounded-lg bg-components-input-bg-normal opacity-60'>
<ModelSelector
readonly
defaultModel={{
@ -270,9 +268,9 @@ const SettingsModal: FC<SettingsModalProps> = ({
modelList={embeddingsModelList}
/>
</div>
<div className='mt-2 w-full text-xs leading-6 text-gray-500'>
<div className='mt-2 w-full text-xs leading-6 text-text-tertiary'>
{t('datasetSettings.form.embeddingModelTip')}
<span className='text-[#155eef] cursor-pointer' onClick={() => setShowAccountSettingModal({ payload: 'provider' })}>{t('datasetSettings.form.embeddingModelTipLink')}</span>
<span className='text-text-accent cursor-pointer' onClick={() => setShowAccountSettingModal({ payload: 'provider' })}>{t('datasetSettings.form.embeddingModelTipLink')}</span>
</div>
</div>
</div>
@ -326,8 +324,8 @@ const SettingsModal: FC<SettingsModalProps> = ({
<div className={cn(labelClass, 'w-auto min-w-[168px]')}>
<div>
<div className='text-text-secondary system-sm-semibold'>{t('datasetSettings.form.retrievalSetting.title')}</div>
<div className='leading-[18px] text-xs font-normal text-gray-500'>
<a target='_blank' rel='noopener noreferrer' href='https://docs.dify.ai/guides/knowledge-base/create-knowledge-and-upload-documents#id-4-retrieval-settings' className='text-[#155eef]'>{t('datasetSettings.form.retrievalSetting.learnMore')}</a>
<div className='leading-[18px] text-xs font-normal text-text-tertiary'>
<a target='_blank' rel='noopener noreferrer' href='https://docs.dify.ai/guides/knowledge-base/create-knowledge-and-upload-documents#id-4-retrieval-settings' className='text-text-accent'>{t('datasetSettings.form.retrievalSetting.learnMore')}</a>
{t('datasetSettings.form.retrievalSetting.description')}
</div>
</div>
@ -360,16 +358,13 @@ const SettingsModal: FC<SettingsModalProps> = ({
e.stopPropagation()
e.nativeEvent.stopImmediatePropagation()
}}>
<RiCloseLine className='w-4 h-4 text-gray-500 ' />
<RiCloseLine className='w-4 h-4 text-gray-500' />
</div>
</div>
)}
<div
className='sticky z-[5] bottom-0 w-full flex justify-end py-4 px-6 border-t bg-white '
style={{
borderColor: 'rgba(0, 0, 0, 0.05)',
}}
className='sticky z-[5] bottom-0 w-full flex justify-end py-4 px-6 border-t border-divider-regular bg-background-section'
>
<Button
onClick={onCancel}

View File

@ -84,7 +84,6 @@ const ChatUserInput = ({
onSelect={(i) => { handleInputValueChange(key, i.value as string) }}
items={(options || []).map(i => ({ name: i, value: i }))}
allowSearch={false}
bgClassName='bg-gray-50'
/>
)}
{type === 'number' && (

View File

@ -31,7 +31,7 @@ import { useFeatures } from '@/app/components/base/features/hooks'
import type { InputForm } from '@/app/components/base/chat/chat/type'
import { getLastAnswer } from '@/app/components/base/chat/utils'
interface ChatItemProps {
type ChatItemProps = {
modelAndParameter: ModelAndParameter
}
const ChatItem: FC<ChatItemProps> = ({

View File

@ -64,11 +64,11 @@ const DebugItem: FC<DebugItemProps> = ({
return (
<div
className={`flex flex-col min-w-[320px] rounded-xl bg-white border-[0.5px] border-black/5 ${className}`}
className={`flex flex-col min-w-[320px] rounded-xl bg-background-section-burn ${className}`}
style={style}
>
<div className='shrink-0 flex items-center justify-between h-10 px-3 border-b-[0.5px] border-b-black/5'>
<div className='flex items-center justify-center w-6 h-5 font-medium italic text-gray-500'>
<div className='shrink-0 flex items-center justify-between h-10 px-3 border-b-[0.5px] border-divider-regular'>
<div className='flex items-center justify-center w-6 h-5 font-medium italic text-text-tertiary'>
#{index + 1}
</div>
<ModelParameterTrigger

View File

@ -73,7 +73,7 @@ const ModelParameterTrigger: FC<ModelParameterTriggerProps> = ({
<div
className={`
flex items-center max-w-[200px] h-8 px-2 rounded-lg cursor-pointer
${open && 'bg-gray-100'}
${open && 'bg-state-base-hover'}
${currentModel && currentModel.status !== ModelStatusEnum.active && '!bg-[#FFFAEB]'}
`}
>
@ -88,27 +88,27 @@ const ModelParameterTrigger: FC<ModelParameterTriggerProps> = ({
}
{
!currentProvider && (
<div className='flex items-center justify-center mr-1 w-4 h-4 rounded border border-dashed border-primary-100'>
<CubeOutline className='w-[11px] h-[11px] text-primary-600' />
<div className='flex items-center justify-center mr-1 w-4 h-4 rounded'>
<CubeOutline className='w-4 h-4 text-text-accent' />
</div>
)
}
{
currentModel && (
<ModelName
className='mr-0.5 text-gray-800'
className='mr-0.5 text-text-secondary'
modelItem={currentModel}
/>
)
}
{
!currentModel && (
<div className='mr-0.5 text-[13px] font-medium text-primary-600 truncate'>
<div className='mr-0.5 text-[13px] font-medium text-text-accent truncate'>
{t('common.modelProvider.selectModel')}
</div>
)
}
<RiArrowDownSLine className={`w-3 h-3 ${(currentModel && currentProvider) ? 'text-gray-800' : 'text-primary-600'}`} />
<RiArrowDownSLine className={`w-3 h-3 ${(currentModel && currentProvider) ? 'text-text-tertiary' : 'text-text-accent'}`} />
{
currentModel && currentModel.status !== ModelStatusEnum.active && (
<Tooltip popupContent={MODEL_STATUS_TEXT[currentModel.status][language]}>

View File

@ -15,7 +15,7 @@ import { useEventEmitterContextContext } from '@/context/event-emitter'
import { useProviderContext } from '@/context/provider-context'
import { useFeatures } from '@/app/components/base/features/hooks'
interface TextGenerationItemProps {
type TextGenerationItemProps = {
modelAndParameter: ModelAndParameter
}
const TextGenerationItem: FC<TextGenerationItemProps> = ({

View File

@ -1,299 +0,0 @@
'use client'
import type { FC } from 'react'
import React, { useEffect, useRef, useState } from 'react'
import {
RiAddLine,
RiDeleteBinLine,
} from '@remixicon/react'
import { useContext } from 'use-context-selector'
import produce from 'immer'
import { useTranslation } from 'react-i18next'
import { useBoolean } from 'ahooks'
import { ReactSortable } from 'react-sortablejs'
import cn from '@/utils/classnames'
import ConfigContext from '@/context/debug-configuration'
import Panel from '@/app/components/app/configuration/base/feature-panel'
import Button from '@/app/components/base/button'
import OperationBtn from '@/app/components/app/configuration/base/operation-btn'
import { getInputKeys } from '@/app/components/base/block-input'
import ConfirmAddVar from '@/app/components/app/configuration/config-prompt/confirm-add-var'
import { getNewVar } from '@/utils/var'
import { varHighlightHTML } from '@/app/components/app/configuration/base/var-highlight'
import Toast from '@/app/components/base/toast'
const MAX_QUESTION_NUM = 10
export type IOpeningStatementProps = {
value: string
readonly?: boolean
onChange?: (value: string) => void
suggestedQuestions?: string[]
onSuggestedQuestionsChange?: (value: string[]) => void
}
// regex to match the {{}} and replace it with a span
const regex = /\{\{([^}]+)\}\}/g
const OpeningStatement: FC<IOpeningStatementProps> = ({
value = '',
readonly,
onChange,
suggestedQuestions = [],
onSuggestedQuestionsChange = () => { },
}) => {
const { t } = useTranslation()
const {
modelConfig,
setModelConfig,
} = useContext(ConfigContext)
const promptVariables = modelConfig.configs.prompt_variables
const [notIncludeKeys, setNotIncludeKeys] = useState<string[]>([])
const hasValue = !!(value || '').trim()
const inputRef = useRef<HTMLTextAreaElement>(null)
const [isFocus, { setTrue: didSetFocus, setFalse: setBlur }] = useBoolean(false)
const setFocus = () => {
didSetFocus()
setTimeout(() => {
const input = inputRef.current
if (input) {
input.focus()
input.setSelectionRange(input.value.length, input.value.length)
}
}, 0)
}
const [tempValue, setTempValue] = useState(value)
useEffect(() => {
setTempValue(value || '')
}, [value])
const [tempSuggestedQuestions, setTempSuggestedQuestions] = useState(suggestedQuestions || [])
const notEmptyQuestions = tempSuggestedQuestions.filter(question => !!question && question.trim())
const coloredContent = (tempValue || '')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(regex, varHighlightHTML({ name: '$1' })) // `<span class="${highLightClassName}">{{$1}}</span>`
.replace(/\n/g, '<br />')
const handleEdit = () => {
if (readonly)
return
setFocus()
}
const [isShowConfirmAddVar, { setTrue: showConfirmAddVar, setFalse: hideConfirmAddVar }] = useBoolean(false)
const handleCancel = () => {
setBlur()
setTempValue(value)
setTempSuggestedQuestions(suggestedQuestions)
}
const handleConfirm = () => {
if (!(tempValue || '').trim()) {
Toast.notify({
type: 'error',
message: t('common.errorMsg.fieldRequired', {
field: t('appDebug.openingStatement.title'),
}),
})
return
}
const keys = getInputKeys(tempValue)
const promptKeys = promptVariables.map(item => item.key)
let notIncludeKeys: string[] = []
if (promptKeys.length === 0) {
if (keys.length > 0)
notIncludeKeys = keys
}
else {
notIncludeKeys = keys.filter(key => !promptKeys.includes(key))
}
if (notIncludeKeys.length > 0) {
setNotIncludeKeys(notIncludeKeys)
showConfirmAddVar()
return
}
setBlur()
onChange?.(tempValue)
onSuggestedQuestionsChange(tempSuggestedQuestions)
}
const cancelAutoAddVar = () => {
onChange?.(tempValue)
hideConfirmAddVar()
setBlur()
}
const autoAddVar = () => {
const newModelConfig = produce(modelConfig, (draft) => {
draft.configs.prompt_variables = [...draft.configs.prompt_variables, ...notIncludeKeys.map(key => getNewVar(key, 'string'))]
})
onChange?.(tempValue)
setModelConfig(newModelConfig)
hideConfirmAddVar()
setBlur()
}
const headerRight = !readonly ? (
isFocus ? (
<div className='flex items-center space-x-1'>
<Button
variant='ghost'
size='small'
onClick={handleCancel}
>
{t('common.operation.cancel')}
</Button>
<Button
onClick={handleConfirm}
variant="primary"
size='small'
>
{t('common.operation.save')}
</Button>
</div>
) : (
<OperationBtn type='edit' actionName={hasValue ? '' : t('appDebug.openingStatement.writeOpener') as string} onClick={handleEdit} />
)
) : null
const renderQuestions = () => {
return isFocus ? (
<div>
<div className='flex items-center py-2'>
<div className='shrink-0 flex space-x-0.5 leading-[18px] text-xs font-medium text-gray-500'>
<div className='uppercase'>{t('appDebug.openingStatement.openingQuestion')}</div>
<div>·</div>
<div>{tempSuggestedQuestions.length}/{MAX_QUESTION_NUM}</div>
</div>
<div className='ml-3 grow w-0 h-px bg-[#243, 244, 246]'></div>
</div>
<ReactSortable
className="space-y-1"
list={tempSuggestedQuestions.map((name, index) => {
return {
id: index,
name,
}
})}
setList={list => setTempSuggestedQuestions(list.map(item => item.name))}
handle='.handle'
ghostClass="opacity-50"
animation={150}
>
{tempSuggestedQuestions.map((question, index) => {
return (
<div className='group relative rounded-lg border border-gray-200 flex items-center pl-2.5 hover:border-gray-300 hover:bg-white' key={index}>
<div className='handle flex items-center justify-center w-4 h-4 cursor-grab'>
<svg width="6" height="10" viewBox="0 0 6 10" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fillRule="evenodd" clipRule="evenodd" d="M1 2C1.55228 2 2 1.55228 2 1C2 0.447715 1.55228 0 1 0C0.447715 0 0 0.447715 0 1C0 1.55228 0.447715 2 1 2ZM1 6C1.55228 6 2 5.55228 2 5C2 4.44772 1.55228 4 1 4C0.447715 4 0 4.44772 0 5C0 5.55228 0.447715 6 1 6ZM6 1C6 1.55228 5.55228 2 5 2C4.44772 2 4 1.55228 4 1C4 0.447715 4.44772 0 5 0C5.55228 0 6 0.447715 6 1ZM5 6C5.55228 6 6 5.55228 6 5C6 4.44772 5.55228 4 5 4C4.44772 4 4 4.44772 4 5C4 5.55228 4.44772 6 5 6ZM2 9C2 9.55229 1.55228 10 1 10C0.447715 10 0 9.55229 0 9C0 8.44771 0.447715 8 1 8C1.55228 8 2 8.44771 2 9ZM5 10C5.55228 10 6 9.55229 6 9C6 8.44771 5.55228 8 5 8C4.44772 8 4 8.44771 4 9C4 9.55229 4.44772 10 5 10Z" fill="#98A2B3" />
</svg>
</div>
<input
type="input"
value={question || ''}
onChange={(e) => {
const value = e.target.value
setTempSuggestedQuestions(tempSuggestedQuestions.map((item, i) => {
if (index === i)
return value
return item
}))
}}
className={'w-full overflow-x-auto pl-1.5 pr-8 text-sm leading-9 text-gray-900 border-0 grow h-9 bg-transparent focus:outline-none cursor-pointer rounded-lg'}
/>
<div
className='block absolute top-1/2 translate-y-[-50%] right-1.5 p-1 rounded-md cursor-pointer hover:bg-[#FEE4E2] hover:text-[#D92D20]'
onClick={() => {
setTempSuggestedQuestions(tempSuggestedQuestions.filter((_, i) => index !== i))
}}
>
<RiDeleteBinLine className='w-3.5 h-3.5' />
</div>
</div>
)
})}</ReactSortable>
{tempSuggestedQuestions.length < MAX_QUESTION_NUM && (
<div
onClick={() => { setTempSuggestedQuestions([...tempSuggestedQuestions, '']) }}
className='mt-1 flex items-center h-9 px-3 gap-2 rounded-lg cursor-pointer text-gray-400 bg-gray-100 hover:bg-gray-200'>
<RiAddLine className='w-4 h-4' />
<div className='text-gray-500 text-[13px]'>{t('appDebug.variableConfig.addOption')}</div>
</div>
)}
</div>
) : (
<div className='mt-1.5 flex flex-wrap'>
{notEmptyQuestions.map((question, index) => {
return (
<div key={index} className='mt-1 mr-1 max-w-full truncate last:mr-0 shrink-0 leading-8 items-center px-2.5 rounded-lg border border-gray-200 shadow-xs bg-white text-[13px] font-normal text-gray-900 cursor-pointer'>
{question}
</div>
)
})}
</div>
)
}
return (
<Panel
className={cn(isShowConfirmAddVar && 'h-[220px]', 'relative mt-4 !bg-gray-25')}
title={t('appDebug.openingStatement.title')}
headerIcon={
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fillRule="evenodd" clipRule="evenodd" d="M8.33353 1.33301C4.83572 1.33301 2.00019 4.16854 2.00019 7.66634C2.00019 8.37301 2.11619 9.05395 2.3307 9.69036C2.36843 9.80229 2.39063 9.86853 2.40507 9.91738L2.40979 9.93383L2.40729 9.93903C2.39015 9.97437 2.36469 10.0218 2.31705 10.11L1.2158 12.1484C1.14755 12.2746 1.07633 12.4064 1.02735 12.5209C0.978668 12.6348 0.899813 12.8437 0.938613 13.0914C0.984094 13.3817 1.15495 13.6373 1.40581 13.7903C1.61981 13.9208 1.843 13.9279 1.96683 13.9264C2.09141 13.925 2.24036 13.9095 2.38314 13.8947L5.81978 13.5395C5.87482 13.5338 5.9036 13.5309 5.92468 13.5292L5.92739 13.529L5.93564 13.532C5.96154 13.5413 5.99666 13.5548 6.0573 13.5781C6.76459 13.8506 7.53244 13.9997 8.33353 13.9997C11.8313 13.9997 14.6669 11.1641 14.6669 7.66634C14.6669 4.16854 11.8313 1.33301 8.33353 1.33301ZM5.9799 5.72116C6.73142 5.08698 7.73164 5.27327 8.33144 5.96584C8.93125 5.27327 9.91854 5.09365 10.683 5.72116C11.4474 6.34867 11.5403 7.41567 10.9501 8.16572C10.5845 8.6304 9.6668 9.47911 9.02142 10.0576C8.78435 10.2702 8.66582 10.3764 8.52357 10.4192C8.40154 10.456 8.26134 10.456 8.13931 10.4192C7.99706 10.3764 7.87853 10.2702 7.64147 10.0576C6.99609 9.47911 6.07839 8.6304 5.71276 8.16572C5.12259 7.41567 5.22839 6.35534 5.9799 5.72116Z" fill="#E74694" />
</svg>
}
headerRight={headerRight}
hasHeaderBottomBorder={!hasValue}
isFocus={isFocus}
>
<div className='text-gray-700 text-sm'>
{(hasValue || (!hasValue && isFocus)) ? (
<>
{isFocus
? (
<div>
<textarea
ref={inputRef}
value={tempValue}
rows={3}
onChange={e => setTempValue(e.target.value)}
className="w-full px-0 text-sm border-0 bg-transparent focus:outline-none "
placeholder={t('appDebug.openingStatement.placeholder') as string}
>
</textarea>
</div>
)
: (
<div dangerouslySetInnerHTML={{
__html: coloredContent,
}}></div>
)}
{renderQuestions()}
</>) : (
<div className='pt-2 pb-1 text-xs text-gray-500'>{t('appDebug.openingStatement.noDataPlaceHolder')}</div>
)}
{isShowConfirmAddVar && (
<ConfirmAddVar
varNameArr={notIncludeKeys}
onConfirm={autoAddVar}
onCancel={cancelAutoAddVar}
onHide={hideConfirmAddVar}
/>
)}
</div>
</Panel>
)
}
export default React.memo(OpeningStatement)

View File

@ -19,6 +19,7 @@ import {
} from '@/app/components/app/configuration/debug/hooks'
import type { ModelAndParameter } from '@/app/components/app/configuration/debug/types'
import Button from '@/app/components/base/button'
import Divider from '@/app/components/base/divider'
import Loading from '@/app/components/base/loading'
import AppPublisher from '@/app/components/app/app-publisher/features-wrapper'
import type {
@ -895,13 +896,13 @@ const Configuration: FC = () => {
<div className="flex flex-col h-full">
<div className='relative flex grow h-[200px] pt-14'>
{/* Header */}
<div className='absolute top-0 left-0 w-full bg-white h-14'>
<div className='absolute top-0 left-0 w-full bg-default-subtle h-14'>
<div className='flex items-center justify-between px-6 h-14'>
<div className='flex items-center'>
<div className='text-base font-semibold leading-6 text-gray-900'>{t('appDebug.orchestrate')}</div>
<div className='system-xl-semibold text-text-primary'>{t('appDebug.orchestrate')}</div>
<div className='flex items-center h-[14px] space-x-1 text-xs'>
{isAdvancedMode && (
<div className='ml-1 flex items-center h-5 px-1.5 border border-gray-100 rounded-md text-[11px] font-medium text-gray-500 uppercase'>{t('appDebug.promptMode.advanced')}</div>
<div className='ml-1 flex items-center h-5 px-1.5 border border-components-button-secondary-border rounded-md system-xs-medium-uppercase text-text-tertiary uppercase'>{t('appDebug.promptMode.advanced')}</div>
)}
</div>
</div>
@ -937,13 +938,13 @@ const Configuration: FC = () => {
debugWithMultipleModel={debugWithMultipleModel}
onDebugWithMultipleModelChange={handleDebugWithMultipleModelChange}
/>
<div className='mx-2 w-[1px] h-[14px] bg-gray-200'></div>
<Divider type='vertical' className='mx-2 h-[14px]' />
</>
)}
{isMobile && (
<Button className='!h-8 !text-[13px] font-medium' onClick={showDebugPanel}>
<Button className='mr-2 !h-8 !text-[13px] font-medium' onClick={showDebugPanel}>
<span className='mr-1'>{t('appDebug.operation.debugConfig')}</span>
<CodeBracketIcon className="w-4 h-4 text-gray-500" />
<CodeBracketIcon className="w-4 h-4 text-text-tertiary" />
</Button>
)}
<AppPublisher {...{
@ -1014,7 +1015,7 @@ const Configuration: FC = () => {
/>
)}
{isMobile && (
<Drawer showClose isOpen={isShowDebugPanel} onClose={hideDebugPanel} mask footer={null} panelClassname='!bg-gray-50'>
<Drawer showClose isOpen={isShowDebugPanel} onClose={hideDebugPanel} mask footer={null}>
<Debug
isAPIKeySet={isAPIKeySet}
onSetting={() => setShowAccountSettingModal({ payload: 'provider' })}

View File

@ -23,7 +23,7 @@ import { DEFAULT_VALUE_MAX_LEN } from '@/config'
import { useStore as useAppStore } from '@/app/components/app/store'
import cn from '@/utils/classnames'
export interface IPromptValuePanelProps {
export type IPromptValuePanelProps = {
appType: AppType
onSend?: () => void
inputs: Inputs
@ -157,7 +157,7 @@ const PromptValuePanel: FC<IPromptValuePanelProps> = ({
))}
{visionConfig?.enabled && (
<div className="mt-3 xl:flex justify-between">
<div className="mr-1 py-2 shrink-0 w-[120px] text-sm text-gray-900">{t('common.imageUploader.imageUpload')}</div>
<div className="mr-1 py-2 shrink-0 w-[120px] text-sm text-text-primary">{t('common.imageUploader.imageUpload')}</div>
<div className='grow'>
<TextGenerationImageUploader
settings={visionConfig}

View File

@ -173,7 +173,7 @@ const ChatInputArea = ({
<Textarea
ref={textareaRef}
className={cn(
'p-1 w-full leading-6 body-lg-regular text-text-tertiary outline-none',
'p-1 w-full leading-6 body-lg-regular text-text-tertiary bg-transparent outline-none',
)}
placeholder={t('common.chat.inputPlaceholder') || ''}
autoFocus

View File

@ -35,7 +35,7 @@ import PromptLogModal from '@/app/components/base/prompt-log-modal'
import { useStore as useAppStore } from '@/app/components/app/store'
import type { AppData } from '@/models/share'
export interface ChatProps {
export type ChatProps = {
appData?: AppData
chatList: ChatItem[]
config?: ChatConfig
@ -251,11 +251,8 @@ const Chat: FC<ChatProps> = ({
</div>
</div>
<div
className={`absolute bottom-0 ${(hasTryToAsk || !noChatInput || !noStopResponding) && chatFooterClassName}`}
className={`absolute bottom-0 bg-chat-input-mask ${(hasTryToAsk || !noChatInput || !noStopResponding) && chatFooterClassName}`}
ref={chatFooterRef}
style={{
background: 'linear-gradient(0deg, #F9FAFB 40%, rgba(255, 255, 255, 0.00) 100%)',
}}
>
<div
ref={chatFooterInnerRef}

View File

@ -33,10 +33,10 @@ const ImageLinkInput: FC<ImageLinkInputProps> = ({
}
return (
<div className='flex items-center pl-1.5 pr-1 h-8 border border-gray-200 bg-white shadow-xs rounded-lg'>
<div className='flex items-center pl-1.5 pr-1 h-8 border border-components-panel-border bg-components-panel-bg shadow-xs rounded-lg'>
<input
type="text"
className='grow mr-0.5 px-1 h-[18px] text-[13px] outline-none appearance-none'
className='grow mr-0.5 px-1 h-[18px] text-[13px] text-text-primary bg-transparent outline-none appearance-none'
value={imageLink}
onChange={e => setImageLink(e.target.value)}
placeholder={t('common.imageUploader.pasteImageLinkInputPlaceholder') || ''}

View File

@ -119,12 +119,12 @@ const ImageList: FC<ImageListProps> = ({
type="button"
className={cn(
'absolute z-10 -top-[9px] -right-[9px] items-center justify-center w-[18px] h-[18px]',
'bg-white hover:bg-gray-50 border-[0.5px] border-black/2 rounded-2xl shadow-lg',
'hover:bg-state-base-hover rounded-2xl shadow-lg',
item.progress === -1 ? 'flex' : 'hidden group-hover:flex',
)}
onClick={() => onRemove && onRemove(item._id)}
>
<RiCloseLine className="w-3 h-3 text-gray-500" />
<RiCloseLine className="w-3 h-3 text-text-tertiary" />
</button>
)}
</div>

View File

@ -50,7 +50,7 @@ const PasteImageLinkButton: FC<PasteImageLinkButtonProps> = ({
>
<PortalToFollowElemTrigger onClick={handleToggle}>
<div className={`
relative flex items-center justify-center px-3 h-8 bg-gray-100 hover:bg-gray-200 text-xs text-gray-500 rounded-lg
relative flex items-center justify-center px-3 h-8 bg-components-option-card-option-bg hover:bg-components-option-card-option-bg-hover text-xs text-text-tertiary rounded-lg
${disabled ? 'cursor-not-allowed' : 'cursor-pointer'}
`}>
<Link03 className='mr-2 w-4 h-4' />
@ -58,7 +58,7 @@ const PasteImageLinkButton: FC<PasteImageLinkButtonProps> = ({
</div>
</PortalToFollowElemTrigger>
<PortalToFollowElemContent className='z-10'>
<div className='p-2 w-[320px] bg-white border-[0.5px] border-gray-200 rounded-lg shadow-lg'>
<div className='p-2 w-[320px] bg-components-panel-bg border-[0.5px] border-components-panel-border rounded-lg shadow-lg'>
<ImageLinkInput onUpload={handleUpload} />
</div>
</PortalToFollowElemContent>
@ -98,9 +98,9 @@ const TextGenerationImageUploader: FC<TextGenerationImageUploaderProps> = ({
{
hovering => (
<div className={`
flex items-center justify-center px-3 h-8 bg-gray-100
text-xs text-gray-500 rounded-lg cursor-pointer
${hovering && 'bg-gray-200'}
flex items-center justify-center px-3 h-8 bg-components-option-card-option-bg
text-xs text-text-tertiary rounded-lg cursor-pointer
${hovering && 'bg-components-option-card-option-bg-hover'}
`}>
<ImagePlus className='mr-2 w-4 h-4' />
{t('common.imageUploader.uploadFromComputer')}

View File

@ -59,7 +59,7 @@ const Select: FC<ISelectProps> = ({
disabled = false,
onSelect,
allowSearch = true,
bgClassName = 'bg-gray-100',
bgClassName = 'bg-components-input-bg-normal',
overlayClassName,
optionClassName,
renderOption,
@ -99,10 +99,10 @@ const Select: FC<ISelectProps> = ({
}
}}>
<div className={classNames('relative')}>
<div className='group text-gray-800'>
<div className='group text-text-secondary'>
{allowSearch
? <Combobox.Input
className={`w-full rounded-lg border-0 ${bgClassName} py-1.5 pl-3 pr-10 shadow-sm sm:text-sm sm:leading-6 focus-visible:outline-none focus-visible:bg-gray-200 group-hover:bg-gray-200 ${disabled ? 'cursor-not-allowed' : 'cursor-pointer'}`}
className={`w-full rounded-lg border-0 ${bgClassName} py-1.5 pl-3 pr-10 shadow-sm sm:text-sm sm:leading-6 focus-visible:outline-none focus-visible:bg-state-base-hover group-hover:bg-state-base-hover ${disabled ? 'cursor-not-allowed' : 'cursor-pointer'}`}
onChange={(event) => {
if (!disabled)
setQuery(event.target.value)
@ -114,10 +114,10 @@ const Select: FC<ISelectProps> = ({
if (!disabled)
setOpen(!open)
}
} className={classNames(`flex items-center h-9 w-full rounded-lg border-0 ${bgClassName} py-1.5 pl-3 pr-10 shadow-sm sm:text-sm sm:leading-6 focus-visible:outline-none focus-visible:bg-gray-200 group-hover:bg-gray-200`, optionClassName)}>
} className={classNames(`flex items-center h-9 w-full rounded-lg border-0 ${bgClassName} py-1.5 pl-3 pr-10 shadow-sm sm:text-sm sm:leading-6 focus-visible:outline-none focus-visible:bg-state-base-hover group-hover:bg-state-base-hover`, optionClassName)}>
<div className='w-0 grow text-left truncate' title={selectedItem?.name}>{selectedItem?.name}</div>
</Combobox.Button>}
<Combobox.Button className="absolute inset-y-0 right-0 flex items-center rounded-r-md px-2 focus:outline-none group-hover:bg-gray-200" onClick={
<Combobox.Button className="absolute inset-y-0 right-0 flex items-center rounded-r-md px-2 focus:outline-none" onClick={
() => {
if (!disabled)
setOpen(!open)
@ -128,15 +128,15 @@ const Select: FC<ISelectProps> = ({
</div>
{(filteredItems.length > 0 && open) && (
<Combobox.Options className={`absolute z-10 mt-1 px-1 max-h-60 w-full overflow-auto rounded-md bg-white py-1 text-base shadow-lg border-gray-200 border-[0.5px] focus:outline-none sm:text-sm ${overlayClassName}`}>
<Combobox.Options className={`absolute z-10 mt-1 px-1 max-h-60 w-full overflow-auto rounded-md bg-components-panel-bg-blur backdrop-blur-sm py-1 text-base shadow-lg border-components-panel-border border-[0.5px] focus:outline-none sm:text-sm ${overlayClassName}`}>
{filteredItems.map((item: Item) => (
<Combobox.Option
key={item.value}
value={item}
className={({ active }: { active: boolean }) =>
classNames(
'relative cursor-default select-none py-2 pl-3 pr-9 rounded-lg hover:bg-gray-100 text-gray-700',
active ? 'bg-gray-100' : '',
'relative cursor-default select-none py-2 pl-3 pr-9 rounded-lg hover:bg-state-base-hover text-text-secondary',
active ? 'bg-state-base-hover' : '',
optionClassName,
)
}
@ -151,7 +151,7 @@ const Select: FC<ISelectProps> = ({
{selected && (
<span
className={classNames(
'absolute inset-y-0 right-0 flex items-center pr-4 text-gray-700',
'absolute inset-y-0 right-0 flex items-center pr-4 text-text-secondary',
)}
>
<RiCheckLine className="h-4 w-4" aria-hidden="true" />

View File

@ -15,7 +15,7 @@ import { Users01, UsersPlus } from '@/app/components/base/icons/src/vender/solid
import type { DatasetPermission } from '@/models/datasets'
import { useAppContext } from '@/context/app-context'
import type { Member } from '@/models/common'
export interface RoleSelectorProps {
export type RoleSelectorProps = {
disabled?: boolean
permission?: DatasetPermission
value: string[]
@ -73,45 +73,45 @@ const PermissionSelector = ({ disabled, permission, value, memberList, onChange,
className='block'
>
{permission === 'only_me' && (
<div className={cn('flex items-center px-3 py-[6px] rounded-lg bg-gray-100 cursor-pointer hover:bg-gray-200', open && 'bg-gray-200', disabled && 'hover:!bg-gray-100 !cursor-default')}>
<div className={cn('flex items-center px-3 py-[6px] rounded-lg bg-components-input-bg-normal cursor-pointer hover:bg-state-base-hover-alt', open && 'hover:bg-state-base-hover-alt', disabled && 'bg-components-input-bg-disabled hover:bg-components-input-bg-disabled !cursor-default')}>
<Avatar avatar={userProfile.avatar_url} name={userProfile.name} className='shrink-0 mr-2' size={24} />
<div className='grow mr-2 text-gray-900 text-sm leading-5'>{t('datasetSettings.form.permissionsOnlyMe')}</div>
{!disabled && <RiArrowDownSLine className='shrink-0 w-4 h-4 text-gray-700' />}
<div className='grow mr-2 text-text-primary text-sm leading-5'>{t('datasetSettings.form.permissionsOnlyMe')}</div>
{!disabled && <RiArrowDownSLine className='shrink-0 w-4 h-4 text-text-secondary' />}
</div>
)}
{permission === 'all_team_members' && (
<div className={cn('flex items-center px-3 py-[6px] rounded-lg bg-gray-100 cursor-pointer hover:bg-gray-200', open && 'bg-gray-200')}>
<div className={cn('flex items-center px-3 py-[6px] rounded-lg bg-components-input-bg-normal cursor-pointer hover:bg-state-base-hover-alt', open && 'hover:bg-state-base-hover-alt')}>
<div className='mr-2 flex items-center justify-center w-6 h-6 rounded-lg bg-[#EEF4FF]'>
<Users01 className='w-3.5 h-3.5 text-[#444CE7]' />
</div>
<div className='grow mr-2 text-gray-900 text-sm leading-5'>{t('datasetSettings.form.permissionsAllMember')}</div>
{!disabled && <RiArrowDownSLine className='shrink-0 w-4 h-4 text-gray-700' />}
<div className='grow mr-2 text-text-primary text-sm leading-5'>{t('datasetSettings.form.permissionsAllMember')}</div>
{!disabled && <RiArrowDownSLine className='shrink-0 w-4 h-4 text-text-secondary' />}
</div>
)}
{permission === 'partial_members' && (
<div className={cn('flex items-center px-3 py-[6px] rounded-lg bg-gray-100 cursor-pointer hover:bg-gray-200', open && 'bg-gray-200')}>
<div className={cn('flex items-center px-3 py-[6px] rounded-lg bg-components-input-bg-normal cursor-pointer hover:bg-state-base-hover-alt', open && 'hover:bg-state-base-hover-alt')}>
<div className='mr-2 flex items-center justify-center w-6 h-6 rounded-lg bg-[#EEF4FF]'>
<Users01 className='w-3.5 h-3.5 text-[#444CE7]' />
</div>
<div title={selectedMembers} className='grow mr-2 text-gray-900 text-sm leading-5 truncate'>{selectedMembers}</div>
{!disabled && <RiArrowDownSLine className='shrink-0 w-4 h-4 text-gray-700' />}
<div title={selectedMembers} className='grow mr-2 text-text-primary text-sm leading-5 truncate'>{selectedMembers}</div>
{!disabled && <RiArrowDownSLine className='shrink-0 w-4 h-4 text-text-secondary' />}
</div>
)}
</PortalToFollowElemTrigger>
<PortalToFollowElemContent className='z-[1002]'>
<div className='relative w-[480px] rounded-lg border-[0.5px] bg-white shadow-lg'>
<div className='relative w-[480px] rounded-lg border-[0.5px] border-components-panel-border bg-components-panel-bg-blur backdrop-blur-sm shadow-lg'>
<div className='p-1'>
<div className='pl-3 pr-2 py-1 rounded-lg hover:bg-gray-50 cursor-pointer' onClick={() => {
<div className='pl-3 pr-2 py-1 rounded-lg hover:bg-state-base-hover cursor-pointer' onClick={() => {
onChange('only_me')
setOpen(false)
}}>
<div className='flex items-center gap-2'>
<Avatar avatar={userProfile.avatar_url} name={userProfile.name} className='shrink-0 mr-2' size={24} />
<div className='grow mr-2 text-gray-900 text-sm leading-5'>{t('datasetSettings.form.permissionsOnlyMe')}</div>
{permission === 'only_me' && <Check className='w-4 h-4 text-primary-600' />}
<div className='grow mr-2 text-text-primary text-sm leading-5'>{t('datasetSettings.form.permissionsOnlyMe')}</div>
{permission === 'only_me' && <Check className='w-4 h-4 text-text-accent' />}
</div>
</div>
<div className='pl-3 pr-2 py-1 rounded-lg hover:bg-gray-50 cursor-pointer' onClick={() => {
<div className='pl-3 pr-2 py-1 rounded-lg hover:bg-state-base-hover cursor-pointer' onClick={() => {
onChange('all_team_members')
setOpen(false)
}}>
@ -119,11 +119,11 @@ const PermissionSelector = ({ disabled, permission, value, memberList, onChange,
<div className='mr-2 flex items-center justify-center w-6 h-6 rounded-lg bg-[#EEF4FF]'>
<Users01 className='w-3.5 h-3.5 text-[#444CE7]' />
</div>
<div className='grow mr-2 text-gray-900 text-sm leading-5'>{t('datasetSettings.form.permissionsAllMember')}</div>
{permission === 'all_team_members' && <Check className='w-4 h-4 text-primary-600' />}
<div className='grow mr-2 text-text-primary text-sm leading-5'>{t('datasetSettings.form.permissionsAllMember')}</div>
{permission === 'all_team_members' && <Check className='w-4 h-4 text-text-accent' />}
</div>
</div>
<div className='pl-3 pr-2 py-1 rounded-lg hover:bg-gray-50 cursor-pointer' onClick={() => {
<div className='pl-3 pr-2 py-1 rounded-lg hover:bg-state-base-hover cursor-pointer' onClick={() => {
onChange('partial_members')
onMemberSelect([userProfile.id])
}}>
@ -131,14 +131,14 @@ const PermissionSelector = ({ disabled, permission, value, memberList, onChange,
<div className={cn('mr-2 flex items-center justify-center w-6 h-6 rounded-lg bg-[#FFF6ED]', permission === 'partial_members' && '!bg-[#EEF4FF]')}>
<UsersPlus className={cn('w-3.5 h-3.5 text-[#FB6514]', permission === 'partial_members' && '!text-[#444CE7]')} />
</div>
<div className='grow mr-2 text-gray-900 text-sm leading-5'>{t('datasetSettings.form.permissionsInvitedMembers')}</div>
{permission === 'partial_members' && <Check className='w-4 h-4 text-primary-600' />}
<div className='grow mr-2 text-text-primary text-sm leading-5'>{t('datasetSettings.form.permissionsInvitedMembers')}</div>
{permission === 'partial_members' && <Check className='w-4 h-4 text-text-accent' />}
</div>
</div>
</div>
{permission === 'partial_members' && (
<div className='max-h-[360px] border-t-[1px] border-gray-100 p-1 overflow-y-auto'>
<div className='sticky left-0 top-0 p-2 pb-1 bg-white'>
<div className='max-h-[360px] border-t-[1px] border-divider-regular p-1 overflow-y-auto'>
<div className='sticky left-0 top-0 p-2 pb-1 bg-components-panel-bg-blur'>
<Input
showLeftIcon
showClearIcon
@ -151,23 +151,23 @@ const PermissionSelector = ({ disabled, permission, value, memberList, onChange,
<div className='pl-3 pr-[10px] py-1 flex gap-2 items-center rounded-lg'>
<Avatar avatar={userProfile.avatar_url} name={userProfile.name} className='shrink-0' size={24} />
<div className='grow'>
<div className='text-[13px] text-gray-700 font-medium leading-[18px] truncate'>
<div className='text-[13px] text-text-secondary font-medium leading-[18px] truncate'>
{userProfile.name}
<span className='text-xs text-gray-500 font-normal'>{t('datasetSettings.form.me')}</span>
<span className='text-xs text-text-tertiary font-normal'>{t('datasetSettings.form.me')}</span>
</div>
<div className='text-xs text-gray-500 leading-[18px] truncate'>{userProfile.email}</div>
<div className='text-xs text-text-tertiary leading-[18px] truncate'>{userProfile.email}</div>
</div>
<Check className='shrink-0 w-4 h-4 text-primary-600 opacity-30' />
<Check className='shrink-0 w-4 h-4 text-text-accent opacity-30' />
</div>
)}
{filteredMemberList.map(member => (
<div key={member.id} className='pl-3 pr-[10px] py-1 flex gap-2 items-center rounded-lg hover:bg-gray-100 cursor-pointer' onClick={() => selectMember(member)}>
<div key={member.id} className='pl-3 pr-[10px] py-1 flex gap-2 items-center rounded-lg hover:bg-state-base-hover cursor-pointer' onClick={() => selectMember(member)}>
<Avatar avatar={userProfile.avatar_url} name={member.name} className='shrink-0' size={24} />
<div className='grow'>
<div className='text-[13px] text-gray-700 font-medium leading-[18px] truncate'>{member.name}</div>
<div className='text-xs text-gray-500 leading-[18px] truncate'>{member.email}</div>
<div className='text-[13px] text-text-secondary font-medium leading-[18px] truncate'>{member.name}</div>
<div className='text-xs text-text-tertiary leading-[18px] truncate'>{member.email}</div>
</div>
{value.includes(member.id) && <Check className='shrink-0 w-4 h-4 text-primary-600' />}
{value.includes(member.id) && <Check className='shrink-0 w-4 h-4 text-text-accent' />}
</div>
))}
</div>

View File

@ -174,35 +174,35 @@ const WorkflowToolConfigureButton = ({
return (
<>
<div className='mt-2 pt-2 border-t-[0.5px] border-t-black/5'>
<div className='mt-2 pt-2 border-t-[0.5px] border-divider-regular'>
{(!published || !isLoading) && (
<div className={cn(
'group bg-gray-100 rounded-lg transition-colors',
'group bg-background-section-burn rounded-lg transition-colors',
disabled ? 'shadow-xs opacity-30 cursor-not-allowed' : 'cursor-pointer',
!published && 'hover:bg-primary-50',
)}>
{isCurrentWorkspaceManager
? (
<div
className='flex justify-start items-center gap-2 px-2.5 py-2'
className='flex justify-start items-center text-text-primary gap-2 px-2.5 py-2'
onClick={() => !published && setShowModal(true)}
>
<Tools className={cn('relative w-4 h-4', !published && 'group-hover:text-primary-600')} />
<div title={t('workflow.common.workflowAsTool') || ''} className={cn('grow shrink basis-0 text-[13px] font-medium leading-[18px] truncate', !published && 'group-hover:text-primary-600')}>{t('workflow.common.workflowAsTool')}</div>
{!published && (
<span className='shrink-0 px-1 border border-black/8 rounded-[5px] bg-white text-[10px] font-medium leading-[18px] text-gray-500'>{t('workflow.common.configureRequired').toLocaleUpperCase()}</span>
<span className='shrink-0 px-1 border border-divider-regular rounded-[5px] bg-background-default-subtle text-[10px] font-medium leading-[18px] text-text-tertiary'>{t('workflow.common.configureRequired').toLocaleUpperCase()}</span>
)}
</div>)
: (
<div
className='flex justify-start items-center gap-2 px-2.5 py-2'
>
<Tools className='w-4 h-4 text-gray-500' />
<div title={t('workflow.common.workflowAsTool') || ''} className='grow shrink basis-0 text-[13px] font-medium leading-[18px] truncate text-gray-500'>{t('workflow.common.workflowAsTool')}</div>
<Tools className='w-4 h-4 text-text-tertiary' />
<div title={t('workflow.common.workflowAsTool') || ''} className='grow shrink basis-0 text-[13px] font-medium leading-[18px] truncate text-text-tertiary'>{t('workflow.common.workflowAsTool')}</div>
</div>
)}
{published && (
<div className='px-2.5 py-2 border-t-[0.5px] border-black/5'>
<div className='px-2.5 py-2 border-t-[0.5px] border-divider-regular'>
<div className='flex justify-between'>
<Button
size='small'

View File

@ -95,15 +95,15 @@ const AllTools = ({
return (
<div className={cn(className)}>
<div className='flex items-center justify-between px-3 bg-background-default-hover border-b-[0.5px] border-black/[0.08] shadow-xs'>
<div className='flex items-center justify-between px-3 bg-background-default-hover border-b-[0.5px] border-divider-subtle shadow-xs'>
<div className='flex items-center h-8 space-x-1'>
{
tabs.map(tab => (
<div
className={cn(
'flex items-center px-2 h-6 rounded-md hover:bg-gray-100 cursor-pointer',
'text-xs font-medium text-gray-700',
activeTab === tab.key && 'bg-gray-200',
'flex items-center px-2 h-6 rounded-md hover:bg-state-base-hover cursor-pointer',
'text-xs font-medium text-text-secondary',
activeTab === tab.key && 'bg-state-base-hover-alt',
)}
key={tab.key}
onClick={() => setActiveTab(tab.key)}

View File

@ -137,7 +137,7 @@ const ToolPicker: FC<Props> = ({
</PortalToFollowElemTrigger>
<PortalToFollowElemContent className='z-[1000]'>
<div className="relative w-[356px] min-h-20 rounded-xl bg-components-panel-bg-blur border-[0.5px] border-components-panel-border shadow-lg">
<div className="relative w-[356px] min-h-20 rounded-xl backdrop-blur-sm bg-components-panel-bg-blur border-[0.5px] border-components-panel-border shadow-lg">
<div className='p-2 pb-1'>
<SearchBox
search={searchText}

View File

@ -35,8 +35,8 @@ const ToolItem: FC<Props> = ({
type={BlockEnum.Tool}
toolIcon={provider.icon}
/>
<div className='mb-1 text-sm leading-5 text-gray-900'>{payload.label[language]}</div>
<div className='text-xs text-gray-700 leading-[18px]'>{payload.description[language]}</div>
<div className='mb-1 text-sm leading-5 text-text-primary'>{payload.label[language]}</div>
<div className='text-xs text-text-secondary leading-[18px]'>{payload.description[language]}</div>
</div>
)}
>

View File

@ -22,7 +22,7 @@ const Item: FC<Props> = ({
}) => {
return (
<div>
<div className='flex items-center px-3 h-[22px] text-xs font-medium text-gray-500'>
<div className='flex items-center px-3 h-[22px] text-xs font-medium text-text-tertiary'>
{groupName}
</div>
<div>

View File

@ -68,7 +68,7 @@ const Tool: FC<Props> = ({
>
<div className={cn(className)}>
<div
className='flex items-center justify-between pl-3 pr-1 w-full rounded-lg hover:bg-gray-50 cursor-pointer select-none'
className='flex items-center justify-between pl-3 pr-1 w-full rounded-lg hover:bg-state-base-hover cursor-pointer select-none'
onClick={() => {
if (hasAction)
setFold(!isFold)
@ -96,7 +96,7 @@ const Tool: FC<Props> = ({
type={BlockEnum.Tool}
toolIcon={payload.icon}
/>
<div className='ml-2 text-sm text-gray-900 flex-1 w-0 grow truncate'>{payload.label[language]}</div>
<div className='ml-2 text-sm text-text-primary flex-1 w-0 grow truncate'>{payload.label[language]}</div>
</div>
<div className='flex items-center'>

View File

@ -4,7 +4,7 @@ import React from 'react'
import { RiAlignLeft, RiCheckboxMultipleLine, RiFileCopy2Line, RiFileList2Line, RiHashtag, RiTextSnippet } from '@remixicon/react'
import { InputVarType } from '../../../types'
interface Props {
type Props = {
className?: string
type: InputVarType
}

View File

@ -103,7 +103,7 @@ const translation = {
edit: 'Edit annotation',
},
dataSet: {
title: 'Context',
title: 'Knowledge',
noData: 'You can import Knowledge as context',
words: 'Words',
textBlocks: 'Text Blocks',

View File

@ -103,7 +103,7 @@ const translation = {
edit: '编辑标注',
},
dataSet: {
title: '上下文',
title: '知识库',
noData: '您可以导入知识库作为上下文',
words: '词',
textBlocks: '文本块',

View File

@ -60,11 +60,11 @@ const config = {
...tailwindThemeVarDefine,
},
screens: {
mobile: '100px',
'mobile': '100px',
// => @media (min-width: 100px) { ... }
tablet: '640px', // 391
'tablet': '640px', // 391
// => @media (min-width: 600px) { ... }
pc: '769px',
'pc': '769px',
// => @media (min-width: 769px) { ... }
'2k': '2560px',
},
@ -87,6 +87,7 @@ const config = {
backgroundImage: {
'chatbot-bg': 'var(--color-chatbot-bg)',
'chat-bubble-bg': 'var(--color-chat-bubble-bg)',
'chat-input-mask': 'var(--color-chat-input-mask)',
'workflow-process-bg': 'var(--color-workflow-process-bg)',
'mask-top2bottom-gray-50-to-transparent': 'var(--mask-top2bottom-gray-50-to-transparent)',
'marketplace-divider-bg': 'var(--color-marketplace-divider-bg)',

View File

@ -5,6 +5,9 @@ html[data-theme="dark"] {
--color-chat-bubble-bg: linear-gradient(180deg,
rgba(200, 206, 218, 0.08) 0%,
rgba(200, 206, 218, 0.02) 100%);
--color-chat-input-mask: linear-gradient(180deg,
rgba(24, 24, 27, 0.04) 0%,
rgba(24, 24, 27, 0.60) 100%);
--color-workflow-process-bg: linear-gradient(90deg,
rgba(24, 24, 27, 0.25) 0%,
rgba(24, 24, 27, 0.04) 100%);

View File

@ -3,8 +3,11 @@ html[data-theme="light"] {
rgba(249, 250, 251, 0.9) 0%,
rgba(242, 244, 247, 0.9) 90.48%);
--color-chat-bubble-bg: linear-gradient(180deg,
#fff 0%,
rgba(255, 255, 255, 0.6) 100%);
#fff 0%,
rgba(255, 255, 255, 0.6) 100%);
--color-chat-input-mask: linear-gradient(180deg,
rgba(255, 255, 255, 0.01) 0%,
#F2F4F7 100%);
--color-workflow-process-bg: linear-gradient(90deg,
rgba(200, 206, 218, 0.2) 0%,
rgba(200, 206, 218, 0.04) 100%);