diff --git a/src/app/common/modals/tabswitcher.tsx b/src/app/common/modals/tabswitcher.tsx index b45057bb..3618c4ac 100644 --- a/src/app/common/modals/tabswitcher.tsx +++ b/src/app/common/modals/tabswitcher.tsx @@ -5,7 +5,7 @@ import * as React from "react"; import * as mobxReact from "mobx-react"; import * as mobx from "mobx"; import { boundMethod } from "autobind-decorator"; -import { For } from "tsx-control-statements/components"; +import { If, For } from "tsx-control-statements/components"; import cn from "classnames"; import { GlobalModel, GlobalCommandRunner } from "../../../models"; import { Modal, TextField, InputDecoration, Tooltip } from "../elements"; @@ -15,6 +15,11 @@ import { ReactComponent as SquareIcon } from "../../assets/icons/tab/square.svg" import "./tabswitcher.less"; +type ViewDataType = { + label: string; + value: string; +}; + type SwitcherDataType = { sessionId: string; sessionName: string; @@ -24,9 +29,25 @@ type SwitcherDataType = { screenName: string; icon: string; color: string; + viewData?: ViewDataType; }; const MaxOptionsToDisplay = 100; +const additionalOptions = [ + { label: "Connections", value: "connections" }, + { label: "History", value: "history" }, + { label: "Settings", value: "clientsettings" }, +].map((item, index) => ({ + sessionId: `additional-${index}`, + sessionName: "", + sessionIdx: -1, + screenId: `additional-${index}`, + screenIdx: -1, + screenName: "", + icon: "", + color: "", + viewData: item, +})); @mobxReact.observer class TabSwitcherModal extends React.Component<{}, {}> { @@ -44,8 +65,8 @@ class TabSwitcherModal extends React.Component<{}, {}> { componentDidMount() { this.activeSessionIdx = GlobalModel.getActiveSession().sessionIdx.get(); - let oSessions = GlobalModel.sessionList; - let oScreens = GlobalModel.screenMap; + const oSessions = GlobalModel.sessionList; + const oScreens = GlobalModel.screenMap; oScreens.forEach((oScreen) => { if (oScreen == null) { return; @@ -54,13 +75,13 @@ class TabSwitcherModal extends React.Component<{}, {}> { return; } // Find the matching session in the observable array - let foundSession = oSessions.find((s) => { + const foundSession = oSessions.find((s) => { return s.sessionId == oScreen.sessionId && !s.archived.get(); }); if (!foundSession) { return; } - let data: SwitcherDataType = { + const data: SwitcherDataType = { sessionName: foundSession.name.get(), sessionId: foundSession.sessionId, sessionIdx: foundSession.sessionIdx.get(), @@ -85,11 +106,11 @@ class TabSwitcherModal extends React.Component<{}, {}> { } componentDidUpdate() { - let currFocusedIdx = this.focusedIdx.get(); + const currFocusedIdx = this.focusedIdx.get(); // Check if selectedIdx has changed if (currFocusedIdx !== this.prevFocusedIdx) { - let optionElement = this.optionRefs[currFocusedIdx]?.current; + const optionElement = this.optionRefs[currFocusedIdx]?.current; if (optionElement) { optionElement.scrollIntoView({ block: "nearest" }); @@ -106,7 +127,7 @@ class TabSwitcherModal extends React.Component<{}, {}> { @boundMethod getTabIcon(screen: Screen): string { let tabIcon = "default"; - let screenOpts = screen.opts.get(); + const screenOpts = screen.opts.get(); if (screenOpts != null && !util.isBlank(screenOpts.tabicon)) { tabIcon = screenOpts.tabicon; } @@ -116,7 +137,7 @@ class TabSwitcherModal extends React.Component<{}, {}> { @boundMethod getTabColor(screen: Screen): string { let tabColor = "default"; - let screenOpts = screen.opts.get(); + const screenOpts = screen.opts.get(); if (screenOpts != null && !util.isBlank(screenOpts.tabcolor)) { tabColor = screenOpts.tabcolor; } @@ -129,7 +150,7 @@ class TabSwitcherModal extends React.Component<{}, {}> { this.closeModal(); } else if (e.key === "ArrowUp" || e.key === "ArrowDown") { e.preventDefault(); - let newIndex = this.calculateNewIndex(e.key === "ArrowUp"); + const newIndex = this.calculateNewIndex(e.key === "ArrowUp"); this.setFocusedIndex(newIndex); } else if (e.key === "Enter") { e.preventDefault(); @@ -139,7 +160,7 @@ class TabSwitcherModal extends React.Component<{}, {}> { @boundMethod calculateNewIndex(isUpKey) { - let currentIndex = this.focusedIdx.get(); + const currentIndex = this.focusedIdx.get(); if (isUpKey) { return Math.max(currentIndex - 1, 0); } else { @@ -162,6 +183,11 @@ class TabSwitcherModal extends React.Component<{}, {}> { @boundMethod handleSelect(index: number): void { const selectedOption = this.sOptions[index]; + if (selectedOption.sessionIdx === -1) { + GlobalCommandRunner.switchView(selectedOption.viewData.value); + this.closeModal(); + return; + } if (selectedOption) { GlobalCommandRunner.switchScreen(selectedOption.screenId, selectedOption.sessionId); this.closeModal(); @@ -189,27 +215,28 @@ class TabSwitcherModal extends React.Component<{}, {}> { @mobx.computed @boundMethod filterOptions(searchInput: string): SwitcherDataType[] { - let filteredScreens = []; - - for (let i = 0; i < this.options.length; i++) { - let tab = this.options[i]; - let match = false; + const searchLower = searchInput.toLowerCase(); + let filteredScreens = this.options.filter((tab) => { if (searchInput.includes("/")) { - let [sessionFilter, screenFilter] = searchInput.split("/").map((s) => s.trim().toLowerCase()); - match = + const [sessionFilter, screenFilter] = searchInput.split("/").map((s) => s.trim().toLowerCase()); + return ( tab.sessionName.toLowerCase().includes(sessionFilter) && - tab.screenName.toLowerCase().includes(screenFilter); + tab.screenName.toLowerCase().includes(screenFilter) + ); } else { - match = - tab.sessionName.toLowerCase().includes(searchInput) || - tab.screenName.toLowerCase().includes(searchInput); + return ( + tab.sessionName.toLowerCase().includes(searchLower) || + tab.screenName.toLowerCase().includes(searchLower) + ); } + }); - // Add tab to filtered list if it matches the criteria - if (match) { - filteredScreens.push(tab); - } + if (searchLower.length > 0) { + const additionalFiltered = additionalOptions.filter((item) => + item.viewData?.label.toLowerCase().includes(searchLower) + ); + filteredScreens = filteredScreens.concat(additionalFiltered); } return filteredScreens; @@ -218,9 +245,10 @@ class TabSwitcherModal extends React.Component<{}, {}> { @mobx.computed @boundMethod sortOptions(options: SwitcherDataType[]): SwitcherDataType[] { - return options.sort((a, b) => { - let aInCurrentSession = a.sessionIdx === this.activeSessionIdx; - let bInCurrentSession = b.sessionIdx === this.activeSessionIdx; + const mainOptions = options.filter((o) => o.sessionIdx !== -1); + mainOptions.sort((a, b) => { + const aInCurrentSession = a.sessionIdx === this.activeSessionIdx; + const bInCurrentSession = b.sessionIdx === this.activeSessionIdx; // Tabs in the current session are sorted by screenIdx if (aInCurrentSession && bInCurrentSession) { @@ -243,11 +271,16 @@ class TabSwitcherModal extends React.Component<{}, {}> { } } }); + + const additionalOptions = options.filter((o) => o.sessionIdx === -1); + additionalOptions.sort((a, b) => a.viewData?.label.localeCompare(b.viewData?.label)); + + return mainOptions.concat(additionalOptions); } @boundMethod renderIcon(option: SwitcherDataType): React.ReactNode { - let tabIcon = option.icon; + const tabIcon = option.icon; if (tabIcon === "default" || tabIcon === "square") { return ; } @@ -268,10 +301,15 @@ class TabSwitcherModal extends React.Component<{}, {}> { })} onClick={() => this.handleSelect(index)} > -
{this.renderIcon(option)}
-
- #{option.sessionName} / {option.screenName} -
+ +
{this.renderIcon(option)}
+
+ #{option.sessionName} / {option.screenName} +
+
+ +
{option.viewData?.label}
+
); } @@ -290,13 +328,13 @@ class TabSwitcherModal extends React.Component<{}, {}> { decoration={{ startDecoration: ( -
Switch to Tab:
+
Go to:
), endDecoration: ( } > diff --git a/src/models/commandrunner.ts b/src/models/commandrunner.ts index 525f9821..eaf516af 100644 --- a/src/models/commandrunner.ts +++ b/src/models/commandrunner.ts @@ -34,6 +34,12 @@ class CommandRunner { return prtn; } + switchView(view: string) { + mobx.action(() => { + GlobalModel.activeMainView.set(view); + })(); + } + switchSession(session: string) { mobx.action(() => { GlobalModel.activeMainView.set("session");