diff --git a/frontend/src/component/admin/apiToken/ProjectsList/ProjectsList.test.tsx b/frontend/src/component/admin/apiToken/ProjectsList/ProjectsList.test.tsx index 119b896981..38064de145 100644 --- a/frontend/src/component/admin/apiToken/ProjectsList/ProjectsList.test.tsx +++ b/frontend/src/component/admin/apiToken/ProjectsList/ProjectsList.test.tsx @@ -4,19 +4,14 @@ import { ProjectsList } from 'component/admin/apiToken/ProjectsList/ProjectsList describe('ProjectsList', () => { it('should prioritize new "projects" array over deprecated "project"', async () => { - render( + const { container } = render( , ); - const links = await screen.findAllByRole('link'); - expect(links).toHaveLength(2); - expect(links[0]).toHaveTextContent('project1'); - expect(links[1]).toHaveTextContent('project2'); - expect(links[0]).toHaveAttribute('href', '/projects/project1'); - expect(links[1]).toHaveAttribute('href', '/projects/project2'); + expect(container.textContent).toContain('2 projects'); }); it('should render correctly with single "project"', async () => { @@ -27,12 +22,6 @@ describe('ProjectsList', () => { expect(links[0]).toHaveTextContent('project'); }); - it('should have comma between project links', async () => { - const { container } = render(); - - expect(container.textContent).toContain(', '); - }); - it('should render asterisk if no projects are passed', async () => { const { container } = render(); @@ -44,4 +33,14 @@ describe('ProjectsList', () => { expect(container.textContent).toEqual('*'); }); + + it('should show the number of projects', async () => { + const { container } = render( + , + ); + + expect(container.textContent).toContain('4 projects'); + }); }); diff --git a/frontend/src/component/admin/apiToken/ProjectsList/ProjectsList.tsx b/frontend/src/component/admin/apiToken/ProjectsList/ProjectsList.tsx index 2a63fedb45..c1db052e07 100644 --- a/frontend/src/component/admin/apiToken/ProjectsList/ProjectsList.tsx +++ b/frontend/src/component/admin/apiToken/ProjectsList/ProjectsList.tsx @@ -1,8 +1,10 @@ import { styled } from '@mui/material'; import { Highlighter } from 'component/common/Highlighter/Highlighter'; +import { HtmlTooltip } from 'component/common/HtmlTooltip/HtmlTooltip'; +import { LinkCell } from 'component/common/Table/cells/LinkCell/LinkCell'; import { TextCell } from 'component/common/Table/cells/TextCell/TextCell'; import { useSearchHighlightContext } from 'component/common/Table/SearchHighlightContext/SearchHighlightContext'; -import { Fragment, type VFC } from 'react'; +import { Fragment, type FC } from 'react'; import { Link } from 'react-router-dom'; const StyledLink = styled(Link)(({ theme }) => ({ @@ -18,42 +20,69 @@ interface IProjectsListProps { projects?: string | string[]; } -export const ProjectsList: VFC = ({ - projects, - project, -}) => { +export const ProjectsList: FC = ({ projects, project }) => { const { searchQuery } = useSearchHighlightContext(); - const fields: string[] = - projects && Array.isArray(projects) - ? projects - : project - ? [project] - : []; - if (fields.length === 0) { + const projectsList = + projects && Array.isArray(projects) && projects.length > 1 + ? projects + : []; + + if (projectsList.length > 0) { return ( - * + ( + + {index > 0 && ', '} + {!item || item === '*' ? ( + + * + + ) : ( + + + {item} + + + )} + + ))} + placement='bottom-start' + arrow + tabIndex={0} + > + {`${projectsList.length}`} projects + ); } - return ( - - {fields.map((item, index) => ( - - {index > 0 && ', '} - {!item || item === '*' ? ( + if ( + (projectsList.length === 1 && projectsList[0] === '*') || + project === '*' || + (!project && (!projectsList || projectsList.length === 0)) + ) { + return ( + + + * - ) : ( - - - {item} - - - )} - - ))} - - ); + + + + ); + } + + if (projectsList.length === 1 || project) { + const item = project || projectsList[0]; + + return ; + } + + return null; }; diff --git a/frontend/src/component/common/HtmlTooltip/HtmlTooltip.tsx b/frontend/src/component/common/HtmlTooltip/HtmlTooltip.tsx index 83ff7e886a..eb58e5e141 100644 --- a/frontend/src/component/common/HtmlTooltip/HtmlTooltip.tsx +++ b/frontend/src/component/common/HtmlTooltip/HtmlTooltip.tsx @@ -68,6 +68,7 @@ export interface IHtmlTooltipProps extends TooltipProps { maxWidth?: SpacingArgument; maxHeight?: SpacingArgument; fontSize?: string; + tabIndex?: number; } export const HtmlTooltip = (props: IHtmlTooltipProps) => {