Feat: Modify the style of the dataset page #3221 (#7446)

### What problem does this PR solve?

Feat:  Modify the style of the dataset page #3221

### Type of change


- [x] New Feature (non-breaking change which adds functionality)
This commit is contained in:
balibabu
2025-05-02 21:27:21 +08:00
committed by GitHub
parent fc379e90d1
commit cb37f00a8f
16 changed files with 211 additions and 153 deletions

View File

@ -119,59 +119,51 @@ export function DatasetTable({
return (
<div className="w-full">
<div className="rounded-md border">
<Table>
<TableHeader>
{table.getHeaderGroups().map((headerGroup) => (
<TableRow key={headerGroup.id}>
{headerGroup.headers.map((header) => {
return (
<TableHead key={header.id}>
{header.isPlaceholder
? null
: flexRender(
header.column.columnDef.header,
header.getContext(),
)}
</TableHead>
);
})}
<Table>
<TableHeader>
{table.getHeaderGroups().map((headerGroup) => (
<TableRow key={headerGroup.id}>
{headerGroup.headers.map((header) => {
return (
<TableHead key={header.id}>
{header.isPlaceholder
? null
: flexRender(
header.column.columnDef.header,
header.getContext(),
)}
</TableHead>
);
})}
</TableRow>
))}
</TableHeader>
<TableBody className="relative">
{table.getRowModel().rows?.length ? (
table.getRowModel().rows.map((row) => (
<TableRow
key={row.id}
data-state={row.getIsSelected() && 'selected'}
>
{row.getVisibleCells().map((cell) => (
<TableCell
key={cell.id}
className={cell.column.columnDef.meta?.cellClassName}
>
{flexRender(cell.column.columnDef.cell, cell.getContext())}
</TableCell>
))}
</TableRow>
))}
</TableHeader>
<TableBody className="relative">
{table.getRowModel().rows?.length ? (
table.getRowModel().rows.map((row) => (
<TableRow
key={row.id}
data-state={row.getIsSelected() && 'selected'}
>
{row.getVisibleCells().map((cell) => (
<TableCell
key={cell.id}
className={cell.column.columnDef.meta?.cellClassName}
>
{flexRender(
cell.column.columnDef.cell,
cell.getContext(),
)}
</TableCell>
))}
</TableRow>
))
) : (
<TableRow>
<TableCell
colSpan={columns.length}
className="h-24 text-center"
>
No results.
</TableCell>
</TableRow>
)}
</TableBody>
</Table>
</div>
))
) : (
<TableRow>
<TableCell colSpan={columns.length} className="h-24 text-center">
No results.
</TableCell>
</TableRow>
)}
</TableBody>
</Table>
<div className="flex items-center justify-end space-x-2 py-4">
<div className="flex-1 text-sm text-muted-foreground">
{table.getFilteredSelectedRowModel().rows.length} of{' '}

View File

@ -60,7 +60,7 @@ export default function Dataset() {
});
return (
<section className="p-8">
<section className="p-5">
<ListFilterBar
title="Dataset"
onSearchChange={handleInputChange}

View File

@ -1,4 +1,4 @@
import SvgIcon from '@/components/svg-icon';
import { FileIcon } from '@/components/icon-font';
import { Button } from '@/components/ui/button';
import { Checkbox } from '@/components/ui/checkbox';
import { Switch } from '@/components/ui/switch';
@ -12,7 +12,6 @@ import { useSetDocumentStatus } from '@/hooks/use-document-request';
import { IDocumentInfo } from '@/interfaces/database/document';
import { cn } from '@/lib/utils';
import { formatDate } from '@/utils/date';
import { getExtension } from '@/utils/document-util';
import { ColumnDef } from '@tanstack/table-core';
import { ArrowUpDown } from 'lucide-react';
import { useTranslation } from 'react-i18next';
@ -88,10 +87,7 @@ export function useDatasetTableColumns({
row.original.kb_id,
)}
>
<SvgIcon
name={`file-icon/${getExtension(name)}`}
width={24}
></SvgIcon>
<FileIcon name={name}></FileIcon>
<span className={cn('truncate')}>{name}</span>
</div>
</TooltipTrigger>

View File

@ -1,55 +1,78 @@
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar';
import { RAGFlowAvatar } from '@/components/ragflow-avatar';
import { Button } from '@/components/ui/button';
import { useSecondPathName } from '@/hooks/route-hook';
import { useFetchKnowledgeBaseConfiguration } from '@/hooks/use-knowledge-request';
import { cn } from '@/lib/utils';
import { cn, formatBytes } from '@/lib/utils';
import { Routes } from '@/routes';
import { formatDate } from '@/utils/date';
import { Banknote, LayoutGrid, User } from 'lucide-react';
import { formatPureDate } from '@/utils/date';
import { Banknote, Database, FileSearch2 } from 'lucide-react';
import { useMemo } from 'react';
import { useTranslation } from 'react-i18next';
import { useHandleMenuClick } from './hooks';
const items = [
{ icon: User, label: 'Dataset', key: Routes.DatasetBase },
{
icon: LayoutGrid,
label: 'Retrieval testing',
key: Routes.DatasetTesting,
},
{ icon: Banknote, label: 'Settings', key: Routes.DatasetSetting },
];
export function SideBar() {
const pathName = useSecondPathName();
const { handleMenuClick } = useHandleMenuClick();
const { data } = useFetchKnowledgeBaseConfiguration();
const { t } = useTranslation();
const items = useMemo(() => {
return [
{
icon: Database,
label: t(`knowledgeDetails.dataset`),
key: Routes.DatasetBase,
},
{
icon: FileSearch2,
label: t(`knowledgeDetails.testing`),
key: Routes.DatasetTesting,
},
{
icon: Banknote,
label: t(`knowledgeDetails.configuration`),
key: Routes.DatasetSetting,
},
];
}, [t]);
return (
<aside className="w-60 relative border-r ">
<div className="p-6 space-y-2 border-b">
<Avatar className="size-20 rounded-lg">
<AvatarImage src={data.avatar} />
<AvatarFallback className="rounded-lg">CN</AvatarFallback>
</Avatar>
<h3 className="text-lg font-semibold mb-2 line-clamp-1">{data.name}</h3>
<div className="text-sm opacity-80">
{data.doc_num} files | {data.chunk_num} chunks
</div>
<div className="text-sm opacity-80">
Created {formatDate(data.create_time)}
<aside className="relative p-5 space-y-8">
<div className="flex gap-2.5 max-w-[200px] items-center">
<RAGFlowAvatar
avatar={data.avatar}
name={data.name}
className="size-16"
></RAGFlowAvatar>
<div className=" text-text-sub-title text-xs space-y-1">
<h3 className="text-lg font-semibold line-clamp-1 text-text-title">
{data.name}
</h3>
<div className="flex justify-between">
<span>{data.doc_num} files</span>
<span>{formatBytes(data.size)}</span>
</div>
<div>Created {formatPureDate(data.create_time)}</div>
</div>
</div>
<div className="mt-4">
<div className="w-[200px] flex flex-col gap-5">
{items.map((item, itemIdx) => {
const active = '/' + pathName === item.key;
return (
<Button
key={itemIdx}
variant={active ? 'secondary' : 'ghost'}
className={cn('w-full justify-start gap-2.5 p-6 relative')}
className={cn(
'w-full justify-start gap-2.5 px-3 relative h-10 text-text-sub-title-invert',
{
'bg-background-card': active,
'text-text-title': active,
},
)}
onClick={handleMenuClick(item.key)}
>
<item.icon className="w-6 h-6" />
<item.icon className="size-4" />
<span>{item.label}</span>
</Button>
);

View File

@ -14,8 +14,8 @@ import {
import { ArrowUpDown } from 'lucide-react';
import * as React from 'react';
import { FileIcon } from '@/components/icon-font';
import { RenameDialog } from '@/components/rename-dialog';
import SvgIcon from '@/components/svg-icon';
import { TableEmpty, TableSkeleton } from '@/components/table-skeleton';
import { Button } from '@/components/ui/button';
import { Checkbox } from '@/components/ui/checkbox';
@ -39,7 +39,6 @@ import { IFile } from '@/interfaces/database/file-manager';
import { cn } from '@/lib/utils';
import { formatFileSize } from '@/utils/common-util';
import { formatDate } from '@/utils/date';
import { getExtension } from '@/utils/document-util';
import { pick } from 'lodash';
import { useMemo } from 'react';
import { useTranslation } from 'react-i18next';
@ -148,10 +147,9 @@ export function FilesTable({
<Tooltip>
<TooltipTrigger asChild>
<div className="flex gap-2">
<SvgIcon
name={`file-icon/${isFolder ? 'folder' : getExtension(name)}`}
width={24}
></SvgIcon>
<span className="size-4">
<FileIcon name={name} type={type}></FileIcon>
</span>
<span
className={cn('truncate', { ['cursor-pointer']: isFolder })}
onClick={handleNameClick}
@ -262,54 +260,50 @@ export function FilesTable({
return (
<div className="w-full">
<div className="rounded-md border">
<Table>
<TableHeader>
{table.getHeaderGroups().map((headerGroup) => (
<TableRow key={headerGroup.id}>
{headerGroup.headers.map((header) => {
return (
<TableHead key={header.id}>
{header.isPlaceholder
? null
: flexRender(
header.column.columnDef.header,
header.getContext(),
)}
</TableHead>
);
})}
<Table>
<TableHeader>
{table.getHeaderGroups().map((headerGroup) => (
<TableRow key={headerGroup.id}>
{headerGroup.headers.map((header) => {
return (
<TableHead key={header.id}>
{header.isPlaceholder
? null
: flexRender(
header.column.columnDef.header,
header.getContext(),
)}
</TableHead>
);
})}
</TableRow>
))}
</TableHeader>
<TableBody>
{loading ? (
<TableSkeleton columnsLength={columns.length}></TableSkeleton>
) : table.getRowModel().rows?.length ? (
table.getRowModel().rows.map((row) => (
<TableRow
key={row.id}
data-state={row.getIsSelected() && 'selected'}
>
{row.getVisibleCells().map((cell) => (
<TableCell
key={cell.id}
className={cell.column.columnDef.meta?.cellClassName}
>
{flexRender(cell.column.columnDef.cell, cell.getContext())}
</TableCell>
))}
</TableRow>
))}
</TableHeader>
<TableBody>
{loading ? (
<TableSkeleton columnsLength={columns.length}></TableSkeleton>
) : table.getRowModel().rows?.length ? (
table.getRowModel().rows.map((row) => (
<TableRow
key={row.id}
data-state={row.getIsSelected() && 'selected'}
>
{row.getVisibleCells().map((cell) => (
<TableCell
key={cell.id}
className={cell.column.columnDef.meta?.cellClassName}
>
{flexRender(
cell.column.columnDef.cell,
cell.getContext(),
)}
</TableCell>
))}
</TableRow>
))
) : (
<TableEmpty columnsLength={columns.length}></TableEmpty>
)}
</TableBody>
</Table>
</div>
))
) : (
<TableEmpty columnsLength={columns.length}></TableEmpty>
)}
</TableBody>
</Table>
<div className="flex items-center justify-end space-x-2 py-4">
<div className="flex-1 text-sm text-muted-foreground">
{table.getFilteredSelectedRowModel().rows.length} of {total} row(s)

View File

@ -88,7 +88,7 @@ export default function Files() {
>
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant={'tertiary'} size={'sm'}>
<Button>
<Upload />
{t('knowledgeDetails.addFile')}
</Button>