NORY-34: show oauth2 clients in a data table
This commit is contained in:
parent
502098d8ef
commit
6335036a04
2 changed files with 141 additions and 1 deletions
105
dashboard/src/app/(inside)/client/data-table.tsx
Normal file
105
dashboard/src/app/(inside)/client/data-table.tsx
Normal file
|
@ -0,0 +1,105 @@
|
|||
'use client';
|
||||
|
||||
import { ColumnDef } from '@tanstack/react-table';
|
||||
import { OAuth2Client } from '@ory/client';
|
||||
import { DataTable } from '@/components/ui/data-table';
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
import { Spinner } from '@/components/ui/spinner';
|
||||
import { FetchClientPageProps } from '@/app/(inside)/client/page';
|
||||
|
||||
interface ClientDataTableProps {
|
||||
data: OAuth2Client[];
|
||||
pageSize: number;
|
||||
pageToken: string | undefined;
|
||||
fetchClientPage: (props: FetchClientPageProps) => Promise<{
|
||||
data: OAuth2Client[],
|
||||
tokens: Map<string, string>
|
||||
}>;
|
||||
}
|
||||
|
||||
export function ClientDataTable(
|
||||
{
|
||||
data,
|
||||
pageSize,
|
||||
pageToken,
|
||||
fetchClientPage,
|
||||
}: ClientDataTableProps,
|
||||
) {
|
||||
|
||||
console.log('OAuth2 client', data);
|
||||
|
||||
const columns: ColumnDef<OAuth2Client>[] = [
|
||||
{
|
||||
id: 'client_id',
|
||||
accessorKey: 'client_id',
|
||||
header: 'Client ID',
|
||||
},
|
||||
{
|
||||
id: 'client_name',
|
||||
accessorKey: 'client_name',
|
||||
header: 'Client Name',
|
||||
},
|
||||
{
|
||||
id: 'owner',
|
||||
accessorKey: 'owner',
|
||||
header: 'Owner',
|
||||
},
|
||||
];
|
||||
|
||||
const [items, setItems] = useState<OAuth2Client[]>(data);
|
||||
const [nextToken, setNextToken] = useState<string | undefined>(pageToken);
|
||||
|
||||
// react on changes from ssr (query params)
|
||||
useEffect(() => {
|
||||
setItems(data);
|
||||
setNextToken(pageToken);
|
||||
}, [data, pageSize, pageToken]);
|
||||
|
||||
// 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 fetchClientPage({
|
||||
pageSize: pageSize,
|
||||
pageToken: nextToken,
|
||||
});
|
||||
|
||||
setItems([...items, ...response.data]);
|
||||
setNextToken(response.tokens.get('next') ?? undefined);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<DataTable columns={columns} data={items}/>
|
||||
{
|
||||
nextToken && (
|
||||
<div className="flex w-full justify-center">
|
||||
<Spinner ref={infiniteScrollSensor} className="h-10"/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</>
|
||||
);
|
||||
}
|
|
@ -1,12 +1,47 @@
|
|||
import { getOAuth2Api } from '@/ory/sdk/server';
|
||||
import { parseTokens } from '@/app/(inside)/user/page';
|
||||
import { ClientDataTable } from '@/app/(inside)/client/data-table';
|
||||
|
||||
export interface FetchClientPageProps {
|
||||
pageSize: number;
|
||||
pageToken: string;
|
||||
}
|
||||
|
||||
async function fetchClientPage({ pageSize, pageToken }: FetchClientPageProps) {
|
||||
'use server';
|
||||
|
||||
const oAuth2Api = await getOAuth2Api();
|
||||
const response = await oAuth2Api.listOAuth2Clients({
|
||||
pageSize: pageSize,
|
||||
pageToken: pageToken,
|
||||
});
|
||||
|
||||
return {
|
||||
data: response.data,
|
||||
tokens: parseTokens(response.headers.link),
|
||||
};
|
||||
}
|
||||
|
||||
export default async function ListClientPage() {
|
||||
|
||||
let pageSize = 100;
|
||||
let pageToken: string = '00000000-0000-0000-0000-000000000000';
|
||||
|
||||
const initialFetch = await fetchClientPage({ pageSize, pageToken });
|
||||
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
<div>
|
||||
<p className="text-3xl font-bold leading-tight tracking-tight">OAuth2 Clients</p>
|
||||
<p className="text-lg font-light">
|
||||
Part of milestone v0.2.0
|
||||
See and manage all OAuth2 clients registered with your Ory Hydra instance
|
||||
</p>
|
||||
</div>
|
||||
<ClientDataTable
|
||||
data={initialFetch.data}
|
||||
pageSize={pageSize}
|
||||
pageToken={initialFetch.tokens.get('next')}
|
||||
fetchClientPage={fetchClientPage}/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue