From 681840656392930f54c4aab063bc5cd700a557e9 Mon Sep 17 00:00:00 2001 From: Konrad Staniszewski Date: Mon, 2 Dec 2024 20:51:35 -0800 Subject: [PATCH 1/9] Prevent table layout shift on changing repo page --- packages/web/src/components/ui/data-table.tsx | 23 +++++++++++++------ 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/packages/web/src/components/ui/data-table.tsx b/packages/web/src/components/ui/data-table.tsx index a328d833..c4c5c663 100644 --- a/packages/web/src/components/ui/data-table.tsx +++ b/packages/web/src/components/ui/data-table.tsx @@ -40,7 +40,7 @@ export function DataTable({ const [sorting, setSorting] = React.useState([]) const [columnFilters, setColumnFilters] = React.useState( [] - ) + ) const table = useReactTable({ data, @@ -70,13 +70,16 @@ export function DataTable({ />
- +
{table.getHeaderGroups().map((headerGroup) => ( {headerGroup.headers.map((header) => { return ( - + {header.isPlaceholder ? null : flexRender( @@ -84,7 +87,7 @@ export function DataTable({ header.getContext() )} - ) + ); })} ))} @@ -94,11 +97,17 @@ export function DataTable({ table.getRowModel().rows.map((row) => ( {row.getVisibleCells().map((cell) => ( - - {flexRender(cell.column.columnDef.cell, cell.getContext())} + + {flexRender( + cell.column.columnDef.cell, + cell.getContext() + )} ))} From 103e4f514dc806f10f1db5eef18fe7fad0f95a0e Mon Sep 17 00:00:00 2001 From: Konrad Staniszewski Date: Mon, 2 Dec 2024 20:55:50 -0800 Subject: [PATCH 2/9] Add size --- packages/web/src/app/repos/columns.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/web/src/app/repos/columns.tsx b/packages/web/src/app/repos/columns.tsx index a239dce8..93f8d7f3 100644 --- a/packages/web/src/app/repos/columns.tsx +++ b/packages/web/src/app/repos/columns.tsx @@ -25,6 +25,7 @@ export const columns: ColumnDef[] = [ { accessorKey: "name", header: "Name", + size: 300, cell: ({ row }) => { const repo = row.original; const url = repo.url; @@ -138,4 +139,4 @@ const createSortHeader = (name: string, column: Column ) -} \ No newline at end of file +} From e284d3e56491cb060cf646604ea56cc398bd688b Mon Sep 17 00:00:00 2001 From: Konrad Staniszewski Date: Mon, 2 Dec 2024 21:03:49 -0800 Subject: [PATCH 3/9] Add pagination numbering and move navigation buttons to search header --- packages/web/src/components/ui/data-table.tsx | 85 +++++++++++-------- 1 file changed, 48 insertions(+), 37 deletions(-) diff --git a/packages/web/src/components/ui/data-table.tsx b/packages/web/src/components/ui/data-table.tsx index c4c5c663..82f35ec0 100644 --- a/packages/web/src/components/ui/data-table.tsx +++ b/packages/web/src/components/ui/data-table.tsx @@ -10,7 +10,7 @@ import { getPaginationRowModel, getSortedRowModel, useReactTable, -} from "@tanstack/react-table" +} from "@tanstack/react-table"; import { Table, TableBody, @@ -18,17 +18,16 @@ import { TableHead, TableHeader, TableRow, -} from "@/components/ui/table" -import { Button } from "@/components/ui/button" -import { Input } from "@/components/ui/input" -import * as React from "react" - +} from "@/components/ui/table"; +import { Button } from "@/components/ui/button"; +import { Input } from "@/components/ui/input"; +import * as React from "react"; interface DataTableProps { - columns: ColumnDef[] - data: TData[] - searchKey: string - searchPlaceholder?: string + columns: ColumnDef[]; + data: TData[]; + searchKey: string; + searchPlaceholder?: string; } export function DataTable({ @@ -37,10 +36,10 @@ export function DataTable({ searchKey, searchPlaceholder, }: DataTableProps) { - const [sorting, setSorting] = React.useState([]) + const [sorting, setSorting] = React.useState([]); const [columnFilters, setColumnFilters] = React.useState( [] - ) + ); const table = useReactTable({ data, @@ -55,19 +54,45 @@ export function DataTable({ sorting, columnFilters, }, - }) + }); return (
-
+
table.getColumn(searchKey)?.setFilterValue(event.target.value) } className="max-w-sm" /> + {/* Pagination Controls */} +
+ {/* Display Current Page and Total Pages */} + + Page {table.getState().pagination.pageIndex + 1} of{' '} + {table.getPageCount()} + + + +
@@ -78,7 +103,7 @@ export function DataTable({ return ( {header.isPlaceholder ? null @@ -102,7 +127,7 @@ export function DataTable({ {row.getVisibleCells().map((cell) => ( {flexRender( cell.column.columnDef.cell, @@ -114,7 +139,10 @@ export function DataTable({ )) ) : ( - + No results. @@ -122,24 +150,7 @@ export function DataTable({
-
- - -
+ - ) + ); } From 51104b5d45f88b2b7e62a53800f7279547ceca8a Mon Sep 17 00:00:00 2001 From: Konrad Staniszewski Date: Mon, 2 Dec 2024 21:51:22 -0800 Subject: [PATCH 4/9] make number of table elements dynamic --- packages/web/src/app/repos/page.tsx | 4 +- packages/web/src/components/ui/data-table.tsx | 88 ++++++++++++------- 2 files changed, 59 insertions(+), 33 deletions(-) diff --git a/packages/web/src/app/repos/page.tsx b/packages/web/src/app/repos/page.tsx index 7da11dd4..dc117b54 100644 --- a/packages/web/src/app/repos/page.tsx +++ b/packages/web/src/app/repos/page.tsx @@ -7,10 +7,10 @@ export default function ReposPage() {
Loading...
}> -
+
) -} \ No newline at end of file +} diff --git a/packages/web/src/components/ui/data-table.tsx b/packages/web/src/components/ui/data-table.tsx index 82f35ec0..05a83d1b 100644 --- a/packages/web/src/components/ui/data-table.tsx +++ b/packages/web/src/components/ui/data-table.tsx @@ -1,5 +1,6 @@ "use client" +import React from "react"; import { ColumnDef, ColumnFiltersState, @@ -21,7 +22,6 @@ import { } from "@/components/ui/table"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; -import * as React from "react"; interface DataTableProps { columns: ColumnDef[]; @@ -37,33 +37,63 @@ export function DataTable({ searchPlaceholder, }: DataTableProps) { const [sorting, setSorting] = React.useState([]); - const [columnFilters, setColumnFilters] = React.useState( - [] - ); + const [columnFilters, setColumnFilters] = React.useState([]); + const [pagination, setPagination] = React.useState({ + pageIndex: 0, + pageSize: 10, // Initial page size + }); const table = useReactTable({ data, columns, - getCoreRowModel: getCoreRowModel(), - getPaginationRowModel: getPaginationRowModel(), - onSortingChange: setSorting, - getSortedRowModel: getSortedRowModel(), - onColumnFiltersChange: setColumnFilters, - getFilteredRowModel: getFilteredRowModel(), state: { sorting, columnFilters, + pagination, }, + onSortingChange: setSorting, + onColumnFiltersChange: setColumnFilters, + onPaginationChange: setPagination, + getCoreRowModel: getCoreRowModel(), + getPaginationRowModel: getPaginationRowModel(), + getSortedRowModel: getSortedRowModel(), + getFilteredRowModel: getFilteredRowModel(), }); + React.useEffect(() => { + function calculatePageSize() { + if (typeof window !== 'undefined') { + const windowHeight = window.innerHeight; + const otherElementsHeight = 200; // Total height of other elements (header, footer, etc.) + const availableHeight = windowHeight - otherElementsHeight; + const rowHeight = 75; // Approximate height of a table row in pixels + const rowsThatFit = Math.floor(availableHeight / rowHeight); + return rowsThatFit > 0 ? rowsThatFit : 1; + } + return 10; // Default page size if window is undefined + } + + function handleResize() { + const newPageSize = calculatePageSize(); + setPagination((prev) => ({ + ...prev, + pageSize: newPageSize, + })); + } + + if (typeof window !== 'undefined') { + window.addEventListener('resize', handleResize); + handleResize(); // Initial calculation + return () => window.removeEventListener('resize', handleResize); + } + }, []); + return (
table.getColumn(searchKey)?.setFilterValue(event.target.value) } @@ -73,8 +103,7 @@ export function DataTable({
{/* Display Current Page and Total Pages */} - Page {table.getState().pagination.pageIndex + 1} of{' '} - {table.getPageCount()} + Page {table.getState().pagination.pageIndex + 1} of {table.getPageCount()}
-
); } From ba230778e3885f9af0575860c17d4b6554f84f1e Mon Sep 17 00:00:00 2001 From: Konrad Staniszewski Date: Mon, 2 Dec 2024 20:51:35 -0800 Subject: [PATCH 5/9] Prevent table layout shift on changing repo page --- packages/web/src/components/ui/data-table.tsx | 23 +++++++++++++------ 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/packages/web/src/components/ui/data-table.tsx b/packages/web/src/components/ui/data-table.tsx index a328d833..c4c5c663 100644 --- a/packages/web/src/components/ui/data-table.tsx +++ b/packages/web/src/components/ui/data-table.tsx @@ -40,7 +40,7 @@ export function DataTable({ const [sorting, setSorting] = React.useState([]) const [columnFilters, setColumnFilters] = React.useState( [] - ) + ) const table = useReactTable({ data, @@ -70,13 +70,16 @@ export function DataTable({ />
- +
{table.getHeaderGroups().map((headerGroup) => ( {headerGroup.headers.map((header) => { return ( - + {header.isPlaceholder ? null : flexRender( @@ -84,7 +87,7 @@ export function DataTable({ header.getContext() )} - ) + ); })} ))} @@ -94,11 +97,17 @@ export function DataTable({ table.getRowModel().rows.map((row) => ( {row.getVisibleCells().map((cell) => ( - - {flexRender(cell.column.columnDef.cell, cell.getContext())} + + {flexRender( + cell.column.columnDef.cell, + cell.getContext() + )} ))} From 2d4e3593fb8c15fa97337e16523caa40db6a7318 Mon Sep 17 00:00:00 2001 From: Konrad Staniszewski Date: Mon, 2 Dec 2024 20:55:50 -0800 Subject: [PATCH 6/9] Add size --- packages/web/src/app/repos/columns.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/web/src/app/repos/columns.tsx b/packages/web/src/app/repos/columns.tsx index a239dce8..93f8d7f3 100644 --- a/packages/web/src/app/repos/columns.tsx +++ b/packages/web/src/app/repos/columns.tsx @@ -25,6 +25,7 @@ export const columns: ColumnDef[] = [ { accessorKey: "name", header: "Name", + size: 300, cell: ({ row }) => { const repo = row.original; const url = repo.url; @@ -138,4 +139,4 @@ const createSortHeader = (name: string, column: Column ) -} \ No newline at end of file +} From 97c5a0fb37f2769e5182577e713569c02f7e83c8 Mon Sep 17 00:00:00 2001 From: Konrad Staniszewski Date: Mon, 2 Dec 2024 21:03:49 -0800 Subject: [PATCH 7/9] Add pagination numbering and move navigation buttons to search header --- packages/web/src/components/ui/data-table.tsx | 85 +++++++++++-------- 1 file changed, 48 insertions(+), 37 deletions(-) diff --git a/packages/web/src/components/ui/data-table.tsx b/packages/web/src/components/ui/data-table.tsx index c4c5c663..82f35ec0 100644 --- a/packages/web/src/components/ui/data-table.tsx +++ b/packages/web/src/components/ui/data-table.tsx @@ -10,7 +10,7 @@ import { getPaginationRowModel, getSortedRowModel, useReactTable, -} from "@tanstack/react-table" +} from "@tanstack/react-table"; import { Table, TableBody, @@ -18,17 +18,16 @@ import { TableHead, TableHeader, TableRow, -} from "@/components/ui/table" -import { Button } from "@/components/ui/button" -import { Input } from "@/components/ui/input" -import * as React from "react" - +} from "@/components/ui/table"; +import { Button } from "@/components/ui/button"; +import { Input } from "@/components/ui/input"; +import * as React from "react"; interface DataTableProps { - columns: ColumnDef[] - data: TData[] - searchKey: string - searchPlaceholder?: string + columns: ColumnDef[]; + data: TData[]; + searchKey: string; + searchPlaceholder?: string; } export function DataTable({ @@ -37,10 +36,10 @@ export function DataTable({ searchKey, searchPlaceholder, }: DataTableProps) { - const [sorting, setSorting] = React.useState([]) + const [sorting, setSorting] = React.useState([]); const [columnFilters, setColumnFilters] = React.useState( [] - ) + ); const table = useReactTable({ data, @@ -55,19 +54,45 @@ export function DataTable({ sorting, columnFilters, }, - }) + }); return (
-
+
table.getColumn(searchKey)?.setFilterValue(event.target.value) } className="max-w-sm" /> + {/* Pagination Controls */} +
+ {/* Display Current Page and Total Pages */} + + Page {table.getState().pagination.pageIndex + 1} of{' '} + {table.getPageCount()} + + + +
@@ -78,7 +103,7 @@ export function DataTable({ return ( {header.isPlaceholder ? null @@ -102,7 +127,7 @@ export function DataTable({ {row.getVisibleCells().map((cell) => ( {flexRender( cell.column.columnDef.cell, @@ -114,7 +139,10 @@ export function DataTable({ )) ) : ( - + No results. @@ -122,24 +150,7 @@ export function DataTable({
-
- - -
+ - ) + ); } From 0979b074cd20dd92bf68b7ae7bf7c75a56d3889b Mon Sep 17 00:00:00 2001 From: Konrad Staniszewski Date: Mon, 2 Dec 2024 21:51:22 -0800 Subject: [PATCH 8/9] make number of table elements dynamic --- packages/web/src/app/repos/page.tsx | 4 +- packages/web/src/components/ui/data-table.tsx | 88 ++++++++++++------- 2 files changed, 59 insertions(+), 33 deletions(-) diff --git a/packages/web/src/app/repos/page.tsx b/packages/web/src/app/repos/page.tsx index 7da11dd4..dc117b54 100644 --- a/packages/web/src/app/repos/page.tsx +++ b/packages/web/src/app/repos/page.tsx @@ -7,10 +7,10 @@ export default function ReposPage() {
Loading...
}> -
+
) -} \ No newline at end of file +} diff --git a/packages/web/src/components/ui/data-table.tsx b/packages/web/src/components/ui/data-table.tsx index 82f35ec0..05a83d1b 100644 --- a/packages/web/src/components/ui/data-table.tsx +++ b/packages/web/src/components/ui/data-table.tsx @@ -1,5 +1,6 @@ "use client" +import React from "react"; import { ColumnDef, ColumnFiltersState, @@ -21,7 +22,6 @@ import { } from "@/components/ui/table"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; -import * as React from "react"; interface DataTableProps { columns: ColumnDef[]; @@ -37,33 +37,63 @@ export function DataTable({ searchPlaceholder, }: DataTableProps) { const [sorting, setSorting] = React.useState([]); - const [columnFilters, setColumnFilters] = React.useState( - [] - ); + const [columnFilters, setColumnFilters] = React.useState([]); + const [pagination, setPagination] = React.useState({ + pageIndex: 0, + pageSize: 10, // Initial page size + }); const table = useReactTable({ data, columns, - getCoreRowModel: getCoreRowModel(), - getPaginationRowModel: getPaginationRowModel(), - onSortingChange: setSorting, - getSortedRowModel: getSortedRowModel(), - onColumnFiltersChange: setColumnFilters, - getFilteredRowModel: getFilteredRowModel(), state: { sorting, columnFilters, + pagination, }, + onSortingChange: setSorting, + onColumnFiltersChange: setColumnFilters, + onPaginationChange: setPagination, + getCoreRowModel: getCoreRowModel(), + getPaginationRowModel: getPaginationRowModel(), + getSortedRowModel: getSortedRowModel(), + getFilteredRowModel: getFilteredRowModel(), }); + React.useEffect(() => { + function calculatePageSize() { + if (typeof window !== 'undefined') { + const windowHeight = window.innerHeight; + const otherElementsHeight = 200; // Total height of other elements (header, footer, etc.) + const availableHeight = windowHeight - otherElementsHeight; + const rowHeight = 75; // Approximate height of a table row in pixels + const rowsThatFit = Math.floor(availableHeight / rowHeight); + return rowsThatFit > 0 ? rowsThatFit : 1; + } + return 10; // Default page size if window is undefined + } + + function handleResize() { + const newPageSize = calculatePageSize(); + setPagination((prev) => ({ + ...prev, + pageSize: newPageSize, + })); + } + + if (typeof window !== 'undefined') { + window.addEventListener('resize', handleResize); + handleResize(); // Initial calculation + return () => window.removeEventListener('resize', handleResize); + } + }, []); + return (
table.getColumn(searchKey)?.setFilterValue(event.target.value) } @@ -73,8 +103,7 @@ export function DataTable({
{/* Display Current Page and Total Pages */} - Page {table.getState().pagination.pageIndex + 1} of{' '} - {table.getPageCount()} + Page {table.getState().pagination.pageIndex + 1} of {table.getPageCount()}
-
); } From 6d8ba19546e192bc97b7187fb8d888026c2506ad Mon Sep 17 00:00:00 2001 From: Konrad Staniszewski Date: Thu, 5 Dec 2024 22:09:31 -0800 Subject: [PATCH 9/9] add table show number dropdown --- packages/backend/src/schemas/v2.ts | 1 - packages/web/src/app/repos/columns.tsx | 7 +- .../web/src/app/repos/repositoryTable.tsx | 7 +- packages/web/src/components/ui/data-table.tsx | 106 ++++++++---------- .../web/src/components/ui/dropdown-menu.tsx | 4 +- 5 files changed, 57 insertions(+), 68 deletions(-) diff --git a/packages/backend/src/schemas/v2.ts b/packages/backend/src/schemas/v2.ts index 56cd0f72..446eea8f 100644 --- a/packages/backend/src/schemas/v2.ts +++ b/packages/backend/src/schemas/v2.ts @@ -192,7 +192,6 @@ export interface GerritConfig { */ projects?: string[]; }; - revisions?: GitRevisions; } export interface LocalConfig { /** diff --git a/packages/web/src/app/repos/columns.tsx b/packages/web/src/app/repos/columns.tsx index 93f8d7f3..be39d72d 100644 --- a/packages/web/src/app/repos/columns.tsx +++ b/packages/web/src/app/repos/columns.tsx @@ -25,7 +25,7 @@ export const columns: ColumnDef[] = [ { accessorKey: "name", header: "Name", - size: 300, + size: 250, cell: ({ row }) => { const repo = row.original; const url = repo.url; @@ -34,7 +34,7 @@ export const columns: ColumnDef[] = [ return (
{ if (!isRemoteRepo) { window.open(url, "_blank"); @@ -62,7 +62,8 @@ export const columns: ColumnDef[] = [ {branches.map(({ name, version }, index) => { const shortVersion = version.substring(0, 8); return ( - + {name} @ { url: repo.Repository.URL, } }).sort((a, b) => { - return new Date(b.lastIndexed).getTime() - new Date(a.lastIndexed).getTime(); + return new Date(b.lastIndexed).getTime() - new Date(a.lastIndexed).getTime(); }); - return ( ); -} \ No newline at end of file +} diff --git a/packages/web/src/components/ui/data-table.tsx b/packages/web/src/components/ui/data-table.tsx index 05a83d1b..be09476e 100644 --- a/packages/web/src/components/ui/data-table.tsx +++ b/packages/web/src/components/ui/data-table.tsx @@ -1,4 +1,4 @@ -"use client" +"use client"; import React from "react"; import { @@ -12,16 +12,17 @@ import { getSortedRowModel, useReactTable, } from "@tanstack/react-table"; -import { - Table, - TableBody, - TableCell, - TableHead, - TableHeader, - TableRow, -} from "@/components/ui/table"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; +import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"; +import { + DropdownMenu, + DropdownMenuTrigger, + DropdownMenuContent, + DropdownMenuRadioGroup, + DropdownMenuRadioItem, +} from "@/components/ui/dropdown-menu"; +import { ChevronDown } from "lucide-react"; interface DataTableProps { columns: ColumnDef[]; @@ -40,7 +41,7 @@ export function DataTable({ const [columnFilters, setColumnFilters] = React.useState([]); const [pagination, setPagination] = React.useState({ pageIndex: 0, - pageSize: 10, // Initial page size + pageSize: 10, // Default page size }); const table = useReactTable({ @@ -60,49 +61,19 @@ export function DataTable({ getFilteredRowModel: getFilteredRowModel(), }); - React.useEffect(() => { - function calculatePageSize() { - if (typeof window !== 'undefined') { - const windowHeight = window.innerHeight; - const otherElementsHeight = 200; // Total height of other elements (header, footer, etc.) - const availableHeight = windowHeight - otherElementsHeight; - const rowHeight = 75; // Approximate height of a table row in pixels - const rowsThatFit = Math.floor(availableHeight / rowHeight); - return rowsThatFit > 0 ? rowsThatFit : 1; - } - return 10; // Default page size if window is undefined - } - - function handleResize() { - const newPageSize = calculatePageSize(); - setPagination((prev) => ({ - ...prev, - pageSize: newPageSize, - })); - } - - if (typeof window !== 'undefined') { - window.addEventListener('resize', handleResize); - handleResize(); // Initial calculation - return () => window.removeEventListener('resize', handleResize); - } - }, []); - return ( -
+
- table.getColumn(searchKey)?.setFilterValue(event.target.value) - } + value={(table.getColumn(searchKey)?.getFilterValue() as string) ?? ""} + onChange={(event) => table.getColumn(searchKey)?.setFilterValue(event.target.value)} className="max-w-sm" /> + {/* Pagination Controls */} -
- {/* Display Current Page and Total Pages */} - +
+ Page {table.getState().pagination.pageIndex + 1} of {table.getPageCount()} + + {/* Radix Dropdown for items per page */} + + + {/* Fixed width here to prevent layout shift */} + + + + + setPagination((prev) => ({ + ...prev, + pageSize: Number(value), + })) + } + > + 10 + 20 + 50 + 100 + + +
+
@@ -147,19 +146,10 @@ export function DataTable({ {table.getRowModel().rows?.length ? ( table.getRowModel().rows.map((row) => ( - + {row.getVisibleCells().map((cell) => ( - - {flexRender( - cell.column.columnDef.cell, - cell.getContext() - )} + + {flexRender(cell.column.columnDef.cell, cell.getContext())} ))} diff --git a/packages/web/src/components/ui/dropdown-menu.tsx b/packages/web/src/components/ui/dropdown-menu.tsx index f69a0d64..9224a3cc 100644 --- a/packages/web/src/components/ui/dropdown-menu.tsx +++ b/packages/web/src/components/ui/dropdown-menu.tsx @@ -47,7 +47,7 @@ const DropdownMenuSubContent = React.forwardRef<