diff --git a/frontend/src/component/changeRequest/ChangeRequestOverview/ChangeRequestOverview.tsx b/frontend/src/component/changeRequest/ChangeRequestOverview/ChangeRequestOverview.tsx
index 65601f800b..bbeb908730 100644
--- a/frontend/src/component/changeRequest/ChangeRequestOverview/ChangeRequestOverview.tsx
+++ b/frontend/src/component/changeRequest/ChangeRequestOverview/ChangeRequestOverview.tsx
@@ -238,7 +238,10 @@ export const ChangeRequestOverview: FC = () => {
-
+
diff --git a/frontend/src/component/changeRequest/ChangeRequestOverview/ChangeRequestTimeline/ChangeRequestTimeline.test.tsx b/frontend/src/component/changeRequest/ChangeRequestOverview/ChangeRequestTimeline/ChangeRequestTimeline.test.tsx
index af047454f5..86625909c5 100644
--- a/frontend/src/component/changeRequest/ChangeRequestOverview/ChangeRequestTimeline/ChangeRequestTimeline.test.tsx
+++ b/frontend/src/component/changeRequest/ChangeRequestOverview/ChangeRequestTimeline/ChangeRequestTimeline.test.tsx
@@ -41,6 +41,21 @@ test('rejected timeline shows all states', () => {
expect(screen.queryByText('Applied')).not.toBeInTheDocument();
});
+test('scheduled timeline shows all states', () => {
+ render(
+ ,
+ );
+
+ expect(screen.getByText('Draft')).toBeInTheDocument();
+ expect(screen.getByText('In review')).toBeInTheDocument();
+ expect(screen.queryByText('Approved')).toBeInTheDocument();
+ expect(screen.getByText('Scheduled')).toBeInTheDocument();
+ expect(screen.queryByText('Applied')).toBeInTheDocument();
+});
+
const irrelevantIndex = -99; // Using a number that's unlikely to be a valid index
test('returns grey for Cancelled state regardless of displayed stage', () => {
@@ -87,6 +102,16 @@ test('returns success for stages other than Rejected in Rejected state', () => {
),
).toBe('success');
});
+test('returns warning for Scheduled stage in Scheduled state', () => {
+ expect(
+ determineColor(
+ 'Scheduled',
+ irrelevantIndex,
+ 'Scheduled',
+ irrelevantIndex,
+ ),
+ ).toBe('warning');
+});
test('returns success for stages at or before activeIndex', () => {
expect(determineColor('In review', 1, 'Draft', 0)).toBe('success');
diff --git a/frontend/src/component/changeRequest/ChangeRequestOverview/ChangeRequestTimeline/ChangeRequestTimeline.tsx b/frontend/src/component/changeRequest/ChangeRequestOverview/ChangeRequestTimeline/ChangeRequestTimeline.tsx
index 86f5721574..3cd36dffd2 100644
--- a/frontend/src/component/changeRequest/ChangeRequestOverview/ChangeRequestTimeline/ChangeRequestTimeline.tsx
+++ b/frontend/src/component/changeRequest/ChangeRequestOverview/ChangeRequestTimeline/ChangeRequestTimeline.tsx
@@ -1,5 +1,5 @@
import { FC } from 'react';
-import { Box, Paper, styled } from '@mui/material';
+import { Box, Paper, styled, Typography } from '@mui/material';
import Timeline from '@mui/lab/Timeline';
import TimelineItem, { timelineItemClasses } from '@mui/lab/TimelineItem';
import TimelineSeparator from '@mui/lab/TimelineSeparator';
@@ -7,9 +7,11 @@ import TimelineDot from '@mui/lab/TimelineDot';
import TimelineConnector from '@mui/lab/TimelineConnector';
import TimelineContent from '@mui/lab/TimelineContent';
import { ChangeRequestState } from '../../changeRequest.types';
+import { ConditionallyRender } from '../../../common/ConditionallyRender/ConditionallyRender';
interface ISuggestChangeTimelineProps {
state: ChangeRequestState;
+ scheduledAt?: string;
}
const StyledPaper = styled(Paper)(({ theme }) => ({
@@ -36,6 +38,13 @@ const steps: ChangeRequestState[] = [
'Applied',
];
const rejectedSteps: ChangeRequestState[] = ['Draft', 'In review', 'Rejected'];
+const scheduledSteps: ChangeRequestState[] = [
+ 'Draft',
+ 'In review',
+ 'Approved',
+ 'Scheduled',
+ 'Applied',
+];
export const determineColor = (
changeRequestState: ChangeRequestState,
@@ -44,21 +53,40 @@ export const determineColor = (
displayStageIndex: number,
) => {
if (changeRequestState === 'Cancelled') return 'grey';
+
if (changeRequestState === 'Rejected')
return displayStage === 'Rejected' ? 'error' : 'success';
if (
changeRequestStateIndex !== -1 &&
- changeRequestStateIndex >= displayStageIndex
+ changeRequestStateIndex > displayStageIndex
)
return 'success';
+ if (
+ changeRequestStateIndex !== -1 &&
+ changeRequestStateIndex === displayStageIndex
+ ) {
+ return changeRequestState === 'Scheduled' ? 'warning' : 'success';
+ }
+
if (changeRequestStateIndex + 1 === displayStageIndex) return 'primary';
return 'grey';
};
export const ChangeRequestTimeline: FC = ({
state,
+ scheduledAt,
}) => {
- const data = state === 'Rejected' ? rejectedSteps : steps;
+ let data;
+ switch (state) {
+ case 'Rejected':
+ data = rejectedSteps;
+ break;
+ case 'Scheduled':
+ data = scheduledSteps;
+ break;
+ default:
+ data = steps;
+ }
const activeIndex = data.findIndex((item) => item === state);
return (
@@ -66,6 +94,12 @@ export const ChangeRequestTimeline: FC = ({
{data.map((title, index) => {
+ const subtitle =
+ scheduledAt &&
+ state === 'Scheduled' &&
+ state === title
+ ? new Date(scheduledAt).toLocaleString()
+ : undefined;
const color = determineColor(
state,
activeIndex,
@@ -85,6 +119,7 @@ export const ChangeRequestTimeline: FC = ({
return createTimelineItem(
color,
title,
+ subtitle,
index < data.length - 1,
timelineDotProps,
);
@@ -96,8 +131,9 @@ export const ChangeRequestTimeline: FC = ({
};
const createTimelineItem = (
- color: 'primary' | 'success' | 'grey' | 'error',
+ color: 'primary' | 'success' | 'grey' | 'error' | 'warning',
title: string,
+ subtitle: string | undefined,
shouldConnectToNextItem: boolean,
timelineDotProps: { [key: string]: string | undefined } = {},
) => (
@@ -106,6 +142,17 @@ const createTimelineItem = (
{shouldConnectToNextItem && }
- {title}
+
+ {title}
+
+ {`(for ${subtitle})`}
+ }
+ />
+
);