mirror of
				https://github.com/Unleash/unleash.git
				synced 2025-10-27 11:02:16 +01:00 
			
		
		
		
	fix: add grid w/container query for projects (#8344)
The main goals of this are: 1. Make it so that the layout grid doesn't break on small screens 2. Fix an issue where the border of the box didn't fit the outline 3. (Bonus): make the layout of the info box depend on the **box's** size, not the screen size. To achieve those goals, this PR: 1. Switches to using a native CSS grid instead of MUI's grid component. This gives us more power over the layout in various different sizes. 2. Switches from putting borders on the boxes inside the grid, instead makes the grid container the color of the border and uses gaps to create borders. 3. If your browser supports it, it will use container queries to determine whether we should display the layout as a multi-column grid or in a single column. Container query demo (both with the same screen sizes): Sidebar closed:  Sidebar open: 
This commit is contained in:
		
							parent
							
								
									9b1d9f57d3
								
							
						
					
					
						commit
						35a73a5b8e
					
				@ -1,6 +1,68 @@
 | 
				
			|||||||
import { Box, Grid, styled } from '@mui/material';
 | 
					import { Box, Grid, styled } from '@mui/material';
 | 
				
			||||||
import type { Theme } from '@mui/material/styles/createTheme';
 | 
					import type { Theme } from '@mui/material/styles/createTheme';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const ContentGridContainer = styled('div')({
 | 
				
			||||||
 | 
					    containerType: 'inline-size',
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const ContentGrid2 = styled('article')(({ theme }) => {
 | 
				
			||||||
 | 
					    return {
 | 
				
			||||||
 | 
					        backgroundColor: theme.palette.divider,
 | 
				
			||||||
 | 
					        borderRadius: `${theme.shape.borderRadiusLarge}px`,
 | 
				
			||||||
 | 
					        overflow: 'hidden',
 | 
				
			||||||
 | 
					        border: `0.5px solid ${theme.palette.divider}`,
 | 
				
			||||||
 | 
					        gap: `2px`,
 | 
				
			||||||
 | 
					        display: 'flex',
 | 
				
			||||||
 | 
					        flexFlow: 'column nowrap',
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        '&>*': {
 | 
				
			||||||
 | 
					            backgroundColor: theme.palette.background.paper,
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const ProjectGrid = styled(ContentGrid2)(({ theme }) => ({
 | 
				
			||||||
 | 
					    '@container (min-width: 1000px)': {
 | 
				
			||||||
 | 
					        gridTemplateColumns: '1fr 1fr 1fr',
 | 
				
			||||||
 | 
					        display: 'grid',
 | 
				
			||||||
 | 
					        gridTemplateAreas: `
 | 
				
			||||||
 | 
					                "title onboarding onboarding"
 | 
				
			||||||
 | 
					                "projects box1 box2"
 | 
				
			||||||
 | 
					                ". owners owners"
 | 
				
			||||||
 | 
					            `,
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    '@supports not (container-type: inline-size)': {
 | 
				
			||||||
 | 
					        [theme.breakpoints.up('lg')]: {
 | 
				
			||||||
 | 
					            gridTemplateColumns: '1fr 1fr 1fr',
 | 
				
			||||||
 | 
					            display: 'grid',
 | 
				
			||||||
 | 
					            gridTemplateAreas: `
 | 
				
			||||||
 | 
					                "title onboarding onboarding"
 | 
				
			||||||
 | 
					                "projects box1 box2"
 | 
				
			||||||
 | 
					                ". owners owners"
 | 
				
			||||||
 | 
					            `,
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					}));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const SpacedGridItem2 = styled('div')(({ theme }) => ({
 | 
				
			||||||
 | 
					    padding: theme.spacing(4),
 | 
				
			||||||
 | 
					}));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const EmptyGridItem = styled('div')(({ theme }) => ({
 | 
				
			||||||
 | 
					    display: 'none',
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    '@container (min-width: 1000px)': {
 | 
				
			||||||
 | 
					        display: 'block',
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    '@supports not (container-type: inline-size)': {
 | 
				
			||||||
 | 
					        [theme.breakpoints.up('lg')]: {
 | 
				
			||||||
 | 
					            display: 'block',
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					}));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const ContentGrid = styled(Grid)(({ theme }) => ({
 | 
					export const ContentGrid = styled(Grid)(({ theme }) => ({
 | 
				
			||||||
    backgroundColor: theme.palette.background.paper,
 | 
					    backgroundColor: theme.palette.background.paper,
 | 
				
			||||||
    borderRadius: `${theme.shape.borderRadiusLarge}px`,
 | 
					    borderRadius: `${theme.shape.borderRadiusLarge}px`,
 | 
				
			||||||
 | 
				
			|||||||
@ -21,10 +21,12 @@ import type {
 | 
				
			|||||||
    PersonalDashboardSchemaProjectsItem,
 | 
					    PersonalDashboardSchemaProjectsItem,
 | 
				
			||||||
} from '../../openapi';
 | 
					} from '../../openapi';
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
    ContentGrid,
 | 
					    ContentGridContainer,
 | 
				
			||||||
 | 
					    EmptyGridItem,
 | 
				
			||||||
    ListItemBox,
 | 
					    ListItemBox,
 | 
				
			||||||
    listItemStyle,
 | 
					    listItemStyle,
 | 
				
			||||||
    SpacedGridItem,
 | 
					    ProjectGrid,
 | 
				
			||||||
 | 
					    SpacedGridItem2,
 | 
				
			||||||
} from './Grid';
 | 
					} from './Grid';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const ActiveProjectDetails: FC<{
 | 
					const ActiveProjectDetails: FC<{
 | 
				
			||||||
@ -78,104 +80,129 @@ export const MyProjects: FC<{
 | 
				
			|||||||
        activeProjectStage === 'first-flag-created';
 | 
					        activeProjectStage === 'first-flag-created';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return (
 | 
					    return (
 | 
				
			||||||
        <ContentGrid container columns={{ lg: 12, md: 1 }}>
 | 
					        <ContentGridContainer>
 | 
				
			||||||
            <SpacedGridItem item lg={4} md={1}>
 | 
					            <ProjectGrid>
 | 
				
			||||||
                <Typography variant='h3'>My projects</Typography>
 | 
					                <SpacedGridItem2
 | 
				
			||||||
            </SpacedGridItem>
 | 
					                    sx={{
 | 
				
			||||||
            <SpacedGridItem
 | 
					                        gridArea: 'title',
 | 
				
			||||||
                item
 | 
					                    }}
 | 
				
			||||||
                lg={8}
 | 
					 | 
				
			||||||
                md={1}
 | 
					 | 
				
			||||||
                sx={{ display: 'flex', justifyContent: 'flex-end' }}
 | 
					 | 
				
			||||||
            >
 | 
					 | 
				
			||||||
                {setupIncomplete ? (
 | 
					 | 
				
			||||||
                    <Badge color='warning'>Setup incomplete</Badge>
 | 
					 | 
				
			||||||
                ) : null}
 | 
					 | 
				
			||||||
            </SpacedGridItem>
 | 
					 | 
				
			||||||
            <SpacedGridItem item lg={4} md={1}>
 | 
					 | 
				
			||||||
                <List
 | 
					 | 
				
			||||||
                    disablePadding={true}
 | 
					 | 
				
			||||||
                    sx={{ maxHeight: '400px', overflow: 'auto' }}
 | 
					 | 
				
			||||||
                >
 | 
					                >
 | 
				
			||||||
                    {projects.map((project) => {
 | 
					                    <Typography variant='h3'>My projects</Typography>
 | 
				
			||||||
                        return (
 | 
					                </SpacedGridItem2>
 | 
				
			||||||
                            <ListItem
 | 
					                <SpacedGridItem2
 | 
				
			||||||
                                key={project.id}
 | 
					                    sx={{
 | 
				
			||||||
                                disablePadding={true}
 | 
					                        gridArea: 'onboarding',
 | 
				
			||||||
                                sx={{ mb: 1 }}
 | 
					                        display: 'flex',
 | 
				
			||||||
                            >
 | 
					                        justifyContent: 'flex-end',
 | 
				
			||||||
                                <ListItemButton
 | 
					                    }}
 | 
				
			||||||
                                    sx={listItemStyle}
 | 
					                >
 | 
				
			||||||
                                    selected={project.id === activeProject}
 | 
					                    {setupIncomplete ? (
 | 
				
			||||||
                                    onClick={() => setActiveProject(project.id)}
 | 
					                        <Badge color='warning'>Setup incomplete</Badge>
 | 
				
			||||||
 | 
					                    ) : null}
 | 
				
			||||||
 | 
					                </SpacedGridItem2>
 | 
				
			||||||
 | 
					                <SpacedGridItem2
 | 
				
			||||||
 | 
					                    sx={{
 | 
				
			||||||
 | 
					                        gridArea: 'projects',
 | 
				
			||||||
 | 
					                    }}
 | 
				
			||||||
 | 
					                >
 | 
				
			||||||
 | 
					                    <List
 | 
				
			||||||
 | 
					                        disablePadding={true}
 | 
				
			||||||
 | 
					                        sx={{ maxHeight: '400px', overflow: 'auto' }}
 | 
				
			||||||
 | 
					                    >
 | 
				
			||||||
 | 
					                        {projects.map((project) => {
 | 
				
			||||||
 | 
					                            return (
 | 
				
			||||||
 | 
					                                <ListItem
 | 
				
			||||||
 | 
					                                    key={project.id}
 | 
				
			||||||
 | 
					                                    disablePadding={true}
 | 
				
			||||||
 | 
					                                    sx={{ mb: 1 }}
 | 
				
			||||||
                                >
 | 
					                                >
 | 
				
			||||||
                                    <ListItemBox>
 | 
					                                    <ListItemButton
 | 
				
			||||||
                                        <ProjectIcon color='primary' />
 | 
					                                        sx={listItemStyle}
 | 
				
			||||||
                                        <StyledCardTitle>
 | 
					                                        selected={project.id === activeProject}
 | 
				
			||||||
                                            {project.name}
 | 
					                                        onClick={() =>
 | 
				
			||||||
                                        </StyledCardTitle>
 | 
					                                            setActiveProject(project.id)
 | 
				
			||||||
                                        <IconButton
 | 
					                                        }
 | 
				
			||||||
                                            component={Link}
 | 
					                                    >
 | 
				
			||||||
                                            href={`projects/${project.id}`}
 | 
					                                        <ListItemBox>
 | 
				
			||||||
                                            size='small'
 | 
					                                            <ProjectIcon color='primary' />
 | 
				
			||||||
                                            sx={{ ml: 'auto' }}
 | 
					                                            <StyledCardTitle>
 | 
				
			||||||
                                        >
 | 
					                                                {project.name}
 | 
				
			||||||
                                            <LinkIcon
 | 
					                                            </StyledCardTitle>
 | 
				
			||||||
                                                titleAccess={`projects/${project.id}`}
 | 
					                                            <IconButton
 | 
				
			||||||
 | 
					                                                component={Link}
 | 
				
			||||||
 | 
					                                                href={`projects/${project.id}`}
 | 
				
			||||||
 | 
					                                                size='small'
 | 
				
			||||||
 | 
					                                                sx={{ ml: 'auto' }}
 | 
				
			||||||
 | 
					                                            >
 | 
				
			||||||
 | 
					                                                <LinkIcon
 | 
				
			||||||
 | 
					                                                    titleAccess={`projects/${project.id}`}
 | 
				
			||||||
 | 
					                                                />
 | 
				
			||||||
 | 
					                                            </IconButton>
 | 
				
			||||||
 | 
					                                        </ListItemBox>
 | 
				
			||||||
 | 
					                                        {project.id === activeProject ? (
 | 
				
			||||||
 | 
					                                            <ActiveProjectDetails
 | 
				
			||||||
 | 
					                                                project={project}
 | 
				
			||||||
                                            />
 | 
					                                            />
 | 
				
			||||||
                                        </IconButton>
 | 
					                                        ) : null}
 | 
				
			||||||
                                    </ListItemBox>
 | 
					                                    </ListItemButton>
 | 
				
			||||||
                                    {project.id === activeProject ? (
 | 
					                                </ListItem>
 | 
				
			||||||
                                        <ActiveProjectDetails
 | 
					                            );
 | 
				
			||||||
                                            project={project}
 | 
					                        })}
 | 
				
			||||||
                                        />
 | 
					                    </List>
 | 
				
			||||||
                                    ) : null}
 | 
					                </SpacedGridItem2>
 | 
				
			||||||
                                </ListItemButton>
 | 
					                <SpacedGridItem2
 | 
				
			||||||
                            </ListItem>
 | 
					                    sx={{
 | 
				
			||||||
                        );
 | 
					                        gridArea: 'box1',
 | 
				
			||||||
                    })}
 | 
					                    }}
 | 
				
			||||||
                </List>
 | 
					                >
 | 
				
			||||||
            </SpacedGridItem>
 | 
					                    {activeProjectStage === 'onboarded' &&
 | 
				
			||||||
            <SpacedGridItem item lg={4} md={1}>
 | 
					                    personalDashboardProjectDetails ? (
 | 
				
			||||||
                {activeProjectStage === 'onboarded' &&
 | 
					                        <ProjectSetupComplete
 | 
				
			||||||
                personalDashboardProjectDetails ? (
 | 
					                            project={activeProject}
 | 
				
			||||||
                    <ProjectSetupComplete
 | 
					                            insights={personalDashboardProjectDetails.insights}
 | 
				
			||||||
                        project={activeProject}
 | 
					                        />
 | 
				
			||||||
                        insights={personalDashboardProjectDetails.insights}
 | 
					                    ) : null}
 | 
				
			||||||
                    />
 | 
					                    {activeProjectStage === 'onboarding-started' ||
 | 
				
			||||||
                ) : null}
 | 
					                    activeProjectStage === 'loading' ? (
 | 
				
			||||||
                {activeProjectStage === 'onboarding-started' ||
 | 
					                        <CreateFlag project={activeProject} />
 | 
				
			||||||
                activeProjectStage === 'loading' ? (
 | 
					                    ) : null}
 | 
				
			||||||
                    <CreateFlag project={activeProject} />
 | 
					                    {activeProjectStage === 'first-flag-created' ? (
 | 
				
			||||||
                ) : null}
 | 
					                        <ExistingFlag project={activeProject} />
 | 
				
			||||||
                {activeProjectStage === 'first-flag-created' ? (
 | 
					                    ) : null}
 | 
				
			||||||
                    <ExistingFlag project={activeProject} />
 | 
					                </SpacedGridItem2>
 | 
				
			||||||
                ) : null}
 | 
					                <SpacedGridItem2
 | 
				
			||||||
            </SpacedGridItem>
 | 
					                    sx={{
 | 
				
			||||||
            <SpacedGridItem item lg={4} md={1} sx={{ pr: 4 }}>
 | 
					                        gridArea: 'box2',
 | 
				
			||||||
                {activeProjectStage === 'onboarded' &&
 | 
					                    }}
 | 
				
			||||||
                personalDashboardProjectDetails ? (
 | 
					                >
 | 
				
			||||||
                    <LatestProjectEvents
 | 
					                    {activeProjectStage === 'onboarded' &&
 | 
				
			||||||
                        latestEvents={
 | 
					                    personalDashboardProjectDetails ? (
 | 
				
			||||||
                            personalDashboardProjectDetails.latestEvents
 | 
					                        <LatestProjectEvents
 | 
				
			||||||
                        }
 | 
					                            latestEvents={
 | 
				
			||||||
                    />
 | 
					                                personalDashboardProjectDetails.latestEvents
 | 
				
			||||||
                ) : null}
 | 
					                            }
 | 
				
			||||||
                {setupIncomplete || activeProjectStage === 'loading' ? (
 | 
					                        />
 | 
				
			||||||
                    <ConnectSDK project={activeProject} />
 | 
					                    ) : null}
 | 
				
			||||||
                ) : null}
 | 
					                    {setupIncomplete || activeProjectStage === 'loading' ? (
 | 
				
			||||||
            </SpacedGridItem>
 | 
					                        <ConnectSDK project={activeProject} />
 | 
				
			||||||
            <SpacedGridItem item lg={4} md={1} />
 | 
					                    ) : null}
 | 
				
			||||||
            <SpacedGridItem item lg={8} md={1}>
 | 
					                </SpacedGridItem2>
 | 
				
			||||||
                {personalDashboardProjectDetails ? (
 | 
					                <EmptyGridItem />
 | 
				
			||||||
                    <RoleAndOwnerInfo
 | 
					                <SpacedGridItem2
 | 
				
			||||||
                        roles={personalDashboardProjectDetails.roles.map(
 | 
					                    sx={{
 | 
				
			||||||
                            (role) => role.name,
 | 
					                        gridArea: 'owners',
 | 
				
			||||||
                        )}
 | 
					                    }}
 | 
				
			||||||
                        owners={personalDashboardProjectDetails.owners}
 | 
					                >
 | 
				
			||||||
                    />
 | 
					                    {personalDashboardProjectDetails ? (
 | 
				
			||||||
                ) : null}
 | 
					                        <RoleAndOwnerInfo
 | 
				
			||||||
            </SpacedGridItem>
 | 
					                            roles={personalDashboardProjectDetails.roles.map(
 | 
				
			||||||
        </ContentGrid>
 | 
					                                (role) => role.name,
 | 
				
			||||||
 | 
					                            )}
 | 
				
			||||||
 | 
					                            owners={personalDashboardProjectDetails.owners}
 | 
				
			||||||
 | 
					                        />
 | 
				
			||||||
 | 
					                    ) : null}
 | 
				
			||||||
 | 
					                </SpacedGridItem2>
 | 
				
			||||||
 | 
					            </ProjectGrid>
 | 
				
			||||||
 | 
					        </ContentGridContainer>
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user