Commit 1373ed06 authored by Joel's avatar Joel

feat: choose plgins

parent 37ea862d
...@@ -7,7 +7,7 @@ export type IFeaturePanelProps = { ...@@ -7,7 +7,7 @@ export type IFeaturePanelProps = {
className?: string className?: string
headerIcon?: ReactNode headerIcon?: ReactNode
title: ReactNode title: ReactNode
headerRight: ReactNode headerRight?: ReactNode
hasHeaderBottomBorder?: boolean hasHeaderBottomBorder?: boolean
isFocus?: boolean isFocus?: boolean
noBodySpacing?: boolean noBodySpacing?: boolean
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
import type { FC } from 'react' import type { FC } from 'react'
import React from 'react' import React from 'react'
import DataConfig from './data-config' import DataConfig from './data-config'
import PluginConfig from './plug-config'
export type IConfigProps = { export type IConfigProps = {
className?: string className?: string
...@@ -23,7 +24,10 @@ const Config: FC<IConfigProps> = ({ ...@@ -23,7 +24,10 @@ const Config: FC<IConfigProps> = ({
<div > <div >
</div> </div>
<PluginConfig
config={plugins}
onChange={onPluginChange}
/>
<DataConfig <DataConfig
dataSets={dataSets} dataSets={dataSets}
onChange={onDataSetsChange} onChange={onDataSetsChange}
......
'use client'
import type { FC } from 'react'
import React from 'react'
import { useTranslation } from 'react-i18next'
import Item from './item'
import FeaturePanel from '@/app/components/app/configuration/base/feature-panel'
export type IPluginsProps = {
config: Record<string, boolean>
onChange: (key: string, value: boolean) => void
}
const plugins = [
{ key: 'google_search', icon: '' },
{ key: 'web_reader', icon: '' },
{ key: 'wikipedia', icon: '' },
]
const Plugins: FC<IPluginsProps> = ({
config,
onChange,
}) => {
const { t } = useTranslation()
const itemConfigs = plugins.map((plugin) => {
const res: Record<string, any> = { ...plugin }
const { key } = plugin
res.name = t(`explore.universalChat.plugins.${key}.name`)
if (key === 'web_reader')
res.description = t(`explore.universalChat.plugins.${key}.description`)
if (key === 'google_search') {
res.more = (
<div className='border-t border-[#FEF0C7] flex items-center h-[34px] pl-2 bg-[#FFFAEB] text-gray-700 text-xs '>
<span className='whitespace-pre'>{t('explore.universalChat.plugins.google_search.more.left')}</span>
<span className='cursor-pointer text-[#155EEF]'>{t('explore.universalChat.plugins.google_search.more.link')}</span>
<span className='whitespace-pre'>{t('explore.universalChat.plugins.google_search.more.right')}</span>
</div>
)
}
return res
})
const enabledPluginNum = Object.values(config).filter(v => v).length
return (
<FeaturePanel
className='mt-3'
title={
<div className='flex space-x-1'>
<div>{t('explore.universalChat.plugins.name')}</div>
<div className='text-[13px] font-normal text-gray-500'>({enabledPluginNum}/{plugins.length})</div>
</div>}
hasHeaderBottomBorder={false}
>
<div className='space-y-2'>
{itemConfigs.map(item => (
<Item
key={item.key}
icon={item.icon}
name={item.name}
description={item.description}
more={item.more}
enabled={config[item.key]}
onChange={enabled => onChange(item.key, enabled)}
/>
))}
</div>
</FeaturePanel>
)
}
export default React.memo(Plugins)
.shadow {
box-shadow: 0px 1px 2px 0px rgba(16, 24, 40, 0.05);
}
\ No newline at end of file
'use client'
import type { FC } from 'react'
import React from 'react'
import cn from 'classnames'
import s from './item.module.css'
import Switch from '@/app/components/base/switch'
export type IItemProps = {
icon: React.ReactNode
name: string
description?: string
more?: React.ReactNode
enabled: boolean
onChange: (enabled: boolean) => void
}
const Item: FC<IItemProps> = ({
icon,
name,
description,
more,
enabled,
onChange,
}) => {
return (
<div className={cn('bg-white rounded-xl border border-gray-200 overflow-hidden', s.shadow)}>
<div className='flex justify-between items-center min-h-[48px] px-2'>
<div className='flex space-x-2 '>
{icon}
<div className='leading-[18px]'>
<div className='text-[13px] font-medium text-gray-800'>{name}</div>
{description && <div className='text-xs leading-[18px] text-gray-500'>{description}</div>}
</div>
</div>
<Switch size='md' defaultValue={enabled} onChange={onChange} />
</div>
{more}
</div>
)
}
export default React.memo(Item)
...@@ -513,8 +513,12 @@ const Main: FC<IMainProps> = () => { ...@@ -513,8 +513,12 @@ const Main: FC<IMainProps> = () => {
) )
} }
const [plugins, setPlugins] = useState<Record<string, boolean>>({}) const [plugins, setPlugins] = useState<Record<string, boolean>>({
const handlePluginsChange = (key, value) => { google_search: false,
web_reader: true,
wikipedia: true,
})
const handlePluginsChange = (key: string, value: boolean) => {
setPlugins({ setPlugins({
...plugins, ...plugins,
[key]: value, [key]: value,
......
...@@ -38,6 +38,24 @@ const translation = { ...@@ -38,6 +38,24 @@ const translation = {
universalChat: { universalChat: {
welcome: 'Start chat with Dify', welcome: 'Start chat with Dify',
welcomeDescribe: 'Your AI conversation companion for personalized assistance', welcomeDescribe: 'Your AI conversation companion for personalized assistance',
plugins: {
name: 'Plugins',
google_search: {
name: 'Google Search',
more: {
left: 'Enable the plugin, ',
link: 'set up your SerpAPI key',
right: ' first.',
},
},
web_reader: {
name: 'Web Reader',
description: 'Get needed information from any web link',
},
wikipedia: {
name: 'Wikipedia',
},
},
}, },
} }
......
...@@ -38,6 +38,23 @@ const translation = { ...@@ -38,6 +38,23 @@ const translation = {
universalChat: { universalChat: {
welcome: '开始和 Dify 聊天吧', welcome: '开始和 Dify 聊天吧',
welcomeDescribe: '您的 AI 对话伴侣,为您提供个性化的帮助', welcomeDescribe: '您的 AI 对话伴侣,为您提供个性化的帮助',
plugins: {
google_search: {
name: '谷歌搜索',
more: {
left: '启用插件,首先',
link: '设置您的 SerpAPI 密钥',
right: '',
},
},
web_reader: {
name: '解析链接',
description: '从任何网页链接获取所需信息',
},
wikipedia: {
name: '维基百科',
},
},
}, },
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment