Remove settings component container dependency (#886)

This commit is contained in:
Steve Faulkner 2021-06-10 17:29:41 -07:00 committed by GitHub
parent 0a1a2bf421
commit ce3c2fcfb6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 46 additions and 156 deletions

View File

@ -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<SettingsComponentProps, S
private collection: ViewModels.Collection;
private database: ViewModels.Database;
private offer: DataModels.Offer;
private container: Explorer;
private changeFeedPolicyVisible: boolean;
private isFixedContainer: boolean;
private shouldShowIndexingPolicyEditor: boolean;
@ -134,7 +132,6 @@ export class SettingsComponent extends React.Component<SettingsComponentProps, S
this.isCollectionSettingsTab = this.props.settingsTab.tabKind === ViewModels.CollectionTabKind.CollectionSettingsV2;
if (this.isCollectionSettingsTab) {
this.collection = this.props.settingsTab.collection as ViewModels.Collection;
this.container = this.collection?.container;
this.offer = this.collection?.offer();
this.isAnalyticalStorageEnabled = !!this.collection?.analyticalStorageTtl();
this.shouldShowIndexingPolicyEditor = userContext.apiType !== "Cassandra" && userContext.apiType !== "Mongo";
@ -146,7 +143,6 @@ export class SettingsComponent extends React.Component<SettingsComponentProps, S
userContext.apiType === "Mongo" && (!this.collection?.partitionKey || this.collection?.partitionKey.systemKey);
} else {
this.database = this.props.settingsTab.database;
this.container = this.database?.container;
this.offer = this.database?.offer();
}
@ -294,7 +290,7 @@ export class SettingsComponent extends React.Component<SettingsComponentProps, S
this.state.wasAutopilotOriginallySet !== this.state.isAutoPilotSelected;
public shouldShowKeyspaceSharedThroughputMessage = (): boolean =>
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<SettingsComponentProps, S
const scaleComponentProps: ScaleComponentProps = {
collection: this.collection,
database: this.database,
container: this.container,
isFixedContainer: this.isFixedContainer,
onThroughputChange: this.onThroughputChange,
throughput: this.state.throughput,
@ -912,7 +907,6 @@ export class SettingsComponent extends React.Component<SettingsComponentProps, S
const subSettingsComponentProps: SubSettingsComponentProps = {
collection: this.collection,
container: this.container,
isAnalyticalStorageEnabled: this.isAnalyticalStorageEnabled,
changeFeedPolicyVisible: this.changeFeedPolicyVisible,
timeToLive: this.state.timeToLive,
@ -965,7 +959,6 @@ export class SettingsComponent extends React.Component<SettingsComponentProps, S
const conflictResolutionPolicyComponentProps: ConflictResolutionComponentProps = {
collection: this.collection,
container: this.container,
conflictResolutionPolicyMode: this.state.conflictResolutionPolicyMode,
conflictResolutionPolicyModeBaseline: this.state.conflictResolutionPolicyModeBaseline,
onConflictResolutionPolicyModeChange: this.onConflictResolutionPolicyModeChange,

View File

@ -1,13 +1,12 @@
import { shallow } from "enzyme";
import React from "react";
import { ConflictResolutionComponentProps, ConflictResolutionComponent } from "./ConflictResolutionComponent";
import { container, collection } from "../TestUtils";
import * as DataModels from "../../../../Contracts/DataModels";
import { collection } from "../TestUtils";
import { ConflictResolutionComponent, ConflictResolutionComponentProps } from "./ConflictResolutionComponent";
describe("ConflictResolutionComponent", () => {
const baseProps: ConflictResolutionComponentProps = {
collection: collection,
container: container,
conflictResolutionPolicyMode: DataModels.ConflictResolutionMode.Custom,
conflictResolutionPolicyModeBaseline: DataModels.ConflictResolutionMode.Custom,
onConflictResolutionPolicyModeChange: () => {

View File

@ -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;

View File

@ -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);
});

View File

@ -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<ScaleComponentProps> {
};
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 => {

View File

@ -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: () => {

View File

@ -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;

View File

@ -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}

View File

@ -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<boolean>(
() =>
configContext.platform === Platform.Portal &&
!this.isRunningOnNationalCloud() &&
userContext.apiType !== "Gremlin"
configContext.platform === Platform.Portal && !isRunningOnNationalCloud() && userContext.apiType !== "Gremlin"
);
this.selectedDatabaseId = ko.computed<string>(() => {
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<void> {
// we reload collections for all databases so the resource tree reflects any collection-level changes
// i.e addition of stored procedures, etc.

View File

@ -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);
});

View File

@ -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));
}
}

9
src/Utils/CloudUtils.ts Normal file
View File

@ -0,0 +1,9 @@
import { userContext } from "../UserContext";
export function isRunningOnNationalCloud(): boolean {
return (
userContext.portalEnv === "blackforest" ||
userContext.portalEnv === "fairfax" ||
userContext.portalEnv === "mooncake"
);
}