From afa572330de892abdd996edd8a437ad26210ff58 Mon Sep 17 00:00:00 2001 From: FeimeiChen <54688836+FeimeiChen@users.noreply.github.com> Date: Wed, 9 Oct 2024 14:11:44 -1000 Subject: [PATCH] Refactor The GroupingsTable --- .../table/groupings-table-skeleton.tsx | 12 ++--- ui/src/components/table/groupings-table.tsx | 48 +++---------------- .../ grouping-description-cell.tsx | 11 +++++ .../table-element/ grouping-name-cell.tsx | 18 +++++++ .../table-element/grouping-path-cell.tsx | 4 +- .../table-element/groupings-table-columns.tsx | 22 +++++++-- .../table-element/tooltip-on-truncate.tsx | 6 ++- .../components/table/groupings-table.test.tsx | 38 +++++---------- .../grouping-description-cell.test.tsx | 28 +++++++++++ .../table-element/grouping-name-cell.test.tsx | 13 +++++ 10 files changed, 120 insertions(+), 80 deletions(-) create mode 100644 ui/src/components/table/table-element/ grouping-description-cell.tsx create mode 100644 ui/src/components/table/table-element/ grouping-name-cell.tsx create mode 100644 ui/tests/components/table/table-element/grouping-description-cell.test.tsx create mode 100644 ui/tests/components/table/table-element/grouping-name-cell.test.tsx diff --git a/ui/src/components/table/groupings-table-skeleton.tsx b/ui/src/components/table/groupings-table-skeleton.tsx index 0f0b41f1..295a3221 100644 --- a/ui/src/components/table/groupings-table-skeleton.tsx +++ b/ui/src/components/table/groupings-table-skeleton.tsx @@ -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 @@ -21,9 +21,9 @@ const GroupingsTableSkeleton = () => { {GroupingsTableColumns.map((column) => ( @@ -33,11 +33,11 @@ const GroupingsTableSkeleton = () => { {Array.from(Array(pageSize), (_, index) => ( - {GroupingsTableColumns.map((column) => ( + {GroupingsTableColumns.map((column, index) => ( 0 ? 'hidden sm:table-cell' : ''}`} > diff --git a/ui/src/components/table/groupings-table.tsx b/ui/src/components/table/groupings-table.tsx index d76d69cf..241a8220 100644 --- a/ui/src/components/table/groupings-table.tsx +++ b/ui/src/components/table/groupings-table.tsx @@ -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); @@ -50,8 +45,6 @@ const GroupingsTable = ({ groupingPaths }: { groupingPaths: GroupingPath[] }) => enableMultiSort: true }); - const columnCount = table.getHeaderGroups()[0].headers.length; - return ( <>
@@ -67,13 +60,14 @@ const GroupingsTable = ({ groupingPaths }: { groupingPaths: GroupingPath[] }) => {table.getHeaderGroups().map((headerGroup) => ( - {headerGroup.headers.map((header, index) => ( + {headerGroup.headers.map((header) => ( 0 ? 'w-2/3' : ''} + ${header.column.getIndex() > 0 ? 'hidden sm:table-cell' : 'w-2/5 md:w-1/3'} + `} >
{flexRender(header.column.columnDef.header, header.getContext())} @@ -90,38 +84,10 @@ const GroupingsTable = ({ groupingPaths }: { groupingPaths: GroupingPath[] }) => {row.getVisibleCells().map((cell) => ( 0 ? 'hidden sm:table-cell' : ''}`} >
-
- {cell.column.id === 'name' && ( - -
- -
- {flexRender(cell.column.columnDef.cell, cell.getContext())} -
-
- - )} -
- {cell.column.id === 'description' && ( - -
- {flexRender(cell.column.columnDef.cell, cell.getContext())} -
-
- )} - {cell.column.id === 'path' && ( - - )} + {flexRender(cell.column.columnDef.cell, cell.getContext())}
))} diff --git a/ui/src/components/table/table-element/ grouping-description-cell.tsx b/ui/src/components/table/table-element/ grouping-description-cell.tsx new file mode 100644 index 00000000..a49c79c6 --- /dev/null +++ b/ui/src/components/table/table-element/ grouping-description-cell.tsx @@ -0,0 +1,11 @@ +import TooltipOnTruncate from '@/components/table/table-element/tooltip-on-truncate'; + +const GroupingDescriptionCell = ({ description }: { description: string }) => { + return ( + +
{description}
+
+ ); +}; + +export default GroupingDescriptionCell; diff --git a/ui/src/components/table/table-element/ grouping-name-cell.tsx b/ui/src/components/table/table-element/ grouping-name-cell.tsx new file mode 100644 index 00000000..31f22f30 --- /dev/null +++ b/ui/src/components/table/table-element/ grouping-name-cell.tsx @@ -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 ( +
+ +
+ +
{name}
+
+ +
+ ); +}; + +export default GroupingNameCell; diff --git a/ui/src/components/table/table-element/grouping-path-cell.tsx b/ui/src/components/table/table-element/grouping-path-cell.tsx index 75106d7f..d59defdd 100644 --- a/ui/src/components/table/table-element/grouping-path-cell.tsx +++ b/ui/src/components/table/table-element/grouping-path-cell.tsx @@ -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'; @@ -23,7 +25,7 @@ const GroupingPathCell = ({ path }: { path: string }) => { }; return ( -
+
[] = [ { header: 'Grouping Name', accessorKey: 'name', enableHiding: false, - sortDescFirst: true + sortDescFirst: true, + cell: ({ row }) => ( + + ) }, { header: 'Description', - accessorKey: 'description' + accessorKey: 'description', + cell: ({ row }) => ( + + ) }, { header: 'Grouping Path', - accessorKey: 'path' + accessorKey: 'path', + cell: ({ row }) => } ]; - export default GroupingsTableColumns; diff --git a/ui/src/components/table/table-element/tooltip-on-truncate.tsx b/ui/src/components/table/table-element/tooltip-on-truncate.tsx index a4104546..30bb98d4 100644 --- a/ui/src/components/table/table-element/tooltip-on-truncate.tsx +++ b/ui/src/components/table/table-element/tooltip-on-truncate.tsx @@ -1,4 +1,5 @@ 'use client'; + import React, { useEffect, useState, useRef } from 'react'; import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip'; @@ -24,7 +25,10 @@ const TooltipOnTruncate = ({ children, value }: { children: React.ReactNode; val {children} {isTruncated && ( - +

{value}

)} diff --git a/ui/tests/components/table/groupings-table.test.tsx b/ui/tests/components/table/groupings-table.test.tsx index f9b292a6..36bad6ee 100644 --- a/ui/tests/components/table/groupings-table.test.tsx +++ b/ui/tests/components/table/groupings-table.test.tsx @@ -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'); @@ -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 @@ -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(); - 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(); - }); - }); }); diff --git a/ui/tests/components/table/table-element/grouping-description-cell.test.tsx b/ui/tests/components/table/table-element/grouping-description-cell.test.tsx new file mode 100644 index 00000000..cd38b1ef --- /dev/null +++ b/ui/tests/components/table/table-element/grouping-description-cell.test.tsx @@ -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(); + 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(); + + const descriptionComponent = screen.getByText(description); + await userEvent.hover(descriptionComponent); + + await waitFor(() => { + expect(screen.getAllByTestId('tooltip-on-truncate')[0]).toBeInTheDocument(); + }); + }); +}); diff --git a/ui/tests/components/table/table-element/grouping-name-cell.test.tsx b/ui/tests/components/table/table-element/grouping-name-cell.test.tsx new file mode 100644 index 00000000..285be690 --- /dev/null +++ b/ui/tests/components/table/table-element/grouping-name-cell.test.tsx @@ -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(); + expect(screen.getByText(name)).toBeInTheDocument(); + expect(screen.getByTestId('edit-icon')).toBeInTheDocument(); + expect(screen.getByRole('link')).toHaveAttribute('href', `/groupings/${path}`) + }); +});