From 46055c2cdee914a5f2bc7ac4b752772b9d3f202c Mon Sep 17 00:00:00 2001 From: Jade Welton Date: Wed, 14 Aug 2024 16:08:14 -0700 Subject: [PATCH] Remove calls to the backend notifications API and related code. --- src/Common/PortalNotifications.ts | 39 ------ src/Contracts/ViewModels.ts | 3 - .../Controls/Settings/SettingsComponent.tsx | 3 - .../ScaleComponent.test.tsx | 39 ------ .../SettingsSubComponents/ScaleComponent.tsx | 26 ---- src/Explorer/Tabs/TabsBase.ts | 3 - src/Explorer/Tree/Collection.ts | 37 ------ src/Explorer/Tree/Database.tsx | 115 +++++------------- 8 files changed, 31 insertions(+), 234 deletions(-) delete mode 100644 src/Common/PortalNotifications.ts diff --git a/src/Common/PortalNotifications.ts b/src/Common/PortalNotifications.ts deleted file mode 100644 index 774c37cad..000000000 --- a/src/Common/PortalNotifications.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { configContext, Platform } from "../ConfigContext"; -import * as DataModels from "../Contracts/DataModels"; -import * as ViewModels from "../Contracts/ViewModels"; -import { userContext } from "../UserContext"; -import { getAuthorizationHeader } from "../Utils/AuthorizationUtils"; - -const notificationsPath = () => { - switch (configContext.platform) { - case Platform.Hosted: - return "/api/guest/notifications"; - case Platform.Portal: - return "/api/notifications"; - default: - throw new Error(`Unknown platform: ${configContext.platform}`); - } -}; - -export const fetchPortalNotifications = async (): Promise => { - if (configContext.platform === Platform.Emulator || configContext.platform === Platform.Hosted) { - return []; - } - - const { databaseAccount, resourceGroup, subscriptionId } = userContext; - const url = `${configContext.BACKEND_ENDPOINT}${notificationsPath()}?accountName=${ - databaseAccount.name - }&subscriptionId=${subscriptionId}&resourceGroup=${resourceGroup}`; - const authorizationHeader: ViewModels.AuthorizationTokenHeaderMetadata = getAuthorizationHeader(); - const headers = { [authorizationHeader.header]: authorizationHeader.token }; - - const response = await window.fetch(url, { - headers, - }); - - if (!response.ok) { - throw new Error(await response.text()); - } - - return (await response.json()) as DataModels.Notification[]; -}; diff --git a/src/Contracts/ViewModels.ts b/src/Contracts/ViewModels.ts index 04afc10bb..767665686 100644 --- a/src/Contracts/ViewModels.ts +++ b/src/Contracts/ViewModels.ts @@ -98,7 +98,6 @@ export interface Database extends TreeNode { openAddCollection(database: Database, event: MouseEvent): void; onSettingsClick: () => void; loadOffer(): Promise; - getPendingThroughputSplitNotification(): Promise; } export interface CollectionBase extends TreeNode { @@ -191,8 +190,6 @@ export interface Collection extends CollectionBase { onDragOver(source: Collection, event: { originalEvent: DragEvent }): void; onDrop(source: Collection, event: { originalEvent: DragEvent }): void; uploadFiles(fileList: FileList): Promise<{ data: UploadDetailsRecord[] }>; - - getPendingThroughputSplitNotification(): Promise; } /** diff --git a/src/Explorer/Controls/Settings/SettingsComponent.tsx b/src/Explorer/Controls/Settings/SettingsComponent.tsx index 04e08753e..74f3fb4f6 100644 --- a/src/Explorer/Controls/Settings/SettingsComponent.tsx +++ b/src/Explorer/Controls/Settings/SettingsComponent.tsx @@ -130,7 +130,6 @@ export interface SettingsComponentState { conflictResolutionPolicyProcedureBaseline: string; isConflictResolutionDirty: boolean; - initialNotification: DataModels.Notification; selectedTab: SettingsV2TabTypes; } @@ -229,7 +228,6 @@ export class SettingsComponent extends React.Component { - const targetThroughput = 6000; - const baseProps: ScaleComponentProps = { collection: collection, database: undefined, @@ -36,39 +28,8 @@ describe("ScaleComponent", () => { onScaleDiscardableChange: () => { return; }, - initialNotification: { - description: `Throughput update for ${targetThroughput} ${throughputUnit}`, - } as DataModels.Notification, }; - it("renders with correct initial notification", () => { - let wrapper = shallow(); - expect(wrapper).toMatchSnapshot(); - expect(wrapper.exists(ThroughputInputAutoPilotV3Component)).toEqual(true); - expect(wrapper.exists("#throughputApplyLongDelayMessage")).toEqual(true); - expect(wrapper.exists("#throughputApplyShortDelayMessage")).toEqual(false); - expect(wrapper.find("#throughputApplyLongDelayMessage").html()).toContain(`${targetThroughput}`); - - const newCollection = { ...collection }; - const maxThroughput = 5000; - newCollection.offer = ko.observable({ - manualThroughput: undefined, - autoscaleMaxThroughput: maxThroughput, - minimumThroughput: 400, - id: "offer", - offerReplacePending: true, - }); - const newProps = { - ...baseProps, - initialNotification: undefined as DataModels.Notification, - collection: newCollection, - }; - wrapper = shallow(); - expect(wrapper.exists("#throughputApplyShortDelayMessage")).toEqual(true); - expect(wrapper.exists("#throughputApplyLongDelayMessage")).toEqual(false); - expect(wrapper.find("#throughputApplyShortDelayMessage").html()).toContain(`${maxThroughput}`); - }); - it("autoScale disabled", () => { const scaleComponent = new ScaleComponent(baseProps); expect(scaleComponent.isAutoScaleEnabled()).toEqual(false); diff --git a/src/Explorer/Controls/Settings/SettingsSubComponents/ScaleComponent.tsx b/src/Explorer/Controls/Settings/SettingsSubComponents/ScaleComponent.tsx index 761fe899b..251a3b841 100644 --- a/src/Explorer/Controls/Settings/SettingsSubComponents/ScaleComponent.tsx +++ b/src/Explorer/Controls/Settings/SettingsSubComponents/ScaleComponent.tsx @@ -10,7 +10,6 @@ import * as AutoPilotUtils from "../../../../Utils/AutoPilotUtils"; import { isRunningOnNationalCloud } from "../../../../Utils/CloudUtils"; import { getTextFieldStyles, - getThroughputApplyLongDelayMessage, getThroughputApplyShortDelayMessage, subComponentStackProps, throughputUnit, @@ -34,7 +33,6 @@ export interface ScaleComponentProps { onMaxAutoPilotThroughputChange: (newThroughput: number) => void; onScaleSaveableChange: (isScaleSaveable: boolean) => void; onScaleDiscardableChange: (isScaleDiscardable: boolean) => void; - initialNotification: DataModels.Notification; throughputError?: string; } @@ -102,10 +100,6 @@ export class ScaleComponent extends React.Component { }; public getInitialNotificationElement = (): JSX.Element => { - if (this.props.initialNotification) { - return this.getLongDelayMessage(); - } - if (this.offer?.offerReplacePending) { const throughput = this.offer.manualThroughput || this.offer.autoscaleMaxThroughput; return getThroughputApplyShortDelayMessage( @@ -120,26 +114,6 @@ export class ScaleComponent extends React.Component { return undefined; }; - public getLongDelayMessage = (): JSX.Element => { - const matches: string[] = this.props.initialNotification?.description.match( - `Throughput update for (.*) ${throughputUnit}`, - ); - - const throughput = this.props.throughputBaseline; - const targetThroughput: number = matches.length > 1 && Number(matches[1]); - if (targetThroughput) { - return getThroughputApplyLongDelayMessage( - this.props.wasAutopilotOriginallySet, - throughput, - throughputUnit, - this.databaseId, - this.collectionId, - targetThroughput, - ); - } - return <>; - }; - private getThroughputInputComponent = (): JSX.Element => ( ; public isExecutionError = ko.observable(false); public isExecuting = ko.observable(false); - public pendingNotification?: ko.Observable; protected _theme: string; public onLoadStartKey: number; @@ -45,7 +43,6 @@ export default class TabsBase extends WaitsForTemplateViewModel { this.tabPath = this.collection && ko.observable(`${this.collection.databaseId}>${this.collection.id()}>${options.title}`); - this.pendingNotification = ko.observable(undefined); this.onLoadStartKey = options.onLoadStartKey; this.closeTabButton = { enabled: ko.computed(() => { diff --git a/src/Explorer/Tree/Collection.ts b/src/Explorer/Tree/Collection.ts index fffacb134..26246f1b1 100644 --- a/src/Explorer/Tree/Collection.ts +++ b/src/Explorer/Tree/Collection.ts @@ -5,8 +5,6 @@ import * as ko from "knockout"; import * as _ from "underscore"; import * as Constants from "../../Common/Constants"; import { getErrorMessage, getErrorStack } from "../../Common/ErrorHandlingUtils"; -import * as Logger from "../../Common/Logger"; -import { fetchPortalNotifications } from "../../Common/PortalNotifications"; import { bulkCreateDocument } from "../../Common/dataAccess/bulkCreateDocument"; import { createDocument } from "../../Common/dataAccess/createDocument"; import { getCollectionUsageSizeInKB } from "../../Common/dataAccess/getCollectionDataUsageSize"; @@ -1020,41 +1018,6 @@ export default class Collection implements ViewModels.Collection { this.uploadFiles(event.originalEvent.dataTransfer.files); } - public async getPendingThroughputSplitNotification(): Promise { - if (!this.container) { - return undefined; - } - - try { - const notifications: DataModels.Notification[] = await fetchPortalNotifications(); - if (!notifications || notifications.length === 0) { - return undefined; - } - - return _.find(notifications, (notification: DataModels.Notification) => { - const throughputUpdateRegExp: RegExp = new RegExp("Throughput update (.*) in progress"); - return ( - notification.kind === "message" && - notification.collectionName === this.id() && - notification.description && - throughputUpdateRegExp.test(notification.description) - ); - }); - } catch (error) { - Logger.logError( - JSON.stringify({ - error: getErrorMessage(error), - accountName: userContext?.databaseAccount, - databaseName: this.databaseId, - collectionName: this.id(), - }), - "Settings tree node", - ); - - return undefined; - } - } - public async uploadFiles(files: FileList): Promise<{ data: UploadDetailsRecord[] }> { const data = await Promise.all(Array.from(files).map((file) => this.uploadFile(file))); diff --git a/src/Explorer/Tree/Database.tsx b/src/Explorer/Tree/Database.tsx index 7da55a1cf..0ed11cb5d 100644 --- a/src/Explorer/Tree/Database.tsx +++ b/src/Explorer/Tree/Database.tsx @@ -4,8 +4,6 @@ import * as _ from "underscore"; import { AuthType } from "../../AuthType"; import * as Constants from "../../Common/Constants"; import { getErrorMessage, getErrorStack } from "../../Common/ErrorHandlingUtils"; -import * as Logger from "../../Common/Logger"; -import { fetchPortalNotifications } from "../../Common/PortalNotifications"; import { readCollections, readCollectionsWithPagination } from "../../Common/dataAccess/readCollections"; import { readDatabaseOffer } from "../../Common/dataAccess/readDatabaseOffer"; import * as DataModels from "../../Contracts/DataModels"; @@ -76,7 +74,6 @@ export default class Database implements ViewModels.Database { await useDatabases.getState().loadAllOffers(); } - const pendingNotificationsPromise: Promise = this.getPendingThroughputSplitNotification(); const tabKind = ViewModels.CollectionTabKind.DatabaseSettingsV2; const matchingTabs = useTabs.getState().getTabs(tabKind, (tab) => tab.node?.id() === this.id()); let settingsTab = matchingTabs?.[0] as DatabaseSettingsTabV2; @@ -87,53 +84,39 @@ export default class Database implements ViewModels.Database { dataExplorerArea: Constants.Areas.Tab, tabTitle: "Scale", }); - pendingNotificationsPromise.then( - // eslint-disable-next-line @typescript-eslint/no-explicit-any - (data: any) => { - const pendingNotification: DataModels.Notification = data?.[0]; - const tabOptions: ViewModels.TabOptions = { - tabKind, - title: "Scale", - tabPath: "", - node: this, - rid: this.rid, - database: this, - onLoadStartKey: startKey, - }; - settingsTab = new DatabaseSettingsTabV2(tabOptions); - settingsTab.pendingNotification(pendingNotification); - useTabs.getState().activateNewTab(settingsTab); - }, - (error) => { - const errorMessage = getErrorMessage(error); - TelemetryProcessor.traceFailure( - Action.Tab, - { - databaseName: this.id(), - collectionName: this.id(), - dataExplorerArea: Constants.Areas.Tab, - tabTitle: "Scale", - error: errorMessage, - errorStack: getErrorStack(error), - }, - startKey, - ); - logConsoleError(`Error while fetching database settings for database ${this.id()}: ${errorMessage}`); - throw error; - }, - ); + try { + const tabOptions: ViewModels.TabOptions = { + tabKind, + title: "Scale", + tabPath: "", + node: this, + rid: this.rid, + database: this, + onLoadStartKey: startKey, + }; + settingsTab = new DatabaseSettingsTabV2(tabOptions); + useTabs.getState().activateNewTab(settingsTab); + } catch (error) { + const errorMessage = getErrorMessage(error); + TelemetryProcessor.traceFailure( + Action.Tab, + { + databaseName: this.id(), + collectionName: this.id(), + + dataExplorerArea: Constants.Areas.Tab, + tabTitle: "Scale", + error: errorMessage, + errorStack: getErrorStack(error), + }, + startKey, + ); + logConsoleError(`Error while fetching database settings for database ${this.id()}: ${errorMessage}`); + throw error; + } } else { - pendingNotificationsPromise.then( - (pendingNotification: DataModels.Notification) => { - settingsTab.pendingNotification(pendingNotification); - useTabs.getState().activateTab(settingsTab); - }, - () => { - settingsTab.pendingNotification(undefined); - useTabs.getState().activateTab(settingsTab); - }, - ); + useTabs.getState().activateTab(settingsTab); } }; @@ -260,42 +243,6 @@ export default class Database implements ViewModels.Database { } } - public async getPendingThroughputSplitNotification(): Promise { - if (!this.container) { - return undefined; - } - - try { - const notifications: DataModels.Notification[] = await fetchPortalNotifications(); - if (!notifications || notifications.length === 0) { - return undefined; - } - - return _.find(notifications, (notification: DataModels.Notification) => { - const throughputUpdateRegExp = new RegExp("Throughput update (.*) in progress"); - return ( - notification.kind === "message" && - !notification.collectionName && - notification.databaseName === this.id() && - notification.description && - throughputUpdateRegExp.test(notification.description) - ); - }); - } catch (error) { - Logger.logError( - JSON.stringify({ - error: getErrorMessage(error), - accountName: userContext?.databaseAccount, - databaseName: this.id(), - collectionName: this.id(), - }), - "Settings tree node", - ); - - return undefined; - } - } - private getDeltaCollections(updatedCollectionsList: DataModels.Collection[]): { toAdd: DataModels.Collection[]; toDelete: Collection[];