Skip to content

Commit 0e28730

Browse files
address comments
Signed-off-by: Adhitya Mamallan <[email protected]>
1 parent d6d8c9a commit 0e28730

File tree

9 files changed

+729
-131
lines changed

9 files changed

+729
-131
lines changed

src/views/workflow-history-v2/helpers/__tests__/generate-history-group-details.test.ts

Lines changed: 468 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import formatPendingWorkflowHistoryEvent from '@/utils/data-formatters/format-pending-workflow-history-event';
2+
import formatWorkflowHistoryEvent from '@/utils/data-formatters/format-workflow-history-event';
3+
import isPendingHistoryEvent from '@/views/workflow-history/workflow-history-event-details/helpers/is-pending-history-event';
4+
import { type HistoryEventsGroup } from '@/views/workflow-history/workflow-history.types';
5+
6+
import generateHistoryEventDetails from '../helpers/generate-history-event-details';
7+
import { type EventDetailsTabContent } from '../workflow-history-group-details/workflow-history-group-details.types';
8+
9+
export default function generateHistoryGroupDetails(
10+
eventGroup: HistoryEventsGroup
11+
) {
12+
const groupDetailsEntries: Array<[string, EventDetailsTabContent]> = [],
13+
summaryDetailsEntries: Array<[string, EventDetailsTabContent]> = [];
14+
15+
eventGroup.events.forEach((event, index) => {
16+
const eventId = event.eventId ?? event.computedEventId;
17+
18+
const eventMetadata = eventGroup.eventsMetadata[index];
19+
if (!eventMetadata) return;
20+
21+
const result = isPendingHistoryEvent(event)
22+
? formatPendingWorkflowHistoryEvent(event)
23+
: formatWorkflowHistoryEvent(event);
24+
25+
const eventDetails = result
26+
? generateHistoryEventDetails({
27+
details: {
28+
...result,
29+
...eventMetadata.additionalDetails,
30+
},
31+
negativeFields: eventMetadata.negativeFields,
32+
})
33+
: [];
34+
35+
groupDetailsEntries.push([
36+
eventId,
37+
{
38+
eventLabel: eventMetadata.label,
39+
eventDetails,
40+
} satisfies EventDetailsTabContent,
41+
]);
42+
43+
const eventSummaryDetails = eventDetails.filter((detail) =>
44+
eventMetadata.summaryFields?.includes(detail.path)
45+
);
46+
47+
if (eventSummaryDetails.length > 0) {
48+
summaryDetailsEntries.push([
49+
eventId,
50+
{
51+
eventLabel: eventMetadata.label,
52+
eventDetails: eventSummaryDetails,
53+
} satisfies EventDetailsTabContent,
54+
]);
55+
}
56+
});
57+
58+
return {
59+
groupDetailsEntries,
60+
summaryDetailsEntries,
61+
};
62+
}

src/views/workflow-history-v2/workflow-history-event-details/__tests__/workflow-history-event-details.test.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ describe(WorkflowHistoryEventDetails.name, () => {
156156
).toBeInTheDocument();
157157
});
158158

159-
it('passes correct props to WorkflowHistoryPanelDetailsEntry', () => {
159+
it('correctly renders panel details entry', () => {
160160
const eventDetails: EventDetailsEntries = [
161161
{
162162
key: 'key1',

src/views/workflow-history-v2/workflow-history-event-details/workflow-history-event-details.tsx

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,21 @@
11
import { useMemo } from 'react';
22

3+
import partition from 'lodash/partition';
4+
35
import WorkflowHistoryEventDetailsGroup from '@/views/workflow-history/workflow-history-event-details-group/workflow-history-event-details-group';
46

57
import WorkflowHistoryPanelDetailsEntry from '../workflow-history-panel-details-entry/workflow-history-panel-details-entry';
68

79
import { styled } from './workflow-history-event-details.styles';
8-
import {
9-
type Props,
10-
type EventDetailsEntries,
11-
} from './workflow-history-event-details.types';
10+
import { type Props } from './workflow-history-event-details.types';
1211

1312
export default function WorkflowHistoryEventDetails({
1413
eventDetails,
1514
workflowPageParams,
1615
}: Props) {
1716
const [panelDetails, restDetails] = useMemo(
1817
() =>
19-
eventDetails.reduce<[EventDetailsEntries, EventDetailsEntries]>(
20-
([panels, rest], entry) => {
21-
if (entry.renderConfig?.showInPanels) {
22-
panels.push(entry);
23-
} else {
24-
rest.push(entry);
25-
}
26-
27-
return [panels, rest];
28-
},
29-
[[], []]
30-
),
18+
partition(eventDetails, (detail) => detail.renderConfig?.showInPanels),
3119
[eventDetails]
3220
);
3321

src/views/workflow-history-v2/workflow-history-event-group/__tests__/workflow-history-event-group.test.tsx

Lines changed: 144 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -14,28 +14,18 @@ import type WorkflowHistoryGroupLabel from '@/views/workflow-history/workflow-hi
1414
import type WorkflowHistoryTimelineResetButton from '@/views/workflow-history/workflow-history-timeline-reset-button/workflow-history-timeline-reset-button';
1515
import { type HistoryEventsGroup } from '@/views/workflow-history/workflow-history.types';
1616

17+
import * as generateHistoryGroupDetailsModule from '../../helpers/generate-history-group-details';
1718
import type { EventDetailsEntries } from '../../workflow-history-event-details/workflow-history-event-details.types';
1819
import type WorkflowHistoryGroupDetails from '../../workflow-history-group-details/workflow-history-group-details';
20+
import type { GroupDetailsEntries } from '../../workflow-history-group-details/workflow-history-group-details.types';
1921
import WorkflowHistoryEventGroup from '../workflow-history-event-group';
2022
import type { Props } from '../workflow-history-event-group.types';
2123

2224
jest.mock('@/utils/data-formatters/format-date', () =>
2325
jest.fn((timeMs: number) => `Formatted: ${timeMs}`)
2426
);
2527

26-
jest.mock('@/utils/data-formatters/format-pending-workflow-history-event', () =>
27-
jest.fn(() => ({ mockFormatted: true }))
28-
);
29-
30-
jest.mock('@/utils/data-formatters/format-workflow-history-event', () =>
31-
jest.fn(() => ({ mockFormatted: true }))
32-
);
33-
34-
const mockGenerateHistoryEventDetails = jest.fn<EventDetailsEntries, any[]>();
35-
36-
jest.mock('../../helpers/generate-history-event-details', () =>
37-
jest.fn(() => mockGenerateHistoryEventDetails())
38-
);
28+
jest.mock('../../helpers/generate-history-group-details', () => jest.fn());
3929

4030
jest.mock<typeof WorkflowHistoryGroupDetails>(
4131
'../../workflow-history-group-details/workflow-history-group-details',
@@ -145,6 +135,10 @@ const mockDecisionEventGroupWithMetadata: HistoryEventsGroup = {
145135
};
146136

147137
describe(WorkflowHistoryEventGroup.name, () => {
138+
beforeEach(() => {
139+
jest.restoreAllMocks();
140+
});
141+
148142
it('renders group correctly', () => {
149143
setup({ eventGroup: mockActivityEventGroupWithMetadata });
150144

@@ -283,7 +277,7 @@ describe(WorkflowHistoryEventGroup.name, () => {
283277
});
284278
});
285279

286-
it('shows summary tab when summaryFields are available to show', () => {
280+
it('shows summary tab when summaryDetailsEntries are available', () => {
287281
const mockEventDetails: EventDetailsEntries = [
288282
{
289283
key: 'input',
@@ -299,10 +293,20 @@ describe(WorkflowHistoryEventGroup.name, () => {
299293
isGroup: false,
300294
renderConfig: null,
301295
},
296+
];
297+
298+
const mockSummaryDetails: EventDetailsEntries = [
299+
{
300+
key: 'input',
301+
path: 'input',
302+
value: 'test input value',
303+
isGroup: false,
304+
renderConfig: null,
305+
},
302306
{
303-
key: 'result',
304-
path: 'result',
305-
value: 'test result',
307+
key: 'activityType',
308+
path: 'activityType',
309+
value: 'TestActivity',
306310
isGroup: false,
307311
renderConfig: null,
308312
},
@@ -340,13 +344,57 @@ describe(WorkflowHistoryEventGroup.name, () => {
340344
(eventId: string) => eventId === completedActivityTaskEvents[0].eventId
341345
);
342346

343-
setup({ eventGroup, getIsEventExpanded, mockEventDetails });
347+
setup({
348+
eventGroup,
349+
getIsEventExpanded,
350+
mockGroupDetails: {
351+
groupDetailsEntries: [
352+
[
353+
completedActivityTaskEvents[0].eventId!,
354+
{
355+
eventLabel: 'Scheduled',
356+
eventDetails: mockEventDetails,
357+
},
358+
],
359+
[
360+
completedActivityTaskEvents[1].eventId!,
361+
{
362+
eventLabel: 'Started',
363+
eventDetails: mockEventDetails,
364+
},
365+
],
366+
[
367+
completedActivityTaskEvents[2].eventId!,
368+
{
369+
eventLabel: 'Completed',
370+
eventDetails: mockEventDetails,
371+
},
372+
],
373+
],
374+
summaryDetailsEntries: [
375+
[
376+
completedActivityTaskEvents[0].eventId!,
377+
{
378+
eventLabel: 'Scheduled',
379+
eventDetails: mockSummaryDetails,
380+
},
381+
],
382+
[
383+
completedActivityTaskEvents[1].eventId!,
384+
{
385+
eventLabel: 'Started',
386+
eventDetails: mockSummaryDetails,
387+
},
388+
],
389+
],
390+
},
391+
});
344392

345-
// Summary tab should appear in groupDetailsEntries when there are multiple events and summary details
393+
// Summary tab should appear in groupDetailsEntries when there are summary details
346394
expect(screen.getByText('Summary')).toBeInTheDocument();
347395
});
348396

349-
it('does not show summary tab when there is only one event', () => {
397+
it('does not show summary tab when summaryDetailsEntries is empty', () => {
350398
const mockEventDetails: EventDetailsEntries = [
351399
{
352400
key: 'input',
@@ -371,14 +419,27 @@ describe(WorkflowHistoryEventGroup.name, () => {
371419
],
372420
};
373421

374-
setup({ eventGroup, mockEventDetails });
422+
setup({
423+
eventGroup,
424+
mockGroupDetails: {
425+
groupDetailsEntries: [
426+
[
427+
scheduleActivityTaskEvent.eventId!,
428+
{
429+
eventLabel: 'Scheduled',
430+
eventDetails: mockEventDetails,
431+
},
432+
],
433+
],
434+
summaryDetailsEntries: [],
435+
},
436+
});
375437

376-
// Summary tab should not appear when there's only one event
377-
expect(screen.queryByTestId('event-summary_7')).not.toBeInTheDocument();
438+
// Summary tab should not appear when summaryDetailsEntries is empty
378439
expect(screen.queryByText('Summary')).not.toBeInTheDocument();
379440
});
380441

381-
it('does not show summary tab when summaryFields do not match any event details', () => {
442+
it('does not show summary tab when summaryDetailsEntries is empty', () => {
382443
const mockEventDetails: EventDetailsEntries = [
383444
{
384445
key: 'input',
@@ -416,9 +477,37 @@ describe(WorkflowHistoryEventGroup.name, () => {
416477
],
417478
};
418479

419-
setup({ eventGroup, mockEventDetails });
480+
setup({
481+
eventGroup,
482+
mockGroupDetails: {
483+
groupDetailsEntries: [
484+
[
485+
completedActivityTaskEvents[0].eventId!,
486+
{
487+
eventLabel: 'Scheduled',
488+
eventDetails: mockEventDetails,
489+
},
490+
],
491+
[
492+
completedActivityTaskEvents[1].eventId!,
493+
{
494+
eventLabel: 'Started',
495+
eventDetails: mockEventDetails,
496+
},
497+
],
498+
[
499+
completedActivityTaskEvents[2].eventId!,
500+
{
501+
eventLabel: 'Completed',
502+
eventDetails: mockEventDetails,
503+
},
504+
],
505+
],
506+
summaryDetailsEntries: [],
507+
},
508+
});
420509

421-
// Summary tab should not appear when no summary details match
510+
// Summary tab should not appear when summaryDetailsEntries is empty
422511
expect(screen.queryByText('Summary')).not.toBeInTheDocument();
423512
});
424513
});
@@ -440,29 +529,51 @@ function setup({
440529
onReset = jest.fn(),
441530
getIsEventExpanded = jest.fn(() => false),
442531
toggleIsEventExpanded = jest.fn(),
443-
mockEventDetails,
532+
mockGroupDetails,
444533
}: Partial<Props> & {
445-
mockEventDetails?: EventDetailsEntries;
534+
mockGroupDetails?: {
535+
groupDetailsEntries: GroupDetailsEntries;
536+
summaryDetailsEntries: GroupDetailsEntries;
537+
};
446538
} = {}) {
447-
mockGenerateHistoryEventDetails.mockReturnValue(
448-
mockEventDetails ?? [
539+
const mockGenerateHistoryGroupDetails = jest.spyOn(
540+
generateHistoryGroupDetailsModule,
541+
'default'
542+
);
543+
544+
if (mockGroupDetails) {
545+
mockGenerateHistoryGroupDetails.mockReturnValue(mockGroupDetails);
546+
} else {
547+
const defaultMockEventDetails: EventDetailsEntries = [
449548
{
450549
key: 'testKey',
451550
path: 'testPath',
452551
value: 'testValue',
453552
isGroup: false,
454553
renderConfig: null,
455554
},
456-
]
457-
);
555+
];
556+
557+
mockGenerateHistoryGroupDetails.mockReturnValue({
558+
groupDetailsEntries: eventGroup.events
559+
.filter((event) => event.eventId)
560+
.map((event, index) => [
561+
event.eventId!,
562+
{
563+
eventLabel: eventGroup.eventsMetadata[index]?.label ?? 'Unknown',
564+
eventDetails: defaultMockEventDetails,
565+
},
566+
]),
567+
summaryDetailsEntries: [],
568+
});
569+
}
458570

459571
const mockOnReset = onReset || jest.fn();
460572
const user = userEvent.setup();
461573

462574
render(
463575
<WorkflowHistoryEventGroup
464576
eventGroup={eventGroup}
465-
groupId={eventGroup.firstEventId ?? ''}
466577
selected={selected}
467578
workflowCloseTimeMs={workflowCloseTimeMs}
468579
workflowCloseStatus={workflowCloseStatus}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { type EventDetailsEntries } from '../../workflow-history-event-details/workflow-history-event-details.types';
2+
import { type EventDetailsTabContent } from '../../workflow-history-group-details/workflow-history-group-details.types';
3+
4+
export default function getSummaryTabContentEntry({
5+
groupId,
6+
summaryDetails,
7+
}: {
8+
groupId: string;
9+
summaryDetails: EventDetailsEntries;
10+
}): [string, EventDetailsTabContent] {
11+
return [
12+
`summary_${groupId}`,
13+
{
14+
eventDetails: summaryDetails,
15+
eventLabel: 'Summary',
16+
},
17+
];
18+
}

0 commit comments

Comments
 (0)