Skip to content

Commit 22dbbc7

Browse files
tsmaederfbricon
authored andcommitted
Changed dashboard to webview panel and addressed some PR comments
Signed-off-by: Thomas Mäder <[email protected]>
1 parent 60e056d commit 22dbbc7

File tree

5 files changed

+194
-148
lines changed

5 files changed

+194
-148
lines changed

package.json

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1776,7 +1776,13 @@
17761776
"title": "Dump State",
17771777
"icon": "$(json)",
17781778
"when": "java:dashboard == true"
1779-
}
1779+
},
1780+
{
1781+
"command": "java.dashboard.open",
1782+
"category": "Java",
1783+
"title": "Open Java Dashboard",
1784+
"icon": "$(dashboard)"
1785+
}
17801786
],
17811787
"keybindings": [
17821788
{
@@ -1829,7 +1835,20 @@
18291835
"group": "1_javaactions@2"
18301836
}
18311837
],
1838+
"editor/title": [
1839+
{
1840+
"command": "java.dashboard.refresh",
1841+
"group": "navigation",
1842+
"when": "webviewId == java.dashboard"
1843+
},
1844+
{
1845+
"command": "java.dashboard.dumpState",
1846+
"group": "navigation",
1847+
"when": "webviewId == java.dashboard"
1848+
}
1849+
],
18321850
"editor/context": [
1851+
18331852
{
18341853
"command": "java.project.updateSourceAttachment.command",
18351854
"when": "editorReadonly && editorLangId == java",
@@ -1952,16 +1971,6 @@
19521971
"command": "java.action.showSubtypeHierarchy",
19531972
"group": "navigation@1",
19541973
"when": "view == references-view.tree && reference-list.hasResult && reference-list.source == javaTypeHierarchy"
1955-
},
1956-
{
1957-
"command": "java.dashboard.refresh",
1958-
"group": "navigation",
1959-
"when": "view == java.dashboard"
1960-
},
1961-
{
1962-
"command": "java.dashboard.dumpState",
1963-
"group": "navigation",
1964-
"when": "view == java.dashboard"
19651974
}
19661975
],
19671976
"view/item/context": [
@@ -1971,16 +1980,6 @@
19711980
"when": "view == references-view.tree && reference-list.hasResult && reference-list.source == javaTypeHierarchy && viewItem != 'false'"
19721981
}
19731982
]
1974-
},
1975-
"views": {
1976-
"explorer": [
1977-
{
1978-
"type": "webview",
1979-
"id": "java.dashboard",
1980-
"name": "Java Dashboard",
1981-
"icon": "icons/java-svgrepo-com.svg"
1982-
}
1983-
]
19841983
}
19851984
},
19861985
"scripts": {

src/commands.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,7 @@ export namespace Commands {
372372
export const GET_VISIBLE_EDITOR_CONTENT = '_java.getVisibleEditorContent';
373373

374374
/**
375-
* Get diagnostic info command in jdt.ls
375+
* Get troubleshooting info command in jdt.ls
376376
*/
377377
export const GET_TROUBLESHOOTING_INFO = 'java.getTroubleshootingInfo';
378378
}

src/dashboard/dashboard.ts

Lines changed: 153 additions & 123 deletions
Original file line numberDiff line numberDiff line change
@@ -1,156 +1,186 @@
1-
import { prepareExecutable } from '../javaServerStarter';
2-
import { getComputedJavaConfig, getExecutable, getWorkspacePath } from '../extension';
3-
import * as fs from 'fs';
4-
import * as path from 'path';
51
import * as vscode from 'vscode';
6-
import { getNonce, getUri } from '../webviewUtils';
7-
import { DashboardState, DiagnosticInfo, JVM, UpdateMessage } from '../webviewProtocol/toDashboard';
8-
import { isLombokSupportEnabled, Lombok } from '../lombokSupport';
9-
import { Commands } from '../commands';
102
import { apiManager } from '../apiManager';
3+
import { Commands } from '../commands';
4+
import { getComputedJavaConfig, getWorkspacePath } from '../extension';
5+
import { isLombokSupportEnabled, Lombok } from '../lombokSupport';
6+
import { DashboardState, DiagnosticInfo, JVM, UpdateMessage } from '../webviewProtocol/toDashboard';
7+
import { getNonce, getUri } from '../webviewUtils';
118

129
const currentState: DashboardState = {
1310
};
1411

15-
export namespace Dashboard {
16-
export function initialize(context: vscode.ExtensionContext): void {
17-
console.log('registering dashboard webview provider');
18-
let webview: vscode.Webview;
1912

20-
context.subscriptions.push(vscode.window.registerWebviewViewProvider('java.dashboard', {
21-
resolveWebviewView: async function (webviewView: vscode.WebviewView, webviewContext: vscode.WebviewViewResolveContext, token: vscode.CancellationToken): Promise<void> {
22-
vscode.commands.executeCommand('setContext', 'java:dashboard', true);
23-
webview = webviewView.webview;
24-
webviewView.webview.options = {
25-
enableScripts: true,
26-
enableCommandUris: true,
27-
localResourceRoots: [context.extensionUri]
28-
};
13+
class DashboardPanel {
14+
private disposables: vscode.Disposable[] = [];
2915

30-
webviewView.webview.html = await getWebviewContent(webviewView.webview, context);
31-
webviewView.onDidDispose(() => {
32-
vscode.commands.executeCommand('setContext', 'java:dashboard', false);
33-
});
16+
constructor(private webView: vscode.Webview, private readonly context: vscode.ExtensionContext) {
17+
this.init();
18+
}
19+
20+
private init(): void {
21+
this.disposables.push(vscode.workspace.onDidChangeConfiguration(e => {
22+
if (e.affectsConfiguration('java.jdt.ls.lombokSupport.enabled')) {
23+
currentState.lombokEnabled = isLombokSupportEnabled();
24+
const msg: UpdateMessage = {
25+
type: "update",
26+
lombokEnabled: isLombokSupportEnabled()
27+
};
28+
this.postMessage(msg);
29+
}
30+
if (e.affectsConfiguration('java')) {
31+
setTimeout(() => this.refreshLSInfo(), 1000); // wait for LS to pick up the config change
3432
}
3533
}));
36-
37-
context.subscriptions.push(vscode.commands.registerCommand('java.dashboard.refresh', async () => {
38-
refreshLSInfo(webview);
34+
this.setWebviewMessageListener();
35+
this.webView.html = this.getWebviewContent();
36+
this.disposables.push(vscode.commands.registerCommand('java.dashboard.refresh', async () => {
37+
this.refreshLSInfo();
3938
}));
4039

41-
context.subscriptions.push(vscode.commands.registerCommand('java.dashboard.revealFileInOS', async (arg: { path: string }) => {
40+
this.disposables.push(vscode.commands.registerCommand('java.dashboard.revealFileInOS', async (arg: { path: string }) => {
4241
await vscode.commands.executeCommand('revealFileInOS', vscode.Uri.file(arg.path));
4342
}));
4443

45-
context.subscriptions.push(vscode.commands.registerCommand('java.dashboard.dumpState', async () => {
46-
await vscode.workspace.openTextDocument({
44+
this.disposables.push(vscode.commands.registerCommand('java.dashboard.dumpState', async () => {
45+
const doc = await vscode.workspace.openTextDocument({
4746
language: 'json',
4847
content: JSON.stringify(currentState, null, 2)
4948
});
49+
vscode.window.showTextDocument(doc);
5050
}));
51+
}
5152

52-
console.log('registered dashboard webview provider');
53+
private postMessage(message: UpdateMessage) {
54+
if (this.webView) {
55+
this.webView.postMessage(message);
56+
}
5357
}
54-
}
5558

56-
async function getJvms(): Promise<JVM[]> {
57-
const config = await getComputedJavaConfig();
58-
const jres: JVM[] = config.configuration.runtimes.map(jre => ({
59-
name: jre.name,
60-
version: jre.version,
61-
path: jre.path,
62-
}));
63-
return jres;
59+
private setWebviewMessageListener() {
60+
this.webView.onDidReceiveMessage(
61+
async (message: any) => {
62+
const command = message.command;
63+
switch (command) {
64+
case "webviewReady": {
65+
await apiManager.getApiInstance().serverReady();
66+
currentState.lombokEnabled = isLombokSupportEnabled();
67+
currentState.activeLombokPath = Lombok.getActiveLombokPath();
68+
currentState.workspacePath = getWorkspacePath();
69+
const message: UpdateMessage = {
70+
type: "update",
71+
lombokEnabled: isLombokSupportEnabled(),
72+
activeLombokPath: Lombok.getActiveLombokPath(),
73+
workspacePath: getWorkspacePath(),
74+
};
75+
await this.postMessage(message);
76+
this.getJvms().then(jvms => {
77+
currentState.jvms = jvms;
78+
const msg: UpdateMessage = {
79+
type: "update",
80+
jvms: jvms
81+
};
82+
83+
this.postMessage(msg);
84+
});
85+
86+
this.refreshLSInfo();
87+
break;
88+
}
89+
}
90+
}
91+
);
92+
}
6493

65-
}
94+
public dispose(): void {
95+
this.webView = undefined;
96+
for (const disposable of this.disposables) {
97+
disposable.dispose();
98+
}
99+
}
100+
101+
private async getJvms(): Promise<JVM[]> {
102+
const config = await getComputedJavaConfig();
103+
const jres: JVM[] = config.configuration.runtimes.map(jre => ({
104+
name: jre.name,
105+
version: jre.version,
106+
path: jre.path,
107+
}));
108+
return jres;
66109

67-
function getWebviewContent(webview: vscode.Webview, context: vscode.ExtensionContext) {
68-
setWebviewMessageListener(webview);
69-
70-
const scriptUri = getUri(webview, context.extensionUri, [
71-
"dist",
72-
"dashboard.js",
73-
]);
74-
75-
const nonce = getNonce();
76-
77-
return /* html*/ `
78-
<!DOCTYPE html>
79-
<html lang="en">
80-
<head>
81-
<meta charset="utf-8">
82-
<meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no">
83-
<meta name="theme-color" content="#000000">
84-
<title>Dashboard</title>
85-
</head>
86-
<body>
87-
<div id="root"></div>
88-
<script nonce="${nonce}" src="${scriptUri}"></script>
89-
</body>
90-
</html>
91-
`;
92-
}
93-
async function refreshLSInfo(webview: vscode.Webview): Promise<void> {
94-
try {
95-
vscode.commands.executeCommand<DiagnosticInfo>(Commands.EXECUTE_WORKSPACE_COMMAND, Commands.GET_TROUBLESHOOTING_INFO).then(info => {
96-
currentState.diagnosticInfo = info;
97-
const msg: UpdateMessage = {
98-
type: "update",
99-
diagnosticInfo: info
100-
};
101-
webview.postMessage(msg);
102-
});
103-
} catch (e) {
104-
console.error('Failed to get diagnostic info', e);
105110
}
106-
}
107111

108-
function setWebviewMessageListener(webview: vscode.Webview) {
112+
private getWebviewContent(): string {
113+
const scriptUri = getUri(this.webView, this.context.extensionUri, [
114+
"dist",
115+
"dashboard.js",
116+
]);
117+
118+
const nonce = getNonce();
119+
const codiconsUri = this.webView.asWebviewUri(vscode.Uri.joinPath(this.context.extensionUri, 'node_modules', '@vscode/codicons', 'dist', 'codicon.css'));
120+
121+
return /* html*/ `
122+
<!DOCTYPE html>
123+
<html lang="en">
124+
<head>
125+
<meta charset="utf-8">
126+
<meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no">
127+
<meta name="theme-color" content="#000000">
128+
<link href="${codiconsUri}" rel="stylesheet" />
129+
<title>Dashboard</title>
130+
</head>
131+
<body>
132+
<div id="root"></div>
133+
<script nonce="${nonce}" src="${scriptUri}"></script>
134+
</body>
135+
</html>
136+
`;
137+
}
109138

110-
vscode.workspace.onDidChangeConfiguration(e => {
111-
if (e.affectsConfiguration('java.jdt.ls.lombokSupport.enabled')) {
112-
currentState.lombokEnabled = isLombokSupportEnabled();
113-
const msg: UpdateMessage = {
114-
type: "update",
115-
lombokEnabled: isLombokSupportEnabled()
116-
};
117-
webview.postMessage(msg);
139+
private async refreshLSInfo(): Promise<void> {
140+
if (!this.webView) {
141+
return;
118142
}
119-
if (e.affectsConfiguration('java')) {
120-
setTimeout(() => refreshLSInfo(webview), 1000); // wait for LS to pick up the config change
143+
try {
144+
vscode.commands.executeCommand<DiagnosticInfo>(Commands.EXECUTE_WORKSPACE_COMMAND, Commands.GET_TROUBLESHOOTING_INFO).then(info => {
145+
currentState.diagnosticInfo = info;
146+
const msg: UpdateMessage = {
147+
type: "update",
148+
diagnosticInfo: info
149+
};
150+
this.postMessage(msg);
151+
});
152+
} catch (e) {
153+
console.error('Failed to get diagnostic info', e);
121154
}
122-
});
123-
124-
webview.onDidReceiveMessage(
125-
async (message: any) => {
126-
const command = message.command;
127-
switch (command) {
128-
case "webviewReady": {
129-
await apiManager.getApiInstance().serverReady;
130-
currentState.lombokEnabled = isLombokSupportEnabled();
131-
currentState.activeLombokPath = Lombok.getActiveLombokPath();
132-
currentState.workspacePath = getWorkspacePath();
133-
const message: UpdateMessage = {
134-
type: "update",
135-
lombokEnabled: isLombokSupportEnabled(),
136-
activeLombokPath: Lombok.getActiveLombokPath(),
137-
workspacePath: getWorkspacePath(),
138-
};
139-
await webview.postMessage(message);
140-
getJvms().then(jvms => {
141-
currentState.jvms = jvms;
142-
const msg: UpdateMessage = {
143-
type: "update",
144-
jvms: jvms
145-
};
155+
}
156+
}
146157

147-
webview.postMessage(msg);
148-
});
158+
export namespace Dashboard {
159+
export function initialize(context: vscode.ExtensionContext): void {
160+
console.log('registering dashboard webview provider');
161+
let dashboardPanel: DashboardPanel;
162+
let webviewPanel: vscode.WebviewPanel;
149163

150-
refreshLSInfo(webview);
151-
break;
152-
}
164+
context.subscriptions.push(vscode.commands.registerCommand('java.dashboard.open', async () => {
165+
if (!dashboardPanel) {
166+
webviewPanel = vscode.window.createWebviewPanel('java.dashboard', 'Dashboard', vscode.ViewColumn.Active, {
167+
enableScripts: true,
168+
enableCommandUris: true,
169+
retainContextWhenHidden: true,
170+
localResourceRoots: [context.extensionUri]
171+
});
172+
dashboardPanel = new DashboardPanel(webviewPanel.webview, context);
173+
174+
webviewPanel.onDidDispose(() => {
175+
dashboardPanel.dispose();
176+
dashboardPanel = undefined;
177+
webviewPanel = undefined;
178+
vscode.commands.executeCommand('setContext', 'java:dashboard', false);
179+
}, undefined, context.subscriptions);
180+
} else {
181+
webviewPanel.reveal();
153182
}
154-
}
155-
);
183+
}));
184+
console.log('registered dashboard webview provider');
185+
}
156186
}

0 commit comments

Comments
 (0)