From cd1bad6da9cd9722fe4dd1594d21ba1d444eef56 Mon Sep 17 00:00:00 2001 From: zhangheng Date: Thu, 23 Apr 2026 10:35:33 +0800 Subject: [PATCH] fix(table): add daterange --- app/layout.tsx | 1 + .../components/PersonalProjectTable.tsx | 78 +++++++++++++++++-- components/label/api/project/index.ts | 7 +- components/label/api/project/typing.ts | 5 ++ package.json | 1 + 5 files changed, 83 insertions(+), 9 deletions(-) diff --git a/app/layout.tsx b/app/layout.tsx index 230ae6c..fb37f14 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -2,6 +2,7 @@ import "@mantine/core/styles.css" import "@mantine/core/styles.layer.css" +import "@mantine/dates/styles.css" import "@mantine/notifications/styles.css" import "mantine-datatable/styles.css" import Script from "next/script" diff --git a/app/person/dashboard/components/PersonalProjectTable.tsx b/app/person/dashboard/components/PersonalProjectTable.tsx index 09dca2b..812bfa6 100644 --- a/app/person/dashboard/components/PersonalProjectTable.tsx +++ b/app/person/dashboard/components/PersonalProjectTable.tsx @@ -2,10 +2,12 @@ import { getPersonProjectDashBoard } from "@/components/label/api/project" import { Project } from "@/components/label/api/project/typing" -import { Button, Group, Text } from "@mantine/core" +import { Button, Flex, Group, Text } from "@mantine/core" +import { DatePickerInput, type DatesRangeValue } from "@mantine/dates" import { IconRefresh } from "@tabler/icons-react" import dayjs from "dayjs" +import "dayjs/locale/zh-cn" import duration from "dayjs/plugin/duration" import { DataTable, DataTableColumn } from "mantine-datatable" import { useRouter } from "next/navigation" @@ -24,6 +26,19 @@ function formatDurationSeconds(seconds?: number | null) { return "-" } +interface FilterFormRecord { + query_date: DatesRangeValue +} + +function createInitialFilters(): FilterFormRecord { + return { + query_date: [ + dayjs().subtract(1, "month").format("YYYY-MM-DD"), + dayjs().format("YYYY-MM-DD"), + ], + } +} + export default function PersonalProjectTable() { const router = useRouter() const [records, setRecords] = useState< @@ -35,6 +50,10 @@ export default function PersonalProjectTable() { const [pageSize, setPageSize] = useState(50) const [totalItems, setTotalItems] = useState(0) + const [filters, setFilters] = useState(() => createInitialFilters()) + const [queryTrigger, setQueryTrigger] = useState(0) + const [form, setForm] = useState(createInitialFilters()) + const totalPages = useMemo(() => { const totalItems = records.length return Math.max(1, Math.ceil(totalItems / pageSize)) @@ -45,22 +64,48 @@ export default function PersonalProjectTable() { return records.slice(start, start + pageSize) }, [page, pageSize, records]) + const appliedParams = useMemo(() => { + const obj: Project.ReqPersonProjectDashBoard = { + start_date: dayjs().format("YYYY-MM-DD"), + end_date: dayjs().format("YYYY-MM-DD"), + } + if (form.query_date[0] && form.query_date[1]) { + obj.start_date = dayjs(form.query_date[0]).format("YYYY-MM-DD") + obj.end_date = dayjs(form.query_date[1]).format("YYYY-MM-DD") + } + + return obj + }, [form.query_date]) + const load = useCallback(async () => { + if (!queryTrigger) return setLoading(true) try { - const res = await getPersonProjectDashBoard() + const res = await getPersonProjectDashBoard(appliedParams) setRecords(res ?? []) setTotalItems(res?.length ?? 0) setPage(1) } finally { setLoading(false) } - }, []) + }, [appliedParams, queryTrigger]) useEffect(() => { load() }, [load]) + useEffect(() => { + queueMicrotask(() => { + setQueryTrigger((v) => v + 1) + }) + }, []) + + const handleSearch = () => { + setPage(1) + setForm({ ...filters }) + setQueryTrigger((v) => v + 1) + } + useEffect(() => { if (page > totalPages) setPage(totalPages) }, [page, totalPages]) @@ -165,15 +210,34 @@ export default function PersonalProjectTable() { align="stretch" style={{ flexDirection: "column" }}> - - 参与项目 - + + + 参与项目 + + + setFilters((s) => ({ + ...s, + query_date: value, + })) + } + /> + +