mirror of
https://github.com/wavetermdev/waveterm.git
synced 2024-12-22 16:48:23 +01:00
Fix logo not being visible in auxiliary views when sidebar is collapsed (#347)
This commit is contained in:
parent
3f83441868
commit
314932d402
@ -250,6 +250,36 @@ a.a-block {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.logo-button-container {
|
||||||
|
width: 105px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
position: absolute;
|
||||||
|
z-index: 25;
|
||||||
|
top: 7px;
|
||||||
|
left: 0px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: flex-end;
|
||||||
|
align-items: center;
|
||||||
|
-webkit-app-region: drag;
|
||||||
|
pointer-events: none;
|
||||||
|
|
||||||
|
.logo-button {
|
||||||
|
width: 25px;
|
||||||
|
height: 25px;
|
||||||
|
margin-right: 6px;
|
||||||
|
cursor: pointer;
|
||||||
|
user-select: none;
|
||||||
|
-webkit-app-region: no-drag;
|
||||||
|
pointer-events: all;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: #333;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.copied-indicator {
|
.copied-indicator {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
@ -641,42 +671,6 @@ a.a-block {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.mainview {
|
|
||||||
flex-grow: 1;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
position: relative;
|
|
||||||
border-radius: 0 var(--app-border-radius) var(--app-border-radius) 0;
|
|
||||||
border-bottom: 1px solid var(--app-border-color);
|
|
||||||
border-right: 1px solid var(--app-border-color);
|
|
||||||
border-left: 1px solid var(--app-border-color);
|
|
||||||
background-color: black;
|
|
||||||
|
|
||||||
&.is-hidden {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.header {
|
|
||||||
-webkit-app-region: drag;
|
|
||||||
padding: 24px 18px;
|
|
||||||
margin: 0;
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
.close-div {
|
|
||||||
-webkit-app-region: no-drag;
|
|
||||||
font-size: 1.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bottom-border {
|
|
||||||
border-bottom: 1px solid white;
|
|
||||||
padding-bottom: 20px;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.settings-field {
|
.settings-field {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
|
@ -8,7 +8,7 @@ import { boundMethod } from "autobind-decorator";
|
|||||||
import { If } from "tsx-control-statements/components";
|
import { If } from "tsx-control-statements/components";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import localizedFormat from "dayjs/plugin/localizedFormat";
|
import localizedFormat from "dayjs/plugin/localizedFormat";
|
||||||
import { GlobalModel } from "@/models";
|
import { GlobalCommandRunner, GlobalModel } from "@/models";
|
||||||
import { isBlank } from "@/util/util";
|
import { isBlank } from "@/util/util";
|
||||||
import { WorkspaceView } from "./workspace/workspaceview";
|
import { WorkspaceView } from "./workspace/workspaceview";
|
||||||
import { PluginsView } from "./pluginsview/pluginsview";
|
import { PluginsView } from "./pluginsview/pluginsview";
|
||||||
@ -20,6 +20,7 @@ import { MainSideBar } from "./sidebar/sidebar";
|
|||||||
import { DisconnectedModal, ClientStopModal } from "./common/modals";
|
import { DisconnectedModal, ClientStopModal } from "./common/modals";
|
||||||
import { ModalsProvider } from "./common/modals/provider";
|
import { ModalsProvider } from "./common/modals/provider";
|
||||||
import { ErrorBoundary } from "./common/error/errorboundary";
|
import { ErrorBoundary } from "./common/error/errorboundary";
|
||||||
|
import cn from "classnames";
|
||||||
import "./app.less";
|
import "./app.less";
|
||||||
|
|
||||||
dayjs.extend(localizedFormat);
|
dayjs.extend(localizedFormat);
|
||||||
@ -37,7 +38,7 @@ class App extends React.Component<{}, {}> {
|
|||||||
@boundMethod
|
@boundMethod
|
||||||
handleContextMenu(e: any) {
|
handleContextMenu(e: any) {
|
||||||
let isInNonTermInput = false;
|
let isInNonTermInput = false;
|
||||||
let activeElem = document.activeElement;
|
const activeElem = document.activeElement;
|
||||||
if (activeElem != null && activeElem.nodeName == "TEXTAREA") {
|
if (activeElem != null && activeElem.nodeName == "TEXTAREA") {
|
||||||
if (!activeElem.classList.contains("xterm-helper-textarea")) {
|
if (!activeElem.classList.contains("xterm-helper-textarea")) {
|
||||||
isInNonTermInput = true;
|
isInNonTermInput = true;
|
||||||
@ -46,17 +47,13 @@ class App extends React.Component<{}, {}> {
|
|||||||
if (activeElem != null && activeElem.nodeName == "INPUT" && activeElem.getAttribute("type") == "text") {
|
if (activeElem != null && activeElem.nodeName == "INPUT" && activeElem.getAttribute("type") == "text") {
|
||||||
isInNonTermInput = true;
|
isInNonTermInput = true;
|
||||||
}
|
}
|
||||||
let opts: ContextMenuOpts = {};
|
const opts: ContextMenuOpts = {};
|
||||||
if (isInNonTermInput) {
|
if (isInNonTermInput) {
|
||||||
opts.showCut = true;
|
opts.showCut = true;
|
||||||
}
|
}
|
||||||
let sel = window.getSelection();
|
const sel = window.getSelection();
|
||||||
if (!isBlank(sel?.toString())) {
|
if (!isBlank(sel?.toString()) || isInNonTermInput) {
|
||||||
GlobalModel.contextEditMenu(e, opts);
|
GlobalModel.contextEditMenu(e, opts);
|
||||||
} else {
|
|
||||||
if (isInNonTermInput) {
|
|
||||||
GlobalModel.contextEditMenu(e, opts);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,13 +64,19 @@ class App extends React.Component<{}, {}> {
|
|||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@boundMethod
|
||||||
|
openSidebar() {
|
||||||
|
const width = GlobalModel.mainSidebarModel.getWidth(true);
|
||||||
|
GlobalCommandRunner.clientSetSidebar(width, false);
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
let remotesModel = GlobalModel.remotesModel;
|
const remotesModel = GlobalModel.remotesModel;
|
||||||
let disconnected = !GlobalModel.ws.open.get() || !GlobalModel.waveSrvRunning.get();
|
const disconnected = !GlobalModel.ws.open.get() || !GlobalModel.waveSrvRunning.get();
|
||||||
let hasClientStop = GlobalModel.getHasClientStop();
|
const hasClientStop = GlobalModel.getHasClientStop();
|
||||||
let dcWait = this.dcWait.get();
|
const dcWait = this.dcWait.get();
|
||||||
let platform = GlobalModel.getPlatform();
|
const platform = GlobalModel.getPlatform();
|
||||||
let clientData = GlobalModel.clientData.get();
|
const clientData = GlobalModel.clientData.get();
|
||||||
|
|
||||||
// Previously, this is done in sidebar.tsx but it causes flicker when clientData is null cos screen-view shifts around.
|
// Previously, this is done in sidebar.tsx but it causes flicker when clientData is null cos screen-view shifts around.
|
||||||
// Doing it here fixes the flicker cos app is not rendered until clientData is populated.
|
// Doing it here fixes the flicker cos app is not rendered until clientData is populated.
|
||||||
@ -106,14 +109,22 @@ class App extends React.Component<{}, {}> {
|
|||||||
setTimeout(() => this.updateDcWait(false), 0);
|
setTimeout(() => this.updateDcWait(false), 0);
|
||||||
}
|
}
|
||||||
// used to force a full reload of the application
|
// used to force a full reload of the application
|
||||||
let renderVersion = GlobalModel.renderVersion.get();
|
const renderVersion = GlobalModel.renderVersion.get();
|
||||||
|
const sidebarCollapsed = GlobalModel.mainSidebarModel.getCollapsed();
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
key={"version-" + renderVersion}
|
key={"version-" + renderVersion}
|
||||||
id="main"
|
id="main"
|
||||||
className={"platform-" + platform}
|
className={cn("platform-" + platform, { "sidebar-collapsed": sidebarCollapsed })}
|
||||||
onContextMenu={this.handleContextMenu}
|
onContextMenu={this.handleContextMenu}
|
||||||
>
|
>
|
||||||
|
<If condition={sidebarCollapsed}>
|
||||||
|
<div key="logo-button" className="logo-button-container">
|
||||||
|
<div className="logo-button" onClick={this.openSidebar}>
|
||||||
|
<img src="public/logos/wave-logo.png" alt="logo" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</If>
|
||||||
<div ref={this.mainContentRef} className="main-content">
|
<div ref={this.mainContentRef} className="main-content">
|
||||||
<MainSideBar parentRef={this.mainContentRef} clientData={clientData} />
|
<MainSideBar parentRef={this.mainContentRef} clientData={clientData} />
|
||||||
<ErrorBoundary>
|
<ErrorBoundary>
|
||||||
|
@ -16,6 +16,7 @@ import { ReactComponent as TrashIcon } from "@/assets/icons/favourites/trash.svg
|
|||||||
import { ReactComponent as FavoritesIcon } from "@/assets/icons/favourites.svg";
|
import { ReactComponent as FavoritesIcon } from "@/assets/icons/favourites.svg";
|
||||||
|
|
||||||
import "./bookmarks.less";
|
import "./bookmarks.less";
|
||||||
|
import { MainView } from "../common/elements/mainview";
|
||||||
|
|
||||||
type BookmarkProps = {
|
type BookmarkProps = {
|
||||||
bookmark: BookmarkType;
|
bookmark: BookmarkType;
|
||||||
@ -23,10 +24,6 @@ type BookmarkProps = {
|
|||||||
|
|
||||||
@mobxReact.observer
|
@mobxReact.observer
|
||||||
class Bookmark extends React.Component<BookmarkProps, {}> {
|
class Bookmark extends React.Component<BookmarkProps, {}> {
|
||||||
constructor(props: BookmarkProps) {
|
|
||||||
super(props);
|
|
||||||
}
|
|
||||||
|
|
||||||
@boundMethod
|
@boundMethod
|
||||||
handleDeleteClick(): void {
|
handleDeleteClick(): void {
|
||||||
let { bookmark } = this.props;
|
let { bookmark } = this.props;
|
||||||
@ -45,14 +42,12 @@ class Bookmark extends React.Component<BookmarkProps, {}> {
|
|||||||
handleEditCancel(): void {
|
handleEditCancel(): void {
|
||||||
let model = GlobalModel.bookmarksModel;
|
let model = GlobalModel.bookmarksModel;
|
||||||
model.cancelEdit();
|
model.cancelEdit();
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@boundMethod
|
@boundMethod
|
||||||
handleEditUpdate(): void {
|
handleEditUpdate(): void {
|
||||||
let model = GlobalModel.bookmarksModel;
|
let model = GlobalModel.bookmarksModel;
|
||||||
model.confirmEdit();
|
model.confirmEdit();
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@boundMethod
|
@boundMethod
|
||||||
@ -185,31 +180,15 @@ class Bookmark extends React.Component<BookmarkProps, {}> {
|
|||||||
|
|
||||||
@mobxReact.observer
|
@mobxReact.observer
|
||||||
class BookmarksView extends React.Component<{}, {}> {
|
class BookmarksView extends React.Component<{}, {}> {
|
||||||
constructor(props: {}) {
|
|
||||||
super(props);
|
|
||||||
}
|
|
||||||
|
|
||||||
@boundMethod
|
|
||||||
closeView(): void {
|
|
||||||
GlobalModel.bookmarksModel.closeView();
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
let isHidden = GlobalModel.activeMainView.get() != "bookmarks";
|
const isHidden = GlobalModel.activeMainView.get() != "bookmarks";
|
||||||
if (isHidden) {
|
if (isHidden) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
let bookmarks = GlobalModel.bookmarksModel.bookmarks;
|
let bookmarks = GlobalModel.bookmarksModel.bookmarks;
|
||||||
let idx: number = 0;
|
|
||||||
let bookmark: BookmarkType = null;
|
let bookmark: BookmarkType = null;
|
||||||
return (
|
return (
|
||||||
<div className={cn("mainview", "bookmarks-view", { "is-hidden": isHidden })}>
|
<MainView viewName="bookmarks" title="Bookmarks" onClose={GlobalModel.bookmarksModel.closeView}>
|
||||||
<div className="header bottom-border">
|
|
||||||
<div className="bookmarks-title text-primary">Favorites</div>
|
|
||||||
<div className="close-div hoverEffect" title="Close (Escape)" onClick={this.closeView}>
|
|
||||||
<i className="fa-sharp fa-solid fa-xmark"></i>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="bookmarks-list">
|
<div className="bookmarks-list">
|
||||||
<For index="idx" each="bookmark" of={bookmarks}>
|
<For index="idx" each="bookmark" of={bookmarks}>
|
||||||
<Bookmark key={bookmark.bookmarkid} bookmark={bookmark} />
|
<Bookmark key={bookmark.bookmarkid} bookmark={bookmark} />
|
||||||
@ -238,7 +217,7 @@ class BookmarksView extends React.Component<{}, {}> {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</If>
|
</If>
|
||||||
</div>
|
</MainView>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ import { commandRtnHandler, isBlank } from "@/util/util";
|
|||||||
import * as appconst from "@/app/appconst";
|
import * as appconst from "@/app/appconst";
|
||||||
|
|
||||||
import "./clientsettings.less";
|
import "./clientsettings.less";
|
||||||
|
import { MainView } from "../common/elements/mainview";
|
||||||
|
|
||||||
@mobxReact.observer
|
@mobxReact.observer
|
||||||
class ClientSettingsView extends React.Component<{ model: RemotesModel }, { hoveredItemId: string }> {
|
class ClientSettingsView extends React.Component<{ model: RemotesModel }, { hoveredItemId: string }> {
|
||||||
@ -105,11 +106,6 @@ class ClientSettingsView extends React.Component<{ model: RemotesModel }, { hove
|
|||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
|
|
||||||
@boundMethod
|
|
||||||
handleClose(): void {
|
|
||||||
GlobalModel.clientSettingsViewModel.closeView();
|
|
||||||
}
|
|
||||||
|
|
||||||
@boundMethod
|
@boundMethod
|
||||||
handleChangeShortcut(newShortcut: string): void {
|
handleChangeShortcut(newShortcut: string): void {
|
||||||
const prtn = GlobalCommandRunner.setGlobalShortcut(newShortcut);
|
const prtn = GlobalCommandRunner.setGlobalShortcut(newShortcut);
|
||||||
@ -148,13 +144,11 @@ class ClientSettingsView extends React.Component<{ model: RemotesModel }, { hove
|
|||||||
const curFontFamily = GlobalModel.getTermFontFamily();
|
const curFontFamily = GlobalModel.getTermFontFamily();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={cn("mainview", "clientsettings-view")}>
|
<MainView
|
||||||
<header className="header bottom-border">
|
viewName="clientsettings"
|
||||||
<div className="clientsettings-title text-primary">Client Settings</div>
|
title="Client Settings"
|
||||||
<div className="close-div hoverEffect" title="Close (Escape)" onClick={this.handleClose}>
|
onClose={GlobalModel.clientSettingsViewModel.closeView}
|
||||||
<i className="fa-sharp fa-solid fa-xmark"></i>
|
>
|
||||||
</div>
|
|
||||||
</header>
|
|
||||||
<div className="content">
|
<div className="content">
|
||||||
<div className="settings-field">
|
<div className="settings-field">
|
||||||
<div className="settings-label">Term Font Size</div>
|
<div className="settings-label">Term Font Size</div>
|
||||||
@ -259,7 +253,7 @@ class ClientSettingsView extends React.Component<{ model: RemotesModel }, { hove
|
|||||||
</div>
|
</div>
|
||||||
<SettingsError errorMessage={this.errorMessage} />
|
<SettingsError errorMessage={this.errorMessage} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</MainView>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
55
src/app/common/elements/mainview.less
Normal file
55
src/app/common/elements/mainview.less
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
.mainview {
|
||||||
|
flex-grow: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
position: relative;
|
||||||
|
border-radius: 0 var(--app-border-radius) var(--app-border-radius) 0;
|
||||||
|
border-bottom: 1px solid var(--app-border-color);
|
||||||
|
border-right: 1px solid var(--app-border-color);
|
||||||
|
border-left: 1px solid var(--app-border-color);
|
||||||
|
background-color: var(--app-bg-color);
|
||||||
|
|
||||||
|
&.is-hidden {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
-webkit-app-region: drag;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
flex-direction: row;
|
||||||
|
line-height: var(--screentabs-height);
|
||||||
|
vertical-align: middle;
|
||||||
|
padding: 0 10px 0 10px;
|
||||||
|
margin: 0;
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-size: 1.5em;
|
||||||
|
padding: 0 10px;
|
||||||
|
vertical-align: middle;
|
||||||
|
line-height: var(--screentabs-height);
|
||||||
|
color: var(--term-white);
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.close-div {
|
||||||
|
-webkit-app-region: no-drag;
|
||||||
|
font-size: 1.5em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.bottom-border {
|
||||||
|
border-bottom: 1px solid var(--app-border-color);
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This ensures the tab bar does not collide with the floating logo. The floating logo sits above the sidebar when it is not collapsed, so no additional margin is needed in that case.
|
||||||
|
// More margin is given on macOS to account for the traffic light buttons
|
||||||
|
#main.platform-darwin.sidebar-collapsed .header {
|
||||||
|
margin-left: var(--floating-logo-width-darwin);
|
||||||
|
}
|
||||||
|
|
||||||
|
#main:not(.platform-darwin).sidebar-collapsed .header {
|
||||||
|
margin-left: var(--floating-logo-width);
|
||||||
|
}
|
38
src/app/common/elements/mainview.tsx
Normal file
38
src/app/common/elements/mainview.tsx
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
// Copyright 2023, Command Line Inc.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
import * as React from "react";
|
||||||
|
import * as mobxReact from "mobx-react";
|
||||||
|
import cn from "classnames";
|
||||||
|
import { GlobalModel } from "@/models";
|
||||||
|
|
||||||
|
import "./mainview.less";
|
||||||
|
|
||||||
|
@mobxReact.observer
|
||||||
|
class MainView extends React.Component<{
|
||||||
|
viewName: string;
|
||||||
|
title: string;
|
||||||
|
onClose: () => void;
|
||||||
|
children: React.ReactNode;
|
||||||
|
}> {
|
||||||
|
render() {
|
||||||
|
// TODO: This is a workaround for History view not honoring the sidebar width. This is rooted in the table width for the history view, which uses `calc(100%-20px)`. To properly fix this, History view needs a full overhaul.
|
||||||
|
const width = window.innerWidth - 6 - GlobalModel.mainSidebarModel.getWidth();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={cn("mainview", `${this.props.viewName}-view`)} style={{ maxWidth: width }}>
|
||||||
|
<div className="header-container bottom-border">
|
||||||
|
<header className="header">
|
||||||
|
<div className="title text-primary">{this.props.title}</div>
|
||||||
|
<div className="close-div hoverEffect" title="Close (Escape)" onClick={this.props.onClose}>
|
||||||
|
<i className="fa-sharp fa-solid fa-xmark"></i>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
</div>
|
||||||
|
{this.props.children}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export { MainView };
|
0
src/app/common/elements/viewheader.less
Normal file
0
src/app/common/elements/viewheader.less
Normal file
0
src/app/common/elements/viewheader.tsx
Normal file
0
src/app/common/elements/viewheader.tsx
Normal file
@ -12,6 +12,7 @@ import { Button, Status, ShowWaveShellInstallPrompt } from "@/common/elements";
|
|||||||
import * as util from "@/util/util";
|
import * as util from "@/util/util";
|
||||||
|
|
||||||
import "./connections.less";
|
import "./connections.less";
|
||||||
|
import { MainView } from "../common/elements/mainview";
|
||||||
|
|
||||||
@mobxReact.observer
|
@mobxReact.observer
|
||||||
class ConnectionsView extends React.Component<{ model: RemotesModel }, { hoveredItemId: string }> {
|
class ConnectionsView extends React.Component<{ model: RemotesModel }, { hoveredItemId: string }> {
|
||||||
@ -97,11 +98,6 @@ class ConnectionsView extends React.Component<{ model: RemotesModel }, { hovered
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@boundMethod
|
|
||||||
handleClose(): void {
|
|
||||||
GlobalModel.connectionViewModel.closeView();
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
if (this.tableRef.current != null) {
|
if (this.tableRef.current != null) {
|
||||||
this.tableRszObs = new ResizeObserver(this.handleTableResize.bind(this));
|
this.tableRszObs = new ResizeObserver(this.handleTableResize.bind(this));
|
||||||
@ -130,13 +126,7 @@ class ConnectionsView extends React.Component<{ model: RemotesModel }, { hovered
|
|||||||
let item: RemoteType = null;
|
let item: RemoteType = null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={cn("mainview", "connections-view")}>
|
<MainView viewName="connections" title="Connections" onClose={GlobalModel.connectionViewModel.closeView}>
|
||||||
<header className="header bottom-border">
|
|
||||||
<div className="connections-title text-primary">Connections</div>
|
|
||||||
<div className="close-div hoverEffect" title="Close (Escape)" onClick={this.handleClose}>
|
|
||||||
<i className="fa-sharp fa-solid fa-xmark"></i>
|
|
||||||
</div>
|
|
||||||
</header>
|
|
||||||
<table
|
<table
|
||||||
className="connections-table"
|
className="connections-table"
|
||||||
cellSpacing="0"
|
cellSpacing="0"
|
||||||
@ -209,7 +199,7 @@ class ConnectionsView extends React.Component<{ model: RemotesModel }, { hovered
|
|||||||
<div>No Connections Items Found</div>
|
<div>No Connections Items Found</div>
|
||||||
</div>
|
</div>
|
||||||
</If>
|
</If>
|
||||||
</div>
|
</MainView>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,6 @@
|
|||||||
.history-view {
|
.history-view {
|
||||||
padding-bottom: 10px;
|
padding-bottom: 10px;
|
||||||
|
|
||||||
.header {
|
|
||||||
padding: 18px 18px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.icon {
|
.icon {
|
||||||
width: 2em !important;
|
width: 2em !important;
|
||||||
height: 1.3em !important;
|
height: 1.3em !important;
|
||||||
@ -43,23 +39,7 @@
|
|||||||
top: 0.5em;
|
top: 0.5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.close-div {
|
|
||||||
position: absolute;
|
|
||||||
right: 1em;
|
|
||||||
top: 0.8em;
|
|
||||||
cursor: pointer;
|
|
||||||
width: 1.5em;
|
|
||||||
height: 1.5em;
|
|
||||||
border-radius: 50%;
|
|
||||||
svg {
|
|
||||||
width: 1.5em;
|
|
||||||
height: 1.5em;
|
|
||||||
fill: var(--app-text-color);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.history-search {
|
.history-search {
|
||||||
flex-grow: 1;
|
|
||||||
padding: 0 10px 10px 10px;
|
padding: 0 10px 10px 10px;
|
||||||
|
|
||||||
input {
|
input {
|
||||||
|
@ -28,6 +28,7 @@ import { ReactComponent as CheckIcon } from "@/assets/icons/line/check.svg";
|
|||||||
import { ReactComponent as CopyIcon } from "@/assets/icons/history/copy.svg";
|
import { ReactComponent as CopyIcon } from "@/assets/icons/history/copy.svg";
|
||||||
|
|
||||||
import "./history.less";
|
import "./history.less";
|
||||||
|
import { MainView } from "../common/elements/mainview";
|
||||||
|
|
||||||
dayjs.extend(customParseFormat);
|
dayjs.extend(customParseFormat);
|
||||||
dayjs.extend(localizedFormat);
|
dayjs.extend(localizedFormat);
|
||||||
@ -178,11 +179,6 @@ class HistoryView extends React.Component<{}, {}> {
|
|||||||
remoteDropdownActive: OV<boolean> = mobx.observable.box(false, { name: "remoteDropdownActive" });
|
remoteDropdownActive: OV<boolean> = mobx.observable.box(false, { name: "remoteDropdownActive" });
|
||||||
copiedItemId: OV<string> = mobx.observable.box(null, { name: "copiedItemId" });
|
copiedItemId: OV<string> = mobx.observable.box(null, { name: "copiedItemId" });
|
||||||
|
|
||||||
@boundMethod
|
|
||||||
clickCloseHandler(): void {
|
|
||||||
GlobalModel.historyViewModel.closeView();
|
|
||||||
}
|
|
||||||
|
|
||||||
@boundMethod
|
@boundMethod
|
||||||
handleNext() {
|
handleNext() {
|
||||||
GlobalModel.historyViewModel.goNext();
|
GlobalModel.historyViewModel.goNext();
|
||||||
@ -206,7 +202,6 @@ class HistoryView extends React.Component<{}, {}> {
|
|||||||
if (checkKeyPressed(waveEvent, "Enter")) {
|
if (checkKeyPressed(waveEvent, "Enter")) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
GlobalModel.historyViewModel.submitSearch();
|
GlobalModel.historyViewModel.submitSearch();
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -229,10 +224,9 @@ class HistoryView extends React.Component<{}, {}> {
|
|||||||
let numSelected = hvm.selectedItems.size;
|
let numSelected = hvm.selectedItems.size;
|
||||||
if (numSelected > 0) {
|
if (numSelected > 0) {
|
||||||
hvm.selectedItems.clear();
|
hvm.selectedItems.clear();
|
||||||
return;
|
|
||||||
} else {
|
} else {
|
||||||
for (let i = 0; i < hvm.items.length; i++) {
|
for (const element of hvm.items) {
|
||||||
hvm.selectedItems.set(hvm.items[i].historyid, true);
|
hvm.selectedItems.set(element.historyid, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
@ -302,7 +296,6 @@ class HistoryView extends React.Component<{}, {}> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
hvm.setFromDate(e.target.value);
|
hvm.setFromDate(e.target.value);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@boundMethod
|
@boundMethod
|
||||||
@ -399,7 +392,6 @@ class HistoryView extends React.Component<{}, {}> {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
let hvm = GlobalModel.historyViewModel;
|
let hvm = GlobalModel.historyViewModel;
|
||||||
let idx: number = 0;
|
|
||||||
let item: HistoryItem = null;
|
let item: HistoryItem = null;
|
||||||
let items = hvm.items.slice();
|
let items = hvm.items.slice();
|
||||||
let nowDate = new Date();
|
let nowDate = new Date();
|
||||||
@ -410,32 +402,13 @@ class HistoryView extends React.Component<{}, {}> {
|
|||||||
let offset = hvm.offset.get();
|
let offset = hvm.offset.get();
|
||||||
let numSelected = hvm.selectedItems.size;
|
let numSelected = hvm.selectedItems.size;
|
||||||
let activeItemId = hvm.activeItem.get();
|
let activeItemId = hvm.activeItem.get();
|
||||||
let activeItem = hvm.getHistoryItemById(activeItemId);
|
|
||||||
let activeLine: LineType = null;
|
|
||||||
if (activeItem != null) {
|
|
||||||
activeLine = hvm.getLineById(activeItem.lineid);
|
|
||||||
}
|
|
||||||
let sessionIds = Object.keys(snames);
|
let sessionIds = Object.keys(snames);
|
||||||
let sessionId: string = null;
|
let sessionId: string = null;
|
||||||
let remoteIds = Object.keys(rnames);
|
let remoteIds = Object.keys(rnames);
|
||||||
let remoteId: string = null;
|
let remoteId: string = null;
|
||||||
|
|
||||||
// TODO: something is weird with how we calculate width for views. Before, history view was not honoring tab width. This fix is copied from workspaceview.tsx, which had a similar issue.
|
|
||||||
const width = window.innerWidth - 6 - GlobalModel.mainSidebarModel.getWidth();
|
|
||||||
return (
|
return (
|
||||||
<div
|
<MainView viewName="history" title="History" onClose={GlobalModel.historyViewModel.closeView}>
|
||||||
className={cn("history-view", "mainview", { "is-hidden": isHidden })}
|
|
||||||
style={{
|
|
||||||
width: `${width}px`,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<header key="header" className="header">
|
|
||||||
<div className="clientsettings-title text-primary">History</div>
|
|
||||||
<div className="close-div hoverEffect" title="Close (Escape)" onClick={this.clickCloseHandler}>
|
|
||||||
<i className="fa-sharp fa-solid fa-xmark"></i>
|
|
||||||
</div>
|
|
||||||
</header>
|
|
||||||
|
|
||||||
<div key="search" className="history-search">
|
<div key="search" className="history-search">
|
||||||
<div className="main-search field">
|
<div className="main-search field">
|
||||||
<TextField
|
<TextField
|
||||||
@ -678,14 +651,13 @@ class HistoryView extends React.Component<{}, {}> {
|
|||||||
<ChevronRightIcon className="icon" />
|
<ChevronRightIcon className="icon" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</MainView>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class LineContainer extends React.Component<{ historyId: string; width: number }, {}> {
|
class LineContainer extends React.Component<{ historyId: string; width: number }, {}> {
|
||||||
line: LineType;
|
line: LineType;
|
||||||
cmd: Cmd;
|
|
||||||
historyItem: HistoryItem;
|
historyItem: HistoryItem;
|
||||||
visible: OV<boolean> = mobx.observable.box(true);
|
visible: OV<boolean> = mobx.observable.box(true);
|
||||||
overrideCollapsed: OV<boolean> = mobx.observable.box(false);
|
overrideCollapsed: OV<boolean> = mobx.observable.box(false);
|
||||||
@ -698,7 +670,6 @@ class LineContainer extends React.Component<{ historyId: string; width: number }
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.line = hvm.getLineById(this.historyItem.lineid);
|
this.line = hvm.getLineById(this.historyItem.lineid);
|
||||||
this.cmd = hvm.getCmdById(this.historyItem.lineid);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@boundMethod
|
@boundMethod
|
||||||
|
@ -26,6 +26,11 @@
|
|||||||
--screentabs-font-weight: 300;
|
--screentabs-font-weight: 300;
|
||||||
--screentabs-selected-font-weight: 300;
|
--screentabs-selected-font-weight: 300;
|
||||||
|
|
||||||
|
// floating logo settings
|
||||||
|
--floating-logo-width-darwin: 110px;
|
||||||
|
--floating-logo-width: 40px;
|
||||||
|
--floating-logo-height: var(--screentabs-height);
|
||||||
|
|
||||||
// global colors
|
// global colors
|
||||||
--app-accent-color: rgb(88, 193, 66);
|
--app-accent-color: rgb(88, 193, 66);
|
||||||
--app-error-color: rgb(204, 0, 0);
|
--app-error-color: rgb(204, 0, 0);
|
||||||
|
@ -8,7 +8,6 @@ import { boundMethod } from "autobind-decorator";
|
|||||||
import cn from "classnames";
|
import cn from "classnames";
|
||||||
import { GlobalModel, GlobalCommandRunner, Screen } from "@/models";
|
import { GlobalModel, GlobalCommandRunner, Screen } from "@/models";
|
||||||
import { ActionsIcon, StatusIndicator, CenteredIcon } from "@/common/icons/icons";
|
import { ActionsIcon, StatusIndicator, CenteredIcon } from "@/common/icons/icons";
|
||||||
import { renderCmdText } from "@/elements";
|
|
||||||
import { ReactComponent as SquareIcon } from "@/assets/icons/tab/square.svg";
|
import { ReactComponent as SquareIcon } from "@/assets/icons/tab/square.svg";
|
||||||
import * as constants from "@/app/appconst";
|
import * as constants from "@/app/appconst";
|
||||||
import { Reorder } from "framer-motion";
|
import { Reorder } from "framer-motion";
|
||||||
|
@ -91,34 +91,6 @@
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
height: var(--screentabs-height);
|
height: var(--screentabs-height);
|
||||||
|
|
||||||
&.sidebar-collapsed .logo-button-container {
|
|
||||||
width: 105px;
|
|
||||||
flex-shrink: 0;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
justify-content: flex-end;
|
|
||||||
align-items: center;
|
|
||||||
-webkit-app-region: drag;
|
|
||||||
|
|
||||||
.logo-button {
|
|
||||||
width: 25px;
|
|
||||||
height: 25px;
|
|
||||||
margin-right: 6px;
|
|
||||||
cursor: pointer;
|
|
||||||
user-select: none;
|
|
||||||
-webkit-app-region: no-drag;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background-color: #333;
|
|
||||||
border-radius: 4px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.logo-button {
|
|
||||||
width: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
z-index: 200;
|
z-index: 200;
|
||||||
}
|
}
|
||||||
@ -206,3 +178,13 @@
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This ensures the tab bar does not collide with the floating logo. The floating logo sits above the sidebar when it is not collapsed, so no additional margin is needed in that case.
|
||||||
|
// More margin is given on macOS to account for the traffic light buttons
|
||||||
|
#main.platform-darwin.sidebar-collapsed .screen-tabs-container {
|
||||||
|
margin-left: var(--floating-logo-width-darwin);
|
||||||
|
}
|
||||||
|
|
||||||
|
#main:not(.platform-darwin).sidebar-collapsed .screen-tabs-container {
|
||||||
|
margin-left: var(--floating-logo-width);
|
||||||
|
}
|
||||||
|
@ -168,12 +168,6 @@ class ScreenTabs extends React.Component<
|
|||||||
// For touchpad events, do nothing and let the browser handle it
|
// For touchpad events, do nothing and let the browser handle it
|
||||||
}
|
}
|
||||||
|
|
||||||
@boundMethod
|
|
||||||
openSidebar() {
|
|
||||||
const width = GlobalModel.mainSidebarModel.getWidth(true);
|
|
||||||
GlobalCommandRunner.clientSetSidebar(width, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
let { showingScreens } = this.state;
|
let { showingScreens } = this.state;
|
||||||
let { session } = this.props;
|
let { session } = this.props;
|
||||||
@ -183,20 +177,8 @@ class ScreenTabs extends React.Component<
|
|||||||
let screen: Screen | null = null;
|
let screen: Screen | null = null;
|
||||||
let index = 0;
|
let index = 0;
|
||||||
let activeScreenId = this.getActiveScreenId();
|
let activeScreenId = this.getActiveScreenId();
|
||||||
const sidebarCollapsed = GlobalModel.mainSidebarModel.getCollapsed();
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div className="screen-tabs-container">
|
||||||
className={cn("screen-tabs-container", {
|
|
||||||
"sidebar-collapsed": sidebarCollapsed,
|
|
||||||
})}
|
|
||||||
>
|
|
||||||
<If condition={sidebarCollapsed}>
|
|
||||||
<div key="logo-button" className="logo-button-container">
|
|
||||||
<div className="logo-button" onClick={this.openSidebar}>
|
|
||||||
<img src="public/logos/wave-logo.png" alt="logo" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</If>
|
|
||||||
{/* Inner container ensures that hovering over the scrollbar doesn't trigger the hover effect on the tabs. This prevents weird flickering of the icons when the mouse is moved over the scrollbar. */}
|
{/* Inner container ensures that hovering over the scrollbar doesn't trigger the hover effect on the tabs. This prevents weird flickering of the icons when the mouse is moved over the scrollbar. */}
|
||||||
<div
|
<div
|
||||||
key="container-inner"
|
key="container-inner"
|
||||||
|
Loading…
Reference in New Issue
Block a user