1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-05-17 01:17:29 +02:00

fix: prevent project cell overflow on api keys table (#7472)

Preparations for virtualizing API tokens table - projects column for tokens with a list of projects assigned will not overflow the cell.
This commit is contained in:
Tymoteusz Czech 2024-07-02 12:10:02 +02:00 committed by GitHub
parent 8a9535d352
commit e916deda74
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 72 additions and 43 deletions

View File

@ -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(
<ProjectsList
project='project'
projects={['project1', 'project2']}
/>,
);
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(<ProjectsList projects={['a', 'b']} />);
expect(container.textContent).toContain(', ');
});
it('should render asterisk if no projects are passed', async () => {
const { container } = render(<ProjectsList />);
@ -44,4 +33,14 @@ describe('ProjectsList', () => {
expect(container.textContent).toEqual('*');
});
it('should show the number of projects', async () => {
const { container } = render(
<ProjectsList
projects={['project1', 'project2', 'project3', 'project4']}
/>,
);
expect(container.textContent).toContain('4 projects');
});
});

View File

@ -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<IProjectsListProps> = ({
projects,
project,
}) => {
export const ProjectsList: FC<IProjectsListProps> = ({ 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 (
<TextCell>
<Highlighter search={searchQuery}>*</Highlighter>
<HtmlTooltip
title={projectsList.map((item, index) => (
<Fragment key={item}>
{index > 0 && ', '}
{!item || item === '*' ? (
<Highlighter search={searchQuery}>
*
</Highlighter>
) : (
<StyledLink to={`/projects/${item}`}>
<Highlighter search={searchQuery}>
{item}
</Highlighter>
</StyledLink>
)}
</Fragment>
))}
placement='bottom-start'
arrow
tabIndex={0}
>
<span>{`${projectsList.length}`} projects</span>
</HtmlTooltip>
</TextCell>
);
}
return (
<TextCell>
{fields.map((item, index) => (
<Fragment key={item}>
{index > 0 && ', '}
{!item || item === '*' ? (
if (
(projectsList.length === 1 && projectsList[0] === '*') ||
project === '*' ||
(!project && (!projectsList || projectsList.length === 0))
) {
return (
<TextCell>
<HtmlTooltip
title='ALL current and future projects'
placement='bottom'
arrow
>
<span>
<Highlighter search={searchQuery}>*</Highlighter>
) : (
<StyledLink to={`/projects/${item}`}>
<Highlighter search={searchQuery}>
{item}
</Highlighter>
</StyledLink>
)}
</Fragment>
))}
</TextCell>
);
</span>
</HtmlTooltip>
</TextCell>
);
}
if (projectsList.length === 1 || project) {
const item = project || projectsList[0];
return <LinkCell to={`/projects/${item}`} title={item} />;
}
return null;
};

View File

@ -68,6 +68,7 @@ export interface IHtmlTooltipProps extends TooltipProps {
maxWidth?: SpacingArgument;
maxHeight?: SpacingArgument;
fontSize?: string;
tabIndex?: number;
}
export const HtmlTooltip = (props: IHtmlTooltipProps) => {