Skip to content

Commit 805a1d3

Browse files
authored
Refactor the implementation and bug fixing (#1348)
- Extract the logic about error handling out of the classpath view. - Remove some redundent effects. - Fix dropdown css bugs. - Fix the bug that activeProjectIndex not currently used in handlers. - Fix the bug when handling the library paths.
1 parent 1acb978 commit 805a1d3

23 files changed

+444
-453
lines changed

src/extension.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,7 @@ import { initialize as initUtils } from "./utils";
2222
import { KEY_SHOW_WHEN_USING_JAVA } from "./utils/globalState";
2323
import { scheduleAction } from "./utils/scheduler";
2424
import { showWelcomeWebview, WelcomeViewSerializer } from "./welcome";
25-
import { activateCopilotInspection } from "./copilot/inspect";
2625
import { ProjectSettingsViewSerializer } from "./project-settings/projectSettingsView";
27-
import { isLlmApiReady } from "./copilot/utils";
2826

2927
let cleanJavaWorkspaceIndicator: string;
3028
let activatedTimestamp: number;

src/project-settings/assets/classpath/features/ClasspathConfigurationView.tsx

Lines changed: 23 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -7,90 +7,59 @@ import { Dispatch } from "@reduxjs/toolkit";
77
import Output from "./components/Output";
88
import Sources from "./components/Sources";
99
import Libraries from "./components/Libraries";
10-
import Exception from "./components/Exception";
11-
import { ClasspathViewException, ProjectInfo } from "../../../types";
12-
import { catchException, listVmInstalls, loadClasspath, updateActiveTab } from "./classpathConfigurationViewSlice";
10+
import { listVmInstalls, updateActiveTab } from "./classpathConfigurationViewSlice";
1311
import JdkRuntime from "./components/JdkRuntime";
14-
import { ClasspathRequest } from "../../vscode/utils";
15-
import { VSCodePanelTab, VSCodePanelView, VSCodePanels, VSCodeProgressRing } from "@vscode/webview-ui-toolkit/react";
12+
import { VSCodePanelTab, VSCodePanelView, VSCodePanels } from "@vscode/webview-ui-toolkit/react";
1613
import { ProjectType } from "../../../../utils/webview";
1714
import UnmanagedFolderSources from "./components/UnmanagedFolderSources";
1815
import Hint from "./components/Hint";
1916
import "../style.scss";
20-
import { setProjectType } from "../../mainpage/features/commonSlice";
2117

2218
const ClasspathConfigurationView = (): JSX.Element => {
2319
const activeTab: string = useSelector((state: any) => state.classpathConfig.ui.activeTab);
2420
const activeProjectIndex: number = useSelector((state: any) => state.commonConfig.ui.activeProjectIndex);
25-
const projects: ProjectInfo[] = useSelector((state: any) => state.commonConfig.data.projects);
2621
const projectType: ProjectType = useSelector((state: any) => state.commonConfig.data.projectType[activeProjectIndex]);
27-
const exception: ClasspathViewException | undefined = useSelector((state: any) => state.classpathConfig.exception);
2822
const dispatch: Dispatch<any> = useDispatch();
2923

3024
const onClickTab = (tabId: string) => {
3125
dispatch(updateActiveTab(tabId));
3226
};
3327

34-
let content: JSX.Element;
35-
if (exception) {
36-
content = <Exception />;
37-
} else if (projects.length === 0) {
38-
content = <VSCodeProgressRing></VSCodeProgressRing>;
39-
} else {
40-
content = (
41-
<div className="root">
42-
<VSCodePanels activeid={activeTab} className="setting-panels">
43-
<VSCodePanelTab id="source" onClick={() => onClickTab("source")}>Sources</VSCodePanelTab>
44-
<VSCodePanelTab id="jdk" onClick={() => onClickTab("jdk")}>JDK Runtime</VSCodePanelTab>
45-
<VSCodePanelTab id="libraries" onClick={() => onClickTab("libraries")}>Libraries</VSCodePanelTab>
46-
<VSCodePanelView className="setting-panels-view">
47-
{[ProjectType.Gradle, ProjectType.Maven].includes(projectType) && (<Sources />)}
48-
{projectType !== ProjectType.Gradle && projectType !== ProjectType.Maven && (<UnmanagedFolderSources />)}
49-
{projectType === ProjectType.UnmanagedFolder && (<Output />)}
50-
</VSCodePanelView>
51-
<VSCodePanelView className="setting-panels-view">
52-
<JdkRuntime />
53-
</VSCodePanelView>
54-
<VSCodePanelView className="setting-panels-view">
55-
<Libraries />
56-
</VSCodePanelView>
57-
</VSCodePanels>
58-
<Hint />
59-
</div>
60-
);
61-
}
62-
6328
const onMessage = (event: any) => {
6429
const { data } = event;
6530
if (data.command === "classpath.onDidListVmInstalls") {
6631
dispatch(listVmInstalls(data.vmInstalls))
67-
} else if (data.command === "classpath.onDidLoadProjectClasspath") {
68-
dispatch(setProjectType({
69-
projectType: data.projectType
70-
}));
71-
dispatch(loadClasspath({
72-
activeProjectIndex,
73-
...data
74-
}));
75-
} else if (data.command === "classpath.onException") {
76-
dispatch(catchException(data.exception));
7732
}
7833
};
7934

8035
useEffect(() => {
8136
window.addEventListener("message", onMessage);
82-
if (projects.length == 0) {
83-
// this makes sure the initialization only happens when the
84-
// redux store is empty. When switching between tabs, the
85-
// state will be preserved.
86-
ClasspathRequest.onWillListProjects();
87-
}
8837
return () => {
8938
window.removeEventListener("message", onMessage);
9039
}
9140
}, []);
9241

93-
return content;
42+
return (
43+
<div className="root">
44+
<VSCodePanels activeid={activeTab} className="setting-panels">
45+
<VSCodePanelTab id="source" onClick={() => onClickTab("source")}>Sources</VSCodePanelTab>
46+
<VSCodePanelTab id="jdk" onClick={() => onClickTab("jdk")}>JDK Runtime</VSCodePanelTab>
47+
<VSCodePanelTab id="libraries" onClick={() => onClickTab("libraries")}>Libraries</VSCodePanelTab>
48+
<VSCodePanelView className="setting-panels-view">
49+
{[ProjectType.Gradle, ProjectType.Maven].includes(projectType) && (<Sources />)}
50+
{projectType !== ProjectType.Gradle && projectType !== ProjectType.Maven && (<UnmanagedFolderSources />)}
51+
{projectType === ProjectType.UnmanagedFolder && (<Output />)}
52+
</VSCodePanelView>
53+
<VSCodePanelView className="setting-panels-view">
54+
<JdkRuntime />
55+
</VSCodePanelView>
56+
<VSCodePanelView className="setting-panels-view">
57+
<Libraries />
58+
</VSCodePanelView>
59+
</VSCodePanels>
60+
<Hint />
61+
</div>
62+
);
9463
};
9564

9665
export default ClasspathConfigurationView;

src/project-settings/assets/classpath/features/classpathConfigurationViewSlice.ts

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,6 @@ export const classpathConfigurationViewSlice = createSlice({
2525
output: [] as string[],
2626
libraries: [] as ClasspathEntry[][],
2727
},
28-
loadingState: false, // TODO: move to common?
29-
exception: undefined,
3028
},
3129
reducers: {
3230
updateActiveTab: (state, action) => {
@@ -107,12 +105,6 @@ export const classpathConfigurationViewSlice = createSlice({
107105
newLibs = _.uniq(newLibs);
108106
state.data.libraries[activeProjectIndex] = _.uniqBy(newLibs, "path");
109107
},
110-
catchException: (state, action) => {
111-
state.exception = action.payload;
112-
},
113-
updateLoadingState: (state, action) => {
114-
state.loadingState = action.payload;
115-
},
116108
},
117109
});
118110

@@ -130,8 +122,6 @@ export const {
130122
setJdks,
131123
removeReferencedLibrary,
132124
addLibraries,
133-
catchException,
134-
updateLoadingState,
135125
flushClasspathToEffective,
136126
} = classpathConfigurationViewSlice.actions;
137127

src/project-settings/assets/classpath/features/components/Exception.tsx

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

src/project-settings/assets/classpath/features/components/JdkRuntime.tsx

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

4-
import React, { Dispatch, useEffect, useState } from "react";
4+
import React, { Dispatch, useEffect, useRef, useState } from "react";
55
import { ClasspathRequest, CommonRequest } from "../../../vscode/utils";
66
import { VSCodeDivider, VSCodeDropdown, VSCodeOption, } from "@vscode/webview-ui-toolkit/react";
77
import { useDispatch, useSelector } from "react-redux";
@@ -11,6 +11,11 @@ import { setJdks } from "../classpathConfigurationViewSlice";
1111
const JdkRuntime = (): JSX.Element => {
1212

1313
const activeProjectIndex: number = useSelector((state: any) => state.commonConfig.ui.activeProjectIndex);
14+
const activeProjectIndexRef = useRef(activeProjectIndex);
15+
useEffect(() => {
16+
activeProjectIndexRef.current = activeProjectIndex;
17+
}, [activeProjectIndex]);
18+
1419
const vmInstalls: VmInstall[] = useSelector((state: any) => state.classpathConfig.data.vmInstalls);
1520
const activeVmInstallPath: string = useSelector((state: any) => state.classpathConfig.data.activeVmInstallPath[activeProjectIndex]);
1621

@@ -35,12 +40,26 @@ const JdkRuntime = (): JSX.Element => {
3540
const {data} = event;
3641
if (data.command === "classpath.onDidChangeJdk") {
3742
dispatch(setJdks({
38-
activeProjectIndex,
43+
activeProjectIndex: activeProjectIndexRef.current,
3944
...data
4045
}));
4146
}
4247
}
4348

49+
useEffect(() => {
50+
window.addEventListener("message", onDidChangeJdk);
51+
// the dropdown list has a fixed height by default, which makes the list jitter
52+
// when the jdk path changes. We set the max-height to initial to fix this issue.
53+
// Note that the list box is rendered inside a shadow dom so this is the only way
54+
// to change its style.
55+
document.querySelector("#jdk-dropdown")?.shadowRoot
56+
?.querySelector(".listbox")?.setAttribute("style", "max-height: initial;");
57+
if (vmInstalls.length === 0) {
58+
ClasspathRequest.onWillListVmInstalls();
59+
}
60+
return () => window.removeEventListener("message", onDidChangeJdk);
61+
}, []);
62+
4463
const jdkSelections = vmInstalls.map((vmInstall) => {
4564
return (
4665
<VSCodeOption
@@ -89,20 +108,6 @@ const JdkRuntime = (): JSX.Element => {
89108
</VSCodeOption>
90109
);
91110

92-
useEffect(() => {
93-
window.addEventListener("message", onDidChangeJdk);
94-
// the dropdown list has a fixed height by default, which makes the list jitter
95-
// when the jdk path changes. We set the max-height to initial to fix this issue.
96-
// Note that the list box is rendered inside a shadow dom so this is the only way
97-
// to change its style.
98-
document.querySelector("#jdk-dropdown")?.shadowRoot
99-
?.querySelector(".listbox")?.setAttribute("style", "max-height: initial;");
100-
if (vmInstalls.length === 0) {
101-
ClasspathRequest.onWillListVmInstalls();
102-
}
103-
return () => window.removeEventListener("message", onDidChangeJdk);
104-
}, []);
105-
106111
return (
107112
<div className="setting-section">
108113
<div className="flex-center mt-2">

src/project-settings/assets/classpath/features/components/Libraries.tsx

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// Licensed under the MIT license.
33

44
import { Dispatch } from "@reduxjs/toolkit";
5-
import React, { useEffect, useState } from "react";
5+
import React, { useEffect, useRef, useState } from "react";
66
import { useSelector, useDispatch } from "react-redux";
77
import { removeReferencedLibrary, addLibraries } from "../classpathConfigurationViewSlice";
88
import { ClasspathRequest } from "../../../vscode/utils";
@@ -13,6 +13,11 @@ const Libraries = (): JSX.Element => {
1313

1414
const [hoveredRow, setHoveredRow] = useState<string | null>(null);
1515
const activeProjectIndex: number = useSelector((state: any) => state.commonConfig.ui.activeProjectIndex);
16+
const activeProjectIndexRef = useRef(activeProjectIndex);
17+
useEffect(() => {
18+
activeProjectIndexRef.current = activeProjectIndex;
19+
}, [activeProjectIndex]);
20+
1621
const libraries: ClasspathEntry[] = useSelector((state: any) => state.classpathConfig.data.libraries[activeProjectIndex]);
1722
const dispatch: Dispatch<any> = useDispatch();
1823

@@ -31,12 +36,19 @@ const Libraries = (): JSX.Element => {
3136
const {data} = event;
3237
if (data.command === "classpath.onDidAddLibraries") {
3338
dispatch(addLibraries({
34-
activeProjectIndex,
39+
activeProjectIndex: activeProjectIndexRef.current,
3540
libraries:data.jars
36-
}));
41+
}));
3742
}
3843
};
3944

45+
useEffect(() => {
46+
window.addEventListener("message", onDidAddLibraries);
47+
return () => {
48+
window.removeEventListener("message", onDidAddLibraries);
49+
}
50+
}, []);
51+
4052
const resolveLibPath = (entry: ClasspathEntry): string => {
4153
if (entry.kind === ClasspathEntryKind.Project) {
4254
return resolveProjectPath(entry);
@@ -68,13 +80,6 @@ const Libraries = (): JSX.Element => {
6880
return pathComponents[pathComponents.length - 1];
6981
}
7082

71-
useEffect(() => {
72-
window.addEventListener("message", onDidAddLibraries);
73-
return () => {
74-
window.removeEventListener("message", onDidAddLibraries);
75-
}
76-
}, []);
77-
7883
let librariesSections: JSX.Element | JSX.Element[];
7984
if (libraries.length === 0) {
8085
librariesSections = (

0 commit comments

Comments
 (0)