mirror of
https://github.com/wavetermdev/waveterm.git
synced 2025-02-22 02:41:23 +01:00
Add overlay scrollbar for main sidebar, adjust active session display behavior (#505)
* Add overlay scrollbar to left sidebar * Keep active session bolded when mainview is not session * fix color of scrollbar * swap expression args * add active color for scrollbar * add active/highlight to history, connections, and settings
This commit is contained in:
parent
3e4ba1bf72
commit
e867bcb398
@ -36,6 +36,8 @@
|
||||
"monaco-editor": "^0.44.0",
|
||||
"mustache": "^4.2.0",
|
||||
"node-fetch": "^3.2.10",
|
||||
"overlayscrollbars": "^2.6.1",
|
||||
"overlayscrollbars-react": "^0.5.5",
|
||||
"papaparse": "^5.4.1",
|
||||
"react": "^18.1.0",
|
||||
"react-dom": "^18.1.0",
|
||||
|
@ -67,6 +67,7 @@
|
||||
--scrollbar-background-color: var(--app-bg-color);
|
||||
--scrollbar-thumb-color: rgba(255, 255, 255, 0.3);
|
||||
--scrollbar-thumb-hover-color: rgba(255, 255, 255, 0.5);
|
||||
--scrollbar-thumb-active-color: rgba(255, 255, 255, 0.6);
|
||||
|
||||
/* code color */
|
||||
--pre-bg-color: rgb(0, 0, 0);
|
||||
@ -112,7 +113,7 @@
|
||||
--hotkey-text-color: var(--app-text-secondary-color);
|
||||
|
||||
/* sidebar colors */
|
||||
--sidebar-highlight-color: rgba(241, 246, 243, 0.08);
|
||||
--sidebar-highlight-color: var(--app-accent-bg-color);
|
||||
--sidebar-font-size: 15px;
|
||||
--sidebar-line-height: 1.5;
|
||||
--sidebar-font-weight: normal;
|
||||
@ -186,4 +187,11 @@
|
||||
--datepicker-header-fade-color: rgba(255, 255, 255, 0.4);
|
||||
--datepicker-year-header-bg-color: rgba(255, 255, 255, 0.2); /* Light grey background */
|
||||
--datepicker-year-header-border-color: rgba(241, 246, 243, 0.15); /* Light grey border */
|
||||
|
||||
/* OverlayScrollbars styling */
|
||||
.os-scrollbar {
|
||||
--os-handle-bg: var(--scrollbar-thumb-color);
|
||||
--os-handle-bg-hover: var(--scrollbar-thumb-hover-color);
|
||||
--os-handle-bg-active: var(--scrollbar-thumb-active-color);
|
||||
}
|
||||
}
|
||||
|
@ -61,6 +61,7 @@
|
||||
--scrollbar-background-color: var(--app-bg-color);
|
||||
--scrollbar-thumb-color: rgba(0, 0, 0, 0.2);
|
||||
--scrollbar-thumb-hover-color: rgba(0, 0, 0, 0.4);
|
||||
--scrollbar-thumb-active-color: rgba(0, 0, 0, 0.5);
|
||||
|
||||
/* line color */
|
||||
--line-actions-bg-color: rgba(0, 0, 0, 0.1);
|
||||
|
@ -101,7 +101,7 @@ class App extends React.Component<{}, {}> {
|
||||
return (
|
||||
<div id="main" className={"platform-" + platform} onContextMenu={this.handleContextMenu}>
|
||||
<div ref={this.mainContentRef} className="main-content">
|
||||
<MainSideBar parentRef={this.mainContentRef} clientData={clientData} />
|
||||
<MainSideBar parentRef={this.mainContentRef} />
|
||||
<div className="session-view" />
|
||||
</div>
|
||||
<If condition={dcWait}>
|
||||
@ -151,7 +151,7 @@ class App extends React.Component<{}, {}> {
|
||||
</div>
|
||||
</If>
|
||||
<div ref={this.mainContentRef} className="main-content">
|
||||
<MainSideBar parentRef={this.mainContentRef} clientData={clientData} />
|
||||
<MainSideBar parentRef={this.mainContentRef} />
|
||||
<ErrorBoundary>
|
||||
<PluginsView />
|
||||
<WorkspaceView />
|
||||
@ -160,7 +160,7 @@ class App extends React.Component<{}, {}> {
|
||||
<ConnectionsView model={remotesModel} />
|
||||
<ClientSettingsView model={remotesModel} />
|
||||
</ErrorBoundary>
|
||||
<RightSideBar parentRef={this.mainContentRef} clientData={clientData} />
|
||||
<RightSideBar parentRef={this.mainContentRef} />
|
||||
</div>
|
||||
<ModalsProvider />
|
||||
</div>
|
||||
|
@ -60,15 +60,15 @@
|
||||
margin-bottom: -4px;
|
||||
}
|
||||
|
||||
.top {
|
||||
padding-right: 6px;
|
||||
}
|
||||
|
||||
.middle {
|
||||
padding: 4px 6px 8px 6px;
|
||||
border-bottom: 1px solid var(--app-border-color);
|
||||
overflow-y: auto;
|
||||
.item {
|
||||
&.active {
|
||||
background-color: var(--sidebar-highlight-color);
|
||||
font-weight: var(--sidebar-highlight-font-weight);
|
||||
}
|
||||
.index {
|
||||
font-size: 10px;
|
||||
}
|
||||
@ -87,6 +87,7 @@
|
||||
left: 0;
|
||||
width: 100%;
|
||||
padding-top: 0.8rem;
|
||||
padding-right: 6px;
|
||||
}
|
||||
|
||||
.item {
|
||||
@ -94,9 +95,6 @@
|
||||
margin-left: 6px;
|
||||
border-radius: 4px;
|
||||
opacity: 1;
|
||||
width: inherit;
|
||||
max-width: inherit;
|
||||
min-width: inherit;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
@ -111,6 +109,13 @@
|
||||
line-height: normal;
|
||||
}
|
||||
|
||||
&.active {
|
||||
font-weight: var(--sidebar-highlight-font-weight);
|
||||
}
|
||||
&.highlight {
|
||||
background-color: var(--sidebar-highlight-color);
|
||||
}
|
||||
|
||||
.item-contents {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
@ -8,7 +8,6 @@ import { boundMethod } from "autobind-decorator";
|
||||
import cn from "classnames";
|
||||
import dayjs from "dayjs";
|
||||
import { If } from "tsx-control-statements/components";
|
||||
import { compareLoose } from "semver";
|
||||
|
||||
import { ReactComponent as AppsIcon } from "@/assets/icons/apps.svg";
|
||||
import { ReactComponent as WorkspacesIcon } from "@/assets/icons/workspaces.svg";
|
||||
@ -24,6 +23,9 @@ import * as appconst from "@/app/appconst";
|
||||
import "./main.less";
|
||||
import { ActionsIcon, CenteredIcon, FrontIcon, StatusIndicator } from "@/common/icons/icons";
|
||||
|
||||
import "overlayscrollbars/overlayscrollbars.css";
|
||||
import { OverlayScrollbarsComponent } from "overlayscrollbars-react";
|
||||
|
||||
dayjs.extend(localizedFormat);
|
||||
|
||||
class SideBarItem extends React.Component<{
|
||||
@ -59,7 +61,6 @@ class HotKeyIcon extends React.Component<{ hotkey: string }> {
|
||||
|
||||
interface MainSideBarProps {
|
||||
parentRef: React.RefObject<HTMLElement>;
|
||||
clientData: ClientDataType;
|
||||
}
|
||||
|
||||
@mobxReact.observer
|
||||
@ -192,14 +193,15 @@ class MainSideBar extends React.Component<MainSideBarProps, {}> {
|
||||
}
|
||||
}
|
||||
return sessionList.map((session, index) => {
|
||||
const isActive = GlobalModel.activeMainView.get() == "session" && activeSessionId == session.sessionId;
|
||||
const isActive = activeSessionId == session.sessionId;
|
||||
const showHighlight = isActive && GlobalModel.activeMainView.get() == "session";
|
||||
const sessionScreens = GlobalModel.getSessionScreens(session.sessionId);
|
||||
const sessionIndicator = Math.max(...sessionScreens.map((screen) => screen.statusIndicator.get()));
|
||||
const sessionRunningCommands = sessionScreens.some((screen) => screen.numRunningCmds.get() > 0);
|
||||
return (
|
||||
<SideBarItem
|
||||
key={session.sessionId}
|
||||
className={`${isActive ? "active" : ""}`}
|
||||
className={cn({ active: isActive, highlight: showHighlight })}
|
||||
frontIcon={<span className="index">{index + 1}</span>}
|
||||
contents={session.name.get()}
|
||||
endIcons={[
|
||||
@ -240,6 +242,10 @@ class MainSideBar extends React.Component<MainSideBarProps, {}> {
|
||||
}
|
||||
|
||||
render() {
|
||||
let mainView = GlobalModel.activeMainView.get();
|
||||
const historyActive = mainView == "history";
|
||||
const connectionsActive = mainView == "connections";
|
||||
const settingsActive = mainView == "clientsettings";
|
||||
return (
|
||||
<ResizableSidebar
|
||||
model={GlobalModel.mainSidebarModel}
|
||||
@ -263,6 +269,7 @@ class MainSideBar extends React.Component<MainSideBarProps, {}> {
|
||||
<SideBarItem
|
||||
key="history"
|
||||
frontIcon={<i className="fa-sharp fa-regular fa-clock-rotate-left icon" />}
|
||||
className={cn({ active: historyActive, highlight: historyActive })}
|
||||
contents="History"
|
||||
endIcons={[<HotKeyIcon key="hotkey" hotkey="H" />]}
|
||||
onClick={this.handleHistoryClick}
|
||||
@ -271,6 +278,7 @@ class MainSideBar extends React.Component<MainSideBarProps, {}> {
|
||||
<SideBarItem
|
||||
key="connections"
|
||||
frontIcon={<i className="fa-sharp fa-regular fa-globe icon " />}
|
||||
className={cn({ active: connectionsActive, highlight: connectionsActive })}
|
||||
contents="Connections"
|
||||
onClick={this.handleConnectionsClick}
|
||||
/>
|
||||
@ -291,15 +299,18 @@ class MainSideBar extends React.Component<MainSideBarProps, {}> {
|
||||
</CenteredIcon>,
|
||||
]}
|
||||
/>
|
||||
<div
|
||||
className="middle scrollbar-hide-until-hover"
|
||||
<OverlayScrollbarsComponent
|
||||
element="div"
|
||||
className="middle"
|
||||
id="sidebar-middle"
|
||||
style={{
|
||||
maxHeight: `calc(100vh - ${this.middleHeightSubtractor.get()}px)`,
|
||||
}}
|
||||
options={{ scrollbars: { autoHide: "leave" } }}
|
||||
>
|
||||
{this.getSessions()}
|
||||
</div>
|
||||
</OverlayScrollbarsComponent>
|
||||
|
||||
<div className="bottom" id="sidebar-bottom">
|
||||
{this.getUpdateAppBanner()}
|
||||
<If condition={GlobalModel.isDev}>
|
||||
@ -314,6 +325,7 @@ class MainSideBar extends React.Component<MainSideBarProps, {}> {
|
||||
<SideBarItem
|
||||
key="settings"
|
||||
frontIcon={<SettingsIcon className="icon" />}
|
||||
className={cn({ active: settingsActive, highlight: settingsActive })}
|
||||
contents="Settings"
|
||||
onClick={this.handleSettingsClick}
|
||||
/>
|
||||
|
@ -15,7 +15,6 @@ dayjs.extend(localizedFormat);
|
||||
|
||||
interface RightSideBarProps {
|
||||
parentRef: React.RefObject<HTMLElement>;
|
||||
clientData: ClientDataType;
|
||||
}
|
||||
|
||||
@mobxReact.observer
|
||||
|
10
yarn.lock
10
yarn.lock
@ -6311,6 +6311,16 @@ opener@^1.5.1, opener@^1.5.2:
|
||||
resolved "https://registry.yarnpkg.com/opener/-/opener-1.5.2.tgz#5d37e1f35077b9dcac4301372271afdeb2a13598"
|
||||
integrity sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==
|
||||
|
||||
overlayscrollbars-react@^0.5.5:
|
||||
version "0.5.5"
|
||||
resolved "https://registry.yarnpkg.com/overlayscrollbars-react/-/overlayscrollbars-react-0.5.5.tgz#983fcff9928cd12fff78351573fdb79f463ea414"
|
||||
integrity sha512-PakK1QEV/PAi4XniiTykcSeyoBmfDvgv2uBQ290IaY5ThrwvWg3Zk3Z39hosJYkyrS4mJ0zuIWtlHX4AKd2nZQ==
|
||||
|
||||
overlayscrollbars@^2.6.1:
|
||||
version "2.6.1"
|
||||
resolved "https://registry.yarnpkg.com/overlayscrollbars/-/overlayscrollbars-2.6.1.tgz#50210de1d869ed0bf027de11cf705f5b9591a097"
|
||||
integrity sha512-V+ZAqWMYMyGBJNRDEcdRC7Ch+WT9RBx9hY8bfJSMyFObQeJoecs1Vqg7ZAzBVcpN6sCUXFAZldCbeySwmmD0RA==
|
||||
|
||||
p-cancelable@^2.0.0:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-2.1.1.tgz#aab7fbd416582fa32a3db49859c122487c5ed2cf"
|
||||
|
Loading…
Reference in New Issue
Block a user