Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
290 changes: 192 additions & 98 deletions package-lock.json

Large diffs are not rendered by default.

22 changes: 17 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,9 @@
"onCommand:java.extGuide",
"onWebviewPanel:java.extGuide",
"onCommand:java.welcome",
"onWebviewPanel:java.welcome"
"onWebviewPanel:java.welcome",
"onCommand:java.classpathConfiguration",
"onWebviewPanel:java.classpathConfiguration"
],
"contributes": {
"commands": [
Expand All @@ -54,6 +56,11 @@
"category": "Java",
"title": "Welcome"
},
{
"command": "java.classpathConfiguration",
"category": "Java",
"title": "Configure Classpath"
},
{
"command": "java.overview",
"title": "Java: Overview"
Expand Down Expand Up @@ -126,15 +133,18 @@
"build": "webpack --config webpack.config.js --mode=\"production\""
},
"devDependencies": {
"@iconify-icons/codicon": "^1.1.3",
"@iconify-icons/codicon": "^1.1.8",
"@iconify/react": "^1.1.3",
"@reduxjs/toolkit": "^1.5.0",
"@types/bytes": "^3.1.0",
"@types/expand-tilde": "^2.0.0",
"@types/lodash": "^4.14.161",
"@types/minimatch": "^3.0.3",
"@types/node": "^8.10.63",
"@types/path-exists": "^3.0.0",
"@types/react": "^17.0.0",
"@types/react-dom": "^16.9.8",
"@types/react-redux": "^7.1.16",
"@types/request": "^2.48.5",
"@types/request-promise-native": "^1.0.17",
"@types/semver": "^5.5.0",
Expand All @@ -152,22 +162,24 @@
"html-webpack-plugin": "^3.2.0",
"jquery": "^3.5.1",
"lodash": "^4.17.20",
"minimatch": "^3.0.4",
"node-sass": "^4.14.1",
"path-exists": "^3.0.0",
"popper.js": "^1.16.1",
"postcss-loader": "^2.1.5",
"react": "^16.13.1",
"react": "^17.0.1",
"react-bootstrap": "^1.4.3",
"react-dom": "^16.13.1",
"react-dom": "^17.0.1",
"react-redux": "^7.2.2",
"request": "^2.88.2",
"request-promise-native": "^1.0.9",
"sass-loader": "^7.3.1",
"style-loader": "^0.21.0",
"ts-loader": "^4.3.0",
"tslint": "^5.20.1",
"typescript": "^3.7.5",
"vscode-tas-client": "^0.1.17",
"url-loader": "^4.1.1",
"vscode-tas-client": "^0.1.17",
"webpack": "^4.44.1",
"webpack-cli": "^3.3.12"
},
Expand Down
14 changes: 14 additions & 0 deletions src/classpath/assets/App.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.

import React from "react";
import ClasspathConfigurationView from "./features/classpathConfiguration/ClasspathConfigurationView";

export class App extends React.Component {

render() {
return (
<ClasspathConfigurationView />
);
}
}
11 changes: 11 additions & 0 deletions src/classpath/assets/app/store.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.

import { configureStore } from "@reduxjs/toolkit";
import classpathConfigurationViewReducer from "../features/classpathConfiguration/classpathConfigurationViewSlice";

export default configureStore({
reducer: {
classpathConfig: classpathConfigurationViewReducer
},
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.

import React, { useEffect } from "react";
import { Col, Container, Row, Spinner } from "react-bootstrap";
import { useSelector, useDispatch } from "react-redux";
import { Dispatch } from "@reduxjs/toolkit";
import Output from "./components/Output";
import ProjectSelector from "./components/ProjectSelector";
import Sources from "./components/Sources";
import ReferencedLibraries from "./components/ReferencedLibraries";
import Header from "./components/Header";
import Exception from "./components/Exception";
import { ClasspathViewException, ProjectInfo } from "../../../types";
import { catchException, listProjects, loadClasspath } from "./classpathConfigurationViewSlice";
import JdkRuntime from "./components/JdkRuntime";

const ClasspathConfigurationView = (): JSX.Element => {
const projects: ProjectInfo[] = useSelector((state: any) => state.classpathConfig.projects);
const exception: ClasspathViewException | undefined = useSelector((state: any) => state.classpathConfig.exception);
let content: JSX.Element;

if (exception) {
content = <Exception />;
} else if (projects.length === 0) {
content = <Spinner animation="border" role="status" size="sm"><span className="sr-only">Loading...</span></Spinner>;
} else {
content = (
<div>
<ProjectSelector />
<Row className="setting-section">
<Col>
<Sources />
</Col>
</Row>
<Row className="setting-section">
<Col>
<Output />
</Col>
</Row>
<Row className="setting-section">
<Col>
<JdkRuntime />
</Col>
</Row>
<Row className="setting-section">
<Col>
<ReferencedLibraries />
</Col>
</Row>
</div>
);
}

const dispatch: Dispatch<any> = useDispatch();

const onInitialize = (event: OnInitializeEvent) => {
const {data} = event;
if (data.command === "onDidListProjects") {
dispatch(listProjects(data.projectInfo));
} else if (data.command === "onDidLoadProjectClasspath") {
dispatch(loadClasspath(data));
} else if (data.command === "onException") {
dispatch(catchException(data.exception));
}
};

useEffect(() => {
window.addEventListener("message", onInitialize);
return () => window.removeEventListener("message", onInitialize);
}, []);

return (
<Container className="root">
<Row className="setting-header">
<Col>
<Header />
</Col>
</Row>
{content}
</Container>
);
};

interface OnInitializeEvent {
data: {
command: string;
projectInfo?: {
name: string;
rootPath: string;
projectType: string;
}[];
sources?: string[];
output?: string;
referencedLibraries?: string[];
exception?: ClasspathViewException;
};
}

export default ClasspathConfigurationView;
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.

import { createSlice } from "@reduxjs/toolkit";
import _ from "lodash";

export const classpathConfigurationViewSlice = createSlice({
name: "classpathConfig",
initialState: {
activeProjectIndex: 0,
projects: [],
projectType: undefined,
sources: [] as string[],
output: "",
referencedLibraries: [] as string[],
exception: undefined,
},
reducers: {
listProjects: (state, action) => {
state.projects = action.payload;
state.activeProjectIndex = 0;
},
activeProjectChange: (state, action) => {
state.activeProjectIndex = action.payload;
},
loadClasspath: (state, action) => {
state.projectType = action.payload.projectType;
state.output = action.payload.output;
// Only update the array when they have different elements.
if (isDifferentStringArray(state.sources, action.payload.sources)) {
state.sources = action.payload.sources;
}
if (isDifferentStringArray(state.referencedLibraries, action.payload.referencedLibraries)) {
state.referencedLibraries = action.payload.referencedLibraries;
}
},
updateSource: (state, action) => {
state.sources = action.payload;
},
setOutputPath: (state, action) => {
state.output = action.payload;
},
removeReferencedLibrary: (state, action) => {
const removedIndex: number = action.payload as number;
if (removedIndex > -1 && removedIndex < state.referencedLibraries.length) {
state.referencedLibraries.splice(removedIndex, 1);
}
},
addReferencedLibraries: (state, action) => {
state.referencedLibraries.push(...action.payload);
state.referencedLibraries = _.uniq(state.referencedLibraries);
},
catchException: (state, action) => {
state.exception = action.payload;
}
},
});

function isDifferentStringArray(a1: string[], a2: string[]): boolean {
return !_.isEmpty(_.xor(a1, a2));
}

export const {
listProjects,
activeProjectChange,
loadClasspath,
updateSource,
setOutputPath,
removeReferencedLibrary,
addReferencedLibraries,
catchException,
} = classpathConfigurationViewSlice.actions;

export default classpathConfigurationViewSlice.reducer;
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.

import React from "react";
import { useSelector } from "react-redux";
import { encodeCommandUriWithTelemetry, supportedByNavigator } from "../../../../../utils/webview";
import { ClasspathViewException } from "../../../../types";
import { WEBVIEW_ID } from "../../../utils";

const Exception = (): JSX.Element | null => {
const exception: ClasspathViewException | undefined = useSelector((state: any) => state.classpathConfig.exception);

let content: JSX.Element;
switch (exception) {
case ClasspathViewException.NoJavaProjects:
let command: string = "workbench.action.files.openFolder";
if (supportedByNavigator("mac")) {
command = "workbench.action.files.openFileFolder";
}
content = (
<div>
<span>There is no Java projects opened in the current workspace. Please <a href={encodeCommandUriWithTelemetry(WEBVIEW_ID, "classpath.openProject", command)}>open a Java project</a>.</span>
</div>
);
break;
case ClasspathViewException.JavaExtensionNotInstalled:
content = (
<div>
<span>The required extension <a href={encodeCommandUriWithTelemetry(WEBVIEW_ID, "classpath.openJavaLanguageSupportMarketPlace", "extension.open", ["redhat.java"])}>Language Support for Java(TM) by Red Hat</a> is not installed or the version is too old. Please <a href={encodeCommandUriWithTelemetry(WEBVIEW_ID, "classpath.installJavaLanguageSupport", "workbench.extensions.installExtension", ["redhat.java"])}>install</a> it in Visual Studio Code and refresh the page after the installation.</span>
</div>
);
break;
default:
return null;
}

return content;
};

export default Exception;
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.

import React from "react";

const Header = (): JSX.Element => {
return (
<h2 className="mb-0">Configure Classpath</h2>
);
};

export default Header;
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.

import React from "react";
import { encodeCommandUriWithTelemetry } from "../../../../../utils/webview";
import { WEBVIEW_ID } from "../../../utils";

const JdkRuntime = (): JSX.Element => {
return (
<div>
<h4 className="setting-section-header mb-1">JDK Runtime</h4>
<span className="setting-section-description">Map Java execution environment to local JDKs. Edit in <a href={encodeCommandUriWithTelemetry(WEBVIEW_ID, "classpath.runtime", "java.runtime")}>Configure Java Runtime</a>.</span>
</div>
);
};

export default JdkRuntime;
Loading