mirror of
				https://github.com/Unleash/unleash.git
				synced 2025-10-27 11:02:16 +01:00 
			
		
		
		
	chore: make project list table take less horizontal space (#10480)
https://linear.app/unleash/issue/2-3761/address-ux-feedback-make-table-take-less-horizontal-space-to-prevent Addresses UX feedback by making the project list table take less horizontal space. This should prevent us from having to scroll horizontally in most cases. <img width="1103" height="647" alt="image" src="https://github.com/user-attachments/assets/e5cc22a2-5eda-4cb5-a226-c54993c019ce" />
This commit is contained in:
		
							parent
							
								
									60a2fa675b
								
							
						
					
					
						commit
						937cba4c1a
					
				@ -10,15 +10,21 @@ import { HtmlTooltip } from 'component/common/HtmlTooltip/HtmlTooltip';
 | 
			
		||||
 | 
			
		||||
type ProjectLastSeenProps = {
 | 
			
		||||
    date?: Date | number | string | null;
 | 
			
		||||
    hideLabel?: boolean;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const StyledContainer = styled(Box)(({ theme }) => ({
 | 
			
		||||
const StyledContainer = styled(Box, {
 | 
			
		||||
    shouldForwardProp: (prop) => prop !== 'secondary',
 | 
			
		||||
})<{ secondary?: boolean }>(({ theme, secondary }) => ({
 | 
			
		||||
    ...flexRow,
 | 
			
		||||
    justifyContent: 'flex-start',
 | 
			
		||||
    textWrap: 'nowrap',
 | 
			
		||||
    width: '50%',
 | 
			
		||||
    gap: theme.spacing(1),
 | 
			
		||||
    cursor: 'default',
 | 
			
		||||
    color: secondary
 | 
			
		||||
        ? theme.palette.text.secondary
 | 
			
		||||
        : theme.palette.text.primary,
 | 
			
		||||
}));
 | 
			
		||||
 | 
			
		||||
const StyledIcon = styled(StyledIconWrapper)<{ background: string }>(
 | 
			
		||||
@ -28,13 +34,18 @@ const StyledIcon = styled(StyledIconWrapper)<{ background: string }>(
 | 
			
		||||
    }),
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
const Title = () => (
 | 
			
		||||
const Title = ({ date }: Pick<ProjectLastSeenProps, 'date'>) => (
 | 
			
		||||
    <>
 | 
			
		||||
        <Typography
 | 
			
		||||
            component='span'
 | 
			
		||||
            sx={(theme) => ({ fontSize: theme.fontSizes.smallBody })}
 | 
			
		||||
        >
 | 
			
		||||
            Last usage reported
 | 
			
		||||
            Last usage reported:{' '}
 | 
			
		||||
            {date ? (
 | 
			
		||||
                <TimeAgo date={date} refresh={false} />
 | 
			
		||||
            ) : (
 | 
			
		||||
                <span>No activity</span>
 | 
			
		||||
            )}
 | 
			
		||||
        </Typography>
 | 
			
		||||
        <Typography
 | 
			
		||||
            sx={(theme) => ({
 | 
			
		||||
@ -48,32 +59,29 @@ const Title = () => (
 | 
			
		||||
    </>
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
export const ProjectLastSeen: FC<ProjectLastSeenProps> = ({ date }) => {
 | 
			
		||||
export const ProjectLastSeen: FC<ProjectLastSeenProps> = ({
 | 
			
		||||
    date,
 | 
			
		||||
    hideLabel,
 | 
			
		||||
}) => {
 | 
			
		||||
    const getColor = useLastSeenColors();
 | 
			
		||||
    const { text, background } = getColor(date);
 | 
			
		||||
 | 
			
		||||
    if (!date) {
 | 
			
		||||
        return (
 | 
			
		||||
            <HtmlTooltip title={<Title />} arrow>
 | 
			
		||||
                <StyledContainer
 | 
			
		||||
                    sx={(theme) => ({ color: theme.palette.text.secondary })}
 | 
			
		||||
                >
 | 
			
		||||
                    <StyledIcon background={background}>
 | 
			
		||||
                        <UsageLine stroke={text} />
 | 
			
		||||
                    </StyledIcon>{' '}
 | 
			
		||||
                    <div>No activity</div>
 | 
			
		||||
                </StyledContainer>
 | 
			
		||||
            </HtmlTooltip>
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return (
 | 
			
		||||
        <HtmlTooltip title={<Title />} arrow>
 | 
			
		||||
            <StyledContainer>
 | 
			
		||||
        <HtmlTooltip title={<Title date={date} />} arrow>
 | 
			
		||||
            <StyledContainer secondary={!date}>
 | 
			
		||||
                <StyledIcon background={background}>
 | 
			
		||||
                    <UsageRate stroke={text} />
 | 
			
		||||
                    {date ? (
 | 
			
		||||
                        <UsageRate stroke={text} />
 | 
			
		||||
                    ) : (
 | 
			
		||||
                        <UsageLine stroke={text} />
 | 
			
		||||
                    )}
 | 
			
		||||
                </StyledIcon>{' '}
 | 
			
		||||
                <TimeAgo date={date} refresh={false} />
 | 
			
		||||
                {!hideLabel &&
 | 
			
		||||
                    (date ? (
 | 
			
		||||
                        <TimeAgo date={date} refresh={false} />
 | 
			
		||||
                    ) : (
 | 
			
		||||
                        <div>No activity</div>
 | 
			
		||||
                    ))}
 | 
			
		||||
            </StyledContainer>
 | 
			
		||||
        </HtmlTooltip>
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,25 @@
 | 
			
		||||
import { styled } from '@mui/material';
 | 
			
		||||
import { ProjectLastSeen } from 'component/project/ProjectCard/ProjectLastSeen/ProjectLastSeen';
 | 
			
		||||
 | 
			
		||||
const StyledContainer = styled('div', {
 | 
			
		||||
    shouldForwardProp: (prop) => prop !== 'hideLabel',
 | 
			
		||||
})<{ hideLabel?: boolean }>(({ theme, hideLabel }) => ({
 | 
			
		||||
    display: 'flex',
 | 
			
		||||
    alignItems: 'center',
 | 
			
		||||
    justifyContent: hideLabel ? 'center' : 'start',
 | 
			
		||||
    padding: theme.spacing(1, 2),
 | 
			
		||||
}));
 | 
			
		||||
 | 
			
		||||
type ProjectListTableLastSeenCellProps = {
 | 
			
		||||
    value?: Date | number | string | null;
 | 
			
		||||
    hideLabel?: boolean;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const ProjectListTableLastSeenCell = ({
 | 
			
		||||
    value,
 | 
			
		||||
    hideLabel,
 | 
			
		||||
}: ProjectListTableLastSeenCellProps) => (
 | 
			
		||||
    <StyledContainer hideLabel={hideLabel}>
 | 
			
		||||
        <ProjectLastSeen date={value} hideLabel={hideLabel} />
 | 
			
		||||
    </StyledContainer>
 | 
			
		||||
);
 | 
			
		||||
@ -4,14 +4,16 @@ import { HighlightCell } from 'component/common/Table/cells/HighlightCell/Highli
 | 
			
		||||
import { TextCell } from 'component/common/Table/cells/TextCell/TextCell';
 | 
			
		||||
import { TimeAgoCell } from 'component/common/Table/cells/TimeAgoCell/TimeAgoCell';
 | 
			
		||||
import { ProjectOwners } from 'component/project/ProjectCard/ProjectCardFooter/ProjectOwners/ProjectOwners';
 | 
			
		||||
import { ProjectLastSeen } from 'component/project/ProjectCard/ProjectLastSeen/ProjectLastSeen';
 | 
			
		||||
import { useFavoriteProjectsApi } from 'hooks/api/actions/useFavoriteProjectsApi/useFavoriteProjectsApi';
 | 
			
		||||
import useProjects from 'hooks/api/getters/useProjects/useProjects';
 | 
			
		||||
import type { ProjectSchema, ProjectSchemaOwners } from 'openapi';
 | 
			
		||||
import { useCallback, useMemo } from 'react';
 | 
			
		||||
import { useFlexLayout, useTable } from 'react-table';
 | 
			
		||||
import { formatDateYMDHMS } from 'utils/formatDate';
 | 
			
		||||
import { ProjectsListTableProjectName } from './ProjectsListTableProjectName.tsx';
 | 
			
		||||
import { ProjectsListTableNameCell } from './ProjectsListTableNameCell.tsx';
 | 
			
		||||
import { useMediaQuery } from '@mui/material';
 | 
			
		||||
import theme from 'themes/theme.ts';
 | 
			
		||||
import { ProjectListTableLastSeenCell } from './ProjectListTableLastSeenCell.tsx';
 | 
			
		||||
 | 
			
		||||
type ProjectsListTableProps = {
 | 
			
		||||
    projects: ProjectSchema[];
 | 
			
		||||
@ -20,6 +22,7 @@ type ProjectsListTableProps = {
 | 
			
		||||
export const ProjectsListTable = ({ projects }: ProjectsListTableProps) => {
 | 
			
		||||
    const { refetch } = useProjects();
 | 
			
		||||
    const { favorite, unfavorite } = useFavoriteProjectsApi();
 | 
			
		||||
    const isMediumScreen = useMediaQuery(theme.breakpoints.down('lg'));
 | 
			
		||||
 | 
			
		||||
    const onFavorite = useCallback(
 | 
			
		||||
        async (project: ProjectSchema) => {
 | 
			
		||||
@ -51,7 +54,7 @@ export const ProjectsListTable = ({ projects }: ProjectsListTableProps) => {
 | 
			
		||||
                accessor: 'name',
 | 
			
		||||
                minWidth: 200,
 | 
			
		||||
                searchable: true,
 | 
			
		||||
                Cell: ProjectsListTableProjectName,
 | 
			
		||||
                Cell: ProjectsListTableNameCell,
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                Header: 'Last updated',
 | 
			
		||||
@ -64,15 +67,17 @@ export const ProjectsListTable = ({ projects }: ProjectsListTableProps) => {
 | 
			
		||||
                        dateFormat={formatDateYMDHMS}
 | 
			
		||||
                    />
 | 
			
		||||
                ),
 | 
			
		||||
                width: 150,
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                Header: 'Number of flags',
 | 
			
		||||
                Header: 'Flags',
 | 
			
		||||
                accessor: 'featureCount',
 | 
			
		||||
                Cell: ({ value }: { value: number }) => (
 | 
			
		||||
                    <TextCell>
 | 
			
		||||
                        {value} flag{value === 1 ? '' : 's'}
 | 
			
		||||
                    </TextCell>
 | 
			
		||||
                ),
 | 
			
		||||
                width: 90,
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                Header: 'Health',
 | 
			
		||||
@ -80,24 +85,30 @@ export const ProjectsListTable = ({ projects }: ProjectsListTableProps) => {
 | 
			
		||||
                Cell: ({ value }: { value: number }) => (
 | 
			
		||||
                    <TextCell>{value}%</TextCell>
 | 
			
		||||
                ),
 | 
			
		||||
                width: 100,
 | 
			
		||||
                width: 70,
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                Header: 'Last seen',
 | 
			
		||||
                accessor: 'lastReportedFlagUsage',
 | 
			
		||||
                Cell: ({ value }: { value: Date }) => (
 | 
			
		||||
                    <ProjectLastSeen date={value} />
 | 
			
		||||
                    <ProjectListTableLastSeenCell
 | 
			
		||||
                        value={value}
 | 
			
		||||
                        hideLabel={isMediumScreen}
 | 
			
		||||
                    />
 | 
			
		||||
                ),
 | 
			
		||||
                width: isMediumScreen ? 100 : 140,
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                Header: 'Owner',
 | 
			
		||||
                accessor: 'owners',
 | 
			
		||||
                Cell: ({ value }: { value: ProjectSchemaOwners }) => (
 | 
			
		||||
                    <ProjectOwners
 | 
			
		||||
                        owners={value?.filter(
 | 
			
		||||
                            (owner) => owner.ownerType !== 'system',
 | 
			
		||||
                        )}
 | 
			
		||||
                    />
 | 
			
		||||
                    <TextCell>
 | 
			
		||||
                        <ProjectOwners
 | 
			
		||||
                            owners={value?.filter(
 | 
			
		||||
                                (owner) => owner.ownerType !== 'system',
 | 
			
		||||
                            )}
 | 
			
		||||
                        />
 | 
			
		||||
                    </TextCell>
 | 
			
		||||
                ),
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
@ -106,6 +117,7 @@ export const ProjectsListTable = ({ projects }: ProjectsListTableProps) => {
 | 
			
		||||
                Cell: ({ value }: { value: number }) => (
 | 
			
		||||
                    <TextCell>{value} members</TextCell>
 | 
			
		||||
                ),
 | 
			
		||||
                width: 120,
 | 
			
		||||
            },
 | 
			
		||||
        ],
 | 
			
		||||
        [onFavorite],
 | 
			
		||||
 | 
			
		||||
@ -20,15 +20,15 @@ const StyledFeatureLink = styled(Link)({
 | 
			
		||||
    },
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
type ProjectsListTableProjectNameProps = {
 | 
			
		||||
type ProjectsListTableNameCellProps = {
 | 
			
		||||
    row: {
 | 
			
		||||
        original: ProjectSchema;
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const ProjectsListTableProjectName = ({
 | 
			
		||||
export const ProjectsListTableNameCell = ({
 | 
			
		||||
    row,
 | 
			
		||||
}: ProjectsListTableProjectNameProps) => {
 | 
			
		||||
}: ProjectsListTableNameCellProps) => {
 | 
			
		||||
    const { searchQuery } = useSearchHighlightContext();
 | 
			
		||||
 | 
			
		||||
    return (
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user