Feat: Bind data to the agent module of the home page #3221 (#7385)

### What problem does this PR solve?

Feat: Bind data to the agent module of the home page #3221

### Type of change


- [x] New Feature (non-breaking change which adds functionality)
This commit is contained in:
balibabu
2025-04-29 09:50:54 +08:00
committed by GitHub
parent c7310f7fb2
commit 5bb1c383ac
26 changed files with 260 additions and 187 deletions

View File

@ -1,3 +1,4 @@
import { cn } from '@/lib/utils';
import { ChevronDown } from 'lucide-react';
import React, {
ChangeEventHandler,
@ -38,7 +39,10 @@ export default function ListFilterBar({
value,
onChange,
filters,
}: PropsWithChildren<IProps & Omit<CheckboxFormMultipleProps, 'setOpen'>>) {
className,
}: PropsWithChildren<IProps & Omit<CheckboxFormMultipleProps, 'setOpen'>> & {
className?: string;
}) {
const filterCount = useMemo(() => {
return typeof value === 'object' && value !== null
? Object.values(value).reduce((pre, cur) => {
@ -48,7 +52,7 @@ export default function ListFilterBar({
}, [value]);
return (
<div className="flex justify-between mb-6 items-center">
<div className={cn('flex justify-between mb-6 items-center', className)}>
<span className="text-3xl font-bold ">{leftPanel || title}</span>
<div className="flex gap-4 items-center">
{showFilter && (

View File

@ -1,5 +1,5 @@
import { Loader2 } from 'lucide-react';
import { PropsWithChildren } from 'react';
import { SkeletonCard } from './skeleton-card';
import { TableCell, TableRow } from './ui/table';
type IProps = { columnsLength: number };
@ -7,17 +7,22 @@ type IProps = { columnsLength: number };
function Row({ children, columnsLength }: PropsWithChildren & IProps) {
return (
<TableRow>
<TableCell colSpan={columnsLength} className="h-24 text-center ">
<TableCell colSpan={columnsLength} className="h-24 text-center">
{children}
</TableCell>
</TableRow>
);
}
export function TableSkeleton({ columnsLength }: { columnsLength: number }) {
export function TableSkeleton({
columnsLength,
children,
}: PropsWithChildren & IProps) {
return (
<Row columnsLength={columnsLength}>
<SkeletonCard></SkeletonCard>
{children || (
<Loader2 className="animate-spin size-16 inline-block text-gray-400" />
)}
</Row>
);
}

View File

@ -99,14 +99,15 @@ export function AsyncTreeSelect({
<li
key={x.id}
onClick={handleNodeClick(x.id)}
className="cursor-pointer hover:bg-slate-50 "
className="cursor-pointer "
>
<div className={cn('flex justify-between items-center')}>
<span
className={cn({ 'bg-cyan-50': value === x.id }, 'flex-1')}
>
{x.title}
</span>
<div
className={cn(
'flex justify-between items-center hover:bg-accent py-0.5 px-1 rounded-md ',
{ 'bg-cyan-50': value === x.id },
)}
>
<span className={cn('flex-1 ')}>{x.title}</span>
{x.isLeaf || (
<Button
variant={'ghost'}
@ -146,10 +147,10 @@ export function AsyncTreeSelect({
{selectedTitle || (
<span className="text-slate-400">{t('common.pleaseSelect')}</span>
)}
<ChevronDown className="size-5" />
<ChevronDown className="size-5 " />
</div>
</PopoverTrigger>
<PopoverContent className="p-1">
<PopoverContent className="p-1 min-w-[var(--radix-popover-trigger-width)]">
<ul>{renderNodes()}</ul>
</PopoverContent>
</Popover>

View File

@ -0,0 +1,133 @@
import {
Pagination,
PaginationContent,
PaginationEllipsis,
PaginationItem,
PaginationLink,
PaginationNext,
PaginationPrevious,
} from '@/components/ui/pagination';
import { RAGFlowSelect, RAGFlowSelectOptionType } from '@/components/ui/select';
import { cn } from '@/lib/utils';
import { useCallback, useEffect, useMemo, useState } from 'react';
export type RAGFlowPaginationType = {
showQuickJumper?: boolean;
onChange?(page: number, pageSize: number): void;
total?: number;
current?: number;
pageSize?: number;
showSizeChanger?: boolean;
};
export function RAGFlowPagination({
current = 1,
pageSize = 10,
total = 0,
onChange,
showSizeChanger = true,
}: RAGFlowPaginationType) {
const [currentPage, setCurrentPage] = useState(1);
const [currentPageSize, setCurrentPageSize] = useState('10');
const sizeChangerOptions: RAGFlowSelectOptionType[] = useMemo(() => {
return [10, 20, 50, 100].map((x) => ({
label: <span>{x} / page</span>,
value: x.toString(),
}));
}, []);
const pages = useMemo(() => {
const num = Math.ceil(total / pageSize);
return new Array(num).fill(0).map((_, idx) => idx + 1);
}, [pageSize, total]);
const changePage = useCallback(
(page: number) => {
onChange?.(page, Number(currentPageSize));
},
[currentPageSize, onChange],
);
const handlePreviousPageChange = useCallback(() => {
setCurrentPage((page) => {
const previousPage = page - 1;
if (previousPage > 0) {
changePage(previousPage);
return previousPage;
}
changePage(page);
return page;
});
}, [changePage]);
const handlePageChange = useCallback(
(page: number) => () => {
changePage(page);
setCurrentPage(page);
},
[changePage],
);
const handleNextPageChange = useCallback(() => {
setCurrentPage((page) => {
const nextPage = page + 1;
if (nextPage <= pages.length) {
changePage(nextPage);
return nextPage;
}
changePage(page);
return page;
});
}, [changePage, pages.length]);
const handlePageSizeChange = useCallback(
(size: string) => {
onChange?.(currentPage, Number(size));
setCurrentPageSize(size);
},
[currentPage, onChange],
);
useEffect(() => {
setCurrentPage(current);
}, [current]);
useEffect(() => {
setCurrentPageSize(pageSize.toString());
}, [pageSize]);
return (
<section className="flex items-center justify-end">
<span className="mr-4">Total {total}</span>
<Pagination className="w-auto mx-0 mr-4">
<PaginationContent>
<PaginationItem>
<PaginationPrevious onClick={handlePreviousPageChange} />
</PaginationItem>
{pages.map((x) => (
<PaginationItem
key={x}
className={cn({ ['bg-accent rounded-md']: currentPage === x })}
>
<PaginationLink onClick={handlePageChange(x)}>{x}</PaginationLink>
</PaginationItem>
))}
<PaginationItem>
<PaginationEllipsis />
</PaginationItem>
<PaginationItem>
<PaginationNext onClick={handleNextPageChange} />
</PaginationItem>
</PaginationContent>
</Pagination>
{showSizeChanger && (
<RAGFlowSelect
options={sizeChangerOptions}
value={currentPageSize}
onChange={handlePageSizeChange}
></RAGFlowSelect>
)}
</section>
);
}

View File

@ -19,7 +19,7 @@ const TooltipContent = React.forwardRef<
ref={ref}
sideOffset={sideOffset}
className={cn(
'z-50 overflow-hidden rounded-md border bg-popover px-3 py-1.5 text-sm text-popover-foreground shadow-md animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',
'z-50 overflow-hidden rounded-md border bg-popover px-3 py-1.5 text-sm text-popover-foreground shadow-md animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 max-w-[20vw]',
className,
)}
{...props}