From 045a28b7a46088fc2b71adcb7a86bdbefe285e89 Mon Sep 17 00:00:00 2001 From: Jordi Bunster Date: Fri, 23 Apr 2021 19:54:21 -0700 Subject: [PATCH] Remove 'any' from existing lazy loaded tabs (#721) * Typesafe lazy loaded GalleryTab * Typesafe lazy loaded NotebookViewerTab * Typesafe lazy loaded NotebookManager --- src/Explorer/Explorer.tsx | 80 +++++++++-------------- src/Explorer/Notebook/NotebookManager.tsx | 10 ++- src/Explorer/Tabs/GalleryTab.tsx | 2 +- 3 files changed, 40 insertions(+), 52 deletions(-) diff --git a/src/Explorer/Explorer.tsx b/src/Explorer/Explorer.tsx index 5e289f1f7..32fb23038 100644 --- a/src/Explorer/Explorer.tsx +++ b/src/Explorer/Explorer.tsx @@ -42,11 +42,13 @@ import * as ComponentRegisterer from "./ComponentRegisterer"; import { ArcadiaWorkspaceItem } from "./Controls/Arcadia/ArcadiaMenuPicker"; import { CommandButtonComponentProps } from "./Controls/CommandButton/CommandButtonComponent"; import { DialogProps, TextFieldProps } from "./Controls/Dialog"; -import { GalleryTab } from "./Controls/NotebookGallery/GalleryViewerComponent"; +import { GalleryTab as GalleryTabKind } from "./Controls/NotebookGallery/GalleryViewerComponent"; import { CommandBarComponentAdapter } from "./Menus/CommandBar/CommandBarComponentAdapter"; import { ConsoleData } from "./Menus/NotificationConsole/NotificationConsoleComponent"; import * as FileSystemUtil from "./Notebook/FileSystemUtil"; import { NotebookContentItem, NotebookContentItemType } from "./Notebook/NotebookContentItem"; +import type NotebookManager from "./Notebook/NotebookManager"; +import type { NotebookPaneContent } from "./Notebook/NotebookManager"; import { NotebookUtil } from "./Notebook/NotebookUtil"; import AddCollectionPane from "./Panes/AddCollectionPane"; import { AddCollectionPanel } from "./Panes/AddCollectionPanel"; @@ -71,9 +73,9 @@ import { UploadItemsPane } from "./Panes/UploadItemsPane/UploadItemsPane"; import TableListViewModal from "./Tables/DataTable/TableEntityListViewModel"; import QueryViewModel from "./Tables/QueryBuilder/QueryViewModel"; import { CassandraAPIDataClient, TableDataClient, TablesAPIDataClient } from "./Tables/TableDataClient"; +import type { GalleryTabOptions } from "./Tabs/GalleryTab"; import NotebookV2Tab, { NotebookTabOptions } from "./Tabs/NotebookV2Tab"; import QueryTablesTab from "./Tabs/QueryTablesTab"; -import TabsBase from "./Tabs/TabsBase"; import { TabsManager } from "./Tabs/TabsManager"; import TerminalTab from "./Tabs/TerminalTab"; import Database from "./Tree/Database"; @@ -165,8 +167,6 @@ export default class Explorer { // Tabs public isTabsContentExpanded: ko.Observable; - public galleryTab: any; - public notebookViewerTab: any; public tabsManager: TabsManager; // Contextual panes @@ -203,7 +203,7 @@ export default class Explorer { public hasStorageAnalyticsAfecFeature: ko.Observable; public isSynapseLinkUpdating: ko.Observable; public memoryUsageInfo: ko.Observable; - public notebookManager?: any; // This is dynamically loaded + public notebookManager?: NotebookManager; public openDialog: ExplorerParams["openDialog"]; public closeDialog: ExplorerParams["closeDialog"]; @@ -636,10 +636,10 @@ export default class Explorer { this.isNotebookEnabled = ko.observable(false); this.isNotebookEnabled.subscribe(async () => { if (!this.notebookManager) { - const notebookManagerModule = await import( - /* webpackChunkName: "NotebookManager" */ "./Notebook/NotebookManager" - ); - this.notebookManager = new notebookManagerModule.default(); + const NotebookManager = await ( + await import(/* webpackChunkName: "NotebookManager" */ "./Notebook/NotebookManager") + ).default; + this.notebookManager = new NotebookManager(); this.notebookManager.initialize({ container: this, notebookBasePath: this.notebookBasePath, @@ -1424,7 +1424,11 @@ export default class Explorer { return Promise.resolve(false); } - public async publishNotebook(name: string, content: string | unknown, parentDomElement?: HTMLElement): Promise { + public async publishNotebook( + name: string, + content: NotebookPaneContent, + parentDomElement?: HTMLElement + ): Promise { if (this.notebookManager) { await this.notebookManager.openPublishNotebookPane(name, content, parentDomElement); this.publishNotebookPaneAdapter = this.notebookManager.publishNotebookPaneAdapter; @@ -1922,86 +1926,66 @@ export default class Explorer { } public async openGallery( - selectedTab?: GalleryTab, + selectedTab?: GalleryTabKind, notebookUrl?: string, galleryItem?: IGalleryItem, isFavorite?: boolean ) { - let title: string = "Gallery"; - let hashLocation: string = "gallery"; + const title = "Gallery"; + const hashLocation = "gallery"; + const GalleryTab = await (await import(/* webpackChunkName: "GalleryTab" */ "./Tabs/GalleryTab")).default; - const galleryTabOptions: any = { - // GalleryTabOptions + const galleryTabOptions: GalleryTabOptions = { account: userContext.databaseAccount, container: this, junoClient: this.notebookManager?.junoClient, - selectedTab: selectedTab || GalleryTab.PublicGallery, + selectedTab: selectedTab || GalleryTabKind.PublicGallery, notebookUrl, galleryItem, isFavorite, - // TabOptions tabKind: ViewModels.CollectionTabKind.Gallery, title: title, tabPath: title, - documentClientUtility: null, - isActive: ko.observable(false), hashLocation: hashLocation, onUpdateTabsButtons: this.onUpdateTabsButtons, isTabsContentExpanded: ko.observable(true), onLoadStartKey: null, }; - const galleryTabs = this.tabsManager.getTabs( - ViewModels.CollectionTabKind.Gallery, - (tab) => tab.hashLocation() == hashLocation - ); - let galleryTab = galleryTabs && galleryTabs[0]; + const galleryTab = this.tabsManager + .getTabs(ViewModels.CollectionTabKind.Gallery) + .find((tab) => tab.hashLocation() == hashLocation); - if (galleryTab) { + if (galleryTab instanceof GalleryTab) { this.tabsManager.activateTab(galleryTab); - (galleryTab as any).reset(galleryTabOptions); + galleryTab.reset(galleryTabOptions); } else { - if (!this.galleryTab) { - this.galleryTab = await import(/* webpackChunkName: "GalleryTab" */ "./Tabs/GalleryTab"); - } - const newTab = new this.galleryTab.default(galleryTabOptions); - this.tabsManager.activateNewTab(newTab); + this.tabsManager.activateNewTab(new GalleryTab(galleryTabOptions)); } } public async openNotebookViewer(notebookUrl: string) { const title = path.basename(notebookUrl); const hashLocation = notebookUrl; + const NotebookViewerTab = await ( + await import(/* webpackChunkName: "NotebookViewerTab" */ "./Tabs/NotebookViewerTab") + ).default; - if (!this.notebookViewerTab) { - this.notebookViewerTab = await import(/* webpackChunkName: "NotebookViewerTab" */ "./Tabs/NotebookViewerTab"); - } - - const notebookViewerTabModule = this.notebookViewerTab; - - let isNotebookViewerOpen = (tab: TabsBase) => { - const notebookViewerTab = tab as typeof notebookViewerTabModule.default; - return notebookViewerTab.notebookUrl === notebookUrl; - }; - - const notebookViewerTabs = this.tabsManager.getTabs(ViewModels.CollectionTabKind.NotebookV2, (tab) => { - return tab.hashLocation() == hashLocation && isNotebookViewerOpen(tab); + const notebookViewerTab = this.tabsManager.getTabs(ViewModels.CollectionTabKind.NotebookV2).find((tab) => { + return tab.hashLocation() == hashLocation && tab instanceof NotebookViewerTab && tab.notebookUrl === notebookUrl; }); - let notebookViewerTab = notebookViewerTabs && notebookViewerTabs[0]; if (notebookViewerTab) { this.tabsManager.activateNewTab(notebookViewerTab); } else { - notebookViewerTab = new this.notebookViewerTab.default({ + const notebookViewerTab = new NotebookViewerTab({ account: userContext.databaseAccount, tabKind: ViewModels.CollectionTabKind.NotebookViewer, node: null, title: title, tabPath: title, - documentClientUtility: null, collection: null, hashLocation: hashLocation, - isActive: ko.observable(false), isTabsContentExpanded: ko.observable(true), onLoadStartKey: null, onUpdateTabsButtons: this.onUpdateTabsButtons, diff --git a/src/Explorer/Notebook/NotebookManager.tsx b/src/Explorer/Notebook/NotebookManager.tsx index 42f41baf5..7d8c9a1d5 100644 --- a/src/Explorer/Notebook/NotebookManager.tsx +++ b/src/Explorer/Notebook/NotebookManager.tsx @@ -2,8 +2,8 @@ * Contains all notebook related stuff meant to be dynamically loaded by explorer */ -import { ImmutableNotebook } from "@nteract/commutable"; -import { IContentProvider } from "@nteract/core"; +import type { ImmutableNotebook } from "@nteract/commutable"; +import type { IContentProvider } from "@nteract/core"; import ko from "knockout"; import React from "react"; import { contents } from "rx-jupyter"; @@ -28,6 +28,10 @@ import { NotebookContentProvider } from "./NotebookComponent/NotebookContentProv import { NotebookContainerClient } from "./NotebookContainerClient"; import { NotebookContentClient } from "./NotebookContentClient"; +type NotebookPaneContent = string | ImmutableNotebook; + +export type { NotebookPaneContent }; + export interface NotebookManagerOptions { container: Explorer; notebookBasePath: ko.Observable; @@ -116,7 +120,7 @@ export default class NotebookManager { public async openPublishNotebookPane( name: string, - content: string | ImmutableNotebook, + content: NotebookPaneContent, parentDomElement: HTMLElement ): Promise { await this.publishNotebookPaneAdapter.open(name, getFullName(), content, parentDomElement); diff --git a/src/Explorer/Tabs/GalleryTab.tsx b/src/Explorer/Tabs/GalleryTab.tsx index abd2b35da..496b13cf8 100644 --- a/src/Explorer/Tabs/GalleryTab.tsx +++ b/src/Explorer/Tabs/GalleryTab.tsx @@ -7,7 +7,7 @@ import { GalleryTab as GalleryViewerTab, SortBy } from "../Controls/NotebookGall import Explorer from "../Explorer"; import TabsBase from "./TabsBase"; -interface GalleryTabOptions extends ViewModels.TabOptions { +export interface GalleryTabOptions extends ViewModels.TabOptions { account: DatabaseAccount; container: Explorer; junoClient: JunoClient;