Skip to content

Commit b4a93d8

Browse files
authored
Add SDK Name, Logo and Version to Workflow Details (#2613)
* Add all sdk versions and logos * Remove toolchain * Rearrange logo * use typescript * Remove dash and font-mono
1 parent 9ed1927 commit b4a93d8

12 files changed

+285
-0
lines changed

Diff for: src/lib/components/lines-and-dots/sdk-logo.svelte

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<script lang="ts">
2+
import { fullEventHistory } from '$lib/stores/events';
3+
import { getSDKandVersion } from '$lib/utilities/get-sdk-version';
4+
import { isWorkflowTaskCompletedEvent } from '$lib/utilities/is-event-type';
5+
import dotNet from '$lib/vendor/sdk-logos/dot-net-logo.png';
6+
import go from '$lib/vendor/sdk-logos/go-logo.png';
7+
import java from '$lib/vendor/sdk-logos/java-logo.png';
8+
import php from '$lib/vendor/sdk-logos/php-logo.png';
9+
import python from '$lib/vendor/sdk-logos/python-logo.png';
10+
import ruby from '$lib/vendor/sdk-logos/ruby-logo.png';
11+
import rust from '$lib/vendor/sdk-logos/rust-logo.png';
12+
import typescript from '$lib/vendor/sdk-logos/ts-logo.png';
13+
14+
const sdkLogos: Record<string, string> = {
15+
go,
16+
typescript,
17+
java,
18+
python,
19+
'.net': dotNet,
20+
ruby,
21+
php,
22+
rust,
23+
};
24+
25+
$: workflowCompletedTasks = $fullEventHistory.filter(
26+
isWorkflowTaskCompletedEvent,
27+
);
28+
29+
$: ({ sdk, version } = getSDKandVersion(workflowCompletedTasks));
30+
$: logo = sdkLogos[sdk.toLowerCase()];
31+
</script>
32+
33+
{#if sdk && version}
34+
<div class="flex h-4 items-center justify-between gap-16 whitespace-nowrap">
35+
<span class="font-mono">SDK</span>
36+
<p class="flex items-center gap-1">
37+
{#if logo}
38+
<img src={logo} alt="SDK Icon" class="h-6 w-6" />
39+
{/if}
40+
{sdk}
41+
{version}
42+
</p>
43+
</div>
44+
{/if}

Diff for: src/lib/components/lines-and-dots/workflow-details.svelte

+2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
routeForWorkflowsWithQuery,
1414
} from '$lib/utilities/route-for';
1515
16+
import SdkLogo from './sdk-logo.svelte';
1617
import WorkflowDetail from './workflow-detail.svelte';
1718
1819
export let workflow: WorkflowExecution;
@@ -131,6 +132,7 @@
131132
<div
132133
class="flex w-full flex-col gap-2 {deployment ? '2xl:w-1/4' : 'xl:w-1/3'}"
133134
>
135+
<SdkLogo />
134136
{#if workflow?.parent}
135137
<WorkflowDetail
136138
title={translate('workflows.parent-workflow')}

Diff for: src/lib/utilities/get-sdk-version.test.ts

+208
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,208 @@
1+
import { describe, expect, it } from 'vitest';
2+
3+
import { getSDKandVersion } from './get-sdk-version';
4+
5+
describe('getSDKandVersion', () => {
6+
const workflowTaskCompletedEvent = {
7+
attributes: {
8+
sdkMetadata: {},
9+
},
10+
};
11+
it('should return empty string if neither exist in task', () => {
12+
const sdk = getSDKandVersion([workflowTaskCompletedEvent]).sdk;
13+
const version = getSDKandVersion([workflowTaskCompletedEvent]).version;
14+
expect(sdk).toBe('');
15+
expect(version).toBe('');
16+
});
17+
18+
it('should return Go sdk and version if both exist in task', () => {
19+
const workflowTaskCompletedEvent = {
20+
attributes: {
21+
sdkMetadata: {
22+
sdkName: 'temporal-go',
23+
sdkVersion: '1.29.1',
24+
},
25+
},
26+
};
27+
28+
const sdk = getSDKandVersion([workflowTaskCompletedEvent]).sdk;
29+
const version = getSDKandVersion([workflowTaskCompletedEvent]).version;
30+
expect(sdk).toBe('Go');
31+
expect(version).toBe('1.29.1');
32+
});
33+
34+
it('should return Java sdk and version if both exist in task', () => {
35+
const workflowTaskCompletedEvent = {
36+
attributes: {
37+
sdkMetadata: {
38+
sdkName: 'temporal-java',
39+
sdkVersion: '1.0.5',
40+
},
41+
},
42+
};
43+
44+
const sdk = getSDKandVersion([workflowTaskCompletedEvent]).sdk;
45+
const version = getSDKandVersion([workflowTaskCompletedEvent]).version;
46+
expect(sdk).toBe('Java');
47+
expect(version).toBe('1.0.5');
48+
});
49+
50+
it('should return Typescript sdk and version if both exist in task', () => {
51+
const workflowTaskCompletedEvent = {
52+
attributes: {
53+
sdkMetadata: {
54+
sdkName: 'temporal-typescript',
55+
sdkVersion: '2.20.5',
56+
},
57+
},
58+
};
59+
60+
const sdk = getSDKandVersion([workflowTaskCompletedEvent]).sdk;
61+
const version = getSDKandVersion([workflowTaskCompletedEvent]).version;
62+
expect(sdk).toBe('Typescript');
63+
expect(version).toBe('2.20.5');
64+
});
65+
66+
it('should return Dotnet sdk and version if both exist in task', () => {
67+
const workflowTaskCompletedEvent = {
68+
attributes: {
69+
sdkMetadata: {
70+
sdkName: 'temporal-dotnet',
71+
sdkVersion: '2.20.5',
72+
},
73+
},
74+
};
75+
76+
const sdk = getSDKandVersion([workflowTaskCompletedEvent]).sdk;
77+
const version = getSDKandVersion([workflowTaskCompletedEvent]).version;
78+
expect(sdk).toBe('.NET');
79+
expect(version).toBe('2.20.5');
80+
});
81+
82+
it('should return Python sdk and version if both exist in task', () => {
83+
const workflowTaskCompletedEvent = {
84+
attributes: {
85+
sdkMetadata: {
86+
sdkName: 'temporal-python',
87+
sdkVersion: '0.2.11',
88+
},
89+
},
90+
};
91+
92+
const sdk = getSDKandVersion([workflowTaskCompletedEvent]).sdk;
93+
const version = getSDKandVersion([workflowTaskCompletedEvent]).version;
94+
expect(sdk).toBe('Python');
95+
expect(version).toBe('0.2.11');
96+
});
97+
98+
it('should return Php sdk and version if both exist in task', () => {
99+
const workflowTaskCompletedEvent = {
100+
attributes: {
101+
sdkMetadata: {
102+
sdkName: 'temporal-php',
103+
sdkVersion: '0.2.11',
104+
},
105+
},
106+
};
107+
108+
const sdk = getSDKandVersion([workflowTaskCompletedEvent]).sdk;
109+
const version = getSDKandVersion([workflowTaskCompletedEvent]).version;
110+
expect(sdk).toBe('Php');
111+
expect(version).toBe('0.2.11');
112+
});
113+
114+
it('should return Rust sdk and version if both exist in task', () => {
115+
const workflowTaskCompletedEvent = {
116+
attributes: {
117+
sdkMetadata: {
118+
sdkName: 'temporal-rust',
119+
sdkVersion: '1.3.2',
120+
},
121+
},
122+
};
123+
124+
const sdk = getSDKandVersion([workflowTaskCompletedEvent]).sdk;
125+
const version = getSDKandVersion([workflowTaskCompletedEvent]).version;
126+
expect(sdk).toBe('Rust');
127+
expect(version).toBe('1.3.2');
128+
});
129+
130+
it('should return Ruby sdk and version if both exist in task', () => {
131+
const workflowTaskCompletedEvent = {
132+
attributes: {
133+
sdkMetadata: {
134+
sdkName: 'temporal-ruby',
135+
sdkVersion: '1.3.21',
136+
},
137+
},
138+
};
139+
140+
const sdk = getSDKandVersion([workflowTaskCompletedEvent]).sdk;
141+
const version = getSDKandVersion([workflowTaskCompletedEvent]).version;
142+
expect(sdk).toBe('Ruby');
143+
expect(version).toBe('1.3.21');
144+
});
145+
146+
it('should return newer Go version with multiple tasks', () => {
147+
const workflowTaskCompletedEvent1 = {
148+
attributes: {
149+
sdkMetadata: {
150+
sdkName: 'temporal-go',
151+
sdkVersion: '1.29.1',
152+
},
153+
},
154+
};
155+
156+
const workflowTaskCompletedEvent2 = {
157+
attributes: {
158+
sdkMetadata: {
159+
sdkVersion: '1.30.5',
160+
},
161+
},
162+
};
163+
const events = [workflowTaskCompletedEvent1, workflowTaskCompletedEvent2];
164+
165+
const sdk = getSDKandVersion(events).sdk;
166+
const version = getSDKandVersion(events).version;
167+
expect(sdk).toBe('Go');
168+
expect(version).toBe('1.30.5');
169+
});
170+
171+
it('should return newer SDK version with multiple tasks', () => {
172+
const workflowTaskCompletedEvent1 = {
173+
attributes: {
174+
sdkMetadata: {
175+
sdkName: 'temporal-go',
176+
sdkVersion: '1.29.1',
177+
},
178+
},
179+
};
180+
181+
const workflowTaskCompletedEvent2 = {
182+
attributes: {
183+
sdkMetadata: {
184+
sdkName: 'temporal-ruby',
185+
sdkVersion: '1.2.3',
186+
},
187+
},
188+
};
189+
190+
const workflowTaskCompletedEvent3 = {
191+
attributes: {
192+
sdkMetadata: {
193+
sdkVersion: '1.2.10',
194+
},
195+
},
196+
};
197+
const events = [
198+
workflowTaskCompletedEvent1,
199+
workflowTaskCompletedEvent2,
200+
workflowTaskCompletedEvent3,
201+
];
202+
203+
const sdk = getSDKandVersion(events).sdk;
204+
const version = getSDKandVersion(events).version;
205+
expect(sdk).toBe('Ruby');
206+
expect(version).toBe('1.2.10');
207+
});
208+
});

Diff for: src/lib/utilities/get-sdk-version.ts

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import type { WorkflowTaskCompletedEvent } from '$lib/types/events';
2+
3+
import { capitalize } from './format-camel-case';
4+
5+
export const getSDKandVersion = (
6+
tasks: WorkflowTaskCompletedEvent[],
7+
): { sdk: string; version: string } => {
8+
let sdk = '';
9+
let version = '';
10+
11+
if (!tasks?.length) return { sdk, version };
12+
13+
tasks.forEach((event) => {
14+
const sdkMetadata = event?.attributes?.sdkMetadata;
15+
if (sdkMetadata) {
16+
const sdkName = sdkMetadata?.sdkName;
17+
const sdkVersion = sdkMetadata?.sdkVersion;
18+
if (sdkName) {
19+
sdk = capitalize(sdkName.split('-')[1]);
20+
if (sdk === 'Dotnet') {
21+
sdk = '.NET';
22+
}
23+
}
24+
if (sdkVersion) {
25+
version = sdkVersion;
26+
}
27+
}
28+
});
29+
30+
return { sdk, version };
31+
};

Diff for: src/lib/vendor/sdk-logos/dot-net-logo.png

1.33 KB
Loading

Diff for: src/lib/vendor/sdk-logos/go-logo.png

9.72 KB
Loading

Diff for: src/lib/vendor/sdk-logos/java-logo.png

24.6 KB
Loading

Diff for: src/lib/vendor/sdk-logos/php-logo.png

7.08 KB
Loading

Diff for: src/lib/vendor/sdk-logos/python-logo.png

8.51 KB
Loading

Diff for: src/lib/vendor/sdk-logos/ruby-logo.png

14 KB
Loading

Diff for: src/lib/vendor/sdk-logos/rust-logo.png

3.54 KB
Loading

Diff for: src/lib/vendor/sdk-logos/ts-logo.png

1.8 KB
Loading

0 commit comments

Comments
 (0)