diff --git a/src/app/app.tsx b/src/app/app.tsx index 682d1e58..7b67a4cd 100644 --- a/src/app/app.tsx +++ b/src/app/app.tsx @@ -74,9 +74,6 @@ class App extends React.Component<{}, {}> { } render() { - let screenSettingsModal = GlobalModel.screenSettingsModal.get(); - let sessionSettingsModal = GlobalModel.sessionSettingsModal.get(); - let lineSettingsModal = GlobalModel.lineSettingsModal.get(); let clientSettingsModal = GlobalModel.clientSettingsModal.get(); let remotesModel = GlobalModel.remotesModel; let disconnected = !GlobalModel.ws.open.get() || !GlobalModel.waveSrvRunning.get(); @@ -121,22 +118,6 @@ class App extends React.Component<{}, {}> { - - - - - - - - - - - - ); } diff --git a/src/app/appconst.ts b/src/app/appconst.ts index b833660e..df63d49d 100644 --- a/src/app/appconst.ts +++ b/src/app/appconst.ts @@ -3,3 +3,7 @@ export const CREATE_REMOTE = "createRemote"; export const VIEW_REMOTE = "viewRemote"; export const EDIT_REMOTE = "editRemote"; export const ALERT = "alert"; +export const SCREEN_SETTINGS = "screenSettings"; +export const SESSION_SETTINGS = "sessionSettings"; +export const LINE_SETTINGS = "lineSettings"; +export const CLIENT_SETTINGS = "clientSettings"; diff --git a/src/app/common/common.less b/src/app/common/common.less index afd60e82..0901315a 100644 --- a/src/app/common/common.less +++ b/src/app/common/common.less @@ -610,7 +610,7 @@ position: relative; background-color: transparent; height: 44px; - min-width: 412px; + min-width: 150px; width: 100%; border: 1px solid var(--element-separator, rgba(241, 246, 243, 0.15)); border-radius: 6px; @@ -618,6 +618,10 @@ 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; + &.no-label { + height: 34px; + } + &-label { position: absolute; left: 16px; @@ -841,7 +845,7 @@ justify-content: center; i { - font-size: 16px; + font-size: 13px; } } @@ -865,11 +869,11 @@ background-color: #444; border-radius: 5px; overflow: hidden; - max-width: 300px; + width: 300px; i { display: inline; - font-size: 16px; + font-size: 13px; fill: @base-color; padding-top: 0.2em; } @@ -1114,6 +1118,11 @@ line-height: 20px; border-bottom: 1px solid rgba(250, 250, 250, 0.1); + .wave-modal-title { + color: #eceeec; + font-size: 15px; + } + button { i { font-size: 18px; @@ -1132,8 +1141,8 @@ width: 100%; padding: 0 20px 20px; - button:first-child { - margin-right: 8px; + button:last-child { + margin-left: 8px; } } } diff --git a/src/app/common/common.tsx b/src/app/common/common.tsx index 2b09d723..00ac7e31 100644 --- a/src/app/common/common.tsx +++ b/src/app/common/common.tsx @@ -150,6 +150,7 @@ interface TooltipProps { message: React.ReactNode; icon?: React.ReactNode; // Optional icon property children: React.ReactNode; + className?: string; } interface TooltipState { @@ -185,8 +186,8 @@ class Tooltip extends React.Component { if (iconElement) { const rect = iconElement.getBoundingClientRect(); return { - top: `${rect.bottom + window.scrollY - 29.5}px`, - left: `${rect.left + window.scrollX + rect.width / 2 - 19}px`, + top: `${rect.bottom + window.scrollY - 29}px`, + left: `${rect.left + window.scrollX + rect.width / 2 - 17.5}px`, }; } return {}; @@ -199,7 +200,7 @@ class Tooltip extends React.Component { const style = this.calculatePosition(); return ReactDOM.createPortal( -
+
{this.props.icon &&
{this.props.icon}
}
{this.props.message}
, @@ -864,7 +865,7 @@ interface DropdownDecorationProps { } interface DropdownProps { - label: string; + label?: string; options: { value: string; label: string }[]; value?: string; className?: string; @@ -1051,7 +1052,7 @@ class Dropdown extends React.Component { {options.map((option, index) => (
this.handleSelect(option.value, e)} @@ -1068,8 +1069,9 @@ class Dropdown extends React.Component { return (
{ onFocus={this.handleFocus} > {decoration?.startDecoration && <>{decoration.startDecoration}} + +
+ {label} +
+
- {label} -
-
{selectedOptionLabel}
@@ -1106,7 +1112,7 @@ interface ModalHeaderProps { const ModalHeader: React.FC = ({ onClose, title }) => (
- {
{title}
} + {
{title}
} diff --git a/src/app/common/modals/modals.less b/src/app/common/modals/modals.less index 1aa1232f..391c2152 100644 --- a/src/app/common/modals/modals.less +++ b/src/app/common/modals/modals.less @@ -396,13 +396,109 @@ gap: 12px; align-self: stretch; width: 100%; + + > div { + width: 100%; + } } } } .screen-settings-modal { width: 640px; - min-height: 329px; + + .wave-modal-content { + gap: 24px; + + .wave-modal-body { + display: flex; + padding: 0px 20px; + flex-direction: column; + align-items: flex-start; + gap: 4px; + align-self: stretch; + width: 100%; + + .screen-settings-dropdown { + width: 412px; + + .lefticon { + position: absolute; + top: 50%; + left: 16px; + transform: translateY(-50%); + + .globe-icon { + width: 16px; + height: 16px; + flex-shrink: 0; + } + + .status-icon { + position: absolute; + left: 7px; + top: 8px; + } + } + } + + .archived-label, + .actions-label { + div:first-child { + margin-right: 5px; + } + div:last-child i { + font-size: 13px; + } + } + } + } +} + +.screen-settings-tooltip .wave-tooltip-icon { + i { + font-size: 13px; + } +} + +.session-settings-modal { + width: 640px; + + .wave-modal-content { + gap: 24px; + + .wave-modal-body { + display: flex; + padding: 0px 20px; + flex-direction: column; + align-items: flex-start; + gap: 4px; + align-self: stretch; + width: 100%; + } + } +} + +.line-settings-modal { + width: 640px; + + .wave-modal-content { + gap: 24px; + + .wave-modal-body { + display: flex; + padding: 0px 20px; + flex-direction: column; + align-items: flex-start; + gap: 4px; + align-self: stretch; + width: 100%; + } + } +} + +.client-settings-modal { + width: 640px; .wave-modal-content { gap: 24px; @@ -470,6 +566,8 @@ } .alert-modal { + width: 500px; + .wave-modal-content { .wave-modal-body { padding: 40px 20px; diff --git a/src/app/common/modals/modalsRegistry.tsx b/src/app/common/modals/modalsRegistry.tsx index a5c5e6df..833d99d4 100644 --- a/src/app/common/modals/modalsRegistry.tsx +++ b/src/app/common/modals/modalsRegistry.tsx @@ -9,6 +9,7 @@ import { EditRemoteConnModal, AlertModal, } from "./modals"; +import { ScreenSettingsModal, SessionSettingsModal, LineSettingsModal, ClientSettingsModal } from "./settings"; import * as constants from "../../appconst"; const modalsRegistry: { [key: string]: () => React.ReactElement } = { @@ -17,6 +18,10 @@ const modalsRegistry: { [key: string]: () => React.ReactElement } = { [constants.VIEW_REMOTE]: () => , [constants.EDIT_REMOTE]: () => , [constants.ALERT]: () => , + [constants.SCREEN_SETTINGS]: () => , + [constants.SESSION_SETTINGS]: () => , + [constants.LINE_SETTINGS]: () => , + [constants.CLIENT_SETTINGS]: () => , }; export { modalsRegistry }; diff --git a/src/app/common/modals/settings.tsx b/src/app/common/modals/settings.tsx index 03e3e3a6..9e43ca33 100644 --- a/src/app/common/modals/settings.tsx +++ b/src/app/common/modals/settings.tsx @@ -15,16 +15,17 @@ import { MaxFontSize, TabIcons, Screen, + Session, } from "../../../model/model"; -import { Toggle, InlineSettingsTextEdit, SettingsError, InfoMessage, Modal } from "../common"; -import { LineType, RendererPluginType, ClientDataType, CommandRtnType } from "../../../types/types"; -import { ConnectionDropdown } from "../../connections_deprecated/connections"; +import { Toggle, InlineSettingsTextEdit, SettingsError, InfoMessage, Modal, Dropdown, Tooltip } from "../common"; +import { LineType, RendererPluginType, ClientDataType, CommandRtnType, RemoteType } from "../../../types/types"; import { PluginModel } from "../../../plugins/plugins"; import * as util from "../../../util/util"; import { commandRtnHandler } from "../../../util/util"; import { ReactComponent as SquareIcon } from "../../assets/icons/tab/square.svg"; -import { ReactComponent as XmarkIcon } from "../../assets/icons/line/xmark.svg"; import { ReactComponent as AngleDownIcon } from "../../assets/icons/history/angle-down.svg"; +import { ReactComponent as GlobeIcon } from "../../assets/icons/globe.svg"; +import { ReactComponent as StatusCircleIcon } from "../../assets/icons/statuscircle.svg"; import "./modals.less"; @@ -58,18 +59,47 @@ Are you sure you want to stop web-sharing this tab? `.trim(); @mobxReact.observer -class ScreenSettingsModal extends React.Component<{ sessionId: string; screenId: string }, {}> { +class ScreenSettingsModal extends React.Component<{}, {}> { shareCopied: OV = mobx.observable.box(false, { name: "ScreenSettings-shareCopied" }); errorMessage: OV = mobx.observable.box(null, { name: "ScreenSettings-errorMessage" }); screen: Screen; + sessionId: string; + screenId: string; + remotes: RemoteType[]; - constructor(props: any) { + constructor(props) { super(props); - let { sessionId, screenId } = props; + let screenSettingsModal = GlobalModel.screenSettingsModal.get(); + let { sessionId, screenId } = screenSettingsModal; + this.sessionId = sessionId; + this.screenId = screenId; this.screen = GlobalModel.getScreenById(sessionId, screenId); - if (this.screen == null) { + if (this.screen == null || sessionId == null || screenId == null) { return; } + this.remotes = GlobalModel.remotes; + } + + @boundMethod + getOptions(): { label: string; value: string }[] { + return this.remotes + .filter((r) => !r.archived) + .map((remote) => ({ + ...remote, + label: + remote.remotealias && !util.isBlank(remote.remotealias) + ? `${remote.remotecanonicalname}` + : remote.remotecanonicalname, + value: remote.remotecanonicalname, + })) + .sort((a, b) => { + let connValA = util.getRemoteConnVal(a); + let connValB = util.getRemoteConnVal(b); + if (connValA !== connValB) { + return connValA - connValB; + } + return a.remoteidx - b.remoteidx; + }); } @boundMethod @@ -77,19 +107,18 @@ class ScreenSettingsModal extends React.Component<{ sessionId: string; screenId: mobx.action(() => { GlobalModel.screenSettingsModal.set(null); })(); + GlobalModel.modalsModel.popModal(); } @boundMethod selectTabColor(color: string): void { - let { sessionId, screenId } = this.props; - let screen = GlobalModel.getScreenById(sessionId, screenId); - if (screen == null) { + if (this.screen == null) { return; } - if (screen.getTabColor() == color) { + if (this.screen.getTabColor() == color) { return; } - let prtn = GlobalCommandRunner.screenSetSettings(this.props.screenId, { tabcolor: color }, false); + let prtn = GlobalCommandRunner.screenSetSettings(this.screenId, { tabcolor: color }, false); commandRtnHandler(prtn, this.errorMessage); } @@ -104,26 +133,22 @@ class ScreenSettingsModal extends React.Component<{ sessionId: string; screenId: @boundMethod handleChangeArchived(val: boolean): void { - let { sessionId, screenId } = this.props; - let screen = GlobalModel.getScreenById(sessionId, screenId); - if (screen == null) { + if (this.screen == null) { return; } - if (screen.archived.get() == val) { + if (this.screen.archived.get() == val) { return; } - let prtn = GlobalCommandRunner.screenArchive(this.props.screenId, val); + let prtn = GlobalCommandRunner.screenArchive(this.screenId, val); commandRtnHandler(prtn, this.errorMessage); } @boundMethod handleChangeWebShare(val: boolean): void { - let { sessionId, screenId } = this.props; - let screen = GlobalModel.getScreenById(sessionId, screenId); - if (screen == null) { + if (this.screen == null) { return; } - if (screen.isWebShared() == val) { + if (this.screen.isWebShared() == val) { return; } let message = val ? WebShareConfirmMarkdown : WebStopShareConfirmMarkdown; @@ -132,19 +157,17 @@ class ScreenSettingsModal extends React.Component<{ sessionId: string; screenId: if (!result) { return; } - let prtn = GlobalCommandRunner.screenWebShare(screen.screenId, val); + let prtn = GlobalCommandRunner.screenWebShare(this.screen.screenId, val); commandRtnHandler(prtn, this.errorMessage); }); } @boundMethod copyShareLink(): void { - let { sessionId, screenId } = this.props; - let screen = GlobalModel.getScreenById(sessionId, screenId); - if (screen == null) { + if (this.screen == null) { return null; } - let shareLink = screen.getWebShareUrl(); + let shareLink = this.screen.getWebShareUrl(); if (shareLink == null) { return; } @@ -161,29 +184,25 @@ class ScreenSettingsModal extends React.Component<{ sessionId: string; screenId: @boundMethod inlineUpdateName(val: string): void { - let { sessionId, screenId } = this.props; - let screen = GlobalModel.getScreenById(sessionId, screenId); - if (screen == null) { + if (this.screen == null) { return; } - if (util.isStrEq(val, screen.name.get())) { + if (util.isStrEq(val, this.screen.name.get())) { return; } - let prtn = GlobalCommandRunner.screenSetSettings(this.props.screenId, { name: val }, false); + let prtn = GlobalCommandRunner.screenSetSettings(this.screenId, { name: val }, false); commandRtnHandler(prtn, this.errorMessage); } @boundMethod inlineUpdateShareName(val: string): void { - let { sessionId, screenId } = this.props; - let screen = GlobalModel.getScreenById(sessionId, screenId); - if (screen == null) { + if (this.screen == null) { return; } - if (util.isStrEq(val, screen.getShareName())) { + if (util.isStrEq(val, this.screen.getShareName())) { return; } - let prtn = GlobalCommandRunner.screenSetSettings(this.props.screenId, { sharename: val }, false); + let prtn = GlobalCommandRunner.screenSetSettings(this.screenId, { sharename: val }, false); commandRtnHandler(prtn, this.errorMessage); } @@ -196,9 +215,7 @@ class ScreenSettingsModal extends React.Component<{ sessionId: string; screenId: @boundMethod handleDeleteScreen(): void { - let { sessionId, screenId } = this.props; - let screen = GlobalModel.getScreenById(sessionId, screenId); - if (screen == null) { + if (this.screen == null) { return; } let message = ScreenDeleteMessage; @@ -207,8 +224,9 @@ class ScreenSettingsModal extends React.Component<{ sessionId: string; screenId: if (!result) { return; } - let prtn = GlobalCommandRunner.screenPurge(screenId); + let prtn = GlobalCommandRunner.screenPurge(this.screenId); commandRtnHandler(prtn, this.errorMessage); + GlobalModel.modalsModel.popModal(); }); } @@ -219,16 +237,15 @@ class ScreenSettingsModal extends React.Component<{ sessionId: string; screenId: } render() { - let { sessionId, screenId } = this.props; - let inline = false; let screen = this.screen; if (screen == null) { return null; } - console.log("screen.getTabIcon()", screen.getTabIcon()); let color: string = null; let icon: string = null; + let index: number = 0; let curRemote = GlobalModel.getRemote(GlobalModel.getActiveScreen().getCurRemoteInstance().remoteid); + return ( @@ -253,10 +270,22 @@ class ScreenSettingsModal extends React.Component<{ sessionId: string; screenId:
Connection
- + + +
+ ), + }} />
@@ -295,9 +324,9 @@ class ScreenSettingsModal extends React.Component<{ sessionId: string; screenId: {screen.getTabIcon()}
|
- +
this.selectTabIcon(icon)} > @@ -308,22 +337,30 @@ class ScreenSettingsModal extends React.Component<{ sessionId: string; screenId:
-
-
Archived
- - Archive will hide the tab. Commands and output will be retained in history. - +
+
Archived
+ } + className="screen-settings-tooltip" + > + +
-
+
Actions
- - Delete will remove the tab, removing all commands and output from history. - + } + className="screen-settings-tooltip" + > + +
{ +class SessionSettingsModal extends React.Component<{}, {}> { errorMessage: OV = mobx.observable.box(null, { name: "ScreenSettings-errorMessage" }); + session: Session; + sessionId: string; constructor(props: any) { super(props); - let { sessionId } = props; - let session = GlobalModel.getSessionById(sessionId); - if (session == null) { + let sessionId = GlobalModel.sessionSettingsModal.get(); + this.session = GlobalModel.getSessionById(sessionId); + if (this.session == null) { return; } } @@ -360,46 +399,42 @@ class SessionSettingsModal extends React.Component<{ sessionId: string }, {}> { mobx.action(() => { GlobalModel.sessionSettingsModal.set(null); })(); + GlobalModel.modalsModel.popModal(); } @boundMethod handleInlineChangeName(newVal: string): void { - let { sessionId } = this.props; - let session = GlobalModel.getSessionById(sessionId); - if (session == null) { + if (this.session == null) { return; } - if (util.isStrEq(newVal, session.name.get())) { + if (util.isStrEq(newVal, this.session.name.get())) { return; } - let prtn = GlobalCommandRunner.sessionSetSettings(this.props.sessionId, { name: newVal }, false); + let prtn = GlobalCommandRunner.sessionSetSettings(this.sessionId, { name: newVal }, false); commandRtnHandler(prtn, this.errorMessage); } @boundMethod handleChangeArchived(val: boolean): void { - let { sessionId } = this.props; - let session = GlobalModel.getSessionById(sessionId); - if (session == null) { + if (this.session == null) { return; } - if (session.archived.get() == val) { + if (this.session.archived.get() == val) { return; } - let prtn = GlobalCommandRunner.sessionArchive(this.props.sessionId, val); + let prtn = GlobalCommandRunner.sessionArchive(this.sessionId, val); commandRtnHandler(prtn, this.errorMessage); } @boundMethod handleDeleteSession(): void { - let { sessionId } = this.props; let message = SessionDeleteMessage; let alertRtn = GlobalModel.showAlert({ message: message, confirm: true, markdown: true }); alertRtn.then((result) => { if (!result) { return; } - let prtn = GlobalCommandRunner.sessionPurge(this.props.sessionId); + let prtn = GlobalCommandRunner.sessionPurge(this.sessionId); commandRtnHandler(prtn, this.errorMessage); }); } @@ -412,86 +447,82 @@ class SessionSettingsModal extends React.Component<{ sessionId: string }, {}> { } render() { - let { sessionId } = this.props; - let session = GlobalModel.getSessionById(sessionId); - if (session == null) { + if (this.session == null) { return null; } return ( -
-
-
-
-
workspace settings ({session.name.get()})
-
- + + +
+
+
Name
+
+
-
-
-
-
Name
-
- -
-
-
-
-
Archived
- - Archive will hide the workspace from the active menu. Commands and output will be - retained in history. - -
-
- -
-
-
-
-
Actions
- - Delete will remove the workspace, removing all commands and output from history. - -
-
-
- Delete Workspace -
-
-
-
-
-
- Close +
+
+
Archived
+ + Archive will hide the workspace from the active menu. Commands and output will be + retained in history. +
-
+
+ +
+
+
+
+
Actions
+ + Delete will remove the workspace, removing all commands and output from history. + +
+
+
+ Delete Workspace +
+
+
+
-
+ + ); } } @mobxReact.observer -class LineSettingsModal extends React.Component<{ linenum: number }, {}> { +class LineSettingsModal extends React.Component<{}, {}> { rendererDropdownActive: OV = mobx.observable.box(false, { name: "lineSettings-rendererDropdownActive" }); errorMessage: OV = mobx.observable.box(null, { name: "ScreenSettings-errorMessage" }); + linenum: number; + + constructor(props: any) { + super(props); + this.linenum = GlobalModel.lineSettingsModal.get(); + if (this.linenum == null) { + return; + } + } @boundMethod closeModal(): void { mobx.action(() => { GlobalModel.lineSettingsModal.set(null); })(); + GlobalModel.modalsModel.popModal(); } @boundMethod @@ -516,7 +547,7 @@ class LineSettingsModal extends React.Component<{ linenum: number }, {}> { if (screen == null) { return; } - return screen.getLineByNum(this.props.linenum); + return screen.getLineByNum(this.linenum); } @boundMethod @@ -532,47 +563,42 @@ class LineSettingsModal extends React.Component<{ linenum: number }, {}> { })(); } - renderRendererDropdown(): any { - let line = this.getLine(); - if (line == null) { - return null; - } - let plugins = PluginModel.rendererPlugins; - let plugin: RendererPluginType = null; - let renderer = line.renderer ?? "terminal"; - return ( -
-
- -
-
-
-
this.clickSetRenderer(null)} key="terminal" className="dropdown-item"> - terminal -
- -
this.clickSetRenderer(plugin.name)} - key={plugin.name} - className="dropdown-item" - > - {plugin.name} -
-
-
this.clickSetRenderer("none")} key="none" className="dropdown-item"> - none -
-
-
-
- ); + getOptions(plugins: RendererPluginType[]) { + // Add label and value to each object in the array + const options = plugins.map((item) => ({ + ...item, + label: item.name, + value: item.name, + })); + + // Create an additional object with label "terminal" and value null + const terminalItem = { + label: "terminal", + value: null, + name: null, + rendererType: null, + heightType: null, + dataType: null, + collapseType: null, + globalCss: null, + mimeTypes: null, + }; + + // Create an additional object with label "none" and value none + const noneItem = { + label: "none", + value: "none", + name: null, + rendererType: null, + heightType: null, + dataType: null, + collapseType: null, + globalCss: null, + mimeTypes: null, + }; + + // Combine the options with the terminal item + return [terminalItem, ...options, noneItem]; } render() { @@ -583,37 +609,35 @@ class LineSettingsModal extends React.Component<{ linenum: number }, {}> { }, 0); return null; } + let plugins = PluginModel.rendererPlugins; + let renderer = line.renderer ?? "terminal"; + return ( -
-
-
-
-
line settings ({line.linenum})
-
- + + +
+
+
Renderer
+
+
-
-
-
-
Renderer
-
{this.renderRendererDropdown()}
-
-
-
Archived
-
- -
-
- -
-
-
- Close +
+
Archived
+
+
-
+
+ +
-
+ + ); } } @@ -625,9 +649,7 @@ class ClientSettingsModal extends React.Component<{}, {}> { @boundMethod closeModal(): void { - mobx.action(() => { - GlobalModel.clientSettingsModal.set(false); - })(); + GlobalModel.modalsModel.popModal(); } @boundMethod @@ -638,7 +660,8 @@ class ClientSettingsModal extends React.Component<{}, {}> { } @boundMethod - handleChangeFontSize(newFontSize: number): void { + handleChangeFontSize(fontSize: string): void { + let newFontSize = Number(fontSize); this.fontSizeDropdownActive.set(false); if (GlobalModel.termFontSize.get() == newFontSize) { return; @@ -665,36 +688,12 @@ class ClientSettingsModal extends React.Component<{}, {}> { commandRtnHandler(prtn, this.errorMessage); } - renderFontSizeDropdown(): any { - let availableFontSizes = []; + getFontSizes(): any { + let availableFontSizes: { label: string; value: number }[] = []; for (let s = MinFontSize; s <= MaxFontSize; s++) { - availableFontSizes.push(s); + availableFontSizes.push({ label: s + "px", value: s }); } - let fsize: number = 0; - let curSize = GlobalModel.termFontSize.get(); - return ( -
-
- -
-
-
- -
this.handleChangeFontSize(fsize)} - key={fsize + "px"} - className="dropdown-item" - > - {fsize}px -
-
-
-
-
- ); + return availableFontSizes; } @boundMethod @@ -729,89 +728,85 @@ class ClientSettingsModal extends React.Component<{}, {}> { let maxTokensStr = String( openAIOpts.maxtokens == null || openAIOpts.maxtokens == 0 ? 1000 : openAIOpts.maxtokens ); + let curFontSize = GlobalModel.termFontSize.get(); return ( -
-
-
-
-
Client settings
-
- + + +
+
+
Term Font Size
+
+
-
-
-
-
Term Font Size
-
{this.renderFontSizeDropdown()}
-
-
-
Client ID
-
{cdata.clientid}
-
-
-
Client Version
-
- {VERSION} {BUILD} -
-
-
-
DB Version
-
{cdata.dbversion}
-
-
-
Basic Telemetry
-
- -
-
-
-
OpenAI Token
-
- -
-
-
-
OpenAI Model
-
- -
-
-
-
OpenAI MaxTokens
-
- -
-
-
-
-
- Close +
+
Client ID
+
{cdata.clientid}
+
+
+
Client Version
+
+ {VERSION} {BUILD}
-
+
+
+
DB Version
+
{cdata.dbversion}
+
+
+
Basic Telemetry
+
+ +
+
+
+
OpenAI Token
+
+ +
+
+
+
OpenAI Model
+
+ +
+
+
+
OpenAI MaxTokens
+
+ +
+
+
-
+ + ); } } diff --git a/src/app/line/linecomps.tsx b/src/app/line/linecomps.tsx index a57eba37..e6746323 100644 --- a/src/app/line/linecomps.tsx +++ b/src/app/line/linecomps.tsx @@ -39,6 +39,7 @@ import { PluginModel } from "../../plugins/plugins"; import { Prompt } from "../common/prompt/prompt"; import * as lineutil from "./lineutil"; import { ErrorBoundary } from "../../app/common/error/errorboundary"; +import * as constants from "../appconst"; import { ReactComponent as CheckIcon } from "../assets/icons/line/check.svg"; import { ReactComponent as CommentIcon } from "../assets/icons/line/comment.svg"; @@ -439,6 +440,7 @@ class LineCmd extends React.Component< mobx.action(() => { GlobalModel.lineSettingsModal.set(line.linenum); })(); + GlobalModel.modalsModel.pushModal(constants.LINE_SETTINGS); } } diff --git a/src/app/sidebar/sidebar.tsx b/src/app/sidebar/sidebar.tsx index 9793b052..56e52ae9 100644 --- a/src/app/sidebar/sidebar.tsx +++ b/src/app/sidebar/sidebar.tsx @@ -15,7 +15,6 @@ import { ReactComponent as HelpIcon } from "../assets/icons/help.svg"; import { ReactComponent as SettingsIcon } from "../assets/icons/settings.svg"; import { ReactComponent as DiscordIcon } from "../assets/icons/discord.svg"; import { ReactComponent as HistoryIcon } from "../assets/icons/history.svg"; -import { ReactComponent as FavoritesIcon } from "../assets/icons/favourites.svg"; import { ReactComponent as AppsIcon } from "../assets/icons/apps.svg"; import { ReactComponent as ConnectionsIcon } from "../assets/icons/connections.svg"; import { ReactComponent as WorkspacesIcon } from "../assets/icons/workspaces.svg"; @@ -25,6 +24,7 @@ import { ReactComponent as ActionsIcon } from "../assets/icons/tab/actions.svg"; import localizedFormat from "dayjs/plugin/localizedFormat"; import { GlobalModel, GlobalCommandRunner, Session } from "../../model/model"; import { sortAndFilterRemotes, isBlank, openLink } from "../../util/util"; +import * as constants from "../appconst"; import "./sidebar.less"; @@ -130,9 +130,7 @@ class MainSideBar extends React.Component<{}, {}> { @boundMethod handleSettingsClick(): void { - mobx.action(() => { - GlobalModel.clientSettingsModal.set(true); - })(); + GlobalModel.modalsModel.pushModal(constants.CLIENT_SETTINGS); } @boundMethod @@ -142,6 +140,7 @@ class MainSideBar extends React.Component<{}, {}> { mobx.action(() => { GlobalModel.sessionSettingsModal.set(session.sessionId); })(); + GlobalModel.modalsModel.pushModal(constants.SESSION_SETTINGS); } getSessions() { diff --git a/src/app/workspace/screen/screenview.less b/src/app/workspace/screen/screenview.less index 38d3346e..30672b0c 100644 --- a/src/app/workspace/screen/screenview.less +++ b/src/app/workspace/screen/screenview.less @@ -131,6 +131,29 @@ gap: 8px; align-self: stretch; + .conn-dropdown { + width: 412px; + + .lefticon { + position: absolute; + top: 50%; + left: 16px; + transform: translateY(-50%); + + .globe-icon { + width: 16px; + height: 16px; + flex-shrink: 0; + } + + .status-icon { + position: absolute; + left: 7px; + top: 8px; + } + } + } + &.conn-section { gap: 8px; } @@ -152,7 +175,7 @@ padding: 8px 0 8px 2px; align-items: flex-start; gap: 14px; - + &.tabicon-list { gap: 12px; } @@ -164,7 +187,6 @@ position: relative; font-size: 14px; - &.tabicon { display: flex; align-items: center; diff --git a/src/app/workspace/screen/screenview.tsx b/src/app/workspace/screen/screenview.tsx index d7152bff..b77f36c4 100644 --- a/src/app/workspace/screen/screenview.tsx +++ b/src/app/workspace/screen/screenview.tsx @@ -19,12 +19,13 @@ import { getRemoteStr } from "../../common/prompt/prompt"; import { GlobalModel, ScreenLines, Screen, Session } from "../../../model/model"; import { Line } from "../../line/linecomps"; import { LinesView } from "../../line/linesview"; -import { ConnectionDropdown } from "../../connections_deprecated/connections"; import * as util from "../../../util/util"; -import { TextField } from "../../common/common"; +import { TextField, Dropdown } from "../../common/common"; import { ReactComponent as EllipseIcon } from "../../assets/icons/ellipse.svg"; import { ReactComponent as Check12Icon } from "../../assets/icons/check12.svg"; import { ReactComponent as SquareIcon } from "../../assets/icons/tab/square.svg"; +import { ReactComponent as GlobeIcon } from "../../assets/icons/globe.svg"; +import { ReactComponent as StatusCircleIcon } from "../../assets/icons/statuscircle.svg"; import "./screenview.less"; import "./tabs.less"; @@ -53,6 +54,12 @@ class ScreenView extends React.Component<{ session: Session; screen: Screen }, { class NewTabSettings extends React.Component<{ screen: Screen }, {}> { connDropdownActive: OV = mobx.observable.box(false, { name: "NewTabSettings-connDropdownActive" }); errorMessage: OV = mobx.observable.box(null, { name: "NewTabSettings-errorMessage" }); + remotes: T.RemoteType[]; + + constructor(props) { + super(props); + this.remotes = GlobalModel.remotes; + } @boundMethod selectTabColor(color: string): void { @@ -99,6 +106,28 @@ class NewTabSettings extends React.Component<{ screen: Screen }, {}> { GlobalModel.remotesModel.openAddModal({ remoteedit: true }); } + @boundMethod + getOptions(): { label: string; value: string }[] { + return this.remotes + .filter((r) => !r.archived) + .map((remote) => ({ + ...remote, + label: + remote.remotealias && !util.isBlank(remote.remotealias) + ? `${remote.remotecanonicalname}` + : remote.remotecanonicalname, + value: remote.remotecanonicalname, + })) + .sort((a, b) => { + let connValA = util.getRemoteConnVal(a); + let connValB = util.getRemoteConnVal(b); + if (connValA !== connValB) { + return connValA - connValB; + } + return a.remoteidx - b.remoteidx; + }); + } + renderTabIconSelector(): React.ReactNode { let { screen } = this.props; let curIcon = screen.getTabIcon(); @@ -163,6 +192,7 @@ class NewTabSettings extends React.Component<{ screen: Screen }, {}> { let { screen } = this.props; let rptr = screen.curRemote.get(); let curRemote = GlobalModel.getRemote(GlobalModel.getActiveScreen().getCurRemoteInstance().remoteid); + return (
@@ -179,11 +209,20 @@ class NewTabSettings extends React.Component<{ screen: Screen }, {}> { You're connected to [{getRemoteStr(rptr)}]. Do you want to change it?
- + + +
+ ), + }} />
diff --git a/src/app/workspace/screen/tabs.tsx b/src/app/workspace/screen/tabs.tsx index 8c00c488..45cff19d 100644 --- a/src/app/workspace/screen/tabs.tsx +++ b/src/app/workspace/screen/tabs.tsx @@ -11,11 +11,12 @@ import cn from "classnames"; import { debounce } from "throttle-debounce"; import dayjs from "dayjs"; import localizedFormat from "dayjs/plugin/localizedFormat"; -import { GlobalModel, GlobalCommandRunner, Session, Screen, TabIcons } from "../../../model/model"; +import { GlobalModel, GlobalCommandRunner, Session, Screen } from "../../../model/model"; import { renderCmdText } from "../../common/common"; import { ReactComponent as SquareIcon } from "../../assets/icons/tab/square.svg"; import { ReactComponent as ActionsIcon } from "../../assets/icons/tab/actions.svg"; import { ReactComponent as AddIcon } from "../../assets/icons/add.svg"; +import * as constants from "../../appconst"; import "../workspace.less"; import "./tabs.less"; @@ -100,6 +101,7 @@ class ScreenTabs extends React.Component<{ session: Session }, {}> { mobx.action(() => { GlobalModel.screenSettingsModal.set({ sessionId: screen.sessionId, screenId: screen.screenId }); })(); + GlobalModel.modalsModel.pushModal(constants.SCREEN_SETTINGS); } renderTabIcon = (screen: Screen): React.ReactNode => { diff --git a/src/util/util.ts b/src/util/util.ts index 0407f9b2..ca7766fb 100644 --- a/src/util/util.ts +++ b/src/util/util.ts @@ -390,7 +390,7 @@ function getColorRGB(colorInput) { return computedColorStyle; } -function commandRtnHandler(prtn: Promise, errorMessage: OV) { +function commandRtnHandler(prtn: Promise, errorMessage: OV) { prtn.then((crtn) => { if (crtn.success) { return; @@ -424,4 +424,5 @@ export { openLink, getColorRGB, commandRtnHandler, + getRemoteConnVal, };