mirror of
https://github.com/csunny/DB-GPT.git
synced 2025-09-13 21:21:08 +00:00
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:
@@ -1,35 +1,41 @@
|
||||
import BlurredCard, { ChatButton, InnerDropdown } from '@/new-components/common/blurredCard';
|
||||
import ConstructLayout from '@/new-components/layout/Construct';
|
||||
import { ChatContext } from '@/app/chat-context';
|
||||
import { apiInterceptors, getDbList, getDbSupportType, newDialogue, postDbDelete } from '@/client/api';
|
||||
import MuiLoading from '@/components/common/loading';
|
||||
import { apiInterceptors, getDbList, getDbSupportType, postDbDelete } from '@/client/api';
|
||||
import GPTCard from '@/components/common/gpt-card';
|
||||
import MuiLoading from '@/components/common/loading';
|
||||
import FormDialog from '@/components/database/form-dialog';
|
||||
import { DBOption, DBType, DbListResponse, DbSupportTypeResponse, IChatDbSchema } from '@/types/db';
|
||||
import ConstructLayout from '@/new-components/layout/Construct';
|
||||
import { DBOption, DBType, DbListResponse, DbSupportTypeResponse } from '@/types/db';
|
||||
import { dbMapper } from '@/utils';
|
||||
import { DeleteFilled, EditFilled, PlusOutlined } from '@ant-design/icons';
|
||||
import { useAsyncEffect } from 'ahooks';
|
||||
import { Button, Card, Drawer, Empty, Modal, Badge, message } from 'antd';
|
||||
import { useRouter } from 'next/router';
|
||||
import { useContext, useMemo, useState } from 'react';
|
||||
import { Badge, Button, Card, Drawer, Empty, Modal, message } from 'antd';
|
||||
import { useMemo, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
type DBItem = DbListResponse[0];
|
||||
|
||||
export function isFileDb(dbTypeList: DBOption[], dbType: DBType) {
|
||||
return dbTypeList.find((item) => item.value === dbType)?.isFileDb;
|
||||
return dbTypeList.find(item => item.value === dbType)?.isFileDb;
|
||||
}
|
||||
|
||||
function Database() {
|
||||
const { setCurrentDialogInfo } = useContext(ChatContext);
|
||||
// const { setCurrentDialogInfo } = useContext(ChatContext); // unused
|
||||
// const router = useRouter(); // unused
|
||||
const { t } = useTranslation();
|
||||
const router = useRouter();
|
||||
|
||||
const [dbList, setDbList] = useState<DbListResponse>([]);
|
||||
const [dbSupportList, setDbSupportList] = useState<DbSupportTypeResponse>([]);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [modal, setModal] = useState<{ open: boolean; info?: DBItem; dbType?: DBType }>({ open: false });
|
||||
const [draw, setDraw] = useState<{ open: boolean; dbList?: DbListResponse; name?: string; type?: DBType }>({ open: false });
|
||||
const [modal, setModal] = useState<{
|
||||
open: boolean;
|
||||
info?: DBItem;
|
||||
dbType?: DBType;
|
||||
}>({ open: false });
|
||||
const [draw, setDraw] = useState<{
|
||||
open: boolean;
|
||||
dbList?: DbListResponse;
|
||||
name?: string;
|
||||
type?: DBType;
|
||||
}>({ open: false });
|
||||
|
||||
const getDbSupportList = async () => {
|
||||
const [, data] = await apiInterceptors(getDbSupportType());
|
||||
@@ -44,14 +50,18 @@ function Database() {
|
||||
};
|
||||
|
||||
const dbTypeList = useMemo(() => {
|
||||
const supportDbList = dbSupportList.map((item) => {
|
||||
const supportDbList = dbSupportList.map(item => {
|
||||
const { db_type, is_file_db } = item;
|
||||
|
||||
return { ...dbMapper[db_type], value: db_type, isFileDb: is_file_db };
|
||||
}) as DBOption[];
|
||||
const unSupportDbList = Object.keys(dbMapper)
|
||||
.filter((item) => !supportDbList.some((db) => db.value === item))
|
||||
.map((item) => ({ ...dbMapper[item], value: dbMapper[item].label, disabled: true })) as DBOption[];
|
||||
.filter(item => !supportDbList.some(db => db.value === item))
|
||||
.map(item => ({
|
||||
...dbMapper[item],
|
||||
value: dbMapper[item].label,
|
||||
disabled: true,
|
||||
})) as DBOption[];
|
||||
return [...supportDbList, ...unSupportDbList];
|
||||
}, [dbSupportList]);
|
||||
|
||||
@@ -64,30 +74,37 @@ function Database() {
|
||||
title: 'Tips',
|
||||
content: `Do you Want to delete the ${item.db_name}?`,
|
||||
onOk() {
|
||||
return new Promise<void>(async (resolve, reject) => {
|
||||
try {
|
||||
const [err] = await apiInterceptors(postDbDelete(item.db_name));
|
||||
if (err) {
|
||||
message.error(err.message);
|
||||
reject();
|
||||
return;
|
||||
}
|
||||
message.success('success');
|
||||
refreshDbList();
|
||||
resolve();
|
||||
} catch (e: any) {
|
||||
reject();
|
||||
}
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
handleDelete(item.db_name, resolve, reject);
|
||||
});
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const handleDelete = async (dbName: string, resolve: () => void, reject: () => void) => {
|
||||
try {
|
||||
const [err] = await apiInterceptors(postDbDelete(dbName));
|
||||
if (err) {
|
||||
message.error(err.message);
|
||||
reject();
|
||||
return;
|
||||
}
|
||||
message.success('success');
|
||||
refreshDbList();
|
||||
resolve();
|
||||
} catch {
|
||||
reject();
|
||||
}
|
||||
};
|
||||
|
||||
const dbListByType = useMemo(() => {
|
||||
const mapper = dbTypeList.reduce((acc, item) => {
|
||||
acc[item.value] = dbList.filter((dbConn) => dbConn.db_type === item.value);
|
||||
return acc;
|
||||
}, {} as Record<DBType, DbListResponse>);
|
||||
const mapper = dbTypeList.reduce(
|
||||
(acc, item) => {
|
||||
acc[item.value] = dbList.filter(dbConn => dbConn.db_type === item.value);
|
||||
return acc;
|
||||
},
|
||||
{} as Record<DBType, DbListResponse>,
|
||||
);
|
||||
return mapper;
|
||||
}, [dbList, dbTypeList]);
|
||||
|
||||
@@ -97,38 +114,45 @@ function Database() {
|
||||
}, []);
|
||||
|
||||
const handleDbTypeClick = (info: DBOption) => {
|
||||
const dbItems = dbList.filter((item) => item.db_type === info.value);
|
||||
setDraw({ open: true, dbList: dbItems, name: info.label, type: info.value });
|
||||
const dbItems = dbList.filter(item => item.db_type === info.value);
|
||||
setDraw({
|
||||
open: true,
|
||||
dbList: dbItems,
|
||||
name: info.label,
|
||||
type: info.value,
|
||||
});
|
||||
};
|
||||
|
||||
const handleChat = async (item: IChatDbSchema) => {
|
||||
const [_, data] = await apiInterceptors(
|
||||
newDialogue({
|
||||
chat_mode: 'chat_with_db_execute',
|
||||
}),
|
||||
);
|
||||
// 知识库对话都默认私有知识库应用下
|
||||
if (data?.conv_uid) {
|
||||
setCurrentDialogInfo?.({
|
||||
chat_scene: data.chat_mode,
|
||||
app_code: data.chat_mode,
|
||||
});
|
||||
localStorage.setItem(
|
||||
'cur_dialog_info',
|
||||
JSON.stringify({
|
||||
chat_scene: data.chat_mode,
|
||||
app_code: data.chat_mode,
|
||||
}),
|
||||
);
|
||||
router.push(`/chat?scene=chat_with_db_execute&id=${data?.conv_uid}&db_name=${item.db_name}`);
|
||||
}
|
||||
};
|
||||
// TODO: unused function call
|
||||
// const handleChat = async (item: IChatDbSchema) => {
|
||||
// const [, data] = await apiInterceptors(
|
||||
// newDialogue({
|
||||
// chat_mode: 'chat_with_db_execute',
|
||||
// }),
|
||||
// );
|
||||
// // 知识库对话都默认私有知识库应用下
|
||||
// if (data?.conv_uid) {
|
||||
// setCurrentDialogInfo?.({
|
||||
// chat_scene: data.chat_mode,
|
||||
// app_code: data.chat_mode,
|
||||
// });
|
||||
// localStorage.setItem(
|
||||
// 'cur_dialog_info',
|
||||
// JSON.stringify({
|
||||
// chat_scene: data.chat_mode,
|
||||
// app_code: data.chat_mode,
|
||||
// }),
|
||||
// );
|
||||
// router.push(`/chat?scene=chat_with_db_execute&id=${data?.conv_uid}&db_name=${item.db_name}`);
|
||||
// }
|
||||
// };
|
||||
|
||||
return (
|
||||
<ConstructLayout>
|
||||
<div className="relative min-h-full overflow-y-auto px-6 max-h-[90vh]">
|
||||
<div className='relative min-h-full overflow-y-auto px-6 max-h-[90vh]'>
|
||||
<MuiLoading visible={loading} />
|
||||
<div className="flex justify-between items-center mb-6">
|
||||
<div className="flex items-center gap-4">
|
||||
<div className='flex justify-between items-center mb-6'>
|
||||
<div className='flex items-center gap-4'>
|
||||
{/* <Input
|
||||
variant="filled"
|
||||
prefix={<SearchOutlined />}
|
||||
@@ -140,9 +164,9 @@ function Database() {
|
||||
/> */}
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-4">
|
||||
<div className='flex items-center gap-4'>
|
||||
<Button
|
||||
className="border-none text-white bg-button-gradient"
|
||||
className='border-none text-white bg-button-gradient'
|
||||
icon={<PlusOutlined />}
|
||||
onClick={() => {
|
||||
setModal({ open: true });
|
||||
@@ -153,12 +177,12 @@ function Database() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-wrap mx-[-8px] gap-2 md:gap-4">
|
||||
{dbTypeList.map((item) => {
|
||||
<div className='flex flex-wrap mx-[-8px] gap-2 md:gap-4'>
|
||||
{dbTypeList.map(item => {
|
||||
return (
|
||||
<Badge key={item.value} count={dbListByType[item.value]?.length} className="min-h-fit">
|
||||
<Badge key={item.value} count={dbListByType[item.value]?.length} className='min-h-fit'>
|
||||
<GPTCard
|
||||
className="h-full"
|
||||
className='h-full'
|
||||
title={item.label}
|
||||
desc={item.desc ?? ''}
|
||||
disabled={item.disabled}
|
||||
@@ -223,7 +247,7 @@ function Database() {
|
||||
dbTypeList={dbTypeList}
|
||||
choiceDBType={modal.dbType}
|
||||
editValue={modal.info}
|
||||
dbNames={dbList.map((item) => item.db_name)}
|
||||
dbNames={dbList.map(item => item.db_name)}
|
||||
onSuccess={() => {
|
||||
setModal({ open: false });
|
||||
refreshDbList();
|
||||
@@ -234,7 +258,7 @@ function Database() {
|
||||
/>
|
||||
<Drawer
|
||||
title={draw.name}
|
||||
placement="right"
|
||||
placement='right'
|
||||
onClose={() => {
|
||||
setDraw({ open: false });
|
||||
}}
|
||||
@@ -243,8 +267,8 @@ function Database() {
|
||||
{draw.type && dbListByType[draw.type] && dbListByType[draw.type].length ? (
|
||||
<>
|
||||
<Button
|
||||
type="primary"
|
||||
className="mb-4 flex items-center"
|
||||
type='primary'
|
||||
className='mb-4 flex items-center'
|
||||
icon={<PlusOutlined />}
|
||||
onClick={() => {
|
||||
setModal({ open: true, dbType: draw.type });
|
||||
@@ -252,14 +276,14 @@ function Database() {
|
||||
>
|
||||
Create
|
||||
</Button>
|
||||
{dbListByType[draw.type].map((item) => (
|
||||
{dbListByType[draw.type].map(item => (
|
||||
<Card
|
||||
key={item.db_name}
|
||||
title={item.db_name}
|
||||
extra={
|
||||
<>
|
||||
<EditFilled
|
||||
className="mr-2"
|
||||
className='mr-2'
|
||||
style={{ color: '#1b7eff' }}
|
||||
onClick={() => {
|
||||
onModify(item);
|
||||
@@ -273,7 +297,7 @@ function Database() {
|
||||
/>
|
||||
</>
|
||||
}
|
||||
className="mb-4"
|
||||
className='mb-4'
|
||||
>
|
||||
{item.db_path ? (
|
||||
<p>path: {item.db_path}</p>
|
||||
@@ -291,8 +315,8 @@ function Database() {
|
||||
) : (
|
||||
<Empty image={Empty.PRESENTED_IMAGE_DEFAULT}>
|
||||
<Button
|
||||
type="primary"
|
||||
className="flex items-center mx-auto"
|
||||
type='primary'
|
||||
className='flex items-center mx-auto'
|
||||
icon={<PlusOutlined />}
|
||||
onClick={() => {
|
||||
setModal({ open: true, dbType: draw.type });
|
||||
|
Reference in New Issue
Block a user