From 54033a7d25664af81648cde415e896b439ddf8ff Mon Sep 17 00:00:00 2001 From: Justin Date: Thu, 12 Dec 2024 21:46:55 -0800 Subject: [PATCH] fix user pagination and page setting --- .../templates/users/usersPageV2.tsx | 131 +++++++++++++++--- web/services/hooks/users.tsx | 26 +++- 2 files changed, 133 insertions(+), 24 deletions(-) diff --git a/web/components/templates/users/usersPageV2.tsx b/web/components/templates/users/usersPageV2.tsx index a4c531426..a7a29e037 100644 --- a/web/components/templates/users/usersPageV2.tsx +++ b/web/components/templates/users/usersPageV2.tsx @@ -1,19 +1,20 @@ +import { UIFilterRowTree } from "@/services/lib/filters/types"; import { UserGroupIcon } from "@heroicons/react/24/outline"; import Link from "next/link"; +import { useSearchParams } from "next/navigation"; import { useRouter } from "next/router"; -import { useState, useCallback } from "react"; +import { useCallback, useEffect, useState } from "react"; import { useDebounce } from "../../../services/hooks/debounce"; import { useUsers } from "../../../services/hooks/users"; import { userTableFilters } from "../../../services/lib/filters/frontendFilterDefs"; -import { SortLeafRequest } from "../../../services/lib/sorts/requests/sorts"; -import { SortDirection } from "../../../services/lib/sorts/users/sorts"; -import AuthHeader from "../../shared/authHeader"; -import ThemedTable from "../../shared/themed/table/themedTable"; import { filterUITreeToFilterNode, getRootFilterNode, } from "../../../services/lib/filters/uiFilterRowTree"; -import { UIFilterRowTree } from "@/services/lib/filters/types"; +import { SortLeafRequest } from "../../../services/lib/sorts/requests/sorts"; +import { SortDirection } from "../../../services/lib/sorts/users/sorts"; +import AuthHeader from "../../shared/authHeader"; +import ThemedTable from "../../shared/themed/table/themedTable"; import TableFooter from "../requestsV2/tableFooter"; import { INITIAL_COLUMNS } from "./initialColumns"; @@ -27,8 +28,50 @@ interface UsersPageV2Props { }; } +function useQueryParam( + paramName: string, + defaultValue: string +): [queryParam: string, setQueryParam: (value: string) => void] { + const router = useRouter(); + const searchParams = useSearchParams(); + + const setQueryParam = useCallback( + (value: string) => { + const currentQuery = { ...router.query }; + currentQuery[paramName] = value; + router.push( + { + pathname: router.pathname, + query: currentQuery, + }, + undefined, + { shallow: true } + ); + }, + [router, paramName] + ); + + // Get the current value from the URL + const queryParam = searchParams?.get(paramName) || defaultValue; + + useEffect(() => { + // If the parameter is not in the URL, set it to the default value + if (!searchParams?.has(paramName)) { + setQueryParam(defaultValue); + } + }, [paramName, defaultValue, searchParams, setQueryParam]); + + return [queryParam, setQueryParam]; +} + const UsersPageV2 = (props: UsersPageV2Props) => { - const { currentPage, pageSize, sort } = props; + const [currentPage, setCurrentPage] = useQueryParam("page", "1"); + const [pageSize, setPageSize] = useQueryParam("pageSize", "100"); + const [sortDirection, setSortDirection] = useQueryParam( + "sortDirection", + "asc" + ); + const [sortKey, setSortKey] = useQueryParam("sortKey", "last_active"); const [advancedFilters, setAdvancedFilters] = useState( getRootFilterNode() @@ -38,22 +81,24 @@ const UsersPageV2 = (props: UsersPageV2Props) => { const router = useRouter(); const sortLeaf: SortLeafRequest = - sort.sortKey && sort.sortDirection + sortKey && sortDirection ? { - [sort.sortKey]: sort.sortDirection, + [sortKey]: sortDirection, } : { last_active: "desc", }; + // const [timeFilter, setTimeFilter] = useState("all"); const { users, count, from, isLoading, to, refetch } = useUsers( - currentPage, - pageSize, + parseInt(currentPage, 10), + parseInt(pageSize, 10), sortLeaf, filterUITreeToFilterNode( userTableFilters.sort((a, b) => a.label.localeCompare(b.label)), debouncedAdvancedFilters ) + // timeFilter ); const checkIsNotUniqueUser = useCallback(() => { @@ -74,17 +119,63 @@ const UsersPageV2 = (props: UsersPageV2Props) => { [] ); + // const onTimeSelectHandler = (key: TimeInterval, value: string) => { + // if (key === "custom") { + // const [start, end] = value.split("_"); + // const filter: FilterNode = { + // left: { + // request_response_rmt: { + // request_created_at: { + // gte: new Date(start), + // }, + // }, + // }, + // operator: "and", + // right: { + // request_response_rmt: { + // request_created_at: { + // lte: new Date(end), + // }, + // }, + // }, + // }; + // setTimeFilter(filter); + // } else { + // setTimeFilter({ + // request_response_rmt: { + // request_created_at: { + // gte: new Date(getTimeIntervalAgo(key)), + // }, + // }, + // }); + // } + // }; + // const defaultTimeFilter: TimeFilter = useMemo(() => { + // return { + // start: new Date(getTimeIntervalAgo("1m")), + // end: new Date(), + // }; + // }, []); return ( <> -
+
{ )} { - refetch(); + onPageChange={(newPage) => { + setCurrentPage(newPage.toString()); }} - onPageSizeChange={() => { - refetch(); + onPageSizeChange={(newPageSize) => { + setPageSize(newPageSize.toString()); }} - pageSizeOptions={[25, 50, 100]} + pageSizeOptions={[100, 250, 500]} showCount={true} />
diff --git a/web/services/hooks/users.tsx b/web/services/hooks/users.tsx index 40244789f..e131b554d 100644 --- a/web/services/hooks/users.tsx +++ b/web/services/hooks/users.tsx @@ -141,15 +141,33 @@ const useUsers = ( currentPage: number, currentPageSize: number, sortLeaf: SortLeafUsers, - advancedFilter?: FilterNode + advancedFilter?: FilterNode, + timeFilter?: FilterNode ) => { const { data, isLoading, refetch, isRefetching } = useQuery({ - queryKey: ["users", currentPage, currentPageSize, advancedFilter, sortLeaf], + queryKey: [ + "users", + currentPage, + currentPageSize, + advancedFilter, + sortLeaf, + timeFilter, + ], queryFn: async (query) => { const currentPage = query.queryKey[1] as number; const currentPageSize = query.queryKey[2] as number; - const advancedFilter = query.queryKey[3]; + const advancedFilter = query.queryKey[3] as FilterNode | undefined; const sortLeaf = query.queryKey[4]; + const timeFilter = query.queryKey[5] as FilterNode | undefined; + + let filter = advancedFilter ?? timeFilter; + if (timeFilter && advancedFilter) { + filter = { + left: advancedFilter, + operator: "and", + right: timeFilter, + }; + } const [response, count] = await Promise.all([ fetch("/api/request_users", { method: "POST", @@ -157,7 +175,7 @@ const useUsers = ( "Content-Type": "application/json", }, body: JSON.stringify({ - filter: advancedFilter, + filter: filter, offset: (currentPage - 1) * currentPageSize, limit: currentPageSize, sort: sortLeaf,