Skip to content

Commit 672069d

Browse files
authored
Improve JDK acquisition UX (#179)
* Improve JDK acquisition UX Signed-off-by: Rome Li <[email protected]> * Resolve comments Signed-off-by: Rome Li <[email protected]>
1 parent 4da1043 commit 672069d

File tree

8 files changed

+335
-188
lines changed

8 files changed

+335
-188
lines changed

src/java-runtime/assets/index.html

Lines changed: 1 addition & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -14,122 +14,7 @@
1414
<h1>Java Development Kit</h1>
1515
</div>
1616
</div>
17-
<div class="row">
18-
<div class="col">
19-
<div class="row mb-3">
20-
<div class="col">
21-
<h3 class="font-weight-light">Configure</h3>
22-
<p>
23-
Java Development Kit (JDK) 8 or later is required for developing Java applications. The path to the JDK is searched in the following order:
24-
</p>
25-
<div class="card">
26-
<div class="card-body">
27-
<div id="javaRuntimeEntryPanel"></div>
28-
</div>
29-
</div>
30-
</div>
31-
</div>
32-
<div class="row mb-3">
33-
<div class="col">
34-
<h3 class="font-weight-light">Install</h3>
35-
<p>
36-
⚠️ No JDK installation was detected. Please follow the links below to download and install JDK:
37-
</p>
38-
<p class="d-none">
39-
<a href="#">Install extra JDKs</a>
40-
</p>
41-
<div class="card">
42-
<div class="card-body">
43-
<ul class="nav nav-tabs mb-3" id="jdkSourceTab" role="tablist">
44-
<li class="nav-item">
45-
<a class="nav-link active" id="adoptOpenJdkTab" data-toggle="tab" href="#adoptOpenJdkPanel" role="tab" aria-controls="adoptOpenJdkPanel" aria-selected="true" title="Reliable source of OpenJDK binaries for all platforms">AdoptOpenJDK</a>
46-
</li>
47-
<li class="nav-item">
48-
<a class="nav-link" id="otherJdkTab" data-toggle="tab" href="#otherJdkPanel" role="tab" aria-controls="otherJdkPanel" aria-selected="false" title="Other choices">Others</a>
49-
</li>
50-
</ul>
51-
<div class="tab-content" id="jdkTabContent">
52-
<div class="tab-pane fade show active" id="adoptOpenJdkPanel" role="tabpanel" aria-labelledby="adoptOpenJdkTab">
53-
<form>
54-
<div class="form-row align-items-center">
55-
<div class="form-group col mb-1">
56-
<h6 class="text-capitalize mb-2">
57-
Download for
58-
<span id="jdkOs">windows</span>
59-
<span id="jdkArch">x64</span>
60-
</h6>
61-
</div>
62-
</div>
63-
<div class="form-row">
64-
<div class="form-group col-sm-6">
65-
<label>JDK Version:</label>
66-
<div class="form-check">
67-
<input class="form-check-input" type="radio" name="jdkVersion" id="openjdk8Radio" value="openjdk8">
68-
<label class="form-check-label" for="openjdk8Radio">
69-
OpenJDK 8
70-
</label>
71-
</div>
72-
<div class="form-check">
73-
<input class="form-check-input" type="radio" name="jdkVersion" id="openjdk11Radio" value="openjdk11" checked>
74-
<label class="form-check-label" for="openjdk11Radio">
75-
OpenJDK 11
76-
</label>
77-
</div>
78-
<div class="form-check">
79-
<input class="form-check-input" type="radio" name="jdkVersion" id="openjdk12Radio" value="openjdk12">
80-
<label class="form-check-label" for="openjdk12Radio">
81-
OpenJDK 12 (Technical Preview)
82-
</label>
83-
</div>
84-
</div>
85-
<div class="form-group col-sm-6">
86-
<label>JVM:</label>
87-
<div class="form-check">
88-
<input class="form-check-input" type="radio" name="jvmImpl" id="hotspotRadio" value="hotspot" checked>
89-
<label class="form-check-label" for="hotspotRadio">
90-
Hotspot (Recommended)
91-
</label>
92-
</div>
93-
<div class="form-check">
94-
<input class="form-check-input" type="radio" name="jvmImpl" id="openj9Radio" value="openj9">
95-
<label class="form-check-label" for="openj9Radio">
96-
OpenJ9
97-
</label>
98-
</div>
99-
</div>
100-
</div>
101-
<div class="form-row">
102-
<div class="form-group col-sm-12">
103-
<div class="spinner-border spinner-border-sm" role="status" id="jdkSpinner">
104-
<span class="sr-only">Loading...</span>
105-
</div>
106-
<a class="btn btn-primary btn-lg d-none" id="jdkDownloadLink" href="command:java.helper.openUrl" role="button" title="Download JDK">
107-
Download
108-
<br>
109-
<sub id="jdkReleaseName">release</sub><sub> | </sub><sub id="jdkDownloadSize">size</sub>
110-
</a>
111-
</div>
112-
</div>
113-
</form>
114-
</div>
115-
<div class="tab-pane fade" id="otherJdkPanel" role="tabpanel" aria-labelledby="otherJdkTab">
116-
<ul id="jdkProviderList" class="list-unstyled">
117-
<li><a href="command:java.helper.openUrl?%22https%3A%2F%2Fwww.azul.com%2Fdownloads%2Fazure-only%2Fzulu%2F%22" title="Recommended for Microsoft Azure Cloud and Azure Stack applications">Azul Zulu Enterprise build of OpenJDK for Azure</a></li>
118-
<li><a href="command:java.helper.openUrl?%22https%3A%2F%2Fdevelopers.redhat.com%2Fproducts%2Fopenjdk%2Fdownload%22" title="Red Hat build of OpenJDK">Red Hat build of OpenJDK</a></li>
119-
<li><a href="command:java.helper.openUrl?%22https%3A%2F%2Fjdk.java.net%2F%22" title="OpenJDK by Oracle">Oracle OpenJDK</a></li>
120-
</ul>
121-
</div>
122-
</div>
123-
<p>When you are finished, please reload Visual Studio Code to activate Java language server.</p>
124-
<p class="mb-0">
125-
<a class="btn btn-primary" href="command:workbench.action.reloadWindow" role="button" title="Reload Visual Studio Code">Reload Window</a>
126-
<a class="btn btn-secondary" href="command:java.helper.openUrl?%22https%3A%2F%2Fgithub.com%2Fredhat-developer%2Fvscode-java%23setting-the-jdk%22" role="button" title="More info on how JDK is resolved">Having Trouble?</a>
127-
</p>
128-
</div>
129-
</div>
130-
</div>
131-
</div>
132-
</div>
17+
<div class="row" id="jdkAcquisitionPanel">
13318
</div>
13419
</div>
13520
</body>

src/java-runtime/assets/index.ts

Lines changed: 30 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
// Copyright (c) Microsoft Corporation. All rights reserved.
22
// Licensed under the MIT license.
33

4-
import $ = require("jquery");
54
import "../../assets/vscode.scss";
65
import "bootstrap/js/src/tab";
76
import bytes = require("bytes");
8-
import { JavaRuntimeEntryPanel } from "./java.runtime.entries";
97
import * as ReactDOM from "react-dom";
10-
import { JavaRuntimeEntry } from "../types";
8+
import { JavaRuntimeEntry, JdkData } from "../types";
9+
import { JdkAcquisitionPanel, JdkAcquisitionPanelProps } from "./jdk.acquisition";
10+
import * as React from "react";
1111

1212
window.addEventListener("message", event => {
1313
if (event.data.command === "applyJdkInfo") {
@@ -17,25 +17,43 @@ window.addEventListener("message", event => {
1717
}
1818
});
1919

20+
let jdkEntries: JavaRuntimeEntry[];
21+
2022
function showJavaRuntimeEntries(entries: JavaRuntimeEntry[]) {
21-
ReactDOM.render(JavaRuntimeEntryPanel(entries), document.getElementById("javaRuntimeEntryPanel"));
23+
jdkEntries = entries;
24+
render();
2225
}
2326

27+
let jdkData: JdkData;
28+
2429
function applyJdkInfo(jdkInfo: any) {
2530
let binary = jdkInfo.binaries[0];
2631
let downloadLink = binary.installer_link || binary.binary_link;
27-
$("#jdkOs").text(binary.os);
28-
$("#jdkArch").text(binary.architecture);
29-
$("#jdkReleaseName").text(jdkInfo.release_name);
30-
$("#jdkDownloadSize").text(bytes(binary.binary_size, {unitSeparator: " "}));
31-
3232
let encodedLink = `command:java.helper.openUrl?${encodeURIComponent(JSON.stringify(downloadLink))}`;
33-
$("#jdkDownloadLink").attr("href", encodedLink);
3433

35-
$("#jdkSpinner").addClass("d-none");
36-
$("#jdkDownloadLink").removeClass("d-none");
34+
jdkData = {
35+
name: jdkInfo.release_name,
36+
os: binary.os,
37+
arch: binary.architecture,
38+
size: bytes(binary.binary_size, {unitSeparator: " "}),
39+
downloadLink: encodedLink
40+
};
41+
42+
render();
43+
}
44+
45+
function render() {
46+
const props: JdkAcquisitionPanelProps = {
47+
jdkEntries: jdkEntries,
48+
jdkData: jdkData,
49+
onRequestJdk: requestJdkInfo
50+
};
51+
52+
ReactDOM.render(React.createElement(JdkAcquisitionPanel, props), document.getElementById("jdkAcquisitionPanel"));
3753
}
3854

55+
render();
56+
3957
declare function acquireVsCodeApi(): any;
4058
const vscode = acquireVsCodeApi();
4159

@@ -46,9 +64,3 @@ function requestJdkInfo(jdkVersion: string, jvmImpl: string) {
4664
jvmImpl: jvmImpl
4765
});
4866
}
49-
50-
$("input[type=radio]").change(() => {
51-
$("#jdkSpinner").removeClass("d-none");
52-
$("#jdkDownloadLink").addClass("d-none");
53-
requestJdkInfo($("input[name=jdkVersion]:checked").val() + "", $("input[name=jvmImpl]:checked").val() + "");
54-
});

src/java-runtime/assets/java.runtime.entries.tsx

Lines changed: 0 additions & 53 deletions
This file was deleted.
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT license.
3+
4+
import * as React from "react";
5+
import { JavaRuntimeEntryPanel } from "./jdk.entries";
6+
import { JdkInstallationPanel, JdkRquestHandler } from "./jdk.installation";
7+
import { JavaRuntimeEntry, JdkData } from "../types";
8+
9+
export interface JdkAcquisitionPanelProps {
10+
jdkEntries: JavaRuntimeEntry[];
11+
jdkData: JdkData;
12+
onRequestJdk: JdkRquestHandler;
13+
}
14+
15+
export const JdkAcquisitionPanel = (props: JdkAcquisitionPanelProps) => {
16+
return (
17+
<div className="col">
18+
<div className="row mb-3">
19+
<div className="col">
20+
<h3 className="font-weight-light">Configure</h3>
21+
<p>
22+
Java Development Kit (JDK) 8 or later is required for developing Java applications. The path to the JDK is searched in the following order:
23+
</p>
24+
<div className="card">
25+
<div className="card-body">
26+
<JavaRuntimeEntryPanel data={props.jdkEntries} />
27+
</div>
28+
</div>
29+
</div>
30+
</div>
31+
<div className="row mb-3">
32+
<div className="col">
33+
<h3 className="font-weight-light">Install</h3>
34+
<p>
35+
To download and install JDK, follow the links below:
36+
</p>
37+
<div className="card">
38+
<div className="card-body">
39+
<JdkInstallationPanel data={props.jdkData} onRequestJdk={props.onRequestJdk} />
40+
</div>
41+
</div>
42+
</div>
43+
</div>
44+
</div>
45+
);
46+
};
47+
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT license.
3+
4+
import * as React from "react";
5+
import { JavaRuntimeEntry } from "../types";
6+
import * as _ from "lodash";
7+
8+
export interface JavaRuntimeEntryPanelProps {
9+
data: JavaRuntimeEntry[];
10+
}
11+
12+
export const JavaRuntimeEntryPanel = (props: JavaRuntimeEntryPanelProps | undefined) => {
13+
const isLoading = _.isEmpty(props && props.data);
14+
15+
if (isLoading) {
16+
return (<div className="spinner-border spinner-border-sm" role="status">
17+
<span className="sr-only">Loading...</span>
18+
</div>);
19+
}
20+
21+
const entryData = (props && props.data) || [];
22+
const currentIndex = entryData.findIndex(entry => !!entry.path);
23+
let errorIndex = -1;
24+
if (currentIndex !== -1 && !entryData[currentIndex].isValid) {
25+
errorIndex = currentIndex;
26+
}
27+
28+
const entries = entryData.map((entry, index) => {
29+
let badgeClasses = ["badge", "badge-pill"];
30+
if (index === currentIndex) {
31+
if (index === errorIndex) {
32+
badgeClasses.push("badge-danger");
33+
} else {
34+
badgeClasses.push("badge-success");
35+
}
36+
}
37+
38+
return (
39+
<tr key={index}>
40+
<th scope="row">{index + 1}</th>
41+
<td>
42+
{!entry.path && <em>{"<Empty>"}</em>}
43+
{entry.path}
44+
&nbsp;
45+
{index === currentIndex && <span className={badgeClasses.join(" ")}>Current</span>}
46+
{entry.path && !entry.isValid && <span className="badge badge-pill badge-secondary" title={entry.hint}>Invalid</span>}
47+
{entry.path && entry.hint && <div><em className={errorIndex === index ? "text-danger" : "text-warning"}>{entry.hint}</em></div>}
48+
</td>
49+
<td>
50+
{entry.name}
51+
</td>
52+
<td>
53+
{!entry.actionUri && entry.type}
54+
{entry.actionUri && <a href={entry.actionUri}>{entry.type}</a>}
55+
</td>
56+
</tr>
57+
);
58+
});
59+
60+
const hasValidJdk = _.some(entryData, entry => entry.isValid);
61+
let message = ``;
62+
if (!hasValidJdk) {
63+
message = "⚠️ No JDK installation was detected. Please follow the links below to download and install one.";
64+
} else if (errorIndex !== -1) {
65+
message = "⚠️ The current path is not pointing to a valid JDK folder. Please fix the path and reload VS Code.";
66+
}
67+
68+
return (
69+
<div className="table-responsive">
70+
<table className="table table-borderless table-hover table-sm mb-0">
71+
<caption className="pb-0">
72+
{message ? message : <div>If you change any of the entries above, you need to <a href="command:workbench.action.reloadWindow">reload</a> VS Code to make them effective.</div>}
73+
</caption>
74+
<thead>
75+
<tr>
76+
<th scope="col">#</th>
77+
<th scope="col">Path</th>
78+
<th scope="col">Source</th>
79+
<th scope="col">Type</th>
80+
</tr>
81+
</thead>
82+
<tbody>
83+
{entries}
84+
</tbody>
85+
</table>
86+
</div>
87+
);
88+
};

0 commit comments

Comments
 (0)