1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-02-23 00:22:19 +01:00

Add close button, fix layout, refactor (#8755)

This PR consists of cleanup for the project status modal as well as
adding the missing button.

I've added inline comments to explain the different steps.

It now looks like this:

![image](https://github.com/user-attachments/assets/29a3c0b7-770c-4019-aaed-b363c5804138)
This commit is contained in:
Thomas Heartman 2024-11-14 15:00:32 +01:00 committed by GitHub
parent 395a4b6be3
commit b4e2d5d270
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 275 additions and 233 deletions

View File

@ -1,3 +1,3 @@
<svg width="20" height="18" viewBox="0 0 20 18" fill="none" xmlns="http://www.w3.org/2000/svg"> <svg width="20" height="18" viewBox="0 0 20 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M14.125 0C15.7917 0 17.1875 0.616667 18.3125 1.85C19.4375 3.08333 20 4.55 20 6.25C20 6.55 19.9833 6.84583 19.95 7.1375C19.9167 7.42917 19.8583 7.71667 19.775 8H13.525L11.825 5.45C11.7417 5.31667 11.625 5.20833 11.475 5.125C11.325 5.04167 11.1667 5 11 5C10.7833 5 10.5875 5.06667 10.4125 5.2C10.2375 5.33333 10.1167 5.5 10.05 5.7L8.7 9.75L7.825 8.45C7.74167 8.31667 7.625 8.20833 7.475 8.125C7.325 8.04167 7.16667 8 7 8H0.225C0.141667 7.71667 0.0833333 7.42917 0.05 7.1375C0.0166667 6.84583 0 6.55833 0 6.275C0 4.55833 0.558333 3.08333 1.675 1.85C2.79167 0.616667 4.18333 0 5.85 0C6.65 0 7.40417 0.158333 8.1125 0.475C8.82083 0.791667 9.45 1.23333 10 1.8C10.5333 1.23333 11.1542 0.791667 11.8625 0.475C12.5708 0.158333 13.325 0 14.125 0ZM10 18C9.7 18 9.4125 17.9458 9.1375 17.8375C8.8625 17.7292 8.61667 17.5667 8.4 17.35L1.7 10.625C1.6 10.525 1.50833 10.425 1.425 10.325C1.34167 10.225 1.25833 10.1167 1.175 10H6.45L8.15 12.55C8.23333 12.6833 8.35 12.7917 8.5 12.875C8.65 12.9583 8.80833 13 8.975 13C9.19167 13 9.39167 12.9333 9.575 12.8C9.75833 12.6667 9.88333 12.5 9.95 12.3L11.3 8.25L12.15 9.55C12.25 9.68333 12.375 9.79167 12.525 9.875C12.675 9.95833 12.8333 10 13 10H18.8L18.55 10.3L18.3 10.6L11.575 17.35C11.3583 17.5667 11.1167 17.7292 10.85 17.8375C10.5833 17.9458 10.3 18 10 18Z" fill="#000"/> <path d="M14.125 0C15.7917 0 17.1875 0.616667 18.3125 1.85C19.4375 3.08333 20 4.55 20 6.25C20 6.55 19.9833 6.84583 19.95 7.1375C19.9167 7.42917 19.8583 7.71667 19.775 8H13.525L11.825 5.45C11.7417 5.31667 11.625 5.20833 11.475 5.125C11.325 5.04167 11.1667 5 11 5C10.7833 5 10.5875 5.06667 10.4125 5.2C10.2375 5.33333 10.1167 5.5 10.05 5.7L8.7 9.75L7.825 8.45C7.74167 8.31667 7.625 8.20833 7.475 8.125C7.325 8.04167 7.16667 8 7 8H0.225C0.141667 7.71667 0.0833333 7.42917 0.05 7.1375C0.0166667 6.84583 0 6.55833 0 6.275C0 4.55833 0.558333 3.08333 1.675 1.85C2.79167 0.616667 4.18333 0 5.85 0C6.65 0 7.40417 0.158333 8.1125 0.475C8.82083 0.791667 9.45 1.23333 10 1.8C10.5333 1.23333 11.1542 0.791667 11.8625 0.475C12.5708 0.158333 13.325 0 14.125 0ZM10 18C9.7 18 9.4125 17.9458 9.1375 17.8375C8.8625 17.7292 8.61667 17.5667 8.4 17.35L1.7 10.625C1.6 10.525 1.50833 10.425 1.425 10.325C1.34167 10.225 1.25833 10.1167 1.175 10H6.45L8.15 12.55C8.23333 12.6833 8.35 12.7917 8.5 12.875C8.65 12.9583 8.80833 13 8.975 13C9.19167 13 9.39167 12.9333 9.575 12.8C9.75833 12.6667 9.88333 12.5 9.95 12.3L11.3 8.25L12.15 9.55C12.25 9.68333 12.375 9.79167 12.525 9.875C12.675 9.95833 12.8333 10 13 10H18.8L18.55 10.3L18.3 10.6L11.575 17.35C11.3583 17.5667 11.1167 17.7292 10.85 17.8375C10.5833 17.9458 10.3 18 10 18Z" />
</svg> </svg>

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -7,16 +7,9 @@ import { styled, Tooltip } from '@mui/material';
const StyledContainer = styled('div')(({ theme }) => ({ const StyledContainer = styled('div')(({ theme }) => ({
display: 'flex', display: 'flex',
flexDirection: 'column', flexDirection: 'column',
justifyContent: 'center',
alignItems: 'center', alignItems: 'center',
gap: theme.spacing(2),
})); }));
const TitleContainer = styled('h4')({
margin: 0,
width: '100%',
});
type Output = { date: string; count: number; level: number }; type Output = { date: string; count: number; level: number };
const ensureFullYearData = (data: Output[]): Output[] => { const ensureFullYearData = (data: Output[]): Output[] => {
@ -93,7 +86,6 @@ export const ProjectActivity = () => {
<> <>
{data.activityCountByDate.length > 0 ? ( {data.activityCountByDate.length > 0 ? (
<StyledContainer> <StyledContainer>
<TitleContainer>Activity in project</TitleContainer>
<ActivityCalendar <ActivityCalendar
theme={explicitTheme} theme={explicitTheme}
data={fullData} data={fullData}

View File

@ -3,14 +3,7 @@ import { Link } from 'react-router-dom';
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig'; import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
import { useProjectStatus } from 'hooks/api/getters/useProjectStatus/useProjectStatus'; import { useProjectStatus } from 'hooks/api/getters/useProjectStatus/useProjectStatus';
import { useRequiredPathParam } from 'hooks/useRequiredPathParam'; import { useRequiredPathParam } from 'hooks/useRequiredPathParam';
import { HealthGridTile } from './ProjectHealthGrid.styles';
const HealthContainer = styled('div')(({ theme }) => ({
backgroundColor: theme.palette.envAccordion.expanded,
padding: theme.spacing(3),
borderRadius: theme.shape.borderRadiusExtraLarge,
minWidth: '300px',
gridArea: 'health',
}));
const TextContainer = styled('div')(({ theme }) => ({ const TextContainer = styled('div')(({ theme }) => ({
display: 'flex', display: 'flex',
@ -63,7 +56,7 @@ export const ProjectHealth = () => {
: theme.palette.success.border; : theme.palette.success.border;
return ( return (
<HealthContainer> <HealthGridTile>
<ChartRow> <ChartRow>
<SVGWrapper> <SVGWrapper>
<StyledSVG viewBox='0 0 100 100'> <StyledSVG viewBox='0 0 100 100'>
@ -111,6 +104,6 @@ export const ProjectHealth = () => {
)} )}
</TextContainer> </TextContainer>
</ChartRow> </ChartRow>
</HealthContainer> </HealthGridTile>
); );
}; };

View File

@ -0,0 +1,7 @@
import { styled } from '@mui/material';
export const HealthGridTile = styled('article')(({ theme }) => ({
backgroundColor: theme.palette.envAccordion.expanded,
padding: theme.spacing(3),
borderRadius: theme.shape.borderRadiusExtraLarge,
}));

View File

@ -0,0 +1,57 @@
import { ProjectHealth } from './ProjectHealth';
import { styled } from '@mui/material';
import { StaleFlags } from './StaleFlags';
import { ProjectResources } from './ProjectResources';
const onNarrowGrid = (css: object) => ({
'@container (max-width: 650px)': css,
'@supports not (container-type: inline-size)': {
'@media (max-width: 712px)': css,
},
});
const HealthContainer = styled('div')({
containerType: 'inline-size',
});
const HealthGrid = styled('div')(({ theme }) => ({
display: 'grid',
gridTemplateAreas: `
"health resources"
"stale resources"
`,
gridTemplateColumns: 'repeat(2, minmax(300px, 1fr))',
gap: theme.spacing(1, 2),
...onNarrowGrid({
display: 'flex',
flexDirection: 'column',
gap: theme.spacing(1),
}),
}));
const Tile = styled('div', {
shouldForwardProp: (prop) => prop !== 'gridArea',
})<{ gridArea: string }>(({ theme, gridArea }) => ({
gridArea,
'&>*': {
height: '100%',
},
}));
export const ProjectHealthGrid = () => {
return (
<HealthContainer>
<HealthGrid>
<Tile gridArea='health'>
<ProjectHealth />
</Tile>
<Tile gridArea='stale'>
<StaleFlags />
</Tile>
<Tile gridArea='resources'>
<ProjectResources />
</Tile>
</HealthGrid>
</HealthContainer>
);
};

View File

@ -6,26 +6,10 @@ import { useRequiredPathParam } from 'hooks/useRequiredPathParam';
import type { FC } from 'react'; import type { FC } from 'react';
import { PrettifyLargeNumber } from 'component/common/PrettifyLargeNumber/PrettifyLargeNumber'; import { PrettifyLargeNumber } from 'component/common/PrettifyLargeNumber/PrettifyLargeNumber';
import type { ProjectStatusSchemaLifecycleSummary } from 'openapi'; import type { ProjectStatusSchemaLifecycleSummary } from 'openapi';
import { HelpIcon } from 'component/common/HelpIcon/HelpIcon';
import { HtmlTooltip } from 'component/common/HtmlTooltip/HtmlTooltip'; import { HtmlTooltip } from 'component/common/HtmlTooltip/HtmlTooltip';
import { lifecycleMessages } from './LifecycleMessages'; import { lifecycleMessages } from './LifecycleMessages';
import InfoIcon from '@mui/icons-material/Info'; import InfoIcon from '@mui/icons-material/Info';
const LifecycleRow = styled('div')(({ theme }) => ({
display: 'flex',
flexFlow: 'column',
gap: theme.spacing(1),
}));
const HeaderRow = styled('div')(({ theme }) => ({
display: 'flex',
flex: 'auto',
'& > *': {
marginBlock: 0,
fontWeight: 'normal',
},
}));
const LifecycleBoxContent = styled('div')(({ theme }) => ({ const LifecycleBoxContent = styled('div')(({ theme }) => ({
padding: theme.spacing(2), padding: theme.spacing(2),
gap: theme.spacing(4), gap: theme.spacing(4),
@ -87,6 +71,7 @@ const LifecycleList = styled('ul')(({ theme }) => ({
justifyContent: 'center', justifyContent: 'center',
padding: 0, padding: 0,
flex: 'auto', flex: 'auto',
margin: 0,
})); }));
const Counter = styled('span')({ const Counter = styled('span')({
@ -146,44 +131,6 @@ const BigNumber: FC<{ value?: number }> = ({ value }) => {
</BigText> </BigText>
); );
}; };
const TooltipContent = styled('div')(({ theme }) => ({
padding: theme.spacing(0.5),
}));
const TooltipText = styled('p')(({ theme }) => ({
fontSize: theme.typography.body1.fontSize,
'& + p': {
marginTop: theme.spacing(1),
},
}));
const LifecycleTooltip: FC = () => {
return (
<HelpIcon
htmlTooltip
htmlTooltipMaxWidth='550px'
tooltip={
<TooltipContent>
<TooltipText>
Based on usage metrics and interactions with Unleash,
feature flags can go through five distinct lifecycle
stages. These stages mirror the typical software
development process and allow you to identify
bottlenecks at any stage of the lifecycle.
</TooltipText>
<TooltipText>
<a href='https://docs.getunleash.io/reference/feature-toggles#feature-flag-lifecycle'>
Read more in our documentation
</a>
</TooltipText>
</TooltipContent>
}
/>
);
};
export const ProjectLifecycleSummary = () => { export const ProjectLifecycleSummary = () => {
const projectId = useRequiredPathParam('projectId'); const projectId = useRequiredPathParam('projectId');
const { data, loading } = useProjectStatus(projectId); const { data, loading } = useProjectStatus(projectId);
@ -200,119 +147,103 @@ export const ProjectLifecycleSummary = () => {
} }
}; };
return ( return (
<LifecycleRow> <LifecycleList ref={loadingRef}>
<HeaderRow> <LifecycleBox tooltipText={lifecycleMessages.initial}>
<h4>Flag lifecycle</h4> <p>
<LifecycleTooltip /> <Counter>
</HeaderRow> <BigNumber
value={data?.lifecycleSummary.initial.currentFlags}
/>
<LifecycleList ref={loadingRef}> <FeatureLifecycleStageIcon
<LifecycleBox tooltipText={lifecycleMessages.initial}> aria-hidden='true'
<p> stage={{ name: 'initial' }}
<Counter> />
<BigNumber </Counter>
value={ <span>{flagWord('initial')} in initial</span>
data?.lifecycleSummary.initial.currentFlags </p>
} <AverageDaysStat
/> averageDays={data?.lifecycleSummary.initial.averageDays}
/>
</LifecycleBox>
<LifecycleBox tooltipText={lifecycleMessages.preLive}>
<p>
<Counter>
<BigNumber
value={data?.lifecycleSummary.preLive.currentFlags}
/>
<FeatureLifecycleStageIcon <FeatureLifecycleStageIcon
aria-hidden='true' aria-hidden='true'
stage={{ name: 'initial' }} stage={{ name: 'pre-live' }}
/> />
</Counter> </Counter>
<span>{flagWord('initial')} in initial</span> <span>{flagWord('preLive')} in pre-live</span>
</p> </p>
<AverageDaysStat <AverageDaysStat
averageDays={data?.lifecycleSummary.initial.averageDays} averageDays={data?.lifecycleSummary.preLive.averageDays}
/> />
</LifecycleBox> </LifecycleBox>
<LifecycleBox tooltipText={lifecycleMessages.preLive}> <LifecycleBox tooltipText={lifecycleMessages.live}>
<p> <p>
<Counter> <Counter>
<BigNumber <BigNumber
value={ value={data?.lifecycleSummary.live.currentFlags}
data?.lifecycleSummary.preLive.currentFlags />
}
/>
<FeatureLifecycleStageIcon <FeatureLifecycleStageIcon
aria-hidden='true' aria-hidden='true'
stage={{ name: 'pre-live' }} stage={{ name: 'live' }}
/> />
</Counter> </Counter>
<span>{flagWord('preLive')} in pre-live</span> <span>{flagWord('live')} in live</span>
</p> </p>
<AverageDaysStat <AverageDaysStat
averageDays={data?.lifecycleSummary.preLive.averageDays} averageDays={data?.lifecycleSummary.live.averageDays}
/> />
</LifecycleBox> </LifecycleBox>
<LifecycleBox tooltipText={lifecycleMessages.live}> <LifecycleBox tooltipText={lifecycleMessages.completed}>
<p> <p>
<Counter> <Counter>
<BigNumber <BigNumber
value={data?.lifecycleSummary.live.currentFlags} value={
/> data?.lifecycleSummary.completed.currentFlags
}
/>
<FeatureLifecycleStageIcon <FeatureLifecycleStageIcon
aria-hidden='true' aria-hidden='true'
stage={{ name: 'live' }} stage={{ name: 'completed' }}
/> />
</Counter> </Counter>
<span>{flagWord('live')} in live</span> <span>{flagWord('completed')} in cleanup</span>
</p> </p>
<AverageDaysStat <AverageDaysStat
averageDays={data?.lifecycleSummary.live.averageDays} averageDays={data?.lifecycleSummary.completed.averageDays}
/> />
</LifecycleBox> </LifecycleBox>
<LifecycleBox tooltipText={lifecycleMessages.completed}> <LifecycleBox tooltipText={lifecycleMessages.archived}>
<p> <p>
<Counter> <Counter>
<BigNumber <BigNumber
value={ value={data?.lifecycleSummary.archived.currentFlags}
data?.lifecycleSummary.completed />
.currentFlags
}
/>
<FeatureLifecycleStageIcon <FeatureLifecycleStageIcon
aria-hidden='true' aria-hidden='true'
stage={{ name: 'completed' }} stage={{ name: 'archived' }}
/> />
</Counter> </Counter>
<span>{flagWord('completed')} in cleanup</span> <span>{flagWord('archived')} in archived</span>
</p> </p>
<AverageDaysStat <Stats>
averageDays={ <dt>This month</dt>
data?.lifecycleSummary.completed.averageDays <dd data-loading-project-lifecycle-summary>
} {data?.lifecycleSummary.archived.currentFlags ?? 0}{' '}
/> flags archived
</LifecycleBox> </dd>
<LifecycleBox tooltipText={lifecycleMessages.archived}> </Stats>
<p> </LifecycleBox>
<Counter> </LifecycleList>
<BigNumber
value={
data?.lifecycleSummary.archived.currentFlags
}
/>
<FeatureLifecycleStageIcon
aria-hidden='true'
stage={{ name: 'archived' }}
/>
</Counter>
<span>{flagWord('archived')} in archived</span>
</p>
<Stats>
<dt>This month</dt>
<dd data-loading-project-lifecycle-summary>
{data?.lifecycleSummary.archived.currentFlags ?? 0}{' '}
flags archived
</dd>
</Stats>
</LifecycleBox>
</LifecycleList>
</LifecycleRow>
); );
}; };

View File

@ -8,14 +8,7 @@ import SegmentsIcon from '@mui/icons-material/DonutLarge';
import ConnectedIcon from '@mui/icons-material/Cable'; import ConnectedIcon from '@mui/icons-material/Cable';
import { useProjectStatus } from 'hooks/api/getters/useProjectStatus/useProjectStatus'; import { useProjectStatus } from 'hooks/api/getters/useProjectStatus/useProjectStatus';
import useLoading from 'hooks/useLoading'; import useLoading from 'hooks/useLoading';
import { HealthGridTile } from './ProjectHealthGrid.styles';
const Wrapper = styled('article')(({ theme }) => ({
backgroundColor: theme.palette.envAccordion.expanded,
padding: theme.spacing(3),
borderRadius: theme.shape.borderRadiusExtraLarge,
minWidth: '300px',
gridArea: 'resources',
}));
const ProjectResourcesInner = styled('div')(({ theme }) => ({ const ProjectResourcesInner = styled('div')(({ theme }) => ({
display: 'flex', display: 'flex',
@ -115,7 +108,7 @@ export const ProjectResources = () => {
const loadingRef = useLoading(loading, '[data-loading-resources=true]'); const loadingRef = useLoading(loading, '[data-loading-resources=true]');
return ( return (
<Wrapper ref={loadingRef}> <HealthGridTile ref={loadingRef}>
<ProjectResourcesInner> <ProjectResourcesInner>
<Typography variant='h4' sx={{ margin: 0 }}> <Typography variant='h4' sx={{ margin: 0 }}>
Project resources Project resources
@ -155,6 +148,6 @@ export const ProjectResources = () => {
</ListItem> </ListItem>
</ResourceList> </ResourceList>
</ProjectResourcesInner> </ProjectResourcesInner>
</Wrapper> </HealthGridTile>
); );
}; };

View File

@ -1,20 +1,28 @@
import { styled } from '@mui/material'; import { Button, styled } from '@mui/material';
import { DynamicSidebarModal } from 'component/common/SidebarModal/SidebarModal'; import { DynamicSidebarModal } from 'component/common/SidebarModal/SidebarModal';
import { ProjectResources } from './ProjectResources'; import { ReactComponent as ProjectStatusSvg } from 'assets/icons/projectStatus.svg';
import { ProjectActivity } from './ProjectActivity'; import { ProjectActivity } from './ProjectActivity';
import { ProjectHealth } from './ProjectHealth';
import { ProjectLifecycleSummary } from './ProjectLifecycleSummary'; import { ProjectLifecycleSummary } from './ProjectLifecycleSummary';
import { StaleFlags } from './StaleFlags'; import type { FC } from 'react';
import { HelpIcon } from 'component/common/HelpIcon/HelpIcon';
import { ProjectHealthGrid } from './ProjectHealthGrid';
const ModalContentContainer = styled('section')(({ theme }) => ({ const ModalContentContainer = styled('section')(({ theme }) => ({
minHeight: '100vh', minHeight: '100vh',
maxWidth: 1100, maxWidth: 1100,
width: '95vw', width: '95vw',
backgroundColor: theme.palette.background.default, backgroundColor: theme.palette.background.default,
padding: theme.spacing(4),
display: 'flex', display: 'flex',
flexFlow: 'column', flexFlow: 'column',
gap: theme.spacing(4), gap: theme.spacing(4),
paddingInline: theme.spacing(4),
paddingBlock: theme.spacing(10),
}));
const WidgetContainer = styled('div')(({ theme }) => ({
display: 'flex',
flexDirection: 'column',
gap: theme.spacing(9),
})); }));
type Props = { type Props = {
@ -22,47 +30,112 @@ type Props = {
close: () => void; close: () => void;
}; };
const onNarrowGrid = (css: object) => ({ const LifecycleHeaderRow = styled('div')(({ theme }) => ({
'@container (max-width: 650px)': css, display: 'flex',
'@supports not (container-type: inline-size)': { alignItems: 'end',
'@media (max-width: 712px)': css, }));
const HeaderRow = styled('div')(({ theme }) => ({
display: 'flex',
alignItems: 'center',
gap: theme.spacing(1.5),
}));
const StyledProjectStatusSvg = styled(ProjectStatusSvg)(({ theme }) => ({
fill: theme.palette.primary.main,
}));
const ModalHeader = styled('h3')(({ theme }) => ({
fontSize: theme.typography.h2.fontSize,
margin: 0,
}));
const RowHeader = styled('h4')(({ theme }) => ({
margin: 0,
fontWeight: 'normal',
}));
const Row = styled('div')(({ theme }) => ({
display: 'flex',
flexDirection: 'column',
gap: theme.spacing(2),
}));
const TooltipContent = styled('div')(({ theme }) => ({
padding: theme.spacing(0.5),
}));
const TooltipText = styled('p')(({ theme }) => ({
fontSize: theme.typography.body1.fontSize,
'& + p': {
marginTop: theme.spacing(1),
}, },
}); }));
const HealthContainer = styled('div')({ const LifecycleTooltip: FC = () => {
containerType: 'inline-size', return (
}); <HelpIcon
htmlTooltip
htmlTooltipMaxWidth='550px'
tooltip={
<TooltipContent>
<TooltipText>
Based on usage metrics and interactions with Unleash,
feature flags can go through five distinct lifecycle
stages. These stages mirror the typical software
development process and allow you to identify
bottlenecks at any stage of the lifecycle.
</TooltipText>
const HealthGrid = styled('div')(({ theme }) => ({ <TooltipText>
display: 'grid', <a href='https://docs.getunleash.io/reference/feature-toggles#feature-flag-lifecycle'>
gridTemplateAreas: ` Read more in our documentation
"health resources" </a>
"stale resources" </TooltipText>
`, </TooltipContent>
gridTemplateColumns: '1fr 1fr', }
gap: theme.spacing(1, 2), />
...onNarrowGrid({ );
display: 'flex', };
flexDirection: 'column',
gap: theme.spacing(1), const CloseRow = styled('div')(({ theme }) => ({
}), display: 'flex',
justifyContent: 'flex-end',
marginBlockStart: 'auto',
})); }));
export const ProjectStatusModal = ({ open, close }: Props) => { export const ProjectStatusModal = ({ open, close }: Props) => {
return ( return (
<DynamicSidebarModal open={open} onClose={close} label='Project status'> <DynamicSidebarModal open={open} onClose={close} label='Project status'>
<ModalContentContainer> <ModalContentContainer>
<HealthContainer> <HeaderRow>
<HealthGrid> <StyledProjectStatusSvg aria-hidden='true' />
<ProjectHealth /> <ModalHeader>Project status</ModalHeader>
<StaleFlags /> </HeaderRow>
<ProjectResources /> <WidgetContainer>
</HealthGrid> <Row>
</HealthContainer> <RowHeader>Health</RowHeader>
<ProjectHealthGrid />
</Row>
<ProjectActivity /> <Row>
<RowHeader>Activity in project</RowHeader>
<ProjectActivity />
</Row>
<ProjectLifecycleSummary /> <Row>
<LifecycleHeaderRow>
<RowHeader>Flag lifecycle</RowHeader>
<LifecycleTooltip />
</LifecycleHeaderRow>
<ProjectLifecycleSummary />
</Row>
</WidgetContainer>
<CloseRow>
<Button variant='outlined' onClick={close}>
Close
</Button>
</CloseRow>
</ModalContentContainer> </ModalContentContainer>
</DynamicSidebarModal> </DynamicSidebarModal>
); );

View File

@ -4,13 +4,9 @@ import { PrettifyLargeNumber } from 'component/common/PrettifyLargeNumber/Pretti
import { useRequiredPathParam } from 'hooks/useRequiredPathParam'; import { useRequiredPathParam } from 'hooks/useRequiredPathParam';
import type { FC } from 'react'; import type { FC } from 'react';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import { HealthGridTile } from './ProjectHealthGrid.styles';
const Wrapper = styled('article')(({ theme }) => ({ const Wrapper = styled(HealthGridTile)(({ theme }) => ({
backgroundColor: theme.palette.envAccordion.expanded,
padding: theme.spacing(3),
borderRadius: theme.shape.borderRadiusExtraLarge,
minWidth: '300px',
gridArea: 'stale',
display: 'flex', display: 'flex',
flexDirection: 'column', flexDirection: 'column',
gap: theme.spacing(1), gap: theme.spacing(1),