Skip to content

Commit

Permalink
feat: show failure reason for scheduled requests in timeline (#5639)
Browse files Browse the repository at this point in the history
Adds an icon with a tooltip and changes the dot color to red for
scheduled change requests

Closes #
[1-1768](https://linear.app/unleash/issue/1-1768/add-reason-and-icon-to-timeline)
<img width="1668" alt="Screenshot 2023-12-14 at 10 20 27"
src="https://github.com/Unleash/unleash/assets/104830839/dcf54834-ea9f-4e78-b69d-15d6179ffce3">

---------

Signed-off-by: andreas-unleash <andreas@getunleash.ai>
  • Loading branch information
andreas-unleash committed Dec 14, 2023
1 parent cbd50ac commit a595c0f
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 5 deletions.
Expand Up @@ -241,6 +241,7 @@ export const ChangeRequestOverview: FC = () => {
<ChangeRequestTimeline
state={changeRequest.state}
scheduledAt={changeRequest.schedule?.scheduledAt}
failureReason={changeRequest.schedule?.failureReason}
/>
<ChangeRequestReviewers changeRequest={changeRequest} />
</StyledAsideBox>
Expand Down
Expand Up @@ -113,6 +113,18 @@ test('returns warning for Scheduled stage in Scheduled state', () => {
).toBe('warning');
});

test('returns error for Scheduled stage in Scheduled state with failure reason', () => {
expect(
determineColor(
'Scheduled',
irrelevantIndex,
'Scheduled',
irrelevantIndex,
'conflicts',
),
).toBe('error');
});

test('returns success for stages at or before activeIndex', () => {
expect(determineColor('In review', 1, 'Draft', 0)).toBe('success');
expect(determineColor('In review', 1, 'In review', 1)).toBe('success');
Expand Down
@@ -1,5 +1,5 @@
import { FC } from 'react';
import { Box, Paper, styled, Typography } from '@mui/material';
import { Box, Paper, styled, Tooltip, Typography } from '@mui/material';
import Timeline from '@mui/lab/Timeline';
import TimelineItem, { timelineItemClasses } from '@mui/lab/TimelineItem';
import TimelineSeparator from '@mui/lab/TimelineSeparator';
Expand All @@ -8,10 +8,13 @@ import TimelineConnector from '@mui/lab/TimelineConnector';
import TimelineContent from '@mui/lab/TimelineContent';
import { ChangeRequestState } from '../../changeRequest.types';
import { ConditionallyRender } from '../../../common/ConditionallyRender/ConditionallyRender';
import { HtmlTooltip } from '../../../common/HtmlTooltip/HtmlTooltip';
import { Info } from '@mui/icons-material';

interface ISuggestChangeTimelineProps {
state: ChangeRequestState;
scheduledAt?: string;
failureReason?: string;
}

const StyledPaper = styled(Paper)(({ theme }) => ({
Expand All @@ -24,6 +27,11 @@ const StyledBox = styled(Box)(({ theme }) => ({
marginBottom: `-${theme.spacing(4)}`,
}));

const StyledSubtitle = styled(Box)(({ theme }) => ({
display: 'flex',
flexDirection: 'row',
}));

const StyledTimeline = styled(Timeline)(() => ({
[`& .${timelineItemClasses.root}:before`]: {
flex: 0,
Expand Down Expand Up @@ -51,6 +59,7 @@ export const determineColor = (
changeRequestStateIndex: number,
displayStage: ChangeRequestState,
displayStageIndex: number,
failureReason?: string,
) => {
if (changeRequestState === 'Cancelled') return 'grey';

Expand All @@ -65,7 +74,11 @@ export const determineColor = (
changeRequestStateIndex !== -1 &&
changeRequestStateIndex === displayStageIndex
) {
return changeRequestState === 'Scheduled' ? 'warning' : 'success';
return changeRequestState === 'Scheduled'
? failureReason
? 'error'
: 'warning'
: 'success';
}

if (changeRequestStateIndex + 1 === displayStageIndex) return 'primary';
Expand All @@ -75,6 +88,7 @@ export const determineColor = (
export const ChangeRequestTimeline: FC<ISuggestChangeTimelineProps> = ({
state,
scheduledAt,
failureReason,
}) => {
let data;
switch (state) {
Expand Down Expand Up @@ -105,6 +119,7 @@ export const ChangeRequestTimeline: FC<ISuggestChangeTimelineProps> = ({
activeIndex,
title,
index,
failureReason,
);
let timelineDotProps = {};

Expand All @@ -120,6 +135,7 @@ export const ChangeRequestTimeline: FC<ISuggestChangeTimelineProps> = ({
color,
title,
subtitle,
failureReason,
index < data.length - 1,
timelineDotProps,
);
Expand All @@ -134,6 +150,7 @@ const createTimelineItem = (
color: 'primary' | 'success' | 'grey' | 'error' | 'warning',
title: string,
subtitle: string | undefined,
failureReason: string | undefined,
shouldConnectToNextItem: boolean,
timelineDotProps: { [key: string]: string | undefined } = {},
) => (
Expand All @@ -148,9 +165,23 @@ const createTimelineItem = (
<ConditionallyRender
condition={Boolean(subtitle)}
show={
<Typography
color={'text.secondary'}
>{`(for ${subtitle})`}</Typography>
<StyledSubtitle>
<Typography
color={'text.secondary'}
sx={{ mr: 1 }}
>{`(for ${subtitle})`}</Typography>
<ConditionallyRender
condition={Boolean(failureReason)}
show={
<HtmlTooltip
title={`Schedule failed because of ${failureReason}`}
arrow
>
<Info color={'error'} fontSize={'small'} />
</HtmlTooltip>
}
/>
</StyledSubtitle>
}
/>
</TimelineContent>
Expand Down
Expand Up @@ -24,6 +24,7 @@ export interface IChangeRequest {
export interface IChangeRequestSchedule {
scheduledAt: string;
status: 'pending' | 'failed';
failureReason?: string;
}

export interface IChangeRequestEnvironmentConfig {
Expand Down

0 comments on commit a595c0f

Please sign in to comment.