mirror of
https://github.com/Unleash/unleash.git
synced 2025-02-09 00:18:00 +01:00
feat: completed stage button (#6914)
This commit is contained in:
parent
f63bae21f5
commit
e91d471d17
@ -5,22 +5,7 @@ import { ReactComponent as LiveStageIcon } from 'assets/icons/stage-live.svg';
|
|||||||
import { ReactComponent as CompletedStageIcon } from 'assets/icons/stage-completed.svg';
|
import { ReactComponent as CompletedStageIcon } from 'assets/icons/stage-completed.svg';
|
||||||
import { ReactComponent as CompletedDiscardedStageIcon } from 'assets/icons/stage-completed-discarded.svg';
|
import { ReactComponent as CompletedDiscardedStageIcon } from 'assets/icons/stage-completed-discarded.svg';
|
||||||
import { ReactComponent as ArchivedStageIcon } from 'assets/icons/stage-archived.svg';
|
import { ReactComponent as ArchivedStageIcon } from 'assets/icons/stage-archived.svg';
|
||||||
|
import type { LifecycleStage } from './LifecycleStage';
|
||||||
export type LifecycleStage =
|
|
||||||
| { name: 'initial' }
|
|
||||||
| {
|
|
||||||
name: 'pre-live';
|
|
||||||
environments: Array<{ name: string; lastSeenAt: string }>;
|
|
||||||
}
|
|
||||||
| {
|
|
||||||
name: 'live';
|
|
||||||
environments: Array<{ name: string; lastSeenAt: string }>;
|
|
||||||
}
|
|
||||||
| {
|
|
||||||
name: 'completed';
|
|
||||||
status: 'kept' | 'discarded';
|
|
||||||
}
|
|
||||||
| { name: 'archived' };
|
|
||||||
|
|
||||||
export const FeatureLifecycleStageIcon: FC<{ stage: LifecycleStage }> = ({
|
export const FeatureLifecycleStageIcon: FC<{ stage: LifecycleStage }> = ({
|
||||||
stage,
|
stage,
|
||||||
|
@ -11,14 +11,13 @@ import { ReactComponent as CompletedDiscardedStageIcon } from 'assets/icons/stag
|
|||||||
import { ReactComponent as ArchivedStageIcon } from 'assets/icons/stage-archived.svg';
|
import { ReactComponent as ArchivedStageIcon } from 'assets/icons/stage-archived.svg';
|
||||||
import CloudCircle from '@mui/icons-material/CloudCircle';
|
import CloudCircle from '@mui/icons-material/CloudCircle';
|
||||||
import { ReactComponent as UsageRate } from 'assets/icons/usage-rate.svg';
|
import { ReactComponent as UsageRate } from 'assets/icons/usage-rate.svg';
|
||||||
import {
|
import { FeatureLifecycleStageIcon } from './FeatureLifecycleStageIcon';
|
||||||
FeatureLifecycleStageIcon,
|
|
||||||
type LifecycleStage,
|
|
||||||
} from './FeatureLifecycleStageIcon';
|
|
||||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
|
||||||
import TimeAgo from 'react-timeago';
|
import TimeAgo from 'react-timeago';
|
||||||
import { StyledIconWrapper } from '../../FeatureEnvironmentSeen/FeatureEnvironmentSeen';
|
import { StyledIconWrapper } from '../../FeatureEnvironmentSeen/FeatureEnvironmentSeen';
|
||||||
import { useLastSeenColors } from '../../FeatureEnvironmentSeen/useLastSeenColors';
|
import { useLastSeenColors } from '../../FeatureEnvironmentSeen/useLastSeenColors';
|
||||||
|
import type { LifecycleStage } from './LifecycleStage';
|
||||||
|
import PermissionButton from 'component/common/PermissionButton/PermissionButton';
|
||||||
|
import { UPDATE_FEATURE } from 'component/providers/AccessProvider/permissions';
|
||||||
|
|
||||||
const TimeLabel = styled('span')(({ theme }) => ({
|
const TimeLabel = styled('span')(({ theme }) => ({
|
||||||
color: theme.palette.text.secondary,
|
color: theme.palette.text.secondary,
|
||||||
@ -204,31 +203,10 @@ const CenteredBox = styled(Box)(({ theme }) => ({
|
|||||||
gap: theme.spacing(1),
|
gap: theme.spacing(1),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const LiveStageDescription: FC<{
|
const Environments: FC<{
|
||||||
name: 'live' | 'pre-live';
|
|
||||||
environments: Array<{ name: string; lastSeenAt: string }>;
|
environments: Array<{ name: string; lastSeenAt: string }>;
|
||||||
}> = ({ name, environments }) => {
|
}> = ({ environments }) => {
|
||||||
return (
|
return (
|
||||||
<>
|
|
||||||
<ConditionallyRender
|
|
||||||
condition={name === 'pre-live'}
|
|
||||||
show={
|
|
||||||
<InfoText>
|
|
||||||
We've seen the feature flag in the following
|
|
||||||
non-production environments:
|
|
||||||
</InfoText>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
<ConditionallyRender
|
|
||||||
condition={name === 'live'}
|
|
||||||
show={
|
|
||||||
<InfoText>
|
|
||||||
Users have been exposed to this feature in the following
|
|
||||||
production environments:
|
|
||||||
</InfoText>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<Box>
|
<Box>
|
||||||
{environments.map((environment) => {
|
{environments.map((environment) => {
|
||||||
return (
|
return (
|
||||||
@ -242,14 +220,61 @@ const LiveStageDescription: FC<{
|
|||||||
minPeriod={60}
|
minPeriod={60}
|
||||||
date={environment.lastSeenAt}
|
date={environment.lastSeenAt}
|
||||||
/>
|
/>
|
||||||
<LastSeenIcon
|
<LastSeenIcon lastSeen={environment.lastSeenAt} />
|
||||||
lastSeen={environment.lastSeenAt}
|
|
||||||
/>
|
|
||||||
</CenteredBox>
|
</CenteredBox>
|
||||||
</EnvironmentLine>
|
</EnvironmentLine>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</Box>
|
</Box>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const PreLiveStageDescription: FC = ({ children }) => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<InfoText>
|
||||||
|
We've seen the feature flag in the following non-production
|
||||||
|
environments:
|
||||||
|
</InfoText>
|
||||||
|
|
||||||
|
{children}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const BoldTitle = styled(Typography)(({ theme }) => ({
|
||||||
|
marginTop: theme.spacing(1),
|
||||||
|
marginBottom: theme.spacing(1),
|
||||||
|
fontSize: theme.fontSizes.smallBody,
|
||||||
|
fontWeight: theme.fontWeight.bold,
|
||||||
|
}));
|
||||||
|
|
||||||
|
const LiveStageDescription: FC = ({ children }) => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<BoldTitle>Is this feature complete?</BoldTitle>
|
||||||
|
<InfoText sx={{ mb: 1 }}>
|
||||||
|
Marking the feature as complete does not affect any
|
||||||
|
configuration, but it moves the feature into it’s next life
|
||||||
|
cycle stage and is an indication that you have learned what you
|
||||||
|
needed in order to progress with the feature. It serves as a
|
||||||
|
reminder to start cleaning up the flag and removing it from the
|
||||||
|
code.
|
||||||
|
</InfoText>
|
||||||
|
<PermissionButton
|
||||||
|
color='inherit'
|
||||||
|
variant='outlined'
|
||||||
|
permission={UPDATE_FEATURE}
|
||||||
|
size='small'
|
||||||
|
>
|
||||||
|
Mark Completed
|
||||||
|
</PermissionButton>
|
||||||
|
<InfoText sx={{ mt: 3 }}>
|
||||||
|
Users have been exposed to this feature in the following
|
||||||
|
production environments:
|
||||||
|
</InfoText>
|
||||||
|
|
||||||
|
{children}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@ -292,11 +317,15 @@ export const FeatureLifecycleTooltip: FC<{
|
|||||||
</Box>
|
</Box>
|
||||||
<ColorFill>
|
<ColorFill>
|
||||||
{stage.name === 'initial' && <InitialStageDescription />}
|
{stage.name === 'initial' && <InitialStageDescription />}
|
||||||
{(stage.name === 'pre-live' || stage.name === 'live') && (
|
{stage.name === 'pre-live' && (
|
||||||
<LiveStageDescription
|
<PreLiveStageDescription>
|
||||||
name={stage.name}
|
<Environments environments={stage.environments} />
|
||||||
environments={stage.environments}
|
</PreLiveStageDescription>
|
||||||
/>
|
)}
|
||||||
|
{stage.name === 'live' && (
|
||||||
|
<LiveStageDescription>
|
||||||
|
<Environments environments={stage.environments} />
|
||||||
|
</LiveStageDescription>
|
||||||
)}
|
)}
|
||||||
</ColorFill>
|
</ColorFill>
|
||||||
</Box>
|
</Box>
|
||||||
|
@ -0,0 +1,15 @@
|
|||||||
|
export type LifecycleStage =
|
||||||
|
| { name: 'initial' }
|
||||||
|
| {
|
||||||
|
name: 'pre-live';
|
||||||
|
environments: Array<{ name: string; lastSeenAt: string }>;
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
name: 'live';
|
||||||
|
environments: Array<{ name: string; lastSeenAt: string }>;
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
name: 'completed';
|
||||||
|
status: 'kept' | 'discarded';
|
||||||
|
}
|
||||||
|
| { name: 'archived' };
|
@ -10,6 +10,7 @@ import { useRequiredPathParam } from 'hooks/useRequiredPathParam';
|
|||||||
import { useUiFlag } from 'hooks/useUiFlag';
|
import { useUiFlag } from 'hooks/useUiFlag';
|
||||||
import { FeatureLifecycleTooltip } from '../FeatureLifecycle/FeatureLifecycleTooltip';
|
import { FeatureLifecycleTooltip } from '../FeatureLifecycle/FeatureLifecycleTooltip';
|
||||||
import { FeatureLifecycleStageIcon } from '../FeatureLifecycle/FeatureLifecycleStageIcon';
|
import { FeatureLifecycleStageIcon } from '../FeatureLifecycle/FeatureLifecycleStageIcon';
|
||||||
|
import type { LifecycleStage } from '../FeatureLifecycle/LifecycleStage';
|
||||||
|
|
||||||
const StyledContainer = styled('div')(({ theme }) => ({
|
const StyledContainer = styled('div')(({ theme }) => ({
|
||||||
borderRadius: theme.shape.borderRadiusLarge,
|
borderRadius: theme.shape.borderRadiusLarge,
|
||||||
@ -81,6 +82,17 @@ const FeatureOverviewMetaData = () => {
|
|||||||
|
|
||||||
const IconComponent = getFeatureTypeIcons(type);
|
const IconComponent = getFeatureTypeIcons(type);
|
||||||
|
|
||||||
|
const currentStage: LifecycleStage = {
|
||||||
|
name: 'live',
|
||||||
|
environments: [
|
||||||
|
{ name: 'production', lastSeenAt: new Date().toISOString() },
|
||||||
|
{
|
||||||
|
name: 'staging',
|
||||||
|
lastSeenAt: new Date().toISOString(),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StyledContainer>
|
<StyledContainer>
|
||||||
<StyledPaddingContainerTop>
|
<StyledPaddingContainerTop>
|
||||||
@ -109,11 +121,9 @@ const FeatureOverviewMetaData = () => {
|
|||||||
show={
|
show={
|
||||||
<StyledRow data-loading>
|
<StyledRow data-loading>
|
||||||
<StyledLabel>Lifecycle:</StyledLabel>
|
<StyledLabel>Lifecycle:</StyledLabel>
|
||||||
<FeatureLifecycleTooltip
|
<FeatureLifecycleTooltip stage={currentStage}>
|
||||||
stage={{ name: 'initial' }}
|
|
||||||
>
|
|
||||||
<FeatureLifecycleStageIcon
|
<FeatureLifecycleStageIcon
|
||||||
stage={{ name: 'initial' }}
|
stage={currentStage}
|
||||||
/>
|
/>
|
||||||
</FeatureLifecycleTooltip>
|
</FeatureLifecycleTooltip>
|
||||||
</StyledRow>
|
</StyledRow>
|
||||||
|
Loading…
Reference in New Issue
Block a user