Skip to content

Commit a80db2c

Browse files
authored
Turn workflow execution & runId in event details to links (#709)
* change runIds and wf executions into links * fix lint * remove log
1 parent 6aa074b commit a80db2c

File tree

8 files changed

+110
-64
lines changed

8 files changed

+110
-64
lines changed

src/components/link/link.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,13 @@ export default function Link({
1212
...restProps
1313
}: Props) {
1414
return (
15-
<styled.LinkBase {...restProps} $as={NextLink} href={href} disabled={!href}>
15+
<styled.LinkBase
16+
{...restProps}
17+
$as={NextLink}
18+
href={href}
19+
disabled={!href}
20+
prefetch={prefetch}
21+
>
1622
{children}
1723
</styled.LinkBase>
1824
);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import React from 'react';
2+
3+
import omit from 'lodash/omit';
4+
5+
import { render } from '@/test-utils/rtl';
6+
7+
import WorkflowHistoryEventDetailsExecutionLink from '../workflow-history-event-details-wf-execution-link';
8+
9+
describe('WorkflowHistoryEventDetailsExecutionLink', () => {
10+
const props = {
11+
runId: 'testRunId',
12+
workflowId: 'testWorkflowId',
13+
cluster: 'testCluster',
14+
domain: 'testDomain',
15+
};
16+
17+
it('should render the link with correct href', () => {
18+
const { getByText } = render(
19+
<WorkflowHistoryEventDetailsExecutionLink {...props} />
20+
);
21+
22+
const linkElement = getByText(props.runId).closest('a');
23+
expect(linkElement).toHaveAttribute(
24+
'href',
25+
`/domains/${props.domain}/${props.cluster}/workflows/${props.workflowId}/${props.runId}`
26+
);
27+
});
28+
29+
it('should render the runId as link text', () => {
30+
const { getByText } = render(
31+
<WorkflowHistoryEventDetailsExecutionLink {...props} />
32+
);
33+
34+
expect(getByText(props.runId)).toBeInTheDocument();
35+
});
36+
37+
it('should render disabled link with empty href if any prop is missing', () => {
38+
const propKeys = Object.keys(props);
39+
40+
propKeys.forEach((key) => {
41+
const { container } = render(
42+
// @ts-expect-error testing missing props
43+
<WorkflowHistoryEventDetailsExecutionLink {...omit(props, key)} />
44+
);
45+
const linkElement = container.querySelector('a');
46+
expect(linkElement).toHaveAttribute('href', '/');
47+
});
48+
});
49+
});
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
'use client';
2+
import React from 'react';
3+
4+
import Link from '@/components/link/link';
5+
6+
import { type Props } from './workflow-history-event-details-wf-execution-link.types';
7+
8+
export default function WorkflowHistoryEventDetailsExecutionLink({
9+
runId,
10+
workflowId,
11+
cluster,
12+
domain,
13+
}: Props) {
14+
const noMissingData = Boolean(domain && cluster && workflowId && runId);
15+
16+
const href = noMissingData
17+
? `/domains/${encodeURIComponent(domain)}/${encodeURIComponent(cluster)}/workflows/${encodeURIComponent(workflowId)}/${encodeURIComponent(runId)}`
18+
: '';
19+
return (
20+
<Link href={href} style={{ fontWeight: 'inherit' }}>
21+
{runId}
22+
</Link>
23+
);
24+
}

src/views/workflow-summary-tab/workflow-summary-tab-details-wf-execution-link/workflow-summary-tab-details-wf-execution-link.types.ts renamed to src/views/shared/workflow-history-event-details-wf-execution-link/workflow-history-event-details-wf-execution-link.types.ts

File renamed without changes.

src/views/workflow-history/config/workflow-history-event-details.config.ts

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { createElement } from 'react';
22

33
import formatDate from '@/utils/data-formatters/format-date';
4+
import WorkflowHistoryEventDetailsExecutionLink from '@/views/shared/workflow-history-event-details-wf-execution-link/workflow-history-event-details-wf-execution-link';
45

56
import WorkflowHistoryEventDetailsTaskListLink from '../../shared/workflow-history-event-details-task-list-link/workflow-history-event-details-task-list-link';
67
import { type WorkflowHistoryEventDetailsConfig } from '../workflow-history-event-details/workflow-history-event-details.types';
@@ -30,15 +31,39 @@ const workflowHistoryEventDetailsConfig = [
3031
},
3132
{
3233
name: 'Json as PrettyJson',
33-
pathRegex: '.*(input|result|details|Error)$',
34+
pathRegex: '(input|result|details|Error)$',
3435
valueComponent: WorkflowHistoryEventDetailsJson,
3536
forceWrap: true,
3637
},
3738
{
3839
name: 'Duration timeout & backoff seconds',
39-
pathRegex: '.+(TimeoutSeconds|BackoffSeconds)$',
40+
pathRegex: '(TimeoutSeconds|BackoffSeconds)$',
4041
valueComponent: ({ entryValue }) => `${entryValue}s`, // TODO @assem.hafez: format the value as duration
4142
},
43+
{
44+
name: 'WorkflowExecution as link',
45+
pathRegex: '(parentWorkflowExecution|externalWorkflowExecution)$',
46+
valueComponent: ({ entryValue, domain, cluster }) => {
47+
return createElement(WorkflowHistoryEventDetailsExecutionLink, {
48+
domain,
49+
cluster,
50+
workflowId: entryValue?.workflowId,
51+
runId: entryValue?.runId,
52+
});
53+
},
54+
},
55+
{
56+
name: 'RunIds as link',
57+
pathRegex: '(firstExecutionRunId|originalExecutionRunId)$',
58+
valueComponent: ({ entryValue, domain, cluster, workflowId }) => {
59+
return createElement(WorkflowHistoryEventDetailsExecutionLink, {
60+
domain,
61+
cluster,
62+
workflowId,
63+
runId: entryValue,
64+
});
65+
},
66+
},
4267
] as const satisfies WorkflowHistoryEventDetailsConfig[];
4368

4469
export default workflowHistoryEventDetailsConfig;

src/views/workflow-summary-tab/config/workflow-summary-tab-details.config.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ import WorkflowHistoryEventDetailsTaskListLink from '@/views/shared/workflow-his
44
import WorkflowStatusTag from '@/views/shared/workflow-status-tag/workflow-status-tag';
55
import getWorkflowStatusTagProps from '@/views/workflow-page/helpers/get-workflow-status-tag-props';
66

7+
import WorkflowHistoryEventDetailsExecutionLink from '../../shared/workflow-history-event-details-wf-execution-link/workflow-history-event-details-wf-execution-link';
78
import { type WorkflowSummaryTabDetailsConfig } from '../workflow-summary-tab-details/workflow-summary-tab-details.types';
8-
import WorkflowSummaryTabDetailsExecutionLink from '../workflow-summary-tab-details-wf-execution-link/workflow-summary-tab-details-wf-execution-link';
99

1010
const workflowSummaryTabDetailsConfig: WorkflowSummaryTabDetailsConfig[] = [
1111
{
@@ -29,7 +29,7 @@ const workflowSummaryTabDetailsConfig: WorkflowSummaryTabDetailsConfig[] = [
2929
firstEvent?.workflowExecutionStartedEventAttributes
3030
?.continuedExecutionRunId;
3131
if (runId) {
32-
return createElement(WorkflowSummaryTabDetailsExecutionLink, {
32+
return createElement(WorkflowHistoryEventDetailsExecutionLink, {
3333
...decodedPageUrlParams,
3434
runId,
3535
});
@@ -116,7 +116,7 @@ const workflowSummaryTabDetailsConfig: WorkflowSummaryTabDetailsConfig[] = [
116116
formattedFirstEvent?.parentWorkflowExecution || {};
117117
const domain = formattedFirstEvent?.parentWorkflowDomain;
118118
if (runId && workflowId && domain && decodedPageUrlParams.cluster) {
119-
return createElement(WorkflowSummaryTabDetailsExecutionLink, {
119+
return createElement(WorkflowHistoryEventDetailsExecutionLink, {
120120
domain,
121121
cluster: decodedPageUrlParams.cluster,
122122
workflowId,

src/views/workflow-summary-tab/workflow-summary-tab-details-wf-execution-link/__tests__/workflow-summary-tab-details-wf-execution-link.test.tsx

Lines changed: 0 additions & 34 deletions
This file was deleted.

src/views/workflow-summary-tab/workflow-summary-tab-details-wf-execution-link/workflow-summary-tab-details-wf-execution-link.tsx

Lines changed: 0 additions & 24 deletions
This file was deleted.

0 commit comments

Comments
 (0)