mirror of
https://github.com/wavetermdev/backup.git
synced 2026-08-05 13:57:07 -07:00
connections screen and modals (#69)
* init * connections table * view styles * new components. header and status. * action buttons * use Button component in other modals * hook add connection button * RemoteConnDetailModal component * refactor remotes model. read connection modal. * remote conn detail modal layout and styles * fix xterm styles * use correct status message in xterm * tone down color of settings input * clean up * edit remote conn modal * fix buttons gap * change button label * archive and force install features * use classnames * add some class names and also set some widths / maxwidth for the table. too hard to read on large screens. * small style updates * fix some typescript errors, other small fixups * fix type error * move add button to the bottom of the table * more improvements * adjust layout, behavior, and style accrdg to mike's feedback * set table max-width in css * open detail modal after creation of new remote * update some working (remote -> connection). fix typescript error in connections. remove some console.logs * fix a couple of mobx warnings (need to wrap in action)
This commit is contained in:
+38
-15
@@ -49,6 +49,14 @@ textarea {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.text-primary {
|
||||||
|
font-size: 15px;
|
||||||
|
font-weight: 500;
|
||||||
|
line-height: 20px;
|
||||||
|
font-family: @text-s1-font;
|
||||||
|
color: @text-primary;
|
||||||
|
}
|
||||||
|
|
||||||
.text-standard {
|
.text-standard {
|
||||||
font-size: 12.5px;
|
font-size: 12.5px;
|
||||||
font-weight: 300;
|
font-weight: 300;
|
||||||
@@ -219,7 +227,8 @@ a.a-block {
|
|||||||
|
|
||||||
.history-view,
|
.history-view,
|
||||||
.bookmarks-view,
|
.bookmarks-view,
|
||||||
.plugins-view {
|
.plugins-view,
|
||||||
|
.connections-view {
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@@ -465,85 +474,99 @@ a.a-block {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.icon.color-red {
|
.icon.color-red {
|
||||||
path, circle {
|
path,
|
||||||
|
circle {
|
||||||
fill: @tab-red;
|
fill: @tab-red;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.icon.color-green {
|
.icon.color-green {
|
||||||
path, circle {
|
path,
|
||||||
|
circle {
|
||||||
fill: @tab-green;
|
fill: @tab-green;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.icon.color-orange {
|
.icon.color-orange {
|
||||||
path, circle {
|
path,
|
||||||
|
circle {
|
||||||
fill: @tab-orange;
|
fill: @tab-orange;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.icon.color-blue {
|
.icon.color-blue {
|
||||||
path, circle {
|
path,
|
||||||
|
circle {
|
||||||
fill: @tab-blue;
|
fill: @tab-blue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.icon.color-yellow {
|
.icon.color-yellow {
|
||||||
path, circle {
|
path,
|
||||||
|
circle {
|
||||||
fill: @tab-yellow;
|
fill: @tab-yellow;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.icon.color-pink {
|
.icon.color-pink {
|
||||||
path, circle {
|
path,
|
||||||
|
circle {
|
||||||
fill: @tab-pink;
|
fill: @tab-pink;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.icon.color-mint {
|
.icon.color-mint {
|
||||||
path, circle {
|
path,
|
||||||
|
circle {
|
||||||
fill: @tab-mint;
|
fill: @tab-mint;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.icon.color-cyan {
|
.icon.color-cyan {
|
||||||
path, circle {
|
path,
|
||||||
|
circle {
|
||||||
fill: @tab-cyan;
|
fill: @tab-cyan;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.icon.color-violet {
|
.icon.color-violet {
|
||||||
path, circle {
|
path,
|
||||||
|
circle {
|
||||||
fill: @tab-violet;
|
fill: @tab-violet;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.icon.color-white {
|
.icon.color-white {
|
||||||
path, circle {
|
path,
|
||||||
|
circle {
|
||||||
fill: @tab-white;
|
fill: @tab-white;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.status-icon.status-connected {
|
.status-icon.status-connected {
|
||||||
path, circle {
|
path,
|
||||||
|
circle {
|
||||||
fill: @status-connected;
|
fill: @status-connected;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.status-icon.status-connecting {
|
.status-icon.status-connecting {
|
||||||
path, circle {
|
path,
|
||||||
|
circle {
|
||||||
fill: @status-connecting;
|
fill: @status-connecting;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.status-icon.status-disconnected {
|
.status-icon.status-disconnected {
|
||||||
path, circle {
|
path,
|
||||||
|
circle {
|
||||||
fill: @status-disconnected;
|
fill: @status-disconnected;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.status-icon.status-error {
|
.status-icon.status-error {
|
||||||
path, circle {
|
path,
|
||||||
|
circle {
|
||||||
fill: @status-error;
|
fill: @status-error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+28
-8
@@ -15,13 +15,14 @@ import { WorkspaceView } from "./workspace/workspaceview";
|
|||||||
import { PluginsView } from "./pluginsview/pluginsview";
|
import { PluginsView } from "./pluginsview/pluginsview";
|
||||||
import { BookmarksView } from "./bookmarks/bookmarks";
|
import { BookmarksView } from "./bookmarks/bookmarks";
|
||||||
import { HistoryView } from "./history/history";
|
import { HistoryView } from "./history/history";
|
||||||
|
import { ConnectionsView } from "./connections/connections";
|
||||||
import {
|
import {
|
||||||
ScreenSettingsModal,
|
ScreenSettingsModal,
|
||||||
SessionSettingsModal,
|
SessionSettingsModal,
|
||||||
LineSettingsModal,
|
LineSettingsModal,
|
||||||
ClientSettingsModal,
|
ClientSettingsModal,
|
||||||
} from "./common/modals/settings";
|
} from "./common/modals/settings";
|
||||||
import { RemotesModal } from "./connections/connections";
|
import { RemotesModal } from "./connections_deprecated/connections";
|
||||||
import { TosModal } from "./common/modals/modals";
|
import { TosModal } from "./common/modals/modals";
|
||||||
import { MainSideBar } from "./sidebar/sidebar";
|
import { MainSideBar } from "./sidebar/sidebar";
|
||||||
import {
|
import {
|
||||||
@@ -30,6 +31,8 @@ import {
|
|||||||
AlertModal,
|
AlertModal,
|
||||||
AboutModal,
|
AboutModal,
|
||||||
CreateRemoteConnModal,
|
CreateRemoteConnModal,
|
||||||
|
ViewRemoteConnDetailModal,
|
||||||
|
EditRemoteConnModal,
|
||||||
} from "./common/modals/modals";
|
} from "./common/modals/modals";
|
||||||
import { ErrorBoundary } from "./common/error/errorboundary";
|
import { ErrorBoundary } from "./common/error/errorboundary";
|
||||||
import "./app.less";
|
import "./app.less";
|
||||||
@@ -85,14 +88,17 @@ class App extends React.Component<{}, {}> {
|
|||||||
let sessionSettingsModal = GlobalModel.sessionSettingsModal.get();
|
let sessionSettingsModal = GlobalModel.sessionSettingsModal.get();
|
||||||
let lineSettingsModal = GlobalModel.lineSettingsModal.get();
|
let lineSettingsModal = GlobalModel.lineSettingsModal.get();
|
||||||
let clientSettingsModal = GlobalModel.clientSettingsModal.get();
|
let clientSettingsModal = GlobalModel.clientSettingsModal.get();
|
||||||
let remotesModel = GlobalModel.remotesModalModel;
|
let remotesModel = GlobalModel.remotesModel;
|
||||||
let remotesModal = remotesModel.isOpen();
|
let remotesModalMode = remotesModel.modalMode.get();
|
||||||
let selectedRemoteId = remotesModel.selectedRemoteId.get();
|
let selectedRemoteId = remotesModel.selectedRemoteId.get();
|
||||||
|
let selectedRemote = GlobalModel.getRemote(selectedRemoteId);
|
||||||
|
let isAuthEditMode = remotesModel.isAuthEditMode();
|
||||||
let remoteEdit = remotesModel.remoteEdit.get();
|
let remoteEdit = remotesModel.remoteEdit.get();
|
||||||
let disconnected = !GlobalModel.ws.open.get() || !GlobalModel.waveSrvRunning.get();
|
let disconnected = !GlobalModel.ws.open.get() || !GlobalModel.waveSrvRunning.get();
|
||||||
let hasClientStop = GlobalModel.getHasClientStop();
|
let hasClientStop = GlobalModel.getHasClientStop();
|
||||||
let dcWait = this.dcWait.get();
|
let dcWait = this.dcWait.get();
|
||||||
let platform = GlobalModel.getPlatform();
|
let platform = GlobalModel.getPlatform();
|
||||||
|
|
||||||
if (disconnected || hasClientStop) {
|
if (disconnected || hasClientStop) {
|
||||||
if (!dcWait) {
|
if (!dcWait) {
|
||||||
setTimeout(() => this.updateDcWait(true), 1500);
|
setTimeout(() => this.updateDcWait(true), 1500);
|
||||||
@@ -117,7 +123,6 @@ class App extends React.Component<{}, {}> {
|
|||||||
if (dcWait) {
|
if (dcWait) {
|
||||||
setTimeout(() => this.updateDcWait(false), 0);
|
setTimeout(() => this.updateDcWait(false), 0);
|
||||||
}
|
}
|
||||||
//console.log(`GlobalModel.activeMainView.get() = ${GlobalModel.activeMainView.get()}`); // @mike - if I remove this, I cant see plugins
|
|
||||||
return (
|
return (
|
||||||
<div id="main" className={"platform-" + platform} onContextMenu={this.handleContextMenu}>
|
<div id="main" className={"platform-" + platform} onContextMenu={this.handleContextMenu}>
|
||||||
<div className="main-content">
|
<div className="main-content">
|
||||||
@@ -127,6 +132,7 @@ class App extends React.Component<{}, {}> {
|
|||||||
<WorkspaceView />
|
<WorkspaceView />
|
||||||
<HistoryView />
|
<HistoryView />
|
||||||
<BookmarksView />
|
<BookmarksView />
|
||||||
|
<ConnectionsView model={remotesModel} />
|
||||||
</ErrorBoundary>
|
</ErrorBoundary>
|
||||||
</div>
|
</div>
|
||||||
<AlertModal />
|
<AlertModal />
|
||||||
@@ -136,9 +142,26 @@ class App extends React.Component<{}, {}> {
|
|||||||
<If condition={GlobalModel.aboutModalOpen.get()}>
|
<If condition={GlobalModel.aboutModalOpen.get()}>
|
||||||
<AboutModal />
|
<AboutModal />
|
||||||
</If>
|
</If>
|
||||||
<If condition={remoteEdit !== null && !remoteEdit.old}>
|
<If condition={remoteEdit !== null && remotesModalMode === "add"}>
|
||||||
<CreateRemoteConnModal model={remotesModel} remoteEdit={remoteEdit} />
|
<CreateRemoteConnModal model={remotesModel} remoteEdit={remoteEdit} />
|
||||||
</If>
|
</If>
|
||||||
|
<If condition={selectedRemote != null}>
|
||||||
|
<If condition={!isAuthEditMode && remotesModalMode === "read"}>
|
||||||
|
<ViewRemoteConnDetailModal
|
||||||
|
key={"remotedetail-" + selectedRemoteId}
|
||||||
|
remote={selectedRemote}
|
||||||
|
model={remotesModel}
|
||||||
|
/>
|
||||||
|
</If>
|
||||||
|
<If condition={remoteEdit !== null && isAuthEditMode && remotesModalMode === "edit"}>
|
||||||
|
<EditRemoteConnModal
|
||||||
|
key={"remotedetail-" + selectedRemoteId}
|
||||||
|
remote={selectedRemote}
|
||||||
|
model={remotesModel}
|
||||||
|
remoteEdit={remoteEdit}
|
||||||
|
/>
|
||||||
|
</If>
|
||||||
|
</If>
|
||||||
<If condition={screenSettingsModal != null}>
|
<If condition={screenSettingsModal != null}>
|
||||||
<ScreenSettingsModal
|
<ScreenSettingsModal
|
||||||
key={screenSettingsModal.sessionId + ":" + screenSettingsModal.screenId}
|
key={screenSettingsModal.sessionId + ":" + screenSettingsModal.screenId}
|
||||||
@@ -155,9 +178,6 @@ class App extends React.Component<{}, {}> {
|
|||||||
<If condition={clientSettingsModal}>
|
<If condition={clientSettingsModal}>
|
||||||
<ClientSettingsModal />
|
<ClientSettingsModal />
|
||||||
</If>
|
</If>
|
||||||
<If condition={remotesModal}>
|
|
||||||
<RemotesModal model={GlobalModel.remotesModalModel} />
|
|
||||||
</If>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
+142
-28
@@ -257,33 +257,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.wave-button {
|
|
||||||
display: flex;
|
|
||||||
padding: 6px 16px !important;
|
|
||||||
color: @term-white !important;
|
|
||||||
align-items: center;
|
|
||||||
gap: 4px;
|
|
||||||
border-radius: 6px !important;
|
|
||||||
height: auto !important;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
color: @term-white !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.wave-button.is-wave-green {
|
|
||||||
color: @term-bright-white !important;
|
|
||||||
background: @term-green !important;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background-color: @term-green;
|
|
||||||
box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.4), 0px 0px 0.5px 0px rgba(0, 0, 0, 0.5),
|
|
||||||
0px 0px 0.5px 0px rgba(255, 255, 255, 0.8) inset, 0px 0.5px 0px 0px rgba(255, 255, 255, 0.6) inset;
|
|
||||||
color: @term-bright-white !important;
|
|
||||||
box-shadow: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.button.is-plain,
|
.button.is-plain,
|
||||||
.button.is-prompt-cancel {
|
.button.is-prompt-cancel {
|
||||||
background-color: #222;
|
background-color: #222;
|
||||||
@@ -637,7 +610,8 @@
|
|||||||
position: relative;
|
position: relative;
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
height: 44px;
|
height: 44px;
|
||||||
width: 412px;
|
min-width: 412px;
|
||||||
|
width: 100%;
|
||||||
border: 1px solid var(--element-separator, rgba(241, 246, 243, 0.15));
|
border: 1px solid var(--element-separator, rgba(241, 246, 243, 0.15));
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
background: var(--element-hover-2, rgba(255, 255, 255, 0.06));
|
background: var(--element-hover-2, rgba(255, 255, 255, 0.06));
|
||||||
@@ -801,10 +775,18 @@
|
|||||||
box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.4), 0px 0px 0.5px 0px rgba(0, 0, 0, 0.5),
|
box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.4), 0px 0px 0.5px 0px rgba(0, 0, 0, 0.5),
|
||||||
0px 0px 0.5px 0px rgba(255, 255, 255, 0.5) inset, 0px 0.5px 0px 0px rgba(255, 255, 255, 0.2) inset;
|
0px 0px 0.5px 0px rgba(255, 255, 255, 0.5) inset, 0px 0.5px 0px 0px rgba(255, 255, 255, 0.2) inset;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
cursor: text;
|
||||||
|
}
|
||||||
|
|
||||||
&.focused {
|
&.focused {
|
||||||
border-color: @term-green;
|
border-color: @term-green;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.disabled {
|
||||||
|
opacity: 0.75;
|
||||||
|
}
|
||||||
|
|
||||||
&.error {
|
&.error {
|
||||||
border-color: @term-red;
|
border-color: @term-red;
|
||||||
}
|
}
|
||||||
@@ -931,3 +913,135 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.wave-button {
|
||||||
|
background: none;
|
||||||
|
color: inherit;
|
||||||
|
border: none;
|
||||||
|
padding: 0;
|
||||||
|
font: inherit;
|
||||||
|
cursor: pointer;
|
||||||
|
outline: inherit;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
padding: 6px 16px;
|
||||||
|
align-items: center;
|
||||||
|
gap: 4px;
|
||||||
|
border-radius: 6px;
|
||||||
|
height: auto;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: @term-white;
|
||||||
|
}
|
||||||
|
|
||||||
|
i {
|
||||||
|
fill: rgba(255, 255, 255, 0.12);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.primary {
|
||||||
|
color: @term-green;
|
||||||
|
background: none;
|
||||||
|
|
||||||
|
i {
|
||||||
|
fill: @term-green;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.solid {
|
||||||
|
color: @term-bright-white;
|
||||||
|
background: @term-green;
|
||||||
|
box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.4), 0px 0px 0.5px 0px rgba(0, 0, 0, 0.5),
|
||||||
|
0px 0px 0.5px 0px rgba(255, 255, 255, 0.8) inset, 0px 0.5px 0px 0px rgba(255, 255, 255, 0.6) inset;
|
||||||
|
|
||||||
|
i {
|
||||||
|
fill: @term-white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.outlined {
|
||||||
|
border: 1px solid @term-green;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.ghost {
|
||||||
|
// Styles for .ghost are already defined above
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: @term-bright-white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.secondary {
|
||||||
|
color: @term-white;
|
||||||
|
background: none;
|
||||||
|
|
||||||
|
&.solid {
|
||||||
|
background: rgba(255, 255, 255, 0.09);
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.outlined {
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.09);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.ghost {
|
||||||
|
padding: 6px 10px;
|
||||||
|
|
||||||
|
i {
|
||||||
|
fill: @term-green;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.color-red {
|
||||||
|
&.solid {
|
||||||
|
border-color: @term-red;
|
||||||
|
background-color: mix(@term-red, @term-white, 50%);
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.outlined {
|
||||||
|
color: @term-red;
|
||||||
|
border-color: @term-red;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.ghost {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.disabled {
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.link-button {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.wave-status-container {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.dot {
|
||||||
|
height: 6px;
|
||||||
|
width: 6px;
|
||||||
|
border-radius: 50%;
|
||||||
|
display: inline-block;
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dot.green {
|
||||||
|
background-color: @status-connected;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dot.red {
|
||||||
|
background-color: @status-error;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dot.gray {
|
||||||
|
background-color: @status-disconnected;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dot.yellow {
|
||||||
|
background-color: @status-connecting;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
+139
-2
@@ -217,6 +217,112 @@ class Tooltip extends React.Component<TooltipProps, TooltipState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
class Button extends React.Component<ButtonProps> {
|
||||||
|
static defaultProps = {
|
||||||
|
theme: "primary",
|
||||||
|
variant: "solid",
|
||||||
|
color: "",
|
||||||
|
};
|
||||||
|
|
||||||
|
@boundMethod
|
||||||
|
handleClick() {
|
||||||
|
if (this.props.onClick && !this.props.disabled) {
|
||||||
|
this.props.onClick();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { leftIcon, rightIcon, theme, children, disabled, variant, color } = this.props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<button
|
||||||
|
className={cn("wave-button", theme, variant, color, { disabled: disabled })}
|
||||||
|
onClick={this.handleClick}
|
||||||
|
disabled={disabled}
|
||||||
|
>
|
||||||
|
{leftIcon && <span className="icon-left">{leftIcon}</span>}
|
||||||
|
{children}
|
||||||
|
{rightIcon && <span className="icon-right">{rightIcon}</span>}
|
||||||
|
</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;
|
||||||
|
|
||||||
|
interface LinkButtonProps extends ButtonProps {
|
||||||
|
href: string;
|
||||||
|
target?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
class LinkButton extends IconButton {
|
||||||
|
render() {
|
||||||
|
// @ts-ignore
|
||||||
|
const { href, target, leftIcon, rightIcon, children, theme, variant }: LinkButtonProps = this.props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<a href={href} target={target} className={`wave-button link-button`}>
|
||||||
|
<button {...this.props} className={`icon-button ${theme} ${variant}`}>
|
||||||
|
{leftIcon && <span className="icon-left">{leftIcon}</span>}
|
||||||
|
{children}
|
||||||
|
{rightIcon && <span className="icon-right">{rightIcon}</span>}
|
||||||
|
</button>
|
||||||
|
</a>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
interface StatusProps {
|
||||||
|
status: "green" | "red" | "gray" | "yellow";
|
||||||
|
text: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
class Status extends React.Component<StatusProps> {
|
||||||
|
@boundMethod
|
||||||
|
renderDot() {
|
||||||
|
const { status } = this.props;
|
||||||
|
|
||||||
|
return <div className={`dot ${status}`} />;
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { text } = this.props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="wave-status-container">
|
||||||
|
{this.renderDot()}
|
||||||
|
<span>{text}</span>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
interface TextFieldDecorationProps {
|
interface TextFieldDecorationProps {
|
||||||
startDecoration?: React.ReactNode;
|
startDecoration?: React.ReactNode;
|
||||||
endDecoration?: React.ReactNode;
|
endDecoration?: React.ReactNode;
|
||||||
@@ -232,6 +338,7 @@ interface TextFieldProps {
|
|||||||
required?: boolean;
|
required?: boolean;
|
||||||
maxLength?: number;
|
maxLength?: number;
|
||||||
autoFocus?: boolean;
|
autoFocus?: boolean;
|
||||||
|
disabled?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface TextFieldState {
|
interface TextFieldState {
|
||||||
@@ -267,6 +374,22 @@ class TextField extends React.Component<TextFieldProps, TextFieldState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Method to handle focus at the component level
|
||||||
|
@boundMethod
|
||||||
|
handleComponentFocus() {
|
||||||
|
if (this.inputRef.current && !this.inputRef.current.contains(document.activeElement)) {
|
||||||
|
this.inputRef.current.focus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Method to handle blur at the component level
|
||||||
|
@boundMethod
|
||||||
|
handleComponentBlur() {
|
||||||
|
if (this.inputRef.current && this.inputRef.current.contains(document.activeElement)) {
|
||||||
|
this.inputRef.current.blur();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@boundMethod
|
@boundMethod
|
||||||
handleFocus() {
|
handleFocus() {
|
||||||
this.setState({ focused: true });
|
this.setState({ focused: true });
|
||||||
@@ -311,14 +434,23 @@ class TextField extends React.Component<TextFieldProps, TextFieldState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { label, value, placeholder, decoration, className, maxLength, autoFocus } = this.props;
|
const { label, value, placeholder, decoration, className, maxLength, autoFocus, disabled } = this.props;
|
||||||
const { focused, internalValue, error } = this.state;
|
const { focused, internalValue, error } = this.state;
|
||||||
|
|
||||||
// Decide if the input should behave as controlled or uncontrolled
|
// Decide if the input should behave as controlled or uncontrolled
|
||||||
const inputValue = value !== undefined ? value : internalValue;
|
const inputValue = value !== undefined ? value : internalValue;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={cn(`wave-textfield ${className || ""}`, { focused: focused, error: error })}>
|
<div
|
||||||
|
className={cn(`wave-textfield ${className || ""}`, {
|
||||||
|
focused: focused,
|
||||||
|
error: error,
|
||||||
|
disabled: disabled,
|
||||||
|
})}
|
||||||
|
onFocus={this.handleComponentFocus}
|
||||||
|
onBlur={this.handleComponentBlur}
|
||||||
|
tabIndex={-1}
|
||||||
|
>
|
||||||
{decoration?.startDecoration && <>{decoration.startDecoration}</>}
|
{decoration?.startDecoration && <>{decoration.startDecoration}</>}
|
||||||
<div className="wave-textfield-inner">
|
<div className="wave-textfield-inner">
|
||||||
<label
|
<label
|
||||||
@@ -341,6 +473,7 @@ class TextField extends React.Component<TextFieldProps, TextFieldState> {
|
|||||||
placeholder={placeholder}
|
placeholder={placeholder}
|
||||||
maxLength={maxLength}
|
maxLength={maxLength}
|
||||||
autoFocus={autoFocus}
|
autoFocus={autoFocus}
|
||||||
|
disabled={disabled}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{decoration?.endDecoration && <>{decoration.endDecoration}</>}
|
{decoration?.endDecoration && <>{decoration.endDecoration}</>}
|
||||||
@@ -980,4 +1113,8 @@ export {
|
|||||||
NumberField,
|
NumberField,
|
||||||
PasswordField,
|
PasswordField,
|
||||||
Tooltip,
|
Tooltip,
|
||||||
|
Button,
|
||||||
|
IconButton,
|
||||||
|
LinkButton,
|
||||||
|
Status,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -460,7 +460,7 @@
|
|||||||
.action-buttons {
|
.action-buttons {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
||||||
div.button {
|
button:first-child {
|
||||||
margin-right: 8px;
|
margin-right: 8px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -468,29 +468,215 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.wave-button {
|
.wave-modal.rconndetail-modal {
|
||||||
display: flex;
|
.wave-modal-content.rconndetail-wave-modal-content {
|
||||||
padding: 6px 16px;
|
width: 631px;
|
||||||
align-items: center;
|
min-height: 565px;
|
||||||
gap: var(--sizing-2-xs, 4px);
|
overflow: visible;
|
||||||
border-radius: 6px;
|
|
||||||
height: auto;
|
.wave-modal-content-inner.rconndetail-wave-modal-content-inner {
|
||||||
|
display: flex;
|
||||||
|
padding-bottom: 0px;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
gap: 20px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
|
||||||
|
.rconndetail-wave-modal-body {
|
||||||
|
display: flex;
|
||||||
|
padding: 0px 20px;
|
||||||
|
align-items: flex-start;
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 16px;
|
||||||
|
align-self: stretch;
|
||||||
|
|
||||||
|
.name-header-actions-wrapper {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-start;
|
||||||
|
gap: 12px;
|
||||||
|
|
||||||
|
.rconndetail-name {
|
||||||
|
color: @term-bright-white;
|
||||||
|
font-size: 15px;
|
||||||
|
font-weight: 500;
|
||||||
|
line-height: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-actions {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
align-items: flex-start;
|
||||||
|
|
||||||
|
.wave-button {
|
||||||
|
padding: 4px 15px;
|
||||||
|
font-size: 11px;
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.remote-detail {
|
||||||
|
.settings-field {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.settings-label {
|
||||||
|
font-weight: bold;
|
||||||
|
width: 12em;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.settings-input {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
color: @term-white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.settings-field:not(:first-child) {
|
||||||
|
margin-top: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status {
|
||||||
|
display: flex;
|
||||||
|
height: 30px;
|
||||||
|
padding: 3px 8px;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
align-self: stretch;
|
||||||
|
border-radius: 6px;
|
||||||
|
background: rgba(241, 246, 243, 0.08);
|
||||||
|
}
|
||||||
|
|
||||||
|
.terminal-wrapper {
|
||||||
|
width: 100%;
|
||||||
|
margin-top: 5px;
|
||||||
|
|
||||||
|
.terminal-connectelem {
|
||||||
|
height: 163px !important; // Needed to override plugin height
|
||||||
|
|
||||||
|
.xterm-viewport {
|
||||||
|
display: flex;
|
||||||
|
padding: 6px 10px;
|
||||||
|
gap: 8px;
|
||||||
|
align-items: flex-start;
|
||||||
|
align-self: stretch;
|
||||||
|
border-radius: 6px;
|
||||||
|
border: 1px solid var(--element-separator, rgba(241, 246, 243, 0.15));
|
||||||
|
background: #080a08;
|
||||||
|
height: 163px !important; // Needed to override plugin height
|
||||||
|
}
|
||||||
|
|
||||||
|
.xterm-screen {
|
||||||
|
padding: 10px;
|
||||||
|
width: 541px !important; // Needed to override plugin width
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.rconndetail-wave-modal-footer {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
width: 100%;
|
||||||
|
padding: 0 20px 20px;
|
||||||
|
|
||||||
|
.action-buttons {
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
button:first-child {
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.wave-button.color-green {
|
.wave-modal.erconn-modal {
|
||||||
color: @term-bright-white;
|
.wave-modal-content.erconn-wave-modal-content {
|
||||||
background: @term-green !important; // !important is needed to override the default button color
|
width: 502px;
|
||||||
box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.4), 0px 0px 0.5px 0px rgba(0, 0, 0, 0.5),
|
min-height: 411px;
|
||||||
0px 0px 0.5px 0px rgba(255, 255, 255, 0.8) inset, 0px 0.5px 0px 0px rgba(255, 255, 255, 0.6) inset;
|
overflow: visible;
|
||||||
|
|
||||||
&:hover {
|
.wave-modal-content-inner.erconn-wave-modal-content-inner {
|
||||||
color: @term-bright-white;
|
display: flex;
|
||||||
|
padding-bottom: 0px;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
gap: 20px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
|
||||||
|
.erconn-wave-modal-body {
|
||||||
|
display: flex;
|
||||||
|
padding: 0px 20px;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-start;
|
||||||
|
gap: 12px;
|
||||||
|
align-self: stretch;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
> div {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.name-actions-section {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-start;
|
||||||
|
gap: 12px;
|
||||||
|
|
||||||
|
.name {
|
||||||
|
color: @term-bright-white;
|
||||||
|
font-size: 15px;
|
||||||
|
font-weight: 500;
|
||||||
|
line-height: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-actions {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
align-items: flex-start;
|
||||||
|
|
||||||
|
.wave-button {
|
||||||
|
padding: 4px 15px;
|
||||||
|
font-size: 11px;
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.erconn-wave-modal-footer {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
width: 100%;
|
||||||
|
padding: 0 20px 20px;
|
||||||
|
|
||||||
|
.action-buttons {
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
button:first-child {
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.wave-button.color-standard {
|
.wave-button.color-standard {
|
||||||
color: @term-white;
|
color: @term-white;
|
||||||
background: var(--overlays-white-6, rgba(255, 255, 255, 0.12));
|
background: rgba(255, 255, 255, 0.12);
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
color: @term-white;
|
color: @term-white;
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -10,7 +10,7 @@ import cn from "classnames";
|
|||||||
import { GlobalModel, GlobalCommandRunner, TabColors, MinFontSize, MaxFontSize } from "../../../model/model";
|
import { GlobalModel, GlobalCommandRunner, TabColors, MinFontSize, MaxFontSize } from "../../../model/model";
|
||||||
import { Toggle, InlineSettingsTextEdit, SettingsError, InfoMessage } from "../common";
|
import { Toggle, InlineSettingsTextEdit, SettingsError, InfoMessage } from "../common";
|
||||||
import { LineType, RendererPluginType, ClientDataType, CommandRtnType } from "../../../types/types";
|
import { LineType, RendererPluginType, ClientDataType, CommandRtnType } from "../../../types/types";
|
||||||
import { ConnectionDropdown } from "../../connections/connections";
|
import { ConnectionDropdown } from "../../connections_deprecated/connections";
|
||||||
import { PluginModel } from "../../../plugins/plugins";
|
import { PluginModel } from "../../../plugins/plugins";
|
||||||
import * as util from "../../../util/util";
|
import * as util from "../../../util/util";
|
||||||
import { commandRtnHandler } from "../../../util/util";
|
import { commandRtnHandler } from "../../../util/util";
|
||||||
|
|||||||
@@ -1,408 +1,107 @@
|
|||||||
@import "../../app/common/themes/themes.less";
|
@import "../../app/common/themes/themes.less";
|
||||||
|
|
||||||
.modal.prompt-modal.remotes-modal {
|
.connections-view {
|
||||||
.modal-content {
|
background-color: @background-session;
|
||||||
min-width: 850px;
|
flex-grow: 1;
|
||||||
}
|
display: flex;
|
||||||
.icon {
|
flex-direction: column;
|
||||||
width: 1em;
|
position: relative;
|
||||||
height: 1em;
|
overflow: auto;
|
||||||
fill: @base-color;
|
margin-bottom: 10px;
|
||||||
margin: 0;
|
margin-right: 10px;
|
||||||
}
|
|
||||||
.button {
|
|
||||||
svg {
|
|
||||||
float: right;
|
|
||||||
margin-top: 0.3em;
|
|
||||||
margin-right: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.dropdown,
|
|
||||||
.button {
|
|
||||||
display: inline-flex;
|
|
||||||
}
|
|
||||||
.dropdown .button {
|
|
||||||
border: none !important;
|
|
||||||
}
|
|
||||||
.inner-content {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
align-items: stretch;
|
|
||||||
padding: 0;
|
|
||||||
min-height: 45em;
|
|
||||||
max-height: 45em;
|
|
||||||
|
|
||||||
.remotes-menu {
|
|
||||||
flex: 0 0 200px;
|
|
||||||
border-right: 1px solid @disabled-color;
|
|
||||||
overflow-y: auto;
|
|
||||||
|
|
||||||
.remote-menu-item {
|
|
||||||
border-top: 1px solid @disabled-color;
|
|
||||||
padding: 0.5em;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
cursor: pointer;
|
|
||||||
|
|
||||||
&.add-remote {
|
|
||||||
padding: 10px 5px 10px 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background-color: #333;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.is-selected {
|
|
||||||
background-color: @active-menu-color;
|
|
||||||
|
|
||||||
.remote-name .remote-name-secondary {
|
|
||||||
color: @term-white;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&:first-child {
|
|
||||||
border-top: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.remote-status-light {
|
|
||||||
width: 2em;
|
|
||||||
margin-top: 0.7em;
|
|
||||||
margin-right: 0.7em;
|
|
||||||
font-size: 0.8em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.remote-name {
|
|
||||||
flex-grow: 1;
|
|
||||||
|
|
||||||
.remote-name-primary {
|
|
||||||
font-weight: bold;
|
|
||||||
max-width: 10em;
|
|
||||||
margin-right: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.remote-name-secondary {
|
|
||||||
color: @disabled-color;
|
|
||||||
max-width: 14em;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.remote-detail {
|
|
||||||
padding: 10px;
|
|
||||||
flex-grow: 1;
|
|
||||||
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
|
|
||||||
.settings-field {
|
|
||||||
margin-top: 0.75em;
|
|
||||||
}
|
|
||||||
|
|
||||||
* {
|
|
||||||
flex-shrink: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.detail-subtitle {
|
|
||||||
margin-bottom: 10px;
|
|
||||||
margin-top: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.title {
|
|
||||||
color: @term-white;
|
|
||||||
padding: 0.75em 0;
|
|
||||||
margin-bottom: 0;
|
|
||||||
border-bottom: 1px solid #777;
|
|
||||||
}
|
|
||||||
|
|
||||||
.terminal-wrapper {
|
|
||||||
margin-left: 0;
|
|
||||||
margin-bottom: 0;
|
|
||||||
&.has-message {
|
|
||||||
margin-top: 0;
|
|
||||||
}
|
|
||||||
box-shadow: none;
|
|
||||||
border: 1px solid #777;
|
|
||||||
border-radius: 0 0 5px 5px;
|
|
||||||
.xterm-rows {
|
|
||||||
padding-top: 0.5em;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.action-buttons {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
gap: 10px;
|
|
||||||
margin-top: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.remote-message {
|
|
||||||
margin-top: 5px;
|
|
||||||
padding: 8px;
|
|
||||||
border-radius: 5px 5px 0 0;
|
|
||||||
background-color: #333;
|
|
||||||
border: 1px solid #777;
|
|
||||||
border-bottom: none;
|
|
||||||
|
|
||||||
.message-row {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
align-items: center;
|
|
||||||
svg {
|
|
||||||
vertical-align: text-bottom;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.remote-status {
|
|
||||||
position: relative;
|
|
||||||
top: -1px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.button {
|
|
||||||
height: 22px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.settings-field {
|
|
||||||
.update-auth-button {
|
|
||||||
visibility: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
.update-auth-button {
|
|
||||||
visibility: visible;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hide-hover {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.auth-editing,
|
|
||||||
&.create-remote {
|
|
||||||
.settings-field.align-top {
|
|
||||||
align-items: flex-start;
|
|
||||||
|
|
||||||
.settings-label {
|
|
||||||
margin-top: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.settings-input {
|
|
||||||
align-items: flex-start;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.settings-label {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
align-items: center;
|
|
||||||
width: 12em !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.settings-field .settings-input .undo-icon {
|
|
||||||
cursor: pointer;
|
|
||||||
|
|
||||||
margin-left: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.editremote-dropdown .dropdown-trigger button {
|
|
||||||
width: 120px;
|
|
||||||
justify-content: flex-start;
|
|
||||||
color: @base-color;
|
|
||||||
border: none;
|
|
||||||
&:hover {
|
|
||||||
box-shadow: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.settings-field .raw-input {
|
|
||||||
width: 120px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.settings-input input {
|
|
||||||
background: rgba(255, 255, 255, 0.8);
|
|
||||||
width: 250px;
|
|
||||||
outline: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dropdown .dropdown-item {
|
|
||||||
padding: 5px 5px 5px 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dropdown .dropdown-content {
|
|
||||||
max-width: 10.6em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.settings-input {
|
|
||||||
.info-message {
|
|
||||||
margin-left: 22px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.settings-label {
|
|
||||||
.info-message {
|
|
||||||
margin-right: 15px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.terminal-wrapper {
|
|
||||||
position: relative;
|
|
||||||
padding: 2px 10px 5px 4px;
|
|
||||||
margin: 5px 5px 10px 5px;
|
|
||||||
box-shadow: 0 0 1px 1px rgba(255, 255, 255, 0.3);
|
|
||||||
&.focus {
|
|
||||||
box-shadow: 0 0 3px 3px rgba(255, 255, 255, 0.3);
|
|
||||||
}
|
|
||||||
|
|
||||||
.term-tag {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
right: 0;
|
|
||||||
background-color: @term-red;
|
|
||||||
color: @term-white;
|
|
||||||
z-index: 110;
|
|
||||||
padding: 4px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.dropdown.conn-dropdown {
|
|
||||||
padding-left: 0;
|
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
background-color: rgba(241, 246, 243, 0.08);
|
border: 1px solid rgba(241, 246, 243, 0.08);
|
||||||
|
background: var(--element-window, rgba(13, 13, 13, 0.85));
|
||||||
|
|
||||||
.conn-dd-trigger {
|
.header {
|
||||||
|
margin: 24px 18px;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
justify-content: space-between;
|
||||||
width: 413px;
|
|
||||||
padding: 6px 8px 6px 12px;
|
|
||||||
align-items: center;
|
align-items: center;
|
||||||
height: 42px;
|
|
||||||
|
|
||||||
.lefticon {
|
.connections-title {
|
||||||
margin-right: 8px;
|
|
||||||
margin-top: 4px;
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
.status-icon {
|
|
||||||
width: 10px;
|
|
||||||
height: 10px;
|
|
||||||
stroke-width: 2px;
|
|
||||||
stroke: @status-outline;
|
|
||||||
position: absolute;
|
|
||||||
bottom: 3px;
|
|
||||||
right: -2px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.dd-control {
|
|
||||||
display: flex;
|
|
||||||
padding: 4px;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
.icon {
|
|
||||||
height: 16px;
|
|
||||||
width: 16px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.globe-icon {
|
|
||||||
width: 16px;
|
|
||||||
height: 16px;
|
|
||||||
flex-shrink: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.conntext {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: flex-start;
|
|
||||||
flex: 1 0 0;
|
|
||||||
|
|
||||||
.conntext-solo {
|
|
||||||
color: @text-primary;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
}
|
|
||||||
|
|
||||||
.conntext-1 {
|
|
||||||
color: @text-primary;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
}
|
|
||||||
|
|
||||||
.conntext-2 {
|
|
||||||
color: @text-secondary;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.conn-dd-menu {
|
.no-items {
|
||||||
display: flex;
|
display: flex;
|
||||||
width: 413px;
|
flex-direction: row;
|
||||||
padding: 6px;
|
justify-content: center;
|
||||||
flex-direction: column;
|
padding: 30px 0 30px 0;
|
||||||
align-items: flex-start;
|
border: 1px solid white;
|
||||||
border-radius: 8px;
|
border-radius: 3px;
|
||||||
background-color: @dropdown-menu;
|
margin: 20px 50px 20px 20px;
|
||||||
|
}
|
||||||
|
|
||||||
.dropdown-item {
|
.connections-table {
|
||||||
display: flex;
|
margin: 0px 10px 10px 10px;
|
||||||
padding: 5px 12px 5px 8px;
|
table-layout: fixed;
|
||||||
align-items: center;
|
max-width: 970px;
|
||||||
gap: 8px;
|
|
||||||
align-self: stretch;
|
|
||||||
border-radius: 6px;
|
|
||||||
|
|
||||||
.status-div {
|
colgroup {
|
||||||
display: flex;
|
.first-col {
|
||||||
align-items: center;
|
max-width: 650px;
|
||||||
justify-content: center;
|
|
||||||
width: 16px;
|
|
||||||
height: 16px;
|
|
||||||
padding: 3px;
|
|
||||||
|
|
||||||
svg.status-icon {
|
|
||||||
width: 10px;
|
|
||||||
height: 10px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
.second-col {
|
||||||
.add-div {
|
max-width: 150px;
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
width: 16px;
|
|
||||||
height: 16px;
|
|
||||||
|
|
||||||
svg.add-icon {
|
|
||||||
width: 16px;
|
|
||||||
height: 16px;
|
|
||||||
|
|
||||||
path {
|
|
||||||
fill: @text-primary;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
.third-col {
|
||||||
|
max-width: 200px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.text-standard {
|
thead {
|
||||||
|
border-radius: var(--sizing-2-xs, 4px);
|
||||||
|
border-top: 1px solid rgba(250, 250, 250, 0.1);
|
||||||
|
border-bottom: 1px solid rgba(241, 246, 243, 0.15);
|
||||||
|
background: var(--opacity-zinc-502, rgba(250, 250, 250, 0.02));
|
||||||
|
box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.4), 0px 0px 0.5px 0px rgba(0, 0, 0, 0.5),
|
||||||
|
0px 0px 0.5px 0px rgba(255, 255, 255, 0.5) inset, 0px 0.5px 0px 0px rgba(255, 255, 255, 0.2) inset;
|
||||||
|
|
||||||
|
th {
|
||||||
|
height: 32px;
|
||||||
|
padding: 5px 15px 5px 10px;
|
||||||
color: @text-secondary;
|
color: @text-secondary;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.text-caption {
|
tr.connections-item {
|
||||||
color: @text-caption;
|
border-bottom: 1px solid rgba(241, 246, 243, 0.15);
|
||||||
}
|
color: @text-secondary;
|
||||||
|
cursor: pointer;
|
||||||
.ellipsis {
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background-color: rgba(241, 246, 243, 0.08);
|
background: rgba(255, 255, 255, 0.06);
|
||||||
|
|
||||||
|
td.bookmark i {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
td {
|
||||||
|
height: 40px;
|
||||||
|
padding: 5px 15px 5px 10px;
|
||||||
|
vertical-align: middle;
|
||||||
|
|
||||||
|
.action-buttons {
|
||||||
|
display: flex;
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.hovered {
|
||||||
|
.action-buttons {
|
||||||
|
visibility: visible;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
footer {
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.help-entry {
|
||||||
|
margin: 1em 2em;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+116
-1231
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,408 @@
|
|||||||
|
@import "../../app/common/themes/themes.less";
|
||||||
|
|
||||||
|
.modal.prompt-modal.remotes-modal {
|
||||||
|
.modal-content {
|
||||||
|
min-width: 850px;
|
||||||
|
}
|
||||||
|
.icon {
|
||||||
|
width: 1em;
|
||||||
|
height: 1em;
|
||||||
|
fill: @base-color;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
.button {
|
||||||
|
svg {
|
||||||
|
float: right;
|
||||||
|
margin-top: 0.3em;
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.dropdown,
|
||||||
|
.button {
|
||||||
|
display: inline-flex;
|
||||||
|
}
|
||||||
|
.dropdown .button {
|
||||||
|
border: none !important;
|
||||||
|
}
|
||||||
|
.inner-content {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: stretch;
|
||||||
|
padding: 0;
|
||||||
|
min-height: 45em;
|
||||||
|
max-height: 45em;
|
||||||
|
|
||||||
|
.remotes-menu {
|
||||||
|
flex: 0 0 200px;
|
||||||
|
border-right: 1px solid @disabled-color;
|
||||||
|
overflow-y: auto;
|
||||||
|
|
||||||
|
.remote-menu-item {
|
||||||
|
border-top: 1px solid @disabled-color;
|
||||||
|
padding: 0.5em;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&.add-remote {
|
||||||
|
padding: 10px 5px 10px 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.is-selected {
|
||||||
|
background-color: @active-menu-color;
|
||||||
|
|
||||||
|
.remote-name .remote-name-secondary {
|
||||||
|
color: @term-white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:first-child {
|
||||||
|
border-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.remote-status-light {
|
||||||
|
width: 2em;
|
||||||
|
margin-top: 0.7em;
|
||||||
|
margin-right: 0.7em;
|
||||||
|
font-size: 0.8em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.remote-name {
|
||||||
|
flex-grow: 1;
|
||||||
|
|
||||||
|
.remote-name-primary {
|
||||||
|
font-weight: bold;
|
||||||
|
max-width: 10em;
|
||||||
|
margin-right: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.remote-name-secondary {
|
||||||
|
color: @disabled-color;
|
||||||
|
max-width: 14em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.remote-detail {
|
||||||
|
padding: 10px;
|
||||||
|
flex-grow: 1;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
.settings-field {
|
||||||
|
margin-top: 0.75em;
|
||||||
|
}
|
||||||
|
|
||||||
|
* {
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-subtitle {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
color: @term-white;
|
||||||
|
padding: 0.75em 0;
|
||||||
|
margin-bottom: 0;
|
||||||
|
border-bottom: 1px solid #777;
|
||||||
|
}
|
||||||
|
|
||||||
|
.terminal-wrapper {
|
||||||
|
margin-left: 0;
|
||||||
|
margin-bottom: 0;
|
||||||
|
&.has-message {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
box-shadow: none;
|
||||||
|
border: 1px solid #777;
|
||||||
|
border-radius: 0 0 5px 5px;
|
||||||
|
.xterm-rows {
|
||||||
|
padding-top: 0.5em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-buttons {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
gap: 10px;
|
||||||
|
margin-top: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.remote-message {
|
||||||
|
margin-top: 5px;
|
||||||
|
padding: 8px;
|
||||||
|
border-radius: 5px 5px 0 0;
|
||||||
|
background-color: #333;
|
||||||
|
border: 1px solid #777;
|
||||||
|
border-bottom: none;
|
||||||
|
|
||||||
|
.message-row {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
svg {
|
||||||
|
vertical-align: text-bottom;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.remote-status {
|
||||||
|
position: relative;
|
||||||
|
top: -1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button {
|
||||||
|
height: 22px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.settings-field {
|
||||||
|
.update-auth-button {
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
.update-auth-button {
|
||||||
|
visibility: visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hide-hover {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.auth-editing,
|
||||||
|
&.create-remote {
|
||||||
|
.settings-field.align-top {
|
||||||
|
align-items: flex-start;
|
||||||
|
|
||||||
|
.settings-label {
|
||||||
|
margin-top: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.settings-input {
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.settings-label {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
width: 12em !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.settings-field .settings-input .undo-icon {
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.editremote-dropdown .dropdown-trigger button {
|
||||||
|
width: 120px;
|
||||||
|
justify-content: flex-start;
|
||||||
|
color: @base-color;
|
||||||
|
border: none;
|
||||||
|
&:hover {
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.settings-field .raw-input {
|
||||||
|
width: 120px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.settings-input input {
|
||||||
|
background: rgba(255, 255, 255, 0.8);
|
||||||
|
width: 250px;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown .dropdown-item {
|
||||||
|
padding: 5px 5px 5px 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown .dropdown-content {
|
||||||
|
max-width: 10.6em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.settings-input {
|
||||||
|
.info-message {
|
||||||
|
margin-left: 22px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.settings-label {
|
||||||
|
.info-message {
|
||||||
|
margin-right: 15px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.terminal-wrapper {
|
||||||
|
position: relative;
|
||||||
|
padding: 2px 10px 5px 4px;
|
||||||
|
margin: 5px 5px 10px 5px;
|
||||||
|
box-shadow: 0 0 1px 1px rgba(255, 255, 255, 0.3);
|
||||||
|
&.focus {
|
||||||
|
box-shadow: 0 0 3px 3px rgba(255, 255, 255, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.term-tag {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
background-color: @term-red;
|
||||||
|
color: @term-white;
|
||||||
|
z-index: 110;
|
||||||
|
padding: 4px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown.conn-dropdown {
|
||||||
|
padding-left: 0;
|
||||||
|
border-radius: 8px;
|
||||||
|
background-color: rgba(241, 246, 243, 0.08);
|
||||||
|
|
||||||
|
.conn-dd-trigger {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
width: 413px;
|
||||||
|
padding: 6px 8px 6px 12px;
|
||||||
|
align-items: center;
|
||||||
|
height: 42px;
|
||||||
|
|
||||||
|
.lefticon {
|
||||||
|
margin-right: 8px;
|
||||||
|
margin-top: 4px;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
.status-icon {
|
||||||
|
width: 10px;
|
||||||
|
height: 10px;
|
||||||
|
stroke-width: 2px;
|
||||||
|
stroke: @status-outline;
|
||||||
|
position: absolute;
|
||||||
|
bottom: 3px;
|
||||||
|
right: -2px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.dd-control {
|
||||||
|
display: flex;
|
||||||
|
padding: 4px;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
height: 16px;
|
||||||
|
width: 16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.globe-icon {
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.conntext {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: flex-start;
|
||||||
|
flex: 1 0 0;
|
||||||
|
|
||||||
|
.conntext-solo {
|
||||||
|
color: @text-primary;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
.conntext-1 {
|
||||||
|
color: @text-primary;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
.conntext-2 {
|
||||||
|
color: @text-secondary;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.conn-dd-menu {
|
||||||
|
display: flex;
|
||||||
|
width: 413px;
|
||||||
|
padding: 6px;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-start;
|
||||||
|
border-radius: 8px;
|
||||||
|
background-color: @dropdown-menu;
|
||||||
|
|
||||||
|
.dropdown-item {
|
||||||
|
display: flex;
|
||||||
|
padding: 5px 12px 5px 8px;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
align-self: stretch;
|
||||||
|
border-radius: 6px;
|
||||||
|
|
||||||
|
.status-div {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
padding: 3px;
|
||||||
|
|
||||||
|
svg.status-icon {
|
||||||
|
width: 10px;
|
||||||
|
height: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.add-div {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
|
||||||
|
svg.add-icon {
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
|
||||||
|
path {
|
||||||
|
fill: @text-primary;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-standard {
|
||||||
|
color: @text-secondary;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-caption {
|
||||||
|
color: @text-caption;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ellipsis {
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: rgba(241, 246, 243, 0.08);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -110,6 +110,15 @@ class MainSideBar extends React.Component<{}, {}> {
|
|||||||
GlobalCommandRunner.bookmarksView();
|
GlobalCommandRunner.bookmarksView();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@boundMethod
|
||||||
|
handleConnectionsClick(): void {
|
||||||
|
if (GlobalModel.activeMainView.get() == "connections") {
|
||||||
|
GlobalModel.showSessionView();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
GlobalCommandRunner.connectionsView();
|
||||||
|
}
|
||||||
|
|
||||||
@boundMethod
|
@boundMethod
|
||||||
handleWebSharingClick(): void {
|
handleWebSharingClick(): void {
|
||||||
if (GlobalModel.activeMainView.get() == "webshare") {
|
if (GlobalModel.activeMainView.get() == "webshare") {
|
||||||
@@ -126,11 +135,6 @@ class MainSideBar extends React.Component<{}, {}> {
|
|||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
|
|
||||||
@boundMethod
|
|
||||||
handleConnectionsClick(): void {
|
|
||||||
GlobalModel.remotesModalModel.openModal();
|
|
||||||
}
|
|
||||||
|
|
||||||
@boundMethod
|
@boundMethod
|
||||||
openSessionSettings(e: any, session: Session): void {
|
openSessionSettings(e: any, session: Session): void {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
@@ -199,14 +203,14 @@ class MainSideBar extends React.Component<{}, {}> {
|
|||||||
<div className="logo">
|
<div className="logo">
|
||||||
<If condition={isCollapsed}>
|
<If condition={isCollapsed}>
|
||||||
<div className="logo-container" onClick={this.toggleCollapsed}>
|
<div className="logo-container" onClick={this.toggleCollapsed}>
|
||||||
<img src="public/logos/wave-logo.png"/>
|
<img src="public/logos/wave-logo.png" />
|
||||||
</div>
|
</div>
|
||||||
</If>
|
</If>
|
||||||
<If condition={!isCollapsed}>
|
<If condition={!isCollapsed}>
|
||||||
<div className="logo-container">
|
<div className="logo-container">
|
||||||
<img src="public/logos/wave-dark.png"/>
|
<img src="public/logos/wave-dark.png" />
|
||||||
</div>
|
</div>
|
||||||
<div className="spacer"/>
|
<div className="spacer" />
|
||||||
<div className="collapse-button" onClick={this.toggleCollapsed}>
|
<div className="collapse-button" onClick={this.toggleCollapsed}>
|
||||||
<LeftChevronIcon className="icon" />
|
<LeftChevronIcon className="icon" />
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ import { getRemoteStr } from "../../common/prompt/prompt";
|
|||||||
import { GlobalModel, ScreenLines, Screen, Session } from "../../../model/model";
|
import { GlobalModel, ScreenLines, Screen, Session } from "../../../model/model";
|
||||||
import { Line } from "../../line/linecomps";
|
import { Line } from "../../line/linecomps";
|
||||||
import { LinesView } from "../../line/linesview";
|
import { LinesView } from "../../line/linesview";
|
||||||
import { ConnectionDropdown } from "../../connections/connections";
|
import { ConnectionDropdown } from "../../connections_deprecated/connections";
|
||||||
import * as util from "../../../util/util";
|
import * as util from "../../../util/util";
|
||||||
import { TextField, InputDecoration } from "../../common/common";
|
import { TextField, InputDecoration } from "../../common/common";
|
||||||
import { ReactComponent as EllipseIcon } from "../../assets/icons/ellipse.svg";
|
import { ReactComponent as EllipseIcon } from "../../assets/icons/ellipse.svg";
|
||||||
@@ -101,7 +101,7 @@ class NewTabSettings extends React.Component<{ screen: Screen }, {}> {
|
|||||||
|
|
||||||
@boundMethod
|
@boundMethod
|
||||||
clickNewConnection(): void {
|
clickNewConnection(): void {
|
||||||
GlobalModel.remotesModalModel.openModalForEdit({ remoteedit: true, old: false }, true);
|
GlobalModel.remotesModel.openAddModal({ remoteedit: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
renderTabIconSelector(): React.ReactNode {
|
renderTabIconSelector(): React.ReactNode {
|
||||||
@@ -117,7 +117,7 @@ class NewTabSettings extends React.Component<{ screen: Screen }, {}> {
|
|||||||
<div className="text-s1 unselectable">Select the icon</div>
|
<div className="text-s1 unselectable">Select the icon</div>
|
||||||
<div className="control-iconlist tabicon-list">
|
<div className="control-iconlist tabicon-list">
|
||||||
<div key="square" className="icondiv" title="square" onClick={() => this.selectTabIcon("square")}>
|
<div key="square" className="icondiv" title="square" onClick={() => this.selectTabIcon("square")}>
|
||||||
<SquareIcon className="icon square-icon"/>
|
<SquareIcon className="icon square-icon" />
|
||||||
</div>
|
</div>
|
||||||
<For each="icon" of={TabIcons}>
|
<For each="icon" of={TabIcons}>
|
||||||
<div
|
<div
|
||||||
|
|||||||
+226
-13
@@ -767,7 +767,7 @@ class Screen {
|
|||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
let p = navigator.clipboard.readText();
|
let p = navigator.clipboard.readText();
|
||||||
p.then((text) => {
|
p.then((text) => {
|
||||||
termWrap.dataHandler?.(text);
|
termWrap.dataHandler?.(text, termWrap);
|
||||||
});
|
});
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -2203,6 +2203,14 @@ class HistoryViewModel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class ConnectionsViewModel {
|
||||||
|
showConnectionsView(): void {
|
||||||
|
mobx.action(() => {
|
||||||
|
GlobalModel.activeMainView.set("connections");
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class BookmarksModel {
|
class BookmarksModel {
|
||||||
bookmarks: OArr<BookmarkType> = mobx.observable.array([], {
|
bookmarks: OArr<BookmarkType> = mobx.observable.array([], {
|
||||||
name: "Bookmarks",
|
name: "Bookmarks",
|
||||||
@@ -2700,6 +2708,202 @@ class RemotesModalModel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class RemotesModel {
|
||||||
|
modalMode: OV<null | "read" | "add" | "edit"> = mobx.observable.box(null, {
|
||||||
|
name: "RemotesModel-modalMode",
|
||||||
|
});
|
||||||
|
selectedRemoteId: OV<string> = mobx.observable.box(null, {
|
||||||
|
name: "RemotesModel-selectedRemoteId",
|
||||||
|
});
|
||||||
|
remoteTermWrap: TermWrap;
|
||||||
|
remoteTermWrapFocus: OV<boolean> = mobx.observable.box(false, {
|
||||||
|
name: "RemotesModel-remoteTermWrapFocus",
|
||||||
|
});
|
||||||
|
showNoInputMsg: OV<boolean> = mobx.observable.box(false, {
|
||||||
|
name: "RemotesModel-showNoInputMg",
|
||||||
|
});
|
||||||
|
showNoInputTimeoutId: any = null;
|
||||||
|
remoteEdit: OV<RemoteEditType> = mobx.observable.box(null, {
|
||||||
|
name: "RemotesModel-remoteEdit",
|
||||||
|
});
|
||||||
|
recentConnAddedState: OV<boolean> = mobx.observable.box(false, {
|
||||||
|
name: "RemotesModel-recentlyAdded",
|
||||||
|
});
|
||||||
|
|
||||||
|
isOpen(): boolean {
|
||||||
|
return this.modalMode.get() != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
get recentConnAdded(): boolean {
|
||||||
|
return this.recentConnAddedState.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
seRecentConnAdded(value: boolean) {
|
||||||
|
this.recentConnAddedState.set(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
deSelectRemote(): void {
|
||||||
|
mobx.action(() => {
|
||||||
|
this.selectedRemoteId.set(null);
|
||||||
|
this.remoteEdit.set(null);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
|
||||||
|
openReadModal(remoteId: string): void {
|
||||||
|
mobx.action(() => {
|
||||||
|
this.selectedRemoteId.set(remoteId);
|
||||||
|
this.remoteEdit.set(null);
|
||||||
|
this.modalMode.set("read");
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
|
||||||
|
openAddModal(redit: RemoteEditType): void {
|
||||||
|
mobx.action(() => {
|
||||||
|
this.remoteEdit.set(redit);
|
||||||
|
this.modalMode.set("add");
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
|
||||||
|
openEditModal(redit?: RemoteEditType): void {
|
||||||
|
if (redit === undefined) {
|
||||||
|
this.startEditAuth();
|
||||||
|
}
|
||||||
|
if (redit != null) {
|
||||||
|
mobx.action(() => {
|
||||||
|
this.selectedRemoteId.set(redit.remoteid);
|
||||||
|
this.remoteEdit.set(redit);
|
||||||
|
this.modalMode.set("edit");
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
selectRemote(remoteId: string): void {
|
||||||
|
if (this.selectedRemoteId.get() == remoteId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mobx.action(() => {
|
||||||
|
this.selectedRemoteId.set(remoteId);
|
||||||
|
this.remoteEdit.set(null);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
|
||||||
|
@boundMethod
|
||||||
|
startEditAuth(): void {
|
||||||
|
let remoteId = this.selectedRemoteId.get();
|
||||||
|
if (remoteId != null) {
|
||||||
|
GlobalCommandRunner.openEditRemote(remoteId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getModalMode(): string {
|
||||||
|
return this.modalMode.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
isAuthEditMode(): boolean {
|
||||||
|
return this.remoteEdit.get() != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@boundMethod
|
||||||
|
closeModal(): void {
|
||||||
|
mobx.action(() => {
|
||||||
|
this.modalMode.set(null);
|
||||||
|
this.selectedRemoteId.set(null);
|
||||||
|
})();
|
||||||
|
setTimeout(() => GlobalModel.refocus(), 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
disposeTerm(): void {
|
||||||
|
if (this.remoteTermWrap == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.remoteTermWrap.dispose();
|
||||||
|
this.remoteTermWrap = null;
|
||||||
|
mobx.action(() => {
|
||||||
|
this.remoteTermWrapFocus.set(false);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
|
||||||
|
receiveData(remoteId: string, ptyPos: number, ptyData: Uint8Array, reason?: string) {
|
||||||
|
if (this.remoteTermWrap == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (this.remoteTermWrap.getContextRemoteId() != remoteId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.remoteTermWrap.receiveData(ptyPos, ptyData);
|
||||||
|
}
|
||||||
|
|
||||||
|
@boundMethod
|
||||||
|
setRemoteTermWrapFocus(focus: boolean): void {
|
||||||
|
mobx.action(() => {
|
||||||
|
this.remoteTermWrapFocus.set(focus);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
|
||||||
|
@boundMethod
|
||||||
|
setShowNoInputMsg(val: boolean) {
|
||||||
|
mobx.action(() => {
|
||||||
|
if (this.showNoInputTimeoutId != null) {
|
||||||
|
clearTimeout(this.showNoInputTimeoutId);
|
||||||
|
this.showNoInputTimeoutId = null;
|
||||||
|
}
|
||||||
|
if (val) {
|
||||||
|
this.showNoInputMsg.set(true);
|
||||||
|
this.showNoInputTimeoutId = setTimeout(() => this.setShowNoInputMsg(false), 2000);
|
||||||
|
} else {
|
||||||
|
this.showNoInputMsg.set(false);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
|
||||||
|
@boundMethod
|
||||||
|
termKeyHandler(remoteId: string, event: any, termWrap: TermWrap): void {
|
||||||
|
let remote = GlobalModel.getRemote(remoteId);
|
||||||
|
if (remote == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (remote.status != "connecting" && remote.installstatus != "connecting") {
|
||||||
|
this.setShowNoInputMsg(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let inputPacket: RemoteInputPacketType = {
|
||||||
|
type: "remoteinput",
|
||||||
|
remoteid: remoteId,
|
||||||
|
inputdata64: btoa(event.key),
|
||||||
|
};
|
||||||
|
GlobalModel.sendInputPacket(inputPacket);
|
||||||
|
}
|
||||||
|
|
||||||
|
createTermWrap(elem: HTMLElement): void {
|
||||||
|
this.disposeTerm();
|
||||||
|
let remoteId = this.selectedRemoteId.get();
|
||||||
|
if (remoteId == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let termOpts = {
|
||||||
|
rows: RemotePtyRows,
|
||||||
|
cols: RemotePtyCols,
|
||||||
|
flexrows: false,
|
||||||
|
maxptysize: 64 * 1024,
|
||||||
|
};
|
||||||
|
let termWrap = new TermWrap(elem, {
|
||||||
|
termContext: { remoteId: remoteId },
|
||||||
|
usedRows: RemotePtyRows,
|
||||||
|
termOpts: termOpts,
|
||||||
|
winSize: null,
|
||||||
|
keyHandler: (e, termWrap) => {
|
||||||
|
this.termKeyHandler(remoteId, e, termWrap);
|
||||||
|
},
|
||||||
|
focusHandler: this.setRemoteTermWrapFocus.bind(this),
|
||||||
|
isRunning: true,
|
||||||
|
fontSize: GlobalModel.termFontSize.get(),
|
||||||
|
ptyDataSource: getTermPtyData,
|
||||||
|
onUpdateContentHeight: null,
|
||||||
|
});
|
||||||
|
this.remoteTermWrap = termWrap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class Model {
|
class Model {
|
||||||
clientId: string;
|
clientId: string;
|
||||||
activeSessionId: OV<string> = mobx.observable.box(null, {
|
activeSessionId: OV<string> = mobx.observable.box(null, {
|
||||||
@@ -2729,9 +2933,10 @@ class Model {
|
|||||||
authKey: string;
|
authKey: string;
|
||||||
isDev: boolean;
|
isDev: boolean;
|
||||||
platform: string;
|
platform: string;
|
||||||
activeMainView: OV<"plugins" | "session" | "history" | "bookmarks" | "webshare"> = mobx.observable.box("session", {
|
activeMainView: OV<"plugins" | "session" | "history" | "bookmarks" | "webshare" | "connections"> =
|
||||||
name: "activeMainView",
|
mobx.observable.box("session", {
|
||||||
});
|
name: "activeMainView",
|
||||||
|
});
|
||||||
termFontSize: CV<number>;
|
termFontSize: CV<number>;
|
||||||
alertMessage: OV<AlertMessageType> = mobx.observable.box(null, {
|
alertMessage: OV<AlertMessageType> = mobx.observable.box(null, {
|
||||||
name: "alertMessage",
|
name: "alertMessage",
|
||||||
@@ -2753,11 +2958,13 @@ class Model {
|
|||||||
name: "lineSettingsModal",
|
name: "lineSettingsModal",
|
||||||
}); // linenum
|
}); // linenum
|
||||||
remotesModalModel: RemotesModalModel;
|
remotesModalModel: RemotesModalModel;
|
||||||
|
remotesModel: RemotesModel;
|
||||||
|
|
||||||
inputModel: InputModel;
|
inputModel: InputModel;
|
||||||
pluginsModel: PluginsModel;
|
pluginsModel: PluginsModel;
|
||||||
bookmarksModel: BookmarksModel;
|
bookmarksModel: BookmarksModel;
|
||||||
historyViewModel: HistoryViewModel;
|
historyViewModel: HistoryViewModel;
|
||||||
|
connectionViewModel: ConnectionsViewModel;
|
||||||
clientData: OV<ClientDataType> = mobx.observable.box(null, {
|
clientData: OV<ClientDataType> = mobx.observable.box(null, {
|
||||||
name: "clientData",
|
name: "clientData",
|
||||||
});
|
});
|
||||||
@@ -2777,7 +2984,9 @@ class Model {
|
|||||||
this.pluginsModel = new PluginsModel();
|
this.pluginsModel = new PluginsModel();
|
||||||
this.bookmarksModel = new BookmarksModel();
|
this.bookmarksModel = new BookmarksModel();
|
||||||
this.historyViewModel = new HistoryViewModel();
|
this.historyViewModel = new HistoryViewModel();
|
||||||
|
this.connectionViewModel = new ConnectionsViewModel();
|
||||||
this.remotesModalModel = new RemotesModalModel();
|
this.remotesModalModel = new RemotesModalModel();
|
||||||
|
this.remotesModel = new RemotesModel();
|
||||||
let isWaveSrvRunning = getApi().getWaveSrvStatus();
|
let isWaveSrvRunning = getApi().getWaveSrvStatus();
|
||||||
this.waveSrvRunning = mobx.observable.box(isWaveSrvRunning, {
|
this.waveSrvRunning = mobx.observable.box(isWaveSrvRunning, {
|
||||||
name: "model-wavesrv-running",
|
name: "model-wavesrv-running",
|
||||||
@@ -3003,8 +3212,8 @@ class Model {
|
|||||||
GlobalModel.screenSettingsModal.set(null);
|
GlobalModel.screenSettingsModal.set(null);
|
||||||
didSomething = true;
|
didSomething = true;
|
||||||
}
|
}
|
||||||
if (GlobalModel.remotesModalModel.isOpen()) {
|
if (GlobalModel.remotesModel.isOpen()) {
|
||||||
GlobalModel.remotesModalModel.closeModal();
|
GlobalModel.remotesModel.closeModal();
|
||||||
didSomething = true;
|
didSomething = true;
|
||||||
}
|
}
|
||||||
if (GlobalModel.clientSettingsModal.get()) {
|
if (GlobalModel.clientSettingsModal.get()) {
|
||||||
@@ -3213,7 +3422,7 @@ class Model {
|
|||||||
} else {
|
} else {
|
||||||
// remote update
|
// remote update
|
||||||
let ptyData = base64ToArray(ptyMsg.ptydata64);
|
let ptyData = base64ToArray(ptyMsg.ptydata64);
|
||||||
this.remotesModalModel.receiveData(ptyMsg.remoteid, ptyMsg.ptypos, ptyData);
|
this.remotesModel.receiveData(ptyMsg.remoteid, ptyMsg.ptypos, ptyData);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -3277,6 +3486,9 @@ class Model {
|
|||||||
this.remotes.clear();
|
this.remotes.clear();
|
||||||
}
|
}
|
||||||
this.updateRemotes(update.remotes);
|
this.updateRemotes(update.remotes);
|
||||||
|
if (update.remotes?.length && this.remotesModel.recentConnAddedState.get()) {
|
||||||
|
this.remotesModel.openReadModal(update.remotes[0].remoteid);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if ("mainview" in update) {
|
if ("mainview" in update) {
|
||||||
if (update.mainview == "plugins") {
|
if (update.mainview == "plugins") {
|
||||||
@@ -3302,12 +3514,8 @@ class Model {
|
|||||||
}
|
}
|
||||||
if (interactive && "remoteview" in update) {
|
if (interactive && "remoteview" in update) {
|
||||||
let rview: RemoteViewType = update.remoteview;
|
let rview: RemoteViewType = update.remoteview;
|
||||||
if (rview.remoteshowall) {
|
if (rview.remoteedit != null) {
|
||||||
this.remotesModalModel.openModal();
|
this.remotesModel.openEditModal({ ...rview.remoteedit });
|
||||||
} else if (rview.remoteedit != null) {
|
|
||||||
this.remotesModalModel.openModalForEdit({ ...rview.remoteedit, old: true }, false);
|
|
||||||
} else if (rview.ptyremoteid) {
|
|
||||||
this.remotesModalModel.openModal(rview.ptyremoteid);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ("cmdline" in update) {
|
if ("cmdline" in update) {
|
||||||
@@ -4037,6 +4245,10 @@ class CommandRunner {
|
|||||||
GlobalModel.submitCommand("bookmarks", "show", null, { nohist: "1" }, true);
|
GlobalModel.submitCommand("bookmarks", "show", null, { nohist: "1" }, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
connectionsView() {
|
||||||
|
GlobalModel.connectionViewModel.showConnectionsView();
|
||||||
|
}
|
||||||
|
|
||||||
historyView(params: HistorySearchParams) {
|
historyView(params: HistorySearchParams) {
|
||||||
let kwargs = { nohist: "1" };
|
let kwargs = { nohist: "1" };
|
||||||
kwargs["offset"] = String(params.offset);
|
kwargs["offset"] = String(params.offset);
|
||||||
@@ -4214,6 +4426,7 @@ export {
|
|||||||
RemoteColors,
|
RemoteColors,
|
||||||
getTermPtyData,
|
getTermPtyData,
|
||||||
RemotesModalModel,
|
RemotesModalModel,
|
||||||
|
RemotesModel,
|
||||||
MinFontSize,
|
MinFontSize,
|
||||||
MaxFontSize,
|
MaxFontSize,
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user