Fix: Bug fixes (#11960)

### What problem does this PR solve?

Fix: Bug fixes

New search popup style modification
Fixed multilingual settings not updating immediately on personal center
page
Changed overlapped percent to percentage format, with maximum value of
30%
### Type of change

- [x] Bug Fix (non-breaking change which fixes an issue)
This commit is contained in:
chanx
2025-12-16 09:44:06 +08:00
committed by GitHub
parent 7ca3e11566
commit a98887d4ca
19 changed files with 192 additions and 137 deletions

View File

@@ -2,6 +2,7 @@ import { Button } from '@/components/ui/button';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { useNavigatePage } from '@/hooks/logic-hooks/navigate-hooks';
import { Settings, Trash2 } from 'lucide-react';
import { useDataSourceInfo } from '../contant';
import { useDeleteDataSource } from '../hooks';
import { IDataSorceInfo, IDataSourceBase } from '../interface';
import { delSourceModal } from './delete-source-modal';
@@ -13,6 +14,7 @@ export const AddedSourceCard = (props: IAddedSourceCardProps) => {
const { list, name, icon } = props;
const { handleDelete } = useDeleteDataSource();
const { navigateToDataSourceDetail } = useNavigatePage();
const { dataSourceInfo } = useDataSourceInfo();
const toDetail = (id: string) => {
navigateToDataSourceDetail(id);
};
@@ -49,6 +51,7 @@ export const AddedSourceCard = (props: IAddedSourceCardProps) => {
onClick={() =>
delSourceModal({
data: item,
dataSourceInfo: dataSourceInfo,
onOk: () => {
handleDelete(item);
},

View File

@@ -1,20 +1,19 @@
import { Button } from '@/components/ui/button';
import { Modal, ModalType } from '@/components/ui/modal/modal';
import { t } from 'i18next';
import { DataSourceInfo } from '../contant';
import { IDataSourceBase } from '../interface';
import { IDataSourceBase, IDataSourceInfoMap } from '../interface';
export type IDelSourceModalProps<T> = Partial<ModalType> & {
data?: T;
type?: 'delete' | 'unlink';
onOk?: (data?: T) => void;
dataSourceInfo: IDataSourceInfoMap;
};
export const delSourceModal = <T extends IDataSourceBase>(
props: IDelSourceModalProps<T>,
) => {
const { data, onOk, type = 'delete', ...otherProps } = props;
console.log('data', data);
const { data, onOk, type = 'delete', dataSourceInfo, ...otherProps } = props;
const config = {
title:
type === 'delete'
@@ -39,7 +38,7 @@ export const delSourceModal = <T extends IDataSourceBase>(
)}
<div className="flex items-center gap-1 p-2 border border-border-button rounded-md mb-3">
<div className="w-6 h-6 flex-shrink-0">
{data?.source ? DataSourceInfo[data?.source].icon : ''}
{data?.source ? dataSourceInfo[data?.source].icon : ''}
</div>
<div className="flex items-center gap-2 text-text-secondary text-xs">
{/* <div className="h-6 flex-shrink-0 text-text-primary text-base">

View File

@@ -1,11 +1,13 @@
import { FormFieldType } from '@/components/dynamic-form';
import SvgIcon from '@/components/svg-icon';
import { t } from 'i18next';
import { t, TFunction } from 'i18next';
import { useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
import BoxTokenField from './component/box-token-field';
import { ConfluenceIndexingModeField } from './component/confluence-token-field';
import GmailTokenField from './component/gmail-token-field';
import GoogleDriveTokenField from './component/google-drive-token-field';
import { IDataSourceInfoMap } from './interface';
export enum DataSourceKey {
CONFLUENCE = 'confluence',
S3 = 's3',
@@ -23,62 +25,75 @@ export enum DataSourceKey {
// TEAMS = 'teams',
}
export const DataSourceInfo = {
[DataSourceKey.S3]: {
name: 'S3',
description: t(`setting.${DataSourceKey.S3}Description`),
icon: <SvgIcon name={'data-source/s3'} width={38} />,
},
[DataSourceKey.NOTION]: {
name: 'Notion',
description: t(`setting.${DataSourceKey.NOTION}Description`),
icon: <SvgIcon name={'data-source/notion'} width={38} />,
},
[DataSourceKey.DISCORD]: {
name: 'Discord',
description: t(`setting.${DataSourceKey.DISCORD}Description`),
icon: <SvgIcon name={'data-source/discord'} width={38} />,
},
[DataSourceKey.CONFLUENCE]: {
name: 'Confluence',
description: t(`setting.${DataSourceKey.CONFLUENCE}Description`),
icon: <SvgIcon name={'data-source/confluence'} width={38} />,
},
[DataSourceKey.GOOGLE_DRIVE]: {
name: 'Google Drive',
description: t(`setting.${DataSourceKey.GOOGLE_DRIVE}Description`),
icon: <SvgIcon name={'data-source/google-drive'} width={38} />,
},
[DataSourceKey.GMAIL]: {
name: 'Gmail',
description: t(`setting.${DataSourceKey.GMAIL}Description`),
icon: <SvgIcon name={'data-source/gmail'} width={38} />,
},
[DataSourceKey.MOODLE]: {
name: 'Moodle',
description: t(`setting.${DataSourceKey.MOODLE}Description`),
icon: <SvgIcon name={'data-source/moodle'} width={38} />,
},
[DataSourceKey.JIRA]: {
name: 'Jira',
description: t(`setting.${DataSourceKey.JIRA}Description`),
icon: <SvgIcon name={'data-source/jira'} width={38} />,
},
[DataSourceKey.WEBDAV]: {
name: 'WebDAV',
description: t(`setting.${DataSourceKey.WEBDAV}Description`),
icon: <SvgIcon name={'data-source/webdav'} width={38} />,
},
[DataSourceKey.DROPBOX]: {
name: 'Dropbox',
description: t(`setting.${DataSourceKey.DROPBOX}Description`),
icon: <SvgIcon name={'data-source/dropbox'} width={38} />,
},
[DataSourceKey.BOX]: {
name: 'Box',
description: t(`setting.${DataSourceKey.BOX}Description`),
icon: <SvgIcon name={'data-source/box'} width={38} />,
},
export const generateDataSourceInfo = (t: TFunction) => {
return {
[DataSourceKey.S3]: {
name: 'S3',
description: t(`setting.${DataSourceKey.S3}Description`),
icon: <SvgIcon name={'data-source/s3'} width={38} />,
},
[DataSourceKey.NOTION]: {
name: 'Notion',
description: t(`setting.${DataSourceKey.NOTION}Description`),
icon: <SvgIcon name={'data-source/notion'} width={38} />,
},
[DataSourceKey.DISCORD]: {
name: 'Discord',
description: t(`setting.${DataSourceKey.DISCORD}Description`),
icon: <SvgIcon name={'data-source/discord'} width={38} />,
},
[DataSourceKey.CONFLUENCE]: {
name: 'Confluence',
description: t(`setting.${DataSourceKey.CONFLUENCE}Description`),
icon: <SvgIcon name={'data-source/confluence'} width={38} />,
},
[DataSourceKey.GOOGLE_DRIVE]: {
name: 'Google Drive',
description: t(`setting.${DataSourceKey.GOOGLE_DRIVE}Description`),
icon: <SvgIcon name={'data-source/google-drive'} width={38} />,
},
[DataSourceKey.GMAIL]: {
name: 'Gmail',
description: t(`setting.${DataSourceKey.GMAIL}Description`),
icon: <SvgIcon name={'data-source/gmail'} width={38} />,
},
[DataSourceKey.MOODLE]: {
name: 'Moodle',
description: t(`setting.${DataSourceKey.MOODLE}Description`),
icon: <SvgIcon name={'data-source/moodle'} width={38} />,
},
[DataSourceKey.JIRA]: {
name: 'Jira',
description: t(`setting.${DataSourceKey.JIRA}Description`),
icon: <SvgIcon name={'data-source/jira'} width={38} />,
},
[DataSourceKey.WEBDAV]: {
name: 'WebDAV',
description: t(`setting.${DataSourceKey.WEBDAV}Description`),
icon: <SvgIcon name={'data-source/webdav'} width={38} />,
},
[DataSourceKey.DROPBOX]: {
name: 'Dropbox',
description: t(`setting.${DataSourceKey.DROPBOX}Description`),
icon: <SvgIcon name={'data-source/dropbox'} width={38} />,
},
[DataSourceKey.BOX]: {
name: 'Box',
description: t(`setting.${DataSourceKey.BOX}Description`),
icon: <SvgIcon name={'data-source/box'} width={38} />,
},
};
};
export const useDataSourceInfo = () => {
const { t } = useTranslation();
const [dataSourceInfo, setDataSourceInfo] = useState<IDataSourceInfoMap>(
generateDataSourceInfo(t) as IDataSourceInfoMap,
);
useEffect(() => {
setDataSourceInfo(generateDataSourceInfo(t));
}, [t]);
return { dataSourceInfo };
};
export const DataSourceFormBaseFields = [

View File

@@ -18,7 +18,7 @@ import {
DataSourceFormBaseFields,
DataSourceFormDefaultValues,
DataSourceFormFields,
DataSourceInfo,
useDataSourceInfo,
} from '../contant';
import {
useAddDataSource,
@@ -32,10 +32,10 @@ const SourceDetailPage = () => {
const { data: detail } = useFetchDataSourceDetail();
const { handleResume } = useDataSourceResume();
const { dataSourceInfo } = useDataSourceInfo();
const detailInfo = useMemo(() => {
if (detail) {
return DataSourceInfo[detail.source];
return dataSourceInfo[detail.source];
}
}, [detail]);

View File

@@ -12,10 +12,11 @@ import { useQuery, useQueryClient } from '@tanstack/react-query';
import { t } from 'i18next';
import { useCallback, useMemo, useState } from 'react';
import { useParams, useSearchParams } from 'umi';
import { DataSourceInfo, DataSourceKey } from './contant';
import { DataSourceKey, useDataSourceInfo } from './contant';
import { IDataSorceInfo, IDataSource, IDataSourceBase } from './interface';
export const useListDataSource = () => {
const { dataSourceInfo } = useDataSourceInfo();
const { data: list, isFetching } = useQuery<IDataSource[]>({
queryKey: ['data-source'],
queryFn: async () => {
@@ -49,12 +50,12 @@ export const useListDataSource = () => {
[];
Object.keys(categorizedData).forEach((key: string) => {
const k = key as DataSourceKey;
if (DataSourceInfo[k]) {
if (dataSourceInfo[k]) {
sourceList.push({
id: k,
name: DataSourceInfo[k].name,
description: DataSourceInfo[k].description,
icon: DataSourceInfo[k].icon,
name: dataSourceInfo[k].name,
description: dataSourceInfo[k].description,
icon: dataSourceInfo[k].icon,
list: categorizedData[k] || [],
});
}

View File

@@ -10,21 +10,21 @@ import {
} from '../components/user-setting-header';
import AddDataSourceModal from './add-datasource-modal';
import { AddedSourceCard } from './component/added-source-card';
import { DataSourceInfo, DataSourceKey } from './contant';
import { DataSourceKey, useDataSourceInfo } from './contant';
import { useAddDataSource, useListDataSource } from './hooks';
import { IDataSorceInfo } from './interface';
const dataSourceTemplates = Object.values(DataSourceKey).map((id) => {
return {
id,
name: DataSourceInfo[id].name,
description: DataSourceInfo[id].description,
icon: DataSourceInfo[id].icon,
};
});
const DataSource = () => {
const { t } = useTranslation();
const { dataSourceInfo } = useDataSourceInfo();
const dataSourceTemplates = Object.values(DataSourceKey).map((id) => {
return {
id,
name: dataSourceInfo[id].name,
description: dataSourceInfo[id].description,
icon: dataSourceInfo[id].icon,
};
});
// useListTenantUser();
const { categorizedList } = useListDataSource();

View File

@@ -43,3 +43,11 @@ export interface IDataSourceLog {
tenant_id: string;
timeout_secs: number;
}
interface IDataSourceInfoItem {
name: string;
description: string;
icon: JSX.Element;
}
export type IDataSourceInfoMap = Record<DataSourceKey, IDataSourceInfoItem>;