diff --git a/frontend/src/component/admin/apiToken/ApiTokenPage/ApiTokenPage.tsx b/frontend/src/component/admin/apiToken/ApiTokenPage/ApiTokenPage.tsx index ad9bb17f91..a832eceb8f 100644 --- a/frontend/src/component/admin/apiToken/ApiTokenPage/ApiTokenPage.tsx +++ b/frontend/src/component/admin/apiToken/ApiTokenPage/ApiTokenPage.tsx @@ -25,8 +25,6 @@ export const ApiTokenPage = () => { const { deleteToken } = useApiTokensApi(); const { - getTableProps, - getTableBodyProps, headerGroups, rows, prepareRow, @@ -103,8 +101,6 @@ export const ApiTokenPage = () => { headerGroups={headerGroups} setHiddenColumns={setHiddenColumns} prepareRow={prepareRow} - getTableBodyProps={getTableBodyProps} - getTableProps={getTableProps} rows={rows} columns={columns} globalFilter={globalFilter} diff --git a/frontend/src/component/admin/apiToken/ProjectsList/ProjectsList.test.tsx b/frontend/src/component/admin/apiToken/ProjectsList/ProjectsList.test.tsx index 38064de145..77fd1536b2 100644 --- a/frontend/src/component/admin/apiToken/ProjectsList/ProjectsList.test.tsx +++ b/frontend/src/component/admin/apiToken/ProjectsList/ProjectsList.test.tsx @@ -22,13 +22,13 @@ describe('ProjectsList', () => { expect(links[0]).toHaveTextContent('project'); }); - it('should render asterisk if no projects are passed', async () => { + it('should render "*" if no projects are passed', async () => { const { container } = render(); expect(container.textContent).toEqual('*'); }); - it('should render asterisk if empty projects array is passed', async () => { + it('should render "*" if empty projects array is passed', async () => { const { container } = render(); expect(container.textContent).toEqual('*'); @@ -43,4 +43,16 @@ describe('ProjectsList', () => { expect(container.textContent).toContain('4 projects'); }); + + it('should render "*" if project is "*" and no projects are passed', async () => { + const { container } = render(); + + expect(container.textContent).toEqual('*'); + }); + + it('should render "*" if projects has only "*"', async () => { + const { container } = render(); + + expect(container.textContent).toEqual('*'); + }); }); diff --git a/frontend/src/component/admin/apiToken/ProjectsList/ProjectsList.tsx b/frontend/src/component/admin/apiToken/ProjectsList/ProjectsList.tsx index c1db052e07..905fc2b9f0 100644 --- a/frontend/src/component/admin/apiToken/ProjectsList/ProjectsList.tsx +++ b/frontend/src/component/admin/apiToken/ProjectsList/ProjectsList.tsx @@ -59,30 +59,25 @@ export const ProjectsList: FC = ({ projects, project }) => { } if ( - (projectsList.length === 1 && projectsList[0] === '*') || - project === '*' || - (!project && (!projectsList || projectsList.length === 0)) + (projectsList.length === 1 && projectsList[0] !== '*') || + (project && project !== '*') ) { - return ( - - - - * - - - - ); - } - - if (projectsList.length === 1 || project) { const item = project || projectsList[0]; return ; } - return null; + return ( + + + + * + + + + ); }; diff --git a/frontend/src/component/common/ApiTokenTable/ApiTokenTable.tsx b/frontend/src/component/common/ApiTokenTable/ApiTokenTable.tsx index 5a2cb4a1ab..edb852a1e3 100644 --- a/frontend/src/component/common/ApiTokenTable/ApiTokenTable.tsx +++ b/frontend/src/component/common/ApiTokenTable/ApiTokenTable.tsx @@ -1,24 +1,6 @@ -import type { - Row, - TablePropGetter, - TableProps, - TableBodyPropGetter, - TableBodyProps, - HeaderGroup, -} from 'react-table'; -import { - SortableTableHeader, - TableCell, - TablePlaceholder, -} from 'component/common/Table'; -import { - Box, - Table, - TableBody, - TableRow, - useMediaQuery, - Link, -} from '@mui/material'; +import type { Row, HeaderGroup } from 'react-table'; +import { TablePlaceholder, VirtualizedTable } from 'component/common/Table'; +import { Box, useMediaQuery, Link } from '@mui/material'; import { SearchHighlightProvider } from 'component/common/Table/SearchHighlightContext/SearchHighlightContext'; import { ApiTokenDocs } from 'component/admin/apiToken/ApiTokenDocs/ApiTokenDocs'; @@ -27,7 +9,7 @@ import { ConditionallyRender } from 'component/common/ConditionallyRender/Condit import { useConditionallyHiddenColumns } from 'hooks/useConditionallyHiddenColumns'; -const hiddenColumnsSmall = ['Icon', 'createdAt']; +const hiddenColumnsNotExtraLarge = ['Icon', 'createdAt', 'seenAt']; const hiddenColumnsCompact = ['Icon', 'project', 'seenAt']; interface IApiTokenTableProps { @@ -37,34 +19,27 @@ interface IApiTokenTableProps { columns: any[]; rows: Row[]; prepareRow: (row: Row) => void; - getTableProps: ( - propGetter?: TablePropGetter | undefined, - ) => TableProps; - getTableBodyProps: ( - propGetter?: TableBodyPropGetter | undefined, - ) => TableBodyProps; headerGroups: HeaderGroup[]; globalFilter: any; } + export const ApiTokenTable = ({ compact = false, setHiddenColumns, columns, loading, rows, - getTableProps, - getTableBodyProps, headerGroups, globalFilter, prepareRow, }: IApiTokenTableProps) => { - const isSmallScreen = useMediaQuery(theme.breakpoints.down('md')); + const isNotExtraLarge = useMediaQuery(theme.breakpoints.down('xl')); useConditionallyHiddenColumns( [ { - condition: isSmallScreen, - columns: hiddenColumnsSmall, + condition: isNotExtraLarge, + columns: hiddenColumnsNotExtraLarge, }, { condition: compact, @@ -87,25 +62,11 @@ export const ApiTokenTable = ({ /> - - - - {rows.map((row) => { - prepareRow(row); - return ( - - {row.cells.map((cell) => ( - - {cell.render('Cell')} - - ))} - - ); - })} - -
+
} />, disableSortBy: true, disableGlobalFilter: true, + width: 50, }, { Header: 'Username', accessor: 'username', Cell: HighlightCell, + minWidth: 35, }, { Header: 'Type', @@ -43,9 +49,10 @@ export const useApiTokenTable = ( ), - minWidth: 280, + width: 180, }, { Header: 'Project', @@ -56,33 +63,33 @@ export const useApiTokenTable = ( projects={props.row.original.projects} /> ), - minWidth: 120, + width: 160, }, { Header: 'Environment', accessor: 'environment', Cell: HighlightCell, - minWidth: 120, + width: 120, }, { Header: 'Created', accessor: 'createdAt', Cell: DateCell, - minWidth: 150, + width: 150, disableGlobalFilter: true, }, { Header: 'Last seen', accessor: 'seenAt', Cell: TimeAgoCell, - minWidth: 150, + width: 140, disableGlobalFilter: true, }, { Header: 'Actions', + width: 120, id: 'Actions', align: 'center', - width: '1%', disableSortBy: true, disableGlobalFilter: true, Cell: getActionCell, @@ -110,6 +117,7 @@ export const useApiTokenTable = ( }, useGlobalFilter, useSortBy, + useFlexLayout, ); return { diff --git a/frontend/src/component/common/Table/cells/HighlightCell/HighlightCell.tsx b/frontend/src/component/common/Table/cells/HighlightCell/HighlightCell.tsx index 5a3fa544ba..3aa5c699d2 100644 --- a/frontend/src/component/common/Table/cells/HighlightCell/HighlightCell.tsx +++ b/frontend/src/component/common/Table/cells/HighlightCell/HighlightCell.tsx @@ -1,5 +1,5 @@ import type React from 'react'; -import type { VFC } from 'react'; +import type { FC } from 'react'; import { Highlighter } from 'component/common/Highlighter/Highlighter'; import { useSearchHighlightContext } from 'component/common/Table/SearchHighlightContext/SearchHighlightContext'; import { Box, styled } from '@mui/material'; @@ -10,6 +10,7 @@ interface IHighlightCellProps { value: string; subtitle?: string; afterTitle?: React.ReactNode; + subtitleTooltip?: boolean; } const StyledContainer = styled(Box)(({ theme }) => ({ @@ -40,16 +41,19 @@ const StyledSubtitle = styled('span')(({ theme }) => ({ WebkitBoxOrient: 'vertical', })); -export const HighlightCell: VFC = ({ +export const HighlightCell: FC = ({ value, subtitle, afterTitle, + subtitleTooltip, }) => { const { searchQuery } = useSearchHighlightContext(); const renderSubtitle = ( 40)} + condition={Boolean( + subtitle && (subtitle.length > 40 || subtitleTooltip), + )} show={ diff --git a/frontend/src/component/project/Project/ProjectSettings/ProjectApiAccess/ProjectApiAccess.tsx b/frontend/src/component/project/Project/ProjectSettings/ProjectApiAccess/ProjectApiAccess.tsx index 165c96d901..8fc0fa8800 100644 --- a/frontend/src/component/project/Project/ProjectSettings/ProjectApiAccess/ProjectApiAccess.tsx +++ b/frontend/src/component/project/Project/ProjectSettings/ProjectApiAccess/ProjectApiAccess.tsx @@ -117,8 +117,6 @@ export const ProjectApiAccess = () => { headerGroups={headerGroups} setHiddenColumns={setHiddenColumns} prepareRow={prepareRow} - getTableBodyProps={getTableBodyProps} - getTableProps={getTableProps} rows={rows} columns={columns} globalFilter={globalFilter}