From ce3c2fcfb6d10a7d3cfd5b815cbfd508d4bffff0 Mon Sep 17 00:00:00 2001 From: Steve Faulkner Date: Thu, 10 Jun 2021 17:29:41 -0700 Subject: [PATCH] Remove settings component container dependency (#886) --- .../Controls/Settings/SettingsComponent.tsx | 9 +- .../ConflictResolutionComponent.test.tsx | 5 +- .../ConflictResolutionComponent.tsx | 14 ++- .../ScaleComponent.test.tsx | 9 +- .../SettingsSubComponents/ScaleComponent.tsx | 9 +- .../SubSettingsComponent.test.tsx | 4 +- .../SubSettingsComponent.tsx | 3 - .../SettingsComponent.test.tsx.snap | 96 ------------------- src/Explorer/Explorer.tsx | 13 +-- .../CommandBarComponentButtonFactory.test.ts | 28 ++++-- .../CommandBarComponentButtonFactory.tsx | 3 +- src/Utils/CloudUtils.ts | 9 ++ 12 files changed, 46 insertions(+), 156 deletions(-) create mode 100644 src/Utils/CloudUtils.ts diff --git a/src/Explorer/Controls/Settings/SettingsComponent.tsx b/src/Explorer/Controls/Settings/SettingsComponent.tsx index f2ba989ff..0094806c6 100644 --- a/src/Explorer/Controls/Settings/SettingsComponent.tsx +++ b/src/Explorer/Controls/Settings/SettingsComponent.tsx @@ -17,7 +17,6 @@ import { userContext } from "../../../UserContext"; import { MongoDBCollectionResource, MongoIndex } from "../../../Utils/arm/generatedClients/cosmos/types"; import * as AutoPilotUtils from "../../../Utils/AutoPilotUtils"; import { CommandButtonComponentProps } from "../../Controls/CommandButton/CommandButtonComponent"; -import Explorer from "../../Explorer"; import { useCommandBar } from "../../Menus/CommandBar/CommandBarComponentAdapter"; import { SettingsTabV2 } from "../../Tabs/SettingsTabV2"; import "./SettingsComponent.less"; @@ -122,7 +121,6 @@ export class SettingsComponent extends React.Component - this.container && userContext.apiType === "Cassandra" && hasDatabaseSharedThroughput(this.collection); + userContext.apiType === "Cassandra" && hasDatabaseSharedThroughput(this.collection); public hasConflictResolution = (): boolean => userContext?.databaseAccount?.properties?.enableMultipleWriteLocations && @@ -884,7 +880,6 @@ export class SettingsComponent extends React.Component { const baseProps: ConflictResolutionComponentProps = { collection: collection, - container: container, conflictResolutionPolicyMode: DataModels.ConflictResolutionMode.Custom, conflictResolutionPolicyModeBaseline: DataModels.ConflictResolutionMode.Custom, onConflictResolutionPolicyModeChange: () => { diff --git a/src/Explorer/Controls/Settings/SettingsSubComponents/ConflictResolutionComponent.tsx b/src/Explorer/Controls/Settings/SettingsSubComponents/ConflictResolutionComponent.tsx index ec23ac0db..c6ca020a5 100644 --- a/src/Explorer/Controls/Settings/SettingsSubComponents/ConflictResolutionComponent.tsx +++ b/src/Explorer/Controls/Settings/SettingsSubComponents/ConflictResolutionComponent.tsx @@ -1,21 +1,19 @@ +import { ChoiceGroup, IChoiceGroupOption, ITextFieldProps, Stack, TextField } from "@fluentui/react"; import * as React from "react"; -import * as ViewModels from "../../../../Contracts/ViewModels"; import * as DataModels from "../../../../Contracts/DataModels"; -import Explorer from "../../../Explorer"; +import * as ViewModels from "../../../../Contracts/ViewModels"; import { - getTextFieldStyles, - conflictResolutionLwwTooltip, conflictResolutionCustomToolTip, - subComponentStackProps, + conflictResolutionLwwTooltip, getChoiceGroupStyles, + getTextFieldStyles, + subComponentStackProps, } from "../SettingsRenderUtils"; -import { TextField, ITextFieldProps, Stack, IChoiceGroupOption, ChoiceGroup } from "@fluentui/react"; -import { ToolTipLabelComponent } from "./ToolTipLabelComponent"; import { isDirty } from "../SettingsUtils"; +import { ToolTipLabelComponent } from "./ToolTipLabelComponent"; export interface ConflictResolutionComponentProps { collection: ViewModels.Collection; - container: Explorer; conflictResolutionPolicyMode: DataModels.ConflictResolutionMode; conflictResolutionPolicyModeBaseline: DataModels.ConflictResolutionMode; onConflictResolutionPolicyModeChange: (newMode: DataModels.ConflictResolutionMode) => void; diff --git a/src/Explorer/Controls/Settings/SettingsSubComponents/ScaleComponent.test.tsx b/src/Explorer/Controls/Settings/SettingsSubComponents/ScaleComponent.test.tsx index 4ba0e0427..eb93add8c 100644 --- a/src/Explorer/Controls/Settings/SettingsSubComponents/ScaleComponent.test.tsx +++ b/src/Explorer/Controls/Settings/SettingsSubComponents/ScaleComponent.test.tsx @@ -7,20 +7,17 @@ import * as SharedConstants from "../../../../Shared/Constants"; import { updateUserContext } from "../../../../UserContext"; import Explorer from "../../../Explorer"; import { throughputUnit } from "../SettingsRenderUtils"; -import { collection, container } from "../TestUtils"; +import { collection } from "../TestUtils"; import { ScaleComponent, ScaleComponentProps } from "./ScaleComponent"; import { ThroughputInputAutoPilotV3Component } from "./ThroughputInputComponents/ThroughputInputAutoPilotV3Component"; describe("ScaleComponent", () => { const nonNationalCloudContainer = new Explorer(); - nonNationalCloudContainer.isRunningOnNationalCloud = () => false; - const targetThroughput = 6000; const baseProps: ScaleComponentProps = { collection: collection, database: undefined, - container: container, isFixedContainer: false, onThroughputChange: () => { return; @@ -111,7 +108,7 @@ describe("ScaleComponent", () => { let scaleComponent = new ScaleComponent(baseProps); expect(scaleComponent.getThroughputTitle()).toEqual("Throughput (6,000 - unlimited RU/s)"); - let newProps = { ...baseProps, container: nonNationalCloudContainer }; + let newProps = { ...baseProps }; scaleComponent = new ScaleComponent(newProps); expect(scaleComponent.getThroughputTitle()).toEqual("Throughput (6,000 - unlimited RU/s)"); @@ -124,7 +121,7 @@ describe("ScaleComponent", () => { let scaleComponent = new ScaleComponent(baseProps); expect(scaleComponent.canThroughputExceedMaximumValue()).toEqual(true); - const newProps = { ...baseProps, container: nonNationalCloudContainer }; + const newProps = { ...baseProps }; scaleComponent = new ScaleComponent(newProps); expect(scaleComponent.canThroughputExceedMaximumValue()).toEqual(true); }); diff --git a/src/Explorer/Controls/Settings/SettingsSubComponents/ScaleComponent.tsx b/src/Explorer/Controls/Settings/SettingsSubComponents/ScaleComponent.tsx index e73469101..98914e33a 100644 --- a/src/Explorer/Controls/Settings/SettingsSubComponents/ScaleComponent.tsx +++ b/src/Explorer/Controls/Settings/SettingsSubComponents/ScaleComponent.tsx @@ -7,7 +7,7 @@ import * as ViewModels from "../../../../Contracts/ViewModels"; import * as SharedConstants from "../../../../Shared/Constants"; import { userContext } from "../../../../UserContext"; import * as AutoPilotUtils from "../../../../Utils/AutoPilotUtils"; -import Explorer from "../../../Explorer"; +import { isRunningOnNationalCloud } from "../../../../Utils/CloudUtils"; import { getTextFieldStyles, getThroughputApplyLongDelayMessage, @@ -23,7 +23,6 @@ import { ThroughputInputAutoPilotV3Component } from "./ThroughputInputComponents export interface ScaleComponentProps { collection: ViewModels.Collection; database: ViewModels.Database; - container: Explorer; isFixedContainer: boolean; onThroughputChange: (newThroughput: number) => void; throughput: number; @@ -109,11 +108,7 @@ export class ScaleComponent extends React.Component { }; public canThroughputExceedMaximumValue = (): boolean => { - return ( - !this.props.isFixedContainer && - configContext.platform === Platform.Portal && - !this.props.container.isRunningOnNationalCloud() - ); + return !this.props.isFixedContainer && configContext.platform === Platform.Portal && !isRunningOnNationalCloud(); }; public getInitialNotificationElement = (): JSX.Element => { diff --git a/src/Explorer/Controls/Settings/SettingsSubComponents/SubSettingsComponent.test.tsx b/src/Explorer/Controls/Settings/SettingsSubComponents/SubSettingsComponent.test.tsx index 2d25f9da7..664bc3968 100644 --- a/src/Explorer/Controls/Settings/SettingsSubComponents/SubSettingsComponent.test.tsx +++ b/src/Explorer/Controls/Settings/SettingsSubComponents/SubSettingsComponent.test.tsx @@ -4,14 +4,12 @@ import { DatabaseAccount } from "../../../../Contracts/DataModels"; import { updateUserContext } from "../../../../UserContext"; import Explorer from "../../../Explorer"; import { ChangeFeedPolicyState, GeospatialConfigType, TtlOff, TtlOn, TtlOnNoDefault, TtlType } from "../SettingsUtils"; -import { collection, container } from "../TestUtils"; +import { collection } from "../TestUtils"; import { SubSettingsComponent, SubSettingsComponentProps } from "./SubSettingsComponent"; describe("SubSettingsComponent", () => { const baseProps: SubSettingsComponentProps = { collection: collection, - container: container, - timeToLive: TtlType.On, timeToLiveBaseline: TtlType.On, onTtlChange: () => { diff --git a/src/Explorer/Controls/Settings/SettingsSubComponents/SubSettingsComponent.tsx b/src/Explorer/Controls/Settings/SettingsSubComponents/SubSettingsComponent.tsx index 0338cc667..84913b022 100644 --- a/src/Explorer/Controls/Settings/SettingsSubComponents/SubSettingsComponent.tsx +++ b/src/Explorer/Controls/Settings/SettingsSubComponents/SubSettingsComponent.tsx @@ -2,7 +2,6 @@ import { ChoiceGroup, IChoiceGroupOption, Label, Link, MessageBar, Stack, Text, import * as React from "react"; import * as ViewModels from "../../../../Contracts/ViewModels"; import { userContext } from "../../../../UserContext"; -import Explorer from "../../../Explorer"; import { Int32 } from "../../../Panes/Tables/Validators/EntityPropertyValidationCommon"; import { changeFeedPolicyToolTip, @@ -28,8 +27,6 @@ import { ToolTipLabelComponent } from "./ToolTipLabelComponent"; export interface SubSettingsComponentProps { collection: ViewModels.Collection; - container: Explorer; - timeToLive: TtlType; timeToLiveBaseline: TtlType; diff --git a/src/Explorer/Controls/Settings/__snapshots__/SettingsComponent.test.tsx.snap b/src/Explorer/Controls/Settings/__snapshots__/SettingsComponent.test.tsx.snap index 7351b3d91..8e49f2ccf 100644 --- a/src/Explorer/Controls/Settings/__snapshots__/SettingsComponent.test.tsx.snap +++ b/src/Explorer/Controls/Settings/__snapshots__/SettingsComponent.test.tsx.snap @@ -91,54 +91,6 @@ exports[`SettingsComponent renders 1`] = ` "usageSizeInKB": [Function], } } - container={ - Explorer { - "_isInitializingNotebooks": false, - "_resetNotebookWorkspace": [Function], - "canSaveQueries": [Function], - "databases": [Function], - "isAccountReady": [Function], - "isFixedCollectionWithSharedThroughputSupported": [Function], - "isHostedDataExplorerEnabled": [Function], - "isNotebookEnabled": [Function], - "isNotebooksEnabledForAccount": [Function], - "isResourceTokenCollectionNodeSelected": [Function], - "isSchemaEnabled": [Function], - "isShellEnabled": [Function], - "isSynapseLinkUpdating": [Function], - "isTabsContentExpanded": [Function], - "memoryUsageInfo": [Function], - "notebookBasePath": [Function], - "notebookServerInfo": [Function], - "onRefreshDatabasesKeyPress": [Function], - "onRefreshResourcesClick": [Function], - "provideFeedbackEmail": [Function], - "queriesClient": QueriesClient { - "container": [Circular], - }, - "refreshNotebookList": [Function], - "resourceTokenCollection": [Function], - "resourceTree": ResourceTreeAdapter { - "container": [Circular], - "copyNotebook": [Function], - "databaseCollectionIdMap": Map {}, - "koSubsCollectionIdMap": Map {}, - "koSubsDatabaseIdMap": Map {}, - "parameters": [Function], - }, - "resourceTreeForResourceToken": ResourceTreeAdapterForResourceToken { - "container": [Circular], - "parameters": [Function], - }, - "selectedDatabaseId": [Function], - "selectedNode": [Function], - "sparkClusterConnectionInfo": [Function], - "tabsManager": TabsManager { - "activeTab": [Function], - "openedTabs": [Function], - }, - } - } isAutoPilotSelected={false} isFixedContainer={false} onAutoPilotSelected={[Function]} @@ -234,54 +186,6 @@ exports[`SettingsComponent renders 1`] = ` "usageSizeInKB": [Function], } } - container={ - Explorer { - "_isInitializingNotebooks": false, - "_resetNotebookWorkspace": [Function], - "canSaveQueries": [Function], - "databases": [Function], - "isAccountReady": [Function], - "isFixedCollectionWithSharedThroughputSupported": [Function], - "isHostedDataExplorerEnabled": [Function], - "isNotebookEnabled": [Function], - "isNotebooksEnabledForAccount": [Function], - "isResourceTokenCollectionNodeSelected": [Function], - "isSchemaEnabled": [Function], - "isShellEnabled": [Function], - "isSynapseLinkUpdating": [Function], - "isTabsContentExpanded": [Function], - "memoryUsageInfo": [Function], - "notebookBasePath": [Function], - "notebookServerInfo": [Function], - "onRefreshDatabasesKeyPress": [Function], - "onRefreshResourcesClick": [Function], - "provideFeedbackEmail": [Function], - "queriesClient": QueriesClient { - "container": [Circular], - }, - "refreshNotebookList": [Function], - "resourceTokenCollection": [Function], - "resourceTree": ResourceTreeAdapter { - "container": [Circular], - "copyNotebook": [Function], - "databaseCollectionIdMap": Map {}, - "koSubsCollectionIdMap": Map {}, - "koSubsDatabaseIdMap": Map {}, - "parameters": [Function], - }, - "resourceTreeForResourceToken": ResourceTreeAdapterForResourceToken { - "container": [Circular], - "parameters": [Function], - }, - "selectedDatabaseId": [Function], - "selectedNode": [Function], - "sparkClusterConnectionInfo": [Function], - "tabsManager": TabsManager { - "activeTab": [Function], - "openedTabs": [Function], - }, - } - } geospatialConfigType="Geometry" geospatialConfigTypeBaseline="Geometry" isAnalyticalStorageEnabled={false} diff --git a/src/Explorer/Explorer.tsx b/src/Explorer/Explorer.tsx index 34709806d..d0b1e7f4e 100644 --- a/src/Explorer/Explorer.tsx +++ b/src/Explorer/Explorer.tsx @@ -34,6 +34,7 @@ import { import { getAuthorizationHeader } from "../Utils/AuthorizationUtils"; import { stringToBlob } from "../Utils/BlobUtils"; import { isCapabilityEnabled } from "../Utils/CapabilityUtils"; +import { isRunningOnNationalCloud } from "../Utils/CloudUtils"; import { fromContentUri, toRawContentUri } from "../Utils/GitHubUtils"; import * as NotificationConsoleUtils from "../Utils/NotificationConsoleUtils"; import { logConsoleError, logConsoleInfo, logConsoleProgress } from "../Utils/NotificationConsoleUtils"; @@ -224,9 +225,7 @@ export default class Explorer { this.isHostedDataExplorerEnabled = ko.computed( () => - configContext.platform === Platform.Portal && - !this.isRunningOnNationalCloud() && - userContext.apiType !== "Gremlin" + configContext.platform === Platform.Portal && !isRunningOnNationalCloud() && userContext.apiType !== "Gremlin" ); this.selectedDatabaseId = ko.computed(() => { const selectedNode = this.selectedNode(); @@ -700,14 +699,6 @@ export default class Explorer { : this.selectedNode().collection) as ViewModels.Collection; } - public isRunningOnNationalCloud(): boolean { - return ( - userContext.portalEnv === "blackforest" || - userContext.portalEnv === "fairfax" || - userContext.portalEnv === "mooncake" - ); - } - private refreshAndExpandNewDatabases(newDatabases: ViewModels.Database[]): Q.Promise { // we reload collections for all databases so the resource tree reflects any collection-level changes // i.e addition of stored procedures, etc. diff --git a/src/Explorer/Menus/CommandBar/CommandBarComponentButtonFactory.test.ts b/src/Explorer/Menus/CommandBar/CommandBarComponentButtonFactory.test.ts index 824aebdb8..b0e2feeec 100644 --- a/src/Explorer/Menus/CommandBar/CommandBarComponentButtonFactory.test.ts +++ b/src/Explorer/Menus/CommandBar/CommandBarComponentButtonFactory.test.ts @@ -27,7 +27,6 @@ describe("CommandBarComponentButtonFactory tests", () => { mockExplorer.isDatabaseNodeOrNoneSelected = () => true; mockExplorer.isNotebookEnabled = ko.observable(false); mockExplorer.isNotebooksEnabledForAccount = ko.observable(false); - mockExplorer.isRunningOnNationalCloud = () => false; }); it("Account is not serverless - button should be visible", () => { @@ -60,6 +59,7 @@ describe("CommandBarComponentButtonFactory tests", () => { beforeAll(() => { mockExplorer = {} as Explorer; updateUserContext({ + portalEnv: "prod", databaseAccount: { properties: { capabilities: [{ name: "EnableTable" }], @@ -72,10 +72,15 @@ describe("CommandBarComponentButtonFactory tests", () => { mockExplorer.isDatabaseNodeOrNoneSelected = () => true; }); + afterEach(() => { + updateUserContext({ + portalEnv: "prod", + }); + }); + it("Notebooks is already enabled - button should be hidden", () => { mockExplorer.isNotebookEnabled = ko.observable(true); mockExplorer.isNotebooksEnabledForAccount = ko.observable(true); - mockExplorer.isRunningOnNationalCloud = ko.observable(false); const buttons = CommandBarComponentButtonFactory.createStaticCommandBarButtons(mockExplorer); const enableNotebookBtn = buttons.find((button) => button.commandButtonLabel === enableNotebookBtnLabel); @@ -85,7 +90,9 @@ describe("CommandBarComponentButtonFactory tests", () => { it("Account is running on one of the national clouds - button should be hidden", () => { mockExplorer.isNotebookEnabled = ko.observable(false); mockExplorer.isNotebooksEnabledForAccount = ko.observable(false); - mockExplorer.isRunningOnNationalCloud = ko.observable(true); + updateUserContext({ + portalEnv: "mooncake", + }); const buttons = CommandBarComponentButtonFactory.createStaticCommandBarButtons(mockExplorer); const enableNotebookBtn = buttons.find((button) => button.commandButtonLabel === enableNotebookBtnLabel); @@ -95,7 +102,6 @@ describe("CommandBarComponentButtonFactory tests", () => { it("Notebooks is not enabled but is available - button should be shown and enabled", () => { mockExplorer.isNotebookEnabled = ko.observable(false); mockExplorer.isNotebooksEnabledForAccount = ko.observable(true); - mockExplorer.isRunningOnNationalCloud = ko.observable(false); const buttons = CommandBarComponentButtonFactory.createStaticCommandBarButtons(mockExplorer); const enableNotebookBtn = buttons.find((button) => button.commandButtonLabel === enableNotebookBtnLabel); @@ -107,7 +113,6 @@ describe("CommandBarComponentButtonFactory tests", () => { it("Notebooks is not enabled and is unavailable - button should be shown and disabled", () => { mockExplorer.isNotebookEnabled = ko.observable(false); mockExplorer.isNotebooksEnabledForAccount = ko.observable(false); - mockExplorer.isRunningOnNationalCloud = ko.observable(false); const buttons = CommandBarComponentButtonFactory.createStaticCommandBarButtons(mockExplorer); const enableNotebookBtn = buttons.find((button) => button.commandButtonLabel === enableNotebookBtnLabel); @@ -150,7 +155,7 @@ describe("CommandBarComponentButtonFactory tests", () => { }); mockExplorer.isNotebookEnabled = ko.observable(false); mockExplorer.isNotebooksEnabledForAccount = ko.observable(false); - mockExplorer.isRunningOnNationalCloud = ko.observable(false); + mockExplorer.isShellEnabled = ko.observable(true); }); @@ -164,7 +169,9 @@ describe("CommandBarComponentButtonFactory tests", () => { }); it("Running on a national cloud - button should be hidden", () => { - mockExplorer.isRunningOnNationalCloud = ko.observable(true); + updateUserContext({ + portalEnv: "mooncake", + }); const buttons = CommandBarComponentButtonFactory.createStaticCommandBarButtons(mockExplorer); const openMongoShellBtn = buttons.find((button) => button.commandButtonLabel === openMongoShellBtnLabel); @@ -244,7 +251,6 @@ describe("CommandBarComponentButtonFactory tests", () => { }); mockExplorer.isNotebookEnabled = ko.observable(false); mockExplorer.isNotebooksEnabledForAccount = ko.observable(false); - mockExplorer.isRunningOnNationalCloud = ko.observable(false); }); it("Cassandra Api not available - button should be hidden", () => { @@ -262,7 +268,9 @@ describe("CommandBarComponentButtonFactory tests", () => { }); it("Running on a national cloud - button should be hidden", () => { - mockExplorer.isRunningOnNationalCloud = ko.observable(true); + updateUserContext({ + portalEnv: "mooncake", + }); const buttons = CommandBarComponentButtonFactory.createStaticCommandBarButtons(mockExplorer); const openCassandraShellBtn = buttons.find((button) => button.commandButtonLabel === openCassandraShellBtnLabel); @@ -322,7 +330,7 @@ describe("CommandBarComponentButtonFactory tests", () => { mockExplorer.isSynapseLinkUpdating = ko.observable(false); mockExplorer.isDatabaseNodeOrNoneSelected = () => true; mockExplorer.isNotebooksEnabledForAccount = ko.observable(false); - mockExplorer.isRunningOnNationalCloud = ko.observable(false); + mockExplorer.notebookManager = new NotebookManager(); mockExplorer.notebookManager.gitHubOAuthService = new GitHubOAuthService(undefined); }); diff --git a/src/Explorer/Menus/CommandBar/CommandBarComponentButtonFactory.tsx b/src/Explorer/Menus/CommandBar/CommandBarComponentButtonFactory.tsx index 1ee629b49..6ff55ef28 100644 --- a/src/Explorer/Menus/CommandBar/CommandBarComponentButtonFactory.tsx +++ b/src/Explorer/Menus/CommandBar/CommandBarComponentButtonFactory.tsx @@ -25,6 +25,7 @@ import { useSidePanel } from "../../../hooks/useSidePanel"; import { userContext } from "../../../UserContext"; import { getCollectionName, getDatabaseName } from "../../../Utils/APITypeUtils"; import { isServerlessAccount } from "../../../Utils/CapabilityUtils"; +import { isRunningOnNationalCloud } from "../../../Utils/CloudUtils"; import { CommandButtonComponentProps } from "../../Controls/CommandButton/CommandButtonComponent"; import Explorer from "../../Explorer"; import { OpenFullScreen } from "../../OpenFullScreen"; @@ -81,7 +82,7 @@ export function createStaticCommandBarButtons(container: Explorer): CommandButto } } } else { - if (!container.isRunningOnNationalCloud()) { + if (!isRunningOnNationalCloud()) { buttons.push(createEnableNotebooksButton(container)); } } diff --git a/src/Utils/CloudUtils.ts b/src/Utils/CloudUtils.ts new file mode 100644 index 000000000..089bbf0b6 --- /dev/null +++ b/src/Utils/CloudUtils.ts @@ -0,0 +1,9 @@ +import { userContext } from "../UserContext"; + +export function isRunningOnNationalCloud(): boolean { + return ( + userContext.portalEnv === "blackforest" || + userContext.portalEnv === "fairfax" || + userContext.portalEnv === "mooncake" + ); +}