mirror of
				https://github.com/Unleash/unleash.git
				synced 2025-10-27 11:02:16 +01: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:
		
							parent
							
								
									8a9535d352
								
							
						
					
					
						commit
						e916deda74
					
				@ -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');
 | 
			
		||||
    });
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
@ -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;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -68,6 +68,7 @@ export interface IHtmlTooltipProps extends TooltipProps {
 | 
			
		||||
    maxWidth?: SpacingArgument;
 | 
			
		||||
    maxHeight?: SpacingArgument;
 | 
			
		||||
    fontSize?: string;
 | 
			
		||||
    tabIndex?: number;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export const HtmlTooltip = (props: IHtmlTooltipProps) => {
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user