diff --git a/app/person/dashboard/components/PersonalProjectTable.tsx b/app/person/dashboard/components/PersonalProjectTable.tsx index bcc5717..e821296 100644 --- a/app/person/dashboard/components/PersonalProjectTable.tsx +++ b/app/person/dashboard/components/PersonalProjectTable.tsx @@ -8,6 +8,10 @@ import { SettingCustomPageSizeControl, usePersistentPageSizeOptions, } from "@/components/setting/PageSurface" +import { + getPersistedPageSizeOptions, + resolvePageSizeWithinOptions, +} from "@/components/setting/pageSize" import { Button, Group, Stack, Text } from "@mantine/core" import { DatePickerInput, type DatesRangeValue } from "@mantine/dates" @@ -66,7 +70,13 @@ export default function PersonalProjectTable() { const [loading, setLoading] = useState(false) const [page, setPage] = useState(1) - const [pageSize, setPageSize] = useState(10) + const [pageSize, setPageSize] = useState(() => + resolvePageSizeWithinOptions( + 10, + getPersistedPageSizeOptions(DEFAULT_RECORDS_PER_PAGE_OPTIONS), + 10 + ) + ) const { recordsPerPageOptions, addCustomPageSize, diff --git a/app/person/dashboard/components/PersonalTaskTable.tsx b/app/person/dashboard/components/PersonalTaskTable.tsx index 961e931..4d7262a 100644 --- a/app/person/dashboard/components/PersonalTaskTable.tsx +++ b/app/person/dashboard/components/PersonalTaskTable.tsx @@ -14,6 +14,10 @@ import { SettingListHeader, usePersistentPageSizeOptions, } from "@/components/setting/PageSurface" +import { + getPersistedPageSizeOptions, + resolvePageSizeWithinOptions, +} from "@/components/setting/pageSize" import { Button, Group, Stack, Text, UnstyledButton } from "@mantine/core" import { IconRefresh } from "@tabler/icons-react" import { DataTableColumn } from "mantine-datatable" @@ -27,7 +31,13 @@ export default function PersonalTaskTable() { const setBackProps = useBackUrlStore((s) => s.setBackProps) const [page, setPage] = useState(1) - const [pageSize, setPageSize] = useState(10) + const [pageSize, setPageSize] = useState(() => + resolvePageSizeWithinOptions( + 10, + getPersistedPageSizeOptions(DEFAULT_RECORDS_PER_PAGE_OPTIONS), + 10 + ) + ) const { recordsPerPageOptions, addCustomPageSize, diff --git a/app/person/report/page.tsx b/app/person/report/page.tsx index 2ca0612..216be81 100644 --- a/app/person/report/page.tsx +++ b/app/person/report/page.tsx @@ -18,6 +18,10 @@ import { SettingPage, usePersistentPageSizeOptions, } from "@/components/setting/PageSurface" +import { + getPersistedPageSizeOptions, + resolvePageSizeWithinOptions, +} from "@/components/setting/pageSize" import { Badge, Button, @@ -126,7 +130,13 @@ export default function PersonReportPage() { const [queryTrigger, setQueryTrigger] = useState(0) const [page, setPage] = useState(1) - const [pageSize, setPageSize] = useState(20) + const [pageSize, setPageSize] = useState(() => + resolvePageSizeWithinOptions( + 20, + getPersistedPageSizeOptions(DEFAULT_RECORDS_PER_PAGE_OPTIONS), + 20 + ) + ) const { recordsPerPageOptions, addCustomPageSize, diff --git a/components/label/hooks/useAuth.ts b/components/label/hooks/useAuth.ts index 4114743..16febc5 100644 --- a/components/label/hooks/useAuth.ts +++ b/components/label/hooks/useAuth.ts @@ -12,15 +12,9 @@ type PermissionMap = { } const mappingList: { [x: string]: [string, string] } = { - "/project/own": ["project", "config"], - "/management/team/employee": ["user", "view"], - "/management/team/organization": ["user", "group_view"], - "/management/team/dailypaper": ["daily_work", "team_view"], - "/management/team/cost": ["settlement_form", "view"], - "/management/team/workload": ["workload", "view"], - "/management/team/sync_server": ["data_sync", "server_view"], - "/management/team/sync_task": ["data_sync", "task_view"], - "/management/team/board": ["user", "view"], + "/person/dashboard": ["task", "view"], + "/person/report": ["daily_work", "self_view"], + "/person/workload": ["workload", "self_view"], } export const headerBarCheckItems = (data: PermissionMap) => { diff --git a/components/setting/pageSize.ts b/components/setting/pageSize.ts new file mode 100644 index 0000000..326f5ca --- /dev/null +++ b/components/setting/pageSize.ts @@ -0,0 +1,71 @@ +const CUSTOM_PAGE_SIZE_STORAGE_KEY = "cowa:custom-records-per-page-options:v1" + +function normalizePageSizeOptions(values: number[]) { + return Array.from( + new Set(values.filter((value) => Number.isInteger(value) && value > 0)) + ).sort((a, b) => a - b) +} + +function normalizeCustomPageSizeCache(value: unknown) { + if (!Array.isArray(value)) return [] + + return normalizePageSizeOptions(value.map((item) => Number(item))) +} + +export function resolvePageSizeWithinOptions( + pageSize: number | undefined, + availableOptions: number[], + fallbackPageSize: number +) { + const normalizedOptions = normalizePageSizeOptions(availableOptions) + + if ( + typeof pageSize === "number" && + Number.isInteger(pageSize) && + pageSize > 0 && + normalizedOptions.includes(pageSize) + ) { + return pageSize + } + + if ( + Number.isInteger(fallbackPageSize) && + fallbackPageSize > 0 && + normalizedOptions.includes(fallbackPageSize) + ) { + return fallbackPageSize + } + + return normalizedOptions[0] ?? fallbackPageSize +} + +export function getPersistedPageSizeOptions(defaultOptions: number[]) { + const normalizedDefaultOptions = normalizePageSizeOptions(defaultOptions) + + if (typeof window === "undefined") { + return normalizedDefaultOptions + } + + try { + const rawValue = window.localStorage.getItem(CUSTOM_PAGE_SIZE_STORAGE_KEY) + if (!rawValue) { + return normalizedDefaultOptions + } + + const parsedValue = JSON.parse(rawValue) as + | { state?: { customPageSizeCache?: unknown } } + | number[] + | null + + const customPageSizeCache = Array.isArray(parsedValue) + ? normalizeCustomPageSizeCache(parsedValue) + : normalizeCustomPageSizeCache(parsedValue?.state?.customPageSizeCache) + + return normalizePageSizeOptions([ + ...normalizedDefaultOptions, + ...customPageSizeCache, + ]) + } catch { + return normalizedDefaultOptions + } +}