From 59655eed5f6f3763fb54b3418c96eef8a57e6619 Mon Sep 17 00:00:00 2001 From: victor-meng <56978073+victor-meng@users.noreply.github.com> Date: Wed, 23 Jun 2021 21:54:37 -0700 Subject: [PATCH] Remove route handlers (#909) * Remove tab handlers * Fix tests --- .eslintignore | 3 - src/Contracts/ViewModels.ts | 1 - .../Settings/SettingsComponent.test.tsx | 1 - src/Explorer/Explorer.tsx | 19 +- src/Explorer/Tabs/DocumentsTab.test.ts | 6 - .../StoredProcedureTab/StoredProcedureTab.tsx | 1 - .../StoredProcedureTabComponent.tsx | 8 - src/Explorer/Tabs/TabsBase.ts | 9 - src/Explorer/Tabs/TabsManager.test.ts | 2 - src/Explorer/Tabs/TriggerTabContent.tsx | 6 - .../Tabs/UserDefinedFunctionTabContent.tsx | 6 - src/Explorer/Tree/Collection.ts | 11 - src/Explorer/Tree/Database.ts | 1 - src/Explorer/Tree/ResourceTokenCollection.ts | 2 - src/Explorer/Tree/StoredProcedure.ts | 5 - src/Explorer/Tree/Trigger.ts | 5 - src/Explorer/Tree/UserDefinedFunction.ts | 5 - src/RouteHandlers/RouteHandler.ts | 35 -- src/RouteHandlers/TabRouteHandler.test.ts | 102 ----- src/RouteHandlers/TabRouteHandler.ts | 407 ------------------ 20 files changed, 5 insertions(+), 630 deletions(-) delete mode 100644 src/RouteHandlers/RouteHandler.ts delete mode 100644 src/RouteHandlers/TabRouteHandler.test.ts delete mode 100644 src/RouteHandlers/TabRouteHandler.ts diff --git a/.eslintignore b/.eslintignore index c23885881..26a8dfa46 100644 --- a/.eslintignore +++ b/.eslintignore @@ -199,9 +199,6 @@ src/ResourceProvider/IResourceProviderClient.test.ts src/ResourceProvider/IResourceProviderClient.ts src/ResourceProvider/ResourceProviderClient.ts src/ResourceProvider/ResourceProviderClientFactory.ts -src/RouteHandlers/RouteHandler.ts -src/RouteHandlers/TabRouteHandler.test.ts -src/RouteHandlers/TabRouteHandler.ts src/Shared/Constants.ts src/Shared/DefaultExperienceUtility.test.ts src/Shared/DefaultExperienceUtility.ts diff --git a/src/Contracts/ViewModels.ts b/src/Contracts/ViewModels.ts index c851ea8aa..7dcea3024 100644 --- a/src/Contracts/ViewModels.ts +++ b/src/Contracts/ViewModels.ts @@ -275,7 +275,6 @@ export interface TabOptions { tabKind: CollectionTabKind; title: string; tabPath: string; - hashLocation: string; isTabsContentExpanded?: ko.Observable; onLoadStartKey?: number; diff --git a/src/Explorer/Controls/Settings/SettingsComponent.test.tsx b/src/Explorer/Controls/Settings/SettingsComponent.test.tsx index e4cee955c..0082db7e9 100644 --- a/src/Explorer/Controls/Settings/SettingsComponent.test.tsx +++ b/src/Explorer/Controls/Settings/SettingsComponent.test.tsx @@ -38,7 +38,6 @@ describe("SettingsComponent", () => { title: "Scale & Settings", tabPath: "", node: undefined, - hashLocation: "settings", }), }; diff --git a/src/Explorer/Explorer.tsx b/src/Explorer/Explorer.tsx index bb7ca660c..6115ad786 100644 --- a/src/Explorer/Explorer.tsx +++ b/src/Explorer/Explorer.tsx @@ -18,7 +18,6 @@ import * as ViewModels from "../Contracts/ViewModels"; import { GitHubOAuthService } from "../GitHub/GitHubOAuthService"; import { useSidePanel } from "../hooks/useSidePanel"; import { IGalleryItem, JunoClient } from "../Juno/JunoClient"; -import { RouteHandler } from "../RouteHandlers/RouteHandler"; import { ExplorerSettings } from "../Shared/ExplorerSettings"; import { Action, ActionModifiers } from "../Shared/Telemetry/TelemetryConstants"; import * as TelemetryProcessor from "../Shared/Telemetry/TelemetryProcessor"; @@ -138,7 +137,6 @@ export default class Explorer { userContext.authType === AuthType.ResourceToken ? this.refreshDatabaseForResourceToken() : this.refreshAllDatabases(true); - RouteHandler.getInstance().initHandler(); await this._refreshNotebooksEnabledStateForAccount(); this.isNotebookEnabled( userContext.authType !== AuthType.ResourceToken && @@ -899,7 +897,6 @@ export default class Explorer { tabPath: notebookContentItem.path, collection: null, masterKey: userContext.masterKey || "", - hashLocation: "notebooks", isTabsContentExpanded: ko.observable(true), onLoadStartKey: null, container: this, @@ -1199,30 +1196,27 @@ export default class Explorer { public openNotebookTerminal(kind: ViewModels.TerminalKind) { let title: string; - let hashLocation: string; switch (kind) { case ViewModels.TerminalKind.Default: title = "Terminal"; - hashLocation = "terminal"; break; case ViewModels.TerminalKind.Mongo: title = "Mongo Shell"; - hashLocation = "mongo-shell"; break; case ViewModels.TerminalKind.Cassandra: title = "Cassandra Shell"; - hashLocation = "cassandra-shell"; break; default: throw new Error("Terminal kind: ${kind} not supported"); } - const terminalTabs: TerminalTab[] = this.tabsManager.getTabs(ViewModels.CollectionTabKind.Terminal, (tab) => - tab.hashLocation().startsWith(hashLocation) + const terminalTabs: TerminalTab[] = this.tabsManager.getTabs( + ViewModels.CollectionTabKind.Terminal, + (tab) => tab.tabTitle() === title ) as TerminalTab[]; let index = 1; @@ -1237,7 +1231,6 @@ export default class Explorer { title: `${title} ${index}`, tabPath: `${title} ${index}`, collection: null, - hashLocation: `${hashLocation} ${index}`, isTabsContentExpanded: ko.observable(true), onLoadStartKey: null, container: this, @@ -1255,11 +1248,10 @@ export default class Explorer { isFavorite?: boolean ) { const title = "Gallery"; - const hashLocation = "gallery"; const GalleryTab = await (await import(/* webpackChunkName: "GalleryTab" */ "./Tabs/GalleryTab")).default; const galleryTab = this.tabsManager .getTabs(ViewModels.CollectionTabKind.Gallery) - .find((tab) => tab.hashLocation() == hashLocation); + .find((tab) => tab.tabTitle() == title); if (galleryTab instanceof GalleryTab) { this.tabsManager.activateTab(galleryTab); @@ -1268,9 +1260,8 @@ export default class Explorer { new GalleryTab( { tabKind: ViewModels.CollectionTabKind.Gallery, - title: title, + title, tabPath: title, - hashLocation: hashLocation, onLoadStartKey: null, isTabsContentExpanded: ko.observable(true), }, diff --git a/src/Explorer/Tabs/DocumentsTab.test.ts b/src/Explorer/Tabs/DocumentsTab.test.ts index bd7018000..c8d84e716 100644 --- a/src/Explorer/Tabs/DocumentsTab.test.ts +++ b/src/Explorer/Tabs/DocumentsTab.test.ts @@ -15,7 +15,6 @@ describe("Documents tab", () => { tabKind: ViewModels.CollectionTabKind.Documents, title: "", tabPath: "", - hashLocation: "", }); expect(documentsTab.buildQuery("")).toContain("select"); @@ -90,7 +89,6 @@ describe("Documents tab", () => { tabKind: ViewModels.CollectionTabKind.Documents, title: "", tabPath: "", - hashLocation: "", }); expect(documentsTab.showPartitionKey).toBe(false); @@ -104,7 +102,6 @@ describe("Documents tab", () => { tabKind: ViewModels.CollectionTabKind.Documents, title: "", tabPath: "", - hashLocation: "", }); expect(documentsTab.showPartitionKey).toBe(false); @@ -118,7 +115,6 @@ describe("Documents tab", () => { tabKind: ViewModels.CollectionTabKind.Documents, title: "", tabPath: "", - hashLocation: "", }); expect(documentsTab.showPartitionKey).toBe(true); @@ -135,7 +131,6 @@ describe("Documents tab", () => { tabKind: ViewModels.CollectionTabKind.Documents, title: "", tabPath: "", - hashLocation: "", }); expect(documentsTab.showPartitionKey).toBe(false); @@ -149,7 +144,6 @@ describe("Documents tab", () => { tabKind: ViewModels.CollectionTabKind.Documents, title: "", tabPath: "", - hashLocation: "", }); expect(documentsTab.showPartitionKey).toBe(true); diff --git a/src/Explorer/Tabs/StoredProcedureTab/StoredProcedureTab.tsx b/src/Explorer/Tabs/StoredProcedureTab/StoredProcedureTab.tsx index 3bf332956..488944a05 100644 --- a/src/Explorer/Tabs/StoredProcedureTab/StoredProcedureTab.tsx +++ b/src/Explorer/Tabs/StoredProcedureTab/StoredProcedureTab.tsx @@ -37,7 +37,6 @@ export class NewStoredProcedureTab extends ScriptTabBase { tabPath: options.tabPath, collectionBase: options.collection, node: options.node, - hasLocation: options.hashLocation, scriptTabBaseInstance: this, collection: props.collection, iStorProcTabComponentAccessor: (instance: IStorProcTabComponentAccessor) => { diff --git a/src/Explorer/Tabs/StoredProcedureTab/StoredProcedureTabComponent.tsx b/src/Explorer/Tabs/StoredProcedureTab/StoredProcedureTabComponent.tsx index 6d2b93be5..e5f5ac935 100644 --- a/src/Explorer/Tabs/StoredProcedureTab/StoredProcedureTabComponent.tsx +++ b/src/Explorer/Tabs/StoredProcedureTab/StoredProcedureTabComponent.tsx @@ -4,7 +4,6 @@ import React from "react"; import DiscardIcon from "../../../../images/discard.svg"; import ExecuteQueryIcon from "../../../../images/ExecuteQuery.svg"; import SaveIcon from "../../../../images/save-cosmos.svg"; -import * as Constants from "../../../Common/Constants"; import { NormalizedEventKey } from "../../../Common/Constants"; import { createStoredProcedure } from "../../../Common/dataAccess/createStoredProcedure"; import { ExecuteSprocResult } from "../../../Common/dataAccess/executeStoredProcedure"; @@ -55,7 +54,6 @@ export interface IStoredProcTabComponentProps { collectionBase: ViewModels.CollectionBase; //eslint-disable-next-line node?: any; - hasLocation: string; scriptTabBaseInstance: ScriptTabBase; collection: ViewModels.Collection; iStorProcTabComponentAccessor: (instance: IStorProcTabComponentAccessor) => void; @@ -389,12 +387,6 @@ export default class StoredProcedureTabComponent extends React.Component< this.props.scriptTabBaseInstance.tabTitle(createdResource.id); this.props.scriptTabBaseInstance.isNew(false); this.props.scriptTabBaseInstance.resource(createdResource); - this.props.scriptTabBaseInstance.hashLocation( - `${Constants.HashRoutePrefixes.collectionsWithIds( - this.props.collectionBase.databaseId, - this.props.collectionBase.id() - )}/sprocs/${createdResource.id}` - ); this.props.scriptTabBaseInstance.setBaselines(); const editorModel = diff --git a/src/Explorer/Tabs/TabsBase.ts b/src/Explorer/Tabs/TabsBase.ts index 9f9f2e48c..84a2dce7c 100644 --- a/src/Explorer/Tabs/TabsBase.ts +++ b/src/Explorer/Tabs/TabsBase.ts @@ -4,7 +4,6 @@ import * as ThemeUtility from "../../Common/ThemeUtility"; import * as DataModels from "../../Contracts/DataModels"; import * as ViewModels from "../../Contracts/ViewModels"; import { useNotificationConsole } from "../../hooks/useNotificationConsole"; -import { RouteHandler } from "../../RouteHandlers/RouteHandler"; import { Action, ActionModifiers } from "../../Shared/Telemetry/TelemetryConstants"; import * as TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor"; import { CommandButtonComponentProps } from "../Controls/CommandButton/CommandButtonComponent"; @@ -25,7 +24,6 @@ export default class TabsBase extends WaitsForTemplateViewModel { public tabKind: ViewModels.CollectionTabKind; public tabTitle: ko.Observable; public tabPath: ko.Observable; - public hashLocation: ko.Observable; public isExecutionError = ko.observable(false); public isExecuting = ko.observable(false); public pendingNotification?: ko.Observable; @@ -49,8 +47,6 @@ export default class TabsBase extends WaitsForTemplateViewModel { ko.observable(`${this.collection.databaseId}>${this.collection.id()}>${this.tabTitle()}`)); this.pendingNotification = ko.observable(undefined); this.onLoadStartKey = options.onLoadStartKey; - this.hashLocation = ko.observable(options.hashLocation || ""); - this.hashLocation.subscribe((newLocation: string) => this.updateGlobalHash(newLocation)); this.closeTabButton = { enabled: ko.computed(() => { return true; @@ -114,7 +110,6 @@ export default class TabsBase extends WaitsForTemplateViewModel { this.updateSelectedNode(); this.collection?.selectedSubnodeKind(this.tabKind); this.database?.selectedSubnodeKind(this.tabKind); - this.updateGlobalHash(this.hashLocation()); this.updateNavbarWithTabsButtons(); TelemetryProcessor.trace(Action.Tab, ActionModifiers.Open, { tabName: this.constructor.name, @@ -152,10 +147,6 @@ export default class TabsBase extends WaitsForTemplateViewModel { return JSON.stringify(value, replacer, space); } - private updateGlobalHash(newHash: string): void { - RouteHandler.getInstance().updateRouteHashLocation(newHash); - } - /** * @return buttons that are displayed in the navbar */ diff --git a/src/Explorer/Tabs/TabsManager.test.ts b/src/Explorer/Tabs/TabsManager.test.ts index eb1e3e4b4..4106eba3c 100644 --- a/src/Explorer/Tabs/TabsManager.test.ts +++ b/src/Explorer/Tabs/TabsManager.test.ts @@ -53,7 +53,6 @@ describe("Tabs manager tests", () => { database, title: "", tabPath: "", - hashLocation: "", queryText: "", partitionKey: collection.partitionKey, onLoadStartKey: 1, @@ -70,7 +69,6 @@ describe("Tabs manager tests", () => { collection, title: "", tabPath: "", - hashLocation: "", }); // make sure tabs have different tabId diff --git a/src/Explorer/Tabs/TriggerTabContent.tsx b/src/Explorer/Tabs/TriggerTabContent.tsx index 1bb619eaf..2add748b1 100644 --- a/src/Explorer/Tabs/TriggerTabContent.tsx +++ b/src/Explorer/Tabs/TriggerTabContent.tsx @@ -100,12 +100,6 @@ export class TriggerTabContent extends Component${this.id()}>Documents`, - hashLocation: `${Constants.HashRoutePrefixes.collectionsWithIds(this.databaseId, this.id())}/documents`, onLoadStartKey: startKey, }); @@ -359,7 +358,6 @@ export default class Collection implements ViewModels.Collection { collection: this, node: this, tabPath: `${this.databaseId}>${this.id()}>Conflicts`, - hashLocation: `${Constants.HashRoutePrefixes.collectionsWithIds(this.databaseId, this.id())}/conflicts`, onLoadStartKey: startKey, }); @@ -413,7 +411,6 @@ export default class Collection implements ViewModels.Collection { tabPath: "", collection: this, node: this, - hashLocation: `${Constants.HashRoutePrefixes.collectionsWithIds(this.databaseId, this.id())}/entities`, onLoadStartKey: startKey, }); @@ -462,7 +459,6 @@ export default class Collection implements ViewModels.Collection { collection: this, masterKey: userContext.masterKey || "", collectionPartitionKeyProperty: this.partitionKeyProperty, - hashLocation: `${Constants.HashRoutePrefixes.collectionsWithIds(this.databaseId, this.id())}/graphs`, collectionId: this.id(), databaseId: this.databaseId, isTabsContentExpanded: this.container.isTabsContentExpanded, @@ -511,7 +507,6 @@ export default class Collection implements ViewModels.Collection { tabPath: "", collection: this, node: this, - hashLocation: `${Constants.HashRoutePrefixes.collectionsWithIds(this.databaseId, this.id())}/mongoDocuments`, onLoadStartKey: startKey, }); this.container.tabsManager.activateNewTab(mongoDocumentsTab); @@ -556,7 +551,6 @@ export default class Collection implements ViewModels.Collection { tabPath: "", collection: this, node: this, - hashLocation: `${Constants.HashRoutePrefixes.collectionsWithIds(this.databaseId, this.id())}/schemaAnalyzer`, onLoadStartKey: startKey, }) ); @@ -596,7 +590,6 @@ export default class Collection implements ViewModels.Collection { tabPath: "", collection: this, node: this, - hashLocation: `${Constants.HashRoutePrefixes.collectionsWithIds(this.databaseId, this.id())}/settings`, }; let settingsTabV2 = matchingTabs && (matchingTabs[0] as CollectionSettingsTabV2); @@ -639,7 +632,6 @@ export default class Collection implements ViewModels.Collection { tabPath: "", collection: this, node: this, - hashLocation: `${Constants.HashRoutePrefixes.collectionsWithIds(this.databaseId, this.id())}/query`, queryText: queryText, partitionKey: collection.partitionKey, onLoadStartKey: startKey, @@ -669,7 +661,6 @@ export default class Collection implements ViewModels.Collection { tabPath: "", collection: this, node: this, - hashLocation: `${Constants.HashRoutePrefixes.collectionsWithIds(this.databaseId, this.id())}/mongoQuery`, partitionKey: collection.partitionKey, onLoadStartKey: startKey, }, @@ -703,7 +694,6 @@ export default class Collection implements ViewModels.Collection { collection: this, masterKey: userContext.masterKey || "", collectionPartitionKeyProperty: this.partitionKeyProperty, - hashLocation: `${Constants.HashRoutePrefixes.collectionsWithIds(this.databaseId, this.id())}/graphs`, collectionId: this.id(), databaseId: this.databaseId, isTabsContentExpanded: this.container.isTabsContentExpanded, @@ -730,7 +720,6 @@ export default class Collection implements ViewModels.Collection { tabPath: "", collection: this, node: this, - hashLocation: `${Constants.HashRoutePrefixes.collectionsWithIds(this.databaseId, this.id())}/mongoShell`, index: index, }, { diff --git a/src/Explorer/Tree/Database.ts b/src/Explorer/Tree/Database.ts index 1c678c4de..83961932b 100644 --- a/src/Explorer/Tree/Database.ts +++ b/src/Explorer/Tree/Database.ts @@ -82,7 +82,6 @@ export default class Database implements ViewModels.Database { node: this, rid: this.rid, database: this, - hashLocation: `${Constants.HashRoutePrefixes.databasesWithId(this.id())}/settings`, onLoadStartKey: startKey, }; settingsTab = new DatabaseSettingsTabV2(tabOptions); diff --git a/src/Explorer/Tree/ResourceTokenCollection.ts b/src/Explorer/Tree/ResourceTokenCollection.ts index 955256d2d..efe38a8f0 100644 --- a/src/Explorer/Tree/ResourceTokenCollection.ts +++ b/src/Explorer/Tree/ResourceTokenCollection.ts @@ -94,7 +94,6 @@ export default class ResourceTokenCollection implements ViewModels.CollectionBas tabPath: "", collection: this, node: this, - hashLocation: `${Constants.HashRoutePrefixes.collectionsWithIds(this.databaseId, this.id())}/query`, queryText: queryText, partitionKey: collection.partitionKey, onLoadStartKey: startKey, @@ -143,7 +142,6 @@ export default class ResourceTokenCollection implements ViewModels.CollectionBas collection: this, node: this, tabPath: `${this.databaseId}>${this.id()}>Documents`, - hashLocation: `${Constants.HashRoutePrefixes.collectionsWithIds(this.databaseId, this.id())}/documents`, onLoadStartKey: startKey, }); diff --git a/src/Explorer/Tree/StoredProcedure.ts b/src/Explorer/Tree/StoredProcedure.ts index 2fa9d6eb7..dc29ec70f 100644 --- a/src/Explorer/Tree/StoredProcedure.ts +++ b/src/Explorer/Tree/StoredProcedure.ts @@ -76,7 +76,6 @@ export default class StoredProcedure { tabPath: `${source.databaseId}>${source.id()}>New Stored Procedure ${id}`, collection: source, node: source, - hashLocation: `${Constants.HashRoutePrefixes.collectionsWithIds(source.databaseId, source.id())}/sproc`, }, { collection: source, @@ -124,10 +123,6 @@ export default class StoredProcedure { tabPath: `${this.collection.databaseId}>${this.collection.id()}>${storedProcedureData.id}`, collection: this.collection, node: this, - hashLocation: `${Constants.HashRoutePrefixes.collectionsWithIds( - this.collection.databaseId, - this.collection.id() - )}/sprocs/${this.id()}`, }, { collection: this.collection, diff --git a/src/Explorer/Tree/Trigger.ts b/src/Explorer/Tree/Trigger.ts index 21f69741d..0168b1eb0 100644 --- a/src/Explorer/Tree/Trigger.ts +++ b/src/Explorer/Tree/Trigger.ts @@ -57,7 +57,6 @@ export default class Trigger { tabPath: "", collection: source, node: source, - hashLocation: `${Constants.HashRoutePrefixes.collectionsWithIds(source.databaseId, source.id())}/trigger`, }); source.container.tabsManager.activateNewTab(triggerTab); @@ -92,10 +91,6 @@ export default class Trigger { tabPath: "", collection: this.collection, node: this, - hashLocation: `${Constants.HashRoutePrefixes.collectionsWithIds( - this.collection.databaseId, - this.collection.id() - )}/triggers/${this.id()}`, }); this.container.tabsManager.activateNewTab(triggerTab); diff --git a/src/Explorer/Tree/UserDefinedFunction.ts b/src/Explorer/Tree/UserDefinedFunction.ts index cbd37ecd6..5dc655ed2 100644 --- a/src/Explorer/Tree/UserDefinedFunction.ts +++ b/src/Explorer/Tree/UserDefinedFunction.ts @@ -43,7 +43,6 @@ export default class UserDefinedFunction { tabPath: "", collection: source, node: source, - hashLocation: `${Constants.HashRoutePrefixes.collectionsWithIds(source.databaseId, source.id())}/udf`, }); source.container.tabsManager.activateNewTab(userDefinedFunctionTab); @@ -76,10 +75,6 @@ export default class UserDefinedFunction { tabPath: "", collection: this.collection, node: this, - hashLocation: `${Constants.HashRoutePrefixes.collectionsWithIds( - this.collection.databaseId, - this.collection.id() - )}/udfs/${this.id()}`, }); this.container.tabsManager.activateNewTab(userDefinedFunctionTab); diff --git a/src/RouteHandlers/RouteHandler.ts b/src/RouteHandlers/RouteHandler.ts deleted file mode 100644 index ade05e7df..000000000 --- a/src/RouteHandlers/RouteHandler.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { MessageTypes } from "../Contracts/ExplorerContracts"; -import { sendMessage } from "../Common/MessageHandler"; -import { TabRouteHandler } from "./TabRouteHandler"; - -export class RouteHandler { - private static _instance: RouteHandler; - private _tabRouteHandler: TabRouteHandler; - - private constructor() { - this._tabRouteHandler = new TabRouteHandler(); - } - - public static getInstance(): RouteHandler { - if (!RouteHandler._instance) { - RouteHandler._instance = new RouteHandler(); - } - - return RouteHandler._instance; - } - - public initHandler(): void { - this._tabRouteHandler.initRouteHandler(); - } - - public parseHash(hash: string): void { - this._tabRouteHandler.parseHash(hash); - } - - public updateRouteHashLocation(hash: string): void { - sendMessage({ - type: MessageTypes.UpdateLocationHash, - locationHash: hash, - }); - } -} diff --git a/src/RouteHandlers/TabRouteHandler.test.ts b/src/RouteHandlers/TabRouteHandler.test.ts deleted file mode 100644 index 0d2031efd..000000000 --- a/src/RouteHandlers/TabRouteHandler.test.ts +++ /dev/null @@ -1,102 +0,0 @@ -import crossroads from "crossroads"; -import hasher from "hasher"; - -import * as Constants from "../Common/Constants"; -import Explorer from "../Explorer/Explorer"; -import { TabRouteHandler } from "./TabRouteHandler"; - -describe("TabRouteHandler", () => { - let tabRouteHandler: TabRouteHandler; - - beforeAll(() => { - (window).dataExplorer = new Explorer(); // create a mock to avoid null refs - }); - - beforeEach(() => { - tabRouteHandler = new TabRouteHandler(); - }); - - afterEach(() => { - crossroads.removeAllRoutes(); - }); - - describe("Route Handling", () => { - let routedSpy: jasmine.Spy; - - beforeEach(() => { - routedSpy = jasmine.createSpy("Routed spy"); - const onMatch = (request: string, data: { route: any; params: string[]; isFirst: boolean }) => { - routedSpy(request, data); - }; - tabRouteHandler.initRouteHandler(onMatch); - }); - - function validateRouteWithParams(route: string, routeParams: string[]): void { - hasher.setHash(route); - expect(routedSpy).toHaveBeenCalledWith( - route, - jasmine.objectContaining({ params: jasmine.arrayContaining(routeParams) }) - ); - } - - it("should include a route for documents tab", () => { - validateRouteWithParams(`${Constants.HashRoutePrefixes.collectionsWithIds("1", "2")}/documents`, ["1", "2"]); - }); - - it("should include a route for entities tab", () => { - validateRouteWithParams(`${Constants.HashRoutePrefixes.collectionsWithIds("1", "2")}/entities`, ["1", "2"]); - }); - - it("should include a route for graphs tab", () => { - validateRouteWithParams(`${Constants.HashRoutePrefixes.collectionsWithIds("1", "2")}/graphs`, ["1", "2"]); - }); - - it("should include a route for mongo documents tab", () => { - validateRouteWithParams(`${Constants.HashRoutePrefixes.collectionsWithIds("1", "2")}/mongoDocuments`, ["1", "2"]); - }); - - it("should include a route for mongo shell", () => { - validateRouteWithParams(`${Constants.HashRoutePrefixes.collectionsWithIds("1", "2")}/mongoShell`, ["1", "2"]); - }); - - it("should include a route for query tab", () => { - validateRouteWithParams(`${Constants.HashRoutePrefixes.collectionsWithIds("1", "2")}/query`, ["1", "2"]); - }); - - it("should include a route for database settings tab", () => { - validateRouteWithParams(`${Constants.HashRoutePrefixes.databasesWithId("1")}/settings`, ["1"]); - }); - - it("should include a route for settings tab", () => { - validateRouteWithParams(`${Constants.HashRoutePrefixes.collectionsWithIds("1", "2")}/settings`, ["1", "2"]); - }); - - it("should include a route for new stored procedure tab", () => { - validateRouteWithParams(`${Constants.HashRoutePrefixes.collectionsWithIds("1", "2")}/sproc`, ["1", "2"]); - }); - - it("should include a route for stored procedure tab", () => { - validateRouteWithParams(`${Constants.HashRoutePrefixes.collectionsWithIds("1", "2")}/sprocs/3`, ["1", "2", "3"]); - }); - - it("should include a route for new trigger tab", () => { - validateRouteWithParams(`${Constants.HashRoutePrefixes.collectionsWithIds("1", "2")}/trigger`, ["1", "2"]); - }); - - it("should include a route for trigger tab", () => { - validateRouteWithParams(`${Constants.HashRoutePrefixes.collectionsWithIds("1", "2")}/triggers/3`, [ - "1", - "2", - "3", - ]); - }); - - it("should include a route for new UDF tab", () => { - validateRouteWithParams(`${Constants.HashRoutePrefixes.collectionsWithIds("1", "2")}/udf`, ["1", "2"]); - }); - - it("should include a route for UDF tab", () => { - validateRouteWithParams(`${Constants.HashRoutePrefixes.collectionsWithIds("1", "2")}/udfs/3`, ["1", "2", "3"]); - }); - }); -}); diff --git a/src/RouteHandlers/TabRouteHandler.ts b/src/RouteHandlers/TabRouteHandler.ts deleted file mode 100644 index a3b74eb8c..000000000 --- a/src/RouteHandlers/TabRouteHandler.ts +++ /dev/null @@ -1,407 +0,0 @@ -import crossroads from "crossroads"; -import hasher from "hasher"; -import * as _ from "underscore"; -import * as Constants from "../Common/Constants"; -import * as ViewModels from "../Contracts/ViewModels"; -import ScriptTabBase from "../Explorer/Tabs/ScriptTabBase"; -import TabsBase from "../Explorer/Tabs/TabsBase"; -import { useDatabases } from "../Explorer/useDatabases"; -import { userContext } from "../UserContext"; - -export class TabRouteHandler { - private _tabRouter: any; - - constructor() {} - - public initRouteHandler( - onMatch?: (request: string, data: { route: any; params: string[]; isFirst: boolean }) => void - ): void { - this._initRouter(); - const parseHash = (newHash: string, oldHash: string) => this._tabRouter.parse(newHash); - const defaultRoutedCallback = (request: string, data: { route: any; params: string[]; isFirst: boolean }) => {}; - this._tabRouter.routed.add(onMatch || defaultRoutedCallback); - hasher.initialized.add(parseHash); - hasher.changed.add(parseHash); - hasher.init(); - } - - public parseHash(hash: string): void { - this._tabRouter.parse(hash); - } - - private _initRouter() { - this._tabRouter = crossroads.create(); - this._setupTabRoutesForRouter(); - } - - private _setupTabRoutesForRouter(): void { - this._tabRouter.addRoute( - `${Constants.HashRoutePrefixes.collections}/documents`, - (db_id: string, coll_id: string) => { - this._openDocumentsTabForResource(db_id, coll_id); - } - ); - - this._tabRouter.addRoute( - `${Constants.HashRoutePrefixes.collections}/entities`, - (db_id: string, coll_id: string) => { - this._openEntitiesTabForResource(db_id, coll_id); - } - ); - - this._tabRouter.addRoute(`${Constants.HashRoutePrefixes.collections}/graphs`, (db_id: string, coll_id: string) => { - this._openGraphTabForResource(db_id, coll_id); - }); - - this._tabRouter.addRoute( - `${Constants.HashRoutePrefixes.collections}/mongoDocuments`, - (db_id: string, coll_id: string) => { - this._openMongoDocumentsTabForResource(db_id, coll_id); - } - ); - - this._tabRouter.addRoute( - `${Constants.HashRoutePrefixes.collections}/schemaAnalyzer`, - (db_id: string, coll_id: string) => { - this._openSchemaAnalyzerTabForResource(db_id, coll_id); - } - ); - - this._tabRouter.addRoute( - `${Constants.HashRoutePrefixes.collections}/mongoQuery`, - (db_id: string, coll_id: string) => { - this._openMongoQueryTabForResource(db_id, coll_id); - } - ); - - this._tabRouter.addRoute( - `${Constants.HashRoutePrefixes.collections}/mongoShell`, - (db_id: string, coll_id: string) => { - this._openMongoShellTabForResource(db_id, coll_id); - } - ); - - this._tabRouter.addRoute(`${Constants.HashRoutePrefixes.collections}/query`, (db_id: string, coll_id: string) => { - this._openQueryTabForResource(db_id, coll_id); - }); - - this._tabRouter.addRoute(`${Constants.HashRoutePrefixes.databases}/settings`, (db_id: string) => { - this._openDatabaseSettingsTabForResource(db_id); - }); - - this._tabRouter.addRoute( - `${Constants.HashRoutePrefixes.collections}/settings`, - (db_id: string, coll_id: string) => { - this._openSettingsTabForResource(db_id, coll_id); - } - ); - - this._tabRouter.addRoute(`${Constants.HashRoutePrefixes.collections}/sproc`, (db_id: string, coll_id: string) => { - this._openNewSprocTabForResource(db_id, coll_id); - }); - - this._tabRouter.addRoute( - `${Constants.HashRoutePrefixes.collections}/sprocs/{sproc_id}`, - (db_id: string, coll_id: string, sproc_id: string) => { - this._openSprocTabForResource(db_id, coll_id, sproc_id); - } - ); - - this._tabRouter.addRoute(`${Constants.HashRoutePrefixes.collections}/trigger`, (db_id: string, coll_id: string) => { - this._openNewTriggerTabForResource(db_id, coll_id); - }); - - this._tabRouter.addRoute( - `${Constants.HashRoutePrefixes.collections}/triggers/{trigger_id}`, - (db_id: string, coll_id: string, trigger_id: string) => { - this._openTriggerTabForResource(db_id, coll_id, trigger_id); - } - ); - - this._tabRouter.addRoute(`${Constants.HashRoutePrefixes.collections}/udf`, (db_id: string, coll_id: string) => { - this._openNewUserDefinedFunctionTabForResource(db_id, coll_id); - }); - - this._tabRouter.addRoute( - `${Constants.HashRoutePrefixes.collections}/udfs/{udf_id}`, - (db_id: string, coll_id: string, udf_id: string) => { - this._openUserDefinedFunctionTabForResource(db_id, coll_id, udf_id); - } - ); - - this._tabRouter.addRoute( - `${Constants.HashRoutePrefixes.collections}/conflicts`, - (db_id: string, coll_id: string) => { - this._openConflictsTabForResource(db_id, coll_id); - } - ); - } - - private _openDocumentsTabForResource(databaseId: string, collectionId: string): void { - this._executeActionHelper(() => { - const collection: ViewModels.Collection = this._findAndExpandMatchingCollectionForResource( - databaseId, - collectionId - ); - userContext.apiType === "SQL" && collection?.onDocumentDBDocumentsClick(); - }); - } - - private _openEntitiesTabForResource(databaseId: string, collectionId: string): void { - this._executeActionHelper(() => { - const collection: ViewModels.Collection = this._findAndExpandMatchingCollectionForResource( - databaseId, - collectionId - ); - collection && - collection.container && - (userContext.apiType === "Tables" || userContext.apiType === "Cassandra") && - collection.onTableEntitiesClick(); - }); - } - - private _openGraphTabForResource(databaseId: string, collectionId: string): void { - this._executeActionHelper(() => { - const collection: ViewModels.Collection = this._findAndExpandMatchingCollectionForResource( - databaseId, - collectionId - ); - userContext.apiType === "Gremlin" && collection.onGraphDocumentsClick(); - }); - } - - private _openMongoDocumentsTabForResource(databaseId: string, collectionId: string): void { - this._executeActionHelper(() => { - const collection: ViewModels.Collection = this._findAndExpandMatchingCollectionForResource( - databaseId, - collectionId - ); - userContext.apiType === "Mongo" && collection.onMongoDBDocumentsClick(); - }); - } - - private _openSchemaAnalyzerTabForResource(databaseId: string, collectionId: string): void { - this._executeActionHelper(() => { - const collection: ViewModels.Collection = this._findAndExpandMatchingCollectionForResource( - databaseId, - collectionId - ); - collection && userContext.apiType === "Mongo" && collection.onSchemaAnalyzerClick(); - }); - } - - private _openQueryTabForResource(databaseId: string, collectionId: string): void { - this._executeActionHelper(() => { - const collection: ViewModels.Collection = this._findAndExpandMatchingCollectionForResource( - databaseId, - collectionId - ); - const matchingTab: TabsBase = this._findMatchingTabByTabKind( - databaseId, - collectionId, - ViewModels.CollectionTabKind.Query - ); - if (!!matchingTab) { - matchingTab.onTabClick(); - } else { - collection && collection.onNewQueryClick(collection, null); - } - }); - } - - private _openMongoQueryTabForResource(databaseId: string, collectionId: string): void { - this._executeActionHelper(() => { - const collection: ViewModels.Collection = this._findAndExpandMatchingCollectionForResource( - databaseId, - collectionId - ); - const matchingTab: TabsBase = this._findMatchingTabByTabKind( - databaseId, - collectionId, - ViewModels.CollectionTabKind.Query - ); - if (!!matchingTab) { - matchingTab.onTabClick(); - } else { - userContext.apiType === "Mongo" && collection.onNewMongoQueryClick(collection, null); - } - }); - } - - private _openMongoShellTabForResource(databaseId: string, collectionId: string): void { - this._executeActionHelper(() => { - const collection: ViewModels.Collection = this._findAndExpandMatchingCollectionForResource( - databaseId, - collectionId - ); - const matchingTab: TabsBase = this._findMatchingTabByTabKind( - databaseId, - collectionId, - ViewModels.CollectionTabKind.MongoShell - ); - if (!!matchingTab) { - matchingTab.onTabClick(); - } else { - userContext.apiType === "Mongo" && collection.onNewMongoShellClick(); - } - }); - } - - private _openDatabaseSettingsTabForResource(databaseId: string): void { - this._executeActionHelper(() => { - const database: ViewModels.Database = _.find( - useDatabases.getState().databases, - (database: ViewModels.Database) => database.id() === databaseId - ); - database?.onSettingsClick(); - }); - } - - private _openSettingsTabForResource(databaseId: string, collectionId: string): void { - this._executeActionHelper(() => { - const collection: ViewModels.Collection = this._findAndExpandMatchingCollectionForResource( - databaseId, - collectionId - ); - collection && collection.onSettingsClick(); - }); - } - - private _openNewSprocTabForResource(databaseId: string, collectionId: string): void { - this._executeActionHelper(() => { - const collection: ViewModels.Collection = this._findAndExpandMatchingCollectionForResource( - databaseId, - collectionId - ); - const matchingTab: TabsBase = this._findMatchingTabByTabKind( - databaseId, - collectionId, - ViewModels.CollectionTabKind.StoredProcedures, - true - ); - if (!!matchingTab) { - matchingTab.onTabClick(); - } else { - collection && collection.onNewStoredProcedureClick(collection, null); - } - }); - } - - private _openSprocTabForResource(databaseId: string, collectionId: string, sprocId: string): void { - this._executeActionHelper(() => { - const collection: ViewModels.Collection = this._findMatchingCollectionForResource(databaseId, collectionId); - collection && collection.expandCollection(); - const storedProcedure = collection && collection.findStoredProcedureWithId(sprocId); - storedProcedure && storedProcedure.open(); - }); - } - - private _openNewTriggerTabForResource(databaseId: string, collectionId: string): void { - this._executeActionHelper(() => { - const collection: ViewModels.Collection = this._findAndExpandMatchingCollectionForResource( - databaseId, - collectionId - ); - const matchingTab: TabsBase = this._findMatchingTabByTabKind( - databaseId, - collectionId, - ViewModels.CollectionTabKind.Triggers, - true - ); - if (!!matchingTab) { - matchingTab.onTabClick(); - } else { - collection && collection.onNewTriggerClick(collection, null); - } - }); - } - - private _openTriggerTabForResource(databaseId: string, collectionId: string, triggerId: string): void { - this._executeActionHelper(() => { - const collection: ViewModels.Collection = this._findMatchingCollectionForResource(databaseId, collectionId); - collection && collection.expandCollection(); - const trigger = collection && collection.findTriggerWithId(triggerId); - trigger && trigger.open(); - }); - } - - private _openNewUserDefinedFunctionTabForResource(databaseId: string, collectionId: string): void { - this._executeActionHelper(() => { - const collection: ViewModels.Collection = this._findAndExpandMatchingCollectionForResource( - databaseId, - collectionId - ); - const matchingTab: TabsBase = this._findMatchingTabByTabKind( - databaseId, - collectionId, - ViewModels.CollectionTabKind.UserDefinedFunctions, - true - ); - if (!!matchingTab) { - matchingTab.onTabClick(); - } else { - collection && collection.onNewUserDefinedFunctionClick(collection, null); - } - }); - } - - private _openUserDefinedFunctionTabForResource(databaseId: string, collectionId: string, udfId: string): void { - this._executeActionHelper(() => { - const collection: ViewModels.Collection = this._findMatchingCollectionForResource(databaseId, collectionId); - collection && collection.expandCollection(); - const userDefinedFunction = collection && collection.findUserDefinedFunctionWithId(udfId); - userDefinedFunction && userDefinedFunction.open(); - }); - } - - private _openConflictsTabForResource(databaseId: string, collectionId: string): void { - this._executeActionHelper(() => { - const collection: ViewModels.Collection = this._findAndExpandMatchingCollectionForResource( - databaseId, - collectionId - ); - collection && collection.container && collection.onConflictsClick(); - }); - } - - private _findAndExpandMatchingCollectionForResource(databaseId: string, collectionId: string): ViewModels.Collection { - const matchedCollection: ViewModels.Collection = this._findMatchingCollectionForResource(databaseId, collectionId); - matchedCollection && matchedCollection.expandCollection(); - - return matchedCollection; - } - - private _findMatchingTabByTabKind( - databaseId: string, - collectionId: string, - tabKind: ViewModels.CollectionTabKind, - isNewScriptTab?: boolean - ): TabsBase { - const explorer = window.dataExplorer; - const matchingTabs: TabsBase[] = explorer.tabsManager.getTabs( - tabKind, - (tab: TabsBase) => - tab.collection && - tab.collection.databaseId === databaseId && - tab.collection.id() === collectionId && - (!isNewScriptTab || (tab as ScriptTabBase).isNew()) - ); - return matchingTabs && matchingTabs[0]; - } - - private _findMatchingCollectionForResource(databaseId: string, collectionId: string): ViewModels.Collection { - const explorer = window.dataExplorer; - const matchedDatabase: ViewModels.Database = useDatabases.getState().findDatabaseWithId(databaseId); - const matchedCollection: ViewModels.Collection = - matchedDatabase && matchedDatabase.findCollectionWithId(collectionId); - - return matchedCollection; - } - - private _executeActionHelper(action: () => void): void { - const explorer = window.dataExplorer; - if (explorer && explorer.isAccountReady()) { - action(); - } - } -}