Feat: Modify the dataset list page style #3221 (#7437)

### What problem does this PR solve?

Feat: Modify the dataset list page style #3221

### Type of change


- [x] New Feature (non-breaking change which adds functionality)
This commit is contained in:
balibabu 2025-04-30 15:37:16 +08:00 committed by GitHub
parent 6e7dd54a50
commit fea9d970ec
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 84 additions and 43 deletions

View File

@ -72,7 +72,7 @@ function CheckboxFormMultiple({
<Form {...form}>
<form
onSubmit={form.handleSubmit(onSubmit)}
className="space-y-8"
className="space-y-8 px-5 py-2.5"
onReset={() => form.reset()}
>
{filters.map((x) => (
@ -81,9 +81,11 @@ function CheckboxFormMultiple({
control={form.control}
name={x.field}
render={() => (
<FormItem>
<div className="mb-4">
<FormLabel className="text-base">{x.label}</FormLabel>
<FormItem className="space-y-4">
<div>
<FormLabel className="text-base text-text-sub-title-invert">
{x.label}
</FormLabel>
</div>
{x.list.map((item) => (
<FormField
@ -92,10 +94,10 @@ function CheckboxFormMultiple({
name={x.field}
render={({ field }) => {
return (
<div className="flex items-center justify-between">
<div className="flex items-center justify-between text-text-title text-xs">
<FormItem
key={item.id}
className="flex flex-row space-x-3 space-y-0 items-center"
className="flex flex-row space-x-3 space-y-0 items-center "
>
<FormControl>
<Checkbox
@ -111,9 +113,7 @@ function CheckboxFormMultiple({
}}
/>
</FormControl>
<FormLabel className="text-lg">
{item.label}
</FormLabel>
<FormLabel>{item.label}</FormLabel>
</FormItem>
<span className=" text-sm">{item.count}</span>
</div>
@ -126,7 +126,7 @@ function CheckboxFormMultiple({
)}
/>
))}
<div className="flex justify-between">
<div className="flex justify-end gap-5">
<Button
type="button"
variant={'outline'}
@ -155,7 +155,7 @@ export function FilterPopover({
return (
<Popover open={open} onOpenChange={setOpen}>
<PopoverTrigger asChild>{children}</PopoverTrigger>
<PopoverContent>
<PopoverContent className="p-0">
<CheckboxFormMultiple
onChange={onChange}
value={value}

View File

@ -6,12 +6,13 @@ import React, {
ReactNode,
useMemo,
} from 'react';
import { IconFont } from '../icon-font';
import { Button, ButtonProps } from '../ui/button';
import { SearchInput } from '../ui/input';
import { CheckboxFormMultipleProps, FilterPopover } from './filter-popover';
interface IProps {
title?: string;
title?: ReactNode;
searchString?: string;
onSearchChange?: ChangeEventHandler<HTMLInputElement>;
showFilter?: boolean;
@ -23,8 +24,21 @@ const FilterButton = React.forwardRef<
ButtonProps & { count?: number }
>(({ count = 0, ...props }, ref) => {
return (
<Button variant="outline" size={'sm'} {...props} ref={ref}>
Filter <span>{count}</span> <ChevronDown />
<Button variant="secondary" {...props} ref={ref}>
<span
className={cn({
'text-text-title': count > 0,
'text-text-sub-title-invert': count === 0,
})}
>
Filter
</span>
{count > 0 && (
<span className="rounded-full bg-text-badge px-1 text-xs ">
{count}
</span>
)}
<ChevronDown />
</Button>
);
});
@ -40,8 +54,10 @@ export default function ListFilterBar({
onChange,
filters,
className,
icon,
}: PropsWithChildren<IProps & Omit<CheckboxFormMultipleProps, 'setOpen'>> & {
className?: string;
icon?: ReactNode;
}) {
const filterCount = useMemo(() => {
return typeof value === 'object' && value !== null
@ -52,9 +68,16 @@ export default function ListFilterBar({
}, [value]);
return (
<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">
<div className={cn('flex justify-between mb-5 items-center', className)}>
<div className="text-2xl font-semibold flex items-center gap-2.5">
{typeof icon === 'string' ? (
<IconFont name={icon} className="size-6"></IconFont>
) : (
icon
)}
{leftPanel || title}
</div>
<div className="flex gap-5 items-center">
{showFilter && (
<FilterPopover value={value} onChange={onChange} filters={filters}>
<FilterButton count={filterCount}></FilterButton>
@ -64,6 +87,7 @@ export default function ListFilterBar({
<SearchInput
value={searchString}
onChange={onSearchChange}
className="w-32"
></SearchInput>
{children}
</div>

View File

@ -13,7 +13,7 @@ const buttonVariants = cva(
destructive:
'bg-destructive text-destructive-foreground hover:bg-destructive/90',
outline:
'border border-colors-outline-sentiment-primary bg-background hover:bg-accent hover:text-accent-foreground',
'border border-text-sub-title-invert bg-transparent hover:bg-accent hover:text-accent-foreground',
secondary:
'bg-secondary text-secondary-foreground hover:bg-secondary/80',
ghost: 'hover:bg-accent hover:text-accent-foreground',
@ -23,8 +23,8 @@ const buttonVariants = cva(
icon: 'bg-colors-background-inverse-standard text-foreground hover:bg-colors-background-inverse-standard/80',
},
size: {
default: 'h-10 px-4 py-2',
sm: 'h-9 rounded-md px-3',
default: 'h-8 px-2.5 py-1.5 ',
sm: 'h-6 rounded-sm px-2',
lg: 'h-11 rounded-md px-8',
icon: 'h-10 w-10',
auto: 'h-full px-1',

View File

@ -12,7 +12,7 @@ const Input = React.forwardRef<HTMLInputElement, InputProps>(
<input
type={type}
className={cn(
'flex h-10 w-full rounded-md border border-input bg-colors-background-inverse-weak px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50',
'flex h-8 w-full rounded-md border border-input bg-colors-background-inverse-weak px-2 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50',
className,
)}
ref={ref}
@ -28,7 +28,12 @@ export interface ExpandedInputProps extends Omit<InputProps, 'prefix'> {
suffix?: React.ReactNode;
}
const ExpandedInput = ({ suffix, prefix, ...props }: ExpandedInputProps) => {
const ExpandedInput = ({
suffix,
prefix,
className,
...props
}: ExpandedInputProps) => {
return (
<div className="relative">
<span
@ -39,7 +44,7 @@ const ExpandedInput = ({ suffix, prefix, ...props }: ExpandedInputProps) => {
{prefix}
</span>
<Input
className={cn({ 'pr-10': suffix, 'pl-10': prefix })}
className={cn({ 'pr-8': !!suffix, 'pl-8': !!prefix }, className)}
{...props}
></Input>
<span
@ -54,7 +59,12 @@ const ExpandedInput = ({ suffix, prefix, ...props }: ExpandedInputProps) => {
};
const SearchInput = (props: InputProps) => {
return <ExpandedInput suffix={<Search />} {...props}></ExpandedInput>;
return (
<ExpandedInput
prefix={<Search className="size-3.5" />}
{...props}
></ExpandedInput>
);
};
export { ExpandedInput, Input, SearchInput };

View File

@ -48,6 +48,7 @@ const PaginationLink = ({
<a
aria-current={isActive ? 'page' : undefined}
className={cn(
'size-8',
buttonVariants({
variant: isActive ? 'outline' : 'ghost',
size,
@ -70,7 +71,6 @@ const PaginationPrevious = ({
{...props}
>
<ChevronLeft className="h-4 w-4" />
<span>Previous</span>
</PaginationLink>
);
PaginationPrevious.displayName = 'PaginationPrevious';
@ -85,7 +85,6 @@ const PaginationNext = ({
className={cn('gap-1 pr-2.5', className)}
{...props}
>
<span>Next</span>
<ChevronRight className="h-4 w-4" />
</PaginationLink>
);

View File

@ -98,7 +98,7 @@ export function RAGFlowPagination({
}, [pageSize]);
return (
<section className="flex items-center justify-end">
<section className="flex items-center justify-end text-text-sub-title-invert ">
<span className="mr-4">Total {total}</span>
<Pagination className="w-auto mx-0 mr-4">
<PaginationContent>
@ -108,9 +108,14 @@ export function RAGFlowPagination({
{pages.map((x) => (
<PaginationItem
key={x}
className={cn({ ['bg-accent rounded-md']: currentPage === x })}
className={cn({
['bg-background-header-bar rounded-md text-text-title']:
currentPage === x,
})}
>
<PaginationLink onClick={handlePageChange(x)}>{x}</PaginationLink>
<PaginationLink onClick={handlePageChange(x)} className="size-8">
{x}
</PaginationLink>
</PaginationItem>
))}
<PaginationItem>
@ -126,6 +131,7 @@ export function RAGFlowPagination({
options={sizeChangerOptions}
value={currentPageSize}
onChange={handlePageSizeChange}
triggerClassName="bg-background-header-bar"
></RAGFlowSelect>
)}
</section>

View File

@ -26,7 +26,7 @@ const SelectTrigger = React.forwardRef<
<SelectPrimitive.Trigger
ref={ref}
className={cn(
'flex h-10 w-full items-center justify-between rounded-md border border-input bg-colors-background-inverse-weak px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1',
'flex h-8 w-full items-center justify-between rounded-md border border-input bg-colors-background-inverse-weak px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1',
className,
)}
{...props}
@ -192,6 +192,7 @@ export type RAGFlowSelectProps = Partial<ControllerRenderProps> & {
allowClear?: boolean;
placeholder?: React.ReactNode;
contentProps?: React.ComponentPropsWithoutRef<typeof SelectPrimitive.Content>;
triggerClassName?: string;
} & SelectPrimitive.SelectProps;
/**
@ -223,6 +224,7 @@ export const RAGFlowSelect = forwardRef<
placeholder,
contentProps = {},
defaultValue,
triggerClassName,
},
ref,
) {
@ -259,11 +261,11 @@ export const RAGFlowSelect = forwardRef<
<Select onValueChange={handleChange} value={value} key={key}>
<FormControlWidget>
<SelectTrigger
className="bg-colors-background-inverse-weak"
value={value}
onReset={handleReset}
allowClear={allowClear}
ref={ref}
className={triggerClassName}
>
<SelectValue placeholder={placeholder} />
</SelectTrigger>

View File

@ -117,7 +117,7 @@ export function Header() {
}, [navigate]);
return (
<section className="py-6 px-10 flex justify-between items-center ">
<section className="p-5 pr-14 flex justify-between items-center ">
<div className="flex items-center gap-4">
<img
src={'/logo.svg'}

View File

@ -15,7 +15,6 @@ import * as React from 'react';
import { ChunkMethodDialog } from '@/components/chunk-method-dialog';
import { RenameDialog } from '@/components/rename-dialog';
import { TableSkeleton } from '@/components/table-skeleton';
import { RAGFlowPagination } from '@/components/ui/ragflow-pagination';
import {
Table,
@ -48,7 +47,6 @@ export function DatasetTable({
setPagination,
rowSelection,
setRowSelection,
loading,
}: DatasetTableProps) {
const [sorting, setSorting] = React.useState<SortingState>([]);
const [columnFilters, setColumnFilters] = React.useState<ColumnFiltersState>(
@ -142,9 +140,7 @@ export function DatasetTable({
))}
</TableHeader>
<TableBody className="relative">
{loading ? (
<TableSkeleton columnsLength={columns.length}></TableSkeleton>
) : table.getRowModel().rows?.length ? (
{table.getRowModel().rows?.length ? (
table.getRowModel().rows.map((row) => (
<TableRow
key={row.id}

View File

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

View File

@ -85,7 +85,7 @@ export function DatasetCreatingDialog({ hideModal, onOk }: IModalProps<any>) {
</DialogHeader>
<InputForm onOk={onOk}></InputForm>
<DialogFooter>
<Button type="submit" variant={'tertiary'} size={'sm'} form={FormId}>
<Button type="submit" form={FormId}>
{t('common.save')}
</Button>
</DialogFooter>

View File

@ -53,18 +53,19 @@ export default function Datasets() {
);
return (
<section className="py-8 text-foreground">
<section className="py-4 text-foreground">
<ListFilterBar
title="Datasets"
title={t('header.knowledgeBase')}
searchString={searchString}
onSearchChange={handleInputChange}
value={filterValue}
filters={owners}
onChange={handleFilterSubmit}
className="px-8"
icon={'data'}
>
<Button size={'sm'} onClick={showModal}>
<Plus className="mr-2 size-2.5" />
<Button onClick={showModal}>
<Plus className=" size-2.5" />
{t('knowledgeList.createKnowledgeBase')}
</Button>
</ListFilterBar>

View File

@ -46,6 +46,7 @@ module.exports = {
'text-badge': 'var(--text-badge)',
'text-title': 'var(--text-title)',
'text-sub-title': 'var(--text-sub-title)',
'text-sub-title-invert': 'var(--text-sub-title-invert)',
'text-title-invert': 'var(--text-title-invert)',
'background-header-bar': 'var(--background-header-bar)',
'background-card': 'var(--background-card)',

View File

@ -79,6 +79,7 @@
--text-title: rgba(22, 22, 24, 1);
--text-sub-title: rgba(151, 154, 171, 1);
--text-sub-title-invert: rgba(91, 93, 106, 1);
--background-header-bar: rgba(11, 11, 12, 1);
--text-title-invert: rgba(255, 255, 255, 1);
@ -182,6 +183,7 @@
--text-title: rgba(255, 255, 255, 1);
--text-sub-title: rgba(91, 93, 106, 1);
--text-sub-title-invert: rgba(151, 154, 171, 1);
--background-header-bar: rgba(11, 11, 12, 1);
--text-title-invert: rgba(22, 22, 24, 1);