Skip to content

Commit 08b1370

Browse files
authored
Merge pull request #97 from sdkman/jdk-installation-improvements
Improvements to the installation section of the JDK details page
2 parents ad05c6c + 3923d3b commit 08b1370

File tree

14 files changed

+328
-25
lines changed

14 files changed

+328
-25
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,4 @@ yarn-error.log*
2525
# Hide auto generated doc pages
2626
/docs/jdks.mdx
2727
/docs/sdks.mdx
28+
/src/data/jdks-versions.ts

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@
1313
"write-translations": "docusaurus write-translations",
1414
"write-heading-ids": "docusaurus write-heading-ids",
1515
"typecheck": "tsc",
16-
"preprocessing:start": "tsc --outDir ./preprocessing/out ./preprocessing/src/*.ts && node ./preprocessing/out/index.js",
17-
"preprocessing:clear": "rm -rf ./preprocessing/out ./docs/jdks.mdx ./docs/sdks.mdx"
16+
"preprocessing:start": "tsc --outDir ./preprocessing/out ./preprocessing/src/*.ts && node ./preprocessing/out/preprocessing/src/index.js",
17+
"preprocessing:clear": "rm -rf ./preprocessing/out ./src/data/jdks-versions.ts ./docs/sdks.mdx"
1818
},
1919
"dependencies": {
2020
"@docusaurus/core": "^3.7.0",

preprocessing/src/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1+
import generateJDKs from './jdks';
12
import generateSDKs from './sdks';
23

34
async function run() {
45
try {
5-
await generateSDKs();
6+
await Promise.all([generateJDKs(), generateSDKs()]);
67
} catch (err) {
78
console.error(err);
89
}

preprocessing/src/jdks/index.ts

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import type { Platform } from '../../../src/types/jdk';
2+
3+
import { writeFile } from 'node:fs/promises';
4+
import { resolve } from 'node:path';
5+
6+
const platformList: Platform[] = [
7+
'linuxx64',
8+
'linuxarm32hf',
9+
'linuxarm64',
10+
'darwinx64',
11+
'darwinarm64',
12+
'windowsx64',
13+
];
14+
15+
export default async function generateJDKs() {
16+
const result = [];
17+
18+
for (const platform of platformList) {
19+
const JDKsData = await fetchJDKs(platform);
20+
const JDKs = parseJDKs(JDKsData);
21+
22+
result.push({
23+
platform,
24+
versions: JDKs,
25+
});
26+
}
27+
28+
try {
29+
await writeFile(
30+
resolve(process.cwd(), './src/data/jdks-versions.ts'),
31+
`const result = ${JSON.stringify(result, null, 2)};\n\n` +
32+
'export default result;',
33+
);
34+
} catch (err) {
35+
console.error(err);
36+
}
37+
}
38+
39+
async function fetchJDKs(platformId: Platform) {
40+
try {
41+
const res = await fetch(
42+
`https://api.sdkman.io/2/candidates/java/${platformId}/versions/list?installed=`,
43+
);
44+
45+
return await res.text();
46+
} catch (err) {
47+
console.error(err);
48+
}
49+
}
50+
51+
function parseJDKs(data: string) {
52+
return data
53+
.split('\n')
54+
.slice(5, -10)
55+
.reduce<{ version: string; dist: string }[]>((acc, val) => {
56+
const rowParts = val.split('|').map((item) => item.trim());
57+
58+
acc.push({
59+
version: rowParts[2],
60+
dist: rowParts[3],
61+
});
62+
63+
return acc;
64+
}, []);
65+
}
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
import type { Architecture } from '@site/src/types/jdk';
2+
import * as React from 'react';
3+
import CodeBlock from '@theme/CodeBlock';
4+
import Heading from '@theme/Heading';
5+
import Select from '@site/src/components/ui/Select';
6+
import styles from './styles.module.scss';
7+
8+
import { jdksService } from '@site/src/lib/services/jdks';
9+
import clsx from 'clsx';
10+
11+
type Props = {
12+
id: string;
13+
architecture: Architecture[];
14+
};
15+
16+
export default function Installation({ id, architecture }: Props) {
17+
const [platform, setPlatform] = React.useState(architecture[0].label);
18+
const [versions, setVersions] = React.useState([]);
19+
const [version, setVersion] = React.useState('');
20+
21+
React.useEffect(() => {
22+
const currentPlatformId = architecture.find(
23+
(arch) => arch.label === platform,
24+
).platformId;
25+
26+
const data = jdksService.getVersions(currentPlatformId, id);
27+
setVersions(data);
28+
setVersion(data[0]);
29+
}, [platform]);
30+
31+
function handleCHangePlatform(value: string) {
32+
setPlatform(value);
33+
}
34+
35+
function handleChangeVersion(value: string) {
36+
setVersion(value);
37+
}
38+
39+
return (
40+
<div>
41+
<div className={styles.sectionTitleWrapper}>
42+
<Heading as="h2">Installation</Heading>
43+
44+
<div className={styles.sectionSelectWrapper}>
45+
<Select
46+
value={platform}
47+
items={architecture.map((arch) => arch.label)}
48+
position="right"
49+
onChange={handleCHangePlatform}
50+
/>
51+
52+
<Select
53+
value={version}
54+
items={versions}
55+
position="right"
56+
onChange={handleChangeVersion}
57+
/>
58+
</div>
59+
</div>
60+
61+
<CodeBlock language="shell">
62+
sdk install java {version}-{id}
63+
</CodeBlock>
64+
65+
<ul className={styles.sectionBadgeList}>
66+
{versions.map((badgeVersion, idx) => (
67+
<li key={`version-${idx}`}>
68+
<button
69+
className={clsx(
70+
'badge',
71+
badgeVersion === version
72+
? 'badge--primary'
73+
: 'badge--secondary',
74+
)}
75+
onClick={() => handleChangeVersion(badgeVersion)}
76+
>
77+
{badgeVersion}
78+
</button>
79+
</li>
80+
))}
81+
</ul>
82+
</div>
83+
);
84+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
.section {
2+
&TitleWrapper {
3+
display: flex;
4+
justify-content: space-between;
5+
}
6+
7+
&SelectWrapper {
8+
display: flex;
9+
align-items: flex-end;
10+
justify-content: flex-end;
11+
margin-bottom: 1.125rem;
12+
}
13+
14+
&BadgeList {
15+
list-style: none;
16+
padding: 0;
17+
display: flex;
18+
flex-wrap: wrap;
19+
gap: 0.5rem;
20+
}
21+
}

src/components/plugins-pages/JDKDetailsPage/index.tsx

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { Redirect, useLocation } from '@docusaurus/router';
22
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
33
import Link from '@docusaurus/Link';
4-
import CodeBlock from '@theme/CodeBlock';
54
import Heading from '@theme/Heading';
65
import Layout from '@theme/Layout';
76
import PageCarbonAds from '@site/src/components/sections/PageCarbonAds';
@@ -10,6 +9,7 @@ import styles from './styles.module.scss';
109

1110
import jdks from '@site/src/data/jdks';
1211
import { getNameFromPath } from '@site/src/lib/utils';
12+
import Installation from './Installation';
1313

1414
export default function JDKDetailsPage() {
1515
const { siteConfig } = useDocusaurusContext();
@@ -37,13 +37,7 @@ export default function JDKDetailsPage() {
3737
<div>
3838
<p>{JDK.description}</p>
3939

40-
<div>
41-
<Heading as="h2">Installation</Heading>
42-
43-
<CodeBlock language="shell">
44-
sdk install java x.y.z-{JDK.id}
45-
</CodeBlock>
46-
</div>
40+
<Installation id={JDK.id} architecture={JDK.architecture?.long} />
4741
</div>
4842

4943
<div className={clsx('card', styles.card)}>
@@ -71,7 +65,7 @@ export default function JDKDetailsPage() {
7165

7266
<ul>
7367
{JDK.architecture?.long.map((arch, idx) => (
74-
<li key={`arch-${JDK.id}-${idx}`}>{arch}</li>
68+
<li key={`arch-${JDK.id}-${idx}`}>{arch.label}</li>
7569
))}
7670
</ul>
7771
</div>

src/components/sections/JDKList/JDKCard/index.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1+
import type { JDK } from '@site/src/types/jdk';
12
import Link from '@docusaurus/Link';
23
import clsx from 'clsx';
34
import styles from './styles.module.scss';
45

5-
import { JDK } from '@site/src/types/jdk';
6-
76
type Props = {
87
item: JDK;
98
};

src/components/sections/JDKList/index.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@ export default function JDKList() {
4242
</Admonition>
4343

4444
<div className={styles.sectionList}>
45-
{jdks.map((JDK) => (
46-
<JDKCard item={JDK} />
45+
{jdks.map((JDK, idx) => (
46+
<JDKCard key={`jdk-${idx}`} item={JDK} />
4747
))}
4848
</div>
4949
</div>

src/components/ui/Select/index.tsx

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
import * as React from 'react';
2+
import clsx from 'clsx';
3+
import styles from './styles.module.scss';
4+
5+
type Props = {
6+
className?: string;
7+
value: string;
8+
items: string[];
9+
position?: 'left' | 'right';
10+
onChange: (value: string) => void;
11+
};
12+
13+
export default function Select({
14+
className,
15+
value,
16+
items,
17+
position = 'left',
18+
onChange,
19+
}: Props) {
20+
const dropdownRef = React.useRef<HTMLDivElement>(null);
21+
const [showDropdown, setShowDropdown] = React.useState(false);
22+
23+
React.useEffect(() => {
24+
const handleClickOutside = (
25+
event: MouseEvent | TouchEvent | FocusEvent,
26+
) => {
27+
if (
28+
!dropdownRef.current ||
29+
dropdownRef.current.contains(event.target as Node)
30+
) {
31+
return;
32+
}
33+
setShowDropdown(false);
34+
};
35+
36+
document.addEventListener('mousedown', handleClickOutside);
37+
document.addEventListener('touchstart', handleClickOutside);
38+
document.addEventListener('focusin', handleClickOutside);
39+
40+
return () => {
41+
document.removeEventListener('mousedown', handleClickOutside);
42+
document.removeEventListener('touchstart', handleClickOutside);
43+
document.removeEventListener('focusin', handleClickOutside);
44+
};
45+
}, [dropdownRef]);
46+
47+
function handleClick() {
48+
setShowDropdown(!showDropdown);
49+
}
50+
51+
function handleKeyDown(event: React.KeyboardEvent<HTMLDivElement>) {
52+
if (event.key === 'Enter') {
53+
event.preventDefault();
54+
setShowDropdown(!showDropdown);
55+
}
56+
}
57+
58+
return (
59+
<div
60+
ref={dropdownRef}
61+
className={clsx('dropdown', className, {
62+
'dropdown--right': position === 'right',
63+
'dropdown--show': showDropdown,
64+
})}
65+
onClick={handleClick}
66+
onKeyDown={handleKeyDown}
67+
>
68+
<button
69+
aria-haspopup="true"
70+
aria-expanded={showDropdown}
71+
className={clsx('navbar__link', styles.button, styles.buttonBackground)}
72+
>
73+
{value}
74+
</button>
75+
76+
<ul className="dropdown__menu">
77+
{items.map((item, idx) => (
78+
<li key={`${item}-${idx}`}>
79+
<button
80+
className={clsx(
81+
'dropdown__link',
82+
styles.button,
83+
item === value
84+
? 'dropdown__link--active'
85+
: styles.buttonBackground,
86+
)}
87+
onClick={() => onChange(item)}
88+
>
89+
{item}
90+
</button>
91+
</li>
92+
))}
93+
</ul>
94+
</div>
95+
);
96+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
.button {
2+
width: 100%;
3+
border: none;
4+
text-align: left;
5+
font-weight: 700;
6+
7+
&Background {
8+
background-color: transparent;
9+
}
10+
}

src/data/jdks.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { JDK } from '@site/src/types/jdk';
1+
import type { Architecture, JDK } from '@site/src/types/jdk';
22
import { FaApple, FaLinux, FaWindows } from 'react-icons/fa6';
33

44
const shortArchList = {
@@ -7,13 +7,13 @@ const shortArchList = {
77
arm32: 'AArch32',
88
};
99

10-
const archList = {
11-
linux_x86_64: 'Linux x86_64',
12-
linux_arm: 'Linux AArch32',
13-
linux_arm64: 'Linux AArch64',
14-
macOS_x86_64: 'macOS x86_64',
15-
macOS_arm64: 'macOS AArch64',
16-
windows_x86_64: 'Windows x86_64',
10+
const archList: Record<string, Architecture> = {
11+
linux_x86_64: { label: 'Linux x86_64', platformId: 'linuxx64' },
12+
linux_arm: { label: 'Linux AArch32', platformId: 'linuxarm32hf' },
13+
linux_arm64: { label: 'Linux AArch64', platformId: 'linuxarm64' },
14+
macOS_x86_64: { label: 'macOS x86_64', platformId: 'darwinx64' },
15+
macOS_arm64: { label: 'macOS AArch64', platformId: 'darwinarm64' },
16+
windows_x86_64: { label: 'Windows x86_64', platformId: 'windowsx64' },
1717
};
1818

1919
const jdks: JDK[] = [

0 commit comments

Comments
 (0)