mirror of
https://github.com/csunny/DB-GPT.git
synced 2025-09-10 13:29:35 +00:00
feat(datasource): Database connection Renewal (#2359)
Co-authored-by: aries_ckt <916701291@qq.com> Co-authored-by: Fangyin Cheng <staneyffer@gmail.com> Co-authored-by: ‘yanzhiyonggit config --global user.email git config --global user.name ‘yanzhiyong <zhiyong.yan@clife.cn>
This commit is contained in:
@@ -16,7 +16,7 @@ type DBItem = DbListResponse[0];
|
||||
export function isFileDb(dbTypeList: DBOption[], dbType: DBType) {
|
||||
return dbTypeList.find(item => item.value === dbType)?.isFileDb;
|
||||
}
|
||||
|
||||
let getFromRenderData: any = [];
|
||||
function Database() {
|
||||
// const { setCurrentDialogInfo } = useContext(ChatContext); // unused
|
||||
// const router = useRouter(); // unused
|
||||
@@ -27,8 +27,10 @@ function Database() {
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [modal, setModal] = useState<{
|
||||
open: boolean;
|
||||
info?: DBItem;
|
||||
info?: string;
|
||||
dbType?: DBType;
|
||||
dbTypeData?: any[];
|
||||
description?: string;
|
||||
}>({ open: false });
|
||||
const [draw, setDraw] = useState<{
|
||||
open: boolean;
|
||||
@@ -40,7 +42,7 @@ function Database() {
|
||||
|
||||
const getDbSupportList = async () => {
|
||||
const [, data] = await apiInterceptors(getDbSupportType());
|
||||
setDbSupportList(data ?? []);
|
||||
setDbSupportList(data?.types ?? []);
|
||||
};
|
||||
|
||||
const refreshDbList = async () => {
|
||||
@@ -52,9 +54,8 @@ function Database() {
|
||||
|
||||
const dbTypeList = useMemo(() => {
|
||||
const supportDbList = dbSupportList.map(item => {
|
||||
const { db_type, is_file_db } = item;
|
||||
|
||||
return { ...dbMapper[db_type], value: db_type, isFileDb: is_file_db };
|
||||
const db_type = item?.name;
|
||||
return { ...dbMapper[db_type], value: db_type, isFileDb: true, parameters: item.parameters };
|
||||
}) as DBOption[];
|
||||
const unSupportDbList = Object.keys(dbMapper)
|
||||
.filter(item => !supportDbList.some(db => db.value === item))
|
||||
@@ -67,24 +68,30 @@ function Database() {
|
||||
}, [dbSupportList]);
|
||||
|
||||
const onModify = (item: DBItem) => {
|
||||
setModal({ open: true, info: item });
|
||||
for (let index = 0; index < getFromRenderData.length; index++) {
|
||||
const element = getFromRenderData[index];
|
||||
if (item.params[element.param_name]) {
|
||||
element.default_value = item.params[element.param_name];
|
||||
}
|
||||
}
|
||||
setModal({ open: true, info: item.id, dbType: item.type, description: item.description });
|
||||
};
|
||||
|
||||
const onDelete = (item: DBItem) => {
|
||||
Modal.confirm({
|
||||
title: 'Tips',
|
||||
content: `Do you Want to delete the ${item.db_name}?`,
|
||||
content: `Do you Want to delete the database connection?`,
|
||||
onOk() {
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
handleDelete(item.db_name, resolve, reject);
|
||||
handleDelete(item.id, resolve, reject);
|
||||
});
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const handleDelete = async (dbName: string, resolve: () => void, reject: () => void) => {
|
||||
const handleDelete = async (id: string, resolve: () => void, reject: () => void) => {
|
||||
try {
|
||||
const [err] = await apiInterceptors(postDbDelete(dbName));
|
||||
const [err] = await apiInterceptors(postDbDelete(id));
|
||||
if (err) {
|
||||
message.error(err.message);
|
||||
reject();
|
||||
@@ -101,7 +108,7 @@ function Database() {
|
||||
const dbListByType = useMemo(() => {
|
||||
const mapper = dbTypeList.reduce(
|
||||
(acc, item) => {
|
||||
acc[item.value] = dbList.filter(dbConn => dbConn.db_type === item.value);
|
||||
acc[item.value] = dbList.filter(dbConn => dbConn?.type.toLowerCase() === item.value.toLowerCase());
|
||||
return acc;
|
||||
},
|
||||
{} as Record<DBType, DbListResponse>,
|
||||
@@ -115,7 +122,9 @@ function Database() {
|
||||
}, []);
|
||||
|
||||
const handleDbTypeClick = (info: DBOption) => {
|
||||
const dbItems = dbList.filter(item => item.db_type === info.value);
|
||||
const dbItems = dbList.filter(item => item.type === info.value);
|
||||
getFromRenderData = info?.parameters;
|
||||
|
||||
setDraw({
|
||||
open: true,
|
||||
dbList: dbItems,
|
||||
@@ -126,58 +135,34 @@ function Database() {
|
||||
|
||||
const onRefresh = async (item: DBItem) => {
|
||||
setRefreshLoading(true);
|
||||
const [, res] = await apiInterceptors(postDbRefresh({ db_name: item.db_name, db_type: item.db_type }));
|
||||
const [, res] = await apiInterceptors(postDbRefresh({ id: item.id }));
|
||||
if (res) message.success(t('refreshSuccess'));
|
||||
setRefreshLoading(false);
|
||||
};
|
||||
|
||||
// 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}`);
|
||||
// }
|
||||
// };
|
||||
const getFileName = (path: string) => {
|
||||
if (!path) return '';
|
||||
// Handle Windows and Unix style paths
|
||||
const parts = path.split(/[/\\]/);
|
||||
return parts[parts.length - 1];
|
||||
};
|
||||
|
||||
return (
|
||||
<ConstructLayout>
|
||||
<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'>
|
||||
{/* <Input
|
||||
variant="filled"
|
||||
prefix={<SearchOutlined />}
|
||||
placeholder={t('please_enter_the_keywords')}
|
||||
// onChange={onSearch}
|
||||
// onPressEnter={onSearch}
|
||||
allowClear
|
||||
className="w-[230px] h-[40px] border-1 border-white backdrop-filter backdrop-blur-lg bg-white bg-opacity-30 dark:border-[#6f7f95] dark:bg-[#6f7f95] dark:bg-opacity-60"
|
||||
/> */}
|
||||
</div>
|
||||
<div className='flex items-center gap-4'></div>
|
||||
|
||||
<div className='flex items-center gap-4'>
|
||||
<Button
|
||||
className='border-none text-white bg-button-gradient'
|
||||
icon={<PlusOutlined />}
|
||||
onClick={() => {
|
||||
setModal({ open: true });
|
||||
console.log(dbList);
|
||||
console.log(dbTypeList);
|
||||
|
||||
setModal({ open: true, dbTypeData: dbTypeList });
|
||||
}}
|
||||
>
|
||||
{t('Add_Datasource')}
|
||||
@@ -201,61 +186,18 @@ function Database() {
|
||||
}}
|
||||
/>
|
||||
</Badge>
|
||||
// <BlurredCard
|
||||
// description={item.db_path ?? ''}
|
||||
// name={item.db_name}
|
||||
// key={item.db_name}
|
||||
// logo={targetDBType?.icon}
|
||||
// RightTop={
|
||||
// <InnerDropdown
|
||||
// menu={{
|
||||
// items: [
|
||||
// {
|
||||
// key: 'del',
|
||||
// label: (
|
||||
// <span
|
||||
// className="text-red-400"
|
||||
// onClick={() => {
|
||||
// onDelete(item);
|
||||
// }}
|
||||
// >
|
||||
// {t('Delete_Btn')}
|
||||
// </span>
|
||||
// ),
|
||||
// },
|
||||
// ],
|
||||
// }}
|
||||
// />
|
||||
// }
|
||||
// rightTopHover={false}
|
||||
// Tags={
|
||||
// <div>
|
||||
// <Tag>{item.db_type}</Tag>
|
||||
// </div>
|
||||
// }
|
||||
// RightBottom={
|
||||
// <ChatButton
|
||||
// text={t('start_chat')}
|
||||
// onClick={() => {
|
||||
// handleChat(item);
|
||||
// }}
|
||||
// />
|
||||
// }
|
||||
// onClick={() => {
|
||||
// // if (targetDBType?.disabled) return;
|
||||
// // handleDbTypeClick(targetDBType);
|
||||
// onModify(item);
|
||||
// }}
|
||||
// />
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
<FormDialog
|
||||
open={modal.open}
|
||||
dbTypeList={dbTypeList}
|
||||
getFromRenderData={getFromRenderData}
|
||||
description={modal.description}
|
||||
choiceDBType={modal.dbType}
|
||||
editValue={modal.info}
|
||||
dbNames={dbList.map(item => item.db_name)}
|
||||
dbTypeData={modal.dbTypeData}
|
||||
dbNames={dbList.map(item => item.params.database)}
|
||||
onSuccess={() => {
|
||||
setModal({ open: false });
|
||||
refreshDbList();
|
||||
@@ -286,8 +228,8 @@ function Database() {
|
||||
</Button>
|
||||
{dbListByType[draw.type].map(item => (
|
||||
<Card
|
||||
key={item.db_name}
|
||||
title={item.db_name}
|
||||
key={item.params?.database || item.params?.path || ''}
|
||||
title={item.params?.database || getFileName(item.params?.path) || ''}
|
||||
extra={
|
||||
<>
|
||||
<RedoOutlined
|
||||
@@ -314,16 +256,19 @@ function Database() {
|
||||
}
|
||||
className='mb-4'
|
||||
>
|
||||
{item.db_path ? (
|
||||
<p>path: {item.db_path}</p>
|
||||
) : (
|
||||
<>
|
||||
<p>host: {item.db_host}</p>
|
||||
<p>username: {item.db_user}</p>
|
||||
<p>port: {item.db_port}</p>
|
||||
</>
|
||||
)}
|
||||
<p>remark: {item.comment}</p>
|
||||
<>
|
||||
{['host', 'port', 'path', 'user', 'database', 'schema']
|
||||
// Just handle these keys
|
||||
.filter(key => Object.prototype.hasOwnProperty.call(item.params, key))
|
||||
.map(key => (
|
||||
<p key={key}>
|
||||
{key}: {key === 'path' ? getFileName(item.params[key]) : item.params[key]}
|
||||
</p>
|
||||
))}
|
||||
</>
|
||||
<p>
|
||||
{t('description')}: {item.description}
|
||||
</p>
|
||||
</Card>
|
||||
))}
|
||||
</Spin>
|
||||
|
Reference in New Issue
Block a user