feat(web): Unified frontend code style (#1923)

Co-authored-by: Fangyin Cheng <staneyffer@gmail.com>
Co-authored-by: 谨欣 <echo.cmy@antgroup.com>
Co-authored-by: 严志勇 <yanzhiyong@tiansuixiansheng.com>
Co-authored-by: yanzhiyong <932374019@qq.com>
This commit is contained in:
Dreammy23
2024-08-30 14:03:06 +08:00
committed by GitHub
parent f866580703
commit 471689ba20
247 changed files with 4960 additions and 4546 deletions

View File

@@ -1,13 +1,17 @@
import React, { useEffect, useMemo } from 'react';
import cls from 'classnames';
import { Form, Select } from 'antd';
import PreviewFlow from '@/components/flow/preview-flow';
import { useRequest } from 'ahooks';
import { apiInterceptors, getFlows } from '@/client/api';
import PreviewFlow from '@/components/flow/preview-flow';
import { IFlowResponse } from '@/types/flow';
import { useRequest } from 'ahooks';
import { Form, Select } from 'antd';
import cls from 'classnames';
import React, { useEffect, useMemo } from 'react';
import { useTranslation } from 'react-i18next';
const AwelLayout: React.FC<{ initValue: any; updateData: (data: any) => void; classNames?: string }> = ({ initValue, updateData, classNames }) => {
const AwelLayout: React.FC<{
initValue: any;
updateData: (data: any) => void;
classNames?: string;
}> = ({ initValue, updateData, classNames }) => {
const { t } = useTranslation();
const [form] = Form.useForm();
const flow = Form.useWatch('flow', form);
@@ -24,7 +28,12 @@ const AwelLayout: React.FC<{ initValue: any; updateData: (data: any) => void; cl
});
const flowOptions = useMemo(() => {
return data?.items?.map((item: any) => ({ label: item.label, value: item.name })) || [];
return (
data?.items?.map((item: any) => ({
label: item.label,
value: item.name,
})) || []
);
}, [data]);
const flowData = useMemo(() => {
@@ -38,11 +47,11 @@ const AwelLayout: React.FC<{ initValue: any; updateData: (data: any) => void; cl
return (
<div className={cls(classNames, 'mb-6')}>
<Form form={form} style={{ width: '100%' }}>
<Form.Item label={t('select_workflow')} name="flow">
<Select className="w-1/4" placeholder={t("please_select_workflow")} options={flowOptions} allowClear />
<Form.Item label={t('select_workflow')} name='flow'>
<Select className='w-1/4' placeholder={t('please_select_workflow')} options={flowOptions} allowClear />
</Form.Item>
{flowData && (
<div className="w-full h-[600px] mx-auto border-[0.5px] border-dark-gray">
<div className='w-full h-[600px] mx-auto border-[0.5px] border-dark-gray'>
<PreviewFlow flowData={flowData} />
</div>
)}

View File

@@ -1,8 +1,8 @@
import AppDefaultIcon from '@/new-components/common/AppDefaultIcon';
import { apiInterceptors, getAppStrategyValues, getNativeAppScenes, getResource } from '@/client/api';
import AppDefaultIcon from '@/new-components/common/AppDefaultIcon';
import { ParamNeed } from '@/types/app';
import { useRequest } from 'ahooks';
import { Form, InputNumber, Select, Tooltip, Typography } from 'antd';
import { Form, InputNumber, Select, Tooltip } from 'antd';
import cls from 'classnames';
import React, { useEffect, useMemo } from 'react';
import { useTranslation } from 'react-i18next';
@@ -39,12 +39,15 @@ const NativeApp: React.FC<{
// 获取应用类型&模型
const { data, loading } = useRequest(async () => {
const res = await Promise.all([apiInterceptors(getNativeAppScenes()), apiInterceptors(getAppStrategyValues('priority'))]);
const res = await Promise.all([
apiInterceptors(getNativeAppScenes()),
apiInterceptors(getAppStrategyValues('priority')),
]);
const [types, models] = res;
form.setFieldValue('chat_scene', team_context?.chat_scene);
form.setFieldValue('model', param_need?.find((param) => param.type === 'model')?.value);
form.setFieldValue('temperature', param_need?.find((param) => param.type === 'temperature')?.value);
await run(param_need?.find((param) => param.type === 'resource')?.value || '');
form.setFieldValue('model', param_need?.find(param => param.type === 'model')?.value);
form.setFieldValue('temperature', param_need?.find(param => param.type === 'temperature')?.value);
await run(param_need?.find(param => param.type === 'resource')?.value || '');
return [types, models] ?? [];
});
@@ -56,12 +59,14 @@ const NativeApp: React.FC<{
} = useRequest(
async (type: string) => {
const [, res] = await apiInterceptors(getResource({ type }));
if (chatScene === team_context?.chat_scene && param_need?.find((param) => param.type === 'resource')?.bind_value) {
form.setFieldsValue({ bind_value: param_need?.find((param) => param.type === 'resource')?.bind_value });
if (chatScene === team_context?.chat_scene && param_need?.find(param => param.type === 'resource')?.bind_value) {
form.setFieldsValue({
bind_value: param_need?.find(param => param.type === 'resource')?.bind_value,
});
}
return (
res?.map((item) => {
res?.map(item => {
return {
...item,
value: item.key,
@@ -80,10 +85,10 @@ const NativeApp: React.FC<{
return {
...type,
label: (
<div className="flex items-center gap-1">
<div className='flex items-center gap-1'>
<AppDefaultIcon width={4} height={4} scene={type.chat_scene} />
<Tooltip title={`资源类型${type.param_need.find((param: any) => param.type === 'resource')?.value}`}>
<span className="text-[#525964] dark:text-[rgba(255,255,255,0.65)] ml-1">{type.scene_name}</span>
<span className='text-[#525964] dark:text-[rgba(255,255,255,0.65)] ml-1'>{type.scene_name}</span>
</Tooltip>
</div>
),
@@ -102,15 +107,16 @@ const NativeApp: React.FC<{
[
{
chat_scene: rawVal.chat_scene,
scene_name: appTypeOptions.find((type) => type.chat_scene === rawVal.chat_scene)?.scene_name,
scene_name: appTypeOptions.find(type => type.chat_scene === rawVal.chat_scene)?.scene_name,
},
[
{ type: 'model', value: rawVal.model },
{ type: 'temperature', value: rawVal.temperature },
{
type: 'resource',
value: appTypeOptions.find((type) => type.chat_scene === rawVal.chat_scene)?.param_need?.find((param: any) => param.type === 'resource')
?.value,
value: appTypeOptions
.find(type => type.chat_scene === rawVal.chat_scene)
?.param_need?.find((param: any) => param.type === 'resource')?.value,
bind_value: rawVal.bind_value,
},
],
@@ -127,25 +133,45 @@ const NativeApp: React.FC<{
return (
<div className={cls(classNames)}>
<Form<FormProps> form={form} autoComplete="off" style={{ width: '100%' }} labelCol={{ span: 3 }} wrapperCol={{ span: 21 }}>
<Form.Item label={t('native_type')} tooltip name="chat_scene">
<Form<FormProps>
form={form}
autoComplete='off'
style={{ width: '100%' }}
labelCol={{ span: 3 }}
wrapperCol={{ span: 21 }}
>
<Form.Item label={t('native_type')} tooltip name='chat_scene'>
<Select
className="w-1/2"
className='w-1/2'
options={appTypeOptions}
placeholder={t('app_type_select')}
onChange={() => form.setFieldsValue({ bind_value: undefined })}
/>
</Form.Item>
{chatScene !== 'chat_excel' && (
<Form.Item label={t('Arguments')} name="bind_value">
<Select placeholder={t('please_select_param')} allowClear className="w-1/2" options={options} loading={paramsLoading} />
<Form.Item label={t('Arguments')} name='bind_value'>
<Select
placeholder={t('please_select_param')}
allowClear
className='w-1/2'
options={options}
loading={paramsLoading}
/>
</Form.Item>
)}
<Form.Item label={t("model")} tooltip name="model">
<Select placeholder={t("please_select_model")} allowClear options={data?.[1]?.[1]?.map((item) => ({ label: item, value: item }))} className="w-1/2" />
<Form.Item label={t('model')} tooltip name='model'>
<Select
placeholder={t('please_select_model')}
allowClear
options={data?.[1]?.[1]?.map(item => ({
label: item,
value: item,
}))}
className='w-1/2'
/>
</Form.Item>
<Form.Item label={t("temperature")} tooltip name="temperature">
<InputNumber className="w-1/5 h-8" max={1} min={0} step={0.1} placeholder={t('please_input_temperature')} />
<Form.Item label={t('temperature')} tooltip name='temperature'>
<InputNumber className='w-1/5 h-8' max={1} min={0} step={0.1} placeholder={t('please_input_temperature')} />
</Form.Item>
</Form>
</div>

View File

@@ -26,7 +26,7 @@ const RecommendQuestions: React.FC<{
// 将数据实时返回给消费组件
useEffect(() => {
updateData(recommendQuestions?.filter((question) => !!question.question));
updateData(recommendQuestions?.filter(question => !!question.question));
}, [recommendQuestions, updateData]);
return (
@@ -34,22 +34,28 @@ const RecommendQuestions: React.FC<{
<Form<FormRecommendQuestion>
style={{ width: '100%' }}
form={form}
initialValues={{ recommend_questions: initValue || [{ question: '', valid: false }] }}
autoComplete="off"
initialValues={{
recommend_questions: initValue || [{ question: '', valid: false }],
}}
autoComplete='off'
wrapperCol={{ span: 20 }}
{...(labelCol && { labelCol: { span: 4 } })}
>
<Form.Item label={t('recommended_questions')}>
<Form.List name="recommend_questions">
<Form.List name='recommend_questions'>
{(fields, { add, remove }) => (
<>
{fields.map(({ key, name }, index) => (
<div key={key} className={cls('flex flex-1 items-center gap-8 mb-6', formStyle)}>
<Form.Item label={`${t('question')} ${index + 1}`} name={[name, 'question']} className="grow">
<Form.Item label={`${t('question')} ${index + 1}`} name={[name, 'question']} className='grow'>
<Input placeholder={t('please_input_recommended_questions')} />
</Form.Item>
<Form.Item label={t('is_effective')} name={[name, 'valid']}>
<Switch style={{ background: recommendQuestions?.[index]?.valid ? '#1677ff' : '#ccc' }} />
<Switch
style={{
background: recommendQuestions?.[index]?.valid ? '#1677ff' : '#ccc',
}}
/>
</Form.Item>
<Form.Item>
<MinusCircleOutlined
@@ -62,7 +68,7 @@ const RecommendQuestions: React.FC<{
))}
<Form.Item className={cls(formStyle)}>
<Button
type="dashed"
type='dashed'
onClick={() => {
add({ question: '', valid: false });
}}

View File

@@ -1,14 +1,14 @@
import MarkDownContext from '@/new-components/common/MarkdownContext';
import { apiInterceptors, getAppStrategyValues } from '@/client/api';
import MarkDownContext from '@/new-components/common/MarkdownContext';
import { IResource } from '@/types/app';
import { ExclamationCircleOutlined } from '@ant-design/icons';
import { useRequest } from 'ahooks';
import { Form, Modal, Select } from 'antd';
import cls from 'classnames';
import React, { useEffect, useMemo, useRef, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { v4 as uuid } from 'uuid';
import ResourcesCard from './ResourcesCard';
import { useTranslation } from 'react-i18next';
type PromptSelectType = {
promptList: Record<string, any>[];
@@ -22,20 +22,20 @@ const PromptSelect: React.FC<PromptSelectType> = ({ value, onChange, promptList
const { t } = useTranslation();
useEffect(() => {
if (value) {
const filterPrompt = promptList?.filter((item) => item.prompt_code === value)[0];
const filterPrompt = promptList?.filter(item => item.prompt_code === value)[0];
setCurPrompt(filterPrompt);
}
}, [promptList, value]);
return (
<div className="w-2/5 flex items-center gap-2">
<div className='w-2/5 flex items-center gap-2'>
<Select
className="w-1/2"
className='w-1/2'
placeholder={t('please_select_prompt')}
options={promptList}
fieldNames={{ label: 'prompt_name', value: 'prompt_code' }}
onChange={(value) => {
const filterPrompt = promptList?.filter((item) => item.prompt_code === value)[0];
onChange={value => {
const filterPrompt = promptList?.filter(item => item.prompt_code === value)[0];
setCurPrompt(filterPrompt);
onChange?.(value);
}}
@@ -44,12 +44,18 @@ const PromptSelect: React.FC<PromptSelectType> = ({ value, onChange, promptList
showSearch
/>
{curPrompt && (
<span className="text-sm text-blue-500 cursor-pointer" onClick={() => setShowPrompt(true)}>
<ExclamationCircleOutlined className="mr-1" />
<span className='text-sm text-blue-500 cursor-pointer' onClick={() => setShowPrompt(true)}>
<ExclamationCircleOutlined className='mr-1' />
{t('View_details')}
</span>
)}
<Modal title={`Prompt ${t('details')}`} open={showPrompt} footer={false} width={'60%'} onCancel={() => setShowPrompt(false)}>
<Modal
title={`Prompt ${t('details')}`}
open={showPrompt}
footer={false}
width={'60%'}
onCancel={() => setShowPrompt(false)}
>
<MarkDownContext>{curPrompt?.content}</MarkDownContext>
</Modal>
</div>
@@ -70,8 +76,9 @@ const DetailsCard: React.FC<{
const promptTemplate = Form.useWatch('prompt_template', form);
const strategy = Form.useWatch('llm_strategy', form);
const strategyValue = Form.useWatch('llm_strategy_value', form);
const [curPrompt, setCurPrompt] = useState<Record<string, any>>();
const [showPrompt, setShowPrompt] = useState<boolean>(false);
// const [curPrompt, setCurPrompt] = useState<Record<string, any>>();
// const [showPrompt, setShowPrompt] = useState<boolean>(false);
const initVal = useMemo(() => {
return initValue?.find((item: any) => item.agent_name === name) || [];
@@ -84,7 +91,7 @@ const DetailsCard: React.FC<{
async () => {
const [, res] = await apiInterceptors(getAppStrategyValues('priority'));
return (
res?.map((item) => {
res?.map(item => {
return {
label: item,
value: item,
@@ -121,20 +128,35 @@ const DetailsCard: React.FC<{
style={{ width: '100%' }}
labelCol={{ span: 4 }}
form={form}
initialValues={{ llm_strategy: 'default', ...initVal, llm_strategy_value: initVal?.llm_strategy_value?.split(',') }}
initialValues={{
llm_strategy: 'default',
...initVal,
llm_strategy_value: initVal?.llm_strategy_value?.split(','),
}}
>
<Form.Item label={t('Prompt')} name="prompt_template">
<Form.Item label={t('Prompt')} name='prompt_template'>
<PromptSelect promptList={promptList} />
</Form.Item>
<Form.Item label={t('LLM_strategy')} required name="llm_strategy">
<Select className="w-1/5" placeholder={t('please_select_LLM_strategy')} options={modelStrategyOptions} allowClear />
<Form.Item label={t('LLM_strategy')} required name='llm_strategy'>
<Select
className='w-1/5'
placeholder={t('please_select_LLM_strategy')}
options={modelStrategyOptions}
allowClear
/>
</Form.Item>
{strategy === 'priority' && (
<Form.Item label={t('LLM_strategy_value')} required name="llm_strategy_value">
<Select mode="multiple" className="w-2/5" placeholder={t('please_select_LLM_strategy_value')} options={data} allowClear />
<Form.Item label={t('LLM_strategy_value')} required name='llm_strategy_value'>
<Select
mode='multiple'
className='w-2/5'
placeholder={t('please_select_LLM_strategy_value')}
options={data}
allowClear
/>
</Form.Item>
)}
<Form.Item label={t('available_resources')} name="resources">
<Form.Item label={t('available_resources')} name='resources'>
<ResourcesCard
resourceTypeOptions={resourceTypeOptions}
initValue={initVal?.resources?.map((res: any) => {
@@ -143,7 +165,7 @@ const DetailsCard: React.FC<{
uid: uuid(),
};
})}
updateData={(data) => {
updateData={data => {
resourcesRef.current = data?.[1];
updateData({
agent_name: name,

View File

@@ -2,7 +2,7 @@ import { apiInterceptors, getResource } from '@/client/api';
import { useRequest } from 'ahooks';
import { Form, Select, Switch } from 'antd';
import cls from 'classnames';
import React, { useMemo, useEffect } from 'react';
import React, { useEffect, useMemo } from 'react';
import { useTranslation } from 'react-i18next';
const ResourceContent: React.FC<{
@@ -25,12 +25,12 @@ const ResourceContent: React.FC<{
const { t } = useTranslation();
// 资源类型选项
const options = useMemo(() => {
return resourceTypeOptions?.filter((item) => item.value !== 'all') || [];
return resourceTypeOptions?.filter(item => item.value !== 'all') || [];
}, [resourceTypeOptions]);
// 获取非动态情况下,知识库、数据库、插件、编排工作流参数列表
const { run, data, loading } = useRequest(
async (type) => {
async type => {
const [, res] = await apiInterceptors(getResource({ type }));
form.setFieldsValue({
value: initValue?.value || res?.[0]?.key,
@@ -51,7 +51,7 @@ const ResourceContent: React.FC<{
// 动态参数value选项
const dynamicOptions = useMemo(() => {
return (
data?.map((item) => {
data?.map(item => {
return {
...item,
label: item.label,
@@ -95,8 +95,14 @@ const ResourceContent: React.FC<{
// );
}
return (
<Form.Item label={t('resource_value')} name="value" required>
<Select placeholder={t('please_select_param')} options={dynamicOptions} loading={loading} className="w-3/5" allowClear />
<Form.Item label={t('resource_value')} name='value' required>
<Select
placeholder={t('please_select_param')}
options={dynamicOptions}
loading={loading}
className='w-3/5'
allowClear
/>
</Form.Item>
);
};
@@ -118,16 +124,16 @@ const ResourceContent: React.FC<{
...initValue,
}}
>
<Form.Item label={t('resource_type')} name="type">
<Form.Item label={t('resource_type')} name='type'>
<Select
className="w-2/5"
className='w-2/5'
options={options}
onChange={(val: string) => {
setCurIcon({ uid, icon: val });
}}
/>
</Form.Item>
<Form.Item label={t('resource_dynamic')} name="is_dynamic">
<Form.Item label={t('resource_dynamic')} name='is_dynamic'>
<Switch style={{ background: isDynamic ? '#1677ff' : '#ccc' }} />
</Form.Item>
{/* 如果选择了动态参数这里就不需要参数了 */}

View File

@@ -1,15 +1,14 @@
import MyEmpty from '@/new-components/common/MyEmpty';
import { IResource } from '@/types/app';
import { DeleteOutlined, PlusOutlined } from '@ant-design/icons';
import { Button, Popconfirm, Select, Space, Typography } from 'antd';
import { Button, Popconfirm, Select, Typography } from 'antd';
import classNames from 'classnames';
import { concat } from 'lodash';
import React, { useEffect, useMemo, useRef, useState } from 'react';
import React, { useEffect, useRef, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { v4 as uuid } from 'uuid';
import { resourceTypeIcon } from '../../config';
import ResourceContent from './ResourceContent';
import { useTranslation } from 'react-i18next';
interface ResourceTabProps extends IResource {
uid?: string;
@@ -18,17 +17,20 @@ interface ResourceTabProps extends IResource {
name?: string;
}
const ResourcesCard: React.FC<{ name: string; updateData: (data: any) => void; initValue?: any; resourceTypeOptions: Record<string, any>[] }> = ({
name,
updateData,
resourceTypeOptions,
initValue,
}) => {
const ResourcesCard: React.FC<{
name: string;
updateData: (data: any) => void;
initValue?: any;
resourceTypeOptions: Record<string, any>[];
}> = ({ name, updateData, resourceTypeOptions, initValue }) => {
const { t } = useTranslation();
const resources = useRef<ResourceTabProps[]>(initValue || []);
const [curIcon, setCurIcon] = useState<{ uid: string; icon: string }>({ uid: '', icon: '' });
const [curIcon, setCurIcon] = useState<{ uid: string; icon: string }>({
uid: '',
icon: '',
});
const [resourcesTabs, setResourcesTabs] = useState<ResourceTabProps[]>(
initValue?.map((item: any, index: number) => {
initValue?.map((item: any) => {
return {
...item,
icon: item.type,
@@ -43,9 +45,9 @@ const ResourcesCard: React.FC<{ name: string; updateData: (data: any) => void; i
// 删除资源
const remove = (e: any, item: any) => {
e?.stopPropagation();
const findActiveIndex = resources.current?.findIndex((i) => i.uid === activeKey);
const filteredResources = resourcesTabs?.filter((i) => i.uid !== item.uid);
resources.current = resources.current.filter((i) => i.uid !== item.uid) || [];
const findActiveIndex = resources.current?.findIndex(i => i.uid === activeKey);
const filteredResources = resourcesTabs?.filter(i => i.uid !== item.uid);
resources.current = resources.current.filter(i => i.uid !== item.uid) || [];
updateData([name, resources.current]);
setResourcesTabs(filteredResources);
if (findActiveIndex === resourcesTabs?.length - 1 && findActiveIndex !== 0) {
@@ -64,7 +66,7 @@ const ResourcesCard: React.FC<{ name: string; updateData: (data: any) => void; i
[
{
is_dynamic: false,
type: resourceTypeOptions?.filter((item) => item.value !== 'all')?.[0].value,
type: resourceTypeOptions?.filter(item => item.value !== 'all')?.[0].value,
value: '',
uid,
name: t('resource') + ` ${resources.current.length + 1}`,
@@ -76,11 +78,11 @@ const ResourcesCard: React.FC<{ name: string; updateData: (data: any) => void; i
return [
...prev,
{
icon: resourceTypeOptions?.filter((item) => item.value !== 'all')?.[0]?.value || '',
icon: resourceTypeOptions?.filter(item => item.value !== 'all')?.[0]?.value || '',
uid,
initVal: {
is_dynamic: false,
type: resourceTypeOptions?.filter((item) => item.value !== 'all')?.[0].value,
type: resourceTypeOptions?.filter(item => item.value !== 'all')?.[0].value,
value: '',
uid,
name: t('resource') + ` ${prev.length + 1}`,
@@ -92,7 +94,7 @@ const ResourcesCard: React.FC<{ name: string; updateData: (data: any) => void; i
setActiveKey(uid);
setCurIcon({
uid,
icon: resourceTypeOptions?.filter((item) => item.value !== 'all')?.[0].value,
icon: resourceTypeOptions?.filter(item => item.value !== 'all')?.[0].value,
});
};
@@ -103,7 +105,7 @@ const ResourcesCard: React.FC<{ name: string; updateData: (data: any) => void; i
// 资源切换图标同步切换
useEffect(() => {
setResourcesTabs(
resourcesTabs.map((item) => {
resourcesTabs.map(item => {
if (curIcon?.uid === item.uid) {
return {
...item,
@@ -117,26 +119,26 @@ const ResourcesCard: React.FC<{ name: string; updateData: (data: any) => void; i
}, [curIcon]);
return (
<div className="flex flex-1 h-64 px-3 py-4 border border-[#d6d8da] rounded-md">
<div className="flex flex-col w-40 h-full">
<div className='flex flex-1 h-64 px-3 py-4 border border-[#d6d8da] rounded-md'>
<div className='flex flex-col w-40 h-full'>
<Select
options={resourceTypeOptions}
className="w-full h-8"
variant="borderless"
defaultValue="all"
className='w-full h-8'
variant='borderless'
defaultValue='all'
onChange={(value: any) => {
if (value === 'all') {
setFilterResourcesTabs(resourcesTabs);
setActiveKey(resourcesTabs?.[0]?.uid || '');
} else {
const newSourcesTabs = resourcesTabs?.filter((item) => item?.icon === value);
const newSourcesTabs = resourcesTabs?.filter(item => item?.icon === value);
setActiveKey(newSourcesTabs?.[0]?.uid || '');
setFilterResourcesTabs(newSourcesTabs as any);
}
}}
/>
<div className="flex flex-1 flex-col gap-1 overflow-y-auto">
{filterResourcesTabs?.map((item) => (
<div className='flex flex-1 flex-col gap-1 overflow-y-auto'>
{filterResourcesTabs?.map(item => (
<div
className={classNames(
'flex h-8 items-center px-3 pl-[0.6rem] rounded-md hover:bg-[#f5faff] hover:dark:bg-[#606264] cursor-pointer relative',
@@ -164,9 +166,9 @@ const ResourcesCard: React.FC<{ name: string; updateData: (data: any) => void; i
autoSize: {
maxRows: 1,
},
onChange: (v) => {
onChange: v => {
setResourcesTabs(
resourcesTabs.map((i) => {
resourcesTabs.map(i => {
if (i.uid === item.uid) {
return {
...i,
@@ -176,7 +178,7 @@ const ResourcesCard: React.FC<{ name: string; updateData: (data: any) => void; i
return i;
}),
);
resources.current = resources.current.map((i) => {
resources.current = resources.current.map(i => {
if (i.uid === item.uid) {
return {
...i,
@@ -196,28 +198,28 @@ const ResourcesCard: React.FC<{ name: string; updateData: (data: any) => void; i
</Typography.Text>
<Popconfirm
title={t('want_delete')}
onConfirm={(e) => {
onConfirm={e => {
remove(e, item);
}}
onCancel={(e) => e?.stopPropagation()}
onCancel={e => e?.stopPropagation()}
>
<DeleteOutlined
className={`text-sm cursor-pointer absolute right-2 ${hoverKey === item.uid ? 'opacity-100' : 'opacity-0'}`}
style={{ top: '50%', transform: 'translateY(-50%)' }}
onClick={(e) => e.stopPropagation()}
onClick={e => e.stopPropagation()}
/>
</Popconfirm>
</div>
))}
</div>
<Button className="w-full h-8" type="dashed" block icon={<PlusOutlined />} onClick={addSource}>
<Button className='w-full h-8' type='dashed' block icon={<PlusOutlined />} onClick={addSource}>
{t('add_resource')}
</Button>
</div>
<div className="flex flex-1 ml-6 ">
<div className='flex flex-1 ml-6 '>
{filterResourcesTabs && filterResourcesTabs?.length > 0 ? (
<div className="flex flex-1">
{filterResourcesTabs?.map((item) => (
<div className='flex flex-1'>
{filterResourcesTabs?.map(item => (
<ResourceContent
key={item.uid}
classNames={item.uid === activeKey ? 'block' : 'hidden'}
@@ -225,7 +227,7 @@ const ResourcesCard: React.FC<{ name: string; updateData: (data: any) => void; i
initValue={item.initVal}
setCurIcon={setCurIcon}
updateData={(data: any) => {
resources.current = resources.current?.map((i) => {
resources.current = resources.current?.map(i => {
if (i?.uid === data?.uid) {
return {
...i,
@@ -241,7 +243,7 @@ const ResourcesCard: React.FC<{ name: string; updateData: (data: any) => void; i
))}
</div>
) : (
<MyEmpty className="w-40 h-40" />
<MyEmpty className='w-40 h-40' />
)}
</div>
</div>

View File

@@ -6,9 +6,9 @@ import { Checkbox, Form, Space, Tooltip } from 'antd';
import cls from 'classnames';
import { concat } from 'lodash';
import React, { useEffect, useMemo, useRef, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { agentIcon, resourceTypeIcon } from '../../config';
import DetailsCard from './DetailsCard';
import { useTranslation } from 'react-i18next';
interface AgentSelectProps {
agents: IAgent[];
@@ -21,13 +21,13 @@ interface AgentSelectProps {
const AgentSelect: React.FC<AgentSelectProps> = ({ value, onChange, agents, selectedTab, setSelectedTab }) => {
return (
<Checkbox.Group
className="grid grid-cols-4 gap-4"
className='grid grid-cols-4 gap-4'
onChange={(value: string[]) => {
onChange?.(value);
}}
value={value}
>
{agents.map((item) => {
{agents.map(item => {
return (
<div
className={`flex grow h-8 items-center px-3 border ${
@@ -39,13 +39,15 @@ const AgentSelect: React.FC<AgentSelectProps> = ({ value, onChange, agents, sele
}}
>
<Checkbox value={item.name} />
<div className="flex items-center flex-1 justify-between">
<div className='flex items-center flex-1 justify-between'>
<div>
<span className="ml-2 mr-1">{agentIcon[item.name || '']}</span>
<span className="text-sm text-[rgba(0,10,26,0.68)] dark:text-[rgba(255,255,255,0.85)]">{item.label}</span>
<span className='ml-2 mr-1'>{agentIcon[item.name || '']}</span>
<span className='text-sm text-[rgba(0,10,26,0.68)] dark:text-[rgba(255,255,255,0.85)]'>
{item.label}
</span>
</div>
<Tooltip title={item.desc}>
<QuestionCircleOutlined className="text-sm" />
<QuestionCircleOutlined className='text-sm' />
</Tooltip>
</div>
</div>
@@ -70,10 +72,14 @@ const AutoPlan: React.FC<{
// 获取agents, strategy, sourceType;
const { data, loading } = useRequest(async () => {
const res = await Promise.all([apiInterceptors(getAgents()), apiInterceptors(getAppStrategy()), apiInterceptors(getResourceType())]);
const res = await Promise.all([
apiInterceptors(getAgents()),
apiInterceptors(getAppStrategy()),
apiInterceptors(getResourceType()),
]);
const [, agents] = res?.[0] || [];
details.current =
agents?.map((item) => {
agents?.map(item => {
return {
agent_name: item.name,
llm_strategy: '',
@@ -82,7 +88,9 @@ const AutoPlan: React.FC<{
resources: [],
};
}) || [];
form.setFieldsValue({ agent_name: initValue?.map((item: any) => item.agent_name) });
form.setFieldsValue({
agent_name: initValue?.map((item: any) => item.agent_name),
});
setSelectedTab(initValue?.map((item: any) => item.agent_name)?.[0] || agents?.[0]?.name || '');
return res ?? [];
});
@@ -102,7 +110,7 @@ const AutoPlan: React.FC<{
const modelStrategyOptions: any[] = useMemo(() => {
const [, strategy] = data?.[1] || [];
if (strategy?.length) {
return strategy.map((item) => {
return strategy.map(item => {
return {
label: language ? item.name : item.name_cn,
value: item.value,
@@ -116,7 +124,7 @@ const AutoPlan: React.FC<{
const resourceTypeOptions: Record<string, any>[] = useMemo(() => {
const [, sourceType] = data?.[2] || [];
if (sourceType?.length) {
const formatterSourceType = sourceType.map((item) => {
const formatterSourceType = sourceType.map(item => {
return {
label: (
<Space>
@@ -132,9 +140,9 @@ const AutoPlan: React.FC<{
[
{
label: (
<div className="flex items-center text-sm">
<div className='flex items-center text-sm'>
{resourceTypeIcon['all']}
<span className="ml-2 text-[rgba(0,10,26,0.68)] dark:text-[#ffffffD9]">{t('All')}</span>
<span className='ml-2 text-[rgba(0,10,26,0.68)] dark:text-[#ffffffD9]'>{t('All')}</span>
</div>
),
value: 'all',
@@ -148,22 +156,27 @@ const AutoPlan: React.FC<{
// 实时返回数据给消费组件
useEffect(() => {
updateData([loading, details.current.filter((detail) => agentName?.includes(detail.agent_name))]);
updateData([loading, details.current.filter(detail => agentName?.includes(detail.agent_name))]);
}, [loading, agentName, updateData]);
return (
<div className={cls(classNames)}>
<Form form={form} style={{ width: '100%' }} labelCol={{ span: 4 }} wrapperCol={{ span: 20 }}>
<Form.Item label={`${t('choose')} agent`} name="agent_name" required rules={[{ required: true, message: t('please_choose') + ' agent' }]}>
<Form.Item
label={`${t('choose')} agent`}
name='agent_name'
required
rules={[{ required: true, message: t('please_choose') + ' agent' }]}
>
<AgentSelect agents={data?.[0]?.[1] || []} selectedTab={selectedTab} setSelectedTab={setSelectedTab} />
</Form.Item>
</Form>
{data?.[0]?.[1]?.map((item) => (
{data?.[0]?.[1]?.map(item => (
<DetailsCard
key={item.name}
classNames={item.name === selectedTab ? 'block' : 'hidden'}
updateData={(data: any) => {
details.current = details.current.map((detail) => {
details.current = details.current.map(detail => {
if (detail.agent_name === data?.agent_name) {
return {
...detail,
@@ -174,7 +187,7 @@ const AutoPlan: React.FC<{
...detail,
};
});
updateData([loading, details.current.filter((detail) => agentName?.includes(detail.agent_name))]);
updateData([loading, details.current.filter(detail => agentName?.includes(detail.agent_name))]);
}}
initValue={initValue}
name={item.name}