mirror of
https://github.com/wavetermdev/backup.git
synced 2026-08-05 13:57:07 -07:00
Rght sidebar (#461)
* init * model * pass model * increase snap threshold * move saving of state to model. backend implementation * fix wrong clientdata prop * right header space for right sidebar toggles * button component refactor * set default classname to primary * remove debugging code * hide trigger for now * disable right sidebar in production (only show on dev for now)
This commit is contained in:
@@ -44,6 +44,10 @@
|
||||
--floating-logo-width: 40px;
|
||||
--floating-logo-height: var(--screentabs-height);
|
||||
|
||||
/* right sidebar triggers */
|
||||
--floating-right-sidebar-triggers-width-darwin: 50px;
|
||||
--floating-right-sidebar-triggers-width: 40px;
|
||||
|
||||
/* global colors */
|
||||
--app-bg-color: black;
|
||||
--app-accent-color: rgb(88, 193, 66);
|
||||
|
||||
@@ -302,6 +302,25 @@ a.a-block {
|
||||
}
|
||||
}
|
||||
|
||||
.right-sidebar-triggers {
|
||||
position: absolute;
|
||||
z-index: 25;
|
||||
right: 0px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
pointer-events: none;
|
||||
height: 38px;
|
||||
padding: 0 5px;
|
||||
|
||||
.right-sidebar-trigger {
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
-webkit-app-region: no-drag;
|
||||
pointer-events: all;
|
||||
}
|
||||
}
|
||||
|
||||
.copied-indicator {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
|
||||
+35
-11
@@ -16,10 +16,12 @@ import { BookmarksView } from "./bookmarks/bookmarks";
|
||||
import { HistoryView } from "./history/history";
|
||||
import { ConnectionsView } from "./connections/connections";
|
||||
import { ClientSettingsView } from "./clientsettings/clientsettings";
|
||||
import { MainSideBar } from "./sidebar/sidebar";
|
||||
import { DisconnectedModal, ClientStopModal } from "./common/modals";
|
||||
import { ModalsProvider } from "./common/modals/provider";
|
||||
import { ErrorBoundary } from "./common/error/errorboundary";
|
||||
import { MainSideBar } from "./sidebar/main";
|
||||
import { RightSideBar } from "./sidebar/right";
|
||||
import { DisconnectedModal, ClientStopModal } from "@/modals";
|
||||
import { ModalsProvider } from "@/modals/provider";
|
||||
import { Button } from "@/elements";
|
||||
import { ErrorBoundary } from "@/common/error/errorboundary";
|
||||
import cn from "classnames";
|
||||
import "./app.less";
|
||||
|
||||
@@ -65,9 +67,17 @@ class App extends React.Component<{}, {}> {
|
||||
}
|
||||
|
||||
@boundMethod
|
||||
openSidebar() {
|
||||
const width = GlobalModel.mainSidebarModel.getWidth(true);
|
||||
GlobalCommandRunner.clientSetSidebar(width, false);
|
||||
openMainSidebar() {
|
||||
const mainSidebarModel = GlobalModel.mainSidebarModel;
|
||||
const width = mainSidebarModel.getWidth(true);
|
||||
mainSidebarModel.saveState(width, false);
|
||||
}
|
||||
|
||||
@boundMethod
|
||||
openRightSidebar() {
|
||||
const rightSidebarModel = GlobalModel.rightSidebarModel;
|
||||
const width = rightSidebarModel.getWidth(true);
|
||||
rightSidebarModel.saveState(width, false);
|
||||
}
|
||||
|
||||
render() {
|
||||
@@ -110,23 +120,36 @@ class App extends React.Component<{}, {}> {
|
||||
}
|
||||
// used to force a full reload of the application
|
||||
const renderVersion = GlobalModel.renderVersion.get();
|
||||
const sidebarCollapsed = GlobalModel.mainSidebarModel.getCollapsed();
|
||||
const mainSidebarCollapsed = GlobalModel.mainSidebarModel.getCollapsed();
|
||||
const rightSidebarCollapsed = GlobalModel.rightSidebarModel.getCollapsed();
|
||||
const activeMainView = GlobalModel.activeMainView.get();
|
||||
const lightDarkClass = GlobalModel.isThemeDark() ? "is-dark" : "is-light";
|
||||
return (
|
||||
<div
|
||||
key={"version-" + renderVersion}
|
||||
id="main"
|
||||
className={cn("platform-" + platform, { "sidebar-collapsed": sidebarCollapsed }, lightDarkClass)}
|
||||
className={cn(
|
||||
"platform-" + platform,
|
||||
{ "mainsidebar-collapsed": mainSidebarCollapsed, "rightsidebar-collapsed": rightSidebarCollapsed },
|
||||
lightDarkClass
|
||||
)}
|
||||
onContextMenu={this.handleContextMenu}
|
||||
>
|
||||
<If condition={sidebarCollapsed}>
|
||||
<If condition={mainSidebarCollapsed}>
|
||||
<div key="logo-button" className="logo-button-container">
|
||||
<div className="logo-button-spacer" />
|
||||
<div className="logo-button" onClick={this.openSidebar}>
|
||||
<div className="logo-button" onClick={this.openMainSidebar}>
|
||||
<img src="public/logos/wave-logo.png" alt="logo" />
|
||||
</div>
|
||||
</div>
|
||||
</If>
|
||||
<If condition={GlobalModel.isDev && rightSidebarCollapsed && activeMainView == "session"}>
|
||||
<div className="right-sidebar-triggers">
|
||||
<Button className="secondary ghost right-sidebar-trigger" onClick={this.openRightSidebar}>
|
||||
<i className="fa-sharp fa-regular fa-lightbulb"></i>
|
||||
</Button>
|
||||
</div>
|
||||
</If>
|
||||
<div ref={this.mainContentRef} className="main-content">
|
||||
<MainSideBar parentRef={this.mainContentRef} clientData={clientData} />
|
||||
<ErrorBoundary>
|
||||
@@ -137,6 +160,7 @@ class App extends React.Component<{}, {}> {
|
||||
<ConnectionsView model={remotesModel} />
|
||||
<ClientSettingsView model={remotesModel} />
|
||||
</ErrorBoundary>
|
||||
<RightSideBar parentRef={this.mainContentRef} clientData={clientData} />
|
||||
</div>
|
||||
<ModalsProvider />
|
||||
</div>
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
font: inherit;
|
||||
cursor: pointer;
|
||||
outline: inherit;
|
||||
|
||||
display: flex;
|
||||
padding: 6px 16px;
|
||||
align-items: center;
|
||||
@@ -15,7 +14,8 @@
|
||||
line-height: 1.5;
|
||||
|
||||
&.primary {
|
||||
background: none;
|
||||
color: var(--form-element-text-color);
|
||||
background: var(--form-element-primary-color);
|
||||
|
||||
i {
|
||||
fill: var(--form-element-primary-color);
|
||||
@@ -31,11 +31,12 @@
|
||||
}
|
||||
|
||||
&.outlined {
|
||||
background: none;
|
||||
border: 1px solid var(--form-element-primary-color);
|
||||
}
|
||||
|
||||
&.ghost {
|
||||
// Styles for .ghost are already defined above
|
||||
background: none;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
@@ -46,6 +47,9 @@
|
||||
&.secondary {
|
||||
color: var(--form-element-text-color);
|
||||
background: none;
|
||||
color: var(--form-element-text-color);
|
||||
background: var(--form-element-secondary-color);
|
||||
box-shadow: none;
|
||||
|
||||
&.solid {
|
||||
color: var(--form-element-text-color);
|
||||
@@ -54,10 +58,12 @@
|
||||
}
|
||||
|
||||
&.outlined {
|
||||
background: none;
|
||||
border: 1px solid var(--form-element-secondary-color);
|
||||
}
|
||||
|
||||
&.ghost {
|
||||
background: none;
|
||||
padding: 6px 10px;
|
||||
|
||||
i {
|
||||
|
||||
@@ -1,24 +1,15 @@
|
||||
// Copyright 2023, Command Line Inc.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import * as React from "react";
|
||||
import { boundMethod } from "autobind-decorator";
|
||||
import cn from "classnames";
|
||||
|
||||
import "./button.less";
|
||||
|
||||
type ButtonVariantType = "outlined" | "solid" | "ghost";
|
||||
type ButtonThemeType = "primary" | "secondary";
|
||||
|
||||
interface ButtonProps {
|
||||
theme?: ButtonThemeType;
|
||||
children: React.ReactNode;
|
||||
onClick?: () => void;
|
||||
disabled?: boolean;
|
||||
variant?: ButtonVariantType;
|
||||
leftIcon?: React.ReactNode;
|
||||
rightIcon?: React.ReactNode;
|
||||
color?: string;
|
||||
style?: React.CSSProperties;
|
||||
autoFocus?: boolean;
|
||||
className?: string;
|
||||
@@ -27,10 +18,8 @@ interface ButtonProps {
|
||||
|
||||
class Button extends React.Component<ButtonProps> {
|
||||
static defaultProps = {
|
||||
theme: "primary",
|
||||
variant: "solid",
|
||||
color: "",
|
||||
style: {},
|
||||
className: "primary",
|
||||
};
|
||||
|
||||
@boundMethod
|
||||
@@ -41,31 +30,11 @@ class Button extends React.Component<ButtonProps> {
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
leftIcon,
|
||||
rightIcon,
|
||||
theme,
|
||||
children,
|
||||
disabled,
|
||||
variant,
|
||||
color,
|
||||
style,
|
||||
autoFocus,
|
||||
termInline,
|
||||
className,
|
||||
} = this.props;
|
||||
const { leftIcon, rightIcon, children, disabled, style, autoFocus, termInline, className } = this.props;
|
||||
|
||||
return (
|
||||
<button
|
||||
className={cn(
|
||||
"wave-button",
|
||||
theme,
|
||||
variant,
|
||||
color,
|
||||
{ disabled: disabled },
|
||||
{ "term-inline": termInline },
|
||||
className
|
||||
)}
|
||||
className={cn("wave-button", { disabled }, { "term-inline": termInline }, className)}
|
||||
onClick={this.handleClick}
|
||||
disabled={disabled}
|
||||
style={style}
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
// Copyright 2023, Command Line Inc.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import * as React from "react";
|
||||
import { Button } from "./button";
|
||||
class IconButton extends Button {
|
||||
render() {
|
||||
const { children, theme, variant = "solid", ...rest } = this.props;
|
||||
const className = `wave-button icon-button ${theme} ${variant}`;
|
||||
|
||||
return (
|
||||
<button {...rest} className={className}>
|
||||
{children}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default IconButton;
|
||||
|
||||
export { IconButton };
|
||||
@@ -3,7 +3,6 @@ export { Checkbox } from "./checkbox";
|
||||
export { CmdStrCode } from "./cmdstrcode";
|
||||
export { renderCmdText } from "./cmdtext";
|
||||
export { Dropdown } from "./dropdown";
|
||||
export { IconButton } from "./iconbutton";
|
||||
export { InlineSettingsTextEdit } from "./inlinesettingstextedit";
|
||||
export { InputDecoration } from "./inputdecoration";
|
||||
export { LinkButton } from "./linkbutton";
|
||||
|
||||
@@ -6,7 +6,6 @@ import * as mobx from "mobx";
|
||||
import { If } from "tsx-control-statements/components";
|
||||
import ReactDOM from "react-dom";
|
||||
import { Button } from "./button";
|
||||
import { IconButton } from "./iconbutton";
|
||||
|
||||
import "./modal.less";
|
||||
|
||||
@@ -19,9 +18,9 @@ const ModalHeader: React.FC<ModalHeaderProps> = ({ onClose, title }) => (
|
||||
<div className="wave-modal-header">
|
||||
{<div className="wave-modal-title">{title}</div>}
|
||||
<If condition={onClose}>
|
||||
<IconButton theme="secondary" variant="ghost" onClick={onClose}>
|
||||
<Button className="secondary ghost" onClick={onClose}>
|
||||
<i className="fa-sharp fa-solid fa-xmark"></i>
|
||||
</IconButton>
|
||||
</Button>
|
||||
</If>
|
||||
</div>
|
||||
);
|
||||
@@ -36,11 +35,15 @@ interface ModalFooterProps {
|
||||
const ModalFooter: React.FC<ModalFooterProps> = ({ onCancel, onOk, cancelLabel = "Cancel", okLabel = "Ok" }) => (
|
||||
<div className="wave-modal-footer">
|
||||
{onCancel && (
|
||||
<Button theme="secondary" onClick={onCancel}>
|
||||
<Button className="secondary" onClick={onCancel}>
|
||||
{cancelLabel}
|
||||
</Button>
|
||||
)}
|
||||
{onOk && <Button onClick={onOk}>{okLabel}</Button>}
|
||||
{onOk && (
|
||||
<Button className="primary" onClick={onOk}>
|
||||
{okLabel}
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ import * as mobxReact from "mobx-react";
|
||||
import * as mobx from "mobx";
|
||||
import { boundMethod } from "autobind-decorator";
|
||||
import cn from "classnames";
|
||||
import { GlobalModel, GlobalCommandRunner } from "@/models";
|
||||
import { GlobalCommandRunner, SidebarModel } from "@/models";
|
||||
import { MagicLayout } from "@/app/magiclayout";
|
||||
|
||||
import "./resizablesidebar.less";
|
||||
@@ -14,6 +14,7 @@ import "./resizablesidebar.less";
|
||||
interface ResizableSidebarProps {
|
||||
parentRef: React.RefObject<HTMLElement>;
|
||||
position: "left" | "right";
|
||||
model: SidebarModel;
|
||||
enableSnap?: boolean;
|
||||
className?: string;
|
||||
children?: (toggleCollapsed: () => void) => React.ReactNode;
|
||||
@@ -32,7 +33,7 @@ class ResizableSidebar extends React.Component<ResizableSidebarProps> {
|
||||
startResizing(event: React.MouseEvent<HTMLDivElement>) {
|
||||
event.preventDefault();
|
||||
|
||||
const { parentRef, position } = this.props;
|
||||
const { parentRef, position, model } = this.props;
|
||||
const parentRect = parentRef.current?.getBoundingClientRect();
|
||||
|
||||
if (!parentRect) return;
|
||||
@@ -43,17 +44,16 @@ class ResizableSidebar extends React.Component<ResizableSidebarProps> {
|
||||
this.startX = event.clientX - parentRect.left;
|
||||
}
|
||||
|
||||
const mainSidebarModel = GlobalModel.mainSidebarModel;
|
||||
const collapsed = mainSidebarModel.getCollapsed();
|
||||
const collapsed = model.getCollapsed();
|
||||
|
||||
this.resizeStartWidth = mainSidebarModel.getWidth();
|
||||
this.resizeStartWidth = model.getWidth();
|
||||
document.addEventListener("mousemove", this.onMouseMove);
|
||||
document.addEventListener("mouseup", this.stopResizing);
|
||||
|
||||
document.body.style.cursor = "col-resize";
|
||||
mobx.action(() => {
|
||||
mainSidebarModel.setTempWidthAndTempCollapsed(this.resizeStartWidth, collapsed);
|
||||
mainSidebarModel.isDragging.set(true);
|
||||
model.setTempWidthAndTempCollapsed(this.resizeStartWidth, collapsed);
|
||||
model.isDragging.set(true);
|
||||
})();
|
||||
}
|
||||
|
||||
@@ -61,11 +61,10 @@ class ResizableSidebar extends React.Component<ResizableSidebarProps> {
|
||||
onMouseMove(event: MouseEvent) {
|
||||
event.preventDefault();
|
||||
|
||||
const { parentRef, enableSnap, position } = this.props;
|
||||
const { parentRef, enableSnap, position, model } = this.props;
|
||||
const parentRect = parentRef.current?.getBoundingClientRect();
|
||||
const mainSidebarModel = GlobalModel.mainSidebarModel;
|
||||
|
||||
if (!mainSidebarModel.isDragging.get() || !parentRect) return;
|
||||
if (!model.isDragging.get() || !parentRect) return;
|
||||
|
||||
let delta: number, newWidth: number;
|
||||
|
||||
@@ -100,34 +99,27 @@ class ResizableSidebar extends React.Component<ResizableSidebarProps> {
|
||||
|
||||
if (newWidth - dragResistance > minWidth && newWidth < snapPoint && dragDirection == "+") {
|
||||
newWidth = snapPoint;
|
||||
mainSidebarModel.setTempWidthAndTempCollapsed(newWidth, false);
|
||||
model.setTempWidthAndTempCollapsed(newWidth, false);
|
||||
} else if (newWidth + dragResistance < snapPoint && dragDirection == "-") {
|
||||
newWidth = minWidth;
|
||||
mainSidebarModel.setTempWidthAndTempCollapsed(newWidth, true);
|
||||
model.setTempWidthAndTempCollapsed(newWidth, true);
|
||||
} else if (newWidth > snapPoint) {
|
||||
mainSidebarModel.setTempWidthAndTempCollapsed(newWidth, false);
|
||||
model.setTempWidthAndTempCollapsed(newWidth, false);
|
||||
}
|
||||
} else {
|
||||
if (newWidth <= MagicLayout.MainSidebarMinWidth) {
|
||||
mainSidebarModel.setTempWidthAndTempCollapsed(newWidth, true);
|
||||
model.setTempWidthAndTempCollapsed(newWidth, true);
|
||||
} else {
|
||||
mainSidebarModel.setTempWidthAndTempCollapsed(newWidth, false);
|
||||
model.setTempWidthAndTempCollapsed(newWidth, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@boundMethod
|
||||
stopResizing() {
|
||||
let mainSidebarModel = GlobalModel.mainSidebarModel;
|
||||
const { model } = this.props;
|
||||
|
||||
GlobalCommandRunner.clientSetSidebar(
|
||||
mainSidebarModel.tempWidth.get(),
|
||||
mainSidebarModel.tempCollapsed.get()
|
||||
).finally(() => {
|
||||
mobx.action(() => {
|
||||
mainSidebarModel.isDragging.set(false);
|
||||
})();
|
||||
});
|
||||
model.saveState(model.tempWidth.get(), model.tempCollapsed.get());
|
||||
|
||||
document.removeEventListener("mousemove", this.onMouseMove);
|
||||
document.removeEventListener("mouseup", this.stopResizing);
|
||||
@@ -136,19 +128,18 @@ class ResizableSidebar extends React.Component<ResizableSidebarProps> {
|
||||
|
||||
@boundMethod
|
||||
toggleCollapsed() {
|
||||
const mainSidebarModel = GlobalModel.mainSidebarModel;
|
||||
const { model } = this.props;
|
||||
|
||||
const tempCollapsed = mainSidebarModel.getCollapsed();
|
||||
const width = mainSidebarModel.getWidth(true);
|
||||
mainSidebarModel.setTempWidthAndTempCollapsed(width, !tempCollapsed);
|
||||
GlobalCommandRunner.clientSetSidebar(width, !tempCollapsed);
|
||||
const tempCollapsed = model.getCollapsed();
|
||||
const width = model.getWidth(true);
|
||||
model.setTempWidthAndTempCollapsed(width, !tempCollapsed);
|
||||
model.saveState(width, !tempCollapsed);
|
||||
}
|
||||
|
||||
render() {
|
||||
const { className, children } = this.props;
|
||||
const mainSidebarModel = GlobalModel.mainSidebarModel;
|
||||
const width = mainSidebarModel.getWidth();
|
||||
const isCollapsed = mainSidebarModel.getCollapsed();
|
||||
const { className, children, model } = this.props;
|
||||
const width = model.getWidth();
|
||||
const isCollapsed = model.getCollapsed();
|
||||
|
||||
return (
|
||||
<div className={cn("sidebar", className, { collapsed: isCollapsed })} style={{ width, minWidth: width }}>
|
||||
|
||||
@@ -54,7 +54,7 @@ class AlertModal extends React.Component<{}, {}> {
|
||||
</div>
|
||||
<div className="wave-modal-footer">
|
||||
<If condition={isConfirm}>
|
||||
<Button theme="secondary" onClick={this.closeModal}>
|
||||
<Button className="secondary" onClick={this.closeModal}>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button autoFocus={true} onClick={this.handleOK}>
|
||||
|
||||
@@ -31,7 +31,7 @@ class ClientStopModal extends React.Component<{}, {}> {
|
||||
</If>
|
||||
<div>
|
||||
<Button
|
||||
theme="secondary"
|
||||
className="secondary"
|
||||
onClick={this.refreshClient}
|
||||
leftIcon={<i className="fa-sharp fa-solid fa-rotate"></i>}
|
||||
>
|
||||
|
||||
@@ -75,7 +75,7 @@ class DisconnectedModal extends React.Component<{}, {}> {
|
||||
</div>
|
||||
<div className="wave-modal-footer">
|
||||
<Button
|
||||
theme="secondary"
|
||||
className="secondary"
|
||||
onClick={this.tryReconnect}
|
||||
leftIcon={
|
||||
<span className="icon">
|
||||
@@ -86,7 +86,7 @@ class DisconnectedModal extends React.Component<{}, {}> {
|
||||
Try Reconnect
|
||||
</Button>
|
||||
<Button
|
||||
theme="secondary"
|
||||
className="secondary"
|
||||
onClick={this.restartServer}
|
||||
leftIcon={<i className="fa-sharp fa-solid fa-triangle-exclamation"></i>}
|
||||
>
|
||||
|
||||
@@ -162,42 +162,42 @@ class ViewRemoteConnDetailModal extends React.Component<{}, {}> {
|
||||
renderHeaderBtns(remote: RemoteType): React.ReactNode {
|
||||
let buttons: React.ReactNode[] = [];
|
||||
const disconnectButton = (
|
||||
<Button theme="secondary" onClick={() => this.disconnectRemote(remote.remoteid)}>
|
||||
<Button className="secondary" onClick={() => this.disconnectRemote(remote.remoteid)}>
|
||||
Disconnect Now
|
||||
</Button>
|
||||
);
|
||||
const connectButton = (
|
||||
<Button theme="secondary" onClick={() => this.connectRemote(remote.remoteid)}>
|
||||
<Button className="secondary" onClick={() => this.connectRemote(remote.remoteid)}>
|
||||
Connect Now
|
||||
</Button>
|
||||
);
|
||||
const tryReconnectButton = (
|
||||
<Button theme="secondary" onClick={() => this.connectRemote(remote.remoteid)}>
|
||||
<Button className="secondary" onClick={() => this.connectRemote(remote.remoteid)}>
|
||||
Try Reconnect
|
||||
</Button>
|
||||
);
|
||||
let updateAuthButton = (
|
||||
<Button theme="secondary" onClick={() => this.openEditModal()}>
|
||||
<Button className="secondary" onClick={() => this.openEditModal()}>
|
||||
Edit
|
||||
</Button>
|
||||
);
|
||||
let cancelInstallButton = (
|
||||
<Button theme="secondary" onClick={() => this.cancelInstall(remote.remoteid)}>
|
||||
<Button className="secondary" onClick={() => this.cancelInstall(remote.remoteid)}>
|
||||
Cancel Install
|
||||
</Button>
|
||||
);
|
||||
let installNowButton = (
|
||||
<Button theme="secondary" onClick={() => this.installRemote(remote.remoteid)}>
|
||||
<Button className="secondary" onClick={() => this.installRemote(remote.remoteid)}>
|
||||
Install Now
|
||||
</Button>
|
||||
);
|
||||
let archiveButton = (
|
||||
<Button theme="secondary" onClick={() => this.clickArchive()}>
|
||||
<Button className="secondary" onClick={() => this.clickArchive()}>
|
||||
Delete
|
||||
</Button>
|
||||
);
|
||||
const reinstallButton = (
|
||||
<Button theme="secondary" onClick={this.clickReinstall}>
|
||||
<Button className="secondary" onClick={this.clickReinstall}>
|
||||
Reinstall
|
||||
</Button>
|
||||
);
|
||||
@@ -207,7 +207,7 @@ class ViewRemoteConnDetailModal extends React.Component<{}, {}> {
|
||||
}
|
||||
if (remote.sshconfigsrc == "sshconfig-import") {
|
||||
archiveButton = (
|
||||
<Button theme="secondary" onClick={() => this.clickArchive()}>
|
||||
<Button className="secondary" onClick={() => this.clickArchive()}>
|
||||
Delete
|
||||
<Tooltip
|
||||
message={
|
||||
@@ -383,7 +383,7 @@ class ViewRemoteConnDetailModal extends React.Component<{}, {}> {
|
||||
</div>
|
||||
<div className="wave-modal-footer">
|
||||
<Button
|
||||
theme="secondary"
|
||||
className="secondary"
|
||||
disabled={selectedRemoteStatus == "connecting"}
|
||||
onClick={this.handleClose}
|
||||
>
|
||||
|
||||
@@ -180,14 +180,14 @@ class ConnectionsView extends React.Component<{ model: RemotesModel }, { hovered
|
||||
</table>
|
||||
<footer>
|
||||
<Button
|
||||
theme="secondary"
|
||||
className="secondary"
|
||||
leftIcon={<i className="fa-sharp fa-solid fa-plus"></i>}
|
||||
onClick={this.handleAddConnection}
|
||||
>
|
||||
New Connection
|
||||
</Button>
|
||||
<Button
|
||||
theme="secondary"
|
||||
className="secondary"
|
||||
leftIcon={<i className="fa-sharp fa-solid fa-fw fa-file-import"></i>}
|
||||
onClick={this.handleImportSshConfig}
|
||||
>
|
||||
|
||||
@@ -16,11 +16,17 @@ let MagicLayout = {
|
||||
ScreenSidebarMinWidth: 200,
|
||||
ScreenSidebarHeaderHeight: 26,
|
||||
|
||||
MainSidebarMinWidth: 75,
|
||||
MainSidebarMinWidth: 0,
|
||||
MainSidebarMaxWidth: 300,
|
||||
MainSidebarSnapThreshold: 90,
|
||||
MainSidebarSnapThreshold: 165,
|
||||
MainSidebarDragResistance: 50,
|
||||
MainSidebarDefaultWidth: 240,
|
||||
|
||||
RightSidebarMinWidth: 0,
|
||||
RightSidebarMaxWidth: 300,
|
||||
RightSidebarSnapThreshold: 90,
|
||||
RightSidebarDragResistance: 50,
|
||||
RightSidebarDefaultWidth: 240,
|
||||
};
|
||||
|
||||
let m = MagicLayout;
|
||||
|
||||
@@ -21,7 +21,7 @@ import { isBlank, openLink } from "@/util/util";
|
||||
import { ResizableSidebar } from "@/common/elements";
|
||||
import * as appconst from "@/app/appconst";
|
||||
|
||||
import "./sidebar.less";
|
||||
import "./main.less";
|
||||
import { ActionsIcon, CenteredIcon, FrontIcon, StatusIndicator } from "@/common/icons/icons";
|
||||
|
||||
dayjs.extend(localizedFormat);
|
||||
@@ -251,6 +251,7 @@ class MainSideBar extends React.Component<MainSideBarProps, {}> {
|
||||
render() {
|
||||
return (
|
||||
<ResizableSidebar
|
||||
model={GlobalModel.mainSidebarModel}
|
||||
className="main-sidebar"
|
||||
position="left"
|
||||
enableSnap={true}
|
||||
@@ -0,0 +1,28 @@
|
||||
@import "@/common/icons/icons.less";
|
||||
|
||||
.right-sidebar {
|
||||
padding: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
position: relative;
|
||||
line-height: 20px;
|
||||
backdrop-filter: blur(4px);
|
||||
z-index: 20;
|
||||
font-size: var(--sidebar-font-size);
|
||||
font-family: var(--base-font-family);
|
||||
font-weight: var(--sidebar-font-weight);
|
||||
border-left: 1px solid var(--app-border-color);
|
||||
|
||||
.header {
|
||||
height: 39px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
padding: 0 5px;
|
||||
border-bottom: 1px solid var(--app-border-color);
|
||||
}
|
||||
|
||||
&.collapsed {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
// Copyright 2023, Command Line Inc.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import * as React from "react";
|
||||
import * as mobxReact from "mobx-react";
|
||||
import dayjs from "dayjs";
|
||||
|
||||
import localizedFormat from "dayjs/plugin/localizedFormat";
|
||||
import { GlobalModel } from "@/models";
|
||||
import { ResizableSidebar, Button } from "@/elements";
|
||||
|
||||
import "./right.less";
|
||||
|
||||
dayjs.extend(localizedFormat);
|
||||
|
||||
interface RightSideBarProps {
|
||||
parentRef: React.RefObject<HTMLElement>;
|
||||
clientData: ClientDataType;
|
||||
}
|
||||
|
||||
@mobxReact.observer
|
||||
class RightSideBar extends React.Component<RightSideBarProps, {}> {
|
||||
render() {
|
||||
return (
|
||||
<ResizableSidebar
|
||||
model={GlobalModel.rightSidebarModel}
|
||||
className="right-sidebar"
|
||||
position="right"
|
||||
enableSnap={true}
|
||||
parentRef={this.props.parentRef}
|
||||
>
|
||||
{(toggleCollapse) => (
|
||||
<React.Fragment>
|
||||
<div className="header">
|
||||
<Button className="secondary ghost" onClick={toggleCollapse}>
|
||||
<i className="fa-sharp fa-regular fa-xmark"></i>
|
||||
</Button>
|
||||
</div>
|
||||
</React.Fragment>
|
||||
)}
|
||||
</ResizableSidebar>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export { RightSideBar };
|
||||
@@ -325,7 +325,7 @@ class ScreenSidebar extends React.Component<{ screen: Screen; width: string }, {
|
||||
<br />
|
||||
</div>
|
||||
<div onClick={this.sidebarClose} className="close-button-container">
|
||||
<Button theme="secondary" onClick={this.sidebarClose}>
|
||||
<Button className="secondary" onClick={this.sidebarClose}>
|
||||
Close Sidebar
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user