mirror of
https://github.com/infiniflow/ragflow.git
synced 2025-12-21 05:16:54 +08:00
### What problem does this PR solve? Feat: Filter the knowledge base list using owner #3221 ### Type of change - [x] New Feature (non-breaking change which adds functionality)
This commit is contained in:
@ -1,24 +1,57 @@
|
||||
import { Filter } from 'lucide-react';
|
||||
import { PropsWithChildren } from 'react';
|
||||
import { Button } from './ui/button';
|
||||
import { ChevronDown } from 'lucide-react';
|
||||
import React, {
|
||||
ChangeEventHandler,
|
||||
FunctionComponent,
|
||||
PropsWithChildren,
|
||||
} from 'react';
|
||||
import { Button, ButtonProps } from './ui/button';
|
||||
import { SearchInput } from './ui/input';
|
||||
|
||||
interface IProps {
|
||||
title: string;
|
||||
showDialog?: () => void;
|
||||
FilterPopover?: FunctionComponent<any>;
|
||||
searchString?: string;
|
||||
onSearchChange?: ChangeEventHandler<HTMLInputElement>;
|
||||
count?: number;
|
||||
}
|
||||
|
||||
const FilterButton = React.forwardRef<
|
||||
HTMLButtonElement,
|
||||
ButtonProps & { count?: number }
|
||||
>(({ count = 0, ...props }, ref) => {
|
||||
return (
|
||||
<Button variant="outline" size={'sm'} {...props} ref={ref}>
|
||||
Filter <span>{count}</span> <ChevronDown />
|
||||
</Button>
|
||||
);
|
||||
});
|
||||
|
||||
export default function ListFilterBar({
|
||||
title,
|
||||
children,
|
||||
showDialog,
|
||||
FilterPopover,
|
||||
searchString,
|
||||
onSearchChange,
|
||||
count,
|
||||
}: PropsWithChildren<IProps>) {
|
||||
return (
|
||||
<div className="flex justify-between mb-6">
|
||||
<span className="text-3xl font-bold ">{title}</span>
|
||||
<div className="flex gap-4 items-center">
|
||||
<Filter className="size-5" />
|
||||
<SearchInput></SearchInput>
|
||||
{FilterPopover ? (
|
||||
<FilterPopover>
|
||||
<FilterButton count={count}></FilterButton>
|
||||
</FilterPopover>
|
||||
) : (
|
||||
<FilterButton></FilterButton>
|
||||
)}
|
||||
|
||||
<SearchInput
|
||||
value={searchString}
|
||||
onChange={onSearchChange}
|
||||
></SearchInput>
|
||||
<Button variant={'tertiary'} size={'sm'} onClick={showDialog}>
|
||||
{children}
|
||||
</Button>
|
||||
|
||||
117
web/src/components/ui/pagination.tsx
Normal file
117
web/src/components/ui/pagination.tsx
Normal file
@ -0,0 +1,117 @@
|
||||
import { ChevronLeft, ChevronRight, MoreHorizontal } from 'lucide-react';
|
||||
import * as React from 'react';
|
||||
|
||||
import { ButtonProps, buttonVariants } from '@/components/ui/button';
|
||||
import { cn } from '@/lib/utils';
|
||||
|
||||
const Pagination = ({ className, ...props }: React.ComponentProps<'nav'>) => (
|
||||
<nav
|
||||
role="navigation"
|
||||
aria-label="pagination"
|
||||
className={cn('mx-auto flex w-full justify-center', className)}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
Pagination.displayName = 'Pagination';
|
||||
|
||||
const PaginationContent = React.forwardRef<
|
||||
HTMLUListElement,
|
||||
React.ComponentProps<'ul'>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<ul
|
||||
ref={ref}
|
||||
className={cn('flex flex-row items-center gap-1', className)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
PaginationContent.displayName = 'PaginationContent';
|
||||
|
||||
const PaginationItem = React.forwardRef<
|
||||
HTMLLIElement,
|
||||
React.ComponentProps<'li'>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<li ref={ref} className={cn('', className)} {...props} />
|
||||
));
|
||||
PaginationItem.displayName = 'PaginationItem';
|
||||
|
||||
type PaginationLinkProps = {
|
||||
isActive?: boolean;
|
||||
} & Pick<ButtonProps, 'size'> &
|
||||
React.ComponentProps<'a'>;
|
||||
|
||||
const PaginationLink = ({
|
||||
className,
|
||||
isActive,
|
||||
size = 'icon',
|
||||
...props
|
||||
}: PaginationLinkProps) => (
|
||||
<a
|
||||
aria-current={isActive ? 'page' : undefined}
|
||||
className={cn(
|
||||
buttonVariants({
|
||||
variant: isActive ? 'outline' : 'ghost',
|
||||
size,
|
||||
}),
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
PaginationLink.displayName = 'PaginationLink';
|
||||
|
||||
const PaginationPrevious = ({
|
||||
className,
|
||||
...props
|
||||
}: React.ComponentProps<typeof PaginationLink>) => (
|
||||
<PaginationLink
|
||||
aria-label="Go to previous page"
|
||||
size="default"
|
||||
className={cn('gap-1 pl-2.5', className)}
|
||||
{...props}
|
||||
>
|
||||
<ChevronLeft className="h-4 w-4" />
|
||||
<span>Previous</span>
|
||||
</PaginationLink>
|
||||
);
|
||||
PaginationPrevious.displayName = 'PaginationPrevious';
|
||||
|
||||
const PaginationNext = ({
|
||||
className,
|
||||
...props
|
||||
}: React.ComponentProps<typeof PaginationLink>) => (
|
||||
<PaginationLink
|
||||
aria-label="Go to next page"
|
||||
size="default"
|
||||
className={cn('gap-1 pr-2.5', className)}
|
||||
{...props}
|
||||
>
|
||||
<span>Next</span>
|
||||
<ChevronRight className="h-4 w-4" />
|
||||
</PaginationLink>
|
||||
);
|
||||
PaginationNext.displayName = 'PaginationNext';
|
||||
|
||||
const PaginationEllipsis = ({
|
||||
className,
|
||||
...props
|
||||
}: React.ComponentProps<'span'>) => (
|
||||
<span
|
||||
aria-hidden
|
||||
className={cn('flex h-9 w-9 items-center justify-center', className)}
|
||||
{...props}
|
||||
>
|
||||
<MoreHorizontal className="h-4 w-4" />
|
||||
<span className="sr-only">More pages</span>
|
||||
</span>
|
||||
);
|
||||
PaginationEllipsis.displayName = 'PaginationEllipsis';
|
||||
|
||||
export {
|
||||
Pagination,
|
||||
PaginationContent,
|
||||
PaginationEllipsis,
|
||||
PaginationItem,
|
||||
PaginationLink,
|
||||
PaginationNext,
|
||||
PaginationPrevious,
|
||||
};
|
||||
Reference in New Issue
Block a user