From b91bf6bd2090415163b8863c47f07df2977d6f51 Mon Sep 17 00:00:00 2001 From: sawka Date: Mon, 3 Oct 2022 12:25:55 -0700 Subject: [PATCH] checkpoint, visual editing of remotes --- src/main.tsx | 235 ++++++++++++++++++++++++++++++++------------------- src/model.ts | 4 + src/types.ts | 2 +- 3 files changed, 153 insertions(+), 88 deletions(-) diff --git a/src/main.tsx b/src/main.tsx index d689b2fd..ca9f1a0b 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -9,7 +9,7 @@ import dayjs from "dayjs"; import {If, For, When, Otherwise, Choose} from "tsx-control-statements/components"; import cn from "classnames"; import {TermWrap} from "./term"; -import type {SessionDataType, LineType, CmdDataType, RemoteType, RemoteStateType, RemoteInstanceType, RemotePtrType, HistoryItem, HistoryQueryOpts} from "./types"; +import type {SessionDataType, LineType, CmdDataType, RemoteType, RemoteStateType, RemoteInstanceType, RemotePtrType, HistoryItem, HistoryQueryOpts, RemoteEditType} from "./types"; import localizedFormat from 'dayjs/plugin/localizedFormat'; import {GlobalModel, GlobalCommandRunner, Session, Cmd, Window, Screen, ScreenWindow, riToRPtr, widthToCols} from "./model"; @@ -688,6 +688,9 @@ class InfoRemoteShowAll extends React.Component<{}, {}> { remotes = sortAndFilterRemotes(remotes); return (
+
+ show all remotes +
@@ -778,10 +781,10 @@ class InfoRemoteShow extends React.Component<{}, {}> { return "(must disconnect to install)"; } if (remote.installstatus == "disconnected" || remote.installstatus == "error") { - return
this.installRemote(remote.remoteid)} className="text-button connect-button">[run install]
+ return
this.installRemote(remote.remoteid)} className="text-button connect-button">[run install]
} if (remote.installstatus == "connecting") { - return
this.cancelInstall(remote.remoteid)} className="text-button disconnect-button">[cancel install]
+ return
this.cancelInstall(remote.remoteid)} className="text-button disconnect-button">[cancel install]
} return null; } @@ -801,7 +804,7 @@ class InfoRemoteShow extends React.Component<{}, {}> { } let installButton = this.renderInstallButton(remote); return ( -
+
install-status
{statusStr} | {this.renderInstallButton(remote)} @@ -817,6 +820,13 @@ class InfoRemoteShow extends React.Component<{}, {}> { inputModel.remoteTermWrap.terminal.focus(); } } + + getCanonicalNameDisplayWithPort(remote : RemoteType) { + if (isBlank(remote.remotevars.port) || remote.remotevars.port == "22") { + return remote.remotecanonicalname; + } + return remote.remotecanonicalname + " (port " + remote.remotevars.port + ")"; + } render() { let inputModel = GlobalModel.inputModel; @@ -838,54 +848,58 @@ class InfoRemoteShow extends React.Component<{}, {}> { } return ( <> -
-
-
remoteid
-
{remote.remoteid}
-
-
-
type
-
{this.getRemoteTypeStr(remote)}
-
-
-
alias
-
{isBlank(remote.remotealias) ? "-" : remote.remotealias}
-
-
-
canonicalname
-
{remote.remotecanonicalname}
-
-
-
connectmode
-
{remote.connectmode}
-
-
-
status
-
{remote.status} | {this.renderConnectButton(remote)}
-
- -
-
error
-
{remote.errorstr}
+
+
+ show remote [{remote.remotecanonicalname}]
- - {this.renderInstallStatus(remote)} - -
-
install error
-
{remote.installerrorstr}
+
+
remoteid
+
{remote.remoteid}
- -
-
- -
-
- -
input is only allowed while status is 'connecting'
-
-
-
+
+
type
+
{this.getRemoteTypeStr(remote)}
+
+ +
+
canonicalname
+
{this.getCanonicalNameDisplayWithPort(remote)}
+
+
+
alias
+
{isBlank(remote.remotealias) ? "-" : remote.remotealias}
+
+
+
connectmode
+
{remote.connectmode}
+
+
+
status
+
{remote.status} | {this.renderConnectButton(remote)}
+
+ +
+
error
+
{remote.errorstr}
+
+
+ {this.renderInstallStatus(remote)} + +
+
install error
+
{remote.installerrorstr}
+
+
+
+
+ +
+
+ +
input is only allowed while status is 'connecting'
+
+
+
); } @@ -896,8 +910,8 @@ class InfoRemoteEdit extends React.Component<{}, {}> { alias : mobx.IObservableValue; hostName : mobx.IObservableValue; keyStr : mobx.IObservableValue; - passwordStr : mobx.IObservableValue; portStr : mobx.IObservableValue; + passwordStr : mobx.IObservableValue; colorStr : mobx.IObservableValue; connectMode : mobx.IObservableValue; sudoBool : mobx.IObservableValue; @@ -912,8 +926,8 @@ class InfoRemoteEdit extends React.Component<{}, {}> { this.alias = mobx.observable.box(""); this.hostName = mobx.observable.box(""); this.keyStr = mobx.observable.box(""); + this.portStr = mobx.observable.box(""); this.passwordStr = mobx.observable.box(""); - this.portStr = mobx.observable.box("22"); this.colorStr = mobx.observable.box(""); this.connectMode = mobx.observable.box("startup"); this.sudoBool = mobx.observable.box(false); @@ -930,9 +944,6 @@ class InfoRemoteEdit extends React.Component<{}, {}> { if (this.sudoBool.get()) { kwargs["sudo"] = "1"; } - if (this.portStr.get() != "22") { - kwargs["port"] = this.portStr.get(); - } if (this.colorStr.get() != "") { kwargs["color"] = this.colorStr.get(); } @@ -998,21 +1009,16 @@ class InfoRemoteEdit extends React.Component<{}, {}> { } @boundMethod - onChangePasswordStr(e : any) { + onChangePortStr(e : any) { mobx.action(() => { - this.passwordStr.set(e.target.value); + this.portStr.set(e.target.value); })(); } @boundMethod - onChangePortStr(e : any) { - let strVal = e.target.value; - let iVal = parseInt(strVal); - if (isNaN(iVal) || iVal < 0) { - iVal = 0; - } + onChangePasswordStr(e : any) { mobx.action(() => { - this.portStr.set(String(iVal)); + this.passwordStr.set(e.target.value); })(); } @@ -1044,11 +1050,52 @@ class InfoRemoteEdit extends React.Component<{}, {}> { })(); } + getRemoteEdit() : RemoteEditType { + let inputModel = GlobalModel.inputModel; + let infoMsg = inputModel.infoMsg.get(); + if (infoMsg == null) { + return null; + } + return infoMsg.remoteedit; + } + + getEditingRemote() : RemoteType { + let inputModel = GlobalModel.inputModel; + let infoMsg = inputModel.infoMsg.get(); + if (infoMsg == null) { + return null; + } + let redit = infoMsg.remoteedit; + if (redit == null || isBlank(redit.remoteid)) { + return null; + } + let remote = GlobalModel.getRemote(redit.remoteid); + return remote; + } + remoteCName() : string { - if (this.hostName.get() == "") { - return "[no host]"; + let redit = this.getRemoteEdit(); + if (isBlank(redit.remoteid)) { + // new-mode + let hostName = this.hostName.get(); + if (hostName == "") { + return "[no host]"; + } + if (hostName.indexOf("@") == -1) { + hostName = "[no user]@" + hostName; + } + if (!hostName.startsWith("sudo@") && this.sudoBool.get()) { + return "sudo@" + hostName; + } + return hostName; + } + else { + let remote = this.getEditingRemote(); + if (remote == null) { + return "[no remote]"; + } + return remote.remotecanonicalname; } - return this.hostName.get(); } render() { @@ -1061,22 +1108,22 @@ class InfoRemoteEdit extends React.Component<{}, {}> { if (!redit.remoteedit) { return null; } - if (!isBlank(redit.remoteid)) { + let isEditMode = !isBlank(redit.remoteid); + let remote = this.getEditingRemote(); + let colorStr : string = null; + if (isEditMode && remote == null) { return ( -
- visual editing of remotes not currently supported -
+
cannot edit, remote {redit.remoteid} not found
); } - let colorStr : string = null; return (
- + add new remote '{this.remoteCName()}' - - edit remote + + edit remote '{this.remoteCName()}'
@@ -1085,18 +1132,38 @@ class InfoRemoteEdit extends React.Component<{}, {}> { ssh
+ +
+ +
user@host
+
+ +
+
+
+
port
+
+ +
+
+
+ +
+
user@host
+
+ {remote.remotecanonicalname} + +  (port {remote.remotevars.port}) + +
+
+
alias
-
-
user@host
-
- -
-
ssh keyfile
@@ -1109,12 +1176,6 @@ class InfoRemoteEdit extends React.Component<{}, {}> {
-
-
port
-
- -
-
sudo
diff --git a/src/model.ts b/src/model.ts index ffa276e8..614c8d55 100644 --- a/src/model.ts +++ b/src/model.ts @@ -1897,6 +1897,10 @@ class CommandRunner { openCreateRemote() : void { GlobalModel.submitCommand("remote", "new", null, {"nohist": "1"}, true); } + + editRemote(remoteid : string) : void { + GlobalModel.submitCommand("remote", "edit", null, {"nohist": "1", "remote": remoteid}, true); + } }; let GlobalModel : Model = null; diff --git a/src/types.ts b/src/types.ts index 20ebe160..3eff3914 100644 --- a/src/types.ts +++ b/src/types.ts @@ -314,4 +314,4 @@ type HistoryQueryOpts = { type UpdateMessage = PtyDataUpdateType | ModelUpdateType; -export type {SessionDataType, LineType, RemoteType, RemoteStateType, RemoteInstanceType, WindowDataType, HistoryItem, CmdRemoteStateType, FeCmdPacketType, TermOptsType, CmdStartPacketType, CmdDonePacketType, CmdDataType, ScreenDataType, ScreenOptsType, ScreenWindowType, LayoutType, PtyDataUpdateType, ModelUpdateType, UpdateMessage, InfoType, CmdLineUpdateType, RemotePtrType, UIContextType, HistoryInfoType, HistoryQueryOpts, WatchScreenPacketType, TermWinSize, FeInputPacketType, RemoteInputPacketType}; +export type {SessionDataType, LineType, RemoteType, RemoteStateType, RemoteInstanceType, WindowDataType, HistoryItem, CmdRemoteStateType, FeCmdPacketType, TermOptsType, CmdStartPacketType, CmdDonePacketType, CmdDataType, ScreenDataType, ScreenOptsType, ScreenWindowType, LayoutType, PtyDataUpdateType, ModelUpdateType, UpdateMessage, InfoType, CmdLineUpdateType, RemotePtrType, UIContextType, HistoryInfoType, HistoryQueryOpts, WatchScreenPacketType, TermWinSize, FeInputPacketType, RemoteInputPacketType, RemoteEditType};