From 42c2626b61d5e81d92fe032236b87da29f3a2475 Mon Sep 17 00:00:00 2001 From: Dhanus Date: Sat, 23 Aug 2025 17:37:36 +0530 Subject: [PATCH 1/3] feat: Support opening policy in new tab for easier navigation --- .../src/components/data-table/data-table.tsx | 74 ++++++++++--------- 1 file changed, 39 insertions(+), 35 deletions(-) diff --git a/apps/app/src/components/data-table/data-table.tsx b/apps/app/src/components/data-table/data-table.tsx index 9c4182fdd..f8449e6a0 100644 --- a/apps/app/src/components/data-table/data-table.tsx +++ b/apps/app/src/components/data-table/data-table.tsx @@ -1,5 +1,5 @@ import { type Table as TanstackTable, flexRender } from '@tanstack/react-table'; -import { useRouter } from 'next/navigation'; +import Link from 'next/link'; import type * as React from 'react'; import { getCommonPinningStyles } from '@/lib/data-table'; @@ -10,8 +10,8 @@ import { DataTablePagination } from './data-table-pagination'; interface DataTableProps extends React.ComponentProps<'div'> { table: TanstackTable; actionBar?: React.ReactNode; - getRowId?: (row: TData) => string; - rowClickBasePath?: string; + getRowId: (row: TData) => string; + rowClickBasePath: string; tableId?: string; onRowClick?: (row: TData) => void; } @@ -27,19 +27,12 @@ export function DataTable({ onRowClick, ...props }: DataTableProps) { - const router = useRouter(); - const handleRowClick = (row: TData) => { if (onRowClick) { onRowClick(row); } - if (getRowId) { - const id = getRowId(row); - router.push(`${rowClickBasePath}/${id}`); - } }; - // Apply client-side filtering const filteredRows = table.getFilteredRowModel().rows; return ( @@ -74,31 +67,42 @@ export function DataTable({ {filteredRows.length ? ( - filteredRows.map((row) => ( - handleRowClick(row.original)} - > - {row.getVisibleCells().map((cell, index) => ( - - {flexRender(cell.column.columnDef.cell, cell.getContext())} - - ))} - - )) + filteredRows.map((row) => { + const id = getRowId(row.original); + const href = `${rowClickBasePath}/${id}`; + + return ( + + {row.getVisibleCells().map((cell, index) => ( + + handleRowClick(row.original)} + className="block w-full h-full" + style={{ textDecoration: 'none', color: 'inherit' }} + > + {flexRender(cell.column.columnDef.cell, cell.getContext())} + + + ))} + + ); + }) ) : ( Date: Sat, 23 Aug 2025 17:45:59 +0530 Subject: [PATCH 2/3] fix: Keep the `getRowId` and `rowClickBasePath` optional --- .../src/components/data-table/data-table.tsx | 61 +++++++++++-------- 1 file changed, 37 insertions(+), 24 deletions(-) diff --git a/apps/app/src/components/data-table/data-table.tsx b/apps/app/src/components/data-table/data-table.tsx index f8449e6a0..c354e471c 100644 --- a/apps/app/src/components/data-table/data-table.tsx +++ b/apps/app/src/components/data-table/data-table.tsx @@ -1,5 +1,6 @@ import { type Table as TanstackTable, flexRender } from '@tanstack/react-table'; import Link from 'next/link'; +import { useRouter } from 'next/navigation'; import type * as React from 'react'; import { getCommonPinningStyles } from '@/lib/data-table'; @@ -10,8 +11,8 @@ import { DataTablePagination } from './data-table-pagination'; interface DataTableProps extends React.ComponentProps<'div'> { table: TanstackTable; actionBar?: React.ReactNode; - getRowId: (row: TData) => string; - rowClickBasePath: string; + getRowId?: (row: TData) => string; + rowClickBasePath?: string; tableId?: string; onRowClick?: (row: TData) => void; } @@ -27,13 +28,21 @@ export function DataTable({ onRowClick, ...props }: DataTableProps) { + const router = useRouter(); + const handleRowClick = (row: TData) => { if (onRowClick) { onRowClick(row); } + // This part of the handler will now only be used for non-link rows + if (getRowId && rowClickBasePath) { + const id = getRowId(row); + router.push(`${rowClickBasePath}/${id}`); + } }; const filteredRows = table.getFilteredRowModel().rows; + const canBeLinks = getRowId && rowClickBasePath; return (
@@ -67,17 +76,17 @@ export function DataTable({ {filteredRows.length ? ( - filteredRows.map((row) => { - const id = getRowId(row.original); - const href = `${rowClickBasePath}/${id}`; + filteredRows.map((row) => ( + handleRowClick(row.original) : undefined} + > + {row.getVisibleCells().map((cell, index) => { + const href = canBeLinks ? `${rowClickBasePath}/${getRowId(row.original)}` : ''; - return ( - - {row.getVisibleCells().map((cell, index) => ( + return ( ({ }), }} > - handleRowClick(row.original)} - className="block w-full h-full" - style={{ textDecoration: 'none', color: 'inherit' }} - > - {flexRender(cell.column.columnDef.cell, cell.getContext())} - + {canBeLinks ? ( + onRowClick && onRowClick(row.original)} + className="block" + style={{ color: 'inherit', textDecoration: 'none' }} + > + {flexRender(cell.column.columnDef.cell, cell.getContext())} + + ) : ( + flexRender(cell.column.columnDef.cell, cell.getContext()) + )} - ))} - - ); - }) + ); + })} + + )) ) : ( Date: Tue, 26 Aug 2025 03:12:50 +0530 Subject: [PATCH 3/3] chore: New tab on title click --- .../all/components/policies-table-columns.tsx | 22 ++++++++++++++---- .../all/components/policies-table.tsx | 5 ++-- .../src/components/data-table/data-table.tsx | 23 ++++--------------- 3 files changed, 25 insertions(+), 25 deletions(-) diff --git a/apps/app/src/app/(app)/[orgId]/policies/all/components/policies-table-columns.tsx b/apps/app/src/app/(app)/[orgId]/policies/all/components/policies-table-columns.tsx index 722e685db..f8ac333c8 100644 --- a/apps/app/src/app/(app)/[orgId]/policies/all/components/policies-table-columns.tsx +++ b/apps/app/src/app/(app)/[orgId]/policies/all/components/policies-table-columns.tsx @@ -5,18 +5,32 @@ import { StatusIndicator } from '@/components/status-indicator'; import { formatDate } from '@/lib/format'; import { Policy } from '@db'; import { ColumnDef } from '@tanstack/react-table'; +import { ExternalLink } from 'lucide-react'; +import Link from 'next/link'; -export function getPolicyColumns(): ColumnDef[] { +export function getPolicyColumns(orgId: string): ColumnDef[] { return [ { id: 'name', accessorKey: 'name', header: ({ column }) => , cell: ({ row }) => { + const policyName = row.getValue('name') as string; + const policyHref = `/${orgId}/policies/${row.original.id}`; + return ( -
- {row.getValue('name')} -
+ e.stopPropagation()} + className="group flex items-center gap-2" + > + + {policyName} + + + ); }, meta: { diff --git a/apps/app/src/app/(app)/[orgId]/policies/all/components/policies-table.tsx b/apps/app/src/app/(app)/[orgId]/policies/all/components/policies-table.tsx index 48f1a9957..54bb21a84 100644 --- a/apps/app/src/app/(app)/[orgId]/policies/all/components/policies-table.tsx +++ b/apps/app/src/app/(app)/[orgId]/policies/all/components/policies-table.tsx @@ -16,9 +16,10 @@ interface PoliciesTableProps { export function PoliciesTable({ promises }: PoliciesTableProps) { const [{ data, pageCount }] = React.use(promises); - const { orgId } = useParams(); + const params = useParams(); + const orgId = params.orgId as string; - const columns = React.useMemo(() => getPolicyColumns(), []); + const columns = React.useMemo(() => getPolicyColumns(orgId), [orgId]); const { table } = useDataTable({ data, diff --git a/apps/app/src/components/data-table/data-table.tsx b/apps/app/src/components/data-table/data-table.tsx index c354e471c..642cf56ad 100644 --- a/apps/app/src/components/data-table/data-table.tsx +++ b/apps/app/src/components/data-table/data-table.tsx @@ -1,5 +1,4 @@ import { type Table as TanstackTable, flexRender } from '@tanstack/react-table'; -import Link from 'next/link'; import { useRouter } from 'next/navigation'; import type * as React from 'react'; @@ -34,7 +33,6 @@ export function DataTable({ if (onRowClick) { onRowClick(row); } - // This part of the handler will now only be used for non-link rows if (getRowId && rowClickBasePath) { const id = getRowId(row); router.push(`${rowClickBasePath}/${id}`); @@ -42,7 +40,7 @@ export function DataTable({ }; const filteredRows = table.getFilteredRowModel().rows; - const canBeLinks = getRowId && rowClickBasePath; + const isRowClickable = !!(getRowId && rowClickBasePath) || !!onRowClick; return (
@@ -80,12 +78,10 @@ export function DataTable({ handleRowClick(row.original) : undefined} + className={cn(isRowClickable && 'hover:bg-muted/50 cursor-pointer')} + onClick={isRowClickable ? () => handleRowClick(row.original) : undefined} > {row.getVisibleCells().map((cell, index) => { - const href = canBeLinks ? `${rowClickBasePath}/${getRowId(row.original)}` : ''; - return ( ({ }), }} > - {canBeLinks ? ( - onRowClick && onRowClick(row.original)} - className="block" - style={{ color: 'inherit', textDecoration: 'none' }} - > - {flexRender(cell.column.columnDef.cell, cell.getContext())} - - ) : ( - flexRender(cell.column.columnDef.cell, cell.getContext()) - )} + {flexRender(cell.column.columnDef.cell, cell.getContext())} ); })}