mirror of
https://github.com/Unleash/unleash.git
synced 2025-01-25 00:07:47 +01:00
feat: health widget (#8686)
![image](https://github.com/user-attachments/assets/01bca9b5-ecc3-4b9e-ae58-a8af84685121)
This commit is contained in:
parent
e224417116
commit
8fc2032bfa
@ -0,0 +1,92 @@
|
||||
import type React from 'react';
|
||||
import { useTheme, Typography } from '@mui/material';
|
||||
import { styled } from '@mui/system';
|
||||
import { Link } from 'react-router-dom';
|
||||
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
|
||||
|
||||
interface ProjectHealthProps {
|
||||
health: number;
|
||||
}
|
||||
|
||||
const HealthContainer = styled('div')(({ theme }) => ({
|
||||
backgroundColor: theme.palette.envAccordion.expanded,
|
||||
padding: theme.spacing(3),
|
||||
borderRadius: theme.shape.borderRadiusExtraLarge,
|
||||
minWidth: '300px',
|
||||
fontSize: theme.spacing(1.75),
|
||||
}));
|
||||
|
||||
const ChartRow = styled('div')(({ theme }) => ({
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
}));
|
||||
|
||||
const StyledSVG = styled('svg')({
|
||||
width: 200,
|
||||
height: 100,
|
||||
});
|
||||
|
||||
const DescriptionText = styled(Typography)(({ theme }) => ({
|
||||
color: theme.palette.text.secondary,
|
||||
}));
|
||||
|
||||
export const ProjectHealth: React.FC<ProjectHealthProps> = ({ health }) => {
|
||||
const { isOss } = useUiConfig();
|
||||
const theme = useTheme();
|
||||
const radius = 40;
|
||||
const strokeWidth = 13;
|
||||
const circumference = 2 * Math.PI * radius;
|
||||
|
||||
const gapLength = 0.3;
|
||||
const filledLength = 1 - gapLength;
|
||||
const offset = 0.75 - gapLength / 2;
|
||||
const healthLength = (health / 100) * circumference * 0.7;
|
||||
|
||||
return (
|
||||
<HealthContainer>
|
||||
<ChartRow>
|
||||
<StyledSVG viewBox='0 0 100'>
|
||||
<circle
|
||||
cx='50'
|
||||
cy='50'
|
||||
r={radius}
|
||||
fill='none'
|
||||
stroke={theme.palette.grey[300]}
|
||||
strokeWidth={strokeWidth}
|
||||
strokeDasharray={`${filledLength * circumference} ${gapLength * circumference}`}
|
||||
strokeDashoffset={offset * circumference}
|
||||
/>
|
||||
<circle
|
||||
cx='50'
|
||||
cy='50'
|
||||
r={radius}
|
||||
fill='none'
|
||||
stroke={theme.palette.warning.border}
|
||||
strokeWidth={strokeWidth}
|
||||
strokeDasharray={`${healthLength} ${circumference - healthLength}`}
|
||||
strokeDashoffset={offset * circumference}
|
||||
/>
|
||||
<text
|
||||
x='50'
|
||||
y='50'
|
||||
textAnchor='middle'
|
||||
dominantBaseline='middle'
|
||||
fill={theme.palette.text.primary}
|
||||
fontSize='24px'
|
||||
>
|
||||
{health}%
|
||||
</text>
|
||||
</StyledSVG>
|
||||
<Typography variant='body2'>
|
||||
On average, your project health has remained at {health}%
|
||||
the last 4 weeks
|
||||
</Typography>
|
||||
</ChartRow>
|
||||
<DescriptionText variant='body2'>
|
||||
Remember to archive your stale feature flags to keep the project
|
||||
health growing
|
||||
</DescriptionText>
|
||||
{!isOss() && <Link to='/insights'>View health over time</Link>}
|
||||
</HealthContainer>
|
||||
);
|
||||
};
|
@ -2,6 +2,7 @@ import { styled } from '@mui/material';
|
||||
import { SidebarModal } from 'component/common/SidebarModal/SidebarModal';
|
||||
import { ProjectResources } from './ProjectResources';
|
||||
import { ProjectActivity } from './ProjectActivity';
|
||||
import { ProjectHealth } from './ProjectHealth';
|
||||
import { ProjectLifecycleSummary } from './ProjectLifecycleSummary';
|
||||
|
||||
const ModalContentContainer = styled('div')(({ theme }) => ({
|
||||
@ -36,7 +37,7 @@ export const ProjectStatusModal = ({ open, close }: Props) => {
|
||||
<SidebarModal open={open} onClose={close} label='Project status'>
|
||||
<ModalContentContainer>
|
||||
<HealthRow>
|
||||
<div>Health widget placeholder</div>
|
||||
<ProjectHealth health={50} />
|
||||
<ProjectResources />
|
||||
</HealthRow>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user