Feat: Add DatasetTable #3221 (#3743)

### What problem does this PR solve?

Feat: Add DatasetTable #3221

### Type of change


- [x] New Feature (non-breaking change which adds functionality)
This commit is contained in:
balibabu 2024-11-29 16:05:46 +08:00 committed by GitHub
parent 1e0fc76efa
commit c93e0355c3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 132 additions and 98 deletions

View File

@ -11,7 +11,7 @@ const Switch = React.forwardRef<
>(({ className, ...props }, ref) => ( >(({ className, ...props }, ref) => (
<SwitchPrimitives.Root <SwitchPrimitives.Root
className={cn( className={cn(
'peer inline-flex h-6 w-11 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=unchecked]:bg-input', 'peer inline-flex h-6 w-11 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-colors-background-core-standard data-[state=unchecked]:bg-colors-background-inverse-standard',
className, className,
)} )}
{...props} {...props}
@ -19,7 +19,7 @@ const Switch = React.forwardRef<
> >
<SwitchPrimitives.Thumb <SwitchPrimitives.Thumb
className={cn( className={cn(
'pointer-events-none block h-5 w-5 rounded-full bg-background shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-5 data-[state=unchecked]:translate-x-0', 'pointer-events-none block h-5 w-5 rounded-full bg-colors-text-neutral-strong shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-5 data-[state=unchecked]:translate-x-0',
)} )}
/> />
</SwitchPrimitives.Root> </SwitchPrimitives.Root>

View File

@ -3,7 +3,7 @@ import { Header } from './next-header';
export default function NextLayout() { export default function NextLayout() {
return ( return (
<section> <section className="h-full flex flex-col">
<Header></Header> <Header></Header>
<Outlet /> <Outlet />
</section> </section>

View File

@ -12,7 +12,7 @@ import {
getSortedRowModel, getSortedRowModel,
useReactTable, useReactTable,
} from '@tanstack/react-table'; } from '@tanstack/react-table';
import { ArrowUpDown, MoreHorizontal } from 'lucide-react'; import { ArrowUpDown, MoreHorizontal, Pencil } from 'lucide-react';
import * as React from 'react'; import * as React from 'react';
import { Button } from '@/components/ui/button'; import { Button } from '@/components/ui/button';
@ -25,6 +25,7 @@ import {
DropdownMenuSeparator, DropdownMenuSeparator,
DropdownMenuTrigger, DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu'; } from '@/components/ui/dropdown-menu';
import { Switch } from '@/components/ui/switch';
import { import {
Table, Table,
TableBody, TableBody,
@ -35,6 +36,7 @@ import {
} from '@/components/ui/table'; } from '@/components/ui/table';
import { RunningStatus } from '@/constants/knowledge'; import { RunningStatus } from '@/constants/knowledge';
import { IDocumentInfo } from '@/interfaces/database/document'; import { IDocumentInfo } from '@/interfaces/database/document';
import { useTranslation } from 'react-i18next';
const data: IDocumentInfo[] = [ const data: IDocumentInfo[] = [
{ {
@ -68,7 +70,19 @@ const data: IDocumentInfo[] = [
}, },
]; ];
export const columns: ColumnDef<IDocumentInfo>[] = [ export function DatasetTable() {
const [sorting, setSorting] = React.useState<SortingState>([]);
const [columnFilters, setColumnFilters] = React.useState<ColumnFiltersState>(
[],
);
const [columnVisibility, setColumnVisibility] =
React.useState<VisibilityState>({});
const [rowSelection, setRowSelection] = React.useState({});
const { t } = useTranslation('translation', {
keyPrefix: 'knowledgeDetails',
});
const columns: ColumnDef<IDocumentInfo>[] = [
{ {
id: 'select', id: 'select',
header: ({ table }) => ( header: ({ table }) => (
@ -92,53 +106,71 @@ export const columns: ColumnDef<IDocumentInfo>[] = [
enableHiding: false, enableHiding: false,
}, },
{ {
accessorKey: 'status', accessorKey: 'name',
header: 'Status',
cell: ({ row }) => (
<div className="capitalize">{row.getValue('status')}</div>
),
},
{
accessorKey: 'email',
header: ({ column }) => { header: ({ column }) => {
return ( return (
<Button <Button
variant="ghost" variant="ghost"
onClick={() => column.toggleSorting(column.getIsSorted() === 'asc')} onClick={() => column.toggleSorting(column.getIsSorted() === 'asc')}
> >
Email {t('name')}
<ArrowUpDown /> <ArrowUpDown />
</Button> </Button>
); );
}, },
cell: ({ row }) => <div className="lowercase">{row.getValue('email')}</div>, cell: ({ row }) => (
<div className="capitalize">{row.getValue('name')}</div>
),
}, },
{ {
accessorKey: 'amount', accessorKey: 'create_time',
header: () => <div className="text-right">Amount</div>, header: ({ column }) => {
cell: ({ row }) => { return (
const amount = parseFloat(row.getValue('amount')); <Button
variant="ghost"
// Format the amount as a dollar amount onClick={() => column.toggleSorting(column.getIsSorted() === 'asc')}
const formatted = new Intl.NumberFormat('en-US', { >
style: 'currency', {t('uploadDate')}
currency: 'USD', <ArrowUpDown />
}).format(amount); </Button>
);
return <div className="text-right font-medium">{formatted}</div>;
}, },
cell: ({ row }) => (
<div className="lowercase">{row.getValue('create_time')}</div>
),
},
{
accessorKey: 'parser_id',
header: t('chunkMethod'),
cell: ({ row }) => (
<div className="capitalize">{row.getValue('parser_id')}</div>
),
},
{
accessorKey: 'run',
header: t('parsingStatus'),
cell: ({ row }) => (
<Button variant="destructive" size={'sm'}>
{row.getValue('run')}
</Button>
),
}, },
{ {
id: 'actions', id: 'actions',
header: t('action'),
enableHiding: false, enableHiding: false,
cell: ({ row }) => { cell: ({ row }) => {
const payment = row.original; const payment = row.original;
return ( return (
<section className="flex gap-4 items-center">
<Switch id="airplane-mode" />
<Button variant="secondary" size={'icon'}>
<Pencil />
</Button>
<DropdownMenu> <DropdownMenu>
<DropdownMenuTrigger asChild> <DropdownMenuTrigger asChild>
<Button variant="ghost" className="h-8 w-8 p-0"> <Button variant="secondary" size={'icon'}>
<span className="sr-only">Open menu</span>
<MoreHorizontal /> <MoreHorizontal />
</Button> </Button>
</DropdownMenuTrigger> </DropdownMenuTrigger>
@ -154,19 +186,11 @@ export const columns: ColumnDef<IDocumentInfo>[] = [
<DropdownMenuItem>View payment details</DropdownMenuItem> <DropdownMenuItem>View payment details</DropdownMenuItem>
</DropdownMenuContent> </DropdownMenuContent>
</DropdownMenu> </DropdownMenu>
</section>
); );
}, },
}, },
]; ];
export function DatasetTable() {
const [sorting, setSorting] = React.useState<SortingState>([]);
const [columnFilters, setColumnFilters] = React.useState<ColumnFiltersState>(
[],
);
const [columnVisibility, setColumnVisibility] =
React.useState<VisibilityState>({});
const [rowSelection, setRowSelection] = React.useState({});
const table = useReactTable({ const table = useReactTable({
data, data,

View File

@ -3,7 +3,7 @@ import { SideBar } from './sidebar';
export default function DatasetWrapper() { export default function DatasetWrapper() {
return ( return (
<div className="text-foreground flex"> <div className="text-foreground flex flex-1">
<SideBar></SideBar> <SideBar></SideBar>
<div className="flex-1"> <div className="flex-1">
<Outlet /> <Outlet />

View File

@ -2,7 +2,7 @@ import { Button } from '@/components/ui/button';
import { KnowledgeRouteKey } from '@/constants/knowledge'; import { KnowledgeRouteKey } from '@/constants/knowledge';
import { useSecondPathName } from '@/hooks/route-hook'; import { useSecondPathName } from '@/hooks/route-hook';
import { cn } from '@/lib/utils'; import { cn } from '@/lib/utils';
import { Banknote, LayoutGrid, User } from 'lucide-react'; import { Banknote, LayoutGrid, Trash2, User } from 'lucide-react';
import { useHandleMenuClick } from './hooks'; import { useHandleMenuClick } from './hooks';
const items = [ const items = [
@ -29,7 +29,7 @@ export function SideBar() {
const { handleMenuClick } = useHandleMenuClick(); const { handleMenuClick } = useHandleMenuClick();
return ( return (
<aside className="w-[303px]"> <aside className="w-[303px] relative">
<div className="p-6 space-y-2 border-b"> <div className="p-6 space-y-2 border-b">
<div <div
className="w-[70px] h-[70px] rounded-xl bg-cover" className="w-[70px] h-[70px] rounded-xl bg-cover"
@ -61,6 +61,13 @@ export function SideBar() {
); );
})} })}
</div> </div>
<Button
variant="outline"
className="absolute bottom-6 left-6 right-6 text-colors-text-functional-danger border-colors-text-functional-danger"
>
<Trash2 />
Delete dataset
</Button>
</aside> </aside>
); );
} }

View File

@ -33,6 +33,7 @@ module.exports = {
'colors-text-core-standard': 'var(--colors-text-core-standard)', 'colors-text-core-standard': 'var(--colors-text-core-standard)',
'colors-text-neutral-strong': 'var(--colors-text-neutral-strong)', 'colors-text-neutral-strong': 'var(--colors-text-neutral-strong)',
'colors-text-neutral-standard': 'var(--colors-text-neutral-standard)', 'colors-text-neutral-standard': 'var(--colors-text-neutral-standard)',
'colors-text-functional-danger': 'var(--colors-text-functional-danger)',
primary: { primary: {
DEFAULT: 'hsl(var(--primary))', DEFAULT: 'hsl(var(--primary))',

View File

@ -46,6 +46,7 @@
--colors-text-core-standard: rgba(127, 105, 255, 1); --colors-text-core-standard: rgba(127, 105, 255, 1);
--colors-text-neutral-strong: rgb(130, 121, 121); --colors-text-neutral-strong: rgb(130, 121, 121);
--colors-text-neutral-standard: rgba(230, 227, 246, 1); --colors-text-neutral-standard: rgba(230, 227, 246, 1);
--colors-text-functional-danger: rgba(255, 81, 81, 1);
} }
.dark { .dark {
@ -122,6 +123,7 @@
--colors-text-core-standard: rgba(137, 126, 255, 1); --colors-text-core-standard: rgba(137, 126, 255, 1);
--colors-text-neutral-strong: rgba(255, 255, 255, 1); --colors-text-neutral-strong: rgba(255, 255, 255, 1);
--colors-text-neutral-standard: rgba(230, 227, 246, 1); --colors-text-neutral-standard: rgba(230, 227, 246, 1);
--colors-text-functional-danger: rgba(255, 81, 81, 1);
} }
} }