Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add format section into the project setting page. #1324

Merged
merged 2 commits into from
May 20, 2024
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
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import React, { useEffect } from "react";
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 Libraries from "./components/Libraries";
import Exception from "./components/Exception";
Expand All @@ -16,7 +15,7 @@ import { ClasspathRequest } from "../../vscode/utils";
import { VSCodePanelTab, VSCodePanelView, VSCodePanels, VSCodeProgressRing } from "@vscode/webview-ui-toolkit/react";
import { ProjectType } from "../../../../utils/webview";
import UnmanagedFolderSources from "./components/UnmanagedFolderSources";
import Footer from "./components/Footer";
import Hint from "./components/Hint";
import "../style.scss";
import { listProjects, setProjectType } from "../../mainpage/features/commonSlice";

Expand All @@ -39,35 +38,32 @@ const ClasspathConfigurationView = (): JSX.Element => {
content = <VSCodeProgressRing></VSCodeProgressRing>;
} else {
content = (
<div>
<div className="mb-12">
<ProjectSelector />
<VSCodePanels activeid={activeTab} className="setting-panels">
<VSCodePanelTab id="source" onClick={() => onClickTab("source")}>Sources</VSCodePanelTab>
<VSCodePanelTab id="jdk" onClick={() => onClickTab("jdk")}>JDK Runtime</VSCodePanelTab>
<VSCodePanelTab id="libraries" onClick={() => onClickTab("libraries")}>Libraries</VSCodePanelTab>
<VSCodePanelView className="setting-panels-view">
{[ProjectType.Gradle, ProjectType.Maven].includes(projectType) && (<Sources />)}
{projectType !== ProjectType.Gradle && projectType !== ProjectType.Maven && (<UnmanagedFolderSources />)}
{projectType === ProjectType.UnmanagedFolder && (<Output />)}
</VSCodePanelView>
<VSCodePanelView className="setting-panels-view">
<JdkRuntime />
</VSCodePanelView>
<VSCodePanelView className="setting-panels-view">
<Libraries />
</VSCodePanelView>
</VSCodePanels>
</div>
<Footer />
<div className="root">
<VSCodePanels activeid={activeTab} className="setting-panels">
<VSCodePanelTab id="source" onClick={() => onClickTab("source")}>Sources</VSCodePanelTab>
<VSCodePanelTab id="jdk" onClick={() => onClickTab("jdk")}>JDK Runtime</VSCodePanelTab>
<VSCodePanelTab id="libraries" onClick={() => onClickTab("libraries")}>Libraries</VSCodePanelTab>
<VSCodePanelView className="setting-panels-view">
{[ProjectType.Gradle, ProjectType.Maven].includes(projectType) && (<Sources />)}
{projectType !== ProjectType.Gradle && projectType !== ProjectType.Maven && (<UnmanagedFolderSources />)}
{projectType === ProjectType.UnmanagedFolder && (<Output />)}
</VSCodePanelView>
<VSCodePanelView className="setting-panels-view">
<JdkRuntime />
</VSCodePanelView>
<VSCodePanelView className="setting-panels-view">
<Libraries />
</VSCodePanelView>
</VSCodePanels>
<Hint />
</div>
);
}

const onMessage = (event: any) => {
const {data} = event;
const { data } = event;
if (data.command === "classpath.onDidListProjects") {
dispatch(initializeProjectsData({projectsNum: data.projectInfo?.length}));
dispatch(initializeProjectsData({ projectsNum: data.projectInfo?.length }));
dispatch(listProjects(data.projectInfo));
} else if (data.command === "classpath.onDidListVmInstalls") {
dispatch(listVmInstalls(data.vmInstalls))
Expand Down Expand Up @@ -98,11 +94,7 @@ const ClasspathConfigurationView = (): JSX.Element => {
}
}, []);

return (
<div className="root">
{content}
</div>
);
return content;
};

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

import { VSCodeLink} from "@vscode/webview-ui-toolkit/react";
import React, { useEffect } from "react";
import { ProjectInfo } from "../../../../handlers/classpath/types";
import { useSelector } from "react-redux";
import { ProjectType } from "../../../../../utils/webview";
import { updateMaxHeight } from "../../utils";
import { ClasspathRequest } from "../../../vscode/utils";

const Hint = (): JSX.Element => {

const activeProjectIndex: number = useSelector((state: any) => state.commonConfig.ui.activeProjectIndex);
const projects: ProjectInfo[] = useSelector((state: any) => state.commonConfig.data.projects);
const projectType: ProjectType[] = useSelector((state: any) => state.commonConfig.data.projectType);

let buildFile: string = "";
if (projectType[activeProjectIndex] === ProjectType.Maven) {
buildFile = "pom.xml";
} else if (projectType[activeProjectIndex] === ProjectType.Gradle) {
buildFile = "build.gradle";
}

const handleOpenBuildFile = () => {
ClasspathRequest.onClickGotoProjectConfiguration(projects[activeProjectIndex].rootPath, projectType[activeProjectIndex]);
};

useEffect(() => {
updateMaxHeight();
window.addEventListener('resize', updateMaxHeight);
return () => {
window.removeEventListener("resize", updateMaxHeight);
}
}, [projectType]);

return (
<div id="hint" className="setting-footer pb-2">
{(projectType[activeProjectIndex] === ProjectType.Gradle || projectType[activeProjectIndex] === ProjectType.Maven) &&
<div className="mt-1">
<span className="setting-section-warning">
'{projects[activeProjectIndex].name}' is imported by {projectType[activeProjectIndex]}, changes made to the classpath might be lost after reloading.
To make permanent changes, please edit the <VSCodeLink href="" onClick={() => handleOpenBuildFile()}>{buildFile}</VSCodeLink> file.
</span>
</div>
}
</div>
);
};

export default Hint;
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Licensed under the MIT license.

import React, { Dispatch, useEffect, useState } from "react";
import { ClasspathRequest } from "../../../vscode/utils";
import { ClasspathRequest, CommonRequest } from "../../../vscode/utils";
import { VSCodeDivider, VSCodeDropdown, VSCodeOption, } from "@vscode/webview-ui-toolkit/react";
import { useDispatch, useSelector } from "react-redux";
import { VmInstall } from "../../../../handlers/classpath/types";
Expand All @@ -22,7 +22,7 @@ const JdkRuntime = (): JSX.Element => {
if (path === "add-new-jdk") {
ClasspathRequest.onWillAddNewJdk();
} else if (path === "download-jdk") {
ClasspathRequest.onWillExecuteCommand("java.installJdk")
CommonRequest.onWillExecuteCommand("java.installJdk")
} else {
dispatch(setJdks({
activeProjectIndex,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ const UnmanagedFolderSources = (): JSX.Element => {
<VSCodeDataGridRow className={`${projectType !== ProjectType.UnmanagedFolder ? "inactive" : ""} setting-section-grid-row`} id={`sources-${index}`} onMouseEnter={() => setHoveredRow(`sources-${index}`)} onMouseLeave={() => setHoveredRow(null)} key={source.path}>
<VSCodeDataGridCell className="setting-section-grid-cell setting-section-grid-cell-readonly" gridColumn="1">
<div className="setting-section-grid-cell">
<span className={"codicon codicon-folder mr-1"}></span>
<span className="codicon codicon-folder mr-1"></span>
<span>{source.path}</span>
</div>
{hoveredRow === `sources-${index}` && projectType === ProjectType.UnmanagedFolder && (
Expand Down
13 changes: 4 additions & 9 deletions src/project-settings/assets/classpath/style.scss
Original file line number Diff line number Diff line change
@@ -1,18 +1,13 @@
.root {
min-width: 560px;
margin: 8px 18px 0;
display: flex;
flex-direction: column;
justify-content: space-between;
flex: 1;
}

.setting-header {
color: var(--vscode-settings-headerForeground);
}

.setting-footer {
position: fixed;
bottom: 0;
width: 80%;
background: var(--background);
}

.setting-section {
width: 100%;
Expand Down
4 changes: 4 additions & 0 deletions src/project-settings/assets/classpath/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ export const updateMaxHeight = () => {
if (projectSelector) {
maxHeight -= projectSelector.getBoundingClientRect().height;
}
const hinter = document.getElementById("hint");
if (hinter) {
maxHeight -= hinter.getBoundingClientRect().height;
}
const footer = document.getElementById("footer");
if (footer) {
maxHeight -= footer.getBoundingClientRect().height;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ import ClasspathConfigurationView from "../../classpath/features/ClasspathConfig
import { updateActiveTab } from "../../classpath/features/classpathConfigurationViewSlice";
import "../style.scss";
import { updateActiveSection } from "./commonSlice";
import ProjectSelector from "./component/ProjectSelector";
import { VSCodeDivider } from "@vscode/webview-ui-toolkit/react";
import Footer from "./component/Footer";
import SideBar from "./component/SideBar";

const ProjectSettingView = (): JSX.Element => {
const activeSection: string = useSelector((state: any) => state.commonConfig.ui.activeSection);
Expand Down Expand Up @@ -35,7 +39,7 @@ const ProjectSettingView = (): JSX.Element => {
if (routes.length > 1) {
switch (routes[0]) {
case "classpath":
// TODO: sometimes when directly trigger 'COnfigure Java Runtime', the tab won't
// TODO: sometimes when directly trigger 'Configure Java Runtime', the tab won't
// focus to the JDK part, need to investigate
dispatch(updateActiveTab(routes[1]));
break;
Expand All @@ -46,26 +50,20 @@ const ProjectSettingView = (): JSX.Element => {
}
}

const onClickNavBarItem = (panelId: string) => {
dispatch(updateActiveSection(panelId));
};

return (
<div className="app-container">
<div className="app-sidebar">
<div className="app-sidebar-content">
<div className="mt-2">
<div className={`section-link ${activeSection === "classpath" ? "section-link-active" : ""}`} onClick={() => onClickNavBarItem("classpath")}>
Classpath
</div>
</div>
</div>
<div className="app-sidebar-resizer" />
</div>
<div className="root">
<ProjectSelector />
<VSCodeDivider />
<div className="app-container">
<SideBar />
<div className="app-frame">
{getSectionContent()}
</div>
</div>
<VSCodeDivider />
<Footer />
</div>

);
};

Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,17 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.

import { VSCodeButton, VSCodeDivider, VSCodeLink} from "@vscode/webview-ui-toolkit/react";
import { VSCodeButton } from "@vscode/webview-ui-toolkit/react";
import { Dispatch } from "@reduxjs/toolkit";
import React, { useEffect } from "react";
import { ClasspathEntry, ProjectInfo } from "../../../../handlers/classpath/types";
import { useDispatch, useSelector } from "react-redux";
import { ProjectType } from "../../../../../utils/webview";
import { updateMaxHeight } from "../../utils";
import { updateLoadingState } from "../classpathConfigurationViewSlice";
import { updateLoadingState } from "../../../classpath/features/classpathConfigurationViewSlice";
import { ClasspathRequest } from "../../../vscode/utils";

const Footer = (): JSX.Element => {

const activeProjectIndex: number = useSelector((state: any) => state.commonConfig.ui.activeProjectIndex);
const projects: ProjectInfo[] = useSelector((state: any) => state.commonConfig.data.projects);
const sources: ClasspathEntry[][] = useSelector((state: any) => state.classpathConfig.data.sources);
const defaultOutput: string[] = useSelector((state: any) => state.classpathConfig.data.output);
Expand All @@ -24,17 +22,6 @@ const Footer = (): JSX.Element => {

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

let buildFile: string = "";
if (projectType[activeProjectIndex] === ProjectType.Maven) {
buildFile = "pom.xml";
} else if (projectType[activeProjectIndex] === ProjectType.Gradle) {
buildFile = "build.gradle";
}

const handleOpenBuildFile = () => {
ClasspathRequest.onClickGotoProjectConfiguration(projects[activeProjectIndex].rootPath, projectType[activeProjectIndex]);
};

const handleApply = () => {
ClasspathRequest.onWillUpdateClassPaths(
projects.map(p => p.rootPath),
Expand All @@ -60,25 +47,8 @@ const Footer = (): JSX.Element => {
}
}, []);

useEffect(() => {
updateMaxHeight();
window.addEventListener('resize', updateMaxHeight);
return () => {
window.removeEventListener("resize", updateMaxHeight);
}
}, [projectType]);

return (
<div id="footer" className="setting-footer pb-2">
<VSCodeDivider/>
{(projectType[activeProjectIndex] === ProjectType.Gradle || projectType[activeProjectIndex] === ProjectType.Maven) &&
<div className="mb-2 mt-1">
<span className="setting-section-warning">
'{projects[activeProjectIndex].name}' is imported by {projectType[activeProjectIndex]}, changes made to the classpath might be lost after reloading.
To make permanent changes, please edit the <VSCodeLink href="" onClick={() => handleOpenBuildFile()}>{buildFile}</VSCodeLink> file.
</span>
</div>
}
<div id="footer" className="pt-1 pb-2">
{loadingState && <VSCodeButton className="ml-1" disabled>Applying...</VSCodeButton>}
{!loadingState && <VSCodeButton className="ml-1" appearance="primary" onClick={() => handleApply()}>Apply Settings</VSCodeButton>}
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,18 @@ const ProjectSelector = (): JSX.Element | null => {
}

useEffect(() => {
if (projects.length === 0) {
return;
}

loadProjectClasspath(projects[activeProjectIndex].rootPath);
}, [activeProjectIndex, projects]);

const projectSelections = projects.map((project, index) => {
if (projects.length === 0) {
return null;
}

return (
<VSCodeOption className="setting-section-option" key={project.rootPath} onClick={() => handleActiveProjectChange(index)}>
{project.name}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.

import React from "react";
import { useSelector, useDispatch } from "react-redux";
import { Dispatch } from "@reduxjs/toolkit";
import { updateActiveSection } from "../commonSlice";
import { CommonRequest } from "../../../vscode/utils";

const CLASSPATH = "classpath";
const FORMATTER = "formatter";

const SideBar = (): JSX.Element => {

const activeSection: string = useSelector((state: any) => state.commonConfig.ui.activeSection);
const dispatch: Dispatch<any> = useDispatch();

const onClickNavBarItem = (panelId: string) => {
if (panelId === FORMATTER) {
CommonRequest.onWillExecuteCommand("java.formatterSettings");
return;
}
dispatch(updateActiveSection(panelId));
};

return (
<div className="app-sidebar">
<div className="app-sidebar-content">
<div className="mt-2">
<div className={`section-link ${activeSection === CLASSPATH ? "section-link-active" : ""} mb-1`} onClick={() => onClickNavBarItem(CLASSPATH)}>
Classpath
</div>
<div className="section-link mb-1" onClick={() => onClickNavBarItem(FORMATTER)}>
Formatter <span className="codicon codicon-link-external"></span>
</div>
</div>
</div>
<div className="app-sidebar-resizer" />
</div>
);
};

export default SideBar;
Loading