From 2e33b6fd7eb5ef8c73e4fd8d2fa51bf1da54a6ff Mon Sep 17 00:00:00 2001 From: zhangheng Date: Fri, 24 Apr 2026 18:10:01 +0800 Subject: [PATCH] fix(table): pagesize --- .../components/PersonalProjectTable.tsx | 113 ++++++++++++++++- .../components/PersonalTaskTable.tsx | 114 +++++++++++++++++- 2 files changed, 223 insertions(+), 4 deletions(-) diff --git a/app/person/dashboard/components/PersonalProjectTable.tsx b/app/person/dashboard/components/PersonalProjectTable.tsx index 812bfa6..df742ba 100644 --- a/app/person/dashboard/components/PersonalProjectTable.tsx +++ b/app/person/dashboard/components/PersonalProjectTable.tsx @@ -2,8 +2,17 @@ import { getPersonProjectDashBoard } from "@/components/label/api/project" import { Project } from "@/components/label/api/project/typing" -import { Button, Flex, Group, Text } from "@mantine/core" +import { + Button, + Flex, + Group, + Modal, + Stack, + Text, + TextInput, +} from "@mantine/core" import { DatePickerInput, type DatesRangeValue } from "@mantine/dates" +import { notifications } from "@mantine/notifications" import { IconRefresh } from "@tabler/icons-react" import dayjs from "dayjs" @@ -39,6 +48,8 @@ function createInitialFilters(): FilterFormRecord { } } +const DEFAULT_RECORDS_PER_PAGE_OPTIONS = [10, 15, 20, 50] + export default function PersonalProjectTable() { const router = useRouter() const [records, setRecords] = useState< @@ -48,6 +59,12 @@ export default function PersonalProjectTable() { const [page, setPage] = useState(1) const [pageSize, setPageSize] = useState(50) + const [recordsPerPageOptions, setRecordsPerPageOptions] = useState( + () => [...DEFAULT_RECORDS_PER_PAGE_OPTIONS] + ) + const [customPageSizeInput, setCustomPageSizeInput] = useState("") + const [customPageSizeModalOpened, setCustomPageSizeModalOpened] = + useState(false) const [totalItems, setTotalItems] = useState(0) const [filters, setFilters] = useState(() => createInitialFilters()) @@ -112,6 +129,53 @@ export default function PersonalProjectTable() { const [currentRowId, setCurrentRowId] = useState(0) + const openCustomPageSizeModal = useCallback(() => { + setCustomPageSizeModalOpened(true) + }, []) + + const closeCustomPageSizeModal = useCallback(() => { + setCustomPageSizeModalOpened(false) + setCustomPageSizeInput("") + }, []) + + const handleAddCustomPageSize = useCallback(() => { + const rawValue = customPageSizeInput.trim() + if (!rawValue) return + const size = Number(rawValue) + if (!Number.isInteger(size) || size <= 0) { + notifications.show({ + color: "red", + title: "输入无效", + message: "请填写大于 0 的整数条数", + }) + return + } + if (recordsPerPageOptions.includes(size)) { + notifications.show({ + color: "blue", + title: "已存在", + message: `每页 ${size} 条已在可选项中`, + }) + return + } + setRecordsPerPageOptions((prev) => [...prev, size].sort((a, b) => a - b)) + closeCustomPageSizeModal() + notifications.show({ + color: "green", + title: "添加成功", + message: `已新增每页 ${size} 条`, + }) + }, [closeCustomPageSizeModal, customPageSizeInput, recordsPerPageOptions]) + + const handleCustomPageSizeEnter = useCallback( + (event: React.KeyboardEvent) => { + if (event.key !== "Enter") return + event.preventDefault() + handleAddCustomPageSize() + }, + [handleAddCustomPageSize] + ) + const originColumn = useMemo(() => { let column: DataTableColumn[] = [ @@ -267,7 +331,7 @@ export default function PersonalProjectTable() { scrollAreaProps={{ type: "auto" }} records={pageRecords} onRecordsPerPageChange={setPageSize} - recordsPerPageOptions={[10, 15, 20]} + recordsPerPageOptions={recordsPerPageOptions} columns={originColumn} totalRecords={totalItems} recordsPerPage={pageSize} @@ -275,8 +339,53 @@ export default function PersonalProjectTable() { onPageChange={setPage} noRecordsText="暂无数据" recordsPerPageLabel="当前页数" + renderPagination={({ Controls }) => ( + + + + + + + + + )} /> + + + + setCustomPageSizeInput(event.currentTarget.value) + } + onKeyDown={handleCustomPageSizeEnter} + /> + + + + + + ) } diff --git a/app/person/dashboard/components/PersonalTaskTable.tsx b/app/person/dashboard/components/PersonalTaskTable.tsx index b94fab0..8be7f5a 100644 --- a/app/person/dashboard/components/PersonalTaskTable.tsx +++ b/app/person/dashboard/components/PersonalTaskTable.tsx @@ -7,7 +7,17 @@ import { usePermissionStore, } from "@/components/label/store/auth" import { TaskStatusEnum } from "@/components/label/utils/constants" -import { Badge, Button, Group, Text, UnstyledButton } from "@mantine/core" +import { + Badge, + Button, + Group, + Modal, + Stack, + Text, + TextInput, + UnstyledButton, +} from "@mantine/core" +import { notifications } from "@mantine/notifications" import { IconRefresh } from "@tabler/icons-react" import { DataTable, DataTableColumn } from "mantine-datatable" import { useCallback, useEffect, useMemo, useState } from "react" @@ -29,12 +39,20 @@ function getStatusColor(status?: number | null) { } } +const DEFAULT_RECORDS_PER_PAGE_OPTIONS = [10, 15, 20, 50] + export default function PersonalTaskTable() { const user_name = usePermissionStore((s) => s.user_name) const setBackProps = useBackUrlStore((s) => s.setBackProps) const [page, setPage] = useState(1) const [pageSize, setPageSize] = useState(50) + const [recordsPerPageOptions, setRecordsPerPageOptions] = useState( + () => [...DEFAULT_RECORDS_PER_PAGE_OPTIONS] + ) + const [customPageSizeInput, setCustomPageSizeInput] = useState("") + const [customPageSizeModalOpened, setCustomPageSizeModalOpened] = + useState(false) const [totalItems, setTotalItems] = useState(0) const [records, setRecords] = useState([]) const [loading, setLoading] = useState(false) @@ -73,6 +91,53 @@ export default function PersonalTaskTable() { const [currentRowId, setCurrentRowId] = useState(0) + const openCustomPageSizeModal = useCallback(() => { + setCustomPageSizeModalOpened(true) + }, []) + + const closeCustomPageSizeModal = useCallback(() => { + setCustomPageSizeModalOpened(false) + setCustomPageSizeInput("") + }, []) + + const handleAddCustomPageSize = useCallback(() => { + const rawValue = customPageSizeInput.trim() + if (!rawValue) return + const size = Number(rawValue) + if (!Number.isInteger(size) || size <= 0) { + notifications.show({ + color: "red", + title: "输入无效", + message: "请填写大于 0 的整数条数", + }) + return + } + if (recordsPerPageOptions.includes(size)) { + notifications.show({ + color: "blue", + title: "已存在", + message: `每页 ${size} 条已在可选项中`, + }) + return + } + setRecordsPerPageOptions((prev) => [...prev, size].sort((a, b) => a - b)) + closeCustomPageSizeModal() + notifications.show({ + color: "green", + title: "添加成功", + message: `已新增每页 ${size} 条`, + }) + }, [closeCustomPageSizeModal, customPageSizeInput, recordsPerPageOptions]) + + const handleCustomPageSizeEnter = useCallback( + (event: React.KeyboardEvent) => { + if (event.key !== "Enter") return + event.preventDefault() + handleAddCustomPageSize() + }, + [handleAddCustomPageSize] + ) + const originColumn = useMemo(() => { let column: DataTableColumn[] = [ { @@ -230,7 +295,7 @@ export default function PersonalTaskTable() { scrollAreaProps={{ type: "auto" }} records={records} onRecordsPerPageChange={setPageSize} - recordsPerPageOptions={[10, 15, 20]} + recordsPerPageOptions={recordsPerPageOptions} columns={originColumn} totalRecords={totalItems} recordsPerPage={pageSize} @@ -238,8 +303,53 @@ export default function PersonalTaskTable() { onPageChange={setPage} noRecordsText="暂无数据" recordsPerPageLabel="当前页数" + renderPagination={({ Controls }) => ( + + + + + + + + + )} /> + + + + setCustomPageSizeInput(event.currentTarget.value) + } + onKeyDown={handleCustomPageSizeEnter} + /> + + + + + + ) }