Feat: Reconstruct the QueryTable of BeginForm using shandcn #3221 (#7807)

### What problem does this PR solve?

Feat: Reconstruct the QueryTable of BeginForm using shandcn #3221
### Type of change


- [x] New Feature (non-breaking change which adds functionality)
This commit is contained in:
balibabu 2025-05-23 12:31:05 +08:00 committed by GitHub
parent 53b991aa0e
commit 3f037c9786
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 164 additions and 65 deletions

View File

@ -17,7 +17,7 @@ import { useTranslation } from 'react-i18next';
import { AgentDialogueMode } from '../../constant'; import { AgentDialogueMode } from '../../constant';
import { INextOperatorForm } from '../../interface'; import { INextOperatorForm } from '../../interface';
import { ParameterDialog } from './parameter-dialog'; import { ParameterDialog } from './parameter-dialog';
import QueryTable from './query-table'; import { QueryTable } from './query-table';
import { useEditQueryRecord } from './use-edit-query'; import { useEditQueryRecord } from './use-edit-query';
const ModeOptions = buildSelectOptions([ const ModeOptions = buildSelectOptions([

View File

@ -1,9 +1,38 @@
import { DeleteOutlined, EditOutlined } from '@ant-design/icons'; 'use client';
import type { TableProps } from 'antd';
import { Collapse, Space, Table, Tooltip } from 'antd';
import { BeginQuery } from '../../interface';
import {
ColumnDef,
ColumnFiltersState,
SortingState,
VisibilityState,
flexRender,
getCoreRowModel,
getFilteredRowModel,
getPaginationRowModel,
getSortedRowModel,
useReactTable,
} from '@tanstack/react-table';
import { Pencil, Trash2 } from 'lucide-react';
import * as React from 'react';
import { TableEmpty } from '@/components/table-skeleton';
import { Button } from '@/components/ui/button';
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from '@/components/ui/table';
import {
Tooltip,
TooltipContent,
TooltipTrigger,
} from '@/components/ui/tooltip';
import { cn } from '@/lib/utils';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { BeginQuery } from '../../interface';
interface IProps { interface IProps {
data: BeginQuery[]; data: BeginQuery[];
@ -11,80 +40,150 @@ interface IProps {
showModal(index: number, record: BeginQuery): void; showModal(index: number, record: BeginQuery): void;
} }
const QueryTable = ({ data, deleteRecord, showModal }: IProps) => { export function QueryTable({ data, deleteRecord, showModal }: IProps) {
const { t } = useTranslation(); const { t } = useTranslation();
const columns: TableProps<BeginQuery>['columns'] = [ const [sorting, setSorting] = React.useState<SortingState>([]);
const [columnFilters, setColumnFilters] = React.useState<ColumnFiltersState>(
[],
);
const [columnVisibility, setColumnVisibility] =
React.useState<VisibilityState>({});
const columns: ColumnDef<BeginQuery>[] = [
{ {
title: 'Key', accessorKey: 'key',
dataIndex: 'key', header: 'key',
key: 'key', meta: { cellClassName: 'max-w-16' },
ellipsis: { cell: ({ row }) => {
showTitle: false, const key: string = row.getValue('key');
}, return (
render: (key) => ( <Tooltip>
<Tooltip placement="topLeft" title={key}> <TooltipTrigger asChild>
{key} <div className="truncate ">{key}</div>
</TooltipTrigger>
<TooltipContent>
<p>{key}</p>
</TooltipContent>
</Tooltip> </Tooltip>
), );
},
}, },
{ {
title: t('flow.name'), accessorKey: 'name',
dataIndex: 'name', header: t('flow.name'),
key: 'name', meta: { cellClassName: 'max-w-20' },
ellipsis: { cell: ({ row }) => {
showTitle: false, const name: string = row.getValue('name');
}, return (
render: (name) => ( <Tooltip>
<Tooltip placement="topLeft" title={name}> <TooltipTrigger asChild>
{name} <div className="truncate">{name}</div>
</TooltipTrigger>
<TooltipContent>
<p>{name}</p>
</TooltipContent>
</Tooltip> </Tooltip>
), );
},
}, },
{ {
title: t('flow.type'), accessorKey: 'type',
dataIndex: 'type', header: t('flow.type'),
key: 'type', cell: ({ row }) => <div>{row.getValue('type')}</div>,
}, },
{ {
title: t('flow.optional'), accessorKey: 'optional',
dataIndex: 'optional', header: t('flow.optional'),
key: 'optional', cell: ({ row }) => <div>{row.getValue('optional') ? 'Yes' : 'No'}</div>,
render: (optional) => (optional ? 'Yes' : 'No'),
}, },
{ {
title: t('common.action'), id: 'actions',
key: 'action', enableHiding: false,
render: (_, record, idx) => ( header: t('common.action'),
<Space> cell: ({ row }) => {
<EditOutlined onClick={() => showModal(idx, record)} /> const record = row.original;
<DeleteOutlined const idx = row.index;
className="cursor-pointer"
onClick={() => deleteRecord(idx)} return (
/> <div>
</Space> <Button variant={'ghost'} onClick={() => showModal(idx, record)}>
), <Pencil />
</Button>
<Button variant={'ghost'} onClick={() => deleteRecord(idx)}>
<Trash2 />
</Button>
</div>
);
},
}, },
]; ];
return ( const table = useReactTable({
<Collapse data,
defaultActiveKey={['1']} columns,
items={[ onSortingChange: setSorting,
{ onColumnFiltersChange: setColumnFilters,
key: '1', getCoreRowModel: getCoreRowModel(),
label: <span>{t('flow.input')}</span>, getPaginationRowModel: getPaginationRowModel(),
children: ( getSortedRowModel: getSortedRowModel(),
<Table<BeginQuery> getFilteredRowModel: getFilteredRowModel(),
columns={columns} onColumnVisibilityChange: setColumnVisibility,
dataSource={data} state: {
pagination={false} sorting,
/> columnFilters,
), columnVisibility,
}, },
]} });
/>
);
};
export default QueryTable; 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>
);
})}
</TableRow>
))}
</TableHeader>
<TableBody>
{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={cn(cell.column.columnDef.meta?.cellClassName)}
>
{flexRender(
cell.column.columnDef.cell,
cell.getContext(),
)}
</TableCell>
))}
</TableRow>
))
) : (
<TableEmpty columnsLength={columns.length}></TableEmpty>
)}
</TableBody>
</Table>
</div>
</div>
);
}