Skip to content

Commit

Permalink
Refactor The GroupingsTable
Browse files Browse the repository at this point in the history
  • Loading branch information
FeimeiChen committed Oct 16, 2024
1 parent 087c7a2 commit 3a4c518
Show file tree
Hide file tree
Showing 9 changed files with 101 additions and 72 deletions.
51 changes: 7 additions & 44 deletions ui/src/components/table/groupings-table.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
'use client';

import {
useReactTable,
flexRender,
Expand All @@ -12,17 +11,14 @@ import {
} from '@tanstack/react-table';
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table';
import ColumnSettings from '@/components/table/table-element/column-settings';
import GroupingsTableColumns from '@/components/table/table-element/groupings-table-columns';

import PaginationBar from '@/components/table/table-element/pagination-bar';
import GlobalFilter from '@/components/table/table-element/global-filter';
import SortArrow from '@/components/table/table-element/sort-arrow';
import { useState } from 'react';
import { SquarePen } from 'lucide-react';
import GroupingPathCell from '@/components/table/table-element/grouping-path-cell';
import Link from 'next/link';
import { useLocalStorage } from 'usehooks-ts';
import { GroupingPath } from '@/lib/types';
import TooltipOnTruncate from '@/components/table/table-element/tooltip-on-truncate';
import GroupingsTableColumns from '@/components/table/table-element/groupings-table-columns';

const pageSize = parseInt(process.env.NEXT_PUBLIC_PAGE_SIZE as string);

Expand All @@ -49,8 +45,6 @@ const GroupingsTable = ({ groupingPaths }: { groupingPaths: GroupingPath[] }) =>
enableMultiSort: true
});

const columnCount = table.getHeaderGroups()[0].headers.length;

return (
<>
<div className="flex flex-col md:flex-row md:justify-between pt-5 mb-4">
Expand All @@ -66,13 +60,14 @@ const GroupingsTable = ({ groupingPaths }: { groupingPaths: GroupingPath[] }) =>
<TableHeader>
{table.getHeaderGroups().map((headerGroup) => (
<TableRow key={headerGroup.id}>
{headerGroup.headers.map((header, index) => (
{headerGroup.headers.map((header) => (
<TableHead
key={header.id}
onClick={header.column.getToggleSortingHandler()}
className={`
${columnCount === 2 && index === 1 ? 'w-2/3' : 'w-1/3'}
${header.column.id !== 'name' ? 'hidden sm:table-cell' : ''}`}
${!table.getIsAllColumnsVisible() && header.column.getIndex() > 0 ? 'w-2/3' : ''}
${header.column.getIndex() > 0 ? 'hidden sm:table-cell' : 'w-2/5 md:w-1/3'}
`}
>
<div className="flex items-center">
{flexRender(header.column.columnDef.header, header.getContext())}
Expand All @@ -90,41 +85,9 @@ const GroupingsTable = ({ groupingPaths }: { groupingPaths: GroupingPath[] }) =>
<TableCell
key={cell.id}
className={`${cell.column.id !== 'name' ? 'hidden sm:table-cell' : ''}`}
width={cell.column.columnDef.size}
>
<div className="flex items-center px-2 overflow-hidden whitespace-nowrap">
<div className={`m-2 ${cell.column.id === 'name' ? 'w-full' : ''}`}>
{cell.column.id === 'name' && (
<Link href={`/groupings/${cell.row.getValue('path')}`}>
<div className="flex">
<SquarePen
size="1.25em"
className="text-text-primary"
data-testid={'square-pen-icon'}
/>
<div className="pl-2">
{flexRender(cell.column.columnDef.cell, cell.getContext())}
</div>
</div>
</Link>
)}
</div>
{cell.column.id === 'description' && (
<TooltipOnTruncate value={String(cell.getValue() as string)}>
<div
className={`${
columnCount === 3
? 'truncate sm:max-w-[calc(6ch+1em)] md:max-w-[calc(40ch+1em)]'
: 'truncate'
}`}
>
{flexRender(cell.column.columnDef.cell, cell.getContext())}
</div>
</TooltipOnTruncate>
)}
{cell.column.id === 'path' && (
<GroupingPathCell path={cell.row.getValue('path')} />
)}
{flexRender(cell.column.columnDef.cell, cell.getContext())}
</div>
</TableCell>
))}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import TooltipOnTruncate from '@/components/table/table-element/tooltip-on-truncate';

const GroupingDescriptionCell = ({ description }: { description: string }) => {
return (
<TooltipOnTruncate value={description}>
<div className="truncate ml-4 pr-4 sm:mr-10 md:mr-2">{description}</div>
</TooltipOnTruncate>
);
};

export default GroupingDescriptionCell;
17 changes: 17 additions & 0 deletions ui/src/components/table/table-element/ grouping-name-cell.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import Link from 'next/link';
import { SquarePen } from 'lucide-react';

const GroupingNameCell = ({ path, name }: { path: string; name: string }) => {
return (
<div className="m-2 w-full'">
<Link href={`/groupings/${path}`}>
<div className="flex">
<SquarePen size="1.25em" className="text-text-primary" data-testid={'square-pen-icon'} />
<div className="pl-2">{name}</div>
</div>
</Link>
</div>
);
};

export default GroupingNameCell;
5 changes: 3 additions & 2 deletions ui/src/components/table/table-element/grouping-path-cell.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
'use client';
import { ClipboardIcon } from 'lucide-react';
import { Input } from '@/components/ui/input';
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip';
Expand All @@ -22,14 +23,14 @@ const GroupingPathCell = ({ path }: { path: string }) => {
};

return (
<div className="flex items-center w-full outline outline-1 rounded h-6 m-1">
<div className="flex items-center w-full outline outline-1 rounded h-6 m-1 ml-4">
<TooltipOnTruncate value={path}>
<Input
id="dataInput"
value={path}
readOnly
className="flex-1 h-6 text-input-text-grey text-[0.875rem]
border-none rounded-none w-full truncate"
border-none rounded-none w-[161px] truncate"
/>
</TooltipOnTruncate>

Expand Down
21 changes: 16 additions & 5 deletions ui/src/components/table/table-element/groupings-table-columns.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,29 @@
const GroupingsTableColumns = [
import { ColumnDef } from '@tanstack/react-table';
import { GroupingPath } from '@/lib/types';
import GroupingPathCell from '@/components/table/table-element/grouping-path-cell';
import GroupingDescriptionCell from '@/components/table/table-element/ grouping-description-cell';
import GroupingNameCell from '@/components/table/table-element/ grouping-name-cell';
const GroupingsTableColumns: ColumnDef<GroupingPath>[] = [
{
header: 'Grouping Name',
accessorKey: 'name',
enableHiding: false,
sortDescFirst: true
sortDescFirst: true,
cell: ({ row }) => (
<GroupingNameCell path={row.getValue('path')} name={row.getValue('name')}></GroupingNameCell>
)
},
{
header: 'Description',
accessorKey: 'description'
accessorKey: 'description',
cell: ({ row }) => (
<GroupingDescriptionCell description={row.getValue('description')}></GroupingDescriptionCell>
)
},
{
header: 'Grouping Path',
accessorKey: 'path'
accessorKey: 'path',
cell: ({ row }) => <GroupingPathCell path={row.getValue('path')} />
}
];

export default GroupingsTableColumns;
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@ const TooltipOnTruncate = ({ children, value }: { children: React.ReactNode; val
{children}
</TooltipTrigger>
{isTruncated && (
<TooltipContent className="max-w-[190px] max-h-[180px] text-center whitespace-normal break-words bg-black text-white">
<TooltipContent
className="max-w-[190px] max-h-[180px] text-center
whitespace-normal break-words bg-black text-white"
>
<p data-testid="tooltip-on-truncate">{value}</p>
</TooltipContent>
)}
Expand Down
20 changes: 0 additions & 20 deletions ui/tests/components/table/groupings-table.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -158,24 +158,4 @@ describe('GroupingsTable', () => {
await checkPageContent('Last', mockData.length - pageSize, mockData.length - 1);
await checkPageContent('Previous', mockData.length - pageSize * 2, mockData.length - pageSize - 1);
});
it('should show tooltip if description content is truncated', async () => {
Object.defineProperties(HTMLElement.prototype, {
scrollWidth: { get: () => 500, configurable: true },
clientWidth: { get: () => 30, configurable: true }
});
render(<GroupingsTable groupingPaths={mockData} />);
const firstButton = screen.getByText('First');

fireEvent.click(firstButton);

const description = screen.getByText('Test Description 0');
await waitFor(async () => {
await userEvent.hover(description);
});

// Wait for the tooltip to appear
await waitFor(() => {
expect(screen.getAllByTestId('tooltip-on-truncate')[0]).toBeInTheDocument();
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import React from 'react';
import { render, screen, waitFor } from '@testing-library/react';

import userEvent from '@testing-library/user-event';
import GroupingDescriptionCell from '@/components/table/table-element/ grouping-description-cell';

describe('GroupingDescriptionCell', () => {
it('renders the description inside TooltipOnTruncate', () => {
const description = 'This is a test description';
render(<GroupingDescriptionCell description={description} />);
expect(screen.getByText(description)).toBeInTheDocument();
});

it('should show tooltip if description content is truncated', async () => {
Object.defineProperties(HTMLElement.prototype, {
scrollWidth: { get: () => 500, configurable: true },
clientWidth: { get: () => 30, configurable: true }
});

const description = 'This is a test description';
render(<GroupingDescriptionCell description={description} />);

const descriptionComponent = screen.getByText(description);
await userEvent.hover(descriptionComponent);

await waitFor(() => {
expect(screen.getAllByTestId('tooltip-on-truncate')[0]).toBeInTheDocument();
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { render, screen} from '@testing-library/react';
import GroupingNameCell from '@/components/table/table-element/ grouping-name-cell';

describe('GroupingNameCell', () => {
it('renders the link with the correct path and displays the name', () => {
const path = 'test-path';
const name = 'Test Name';
render(<GroupingNameCell path={path} name={name} />);
expect(screen.getByText(name)).toBeInTheDocument();
expect(screen.getByTestId('square-pen-icon')).toBeInTheDocument();
expect(screen.getByRole('link')).toHaveAttribute('href', `/groupings/${path}`)
});
});

0 comments on commit 3a4c518

Please sign in to comment.