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 21, 2024
1 parent 22f7c0e commit afa5723
Show file tree
Hide file tree
Showing 10 changed files with 120 additions and 80 deletions.
12 changes: 6 additions & 6 deletions ui/src/components/table/groupings-table-skeleton.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import GroupingsTableColumns from '@/components/table/table-element/groupings-table-columns';
import { Skeleton } from '@/components/ui/skeleton';
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table';
import GroupingsTableColumns from '@/components/table/table-element/groupings-table-columns';

const GroupingsTableSkeleton = () => {
const pageSize = 7; // Average number of rows
Expand All @@ -21,9 +21,9 @@ const GroupingsTableSkeleton = () => {
<TableRow>
{GroupingsTableColumns.map((column) => (
<TableHead
key={column.accessorKey}
key={column.id}
className={`pl-[0.5rem]
${column.accessorKey !== 'name' ? 'hidden sm:table-cell' : ''}`}
${column.id !== 'name' ? 'hidden sm:table-cell' : ''}`}
>
<Skeleton className="h-5 w-36 rounded-[0.25rem]" />
</TableHead>
Expand All @@ -33,11 +33,11 @@ const GroupingsTableSkeleton = () => {
<TableBody>
{Array.from(Array(pageSize), (_, index) => (
<TableRow key={index}>
{GroupingsTableColumns.map((column) => (
{GroupingsTableColumns.map((column, index) => (
<TableCell
key={column.accessorKey}
key={column.id}
className={`p-[0.5rem]
${column.accessorKey !== 'name' ? 'hidden sm:table-cell' : ''}`}
${index > 0 ? 'hidden sm:table-cell' : ''}`}
>
<Skeleton className="h-5 w-72 rounded-[0.25rem]" />
</TableCell>
Expand Down
48 changes: 7 additions & 41 deletions ui/src/components/table/groupings-table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,13 @@ 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 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 { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faEdit } from '@fortawesome/free-regular-svg-icons';
import GroupingsTableColumns from '@/components/table/table-element/groupings-table-columns';

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

Expand All @@ -50,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 @@ -67,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,38 +84,10 @@ const GroupingsTable = ({ groupingPaths }: { groupingPaths: GroupingPath[] }) =>
{row.getVisibleCells().map((cell) => (
<TableCell
key={cell.id}
className={`${cell.column.id !== 'name' ? 'hidden sm:table-cell' : ''}`}
width={cell.column.columnDef.size}
className={`${cell.column.getIndex() > 0 ? 'hidden sm:table-cell' : ''}`}
>
<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">
<FontAwesomeIcon className="text-text-primary" data-testid={'edit-icon'} icon={faEdit} />
<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;
18 changes: 18 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,18 @@
import Link from 'next/link';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faEdit } from '@fortawesome/free-regular-svg-icons';

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

export default GroupingNameCell;
4 changes: 3 additions & 1 deletion ui/src/components/table/table-element/grouping-path-cell.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
'use client';

import { Input } from '@/components/ui/input';
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip';
import { useState } from 'react';
Expand All @@ -23,7 +25,7 @@ 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"
Expand Down
22 changes: 17 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,30 @@
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
@@ -1,4 +1,5 @@
'use client';

import React, { useEffect, useState, useRef } from 'react';
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip';

Expand All @@ -24,7 +25,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
38 changes: 12 additions & 26 deletions ui/tests/components/table/groupings-table.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,12 @@ describe('GroupingsTable', () => {
const user = userEvent.setup();

// Open column settings
await waitFor(async () => {
await user.click(screen.getByLabelText('column-settings-button'));
});
await waitFor(
async () => {
await user.click(screen.getByLabelText('column-settings-button'));
},
{ timeout: 2000 }
);

// Toggle Grouping Path Switch to true
const groupingPathSwitch = await screen.findByTestId('Grouping Path Switch');
Expand Down Expand Up @@ -122,9 +125,12 @@ describe('GroupingsTable', () => {
const user = userEvent.setup();

const toggleColumnVisibility = async (columnTestId: string, isVisible: boolean) => {
await waitFor(async () => {
await user.click(button);
});
await waitFor(
async () => {
await user.click(button);
},
{ timeout: 2000 }
);
fireEvent.click(screen.getByTestId(columnTestId));

// Check getByText('Description') or getByText('Grouping Path') to be in document
Expand Down Expand Up @@ -158,24 +164,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,28 @@
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('edit-icon')).toBeInTheDocument();
expect(screen.getByRole('link')).toHaveAttribute('href', `/groupings/${path}`)
});
});

0 comments on commit afa5723

Please sign in to comment.