From 2dc33c033396d359f13955aadd0eecc0b597e941 Mon Sep 17 00:00:00 2001 From: hardiknai-techm Date: Wed, 7 Apr 2021 05:39:29 +0530 Subject: [PATCH] remove AddDatabasePane knowckout.js code --- src/Explorer/Panes/AddDatabasePane.test.ts | 105 ----- src/Explorer/Panes/AddDatabasePane.ts | 461 --------------------- 2 files changed, 566 deletions(-) delete mode 100644 src/Explorer/Panes/AddDatabasePane.test.ts delete mode 100644 src/Explorer/Panes/AddDatabasePane.ts diff --git a/src/Explorer/Panes/AddDatabasePane.test.ts b/src/Explorer/Panes/AddDatabasePane.test.ts deleted file mode 100644 index 711a9cfc1..000000000 --- a/src/Explorer/Panes/AddDatabasePane.test.ts +++ /dev/null @@ -1,105 +0,0 @@ -import * as Constants from "../../Common/Constants"; -import { DatabaseAccount } from "../../Contracts/DataModels"; -import { SubscriptionType } from "../../Contracts/SubscriptionType"; -import { updateUserContext } from "../../UserContext"; -import Explorer from "../Explorer"; -import AddDatabasePane from "./AddDatabasePane"; - -describe("Add Database Pane", () => { - describe("getSharedThroughputDefault()", () => { - let explorer: Explorer; - const mockDatabaseAccount: DatabaseAccount = { - id: "mock", - kind: "DocumentDB", - location: "", - name: "mock", - properties: { - documentEndpoint: "", - cassandraEndpoint: "", - gremlinEndpoint: "", - tableEndpoint: "", - enableFreeTier: false, - }, - type: undefined, - tags: [], - }; - - const mockFreeTierDatabaseAccount: DatabaseAccount = { - id: "mock", - kind: "DocumentDB", - location: "", - name: "mock", - properties: { - documentEndpoint: "", - cassandraEndpoint: "", - gremlinEndpoint: "", - tableEndpoint: "", - enableFreeTier: true, - }, - type: undefined, - tags: [], - }; - - beforeEach(() => { - explorer = new Explorer(); - }); - - it("should be true if subscription type is Benefits", () => { - updateUserContext({ - subscriptionType: SubscriptionType.Benefits, - }); - const addDatabasePane = explorer.addDatabasePane as AddDatabasePane; - expect(addDatabasePane.getSharedThroughputDefault()).toBe(true); - }); - - it("should be false if subscription type is EA", () => { - updateUserContext({ - subscriptionType: SubscriptionType.EA, - }); - const addDatabasePane = explorer.addDatabasePane as AddDatabasePane; - expect(addDatabasePane.getSharedThroughputDefault()).toBe(false); - }); - - it("should be true if subscription type is Free", () => { - updateUserContext({ - subscriptionType: SubscriptionType.Free, - }); - const addDatabasePane = explorer.addDatabasePane as AddDatabasePane; - expect(addDatabasePane.getSharedThroughputDefault()).toBe(true); - }); - - it("should be true if subscription type is Internal", () => { - updateUserContext({ - subscriptionType: SubscriptionType.Internal, - }); - const addDatabasePane = explorer.addDatabasePane as AddDatabasePane; - expect(addDatabasePane.getSharedThroughputDefault()).toBe(true); - }); - - it("should be true if subscription type is PAYG", () => { - updateUserContext({ - subscriptionType: SubscriptionType.PAYG, - }); - const addDatabasePane = explorer.addDatabasePane as AddDatabasePane; - expect(addDatabasePane.getSharedThroughputDefault()).toBe(true); - }); - - it("should display free tier text in upsell messaging", () => { - explorer.databaseAccount(mockFreeTierDatabaseAccount); - const addDatabasePane = explorer.addDatabasePane as AddDatabasePane; - expect(addDatabasePane.isFreeTierAccount()).toBe(true); - expect(addDatabasePane.upsellMessage()).toContain("With free tier"); - expect(addDatabasePane.upsellAnchorUrl()).toBe(Constants.Urls.freeTierInformation); - expect(addDatabasePane.upsellAnchorText()).toBe("Learn more"); - }); - - it("should display standard texr in upsell messaging", () => { - explorer.databaseAccount(mockDatabaseAccount); - const addDatabasePane = explorer.addDatabasePane as AddDatabasePane; - expect(addDatabasePane.isFreeTierAccount()).toBe(false); - expect(addDatabasePane.upsellMessage()).toContain("Start at"); - expect(addDatabasePane.upsellAnchorUrl()).toBe(Constants.Urls.cosmosPricing); - expect(addDatabasePane.upsellAnchorText()).toBe("More details"); - }); - }); -}); diff --git a/src/Explorer/Panes/AddDatabasePane.ts b/src/Explorer/Panes/AddDatabasePane.ts deleted file mode 100644 index dff1f08ff..000000000 --- a/src/Explorer/Panes/AddDatabasePane.ts +++ /dev/null @@ -1,461 +0,0 @@ -import * as ko from "knockout"; -import * as Constants from "../../Common/Constants"; -import { createDatabase } from "../../Common/dataAccess/createDatabase"; -import editable from "../../Common/EditableUtility"; -import { getErrorMessage, getErrorStack } from "../../Common/ErrorHandlingUtils"; -import { configContext, Platform } from "../../ConfigContext"; -import * as DataModels from "../../Contracts/DataModels"; -import { SubscriptionType } from "../../Contracts/SubscriptionType"; -import * as ViewModels from "../../Contracts/ViewModels"; -import * as SharedConstants from "../../Shared/Constants"; -import { Action, ActionModifiers } from "../../Shared/Telemetry/TelemetryConstants"; -import * as TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor"; -import { userContext } from "../../UserContext"; -import * as AutoPilotUtils from "../../Utils/AutoPilotUtils"; -import * as PricingUtils from "../../Utils/PricingUtils"; -import { ContextualPaneBase } from "./ContextualPaneBase"; - -export default class AddDatabasePane extends ContextualPaneBase { - public defaultExperience: ko.Computed; - public databaseIdLabel: ko.Computed; - public databaseIdPlaceHolder: ko.Computed; - public databaseId: ko.Observable; - public databaseIdTooltipText: ko.Computed; - public databaseLevelThroughputTooltipText: ko.Computed; - public databaseCreateNewShared: ko.Observable; - public formErrorsDetails: ko.Observable; - public throughput: ViewModels.Editable; - public maxThroughputRU: ko.Observable; - public minThroughputRU: ko.Observable; - public maxThroughputRUText: ko.PureComputed; - public throughputRangeText: ko.Computed; - public throughputSpendAckText: ko.Observable; - public throughputSpendAck: ko.Observable; - public throughputSpendAckVisible: ko.Computed; - public requestUnitsUsageCost: ko.Computed; - public canRequestSupport: ko.PureComputed; - public costsVisible: ko.PureComputed; - public upsellMessage: ko.PureComputed; - public upsellMessageAriaLabel: ko.PureComputed; - public upsellAnchorUrl: ko.PureComputed; - public upsellAnchorText: ko.PureComputed; - public isAutoPilotSelected: ko.Observable; - public maxAutoPilotThroughputSet: ko.Observable; - public autoPilotUsageCost: ko.Computed; - public canExceedMaximumValue: ko.PureComputed; - public ruToolTipText: ko.Computed; - public freeTierExceedThroughputTooltip: ko.Computed; - public isFreeTierAccount: ko.Computed; - public canConfigureThroughput: ko.PureComputed; - public showUpsellMessage: ko.PureComputed; - - constructor(options: ViewModels.PaneOptions) { - super(options); - this.title((this.container && this.container.addDatabaseText()) || "New Database"); - this.databaseId = ko.observable(); - this.ruToolTipText = ko.pureComputed(() => PricingUtils.getRuToolTipText()); - this.canConfigureThroughput = ko.pureComputed(() => !this.container.isServerlessEnabled()); - - this.canExceedMaximumValue = ko.pureComputed(() => this.container.canExceedMaximumValue()); - - // TODO 388844: get defaults from parent frame - this.databaseCreateNewShared = ko.observable(this.getSharedThroughputDefault()); - - this.databaseIdLabel = ko.computed(() => - this.container.isPreferredApiCassandra() ? "Keyspace id" : "Database id" - ); - - this.databaseIdPlaceHolder = ko.computed(() => - this.container.isPreferredApiCassandra() ? "Type a new keyspace id" : "Type a new database id" - ); - - this.databaseIdTooltipText = ko.computed(() => { - const isCassandraAccount: boolean = this.container.isPreferredApiCassandra(); - return `A ${isCassandraAccount ? "keyspace" : "database"} is a logical container of one or more ${ - isCassandraAccount ? "tables" : "collections" - }`; - }); - this.databaseLevelThroughputTooltipText = ko.computed(() => { - const isCassandraAccount: boolean = this.container.isPreferredApiCassandra(); - const databaseLabel: string = isCassandraAccount ? "keyspace" : "database"; - const collectionsLabel: string = isCassandraAccount ? "tables" : "collections"; - return `Provisioned throughput at the ${databaseLabel} level will be shared across all ${collectionsLabel} within the ${databaseLabel}.`; - }); - - this.throughput = editable.observable(); - this.maxThroughputRU = ko.observable(); - this.minThroughputRU = ko.observable(); - this.throughputSpendAckText = ko.observable(); - this.throughputSpendAck = ko.observable(false); - this.isAutoPilotSelected = ko.observable(false); - this.maxAutoPilotThroughputSet = ko.observable(AutoPilotUtils.minAutoPilotThroughput); - this.autoPilotUsageCost = ko.pureComputed(() => { - const autoPilot = this._isAutoPilotSelectedAndWhatTier(); - if (!autoPilot) { - return ""; - } - return PricingUtils.getAutoPilotV3SpendHtml(autoPilot.maxThroughput, true /* isDatabaseThroughput */); - }); - this.throughputRangeText = ko.pureComputed(() => { - if (this.isAutoPilotSelected()) { - return AutoPilotUtils.getAutoPilotHeaderText(); - } - return `Throughput (${this.minThroughputRU().toLocaleString()} - ${this.maxThroughputRU().toLocaleString()} RU/s)`; - }); - - this.requestUnitsUsageCost = ko.computed(() => { - const offerThroughput: number = this.throughput(); - if ( - offerThroughput < this.minThroughputRU() || - (offerThroughput > this.maxThroughputRU() && !this.canExceedMaximumValue()) - ) { - return ""; - } - - const account = this.container.databaseAccount(); - if (!account) { - return ""; - } - - const regions = - (account && - account.properties && - account.properties.readLocations && - account.properties.readLocations.length) || - 1; - const multimaster = (account && account.properties && account.properties.enableMultipleWriteLocations) || false; - - let estimatedSpendAcknowledge: string; - let estimatedSpend: string; - if (!this.isAutoPilotSelected()) { - estimatedSpend = PricingUtils.getEstimatedSpendHtml( - offerThroughput, - userContext.portalEnv, - regions, - multimaster - ); - estimatedSpendAcknowledge = PricingUtils.getEstimatedSpendAcknowledgeString( - offerThroughput, - userContext.portalEnv, - regions, - multimaster, - this.isAutoPilotSelected() - ); - } else { - estimatedSpend = PricingUtils.getEstimatedAutoscaleSpendHtml( - this.maxAutoPilotThroughputSet(), - userContext.portalEnv, - regions, - multimaster - ); - estimatedSpendAcknowledge = PricingUtils.getEstimatedSpendAcknowledgeString( - this.maxAutoPilotThroughputSet(), - userContext.portalEnv, - regions, - multimaster, - this.isAutoPilotSelected() - ); - } - // TODO: change throughputSpendAckText to be a computed value, instead of having this side effect - this.throughputSpendAckText(estimatedSpendAcknowledge); - return estimatedSpend; - }); - - this.canRequestSupport = ko.pureComputed(() => { - if ( - configContext.platform !== Platform.Emulator && - !userContext.isTryCosmosDBSubscription && - configContext.platform !== Platform.Portal - ) { - const offerThroughput: number = this.throughput(); - return offerThroughput <= 100000; - } - - return false; - }); - - this.isFreeTierAccount = ko.computed(() => { - const databaseAccount = this.container && this.container.databaseAccount && this.container.databaseAccount(); - const isFreeTierAccount = - databaseAccount && databaseAccount.properties && databaseAccount.properties.enableFreeTier; - return isFreeTierAccount; - }); - - this.showUpsellMessage = ko.pureComputed(() => { - if (this.container.isServerlessEnabled()) { - return false; - } - - if (this.isFreeTierAccount()) { - return this.databaseCreateNewShared(); - } - - return true; - }); - - this.maxThroughputRUText = ko.pureComputed(() => { - return this.maxThroughputRU().toLocaleString(); - }); - - this.costsVisible = ko.pureComputed(() => { - return configContext.platform !== Platform.Emulator; - }); - - this.throughputSpendAckVisible = ko.pureComputed(() => { - const autoscaleThroughput = this.maxAutoPilotThroughputSet() * 1; - if (this.isAutoPilotSelected()) { - return autoscaleThroughput > SharedConstants.CollectionCreation.DefaultCollectionRUs100K; - } - - const selectedThroughput: number = this.throughput(); - const maxRU: number = this.maxThroughputRU && this.maxThroughputRU(); - - const isMaxRUGreaterThanDefault: boolean = maxRU > SharedConstants.CollectionCreation.DefaultCollectionRUs100K; - const isThroughputSetGreaterThanDefault: boolean = - selectedThroughput > SharedConstants.CollectionCreation.DefaultCollectionRUs100K; - - if (this.canExceedMaximumValue()) { - return isThroughputSetGreaterThanDefault; - } - - return isThroughputSetGreaterThanDefault && isMaxRUGreaterThanDefault; - }); - - this.databaseCreateNewShared.subscribe((useShared: boolean) => { - this._updateThroughputLimitByDatabase(); - }); - - this.resetData(); - - this.freeTierExceedThroughputTooltip = ko.pureComputed(() => - this.isFreeTierAccount() && !this.container.isFirstResourceCreated() - ? "The first 400 RU/s in this account are free. Billing will apply to any throughput beyond 400 RU/s." - : "" - ); - - this.upsellMessage = ko.pureComputed(() => { - return PricingUtils.getUpsellMessage( - userContext.portalEnv, - this.isFreeTierAccount(), - this.container.isFirstResourceCreated(), - this.container.defaultExperience(), - false - ); - }); - - this.upsellMessageAriaLabel = ko.pureComputed(() => { - return `${this.upsellMessage()}. Click ${this.isFreeTierAccount() ? "to learn more" : "for more details"}`; - }); - - this.upsellAnchorUrl = ko.pureComputed(() => { - return this.isFreeTierAccount() ? Constants.Urls.freeTierInformation : Constants.Urls.cosmosPricing; - }); - - this.upsellAnchorText = ko.pureComputed(() => { - return this.isFreeTierAccount() ? "Learn more" : "More details"; - }); - } - - public onMoreDetailsKeyPress = (source: any, event: KeyboardEvent): boolean => { - if (event.keyCode === Constants.KeyCodes.Space || event.keyCode === Constants.KeyCodes.Enter) { - this.showErrorDetails(); - return false; - } - return true; - }; - - public open() { - super.open(); - this.resetData(); - const addDatabasePaneOpenMessage = { - subscriptionType: userContext.subscriptionType, - subscriptionQuotaId: userContext.quotaId, - defaultsCheck: { - throughput: this.throughput(), - flight: userContext.addCollectionFlight, - }, - dataExplorerArea: Constants.Areas.ContextualPane, - }; - const focusElement = document.getElementById("database-id"); - focusElement && focusElement.focus(); - TelemetryProcessor.trace(Action.CreateDatabase, ActionModifiers.Open, addDatabasePaneOpenMessage); - } - - public submit() { - if (!this._isValid()) { - return; - } - - const offerThroughput: number = this._computeOfferThroughput(); - - const addDatabasePaneStartMessage = { - database: ko.toJS({ - id: this.databaseId(), - shared: this.databaseCreateNewShared(), - }), - offerThroughput, - subscriptionType: userContext.subscriptionType, - subscriptionQuotaId: userContext.quotaId, - defaultsCheck: { - flight: userContext.addCollectionFlight, - }, - dataExplorerArea: Constants.Areas.ContextualPane, - }; - const startKey: number = TelemetryProcessor.traceStart(Action.CreateDatabase, addDatabasePaneStartMessage); - this.formErrors(""); - this.isExecuting(true); - - const createDatabaseParams: DataModels.CreateDatabaseParams = { - databaseId: addDatabasePaneStartMessage.database.id, - databaseLevelThroughput: addDatabasePaneStartMessage.database.shared, - }; - - if (this.isAutoPilotSelected()) { - createDatabaseParams.autoPilotMaxThroughput = this.maxAutoPilotThroughputSet(); - } else { - createDatabaseParams.offerThroughput = addDatabasePaneStartMessage.offerThroughput; - } - - createDatabase(createDatabaseParams).then( - (database: DataModels.Database) => { - this._onCreateDatabaseSuccess(offerThroughput, startKey); - }, - (error: any) => { - this._onCreateDatabaseFailure(error, offerThroughput, startKey); - } - ); - } - - public resetData() { - this.databaseId(""); - this.databaseCreateNewShared(this.getSharedThroughputDefault()); - this.isAutoPilotSelected(this.container.isAutoscaleDefaultEnabled()); - this.maxAutoPilotThroughputSet(AutoPilotUtils.minAutoPilotThroughput); - this._updateThroughputLimitByDatabase(); - this.throughputSpendAck(false); - super.resetData(); - } - - public getSharedThroughputDefault(): boolean { - const subscriptionType = userContext.subscriptionType; - - if (subscriptionType === SubscriptionType.EA || this.container.isServerlessEnabled()) { - return false; - } - - return true; - } - - private _onCreateDatabaseSuccess(offerThroughput: number, startKey: number): void { - this.isExecuting(false); - this.close(); - this.container.refreshAllDatabases(); - const addDatabasePaneSuccessMessage = { - database: ko.toJS({ - id: this.databaseId(), - shared: this.databaseCreateNewShared(), - }), - offerThroughput: offerThroughput, - subscriptionType: userContext.subscriptionType, - subscriptionQuotaId: userContext.quotaId, - defaultsCheck: { - flight: userContext.addCollectionFlight, - }, - dataExplorerArea: Constants.Areas.ContextualPane, - }; - TelemetryProcessor.traceSuccess(Action.CreateDatabase, addDatabasePaneSuccessMessage, startKey); - this.resetData(); - } - - private _onCreateDatabaseFailure(error: any, offerThroughput: number, startKey: number): void { - this.isExecuting(false); - const errorMessage = getErrorMessage(error); - this.formErrors(errorMessage); - this.formErrorsDetails(errorMessage); - const addDatabasePaneFailedMessage = { - database: ko.toJS({ - id: this.databaseId(), - shared: this.databaseCreateNewShared(), - }), - offerThroughput: offerThroughput, - subscriptionType: userContext.subscriptionType, - subscriptionQuotaId: userContext.quotaId, - defaultsCheck: { - flight: userContext.addCollectionFlight, - }, - dataExplorerArea: Constants.Areas.ContextualPane, - error: errorMessage, - errorStack: getErrorStack(error), - }; - TelemetryProcessor.traceFailure(Action.CreateDatabase, addDatabasePaneFailedMessage, startKey); - } - - private _getThroughput(): number { - const throughput: number = this.throughput(); - return isNaN(throughput) ? 0 : Number(throughput); - } - - private _computeOfferThroughput(): number { - if (!this.canConfigureThroughput()) { - return undefined; - } - - if (this.isAutoPilotSelected()) { - return undefined; - } - - return this._getThroughput(); - } - - private _isValid(): boolean { - // TODO add feature flag that disables validation for customers with custom accounts - if (this.isAutoPilotSelected()) { - const autoPilot = this._isAutoPilotSelectedAndWhatTier(); - if ( - !autoPilot || - !autoPilot.maxThroughput || - !AutoPilotUtils.isValidAutoPilotThroughput(autoPilot.maxThroughput) - ) { - this.formErrors( - `Please enter a value greater than ${AutoPilotUtils.minAutoPilotThroughput} for autopilot throughput` - ); - return false; - } - } - const throughput = this._getThroughput(); - - if (throughput > SharedConstants.CollectionCreation.DefaultCollectionRUs100K && !this.throughputSpendAck()) { - this.formErrors(`Please acknowledge the estimated daily spend.`); - return false; - } - - const autoscaleThroughput = this.maxAutoPilotThroughputSet() * 1; - - if ( - this.isAutoPilotSelected() && - autoscaleThroughput > SharedConstants.CollectionCreation.DefaultCollectionRUs100K && - !this.throughputSpendAck() - ) { - this.formErrors(`Please acknowledge the estimated monthly spend.`); - return false; - } - - return true; - } - - private _isAutoPilotSelectedAndWhatTier(): DataModels.AutoPilotCreationSettings { - if (this.isAutoPilotSelected() && this.maxAutoPilotThroughputSet()) { - return { - maxThroughput: this.maxAutoPilotThroughputSet() * 1, - }; - } - return undefined; - } - - private _updateThroughputLimitByDatabase() { - const throughputDefaults = this.container.collectionCreationDefaults.throughput; - this.throughput(throughputDefaults.shared); - this.maxThroughputRU(throughputDefaults.unlimitedmax); - this.minThroughputRU(throughputDefaults.unlimitedmin); - } -}