mirror of
https://git.mirrors.martin98.com/https://github.com/infiniflow/ragflow.git
synced 2025-06-04 11:24:00 +08:00
### What problem does this PR solve? Feat: Rename a dataset #3221 ### Type of change - [x] New Feature (non-breaking change which adds functionality)
This commit is contained in:
parent
ad220a0a3c
commit
e7f83b13ca
@ -78,13 +78,15 @@ const DropdownMenuItem = React.forwardRef<
|
||||
React.ElementRef<typeof DropdownMenuPrimitive.Item>,
|
||||
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Item> & {
|
||||
inset?: boolean;
|
||||
justifyBetween?: boolean;
|
||||
}
|
||||
>(({ className, inset, ...props }, ref) => (
|
||||
>(({ className, inset, justifyBetween = true, ...props }, ref) => (
|
||||
<DropdownMenuPrimitive.Item
|
||||
ref={ref}
|
||||
className={cn(
|
||||
'relative flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0',
|
||||
inset && 'pl-8',
|
||||
justifyBetween && 'flex justify-between',
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
|
@ -180,7 +180,7 @@ export const useDeleteKnowledge = () => {
|
||||
|
||||
//#region knowledge configuration
|
||||
|
||||
export const useUpdateKnowledge = () => {
|
||||
export const useUpdateKnowledge = (shouldFetchList = false) => {
|
||||
const knowledgeBaseId = useKnowledgeBaseId();
|
||||
const queryClient = useQueryClient();
|
||||
const {
|
||||
@ -191,12 +191,18 @@ export const useUpdateKnowledge = () => {
|
||||
mutationKey: ['saveKnowledge'],
|
||||
mutationFn: async (params: Record<string, any>) => {
|
||||
const { data = {} } = await kbService.updateKb({
|
||||
kb_id: knowledgeBaseId,
|
||||
kb_id: params?.kb_id ? params?.kb_id : knowledgeBaseId,
|
||||
...params,
|
||||
});
|
||||
if (data.code === 0) {
|
||||
message.success(i18n.t(`message.updated`));
|
||||
queryClient.invalidateQueries({ queryKey: ['fetchKnowledgeDetail'] });
|
||||
if (shouldFetchList) {
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: ['infiniteFetchKnowledgeList'],
|
||||
});
|
||||
} else {
|
||||
queryClient.invalidateQueries({ queryKey: ['fetchKnowledgeDetail'] });
|
||||
}
|
||||
}
|
||||
return data;
|
||||
},
|
||||
|
@ -23,7 +23,7 @@ import { z } from 'zod';
|
||||
|
||||
const FormId = 'dataset-creating-form';
|
||||
|
||||
export function InputForm() {
|
||||
export function InputForm({ onOk }: IModalProps<any>) {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const FormSchema = z.object({
|
||||
@ -43,7 +43,7 @@ export function InputForm() {
|
||||
});
|
||||
|
||||
function onSubmit(data: z.infer<typeof FormSchema>) {
|
||||
console.log('🚀 ~ onSubmit ~ data:', data);
|
||||
onOk?.(data.name);
|
||||
}
|
||||
|
||||
return (
|
||||
@ -74,7 +74,7 @@ export function InputForm() {
|
||||
);
|
||||
}
|
||||
|
||||
export function DatasetCreatingDialog({ hideModal }: IModalProps<any>) {
|
||||
export function DatasetCreatingDialog({ hideModal, onOk }: IModalProps<any>) {
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
@ -83,7 +83,7 @@ export function DatasetCreatingDialog({ hideModal }: IModalProps<any>) {
|
||||
<DialogHeader>
|
||||
<DialogTitle>{t('knowledgeList.createKnowledgeBase')}</DialogTitle>
|
||||
</DialogHeader>
|
||||
<InputForm></InputForm>
|
||||
<InputForm onOk={onOk}></InputForm>
|
||||
<DialogFooter>
|
||||
<Button type="submit" variant={'tertiary'} size={'sm'} form={FormId}>
|
||||
{t('common.save')}
|
||||
|
54
web/src/pages/datasets/dataset-dropdown.tsx
Normal file
54
web/src/pages/datasets/dataset-dropdown.tsx
Normal file
@ -0,0 +1,54 @@
|
||||
import { ConfirmDeleteDialog } from '@/components/confirm-delete-dialog';
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuSeparator,
|
||||
DropdownMenuTrigger,
|
||||
} from '@/components/ui/dropdown-menu';
|
||||
import { useDeleteKnowledge } from '@/hooks/knowledge-hooks';
|
||||
import { IKnowledge } from '@/interfaces/database/knowledge';
|
||||
import { PenLine, Trash2 } from 'lucide-react';
|
||||
import { PropsWithChildren, useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useRenameDataset } from './use-rename-dataset';
|
||||
|
||||
export function DatasetDropdown({
|
||||
children,
|
||||
showDatasetRenameModal,
|
||||
dataset,
|
||||
}: PropsWithChildren &
|
||||
Pick<ReturnType<typeof useRenameDataset>, 'showDatasetRenameModal'> & {
|
||||
dataset: IKnowledge;
|
||||
}) {
|
||||
const { t } = useTranslation();
|
||||
const { deleteKnowledge } = useDeleteKnowledge();
|
||||
|
||||
const handleShowDatasetRenameModal = useCallback(() => {
|
||||
showDatasetRenameModal(dataset);
|
||||
}, [dataset, showDatasetRenameModal]);
|
||||
|
||||
const handleDelete = useCallback(() => {
|
||||
deleteKnowledge(dataset.id);
|
||||
}, [dataset.id, deleteKnowledge]);
|
||||
|
||||
return (
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>{children}</DropdownMenuTrigger>
|
||||
<DropdownMenuContent>
|
||||
<DropdownMenuItem onClick={handleShowDatasetRenameModal}>
|
||||
{t('common.rename')} <PenLine />
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuSeparator />
|
||||
<ConfirmDeleteDialog onOk={handleDelete}>
|
||||
<DropdownMenuItem
|
||||
className="text-text-delete-red"
|
||||
onSelect={(e) => e.preventDefault()}
|
||||
>
|
||||
{t('common.delete')} <Trash2 />
|
||||
</DropdownMenuItem>
|
||||
</ConfirmDeleteDialog>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
);
|
||||
}
|
@ -1,8 +1,7 @@
|
||||
import { KnowledgeRouteKey } from '@/constants/knowledge';
|
||||
import { useSetModalState } from '@/hooks/common-hooks';
|
||||
import { useCreateKnowledge } from '@/hooks/knowledge-hooks';
|
||||
import { useNavigatePage } from '@/hooks/logic-hooks/navigate-hooks';
|
||||
import { useCallback, useState } from 'react';
|
||||
import { useNavigate } from 'umi';
|
||||
|
||||
export const useSearchKnowledge = () => {
|
||||
const [searchString, setSearchString] = useState<string>('');
|
||||
@ -19,7 +18,7 @@ export const useSearchKnowledge = () => {
|
||||
export const useSaveKnowledge = () => {
|
||||
const { visible: visible, hideModal, showModal } = useSetModalState();
|
||||
const { loading, createKnowledge } = useCreateKnowledge();
|
||||
const navigate = useNavigate();
|
||||
const { navigateToDataset } = useNavigatePage();
|
||||
|
||||
const onCreateOk = useCallback(
|
||||
async (name: string) => {
|
||||
@ -29,12 +28,10 @@ export const useSaveKnowledge = () => {
|
||||
|
||||
if (ret?.code === 0) {
|
||||
hideModal();
|
||||
navigate(
|
||||
`/knowledge/${KnowledgeRouteKey.Configuration}?id=${ret.data.kb_id}`,
|
||||
);
|
||||
navigateToDataset(ret.data.kb_id)();
|
||||
}
|
||||
},
|
||||
[createKnowledge, hideModal, navigate],
|
||||
[createKnowledge, hideModal, navigateToDataset],
|
||||
);
|
||||
|
||||
return {
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { ConfirmDeleteDialog } from '@/components/confirm-delete-dialog';
|
||||
import ListFilterBar from '@/components/list-filter-bar';
|
||||
import { RenameDialog } from '@/components/rename-dialog';
|
||||
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Card, CardContent } from '@/components/ui/card';
|
||||
@ -7,10 +7,12 @@ import { useInfiniteFetchKnowledgeList } from '@/hooks/knowledge-hooks';
|
||||
import { useNavigatePage } from '@/hooks/logic-hooks/navigate-hooks';
|
||||
import { IKnowledge } from '@/interfaces/database/knowledge';
|
||||
import { formatDate } from '@/utils/date';
|
||||
import { ChevronRight, Plus, Trash2 } from 'lucide-react';
|
||||
import { ChevronRight, Ellipsis, Plus } from 'lucide-react';
|
||||
import { useMemo } from 'react';
|
||||
import { DatasetCreatingDialog } from './dataset-creating-dialog';
|
||||
import { DatasetDropdown } from './dataset-dropdown';
|
||||
import { useSaveKnowledge } from './hooks';
|
||||
import { useRenameDataset } from './use-rename-dataset';
|
||||
|
||||
export default function Datasets() {
|
||||
const {
|
||||
@ -41,6 +43,15 @@ export default function Datasets() {
|
||||
return data?.pages.at(-1).total ?? 0;
|
||||
}, [data?.pages]);
|
||||
|
||||
const {
|
||||
datasetRenameLoading,
|
||||
initialDatasetName,
|
||||
onDatasetRenameOk,
|
||||
datasetRenameVisible,
|
||||
hideDatasetRenameModal,
|
||||
showDatasetRenameModal,
|
||||
} = useRenameDataset();
|
||||
|
||||
return (
|
||||
<section className="p-8 text-foreground">
|
||||
<ListFilterBar title="Datasets" showDialog={showModal}>
|
||||
@ -59,11 +70,14 @@ export default function Datasets() {
|
||||
<AvatarImage src={dataset.avatar} />
|
||||
<AvatarFallback className="rounded-lg">CN</AvatarFallback>
|
||||
</Avatar>
|
||||
<ConfirmDeleteDialog>
|
||||
<DatasetDropdown
|
||||
showDatasetRenameModal={showDatasetRenameModal}
|
||||
dataset={dataset}
|
||||
>
|
||||
<Button variant="ghost" size="icon">
|
||||
<Trash2 />
|
||||
<Ellipsis />
|
||||
</Button>
|
||||
</ConfirmDeleteDialog>
|
||||
</DatasetDropdown>
|
||||
</div>
|
||||
<div className="flex justify-between items-end">
|
||||
<div>
|
||||
@ -92,6 +106,14 @@ export default function Datasets() {
|
||||
loading={creatingLoading}
|
||||
></DatasetCreatingDialog>
|
||||
)}
|
||||
{datasetRenameVisible && (
|
||||
<RenameDialog
|
||||
hideModal={hideDatasetRenameModal}
|
||||
onOk={onDatasetRenameOk}
|
||||
initialName={initialDatasetName}
|
||||
loading={datasetRenameLoading}
|
||||
></RenameDialog>
|
||||
)}
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
47
web/src/pages/datasets/use-rename-dataset.ts
Normal file
47
web/src/pages/datasets/use-rename-dataset.ts
Normal file
@ -0,0 +1,47 @@
|
||||
import { useSetModalState } from '@/hooks/common-hooks';
|
||||
import { useUpdateKnowledge } from '@/hooks/knowledge-hooks';
|
||||
import { IKnowledge } from '@/interfaces/database/knowledge';
|
||||
import { omit } from 'lodash';
|
||||
import { useCallback, useState } from 'react';
|
||||
|
||||
export const useRenameDataset = () => {
|
||||
const [dataset, setDataset] = useState<IKnowledge>({} as IKnowledge);
|
||||
const {
|
||||
visible: datasetRenameVisible,
|
||||
hideModal: hideDatasetRenameModal,
|
||||
showModal: showDatasetRenameModal,
|
||||
} = useSetModalState();
|
||||
const { saveKnowledgeConfiguration, loading } = useUpdateKnowledge(true);
|
||||
|
||||
const onDatasetRenameOk = useCallback(
|
||||
async (name: string) => {
|
||||
const ret = await saveKnowledgeConfiguration({
|
||||
...omit(dataset, ['id', 'update_time', 'nickname', 'tenant_avatar']),
|
||||
kb_id: dataset.id,
|
||||
name,
|
||||
});
|
||||
|
||||
if (ret.code === 0) {
|
||||
hideDatasetRenameModal();
|
||||
}
|
||||
},
|
||||
[saveKnowledgeConfiguration, dataset, hideDatasetRenameModal],
|
||||
);
|
||||
|
||||
const handleShowDatasetRenameModal = useCallback(
|
||||
async (record: IKnowledge) => {
|
||||
setDataset(record);
|
||||
showDatasetRenameModal();
|
||||
},
|
||||
[showDatasetRenameModal],
|
||||
);
|
||||
|
||||
return {
|
||||
datasetRenameLoading: loading,
|
||||
initialDatasetName: dataset?.name,
|
||||
onDatasetRenameOk,
|
||||
datasetRenameVisible,
|
||||
hideDatasetRenameModal,
|
||||
showDatasetRenameModal: handleShowDatasetRenameModal,
|
||||
};
|
||||
};
|
@ -40,6 +40,7 @@ module.exports = {
|
||||
'colors-text-inverse-strong': 'var(--colors-text-inverse-strong)',
|
||||
'colors-text-persist-light': 'var(--colors-text-persist-light)',
|
||||
'colors-text-inverse-weak': 'var(--colors-text-inverse-weak)',
|
||||
'text-delete-red': 'var(--text-delete-red)',
|
||||
|
||||
primary: {
|
||||
DEFAULT: 'hsl(var(--primary))',
|
||||
|
@ -61,6 +61,7 @@
|
||||
--colors-text-inverse-strong: rgba(255, 255, 255, 1);
|
||||
--colors-text-persist-light: rgba(255, 255, 255, 1);
|
||||
--colors-text-inverse-weak: rgba(184, 181, 203, 1);
|
||||
--text-delete-red: rgba(216, 73, 75, 1);
|
||||
|
||||
--sidebar-background: 0 0% 98%;
|
||||
--sidebar-foreground: 240 5.3% 26.1%;
|
||||
@ -153,6 +154,7 @@
|
||||
--colors-text-inverse-strong: rgba(17, 16, 23, 1);
|
||||
--colors-text-persist-light: rgba(255, 255, 255, 1);
|
||||
--colors-text-inverse-weak: rgba(84, 80, 106, 1);
|
||||
--text-delete-red: rgba(216, 73, 75, 1);
|
||||
|
||||
--sidebar-background: 240 5.9% 10%;
|
||||
--sidebar-foreground: 240 4.8% 95.9%;
|
||||
|
Loading…
x
Reference in New Issue
Block a user