diff --git a/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureLifecycle/FeatureLifecycleStageIcon.tsx b/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureLifecycle/FeatureLifecycleStageIcon.tsx index e8d79886c002..0b0ed1bb3f7d 100644 --- a/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureLifecycle/FeatureLifecycleStageIcon.tsx +++ b/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureLifecycle/FeatureLifecycleStageIcon.tsx @@ -6,18 +6,16 @@ import { ReactComponent as CompletedStageIcon } from 'assets/icons/stage-complet import { ReactComponent as ArchivedStageIcon } from 'assets/icons/stage-archived.svg'; import type { LifecycleStage } from './LifecycleStage'; -export const FeatureLifecycleStageIcon: FC<{ stage: LifecycleStage }> = ({ - stage, -}) => { +export const FeatureLifecycleStageIcon: FC<{ + stage: Pick; +}> = ({ stage }) => { if (stage.name === 'archived') { return ; } else if (stage.name === 'pre-live') { return ; } else if (stage.name === 'live') { return ; - } else if (stage.name === 'completed' && stage.status === 'kept') { - return ; - } else if (stage.name === 'completed' && stage.status === 'discarded') { + } else if (stage.name === 'completed') { return ; } else { return ; diff --git a/frontend/src/component/project/Project/ProjectStatus/ProjectLifecycleSummary.tsx b/frontend/src/component/project/Project/ProjectStatus/ProjectLifecycleSummary.tsx index 972269351186..5bd0c6000938 100644 --- a/frontend/src/component/project/Project/ProjectStatus/ProjectLifecycleSummary.tsx +++ b/frontend/src/component/project/Project/ProjectStatus/ProjectLifecycleSummary.tsx @@ -1,6 +1,9 @@ import { styled } from '@mui/material'; import { FeatureLifecycleStageIcon } from 'component/feature/FeatureView/FeatureOverview/FeatureLifecycle/FeatureLifecycleStageIcon'; +import { useProjectStatus } from 'hooks/api/getters/useProjectStatus/useProjectStatus'; +import useLoading from 'hooks/useLoading'; import { useRequiredPathParam } from 'hooks/useRequiredPathParam'; +import type { FC } from 'react'; import { Link } from 'react-router-dom'; const LifecycleBox = styled('li')(({ theme }) => ({ @@ -41,10 +44,6 @@ const Stats = styled('dl')(({ theme }) => ({ }, })); -const NegativeStat = styled('span')(({ theme }) => ({ - color: theme.palette.warning.contrastText, -})); - const NoData = styled('span')({ fontWeight: 'normal', }); @@ -53,123 +52,128 @@ const LinkNoUnderline = styled(Link)({ textDecoration: 'none', }); +const AverageDaysStat: FC<{ averageDays?: number | null }> = ({ + averageDays, +}) => { + const Content = () => { + if (averageDays === null || averageDays === undefined) { + return No data; + } + + return `${averageDays} days`; + }; + return ( + +
Avg. time in stage
+
+ +
+
+ ); +}; + export const ProjectLifecycleSummary = () => { const projectId = useRequiredPathParam('projectId'); + const { data, loading } = useProjectStatus(projectId); + + const loadingRef = useLoading( + loading, + '[data-loading-project-lifecycle-summary=true]', + ); return ( - +

- 15 + + {data?.lifecycleSummary.initial.currentFlags ?? 0} + flags in initial

- -
Avg. time in stage
-
- 21 days -
-
+

- 3 + + {data?.lifecycleSummary.preLive.currentFlags ?? 0} + flags in pre-live

- -
Avg. time in stage
-
18 days
-
+

- 2 + + {data?.lifecycleSummary.live.currentFlags ?? 0} + flags in live

- -
Avg. time in stage
-
10 days
-
+

- 6 + + {data?.lifecycleSummary.completed.currentFlags ?? 0} + - - - flags - {' '} - in cleanup - + flags in cleanup

- -
Avg. time in stage
-
- No data -
-
+

- 15 + + {data?.lifecycleSummary.archived.currentFlags ?? 0} + flags in archived

This month
-
3 flags archived
+
+ {data?.lifecycleSummary.archived.currentFlags ?? 0}{' '} + flags archived +
diff --git a/frontend/src/hooks/useLoading.ts b/frontend/src/hooks/useLoading.ts index 9db84aff32f0..6e05e1f5b8de 100644 --- a/frontend/src/hooks/useLoading.ts +++ b/frontend/src/hooks/useLoading.ts @@ -1,9 +1,10 @@ import { createRef, useLayoutEffect } from 'react'; -type refElement = HTMLDivElement; - -const useLoading = (loading: boolean, selector = '[data-loading=true]') => { - const ref = createRef(); +const useLoading = ( + loading: boolean, + selector = '[data-loading=true]', +) => { + const ref = createRef(); useLayoutEffect(() => { if (ref.current) { const elements = ref.current.querySelectorAll(selector);