diff --git a/src/views/workflow-history-v2/workflow-history-event-group-duration/__tests__/workflow-history-event-group-duration.test.tsx b/src/views/workflow-history-v2/workflow-history-event-group-duration/__tests__/workflow-history-event-group-duration.test.tsx
index b716ef6e7..a73e139f9 100644
--- a/src/views/workflow-history-v2/workflow-history-event-group-duration/__tests__/workflow-history-event-group-duration.test.tsx
+++ b/src/views/workflow-history-v2/workflow-history-event-group-duration/__tests__/workflow-history-event-group-duration.test.tsx
@@ -16,6 +16,23 @@ jest.mock('../helpers/get-formatted-events-duration', () =>
)
);
+jest.mock(
+ '@/views/workflow-history/workflow-history-remaining-duration-badge/workflow-history-remaining-duration-badge',
+ () => {
+ return function MockWorkflowHistoryRemainingDurationBadge({
+ prefix,
+ expectedEndTime,
+ }: {
+ prefix: string;
+ expectedEndTime: number;
+ }) {
+ return (
+
{`${prefix} ${expectedEndTime}`}
+ );
+ };
+ }
+);
+
const mockStartTime = new Date('2024-01-01T10:00:00Z').getTime();
const mockCloseTime = new Date('2024-01-01T10:01:00Z').getTime();
const mockNow = new Date('2024-01-01T10:02:00Z').getTime();
@@ -111,15 +128,6 @@ describe('WorkflowHistoryEventGroupDuration', () => {
expect(getFormattedEventsDuration).toHaveBeenCalledTimes(2);
});
- it('cleans up interval when component unmounts', () => {
- const { unmount } = setup();
-
- const clearIntervalSpy = jest.spyOn(global, 'clearInterval');
- unmount();
-
- expect(clearIntervalSpy).toHaveBeenCalled();
- });
-
it('uses workflow close time when close time is not provided', () => {
setup({
closeTime: null,
@@ -133,6 +141,28 @@ describe('WorkflowHistoryEventGroupDuration', () => {
);
expect(screen.getByText('60')).toBeInTheDocument();
});
+
+ it('renders end time badge when expectedEndTimeInfo is provided', () => {
+ const expectedEndTime = new Date('2024-01-01T10:05:00Z').getTime();
+ setup({
+ expectedEndTimeInfo: {
+ timeMs: expectedEndTime,
+ prefix: 'Fires in',
+ },
+ });
+
+ expect(screen.getByTestId('end-time-badge')).toBeInTheDocument();
+ expect(screen.getByText(`Fires in ${expectedEndTime}`)).toBeInTheDocument();
+ });
+
+ it('cleans up interval when component unmounts', () => {
+ const { unmount } = setup();
+
+ const clearIntervalSpy = jest.spyOn(global, 'clearInterval');
+ unmount();
+
+ expect(clearIntervalSpy).toHaveBeenCalled();
+ });
});
function setup({
@@ -144,6 +174,7 @@ function setup({
workflowIsArchived = false,
workflowCloseStatus = WorkflowExecutionCloseStatus.WORKFLOW_EXECUTION_CLOSE_STATUS_INVALID,
workflowCloseTime = null,
+ expectedEndTimeInfo,
}: Partial = {}) {
return render(
);
}
diff --git a/src/views/workflow-history-v2/workflow-history-event-group-duration/workflow-history-event-group-duration.styles.ts b/src/views/workflow-history-v2/workflow-history-event-group-duration/workflow-history-event-group-duration.styles.ts
new file mode 100644
index 000000000..e69faf8d7
--- /dev/null
+++ b/src/views/workflow-history-v2/workflow-history-event-group-duration/workflow-history-event-group-duration.styles.ts
@@ -0,0 +1,9 @@
+import { styled as createStyled, type Theme } from 'baseui';
+
+export const styled = {
+ DurationContainer: createStyled('div', ({ $theme }: { $theme: Theme }) => ({
+ display: 'flex',
+ alignItems: 'baseline',
+ gap: $theme.sizing.scale200,
+ })),
+};
diff --git a/src/views/workflow-history-v2/workflow-history-event-group-duration/workflow-history-event-group-duration.tsx b/src/views/workflow-history-v2/workflow-history-event-group-duration/workflow-history-event-group-duration.tsx
index 3672eba58..7e4da3e95 100644
--- a/src/views/workflow-history-v2/workflow-history-event-group-duration/workflow-history-event-group-duration.tsx
+++ b/src/views/workflow-history-v2/workflow-history-event-group-duration/workflow-history-event-group-duration.tsx
@@ -1,11 +1,15 @@
import React, { useEffect, useState } from 'react';
+import WorkflowHistoryRemainingDurationBadge from '@/views/workflow-history/workflow-history-remaining-duration-badge/workflow-history-remaining-duration-badge';
+
import getFormattedEventsDuration from './helpers/get-formatted-events-duration';
+import { styled } from './workflow-history-event-group-duration.styles';
import { type Props } from './workflow-history-event-group-duration.types';
export default function WorkflowHistoryEventGroupDuration({
startTime,
closeTime,
+ expectedEndTimeInfo,
workflowIsArchived,
workflowCloseStatus,
eventsCount,
@@ -42,9 +46,23 @@ export default function WorkflowHistoryEventGroupDuration({
}
}, [startTime, endTime, isOngoing]);
- if (!startTime || hideDuration) {
+ if (!startTime) {
return null;
}
- return <>{duration}>;
+ return (
+
+ {!hideDuration && duration}
+ {expectedEndTimeInfo ? (
+
+ ) : null}
+
+ );
}
diff --git a/src/views/workflow-history-v2/workflow-history-event-group-duration/workflow-history-event-group-duration.types.ts b/src/views/workflow-history-v2/workflow-history-event-group-duration/workflow-history-event-group-duration.types.ts
index 0b81a2a58..0076c4be3 100644
--- a/src/views/workflow-history-v2/workflow-history-event-group-duration/workflow-history-event-group-duration.types.ts
+++ b/src/views/workflow-history-v2/workflow-history-event-group-duration/workflow-history-event-group-duration.types.ts
@@ -1,8 +1,10 @@
import { type WorkflowExecutionCloseStatus } from '@/__generated__/proto-ts/uber/cadence/api/v1/WorkflowExecutionCloseStatus';
+import { type HistoryEventsGroup } from '@/views/workflow-history/workflow-history.types';
export type Props = {
startTime: number | null | undefined;
closeTime: number | null | undefined;
+ expectedEndTimeInfo?: HistoryEventsGroup['expectedEndTimeInfo'];
workflowIsArchived: boolean;
workflowCloseStatus: WorkflowExecutionCloseStatus | null | undefined;
eventsCount: number;
diff --git a/src/views/workflow-history-v2/workflow-history-event-group/workflow-history-event-group.tsx b/src/views/workflow-history-v2/workflow-history-event-group/workflow-history-event-group.tsx
index 192982f8b..35268b9ce 100644
--- a/src/views/workflow-history-v2/workflow-history-event-group/workflow-history-event-group.tsx
+++ b/src/views/workflow-history-v2/workflow-history-event-group/workflow-history-event-group.tsx
@@ -36,12 +36,13 @@ export default function WorkflowHistoryEventGroup({
}: Props) {
const {
status,
+ firstEventId,
label,
shortLabel,
timeMs,
startTimeMs,
closeTimeMs,
- // expectedEndTimeInfo,
+ expectedEndTimeInfo,
events,
eventsMetadata,
hasMissingEvents,
@@ -86,14 +87,14 @@ export default function WorkflowHistoryEventGroup({
...(groupSummaryDetails.length > 0 && groupDetailsEntries.length > 1
? [
getSummaryTabContentEntry({
- groupId: eventGroup.firstEventId ?? 'unknown',
+ groupId: firstEventId ?? 'unknown',
summaryDetails: groupSummaryDetails,
}),
]
: []),
...groupDetailsEntries,
],
- [eventGroup.firstEventId, groupDetailsEntries, groupSummaryDetails]
+ [firstEventId, groupDetailsEntries, groupSummaryDetails]
);
return (
@@ -128,6 +129,7 @@ export default function WorkflowHistoryEventGroup({
loadingMoreEvents={showLoadingMoreEvents}
hasMissingEvents={hasMissingEvents}
workflowCloseTime={workflowCloseTimeMs}
+ expectedEndTimeInfo={expectedEndTimeInfo}
/>