Skip to content

Commit c51031a

Browse files
Allow truncating long activity names (#918)
1 parent 63a4939 commit c51031a

14 files changed

+163
-4
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
const WORKFLOW_HISTORY_SHOULD_SHORTEN_GROUP_LABELS_CONFIG: boolean = false;
2+
3+
export default WORKFLOW_HISTORY_SHOULD_SHORTEN_GROUP_LABELS_CONFIG;

src/views/workflow-history/helpers/get-history-group-from-events/__tests__/get-activity-group-from-events.test.ts

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,28 @@ import {
1010
pendingActivityTaskStartEvent,
1111
pendingActivityTaskStartEventWithStartedState,
1212
} from '@/views/workflow-history/__fixtures__/workflow-history-pending-events';
13+
import * as shortenGroupLabelsConfigModule from '@/views/workflow-history/config/workflow-history-should-shorten-group-labels.config';
1314

1415
import type { ExtendedActivityHistoryEvent } from '../../../workflow-history.types';
1516
import getActivityGroupFromEvents from '../get-activity-group-from-events';
1617

1718
jest.useFakeTimers().setSystemTime(new Date('2024-05-25'));
1819

20+
jest.mock(
21+
'@/views/workflow-history/config/workflow-history-should-shorten-group-labels.config',
22+
() => ({
23+
__esModule: true,
24+
get default() {
25+
return false;
26+
},
27+
})
28+
);
29+
1930
describe('getActivityGroupFromEvents', () => {
31+
beforeEach(() => {
32+
jest.clearAllMocks();
33+
});
34+
2035
it('should return a group with a proper label when scheduled event exists', () => {
2136
const events: ExtendedActivityHistoryEvent[] = [scheduleActivityTaskEvent];
2237

@@ -254,4 +269,46 @@ describe('getActivityGroupFromEvents', () => {
254269
]);
255270
expect(groupWithMissingCloseEvent.closeTimeMs).toEqual(null);
256271
});
272+
273+
it('should return a short label when short names are enabled and activityName contains a dot', () => {
274+
jest
275+
.spyOn(shortenGroupLabelsConfigModule, 'default', 'get')
276+
.mockReturnValueOnce(true);
277+
278+
const events: ExtendedActivityHistoryEvent[] = [scheduleActivityTaskEvent];
279+
280+
const group = getActivityGroupFromEvents(events);
281+
282+
expect(group.shortLabel).toBe('Activity 0: Start');
283+
284+
const eventsWithoutDot: ExtendedActivityHistoryEvent[] = [
285+
{
286+
...scheduleActivityTaskEvent,
287+
activityTaskScheduledEventAttributes: {
288+
...scheduleActivityTaskEvent.activityTaskScheduledEventAttributes,
289+
activityType: {
290+
...scheduleActivityTaskEvent.activityTaskScheduledEventAttributes
291+
.activityType,
292+
name: 'name-without-dot',
293+
},
294+
},
295+
},
296+
];
297+
298+
const groupWithoutDot = getActivityGroupFromEvents(eventsWithoutDot);
299+
300+
expect(groupWithoutDot.shortLabel).toBeUndefined();
301+
});
302+
303+
it('should return no short label when short names are disabled', () => {
304+
jest
305+
.spyOn(shortenGroupLabelsConfigModule, 'default', 'get')
306+
.mockReturnValueOnce(false);
307+
308+
const events: ExtendedActivityHistoryEvent[] = [scheduleActivityTaskEvent];
309+
310+
const group = getActivityGroupFromEvents(events);
311+
312+
expect(group.shortLabel).toBeUndefined();
313+
});
257314
});

src/views/workflow-history/helpers/get-history-group-from-events/get-activity-group-from-events.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import WORKFLOW_HISTORY_SHOULD_SHORTEN_GROUP_LABELS_CONFIG from '../../config/workflow-history-should-shorten-group-labels.config';
12
import type {
23
ActivityHistoryGroup,
34
ExtendedActivityHistoryEvent,
@@ -11,6 +12,7 @@ export default function getActivityGroupFromEvents(
1112
events: ExtendedActivityHistoryEvent[]
1213
): ActivityHistoryGroup {
1314
let label = '';
15+
let shortLabel = undefined;
1416
const groupType = 'Activity';
1517
const badges = [];
1618

@@ -44,7 +46,18 @@ export default function getActivityGroupFromEvents(
4446

4547
// getting group label
4648
if (scheduleEvent && scheduleAttr in scheduleEvent) {
47-
label = `Activity ${scheduleEvent[scheduleAttr]?.activityId}: ${scheduleEvent[scheduleAttr]?.activityType?.name}`;
49+
const activityName = scheduleEvent[scheduleAttr]?.activityType?.name;
50+
const activityId = scheduleEvent[scheduleAttr]?.activityId;
51+
label = `Activity ${activityId}: ${activityName}`;
52+
53+
if (
54+
WORKFLOW_HISTORY_SHOULD_SHORTEN_GROUP_LABELS_CONFIG &&
55+
activityName?.includes('.')
56+
) {
57+
shortLabel = `Activity ${activityId}: ${(activityName || '')
58+
.split(/[./]/g)
59+
.pop()}`;
60+
}
4861
}
4962

5063
// getting retry badge
@@ -97,6 +110,7 @@ export default function getActivityGroupFromEvents(
97110

98111
return {
99112
label,
113+
shortLabel,
100114
hasMissingEvents,
101115
groupType,
102116
badges,

src/views/workflow-history/workflow-history-compact-event-card/__tests__/workflow-history-compact-event-card.test.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@ jest.mock<typeof WorkflowHistoryEventsDurationBadge>(
1818
() => jest.fn(() => <div>Duration Badge</div>)
1919
);
2020

21+
jest.mock(
22+
'../../workflow-history-group-label/workflow-history-group-label',
23+
() => jest.fn((props) => <>{props.label}</>)
24+
);
25+
2126
describe('WorkflowHistoryCompactEventCard', () => {
2227
beforeEach(() => {
2328
jest.clearAllMocks();

src/views/workflow-history/workflow-history-compact-event-card/workflow-history-compact-event-card.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import useStyletronClasses from '@/hooks/use-styletron-classes';
99

1010
import WorkflowHistoryEventStatusBadge from '../workflow-history-event-status-badge/workflow-history-event-status-badge';
1111
import WorkflowHistoryEventsDurationBadge from '../workflow-history-events-duration-badge/workflow-history-events-duration-badge';
12+
import WorkflowHistoryGroupLabel from '../workflow-history-group-label/workflow-history-group-label';
1213

1314
import {
1415
cssStyles,
@@ -20,6 +21,7 @@ export default function WorkflowHistoryCompactEventCard({
2021
status,
2122
statusReady,
2223
label,
24+
shortLabel,
2325
showLabelPlaceholder,
2426
selected,
2527
disabled,
@@ -54,7 +56,7 @@ export default function WorkflowHistoryCompactEventCard({
5456
<div className={cls.textContainer}>
5557
{label && !showLabelPlaceholder && (
5658
<div className={cls.label}>
57-
{label}
59+
<WorkflowHistoryGroupLabel label={label} shortLabel={shortLabel} />
5860
{hasBadges &&
5961
badges.map((badge) => (
6062
<Badge

src/views/workflow-history/workflow-history-compact-event-card/workflow-history-compact-event-card.types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ export type Props = Pick<
1414
| 'resetToDecisionEventId'
1515
| 'startTimeMs'
1616
| 'closeTimeMs'
17+
| 'shortLabel'
1718
> & {
1819
statusReady: boolean;
1920
showLabelPlaceholder?: boolean;

src/views/workflow-history/workflow-history-export-json-button/workflow-history-export-json-button.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,9 @@ export default function WorkflowHistoryExportJsonButton(props: Props) {
6666
kind="secondary"
6767
startEnhancer={<MdOutlineCloudDownload size={16} />}
6868
onClick={handleExport}
69-
endEnhancer={loadingState === 'loading' && <Spinner $size={16} />}
69+
endEnhancer={
70+
loadingState === 'loading' ? <Spinner $size={16} /> : undefined
71+
}
7072
>
7173
Export JSON
7274
</Button>
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import React from 'react';
2+
3+
import { render, screen, userEvent } from '@/test-utils/rtl';
4+
5+
import WorkflowHistoryGroupLabel from '../workflow-history-group-label';
6+
7+
describe('WorkflowHistoryGroupLabel', () => {
8+
it('renders just the label when shortLabel is not provided', () => {
9+
render(
10+
<WorkflowHistoryGroupLabel label="Activity 0: activity.cron.Start" />
11+
);
12+
expect(
13+
screen.getByText('Activity 0: activity.cron.Start')
14+
).toBeInTheDocument();
15+
});
16+
17+
it('renders shortLabel with tooltip containing full label when shortLabel is provided', async () => {
18+
const user = userEvent.setup();
19+
20+
render(
21+
<WorkflowHistoryGroupLabel
22+
label="Activity 0: activity.cron.Start"
23+
shortLabel="Activity 0: Start"
24+
/>
25+
);
26+
27+
const label = await screen.findByText('Activity 0: Start');
28+
expect(label).toBeInTheDocument();
29+
30+
await user.hover(label);
31+
32+
expect(
33+
await screen.findByText('Activity 0: activity.cron.Start')
34+
).toBeInTheDocument();
35+
});
36+
});
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { StatefulTooltip } from 'baseui/tooltip';
2+
3+
import { type Props } from './workflow-history-group-label.types';
4+
5+
export default function WorkflowHistoryGroupLabel({
6+
label,
7+
shortLabel,
8+
}: Props) {
9+
if (!shortLabel) return <>{label}</>;
10+
11+
return (
12+
<StatefulTooltip
13+
showArrow
14+
placement="bottom"
15+
popoverMargin={8}
16+
accessibilityType="tooltip"
17+
content={() => label}
18+
returnFocus
19+
autoFocus
20+
>
21+
{shortLabel}
22+
</StatefulTooltip>
23+
);
24+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
export type Props = {
2+
label: string;
3+
shortLabel?: string;
4+
};

0 commit comments

Comments
 (0)