Skip to content

Commit fffb7aa

Browse files
Add reset button to ungrouped history view (#931)
- Add canReset field to ungrouped history event info to determine if an event can be reset to (this is determined based on the resetToEventId in the event group - Pass onReset down to the Ungrouped Event Card component - Add reset button in Ungrouped Event Card component - Stop onClick event propagation in the reset button, to prevent clicks from affecting accordion state
1 parent 1d42160 commit fffb7aa

File tree

9 files changed

+97
-2
lines changed

9 files changed

+97
-2
lines changed

src/views/workflow-history/workflow-history-timeline-reset-button/workflow-history-timeline-reset-button.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,10 @@ export default function WorkflowHistoryTimelineResetButton({
5353
return (
5454
<Button
5555
kind={KIND.secondary}
56-
onClick={onReset}
56+
onClick={(e) => {
57+
e.stopPropagation();
58+
onReset();
59+
}}
5760
startEnhancer={<MdRefresh />}
5861
size="mini"
5962
>

src/views/workflow-history/workflow-history-ungrouped-event/__tests__/workflow-history-ungrouped-event.test.tsx

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,18 @@ jest.mock(
8080
})
8181
);
8282

83+
jest.mock(
84+
'../../workflow-history-timeline-reset-button/workflow-history-timeline-reset-button',
85+
() => ({
86+
__esModule: true,
87+
default: ({ onReset }: { onReset: () => void }) => (
88+
<button onClick={onReset} data-testid="reset-button">
89+
Reset
90+
</button>
91+
),
92+
})
93+
);
94+
8395
const mockEventInfo: WorkflowHistoryUngroupedEventInfo = {
8496
id: '1',
8597
label: 'Workflow Execution Started',
@@ -176,16 +188,42 @@ describe(WorkflowHistoryUngroupedEvent.name, () => {
176188

177189
expect(screen.queryByText(/retry/)).not.toBeInTheDocument();
178190
});
191+
192+
it('renders reset button when onReset function is provided', async () => {
193+
const mockOnReset = jest.fn();
194+
setup({ onReset: mockOnReset });
195+
196+
expect(await screen.findByTestId('reset-button')).toBeInTheDocument();
197+
expect(await screen.findByText('Reset')).toBeInTheDocument();
198+
});
199+
200+
it('does not render reset button when onReset function is not provided', () => {
201+
setup({ onReset: undefined });
202+
203+
expect(screen.queryByTestId('reset-button')).not.toBeInTheDocument();
204+
});
205+
206+
it('calls onReset when reset button is clicked', async () => {
207+
const mockOnReset = jest.fn();
208+
const { user } = setup({ onReset: mockOnReset });
209+
210+
const resetButton = await screen.findByTestId('reset-button');
211+
await user.click(resetButton);
212+
213+
expect(mockOnReset).toHaveBeenCalledTimes(1);
214+
});
179215
});
180216

181217
function setup({
182218
eventInfo = mockEventInfo,
183219
isExpanded = false,
184220
animateBorderOnEnter = false,
221+
onReset,
185222
}: {
186223
eventInfo?: WorkflowHistoryUngroupedEventInfo;
187224
isExpanded?: boolean;
188225
animateBorderOnEnter?: boolean;
226+
onReset?: (() => void) | undefined;
189227
} = {}) {
190228
const mockToggleIsExpanded = jest.fn();
191229

@@ -199,6 +237,7 @@ function setup({
199237
isExpanded,
200238
toggleIsExpanded: mockToggleIsExpanded,
201239
animateBorderOnEnter,
240+
onReset,
202241
};
203242

204243
const user = userEvent.setup();

src/views/workflow-history/workflow-history-ungrouped-event/workflow-history-ungrouped-event.styles.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,14 @@ export const styled = {
3131
alignItems: 'center',
3232
gap: $theme.sizing.scale400,
3333
})),
34+
ResetButtonContainer: createStyled(
35+
'div',
36+
({ $theme }: { $theme: Theme }) => ({
37+
display: 'flex',
38+
justifyContent: 'flex-end',
39+
paddingRight: $theme.sizing.scale400,
40+
})
41+
),
3442
};
3543

3644
export const overrides = (animateBorderOnEnter?: boolean) => ({

src/views/workflow-history/workflow-history-ungrouped-event/workflow-history-ungrouped-event.tsx

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import WorkflowHistoryEventLinkButton from '../workflow-history-event-link-butto
1111
import WorkflowHistoryEventStatusBadge from '../workflow-history-event-status-badge/workflow-history-event-status-badge';
1212
import getFormattedEventsDuration from '../workflow-history-events-duration-badge/helpers/get-formatted-events-duration';
1313
import WorkflowHistoryGroupLabel from '../workflow-history-group-label/workflow-history-group-label';
14+
import WorkflowHistoryTimelineResetButton from '../workflow-history-timeline-reset-button/workflow-history-timeline-reset-button';
1415

1516
import getRetriesForHistoryEvent from './helpers/get-retries-for-history-event';
1617
import {
@@ -26,6 +27,7 @@ export default function WorkflowHistoryUngroupedEvent({
2627
isExpanded,
2728
toggleIsExpanded,
2829
animateBorderOnEnter,
30+
onReset,
2931
}: Props) {
3032
const retries = getRetriesForHistoryEvent(eventInfo.event);
3133
const overrides = getOverrides(animateBorderOnEnter);
@@ -90,6 +92,19 @@ export default function WorkflowHistoryUngroupedEvent({
9092
) : (
9193
<div />
9294
)}
95+
{typeof onReset === 'function' ? (
96+
<styled.ResetButtonContainer>
97+
<WorkflowHistoryTimelineResetButton
98+
domain={decodedPageUrlParams.domain}
99+
cluster={decodedPageUrlParams.cluster}
100+
workflowId={decodedPageUrlParams.workflowId}
101+
runId={decodedPageUrlParams.runId}
102+
onReset={onReset}
103+
/>
104+
</styled.ResetButtonContainer>
105+
) : (
106+
<div />
107+
)}
93108
</styled.CardHeaderContainer>
94109
}
95110
expanded={isExpanded}

src/views/workflow-history/workflow-history-ungrouped-event/workflow-history-ungrouped-event.types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ export type WorkflowHistoryUngroupedEventInfo = {
1818
| HistoryEvent
1919
| PendingDecisionTaskStartEvent
2020
| PendingActivityTaskStartEvent;
21+
canReset?: boolean;
2122
};
2223

2324
export type Props = {
@@ -32,4 +33,5 @@ export type Props = {
3233

3334
// UI behavior
3435
animateBorderOnEnter?: boolean;
36+
onReset?: () => void;
3537
};

src/views/workflow-history/workflow-history-ungrouped-table/__tests__/workflow-history-ungrouped-table.test.tsx

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,11 @@ import WorkflowHistoryUngroupedTable from '../workflow-history-ungrouped-table';
1414
jest.mock(
1515
'../../workflow-history-ungrouped-event/workflow-history-ungrouped-event',
1616
() =>
17-
jest.fn(({ eventInfo, isExpanded, toggleIsExpanded }) => (
17+
jest.fn(({ eventInfo, isExpanded, toggleIsExpanded, onReset }) => (
1818
<div data-testid="mock-event" data-expanded={isExpanded}>
1919
<button onClick={toggleIsExpanded}>Toggle Event</button>
2020
<div>Event ID: {eventInfo.id}</div>
21+
{onReset && <button onClick={onReset}>Reset Event</button>}
2122
</div>
2223
))
2324
);
@@ -116,6 +117,23 @@ describe(WorkflowHistoryUngroupedTable.name, () => {
116117
expect(events).toHaveLength(2);
117118
});
118119
});
120+
121+
it('calls onResetToEventId when reset button is clicked on resettable event', async () => {
122+
const { user, mockOnResetToEventId } = setup({
123+
eventsInfo: [
124+
{
125+
...mockEventsInfo[0],
126+
canReset: true,
127+
},
128+
mockEventsInfo[1],
129+
],
130+
});
131+
132+
const resetButtons = screen.getAllByText('Reset Event');
133+
await user.click(resetButtons[0]);
134+
135+
expect(mockOnResetToEventId).toHaveBeenCalledWith('1');
136+
});
119137
});
120138

121139
function setup({
@@ -135,6 +153,7 @@ function setup({
135153
const mockGetIsEventExpanded = jest.fn(() => false);
136154
const mockToggleIsEventExpanded = jest.fn();
137155
const mockOnVisibleRangeChange = jest.fn();
156+
const mockOnResetToEventId = jest.fn();
138157

139158
const props = {
140159
eventsInfo,
@@ -148,6 +167,7 @@ function setup({
148167
onVisibleRangeChange: mockOnVisibleRangeChange,
149168
virtuosoRef: { current: null },
150169
selectedEventId,
170+
onResetToEventId: mockOnResetToEventId,
151171
};
152172

153173
const user = userEvent.setup();
@@ -167,5 +187,6 @@ function setup({
167187
mockGetIsEventExpanded,
168188
mockToggleIsEventExpanded,
169189
mockOnVisibleRangeChange,
190+
mockOnResetToEventId,
170191
};
171192
}

src/views/workflow-history/workflow-history-ungrouped-table/workflow-history-ungrouped-table.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ export default function WorkflowHistoryUngroupedTable({
1010
eventsInfo,
1111
selectedEventId,
1212
decodedPageUrlParams,
13+
onResetToEventId,
1314
error,
1415
hasMoreEvents,
1516
isFetchingMoreEvents,
@@ -43,6 +44,9 @@ export default function WorkflowHistoryUngroupedTable({
4344
isExpanded={getIsEventExpanded(eventInfo.id)}
4445
toggleIsExpanded={() => toggleIsEventExpanded(eventInfo.id)}
4546
animateBorderOnEnter={eventInfo.id === selectedEventId}
47+
{...(eventInfo.canReset
48+
? { onReset: () => onResetToEventId(eventInfo.id) }
49+
: {})}
4650
/>
4751
)}
4852
{...(selectedEventId && {

src/views/workflow-history/workflow-history-ungrouped-table/workflow-history-ungrouped-table.types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ export type Props = {
1414
eventsInfo: Array<WorkflowHistoryUngroupedEventInfo>;
1515
selectedEventId?: string;
1616
decodedPageUrlParams: WorkflowPageTabsParams;
17+
onResetToEventId: (eventId: string) => void;
1718

1819
// React Query props
1920
error: RequestError | null;

src/views/workflow-history/workflow-history.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,7 @@ export default function WorkflowHistory({ params }: Props) {
205205
status: group.eventsMetadata[index].status,
206206
statusLabel: group.eventsMetadata[index].label,
207207
id: event.eventId ?? event.computedEventId,
208+
canReset: group.resetToDecisionEventId === event.eventId,
208209
})),
209210
])
210211
.flat(1)
@@ -454,6 +455,7 @@ export default function WorkflowHistory({ params }: Props) {
454455
}))
455456
}
456457
virtuosoRef={ungroupedTableRef}
458+
onResetToEventId={setResetToDecisionEventId}
457459
/>
458460
</section>
459461
) : (

0 commit comments

Comments
 (0)