From 8c60929fb70f95a67a39d0ce31a6623155c071db Mon Sep 17 00:00:00 2001 From: Thomas Heartman Date: Tue, 12 Nov 2024 14:50:48 +0100 Subject: [PATCH 01/11] 1-3083: wrap up lifecycle summary component --- .../ProjectStatus/ProjectLifecycleSummary.tsx | 228 ++++++++++-------- 1 file changed, 129 insertions(+), 99 deletions(-) diff --git a/frontend/src/component/project/Project/ProjectStatus/ProjectLifecycleSummary.tsx b/frontend/src/component/project/Project/ProjectStatus/ProjectLifecycleSummary.tsx index ecf58ea9b19d..d21bae6b52a7 100644 --- a/frontend/src/component/project/Project/ProjectStatus/ProjectLifecycleSummary.tsx +++ b/frontend/src/component/project/Project/ProjectStatus/ProjectLifecycleSummary.tsx @@ -6,6 +6,20 @@ import { useRequiredPathParam } from 'hooks/useRequiredPathParam'; import type { FC } from 'react'; import { PrettifyLargeNumber } from 'component/common/PrettifyLargeNumber/PrettifyLargeNumber'; import type { ProjectStatusSchemaLifecycleSummary } from 'openapi'; +import { Link } from 'react-router-dom'; + +const LifecycleRow = styled('div')(({ theme }) => ({ + display: 'flex', + gap: theme.spacing(4), +})); + +const HeaderRow = styled('div')(({ theme }) => ({ + display: 'flex', + gap: theme.spacing(2), + justifyContent: 'space-between', + flex: 'auto', +})); + const LifecycleBox = styled('li')(({ theme }) => ({ padding: theme.spacing(2), borderRadius: theme.shape.borderRadiusExtraLarge, @@ -16,13 +30,14 @@ const LifecycleBox = styled('li')(({ theme }) => ({ justifyContent: 'space-between', })); -const Wrapper = styled('ul')(({ theme }) => ({ +const LifecycleList = styled('ul')(({ theme }) => ({ display: 'grid', listStyle: 'none', gridTemplateColumns: 'repeat(auto-fit, minmax(180px, 1fr))', gap: theme.spacing(1), justifyContent: 'center', padding: 0, + flex: 'auto', })); const Counter = styled('span')({ @@ -99,103 +114,118 @@ export const ProjectLifecycleSummary = () => { } }; return ( - - -

- - - - - {flagWord('initial')} in initial -

- -
- -

- - - - - {flagWord('preLive')} in pre-live -

- -
- -

- - - - - {flagWord('live')} in live -

- -
- -

- - - - - {flagWord('completed')} in cleanup -

- -
- -

- - - - - {flagWord('archived')} in archived -

- -
This month
-
- {data?.lifecycleSummary.archived.currentFlags ?? 0}{' '} - flags archived -
-
-
-
+ + +

Flag lifecycle

+ View graph over time +
+ + +

+ + + + + {flagWord('initial')} in initial +

+ +
+ +

+ + + + + {flagWord('preLive')} in pre-live +

+ +
+ +

+ + + + + {flagWord('live')} in live +

+ +
+ +

+ + + + + {flagWord('completed')} in cleanup +

+ +
+ +

+ + + + + {flagWord('archived')} in archived +

+ +
This month
+
+ {data?.lifecycleSummary.archived.currentFlags ?? 0}{' '} + flags archived +
+
+
+
+
); }; From 356491ebfcbf0503fee75ac07df21099d024976d Mon Sep 17 00:00:00 2001 From: Thomas Heartman Date: Tue, 12 Nov 2024 14:53:52 +0100 Subject: [PATCH 02/11] 1-3083: fix flex flow --- .../Project/ProjectStatus/ProjectLifecycleSummary.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/frontend/src/component/project/Project/ProjectStatus/ProjectLifecycleSummary.tsx b/frontend/src/component/project/Project/ProjectStatus/ProjectLifecycleSummary.tsx index d21bae6b52a7..03f36d996cd3 100644 --- a/frontend/src/component/project/Project/ProjectStatus/ProjectLifecycleSummary.tsx +++ b/frontend/src/component/project/Project/ProjectStatus/ProjectLifecycleSummary.tsx @@ -10,7 +10,8 @@ import { Link } from 'react-router-dom'; const LifecycleRow = styled('div')(({ theme }) => ({ display: 'flex', - gap: theme.spacing(4), + flexFlow: 'column', + gap: theme.spacing(1), })); const HeaderRow = styled('div')(({ theme }) => ({ @@ -18,6 +19,9 @@ const HeaderRow = styled('div')(({ theme }) => ({ gap: theme.spacing(2), justifyContent: 'space-between', flex: 'auto', + '& > *': { + margin: 0, + }, })); const LifecycleBox = styled('li')(({ theme }) => ({ From 458f47e42ae10627854dcfd97d096c5b99439b87 Mon Sep 17 00:00:00 2001 From: Thomas Heartman Date: Tue, 12 Nov 2024 15:06:17 +0100 Subject: [PATCH 03/11] 1-3083: only show lifecycle link if not enterprise --- .../Project/ProjectStatus/ProjectLifecycleSummary.tsx | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/frontend/src/component/project/Project/ProjectStatus/ProjectLifecycleSummary.tsx b/frontend/src/component/project/Project/ProjectStatus/ProjectLifecycleSummary.tsx index 03f36d996cd3..9381b3dd943b 100644 --- a/frontend/src/component/project/Project/ProjectStatus/ProjectLifecycleSummary.tsx +++ b/frontend/src/component/project/Project/ProjectStatus/ProjectLifecycleSummary.tsx @@ -7,6 +7,7 @@ import type { FC } from 'react'; import { PrettifyLargeNumber } from 'component/common/PrettifyLargeNumber/PrettifyLargeNumber'; import type { ProjectStatusSchemaLifecycleSummary } from 'openapi'; import { Link } from 'react-router-dom'; +import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig'; const LifecycleRow = styled('div')(({ theme }) => ({ display: 'flex', @@ -14,7 +15,7 @@ const LifecycleRow = styled('div')(({ theme }) => ({ gap: theme.spacing(1), })); -const HeaderRow = styled('div')(({ theme }) => ({ +const HeaderRow = styled('hgroup')(({ theme }) => ({ display: 'flex', gap: theme.spacing(2), justifyContent: 'space-between', @@ -105,6 +106,7 @@ const BigNumber: FC<{ value?: number }> = ({ value }) => { export const ProjectLifecycleSummary = () => { const projectId = useRequiredPathParam('projectId'); const { data, loading } = useProjectStatus(projectId); + const { isEnterprise } = useUiConfig(); const loadingRef = useLoading( loading, @@ -121,7 +123,11 @@ export const ProjectLifecycleSummary = () => {

Flag lifecycle

- View graph over time + {isEnterprise() && ( +

+ View graph over time +

+ )}
From 462572be415cd17e723e19c2f5885b79407a7732 Mon Sep 17 00:00:00 2001 From: Thomas Heartman Date: Wed, 13 Nov 2024 08:35:25 +0100 Subject: [PATCH 04/11] Remove lifecycle link that we don't have yet. --- .../Project/ProjectStatus/ProjectLifecycleSummary.tsx | 6 ------ 1 file changed, 6 deletions(-) diff --git a/frontend/src/component/project/Project/ProjectStatus/ProjectLifecycleSummary.tsx b/frontend/src/component/project/Project/ProjectStatus/ProjectLifecycleSummary.tsx index 9381b3dd943b..63dba183b7ac 100644 --- a/frontend/src/component/project/Project/ProjectStatus/ProjectLifecycleSummary.tsx +++ b/frontend/src/component/project/Project/ProjectStatus/ProjectLifecycleSummary.tsx @@ -6,7 +6,6 @@ import { useRequiredPathParam } from 'hooks/useRequiredPathParam'; import type { FC } from 'react'; import { PrettifyLargeNumber } from 'component/common/PrettifyLargeNumber/PrettifyLargeNumber'; import type { ProjectStatusSchemaLifecycleSummary } from 'openapi'; -import { Link } from 'react-router-dom'; import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig'; const LifecycleRow = styled('div')(({ theme }) => ({ @@ -123,11 +122,6 @@ export const ProjectLifecycleSummary = () => {

Flag lifecycle

- {isEnterprise() && ( -

- View graph over time -

- )}
From 26b96619b96a9d090264322343b309699ae1f39f Mon Sep 17 00:00:00 2001 From: Thomas Heartman Date: Wed, 13 Nov 2024 09:10:11 +0100 Subject: [PATCH 05/11] 1-3083: add lifecycle tooltip --- .../ProjectStatus/ProjectLifecycleSummary.tsx | 45 +++++++++++++++++-- 1 file changed, 41 insertions(+), 4 deletions(-) diff --git a/frontend/src/component/project/Project/ProjectStatus/ProjectLifecycleSummary.tsx b/frontend/src/component/project/Project/ProjectStatus/ProjectLifecycleSummary.tsx index 63dba183b7ac..cf0b20b40301 100644 --- a/frontend/src/component/project/Project/ProjectStatus/ProjectLifecycleSummary.tsx +++ b/frontend/src/component/project/Project/ProjectStatus/ProjectLifecycleSummary.tsx @@ -7,6 +7,7 @@ import type { FC } from 'react'; import { PrettifyLargeNumber } from 'component/common/PrettifyLargeNumber/PrettifyLargeNumber'; import type { ProjectStatusSchemaLifecycleSummary } from 'openapi'; import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig'; +import { HelpIcon } from 'component/common/HelpIcon/HelpIcon'; const LifecycleRow = styled('div')(({ theme }) => ({ display: 'flex', @@ -14,13 +15,11 @@ const LifecycleRow = styled('div')(({ theme }) => ({ gap: theme.spacing(1), })); -const HeaderRow = styled('hgroup')(({ theme }) => ({ +const HeaderRow = styled('div')(({ theme }) => ({ display: 'flex', - gap: theme.spacing(2), - justifyContent: 'space-between', flex: 'auto', '& > *': { - margin: 0, + marginBlock: 0, }, })); @@ -102,6 +101,43 @@ const BigNumber: FC<{ value?: number }> = ({ value }) => { ); }; +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), + }, +})); +export const LifecycleTooltip: FC = () => { + return ( + + + 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. These + insights can help you improve the efficiency of your + software development process. + + + + + Read more in our documentation + + + + } + /> + ); +}; + export const ProjectLifecycleSummary = () => { const projectId = useRequiredPathParam('projectId'); const { data, loading } = useProjectStatus(projectId); @@ -122,6 +158,7 @@ export const ProjectLifecycleSummary = () => {

Flag lifecycle

+
From 7fbe54ec5e68c7409fa15d2f4da0992857e7a835 Mon Sep 17 00:00:00 2001 From: Thomas Heartman Date: Wed, 13 Nov 2024 09:11:53 +0100 Subject: [PATCH 06/11] 1-3083: use normal font weight --- .../project/Project/ProjectStatus/ProjectLifecycleSummary.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/frontend/src/component/project/Project/ProjectStatus/ProjectLifecycleSummary.tsx b/frontend/src/component/project/Project/ProjectStatus/ProjectLifecycleSummary.tsx index cf0b20b40301..e9e88c582966 100644 --- a/frontend/src/component/project/Project/ProjectStatus/ProjectLifecycleSummary.tsx +++ b/frontend/src/component/project/Project/ProjectStatus/ProjectLifecycleSummary.tsx @@ -20,6 +20,7 @@ const HeaderRow = styled('div')(({ theme }) => ({ flex: 'auto', '& > *': { marginBlock: 0, + fontWeight: 'normal', }, })); From 7f4c69cda7929f2f7e7d41d6797799cd4db2dca5 Mon Sep 17 00:00:00 2001 From: Thomas Heartman Date: Wed, 13 Nov 2024 09:29:38 +0100 Subject: [PATCH 07/11] 1-3083: shorten popover text --- .../project/Project/ProjectStatus/ProjectLifecycleSummary.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/frontend/src/component/project/Project/ProjectStatus/ProjectLifecycleSummary.tsx b/frontend/src/component/project/Project/ProjectStatus/ProjectLifecycleSummary.tsx index e9e88c582966..5fefb095350d 100644 --- a/frontend/src/component/project/Project/ProjectStatus/ProjectLifecycleSummary.tsx +++ b/frontend/src/component/project/Project/ProjectStatus/ProjectLifecycleSummary.tsx @@ -123,9 +123,7 @@ export const LifecycleTooltip: FC = () => { 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. These - insights can help you improve the efficiency of your - software development process. + bottlenecks at any stage of the lifecycle. From 6a87a77c61b6e3254b5c54554ead65b7782b0a1a Mon Sep 17 00:00:00 2001 From: Thomas Heartman Date: Wed, 13 Nov 2024 09:29:59 +0100 Subject: [PATCH 08/11] 1-3083: allow custom widths for help icon --- .../src/component/common/HelpIcon/HelpIcon.tsx | 14 ++++++++++++-- .../ProjectStatus/ProjectLifecycleSummary.tsx | 2 ++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/frontend/src/component/common/HelpIcon/HelpIcon.tsx b/frontend/src/component/common/HelpIcon/HelpIcon.tsx index 1c54473b769d..1b53fce5f2bc 100644 --- a/frontend/src/component/common/HelpIcon/HelpIcon.tsx +++ b/frontend/src/component/common/HelpIcon/HelpIcon.tsx @@ -1,6 +1,9 @@ import { styled, Tooltip, type TooltipProps } from '@mui/material'; import HelpOutline from '@mui/icons-material/HelpOutline'; -import { HtmlTooltip } from 'component/common/HtmlTooltip/HtmlTooltip'; +import { + HtmlTooltip, + type IHtmlTooltipProps, +} from 'component/common/HtmlTooltip/HtmlTooltip'; const StyledContainer = styled('span')<{ size: string | undefined }>( ({ theme, size }) => ({ @@ -27,6 +30,7 @@ const StyledContainer = styled('span')<{ size: string | undefined }>( interface IHelpIconProps { tooltip: React.ReactNode; htmlTooltip?: boolean; + htmlTooltipMaxWidth?: IHtmlTooltipProps['maxWidth']; placement?: TooltipProps['placement']; children?: React.ReactNode; size?: string; @@ -35,13 +39,19 @@ interface IHelpIconProps { export const HelpIcon = ({ tooltip, htmlTooltip, + htmlTooltipMaxWidth, placement, children, size, }: IHelpIconProps) => { if (htmlTooltip) { return ( - + {children ?? } diff --git a/frontend/src/component/project/Project/ProjectStatus/ProjectLifecycleSummary.tsx b/frontend/src/component/project/Project/ProjectStatus/ProjectLifecycleSummary.tsx index 5fefb095350d..1835e60f3726 100644 --- a/frontend/src/component/project/Project/ProjectStatus/ProjectLifecycleSummary.tsx +++ b/frontend/src/component/project/Project/ProjectStatus/ProjectLifecycleSummary.tsx @@ -112,10 +112,12 @@ const TooltipText = styled('p')(({ theme }) => ({ marginTop: theme.spacing(1), }, })); + export const LifecycleTooltip: FC = () => { return ( From d2bf134d299ddc4233a4920e7b06fa4c723ca90a Mon Sep 17 00:00:00 2001 From: Thomas Heartman Date: Wed, 13 Nov 2024 09:35:59 +0100 Subject: [PATCH 09/11] 1-3083: don't export tooltip --- .../project/Project/ProjectStatus/ProjectLifecycleSummary.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/component/project/Project/ProjectStatus/ProjectLifecycleSummary.tsx b/frontend/src/component/project/Project/ProjectStatus/ProjectLifecycleSummary.tsx index 1835e60f3726..89a122a0530d 100644 --- a/frontend/src/component/project/Project/ProjectStatus/ProjectLifecycleSummary.tsx +++ b/frontend/src/component/project/Project/ProjectStatus/ProjectLifecycleSummary.tsx @@ -113,7 +113,7 @@ const TooltipText = styled('p')(({ theme }) => ({ }, })); -export const LifecycleTooltip: FC = () => { +const LifecycleTooltip: FC = () => { return ( Date: Wed, 13 Nov 2024 09:41:06 +0100 Subject: [PATCH 10/11] 1-3083: use type and exclusive args --- .../component/common/HelpIcon/HelpIcon.tsx | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/frontend/src/component/common/HelpIcon/HelpIcon.tsx b/frontend/src/component/common/HelpIcon/HelpIcon.tsx index 1b53fce5f2bc..f40b8008a3b0 100644 --- a/frontend/src/component/common/HelpIcon/HelpIcon.tsx +++ b/frontend/src/component/common/HelpIcon/HelpIcon.tsx @@ -27,22 +27,26 @@ const StyledContainer = styled('span')<{ size: string | undefined }>( }), ); -interface IHelpIconProps { +type IHelpIconProps = { tooltip: React.ReactNode; - htmlTooltip?: boolean; - htmlTooltipMaxWidth?: IHtmlTooltipProps['maxWidth']; placement?: TooltipProps['placement']; children?: React.ReactNode; size?: string; -} +} & ( + | { + htmlTooltip: true; + htmlTooltipMaxWidth?: IHtmlTooltipProps['maxWidth']; + } + | { htmlTooltip?: false } +); export const HelpIcon = ({ tooltip, htmlTooltip, - htmlTooltipMaxWidth, placement, children, size, + ...props }: IHelpIconProps) => { if (htmlTooltip) { return ( @@ -50,7 +54,11 @@ export const HelpIcon = ({ title={tooltip} placement={placement} arrow - maxWidth={htmlTooltipMaxWidth} + maxWidth={ + 'htmlTooltipMaxWidth' in props + ? props.htmlTooltipMaxWidth + : undefined + } > {children ?? } From 01fc7b8e285fef931a3ccf8275000123d4becde3 Mon Sep 17 00:00:00 2001 From: Thomas Heartman Date: Wed, 13 Nov 2024 09:49:13 +0100 Subject: [PATCH 11/11] 1-3083: better variable assignment --- frontend/src/component/common/HelpIcon/HelpIcon.tsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/frontend/src/component/common/HelpIcon/HelpIcon.tsx b/frontend/src/component/common/HelpIcon/HelpIcon.tsx index f40b8008a3b0..70177f828a11 100644 --- a/frontend/src/component/common/HelpIcon/HelpIcon.tsx +++ b/frontend/src/component/common/HelpIcon/HelpIcon.tsx @@ -49,16 +49,16 @@ export const HelpIcon = ({ ...props }: IHelpIconProps) => { if (htmlTooltip) { + const { htmlTooltipMaxWidth } = props as { + htmlTooltipMaxWidth?: IHtmlTooltipProps['maxWidth']; + }; + return ( {children ?? }