mirror of
				https://github.com/Unleash/unleash.git
				synced 2025-10-27 11:02:16 +01:00 
			
		
		
		
	chore: prepare for lifecycle comments (#8733)
This PR is a preparation for adding lifecycle comments. It turns the Lifecycle boxes into buttons, using MUI's [`CardActionArea`](https://mui.com/material-ui/api/card-action-area/) component, and allows you to select one at a time. I'm not convinced about the a11y of this approach, but it appears to be in line with what MUI suggests, so ... I'll add the speech bubbles in a follow-up. <img width="1059" alt="image" src="https://github.com/user-attachments/assets/ad3f649f-10de-4418-a780-10321e90d001">
This commit is contained in:
		
							parent
							
								
									61e297dd22
								
							
						
					
					
						commit
						bc7511abd4
					
				@ -0,0 +1,16 @@
 | 
				
			|||||||
 | 
					import type { ProjectStatusSchemaLifecycleSummary } from 'openapi';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const lifecycleMessages: Record<
 | 
				
			||||||
 | 
					    keyof ProjectStatusSchemaLifecycleSummary,
 | 
				
			||||||
 | 
					    string
 | 
				
			||||||
 | 
					> = {
 | 
				
			||||||
 | 
					    initial:
 | 
				
			||||||
 | 
					        'Feature flags in the initial phase indicate you have created flags that is not detected in any environments which mean either integration issues or unused flags',
 | 
				
			||||||
 | 
					    preLive:
 | 
				
			||||||
 | 
					        'In the pre-live phase the feature is being developed and tested in controlled environments. Once the feature is ready the flag can be enabled in production.',
 | 
				
			||||||
 | 
					    live: 'The feature is being rolled out in production according to the decided strategy targeting user segments and/or using percentage rollout. ',
 | 
				
			||||||
 | 
					    completed:
 | 
				
			||||||
 | 
					        'Flags that are in cleanup are potentially stale flags. View the flags to evaluate whether you should archive them in Unleash and clean up your codebase to reduce technical debt',
 | 
				
			||||||
 | 
					    archived:
 | 
				
			||||||
 | 
					        'Flags that have been archived and are no longer in use, but kept for future reference.',
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
@ -1,9 +1,9 @@
 | 
				
			|||||||
import { styled } from '@mui/material';
 | 
					import { CardActionArea, styled } from '@mui/material';
 | 
				
			||||||
import { FeatureLifecycleStageIcon } from 'component/feature/FeatureView/FeatureOverview/FeatureLifecycle/FeatureLifecycleStageIcon';
 | 
					import { FeatureLifecycleStageIcon } from 'component/feature/FeatureView/FeatureOverview/FeatureLifecycle/FeatureLifecycleStageIcon';
 | 
				
			||||||
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 { useRequiredPathParam } from 'hooks/useRequiredPathParam';
 | 
					import { useRequiredPathParam } from 'hooks/useRequiredPathParam';
 | 
				
			||||||
import type { FC } from 'react';
 | 
					import { useState, 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 useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
 | 
					import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
 | 
				
			||||||
@ -24,16 +24,45 @@ const HeaderRow = styled('div')(({ theme }) => ({
 | 
				
			|||||||
    },
 | 
					    },
 | 
				
			||||||
}));
 | 
					}));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const LifecycleBox = styled('li')(({ theme }) => ({
 | 
					const LifecycleBoxContent = styled('div')(({ theme }) => ({
 | 
				
			||||||
    padding: theme.spacing(2),
 | 
					    padding: theme.spacing(2),
 | 
				
			||||||
    borderRadius: theme.shape.borderRadiusExtraLarge,
 | 
					 | 
				
			||||||
    border: `2px solid ${theme.palette.divider}`,
 | 
					 | 
				
			||||||
    gap: theme.spacing(4),
 | 
					    gap: theme.spacing(4),
 | 
				
			||||||
    display: 'flex',
 | 
					    display: 'flex',
 | 
				
			||||||
    flexFlow: 'column',
 | 
					    flexFlow: 'column',
 | 
				
			||||||
    justifyContent: 'space-between',
 | 
					    justifyContent: 'space-between',
 | 
				
			||||||
 | 
					    transition: 'border-color 200ms',
 | 
				
			||||||
 | 
					    borderRadius: theme.shape.borderRadiusExtraLarge,
 | 
				
			||||||
 | 
					    border: `2px solid ${theme.palette.divider}`,
 | 
				
			||||||
}));
 | 
					}));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const StyledCardActionArea = styled(CardActionArea)(({ theme }) => ({
 | 
				
			||||||
 | 
					    borderRadius: theme.shape.borderRadiusExtraLarge,
 | 
				
			||||||
 | 
					    '&[aria-pressed="true"] > *': {
 | 
				
			||||||
 | 
					        borderColor: theme.palette.primary.main,
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					}));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const LifecycleBox = ({
 | 
				
			||||||
 | 
					    children,
 | 
				
			||||||
 | 
					    isActive,
 | 
				
			||||||
 | 
					    onClick,
 | 
				
			||||||
 | 
					}: {
 | 
				
			||||||
 | 
					    children: React.ReactNode;
 | 
				
			||||||
 | 
					    isActive?: boolean;
 | 
				
			||||||
 | 
					    onClick?: () => void;
 | 
				
			||||||
 | 
					}) => {
 | 
				
			||||||
 | 
					    return (
 | 
				
			||||||
 | 
					        <li>
 | 
				
			||||||
 | 
					            <StyledCardActionArea
 | 
				
			||||||
 | 
					                onClick={onClick}
 | 
				
			||||||
 | 
					                aria-pressed={isActive ? 'true' : 'false'}
 | 
				
			||||||
 | 
					            >
 | 
				
			||||||
 | 
					                <LifecycleBoxContent>{children}</LifecycleBoxContent>
 | 
				
			||||||
 | 
					            </StyledCardActionArea>
 | 
				
			||||||
 | 
					        </li>
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const LifecycleList = styled('ul')(({ theme }) => ({
 | 
					const LifecycleList = styled('ul')(({ theme }) => ({
 | 
				
			||||||
    display: 'grid',
 | 
					    display: 'grid',
 | 
				
			||||||
    listStyle: 'none',
 | 
					    listStyle: 'none',
 | 
				
			||||||
@ -144,6 +173,9 @@ export const ProjectLifecycleSummary = () => {
 | 
				
			|||||||
    const { data, loading } = useProjectStatus(projectId);
 | 
					    const { data, loading } = useProjectStatus(projectId);
 | 
				
			||||||
    const { isEnterprise } = useUiConfig();
 | 
					    const { isEnterprise } = useUiConfig();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const [activeLifecycleStage, setActiveLifecycleStage] = useState<
 | 
				
			||||||
 | 
					        keyof ProjectStatusSchemaLifecycleSummary | null
 | 
				
			||||||
 | 
					    >(null);
 | 
				
			||||||
    const loadingRef = useLoading<HTMLUListElement>(
 | 
					    const loadingRef = useLoading<HTMLUListElement>(
 | 
				
			||||||
        loading,
 | 
					        loading,
 | 
				
			||||||
        '[data-loading-project-lifecycle-summary=true]',
 | 
					        '[data-loading-project-lifecycle-summary=true]',
 | 
				
			||||||
@ -162,7 +194,10 @@ export const ProjectLifecycleSummary = () => {
 | 
				
			|||||||
                <LifecycleTooltip />
 | 
					                <LifecycleTooltip />
 | 
				
			||||||
            </HeaderRow>
 | 
					            </HeaderRow>
 | 
				
			||||||
            <LifecycleList ref={loadingRef}>
 | 
					            <LifecycleList ref={loadingRef}>
 | 
				
			||||||
                <LifecycleBox>
 | 
					                <LifecycleBox
 | 
				
			||||||
 | 
					                    onClick={() => setActiveLifecycleStage('initial')}
 | 
				
			||||||
 | 
					                    isActive={activeLifecycleStage === 'initial'}
 | 
				
			||||||
 | 
					                >
 | 
				
			||||||
                    <p>
 | 
					                    <p>
 | 
				
			||||||
                        <Counter>
 | 
					                        <Counter>
 | 
				
			||||||
                            <BigNumber
 | 
					                            <BigNumber
 | 
				
			||||||
@ -182,7 +217,10 @@ export const ProjectLifecycleSummary = () => {
 | 
				
			|||||||
                        averageDays={data?.lifecycleSummary.initial.averageDays}
 | 
					                        averageDays={data?.lifecycleSummary.initial.averageDays}
 | 
				
			||||||
                    />
 | 
					                    />
 | 
				
			||||||
                </LifecycleBox>
 | 
					                </LifecycleBox>
 | 
				
			||||||
                <LifecycleBox>
 | 
					                <LifecycleBox
 | 
				
			||||||
 | 
					                    onClick={() => setActiveLifecycleStage('preLive')}
 | 
				
			||||||
 | 
					                    isActive={activeLifecycleStage === 'preLive'}
 | 
				
			||||||
 | 
					                >
 | 
				
			||||||
                    <p>
 | 
					                    <p>
 | 
				
			||||||
                        <Counter>
 | 
					                        <Counter>
 | 
				
			||||||
                            <BigNumber
 | 
					                            <BigNumber
 | 
				
			||||||
@ -202,7 +240,10 @@ export const ProjectLifecycleSummary = () => {
 | 
				
			|||||||
                        averageDays={data?.lifecycleSummary.preLive.averageDays}
 | 
					                        averageDays={data?.lifecycleSummary.preLive.averageDays}
 | 
				
			||||||
                    />
 | 
					                    />
 | 
				
			||||||
                </LifecycleBox>
 | 
					                </LifecycleBox>
 | 
				
			||||||
                <LifecycleBox>
 | 
					                <LifecycleBox
 | 
				
			||||||
 | 
					                    onClick={() => setActiveLifecycleStage('live')}
 | 
				
			||||||
 | 
					                    isActive={activeLifecycleStage === 'live'}
 | 
				
			||||||
 | 
					                >
 | 
				
			||||||
                    <p>
 | 
					                    <p>
 | 
				
			||||||
                        <Counter>
 | 
					                        <Counter>
 | 
				
			||||||
                            <BigNumber
 | 
					                            <BigNumber
 | 
				
			||||||
@ -220,7 +261,10 @@ export const ProjectLifecycleSummary = () => {
 | 
				
			|||||||
                        averageDays={data?.lifecycleSummary.live.averageDays}
 | 
					                        averageDays={data?.lifecycleSummary.live.averageDays}
 | 
				
			||||||
                    />
 | 
					                    />
 | 
				
			||||||
                </LifecycleBox>
 | 
					                </LifecycleBox>
 | 
				
			||||||
                <LifecycleBox>
 | 
					                <LifecycleBox
 | 
				
			||||||
 | 
					                    onClick={() => setActiveLifecycleStage('completed')}
 | 
				
			||||||
 | 
					                    isActive={activeLifecycleStage === 'completed'}
 | 
				
			||||||
 | 
					                >
 | 
				
			||||||
                    <p>
 | 
					                    <p>
 | 
				
			||||||
                        <Counter>
 | 
					                        <Counter>
 | 
				
			||||||
                            <BigNumber
 | 
					                            <BigNumber
 | 
				
			||||||
@ -243,7 +287,10 @@ export const ProjectLifecycleSummary = () => {
 | 
				
			|||||||
                        }
 | 
					                        }
 | 
				
			||||||
                    />
 | 
					                    />
 | 
				
			||||||
                </LifecycleBox>
 | 
					                </LifecycleBox>
 | 
				
			||||||
                <LifecycleBox>
 | 
					                <LifecycleBox
 | 
				
			||||||
 | 
					                    onClick={() => setActiveLifecycleStage('archived')}
 | 
				
			||||||
 | 
					                    isActive={activeLifecycleStage === 'archived'}
 | 
				
			||||||
 | 
					                >
 | 
				
			||||||
                    <p>
 | 
					                    <p>
 | 
				
			||||||
                        <Counter>
 | 
					                        <Counter>
 | 
				
			||||||
                            <BigNumber
 | 
					                            <BigNumber
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user