mirror of
https://github.com/Unleash/unleash.git
synced 2025-08-13 13:48:59 +02:00
feat: rename health to technical debt (#10063)
On insights and project status, we would like to show "technica debt" instead of "health". New value is that of `1/health`, or simplified: `healthy flags / total flags`
This commit is contained in:
parent
8d7a0fdd7f
commit
37548c3436
@ -18,6 +18,7 @@ import { allOption } from 'component/common/ProjectSelect/ProjectSelect';
|
||||
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
|
||||
import { WidgetTitle } from './components/WidgetTitle/WidgetTitle.tsx';
|
||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||
import { useFlag } from '@unleash/proxy-client-react';
|
||||
|
||||
export interface IChartsProps {
|
||||
flagTrends: InstanceInsightsSchema['flagTrends'];
|
||||
@ -104,6 +105,7 @@ export const InsightsCharts: FC<IChartsProps> = ({
|
||||
const showAllProjects = projects[0] === allOption.id;
|
||||
const isOneProjectSelected = projects.length === 1;
|
||||
const { isEnterprise } = useUiConfig();
|
||||
const healthToDebtEnabled = useFlag('healthToTechDebt');
|
||||
|
||||
const lastUserTrend = userTrends[userTrends.length - 1];
|
||||
const lastFlagTrend = flagTrends[flagTrends.length - 1];
|
||||
@ -189,9 +191,15 @@ export const InsightsCharts: FC<IChartsProps> = ({
|
||||
potentiallyStale={summary.potentiallyStale}
|
||||
title={
|
||||
<WidgetTitle
|
||||
title='Health'
|
||||
title={
|
||||
healthToDebtEnabled
|
||||
? 'Technical debt'
|
||||
: 'Health'
|
||||
}
|
||||
tooltip={
|
||||
'Percentage of flags that are not stale or potentially stale.'
|
||||
healthToDebtEnabled
|
||||
? 'Percentage of stale and potentially stale flags.'
|
||||
: 'Percentage of flags that are not stale or potentially stale.'
|
||||
}
|
||||
/>
|
||||
}
|
||||
|
@ -5,6 +5,8 @@ import { Badge } from 'component/common/Badge/Badge';
|
||||
import type { TooltipState } from 'component/insights/components/LineChart/ChartTooltip/ChartTooltip';
|
||||
import { HorizontalDistributionChart } from 'component/insights/components/HorizontalDistributionChart/HorizontalDistributionChart';
|
||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||
import { useFlag } from '@unleash/proxy-client-react';
|
||||
import { getTechnicalDebtColor } from 'utils/getTechnicalDebtColor.ts';
|
||||
|
||||
const StyledTooltipItemContainer = styled(Paper)(({ theme }) => ({
|
||||
padding: theme.spacing(2),
|
||||
@ -33,6 +35,13 @@ const getHealthBadgeColor = (health?: number | null) => {
|
||||
return 'error';
|
||||
};
|
||||
|
||||
const getTechnicalDebtBadgeColor = (technicalDebt?: number | null) => {
|
||||
if (technicalDebt === undefined || technicalDebt === null) {
|
||||
return 'info';
|
||||
}
|
||||
return getTechnicalDebtColor(technicalDebt);
|
||||
};
|
||||
|
||||
const Distribution = ({ stale = 0, potentiallyStale = 0, total = 0 }) => {
|
||||
const healthyFlagCount = total - stale - potentiallyStale;
|
||||
|
||||
@ -99,12 +108,16 @@ const Distribution = ({ stale = 0, potentiallyStale = 0, total = 0 }) => {
|
||||
export const HealthTooltip: FC<{ tooltip: TooltipState | null }> = ({
|
||||
tooltip,
|
||||
}) => {
|
||||
const healthToTechDebtEnabled = useFlag('healthToTechDebt');
|
||||
|
||||
const data = tooltip?.dataPoints.map((point) => {
|
||||
return {
|
||||
label: point.label,
|
||||
title: point.dataset.label,
|
||||
color: point.dataset.borderColor,
|
||||
value: point.raw as InstanceInsightsSchemaProjectFlagTrendsItem,
|
||||
value: point.raw as InstanceInsightsSchemaProjectFlagTrendsItem & {
|
||||
technicalDebt?: number | null;
|
||||
}, // TODO: get from backend
|
||||
};
|
||||
});
|
||||
|
||||
@ -137,7 +150,9 @@ export const HealthTooltip: FC<{ tooltip: TooltipState | null }> = ({
|
||||
color='textSecondary'
|
||||
component='span'
|
||||
>
|
||||
Project health
|
||||
{healthToTechDebtEnabled
|
||||
? 'Technical debt'
|
||||
: 'Project health'}
|
||||
</Typography>
|
||||
</StyledItemHeader>
|
||||
<StyledItemHeader>
|
||||
@ -150,9 +165,21 @@ export const HealthTooltip: FC<{ tooltip: TooltipState | null }> = ({
|
||||
</Typography>
|
||||
<strong>{point.title}</strong>
|
||||
</Typography>
|
||||
<Badge color={getHealthBadgeColor(point.value.health)}>
|
||||
{point.value.health}%
|
||||
</Badge>
|
||||
{healthToTechDebtEnabled ? (
|
||||
<Badge
|
||||
color={getTechnicalDebtBadgeColor(
|
||||
point.value.technicalDebt,
|
||||
)}
|
||||
>
|
||||
{point.value.technicalDebt}%
|
||||
</Badge>
|
||||
) : (
|
||||
<Badge
|
||||
color={getHealthBadgeColor(point.value.health)}
|
||||
>
|
||||
{point.value.health}%
|
||||
</Badge>
|
||||
)}
|
||||
</StyledItemHeader>{' '}
|
||||
<Divider
|
||||
sx={(theme) => ({ margin: theme.spacing(1.5, 0) })}
|
||||
|
@ -2,7 +2,10 @@ import 'chartjs-adapter-date-fns';
|
||||
import { type FC, useMemo } from 'react';
|
||||
import type { InstanceInsightsSchema } from 'openapi';
|
||||
import { HealthTooltip } from './HealthChartTooltip/HealthChartTooltip.tsx';
|
||||
import { useProjectChartData } from 'component/insights/hooks/useProjectChartData';
|
||||
import {
|
||||
calculateTechDebt,
|
||||
useProjectChartData,
|
||||
} from 'component/insights/hooks/useProjectChartData';
|
||||
import {
|
||||
fillGradientPrimary,
|
||||
LineChart,
|
||||
@ -11,6 +14,7 @@ import {
|
||||
import { useTheme } from '@mui/material';
|
||||
import type { GroupedDataByProject } from 'component/insights/hooks/useGroupedProjectTrends';
|
||||
import { usePlaceholderData } from 'component/insights/hooks/usePlaceholderData';
|
||||
import { useFlag } from '@unleash/proxy-client-react';
|
||||
|
||||
interface IProjectHealthChartProps {
|
||||
projectFlagTrends: GroupedDataByProject<
|
||||
@ -42,6 +46,7 @@ export const ProjectHealthChart: FC<IProjectHealthChartProps> = ({
|
||||
const projectsData = useProjectChartData(projectFlagTrends);
|
||||
const theme = useTheme();
|
||||
const placeholderData = usePlaceholderData();
|
||||
const healthToTechDebtEnabled = useFlag('healthToTechDebt');
|
||||
|
||||
const aggregateHealthData = useMemo(() => {
|
||||
const labels = Array.from(
|
||||
@ -80,9 +85,18 @@ export const ProjectHealthChart: FC<IProjectHealthChartProps> = ({
|
||||
return {
|
||||
datasets: [
|
||||
{
|
||||
label: 'Health',
|
||||
label: healthToTechDebtEnabled
|
||||
? 'Technical debt'
|
||||
: 'Health',
|
||||
data: weeks.map((item) => ({
|
||||
health: item.total ? calculateHealth(item) : undefined,
|
||||
...(healthToTechDebtEnabled
|
||||
? {
|
||||
technicalDebt: item.total
|
||||
? calculateTechDebt(item)
|
||||
: undefined,
|
||||
}
|
||||
: {}),
|
||||
date: item.date,
|
||||
total: item.total,
|
||||
stale: item.stale,
|
||||
@ -117,7 +131,12 @@ export const ProjectHealthChart: FC<IProjectHealthChartProps> = ({
|
||||
notEnoughData
|
||||
? {}
|
||||
: {
|
||||
parsing: { yAxisKey: 'health', xAxisKey: 'date' },
|
||||
parsing: {
|
||||
yAxisKey: healthToTechDebtEnabled
|
||||
? 'technicalDebt'
|
||||
: 'health',
|
||||
xAxisKey: 'date',
|
||||
},
|
||||
scales: {
|
||||
y: {
|
||||
min: 0,
|
||||
|
@ -1,6 +1,7 @@
|
||||
import type { FC, ReactNode } from 'react';
|
||||
import { Box, Divider, Link, styled } from '@mui/material';
|
||||
import { ReactComponent as InstanceHealthIcon } from 'assets/icons/instance-health.svg';
|
||||
import { useFlag } from '@unleash/proxy-client-react';
|
||||
|
||||
interface IHealthStatsProps {
|
||||
value?: string | number;
|
||||
@ -69,43 +70,59 @@ export const HealthStats: FC<IHealthStatsProps> = ({
|
||||
stale,
|
||||
potentiallyStale,
|
||||
title,
|
||||
}) => (
|
||||
<StyledContainer>
|
||||
<StyledHeader>
|
||||
<StyledSection>{title}</StyledSection>
|
||||
<StyledSection>{/* TODO: trend */}</StyledSection>
|
||||
</StyledHeader>
|
||||
<Divider />
|
||||
<StyledSection>
|
||||
<StyledStatsRow>
|
||||
<StyledIcon />
|
||||
Instance health
|
||||
<StyledMainValue>{`${value || 0}%`}</StyledMainValue>
|
||||
</StyledStatsRow>
|
||||
</StyledSection>
|
||||
<Divider />
|
||||
<FlagsSection>
|
||||
<StyledStatsRow>
|
||||
Healthy flags
|
||||
<StyledValue>{healthy || 0}</StyledValue>
|
||||
</StyledStatsRow>
|
||||
<StyledStatsRow>
|
||||
Stale flags
|
||||
<StyledValue>{stale || 0}</StyledValue>
|
||||
</StyledStatsRow>
|
||||
<StyledStatsRow>
|
||||
Potentially stale flags
|
||||
<StyledValue>{potentiallyStale || 0}</StyledValue>
|
||||
</StyledStatsRow>
|
||||
<ExplanationRow>
|
||||
<Link
|
||||
href='https://docs.getunleash.io/reference/insights#health'
|
||||
target='_blank'
|
||||
rel='noreferrer'
|
||||
>
|
||||
What affects instance health?
|
||||
</Link>
|
||||
</ExplanationRow>
|
||||
</FlagsSection>
|
||||
</StyledContainer>
|
||||
);
|
||||
}) => {
|
||||
const healthToDebtEnabled = useFlag('healthToTechDebt');
|
||||
|
||||
// TODO: get the following from backend
|
||||
const unhealthy = stale + potentiallyStale;
|
||||
const technicalDebtValue = (
|
||||
(unhealthy / (healthy + unhealthy)) *
|
||||
100
|
||||
).toFixed(1);
|
||||
|
||||
return (
|
||||
<StyledContainer>
|
||||
<StyledHeader>
|
||||
<StyledSection>{title}</StyledSection>
|
||||
</StyledHeader>
|
||||
<Divider />
|
||||
<StyledSection>
|
||||
<StyledStatsRow>
|
||||
<StyledIcon />
|
||||
{healthToDebtEnabled ? 'Technical debt' : 'Instance health'}
|
||||
{healthToDebtEnabled ? (
|
||||
<StyledMainValue>{`${technicalDebtValue}%`}</StyledMainValue>
|
||||
) : (
|
||||
<StyledMainValue>{`${value || 0}%`}</StyledMainValue>
|
||||
)}
|
||||
</StyledStatsRow>
|
||||
</StyledSection>
|
||||
<Divider />
|
||||
<FlagsSection>
|
||||
<StyledStatsRow>
|
||||
Healthy flags
|
||||
<StyledValue>{healthy || 0}</StyledValue>
|
||||
</StyledStatsRow>
|
||||
<StyledStatsRow>
|
||||
Stale flags
|
||||
<StyledValue>{stale || 0}</StyledValue>
|
||||
</StyledStatsRow>
|
||||
<StyledStatsRow>
|
||||
Potentially stale flags
|
||||
<StyledValue>{potentiallyStale || 0}</StyledValue>
|
||||
</StyledStatsRow>
|
||||
<ExplanationRow>
|
||||
<Link
|
||||
href='https://docs.getunleash.io/reference/insights#health'
|
||||
target='_blank'
|
||||
rel='noreferrer'
|
||||
>
|
||||
{healthToDebtEnabled
|
||||
? 'What affects technical debt?'
|
||||
: 'What affects instance health?'}
|
||||
</Link>
|
||||
</ExplanationRow>
|
||||
</FlagsSection>
|
||||
</StyledContainer>
|
||||
);
|
||||
};
|
||||
|
@ -4,13 +4,29 @@ import { useProjectColor } from './useProjectColor.js';
|
||||
import { useTheme } from '@mui/material';
|
||||
import type { GroupedDataByProject } from './useGroupedProjectTrends.js';
|
||||
import useProjects from 'hooks/api/getters/useProjects/useProjects';
|
||||
import { useFlag } from '@unleash/proxy-client-react';
|
||||
|
||||
type ProjectFlagTrends = InstanceInsightsSchema['projectFlagTrends'];
|
||||
|
||||
export const calculateTechDebt = (item: {
|
||||
total: number;
|
||||
stale: number;
|
||||
potentiallyStale: number;
|
||||
}) => {
|
||||
if (!item.total) {
|
||||
return '0';
|
||||
}
|
||||
|
||||
return (((item.stale + item.potentiallyStale) / item.total) * 100).toFixed(
|
||||
2,
|
||||
);
|
||||
};
|
||||
|
||||
export const useProjectChartData = (
|
||||
projectFlagTrends: GroupedDataByProject<ProjectFlagTrends>,
|
||||
) => {
|
||||
const theme = useTheme();
|
||||
const healthToTechDebtEnabled = useFlag('healthToTechDebt');
|
||||
const getProjectColor = useProjectColor();
|
||||
const { projects } = useProjects();
|
||||
const projectNames = new Map(
|
||||
@ -23,7 +39,17 @@ export const useProjectChartData = (
|
||||
const color = getProjectColor(project);
|
||||
return {
|
||||
label: projectNames.get(project) || project,
|
||||
data: trends,
|
||||
data: trends.map((item) => ({
|
||||
...item,
|
||||
|
||||
...(healthToTechDebtEnabled
|
||||
? {
|
||||
technicalDebt: item.total
|
||||
? calculateTechDebt(item)
|
||||
: undefined,
|
||||
}
|
||||
: {}),
|
||||
})),
|
||||
borderColor: color,
|
||||
backgroundColor: color,
|
||||
fill: false,
|
||||
|
@ -23,6 +23,7 @@ import {
|
||||
StyledWidgetContent,
|
||||
StyledWidgetStats,
|
||||
} from '../InsightsCharts.styles';
|
||||
import { useFlag } from '@unleash/proxy-client-react';
|
||||
|
||||
export const PerformanceInsights: FC = () => {
|
||||
const statePrefix = 'performance-';
|
||||
@ -47,6 +48,8 @@ export const PerformanceInsights: FC = () => {
|
||||
state[`${statePrefix}to`]?.values[0],
|
||||
);
|
||||
|
||||
const healthToTechDebtEnabled = useFlag('healthToTechDebt');
|
||||
|
||||
const projects = state[`${statePrefix}project`]?.values ?? [allOption.id];
|
||||
|
||||
const showAllProjects = projects[0] === allOption.id;
|
||||
@ -131,12 +134,21 @@ export const PerformanceInsights: FC = () => {
|
||||
stale={summary.stale}
|
||||
potentiallyStale={summary.potentiallyStale}
|
||||
title={
|
||||
<WidgetTitle
|
||||
title='Health'
|
||||
tooltip={
|
||||
'Percentage of flags that are not stale or potentially stale.'
|
||||
}
|
||||
/>
|
||||
healthToTechDebtEnabled ? (
|
||||
<WidgetTitle
|
||||
title='Technical debt'
|
||||
tooltip={
|
||||
'Percentage of flags that are stale or potentially stale.'
|
||||
}
|
||||
/>
|
||||
) : (
|
||||
<WidgetTitle
|
||||
title='Health'
|
||||
tooltip={
|
||||
'Percentage of flags that are not stale or potentially stale.'
|
||||
}
|
||||
/>
|
||||
)
|
||||
}
|
||||
/>
|
||||
</StyledWidgetStats>
|
||||
|
@ -39,10 +39,14 @@ import { ActionBox } from './ActionBox.tsx';
|
||||
import useLoading from 'hooks/useLoading';
|
||||
import { NoProjectsContactAdmin } from './NoProjectsContactAdmin.tsx';
|
||||
import { AskOwnerToAddYouToTheirProject } from './AskOwnerToAddYouToTheirProject.tsx';
|
||||
import { useFlag } from '@unleash/proxy-client-react';
|
||||
|
||||
const ActiveProjectDetails: FC<{
|
||||
project: PersonalDashboardSchemaProjectsItem;
|
||||
}> = ({ project }) => {
|
||||
const healthToTechDebtEnabled = useFlag('healthToTechDebt');
|
||||
|
||||
const techicalDebt = 100 - project.health; // TODO: health to technical debt from backend
|
||||
return (
|
||||
<Box sx={{ display: 'flex', gap: 2 }}>
|
||||
<Box sx={{ display: 'flex', flexDirection: 'column' }}>
|
||||
@ -63,10 +67,10 @@ const ActiveProjectDetails: FC<{
|
||||
</Box>
|
||||
<Box sx={{ display: 'flex', flexDirection: 'column' }}>
|
||||
<Typography variant='subtitle2' color='primary'>
|
||||
{project.health}%
|
||||
{healthToTechDebtEnabled ? techicalDebt : project.health}%
|
||||
</Typography>
|
||||
<Typography variant='caption' color='text.secondary'>
|
||||
health
|
||||
{healthToTechDebtEnabled ? 'technical debt' : 'health'}
|
||||
</Typography>
|
||||
</Box>
|
||||
</Box>
|
||||
|
@ -4,6 +4,7 @@ import { Link } from 'react-router-dom';
|
||||
import Lightbulb from '@mui/icons-material/LightbulbOutlined';
|
||||
import type { PersonalDashboardProjectDetailsSchemaInsights } from 'openapi';
|
||||
import { ActionBox } from './ActionBox.tsx';
|
||||
import { useFlag } from '@unleash/proxy-client-react';
|
||||
|
||||
const PercentageScore = styled('span')(({ theme }) => ({
|
||||
fontWeight: theme.typography.fontWeightBold,
|
||||
@ -57,9 +58,11 @@ const ProjectHealthMessage: FC<{
|
||||
insights: PersonalDashboardProjectDetailsSchemaInsights;
|
||||
project: string;
|
||||
}> = ({ trend, insights, project }) => {
|
||||
const healthToTechDebtEnabled = useFlag('healthToTechDebt');
|
||||
const { avgHealthCurrentWindow, avgHealthPastWindow, health } = insights;
|
||||
const improveMessage =
|
||||
'Remember to archive your stale feature flags to keep the project health growing.';
|
||||
const improveMessage = healthToTechDebtEnabled
|
||||
? 'Remember to archive your stale feature flags to keep the technical debt low.'
|
||||
: 'Remember to archive your stale feature flags to keep the project health growing.';
|
||||
const keepDoingMessage =
|
||||
'This indicates that you are doing a good job of archiving your feature flags.';
|
||||
|
||||
|
@ -373,6 +373,7 @@ export const Project = () => {
|
||||
}}
|
||||
/>
|
||||
<Routes>
|
||||
{/* FIXME: remove /health with `healthToTechDebt` flag - redirect to project status */}
|
||||
<Route path='health' element={<ProjectHealth />} />
|
||||
<Route
|
||||
path='access/*'
|
||||
|
@ -5,6 +5,8 @@ import { useProjectStatus } from 'hooks/api/getters/useProjectStatus/useProjectS
|
||||
import { useRequiredPathParam } from 'hooks/useRequiredPathParam';
|
||||
import { HealthGridTile } from './ProjectHealthGrid.styles';
|
||||
import { PrettifyLargeNumber } from 'component/common/PrettifyLargeNumber/PrettifyLargeNumber';
|
||||
import { useFlag } from '@unleash/proxy-client-react';
|
||||
import { getTechnicalDebtColor } from 'utils/getTechnicalDebtColor.ts';
|
||||
|
||||
const ChartRadius = 40;
|
||||
const ChartStrokeWidth = 13;
|
||||
@ -80,6 +82,29 @@ const UnhealthyFlagBox = ({ flagCount }: { flagCount: number }) => {
|
||||
);
|
||||
};
|
||||
|
||||
const useHealthColor = (healthRating: number) => {
|
||||
const theme = useTheme();
|
||||
if (healthRating <= 24) {
|
||||
return theme.palette.error.main;
|
||||
}
|
||||
if (healthRating <= 74) {
|
||||
return theme.palette.warning.border;
|
||||
}
|
||||
return theme.palette.success.border;
|
||||
};
|
||||
|
||||
const useTechnicalDebtColor = (techicalDebt: number) => {
|
||||
const theme = useTheme();
|
||||
switch (getTechnicalDebtColor(techicalDebt)) {
|
||||
case 'error':
|
||||
return theme.palette.error.main;
|
||||
case 'warning':
|
||||
return theme.palette.warning.border;
|
||||
default:
|
||||
return theme.palette.success.border;
|
||||
}
|
||||
};
|
||||
|
||||
const Wrapper = styled(HealthGridTile)(({ theme }) => ({
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
@ -92,22 +117,21 @@ export const ProjectHealth = () => {
|
||||
const {
|
||||
data: { health, staleFlags },
|
||||
} = useProjectStatus(projectId);
|
||||
const healthRating = health.current;
|
||||
const { isOss } = useUiConfig();
|
||||
const theme = useTheme();
|
||||
const circumference = 2 * Math.PI * ChartRadius; //
|
||||
const healthToDebtEnabled = useFlag('healthToTechDebt');
|
||||
const circumference = 2 * Math.PI * ChartRadius;
|
||||
const healthRating = health.current;
|
||||
const technicalDebt = 100 - healthRating; // TODO: get from backend
|
||||
|
||||
const gapLength = 0.3;
|
||||
const filledLength = 1 - gapLength;
|
||||
const offset = 0.75 - gapLength / 2;
|
||||
const healthLength = (healthRating / 100) * circumference * 0.7;
|
||||
const technicalDebtLength = (technicalDebt / 100) * circumference * 0.7;
|
||||
|
||||
const healthColor =
|
||||
healthRating >= 0 && healthRating <= 24
|
||||
? theme.palette.error.main
|
||||
: healthRating >= 25 && healthRating <= 74
|
||||
? theme.palette.warning.border
|
||||
: theme.palette.success.border;
|
||||
const healthColor = useHealthColor(healthRating);
|
||||
const technicalDebtColor = useTechnicalDebtColor(technicalDebt);
|
||||
|
||||
return (
|
||||
<Wrapper>
|
||||
@ -129,9 +153,17 @@ export const ProjectHealth = () => {
|
||||
cy='50'
|
||||
r={ChartRadius}
|
||||
fill='none'
|
||||
stroke={healthColor}
|
||||
stroke={
|
||||
healthToDebtEnabled
|
||||
? technicalDebtColor
|
||||
: healthColor
|
||||
}
|
||||
strokeWidth={ChartStrokeWidth}
|
||||
strokeDasharray={`${healthLength} ${circumference - healthLength}`}
|
||||
strokeDasharray={
|
||||
healthToDebtEnabled
|
||||
? `${technicalDebtLength} ${circumference - technicalDebtLength}`
|
||||
: `${healthLength} ${circumference - healthLength}`
|
||||
}
|
||||
strokeDashoffset={offset * circumference}
|
||||
/>
|
||||
<text
|
||||
@ -142,17 +174,30 @@ export const ProjectHealth = () => {
|
||||
fill={theme.palette.text.primary}
|
||||
fontSize={theme.typography.h1.fontSize}
|
||||
>
|
||||
{healthRating}%
|
||||
{healthToDebtEnabled ? technicalDebt : healthRating}
|
||||
%
|
||||
</text>
|
||||
</StyledSVG>
|
||||
</SVGWrapper>
|
||||
<TextContainer>
|
||||
<Typography>
|
||||
Your current project health rating is {healthRating}%
|
||||
{healthToDebtEnabled ? (
|
||||
<>
|
||||
Your current technical debt rating is{' '}
|
||||
{technicalDebt}%.
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
Your current project health rating is{' '}
|
||||
{healthRating}%.
|
||||
</>
|
||||
)}
|
||||
</Typography>
|
||||
{!isOss() && (
|
||||
<Link to={`/insights?project=IS%3A${projectId}`}>
|
||||
View health over time
|
||||
{healthToDebtEnabled
|
||||
? 'View technical debt over time'
|
||||
: 'View health over time'}
|
||||
</Link>
|
||||
)}
|
||||
</TextContainer>
|
||||
|
@ -9,6 +9,7 @@ import { ProjectHealthGrid } from './ProjectHealthGrid.tsx';
|
||||
import { useFeedback } from 'component/feedbackNew/useFeedback';
|
||||
import FeedbackIcon from '@mui/icons-material/ChatOutlined';
|
||||
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
|
||||
import { useFlag } from '@unleash/proxy-client-react';
|
||||
|
||||
const ModalContentContainer = styled('section')(({ theme }) => ({
|
||||
minHeight: '100vh',
|
||||
@ -140,6 +141,7 @@ export const ProjectStatusModal = ({ open, onClose, onFollowLink }: Props) => {
|
||||
});
|
||||
};
|
||||
const { isOss } = useUiConfig();
|
||||
const healthToDebtEnabled = useFlag('healthToTechDebt');
|
||||
|
||||
return (
|
||||
<DynamicSidebarModal
|
||||
@ -159,7 +161,9 @@ export const ProjectStatusModal = ({ open, onClose, onFollowLink }: Props) => {
|
||||
</HeaderRow>
|
||||
<WidgetContainer>
|
||||
<Row>
|
||||
<RowHeader>Health</RowHeader>
|
||||
<RowHeader>
|
||||
{healthToDebtEnabled ? 'Technical debt' : 'Health'}
|
||||
</RowHeader>
|
||||
<ProjectHealthGrid />
|
||||
</Row>
|
||||
{!isOss() && (
|
||||
|
13
frontend/src/utils/getTechnicalDebtColor.ts
Normal file
13
frontend/src/utils/getTechnicalDebtColor.ts
Normal file
@ -0,0 +1,13 @@
|
||||
/**
|
||||
* Consistent values for boundries between healthy, warning and error colors
|
||||
* @param technicalDebt {Number} 0-100
|
||||
*/
|
||||
export const getTechnicalDebtColor = (technicalDebt: number) => {
|
||||
if (technicalDebt >= 50) {
|
||||
return 'error';
|
||||
}
|
||||
if (technicalDebt >= 25) {
|
||||
return 'warning';
|
||||
}
|
||||
return 'success';
|
||||
};
|
Loading…
Reference in New Issue
Block a user