Commit fd5c9afc authored by Joel's avatar Joel

feat: support view config detail

parent f277a347
'use client' 'use client'
import React, { FC } from 'react' import type { FC } from 'react'
import React from 'react'
import cn from 'classnames' import cn from 'classnames'
import TypeIcon from '../type-icon'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import { formatNumber } from '@/utils/format' import TypeIcon from '../type-icon'
import RemoveIcon from '../../base/icons/remove-icon' import RemoveIcon from '../../base/icons/remove-icon'
import s from './style.module.css' import s from './style.module.css'
import { formatNumber } from '@/utils/format'
export interface ICardItemProps { export type ICardItemProps = {
className?: string className?: string
config: any config: any
onRemove: (id: string) => void onRemove: (id: string) => void
readonly?: boolean
} }
// const RemoveIcon = ({ className, onClick }: { className: string, onClick: () => void }) => ( // const RemoveIcon = ({ className, onClick }: { className: string, onClick: () => void }) => (
// <svg className={className} onClick={onClick} width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> // <svg className={className} onClick={onClick} width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
// <path d="M10 6H14M6 8H18M16.6667 8L16.1991 15.0129C16.129 16.065 16.0939 16.5911 15.8667 16.99C15.6666 17.3412 15.3648 17.6235 15.0011 17.7998C14.588 18 14.0607 18 13.0062 18H10.9938C9.93927 18 9.41202 18 8.99889 17.7998C8.63517 17.6235 8.33339 17.3412 8.13332 16.99C7.90607 16.5911 7.871 16.065 7.80086 15.0129L7.33333 8M10.6667 11V14.3333M13.3333 11V14.3333" stroke="#667085" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" /> // <path d="M10 6H14M6 8H18M16.6667 8L16.1991 15.0129C16.129 16.065 16.0939 16.5911 15.8667 16.99C15.6666 17.3412 15.3648 17.6235 15.0011 17.7998C14.588 18 14.0607 18 13.0062 18H10.9938C9.93927 18 9.41202 18 8.99889 17.7998C8.63517 17.6235 8.33339 17.3412 8.13332 16.99C7.90607 16.5911 7.871 16.065 7.80086 15.0129L7.33333 8M10.6667 11V14.3333M13.3333 11V14.3333" stroke="#667085" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
...@@ -24,7 +24,8 @@ export interface ICardItemProps { ...@@ -24,7 +24,8 @@ export interface ICardItemProps {
const CardItem: FC<ICardItemProps> = ({ const CardItem: FC<ICardItemProps> = ({
className, className,
config, config,
onRemove onRemove,
readonly,
}) => { }) => {
const { t } = useTranslation() const { t } = useTranslation()
...@@ -44,7 +45,7 @@ const CardItem: FC<ICardItemProps> = ({ ...@@ -44,7 +45,7 @@ const CardItem: FC<ICardItemProps> = ({
</div> </div>
</div> </div>
<RemoveIcon className={`${s.deleteBtn} shrink-0`} onClick={() => onRemove(config.id)} /> {!readonly && <RemoveIcon className={`${s.deleteBtn} shrink-0`} onClick={() => onRemove(config.id)} />}
</div> </div>
) )
} }
......
'use client'
import type { FC } from 'react'
import React from 'react'
import cn from 'classnames'
import { useTranslation } from 'react-i18next'
import { useBoolean, useClickAway } from 'ahooks'
import s from './style.module.css'
import Config from '@/app/components/explore/universal-chat/config'
type Props = {
modelId: string
plugins: Record<string, boolean>
dataSets: any[]
}
const ConfigViewPanel: FC<Props> = ({
modelId,
plugins,
dataSets,
}) => {
const { t } = useTranslation()
const [isShowConfig, { setFalse: hideConfig, toggle: toggleShowConfig }] = useBoolean(false)
const configContentRef = React.useRef(null)
useClickAway(() => {
hideConfig()
}, configContentRef)
return (
<div ref={configContentRef} className='relative'>
<div onClick={toggleShowConfig} className={cn(s.btn, 'flex h-8 w-8 rounded-lg border border-gray-200 bg-white cursor-pointer')}></div>
{isShowConfig && (
<div className={cn('absolute top-9 right-0 z-20 p-4 bg-white rounded-2xl shadow-md', s.panelBorder)}>
<div className='w-[368px]'>
<Config
readonly
modelId={modelId}
plugins={plugins}
dataSets={dataSets}
/>
<div className='mt-3 text-xs leading-[18px] text-500 font-normal'>{t('explore.universalChat.viewConfigDetailTip')}</div>
</div>
</div>
)}
</div>
)
}
export default React.memo(ConfigViewPanel)
.btn {
background: url(~@/app/components/datasets/documents/assets/action.svg) center center no-repeat transparent;
background-size: 16px 16px;
/* mask-image: ; */
}
.panelBorder {
border: 0.5px solid rgba(0, 0, 0, .05);
}
\ No newline at end of file
'use client'
import type { FC } from 'react'
import React from 'react'
const ConfigViewPanel: FC = () => {
return (
<div>
</div>
)
}
export default React.memo(ConfigViewPanel)
...@@ -12,11 +12,13 @@ import SelectDataSet from '@/app/components/app/configuration/dataset-config/sel ...@@ -12,11 +12,13 @@ import SelectDataSet from '@/app/components/app/configuration/dataset-config/sel
import type { DataSet } from '@/models/datasets' import type { DataSet } from '@/models/datasets'
type Props = { type Props = {
readonly?: boolean
dataSets: DataSet[] dataSets: DataSet[]
onChange: (data: DataSet[]) => void onChange?: (data: DataSet[]) => void
} }
const DatasetConfig: FC<Props> = ({ const DatasetConfig: FC<Props> = ({
readonly,
dataSets, dataSets,
onChange, onChange,
}) => { }) => {
...@@ -42,22 +44,22 @@ const DatasetConfig: FC<Props> = ({ ...@@ -42,22 +44,22 @@ const DatasetConfig: FC<Props> = ({
} }
}) })
}) })
onChange(newSelected) onChange?.(newSelected)
} }
else { else {
onChange(data) onChange?.(data)
} }
hideSelectDataSet() hideSelectDataSet()
} }
const onRemove = (id: string) => { const onRemove = (id: string) => {
onChange(dataSets.filter(item => item.id !== id)) onChange?.(dataSets.filter(item => item.id !== id))
} }
return ( return (
<FeaturePanel <FeaturePanel
className='mt-3' className='mt-3'
title={t('appDebug.feature.dataSet.title')} title={t('appDebug.feature.dataSet.title')}
headerRight={<OperationBtn type="add" onClick={showSelectDataSet} />} headerRight={!readonly && <OperationBtn type="add" onClick={showSelectDataSet} />}
hasHeaderBottomBorder={!hasData} hasHeaderBottomBorder={!hasData}
> >
{hasData {hasData
...@@ -69,6 +71,8 @@ const DatasetConfig: FC<Props> = ({ ...@@ -69,6 +71,8 @@ const DatasetConfig: FC<Props> = ({
key={item.id} key={item.id}
config={item} config={item}
onRemove={onRemove} onRemove={onRemove}
readonly={readonly}
// TODO: readonly remove btn
/> />
))} ))}
</div> </div>
......
...@@ -9,11 +9,11 @@ export type IConfigProps = { ...@@ -9,11 +9,11 @@ export type IConfigProps = {
className?: string className?: string
readonly?: boolean readonly?: boolean
modelId: string modelId: string
onModelChange: (modelId: string) => void onModelChange?: (modelId: string) => void
plugins: Record<string, boolean> plugins: Record<string, boolean>
onPluginChange: (key: string, value: boolean) => void onPluginChange?: (key: string, value: boolean) => void
dataSets: any[] dataSets: any[]
onDataSetsChange: (contexts: any[]) => void onDataSetsChange?: (contexts: any[]) => void
} }
const Config: FC<IConfigProps> = ({ const Config: FC<IConfigProps> = ({
...@@ -34,13 +34,17 @@ const Config: FC<IConfigProps> = ({ ...@@ -34,13 +34,17 @@ const Config: FC<IConfigProps> = ({
onChange={onModelChange} onChange={onModelChange}
/> />
<PluginConfig <PluginConfig
readonly={readonly}
config={plugins} config={plugins}
onChange={onPluginChange} onChange={onPluginChange}
/> />
<DataConfig {(!readonly || (readonly && dataSets.length > 0)) && (
dataSets={dataSets} <DataConfig
onChange={onDataSetsChange} readonly={readonly}
/> dataSets={dataSets}
onChange={onDataSetsChange}
/>
)}
</div> </div>
) )
} }
......
...@@ -9,7 +9,7 @@ import { UNIVERSAL_CHAT_MODEL_LIST as MODEL_LIST } from '@/config' ...@@ -9,7 +9,7 @@ import { UNIVERSAL_CHAT_MODEL_LIST as MODEL_LIST } from '@/config'
export type IModelConfigProps = { export type IModelConfigProps = {
modelId: string modelId: string
onChange: (model: string) => void onChange?: (model: string) => void
readonly?: boolean readonly?: boolean
} }
...@@ -37,7 +37,7 @@ const ModelConfig: FC<IModelConfigProps> = ({ ...@@ -37,7 +37,7 @@ const ModelConfig: FC<IModelConfigProps> = ({
{isShowOption && ( {isShowOption && (
<div className={cn('min-w-[159px] absolute right-0 bg-gray-50 rounded-lg shadow')}> <div className={cn('min-w-[159px] absolute right-0 bg-gray-50 rounded-lg shadow')}>
{MODEL_LIST.map(item => ( {MODEL_LIST.map(item => (
<div key={item.id} onClick={() => onChange(item.id)} className="flex items-center h-9 px-3 rounded-lg cursor-pointer hover:bg-gray-100"> <div key={item.id} onClick={() => onChange?.(item.id)} className="flex items-center h-9 px-3 rounded-lg cursor-pointer hover:bg-gray-100">
<ModelIcon className='shrink-0 mr-2' provider={item?.provider} /> <ModelIcon className='shrink-0 mr-2' provider={item?.provider} />
<div className="text-sm gray-900 whitespace-nowrap">{item.name}</div> <div className="text-sm gray-900 whitespace-nowrap">{item.name}</div>
</div> </div>
......
...@@ -6,8 +6,9 @@ import Item from './item' ...@@ -6,8 +6,9 @@ import Item from './item'
import FeaturePanel from '@/app/components/app/configuration/base/feature-panel' import FeaturePanel from '@/app/components/app/configuration/base/feature-panel'
export type IPluginsProps = { export type IPluginsProps = {
readonly?: boolean
config: Record<string, boolean> config: Record<string, boolean>
onChange: (key: string, value: boolean) => void onChange?: (key: string, value: boolean) => void
} }
const plugins = [ const plugins = [
...@@ -16,6 +17,7 @@ const plugins = [ ...@@ -16,6 +17,7 @@ const plugins = [
{ key: 'wikipedia', icon: '' }, { key: 'wikipedia', icon: '' },
] ]
const Plugins: FC<IPluginsProps> = ({ const Plugins: FC<IPluginsProps> = ({
readonly,
config, config,
onChange, onChange,
}) => { }) => {
...@@ -28,7 +30,7 @@ const Plugins: FC<IPluginsProps> = ({ ...@@ -28,7 +30,7 @@ const Plugins: FC<IPluginsProps> = ({
if (key === 'web_reader') if (key === 'web_reader')
res.description = t(`explore.universalChat.plugins.${key}.description`) res.description = t(`explore.universalChat.plugins.${key}.description`)
if (key === 'google_search') { if (key === 'google_search' && !readonly) {
res.more = ( res.more = (
<div className='border-t border-[#FEF0C7] flex items-center h-[34px] pl-2 bg-[#FFFAEB] text-gray-700 text-xs '> <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='whitespace-pre'>{t('explore.universalChat.plugins.google_search.more.left')}</span>
...@@ -61,7 +63,8 @@ const Plugins: FC<IPluginsProps> = ({ ...@@ -61,7 +63,8 @@ const Plugins: FC<IPluginsProps> = ({
description={item.description} description={item.description}
more={item.more} more={item.more}
enabled={config[item.key]} enabled={config[item.key]}
onChange={enabled => onChange(item.key, enabled)} onChange={enabled => onChange?.(item.key, enabled)}
readonly={readonly}
/> />
))} ))}
</div> </div>
......
...@@ -12,6 +12,7 @@ export type IItemProps = { ...@@ -12,6 +12,7 @@ export type IItemProps = {
more?: React.ReactNode more?: React.ReactNode
enabled: boolean enabled: boolean
onChange: (enabled: boolean) => void onChange: (enabled: boolean) => void
readonly?: boolean
} }
const Item: FC<IItemProps> = ({ const Item: FC<IItemProps> = ({
...@@ -21,6 +22,7 @@ const Item: FC<IItemProps> = ({ ...@@ -21,6 +22,7 @@ const Item: FC<IItemProps> = ({
more, more,
enabled, enabled,
onChange, onChange,
readonly,
}) => { }) => {
return ( return (
<div className={cn('bg-white rounded-xl border border-gray-200 overflow-hidden', s.shadow)}> <div className={cn('bg-white rounded-xl border border-gray-200 overflow-hidden', s.shadow)}>
...@@ -32,7 +34,7 @@ const Item: FC<IItemProps> = ({ ...@@ -32,7 +34,7 @@ const Item: FC<IItemProps> = ({
{description && <div className='text-xs leading-[18px] text-gray-500'>{description}</div>} {description && <div className='text-xs leading-[18px] text-gray-500'>{description}</div>}
</div> </div>
</div> </div>
<Switch size='md' defaultValue={enabled} onChange={onChange} /> <Switch size='md' defaultValue={enabled} onChange={onChange} disabled={readonly} />
</div> </div>
{more} {more}
</div> </div>
......
...@@ -36,9 +36,9 @@ import { userInputsFormToPromptVariables } from '@/utils/model-config' ...@@ -36,9 +36,9 @@ import { userInputsFormToPromptVariables } from '@/utils/model-config'
import Confirm from '@/app/components/base/confirm' import Confirm from '@/app/components/base/confirm'
import type { DataSet } from '@/models/datasets' import type { DataSet } from '@/models/datasets'
import ConfigSummary from '@/app/components/explore/universal-chat/config-view/summary' import ConfigSummary from '@/app/components/explore/universal-chat/config-view/summary'
import ConfigDetail from '@/app/components/explore/universal-chat/config-view/detail'
const APP_ID = 'universal-chat' const APP_ID = 'universal-chat'
const isUniversalChat = true
export type IMainProps = {} export type IMainProps = {}
...@@ -566,9 +566,10 @@ const Main: FC<IMainProps> = () => { ...@@ -566,9 +566,10 @@ const Main: FC<IMainProps> = () => {
{(!isNewConversation || isResponsing) && ( {(!isNewConversation || isResponsing) && (
<div className='absolute z-10 top-0 left-0 right-0 flex items-center justify-between border-b border-gray-100 mobile:h-12 tablet:h-16 px-8 bg-white'> <div className='absolute z-10 top-0 left-0 right-0 flex items-center justify-between border-b border-gray-100 mobile:h-12 tablet:h-16 px-8 bg-white'>
<div className='text-gray-900'>{conversationName}</div> <div className='text-gray-900'>{conversationName}</div>
<div className='flex items-center shrink-0 ml-2'> <div className='flex items-center shrink-0 ml-2 space-x-2'>
<ConfigSummary modelId={modelId} pluginIds={Object.keys(plugins).filter(key => plugins[key])} <ConfigSummary modelId={modelId} pluginIds={Object.keys(plugins).filter(key => plugins[key])}
/> />
<ConfigDetail modelId={modelId} plugins={plugins} dataSets={dataSets}/>
</div> </div>
</div> </div>
)} )}
......
...@@ -56,6 +56,7 @@ const translation = { ...@@ -56,6 +56,7 @@ const translation = {
name: 'Wikipedia', name: 'Wikipedia',
}, },
}, },
viewConfigDetailTip: 'In conversation, cannot change above settings',
}, },
} }
......
...@@ -55,6 +55,7 @@ const translation = { ...@@ -55,6 +55,7 @@ const translation = {
name: '维基百科', name: '维基百科',
}, },
}, },
viewConfigDetailTip: '在对话中,无法更改上述设置',
}, },
} }
......
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