From c1b4b7eb63b1896217be114c40da7df027d42269 Mon Sep 17 00:00:00 2001 From: sawka Date: Mon, 3 Apr 2023 21:33:03 -0700 Subject: [PATCH] cleanup old connections code, more cleanup on the connection flows --- src/main.tsx | 711 +----------------------------------------------- src/model.ts | 102 +------ src/remotes.tsx | 212 +++++++++++---- 3 files changed, 155 insertions(+), 870 deletions(-) diff --git a/src/main.tsx b/src/main.tsx index 0035fa8a..dd5a06c1 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -568,706 +568,6 @@ class TextAreaInput extends React.Component<{onHeightChange : () => void}, {}> { } } -@mobxReact.observer -class InfoRemoteShowAll extends React.Component<{}, {}> { - clickRow(remoteId : string) : void { - GlobalCommandRunner.showRemote(remoteId); - } - - render() { - let inputModel = GlobalModel.inputModel; - let infoMsg = inputModel.infoMsg.get(); - if (infoMsg == null || !infoMsg.remoteshowall) { - return null; - } - let remotes = GlobalModel.remotes ?? []; - let remote : RemoteType = null; - let idx : number = 0; - remotes = sortAndFilterRemotes(remotes); - return ( -
-
- show all remotes -
- - - - - - - - - - - - - this.clickRow(remote.remoteid)}> - - - - - - - - -
statusidaliasuser@hostconnectmode
-
{remote.status}
-
- {remote.remoteid.substr(0, 8)} - - {isBlank(remote.remotealias) ? "-" : remote.remotealias} - - {remote.remotecanonicalname} - - {remote.connectmode} -
-
- ); - } -} - -@mobxReact.observer -class InfoRemoteShow extends React.Component<{}, {}> { - getRemoteTypeStr(remote : RemoteType) : string { - let mshellStr = ""; - if (!isBlank(remote.mshellversion)) { - mshellStr = "mshell=" + remote.mshellversion; - } - if (!isBlank(remote.uname)) { - if (mshellStr != "") { - mshellStr += " "; - } - mshellStr += "uname=\"" + remote.uname + "\""; - } - if (mshellStr == "") { - return remote.remotetype; - } - return remote.remotetype + " (" + mshellStr + ")"; - } - - @boundMethod - connectRemote(remoteId : string) { - GlobalCommandRunner.connectRemote(remoteId); - } - - @boundMethod - disconnectRemote(remoteId : string) { - GlobalCommandRunner.disconnectRemote(remoteId); - } - - @boundMethod - installRemote(remoteId : string) { - GlobalCommandRunner.installRemote(remoteId); - } - - @boundMethod - cancelInstall(remoteId : string) { - GlobalCommandRunner.installCancelRemote(remoteId); - } - - @boundMethod - editRemote(remoteId : string) { - GlobalCommandRunner.openEditRemote(remoteId); - } - - renderConnectButton(remote : RemoteType) : any { - if (remote.status == "connected" || remote.status == "connecting") { - return
this.disconnectRemote(remote.remoteid)} className="text-button disconnect-button">[disconnect remote]
- } - else { - return
this.connectRemote(remote.remoteid)} className="text-button connect-button">[connect remote]
- } - } - - renderEditButton(remote : RemoteType) : any { - return
this.editRemote(remote.remoteid)} className="text-button">[edit remote]
- } - - renderInstallButton(remote : RemoteType) : any { - if (remote.status == "connected" || remote.status == "connecting") { - return null; - } - if (remote.installstatus == "disconnected" || remote.installstatus == "error") { - 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 null; - } - - renderInstallStatus(remote : RemoteType) : any { - let statusStr : string = null; - if (remote.installstatus == "disconnected") { - if (remote.needsmshellupgrade) { - statusStr = "mshell " + remote.mshellversion + " (needs upgrade)"; - } - else if (isBlank(remote.mshellversion)) { - statusStr = "mshell unknown"; - } - else { - statusStr = "mshell " + remote.mshellversion + " (current)"; - } - } - else { - statusStr = remote.installstatus; - } - if (statusStr == null) { - return null; - } - let installButton = this.renderInstallButton(remote); - return ( -
-
install-status
-
- {statusStr} | {this.renderInstallButton(remote)} -
-
- ); - } - - @boundMethod - clickTermBlock(e : any) { - let inputModel = GlobalModel.inputModel; - if (inputModel.remoteTermWrap != null) { - inputModel.remoteTermWrap.giveFocus(); - } - } - - 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; - let infoMsg = inputModel.infoMsg.get(); - let ptyRemoteId = (infoMsg == null ? null : infoMsg.ptyremoteid); - let isTermFocused = (inputModel.remoteTermWrap == null ? false : inputModel.remoteTermWrapFocus.get()); - let remote : RemoteType; - if (ptyRemoteId != null) { - remote = GlobalModel.getRemote(ptyRemoteId); - } - if (ptyRemoteId == null || remote == null) { - return ( - <> -
-
-
- - ); - } - let termFontSize = GlobalModel.termFontSize.get(); - return ( - <> -
-
- show remote [{remote.remotecanonicalname}] -
-
-
remoteid
-
{remote.remoteid} | {this.renderEditButton(remote)}
-
-
-
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'
-
-
-
- - ); - } -} - -@mobxReact.observer -class InfoRemoteEdit extends React.Component<{}, {}> { - alias : mobx.IObservableValue; - hostName : mobx.IObservableValue; - keyStr : mobx.IObservableValue; - portStr : mobx.IObservableValue; - passwordStr : mobx.IObservableValue; - colorStr : mobx.IObservableValue; - connectMode : mobx.IObservableValue; - sudoBool : mobx.IObservableValue; - autoInstallBool : mobx.IObservableValue; - authMode : mobx.IObservableValue; - archiveConfirm : mobx.IObservableValue = mobx.observable.box(false); - - constructor(props) { - super(props); - this.resetForm(); - } - - getEditAuthMode(redit : RemoteEditType) : string { - if (!isBlank(redit.keystr) && redit.haspassword) { - return "key+pw"; - } - else if (!isBlank(redit.keystr)) { - return "key"; - } - else if (redit.haspassword) { - return "pw"; - } - else { - return "none"; - } - } - - resetForm() { - let redit = this.getRemoteEdit(); - let remote = this.getEditingRemote(); - if (redit == null) { - return; - } - let isEditMode = !isBlank(redit.remoteid); - if (isEditMode && remote == null) { - return; - } - - // not editable - this.hostName = mobx.observable.box(""); - this.portStr = mobx.observable.box(""); - this.sudoBool = mobx.observable.box(false); - - // editable - if (isEditMode) { - this.authMode = mobx.observable.box(this.getEditAuthMode(redit)); - this.alias = mobx.observable.box(remote.remotealias ?? ""); - this.passwordStr = mobx.observable.box(redit.haspassword ? PasswordUnchangedSentinel : ""); - this.keyStr = mobx.observable.box(redit.keystr ?? ""); - this.colorStr = mobx.observable.box(remote.remotevars["color"] ?? ""); - this.connectMode = mobx.observable.box(remote.connectmode); - this.autoInstallBool = mobx.observable.box(remote.autoinstall); - } - else { - this.authMode = mobx.observable.box("none"); - this.alias = mobx.observable.box(""); - this.passwordStr = mobx.observable.box(""); - this.keyStr = mobx.observable.box(""); - this.colorStr = mobx.observable.box(""); - this.connectMode = mobx.observable.box("startup"); - this.autoInstallBool = mobx.observable.box(true); - } - } - - canResetPw() : boolean { - let redit = this.getRemoteEdit(); - if (redit == null) { - return false; - } - return redit.haspassword && this.passwordStr.get() != PasswordUnchangedSentinel; - } - - @boundMethod - resetPw() : void { - mobx.action(() => { - this.passwordStr.set(PasswordUnchangedSentinel); - })(); - } - - @boundMethod - updateArchiveConfirm(e : any) : void { - mobx.action(() => { - this.archiveConfirm.set(e.target.checked); - })(); - } - - @boundMethod - doArchiveRemote(e : any) { - e.preventDefault(); - if (!this.archiveConfirm.get()) { - return; - } - let redit = this.getRemoteEdit(); - if (redit == null || isBlank(redit.remoteid)) { - return; - } - GlobalCommandRunner.archiveRemote(redit.remoteid); - } - - @boundMethod - doSubmitRemote() { - let redit = this.getRemoteEdit(); - let isEditing = !isBlank(redit.remoteid); - let cname = this.hostName.get(); - let kwargs : Record = {}; - let authMode = this.authMode.get(); - if (!isEditing) { - if (this.sudoBool.get()) { - kwargs["sudo"] = "1"; - } - if (this.portStr.get() != "" && this.portStr.get() != "22") { - kwargs["port"] = this.portStr.get(); - } - } - kwargs["alias"] = this.alias.get(); - kwargs["color"] = this.colorStr.get(); - if (authMode == "key" || authMode == "key+pw") { - kwargs["key"] = this.keyStr.get(); - } - else { - kwargs["key"] = ""; - } - if (authMode == "pw" || authMode == "key+pw") { - kwargs["password"] = this.passwordStr.get(); - } - else { - kwargs["password"] = "" - } - kwargs["connectmode"] = this.connectMode.get(); - kwargs["autoinstall"] = (this.autoInstallBool.get() ? "1" : "0"); - kwargs["visual"] = "1"; - kwargs["submit"] = "1"; - mobx.action(() => { - if (isEditing) { - GlobalCommandRunner.editRemote(redit.remoteid, kwargs); - } - else { - GlobalCommandRunner.createRemote(cname, kwargs); - } - })(); - } - - @boundMethod - doCancel() { - mobx.action(() => { - this.resetForm(); - GlobalModel.inputModel.clearInfoMsg(true); - })(); - } - - @boundMethod - keyDownCreateRemote(e : any) { - if (e.code == "Enter") { - this.doSubmitRemote(); - } - } - - @boundMethod - keyDownCancel(e : any) { - if (e.code == "Enter") { - this.doCancel(); - } - } - - @boundMethod - onChangeAlias(e : any) { - mobx.action(() => { - this.alias.set(e.target.value); - })(); - } - - @boundMethod - onChangeHostName(e : any) { - mobx.action(() => { - this.hostName.set(e.target.value); - })(); - } - - @boundMethod - onChangeKeyStr(e : any) { - mobx.action(() => { - this.keyStr.set(e.target.value); - })(); - } - - @boundMethod - onChangePortStr(e : any) { - mobx.action(() => { - this.portStr.set(e.target.value); - })(); - } - - @boundMethod - onChangePasswordStr(e : any) { - mobx.action(() => { - this.passwordStr.set(e.target.value); - })(); - } - - @boundMethod - onFocusPasswordStr(e : any) { - if (this.passwordStr.get() == PasswordUnchangedSentinel) { - e.target.select(); - } - } - - @boundMethod - onChangeColorStr(e : any) { - mobx.action(() => { - this.colorStr.set(e.target.value); - })(); - } - - @boundMethod - onChangeConnectMode(e : any) { - mobx.action(() => { - this.connectMode.set(e.target.value); - })(); - } - - @boundMethod - onChangeAuthMode(e : any) { - mobx.action(() => { - this.authMode.set(e.target.value); - })(); - } - - @boundMethod - onChangeSudo(e : any) { - mobx.action(() => { - this.sudoBool.set(e.target.checked); - })(); - } - - @boundMethod - onChangeAutoInstall(e : any) { - mobx.action(() => { - this.autoInstallBool.set(e.target.checked); - })(); - } - - 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 { - 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; - } - } - - render() { - let inputModel = GlobalModel.inputModel; - let infoMsg = inputModel.infoMsg.get(); - if (infoMsg == null || !infoMsg.remoteedit) { - return null; - } - let redit = infoMsg.remoteedit; - if (!redit.remoteedit) { - return null; - } - let isEditMode = !isBlank(redit.remoteid); - let remote = this.getEditingRemote(); - if (isEditMode && remote == null) { - return ( -
cannot edit, remote {redit.remoteid} not found
- ); - } - let colorStr : string = null; - return ( -
-
- - add new remote '{this.remoteCName()}' - - - edit remote '{this.remoteCName()}' - -
-
-
type
-
- ssh -
-
- -
-
user@host
-
- -
-
-
-
port
-
- -
-
-
- -
-
user@host
-
- {remote.remotecanonicalname} - -  (port {remote.remotevars.port}) - -
-
-
-
-
alias
-
- -
-
-
-
authmode
-
- -
-
- -
-
ssh keyfile
-
- -
-
-
- -
-
ssh password
-
- - - - -
-
-
-
-
sudo
-
- -
-
-
-
connectmode
-
- -
-
-
-
autoinstall
-
- -
-
-
-
color
-
- -
-
- -
- {redit.errorstr} -
-
- -
- {redit.infostr} -
-
- - - ); - } -} - @mobxReact.observer class InfoMsg extends React.Component<{}, {}> { getAfterSlash(s : string) : string { @@ -1304,9 +604,6 @@ class InfoMsg extends React.Component<{}, {}> { let remoteEditKey = "inforemoteedit"; if (infoMsg != null) { titleStr = infoMsg.infotitle; - if (infoMsg.remoteedit != null) { - remoteEditKey += (infoMsg.remoteedit.remoteid == null ? "-new" : "-" + infoMsg.remoteedit.remoteid); - } } let activeScreen = model.getActiveScreen(); return ( @@ -1338,11 +635,6 @@ class InfoMsg extends React.Component<{}, {}> { - - - - - 0}>
@@ -1616,11 +908,10 @@ class CmdInput extends React.Component<{}, {}> { let historyShow = !infoShow && inputModel.historyShow.get(); let infoMsg = inputModel.infoMsg.get(); let hasInfo = (infoMsg != null); - let remoteShow = (infoMsg != null && !isBlank(infoMsg.ptyremoteid)); let focusVal = inputModel.physicalInputFocused.get(); let inputMode : string = inputModel.inputMode.get(); return ( -
+
diff --git a/src/model.ts b/src/model.ts index 938e87d7..17777ba0 100644 --- a/src/model.ts +++ b/src/model.ts @@ -962,10 +962,6 @@ class InputModel { infoMsg : OV = mobx.observable.box(null); infoTimeoutId : any = null; - remoteTermWrap : TermWrap; - remoteTermWrapFocus : OV = mobx.observable.box(false, {name: "remoteTermWrapFocus"}); - showNoInputMsg : OV = mobx.observable.box(false); - showNoInputTimeoutId : any = null; inputMode : OV = mobx.observable.box(null); // cursor @@ -982,34 +978,12 @@ class InputModel { }); } - setRemoteTermWrapFocus(focus : boolean) : void { - mobx.action(() => { - this.remoteTermWrapFocus.set(focus); - })(); - } - setInputMode(inputMode : null | "comment" | "global") : void { mobx.action(() => { this.inputMode.set(inputMode); })(); } - 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); - } - })(); - } - onInputFocus(isFocused : boolean) : void { mobx.action(() => { if (isFocused) { @@ -1075,14 +1049,6 @@ class InputModel { } } - getPtyRemoteId() : string { - let info = this.infoMsg.get(); - if (info == null || isBlank(info.ptyremoteid)) { - return null; - } - return info.ptyremoteid; - } - hasFocus() : boolean { let mainInputElem = document.getElementById("main-cmd-input"); if (document.activeElement == mainInputElem) { @@ -1404,7 +1370,6 @@ class InputModel { this._clearInfoTimeout(); mobx.action(() => { this.infoMsg.set(info); - this.syncTermWrap(); if (info == null) { this.infoShow.set(false); } @@ -1452,7 +1417,6 @@ class InputModel { this.infoShow.set(false); if (setNull) { this.infoMsg.set(null); - this.syncTermWrap(); } })(); } @@ -1525,62 +1489,10 @@ class InputModel { this.resetHistory(); this.dropModHistory(false); this.infoMsg.set(null); - this.syncTermWrap(); this._clearInfoTimeout(); })(); } - 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); - } - - syncTermWrap() : void { - let infoMsg = this.infoMsg.get(); - let remoteId = (infoMsg == null ? null : infoMsg.ptyremoteid); - let curTermRemoteId = (this.remoteTermWrap == null ? null : this.remoteTermWrap.getContextRemoteId()); - if (remoteId == curTermRemoteId) { - return; - } - if (this.remoteTermWrap != null) { - this.remoteTermWrap.dispose(); - this.remoteTermWrap = null; - } - if (remoteId != null) { - let elem = document.getElementById("term-remote"); - if (elem == null) { - console.log("ERROR null term-remote element"); - } - else { - let termOpts = {rows: RemotePtyRows, cols: RemotePtyCols, flexrows: false, maxptysize: 64*1024}; - this.remoteTermWrap = 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, - }); - } - } - } - getCurLine() : string { let model = GlobalModel; let hidx = this.historyIndex.get(); @@ -2314,6 +2226,7 @@ class RemotesModalModel { deSelectRemote() : void { mobx.action(() => { this.selectedRemoteId.set(null); + this.remoteEdit.set(null); })(); } @@ -2886,24 +2799,13 @@ class Model { if (isBlank(ptyMsg.remoteid)) { // regular update this.updatePtyData(ptyMsg); - return; } else { // remote update let ptyData = base64ToArray(ptyMsg.ptydata64); - - // new remote term this.remotesModalModel.receiveData(ptyMsg.remoteid, ptyMsg.ptypos, ptyData); - - // old remote term - let activeRemoteId = this.inputModel.getPtyRemoteId(); - if (activeRemoteId != ptyMsg.remoteid || this.inputModel.remoteTermWrap == null) { - return; - } - this.inputModel.remoteTermWrap.receiveData(ptyMsg.ptypos, ptyData); - - return; } + return; } let update : ModelUpdateType = genUpdate; if ("screens" in update) { diff --git a/src/remotes.tsx b/src/remotes.tsx index b9e4c751..ff55f51f 100644 --- a/src/remotes.tsx +++ b/src/remotes.tsx @@ -34,6 +34,17 @@ function getRemoteTitle(remote : RemoteType) { return remote.remotecanonicalname; } +function isStrEq(s1 : string, s2 : string) { + if (util.isBlank(s1) && util.isBlank(s2)) { + return true; + } + return s1 == s2; +} + +function isBoolEq(b1 : boolean, b2 : boolean) { + return (!!b1) == (!!b2); +} + @mobxReact.observer class AuthModeDropdown extends React.Component<{tempVal : OV}, {}> { active : OV = mobx.observable.box(false, {name: "AuthModeDropdown-active"}); @@ -131,6 +142,7 @@ class CreateRemote extends React.Component<{model : RemotesModalModel, remoteEdi tempManualMode : OV; tempPassword : OV; tempKeyFile : OV; + tempAutoInstall : OV; errorStr : OV; constructor(props : any) { @@ -143,9 +155,21 @@ class CreateRemote extends React.Component<{model : RemotesModalModel, remoteEdi this.tempConnectMode = mobx.observable.box("auto", {name: "CreateRemote-connectMode"}); this.tempKeyFile = mobx.observable.box("", {name: "CreateRemote-keystr"}); this.tempPassword = mobx.observable.box("", {name: "CreateRemote-password"}); + this.tempAutoInstall = mobx.observable.box(true, {name: "CreateRemote-autoinstall"}); this.errorStr = mobx.observable.box(remoteEdit.errorstr, {name: "CreateRemote-errorStr"}); } + remoteCName() : string { + let hostName = this.tempHostName.get(); + if (hostName == "") { + return "[no host]"; + } + if (hostName.indexOf("@") == -1) { + hostName = "[no user]@" + hostName; + } + return hostName; + } + getErrorStr() : string { if (this.errorStr.get() != null) { return this.errorStr.get(); @@ -190,7 +214,7 @@ class CreateRemote extends React.Component<{model : RemotesModalModel, remoteEdi kwargs["password"] = "" } kwargs["connectmode"] = this.tempConnectMode.get(); - kwargs["autoinstall"] = "1"; + kwargs["autoinstall"] = (this.tempAutoInstall.get() ? "1" : "0"); kwargs["visual"] = "1"; kwargs["submit"] = "1"; GlobalCommandRunner.createRemote(cname, kwargs); @@ -230,13 +254,20 @@ class CreateRemote extends React.Component<{model : RemotesModalModel, remoteEdi this.tempHostName.set(e.target.value); })(); } + + @boundMethod + handleChangeAutoInstall(val : boolean) : void { + mobx.action(() => { + this.tempAutoInstall.set(val); + })(); + } render() { - let {model, remote, remoteEdit} = this.props; + let {model, remoteEdit} = this.props; let authMode = this.tempAuthMode.get(); return (
-
Create New Remote
+
Create New Connection
user@host
@@ -304,11 +335,11 @@ class CreateRemote extends React.Component<{model : RemotesModalModel, remoteEdi
{authMode == "password" ? "SSH Password" : "Key Passphrase"} -
-
- -
-
+
+
+ +
+
@@ -326,6 +357,18 @@ class CreateRemote extends React.Component<{model : RemotesModalModel, remoteEdi
+
+
+
Auto Install
+
+ + If selected, will try to auto-install the mshell client if it is not installed or out of date. + +
+
+ +
+
Error: {this.getErrorStr()} @@ -350,6 +393,7 @@ class EditRemoteSettings extends React.Component<{model : RemotesModalModel, rem tempManualMode : OV; tempPassword : OV; tempKeyFile : OV; + tempAutoInstall : OV; constructor(props : any) { super(props); @@ -359,6 +403,36 @@ class EditRemoteSettings extends React.Component<{model : RemotesModalModel, rem this.tempConnectMode = mobx.observable.box(remote.connectmode, {name: "EditRemoteSettings-connectMode"}); this.tempKeyFile = mobx.observable.box(remoteEdit.keystr ?? "", {name: "EditRemoteSettings-keystr"}); this.tempPassword = mobx.observable.box(remoteEdit.haspassword ? PasswordUnchangedSentinel : "", {name: "EditRemoteSettings-password"}); + this.tempAutoInstall = mobx.observable.box(!!remote.autoinstall, {name: "EditRemoteSettings-autoinstall"}); + } + + componentDidUpdate() { + let {remote} = this.props; + if (remote == null || remote.archived) { + this.props.model.deSelectRemote(); + } + } + + @boundMethod + clickArchive() : void { + let {remote} = this.props; + if (remote.status == "connected") { + GlobalModel.showAlert({message: "Cannot archived a connected remote. Disconnect and try again."}); + return; + } + let prtn = GlobalModel.showAlert({message: "Are you sure you want to archive this connection?", confirm: true}); + prtn.then((confirm) => { + if (!confirm) { + return; + } + GlobalCommandRunner.archiveRemote(remote.remoteid); + }); + } + + @boundMethod + clickForceInstall() : void { + let {remote} = this.props; + GlobalCommandRunner.installRemote(remote.remoteid); } @boundMethod @@ -382,6 +456,13 @@ class EditRemoteSettings extends React.Component<{model : RemotesModalModel, rem })(); } + @boundMethod + handleChangeAutoInstall(val : boolean) : void { + mobx.action(() => { + this.tempAutoInstall.set(val); + })(); + } + @boundMethod canResetPw() : boolean { let {remoteEdit} = this.props; @@ -407,23 +488,39 @@ class EditRemoteSettings extends React.Component<{model : RemotesModalModel, rem @boundMethod submitRemote() : void { - let {remote} = this.props; + let {remote, remoteEdit} = this.props; let authMode = this.tempAuthMode.get(); let kwargs : Record = {}; - if (authMode == "key" || authMode == "key+password") { - kwargs["key"] = this.tempKeyFile.get(); - } - else { - kwargs["key"] = ""; + if (!isStrEq(this.tempKeyFile.get(), remoteEdit.keystr)) { + if (authMode == "key" || authMode == "key+password") { + kwargs["key"] = this.tempKeyFile.get(); + } + else { + kwargs["key"] = ""; + } } if (authMode == "password" || authMode == "key+password") { - kwargs["password"] = this.tempPassword.get(); + if (this.tempPassword.get() != PasswordUnchangedSentinel) { + kwargs["password"] = this.tempPassword.get(); + } } else { - kwargs["password"] = "" + if (remoteEdit.haspassword) { + kwargs["password"] = "" + } + } + if (!isStrEq(this.tempAlias.get(), remote.remotealias)) { + kwargs["alias"] = this.tempAlias.get(); + } + if (!isStrEq(this.tempConnectMode.get(), remote.connectmode)) { + kwargs["connectmode"] = this.tempConnectMode.get(); + } + if (!isBoolEq(this.tempAutoInstall.get(), remote.autoinstall)) { + kwargs["autoinstall"] = (this.tempAutoInstall.get() ? "1" : "0"); + } + if (Object.keys(kwargs).length == 0) { + return; } - kwargs["alias"] = this.tempAlias.get(); - kwargs["connectmode"] = this.tempConnectMode.get(); kwargs["visual"] = "1"; kwargs["submit"] = "1"; GlobalCommandRunner.editRemote(remote.remoteid, kwargs); @@ -453,7 +550,7 @@ class EditRemoteSettings extends React.Component<{model : RemotesModalModel, rem
{getRemoteTitle(remote)}
- Editing Remote Settings + Editing Connection Settings
@@ -523,6 +620,29 @@ class EditRemoteSettings extends React.Component<{model : RemotesModalModel, rem
+
+
+
Auto Install
+
+ + If selected, will try to auto-install the mshell client if it is not installed or out of date. + +
+
+ +
+
+
+
Actions
+
+
+ Archive Connection +
+
+ Force Install +
+
+
Error: {remoteEdit.errorstr ?? "An error occured"} @@ -604,38 +724,17 @@ class RemoteDetailView extends React.Component<{model : RemotesModalModel, remot this.props.model.startEditAuth(); } - @boundMethod - clickArchive(remoteId : string) : void { - let {remote} = this.props; - if (remote.status == "connected") { - GlobalModel.showAlert({message: "Cannot archived a connected remote. Disconnect and try again."}); - return; - } - let prtn = GlobalModel.showAlert({message: "Are you sure you want to archive this connection?", confirm: true}); - prtn.then((confirm) => { - if (!confirm) { - return; - } - GlobalCommandRunner.archiveRemote(remoteId); - }); - } - - @boundMethod - editAlias(remoteId : string, alias : string) : void { - this.props.model.startEditAuth(); - } - renderInstallStatus(remote : RemoteType) : any { let statusStr : string = null; if (remote.installstatus == "disconnected") { if (remote.needsmshellupgrade) { - statusStr = "mshell " + remote.mshellversion + " (needs upgrade)"; + statusStr = "mshell " + remote.mshellversion + " - needs upgrade"; } else if (util.isBlank(remote.mshellversion)) { statusStr = "mshell unknown"; } else { - statusStr = "mshell " + remote.mshellversion + " (current)"; + statusStr = "mshell " + remote.mshellversion + " - current"; } } else { @@ -644,6 +743,9 @@ class RemoteDetailView extends React.Component<{model : RemotesModalModel, remot if (statusStr == null) { return null; } + if (remote.autoinstall) { + statusStr = statusStr + " (autoinstall)"; + } return (
Install Status
@@ -760,22 +862,14 @@ class RemoteDetailView extends React.Component<{model : RemotesModalModel, remot
Alias
- {remoteAliasText} -
this.editAlias()} className="button is-plain is-outlined is-small is-inline-height ml-2 update-auth-button"> - - Update Alias -
+ {remoteAliasText}
Auth Type
- {remote.authtype} -
this.editAuthSettings()} className="button is-plain is-outlined is-small is-inline-height ml-2 update-auth-button"> - - Update Auth Settings -
+ {remote.authtype}
local @@ -789,16 +883,14 @@ class RemoteDetailView extends React.Component<{model : RemotesModalModel, remot
{this.renderInstallStatus(remote)} - -
-
Archive
-
-
this.clickArchive(remote.remoteid)} className="button is-prompt-danger is-outlined is-small is-inline-height"> - Archive This Connection -
+
+
Actions
+
+
this.editAuthSettings()} className="button is-prompt-green is-outlined is-small is-inline-height"> + Edit Connection Settings
- +
{remoteMessage}