From 7df37e400188a3e66e096ac5d3764196b1b8f774 Mon Sep 17 00:00:00 2001 From: Markus Thielker Date: Sat, 4 Jan 2025 10:53:08 +0100 Subject: [PATCH] NORY-41: apply new query and temporarily remove pagination --- .../src/app/(inside)/user/data-table.tsx | 97 +++++-------------- dashboard/src/app/(inside)/user/page.tsx | 57 ++--------- 2 files changed, 29 insertions(+), 125 deletions(-) diff --git a/dashboard/src/app/(inside)/user/data-table.tsx b/dashboard/src/app/(inside)/user/data-table.tsx index 8f4e3ac..510ee6c 100644 --- a/dashboard/src/app/(inside)/user/data-table.tsx +++ b/dashboard/src/app/(inside)/user/data-table.tsx @@ -4,9 +4,7 @@ import { ColumnDef } from '@tanstack/react-table'; import { Identity } from '@ory/client'; import { DataTable } from '@/components/ui/data-table'; import { CircleCheck, CircleX, Copy, MoreHorizontal, Trash, UserCheck, UserMinus, UserPen, UserX } from 'lucide-react'; -import React, { useEffect, useRef, useState } from 'react'; -import { FetchIdentityPageProps } from '@/app/(inside)/user/page'; -import { Spinner } from '@/components/ui/spinner'; +import React, { useEffect, useState } from 'react'; import { DropdownMenu, DropdownMenuContent, @@ -33,13 +31,11 @@ import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip interface IdentityDataTableProps { data: Identity[]; - pageSize: number; - pageToken: string | undefined; + page: number; query: string; - fetchIdentityPage: (props: FetchIdentityPageProps) => Promise<{ data: Identity[], tokens: Map }>; } -export function IdentityDataTable({ data, pageSize, pageToken, query, fetchIdentityPage }: IdentityDataTableProps) { +export function IdentityDataTable({ data, page, query }: IdentityDataTableProps) { const columns: ColumnDef[] = [ { @@ -81,27 +77,24 @@ export function IdentityDataTable({ data, pageSize, pageToken, query, fetchIdent return (
{email.value} - { - email.verified ? - - - - - - This email was confirmed at - {new Date(email.verified_at!!).toLocaleString()} - - - : - - - - - - This email is not confirmed yet - - - } + + + { + email.verified ? : + } + + + { + email.verified ? + <> + This email was confirmed at + {new Date(email.verified_at!!).toLocaleString()} + + : +

This email is not confirmed yet

+ } +
+
); } @@ -189,49 +182,10 @@ export function IdentityDataTable({ data, pageSize, pageToken, query, fetchIdent ]; const [items, setItems] = useState(data); - const [nextToken, setNextToken] = useState(pageToken); - // react on changes from ssr (query params) useEffect(() => { setItems(data); - setNextToken(pageToken); - }, [data, pageSize, pageToken, query]); - - // infinite scroll handling - const infiniteScrollSensor = useRef(null); - useEffect(() => { - const observer = new IntersectionObserver( - (entries) => { - if (entries[0].isIntersecting) { - fetchMore(); - } - }, - { threshold: 0.5 }, // Adjust threshold as needed - ); - - if (infiniteScrollSensor.current) { - observer.observe(infiniteScrollSensor.current); - } - - return () => { - if (infiniteScrollSensor.current) { - observer.unobserve(infiniteScrollSensor.current); - } - }; - }, [items]); - - const fetchMore = async () => { - if (!nextToken) return; - - const response = await fetchIdentityPage({ - pageSize: pageSize, - pageToken: nextToken, - query: query, - }); - - setItems([...items, ...response.data]); - setNextToken(response.tokens.get('next') ?? undefined); - }; + }, [data]); // quick actions const [currentIdentity, setCurrentIdentity] = useState(undefined); @@ -341,13 +295,6 @@ export function IdentityDataTable({ data, pageSize, pageToken, query, fetchIdent ) } - { - nextToken && ( -
- -
- ) - } ); } diff --git a/dashboard/src/app/(inside)/user/page.tsx b/dashboard/src/app/(inside)/user/page.tsx index f02c636..c1acd7e 100644 --- a/dashboard/src/app/(inside)/user/page.tsx +++ b/dashboard/src/app/(inside)/user/page.tsx @@ -1,49 +1,7 @@ import React from 'react'; import { IdentityDataTable } from '@/app/(inside)/user/data-table'; -import { getIdentityApi } from '@/ory/sdk/server'; import { SearchInput } from '@/components/search-input'; - -export interface FetchIdentityPageProps { - pageSize: number; - pageToken: string; - query: string; -} - -async function fetchIdentityPage({ pageSize, pageToken, query }: FetchIdentityPageProps) { - 'use server'; - - const identityApi = await getIdentityApi(); - const response = await identityApi.listIdentities({ - pageSize: pageSize, - pageToken: pageToken, - previewCredentialsIdentifierSimilar: query, - }); - - return { - data: response.data, - tokens: parseTokens(response.headers.link), - }; -} - -function parseTokens(link: string) { - - const parsed = link.split(',').map((it) => { - const startRel = it.lastIndexOf('rel="'); - const endRel = it.lastIndexOf('"'); - const rel = it.slice(startRel, endRel); - - const startToken = it.lastIndexOf('page_token='); - const endToken = it.lastIndexOf('&'); - const token = it.slice(startToken, endToken); - - return [rel, token]; - }); - - return new Map(parsed.map(obj => [ - obj[0].replace('rel="', ''), - obj[1].replace('page_token=', ''), - ])); -} +import { queryIdentities } from '@/lib/action/identity'; export default async function UserPage( { @@ -54,12 +12,13 @@ export default async function UserPage( ) { const params = await searchParams; + + const page = params.page ? Number(params.page) : 1; const query = params.query ? params.query as string : ''; let pageSize = 250; - let pageToken: string = '00000000-0000-0000-0000-000000000000'; - const initialFetch = await fetchIdentityPage({ pageSize, pageToken, query: query }); + const initialData = await queryIdentities({ page, pageSize, query }); return (
@@ -72,11 +31,9 @@ export default async function UserPage(
+ data={initialData} + page={page} + query={query}/>
);