mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2025-12-19 17:01:13 +00:00
Remove Explorer.features (#563)
In addition this makes the URL-passed feature flags type safe
This commit is contained in:
@@ -139,9 +139,7 @@ export class SettingsComponent extends React.Component<SettingsComponentProps, S
|
||||
this.shouldShowIndexingPolicyEditor =
|
||||
this.container && !this.container.isPreferredApiCassandra() && !this.container.isPreferredApiMongoDB();
|
||||
|
||||
this.changeFeedPolicyVisible = this.collection?.container.isFeatureEnabled(
|
||||
Constants.Features.enableChangeFeedPolicy
|
||||
);
|
||||
this.changeFeedPolicyVisible = userContext.features.enableChangeFeedPolicy;
|
||||
|
||||
// Mongo container with system partition key still treat as "Fixed"
|
||||
this.isFixedContainer =
|
||||
|
||||
@@ -12,7 +12,6 @@ import {
|
||||
TextField,
|
||||
} from "office-ui-fabric-react";
|
||||
import React from "react";
|
||||
import { Features } from "../../../../../Common/Constants";
|
||||
import * as DataModels from "../../../../../Contracts/DataModels";
|
||||
import { SubscriptionType } from "../../../../../Contracts/SubscriptionType";
|
||||
import * as SharedConstants from "../../../../../Shared/Constants";
|
||||
@@ -465,7 +464,7 @@ export class ThroughputInputAutoPilotV3Component extends React.Component<
|
||||
const href = `https://ncv.microsoft.com/vRBTO37jmO?ctx={"AzureSubscriptionId":"${userContext.subscriptionId}","CosmosDBAccountName":"${userContext.databaseAccount?.name}"}`;
|
||||
const oneTBinKB = 1000000000;
|
||||
const minRUperGB = 10;
|
||||
const featureFlagEnabled = window.dataExplorer?.isFeatureEnabled(Features.showMinRUSurvey);
|
||||
const featureFlagEnabled = userContext.features.showMinRUSurvey;
|
||||
const collectionIsEligible =
|
||||
userContext.subscriptionType !== SubscriptionType.Internal &&
|
||||
this.props.usageSizeInKB > oneTBinKB &&
|
||||
|
||||
@@ -895,7 +895,6 @@ exports[`SettingsComponent renders 1`] = `
|
||||
"validPartitionKeyValue": [Function],
|
||||
"visible": [Function],
|
||||
},
|
||||
"features": [Function],
|
||||
"flight": [Function],
|
||||
"graphStylingPane": GraphStylingPane {
|
||||
"container": [Circular],
|
||||
@@ -2092,7 +2091,6 @@ exports[`SettingsComponent renders 1`] = `
|
||||
"validPartitionKeyValue": [Function],
|
||||
"visible": [Function],
|
||||
},
|
||||
"features": [Function],
|
||||
"flight": [Function],
|
||||
"graphStylingPane": GraphStylingPane {
|
||||
"container": [Circular],
|
||||
@@ -3302,7 +3300,6 @@ exports[`SettingsComponent renders 1`] = `
|
||||
"validPartitionKeyValue": [Function],
|
||||
"visible": [Function],
|
||||
},
|
||||
"features": [Function],
|
||||
"flight": [Function],
|
||||
"graphStylingPane": GraphStylingPane {
|
||||
"container": [Circular],
|
||||
@@ -4499,7 +4496,6 @@ exports[`SettingsComponent renders 1`] = `
|
||||
"validPartitionKeyValue": [Function],
|
||||
"visible": [Function],
|
||||
},
|
||||
"features": [Function],
|
||||
"flight": [Function],
|
||||
"graphStylingPane": GraphStylingPane {
|
||||
"container": [Circular],
|
||||
|
||||
@@ -329,7 +329,7 @@ export default class Explorer {
|
||||
this.isNotebookEnabled(
|
||||
userContext.authType !== AuthType.ResourceToken &&
|
||||
((await this._containsDefaultNotebookWorkspace(this.databaseAccount())) ||
|
||||
this.isFeatureEnabled(Constants.Features.enableNotebooks))
|
||||
userContext.features.enableNotebooks)
|
||||
);
|
||||
|
||||
TelemetryProcessor.trace(Action.NotebookEnabled, ActionModifiers.Mark, {
|
||||
@@ -351,7 +351,7 @@ export default class Explorer {
|
||||
this.isSparkEnabledForAccount() &&
|
||||
this.arcadiaWorkspaces() &&
|
||||
this.arcadiaWorkspaces().length > 0) ||
|
||||
this.isFeatureEnabled(Constants.Features.enableSpark)
|
||||
userContext.features.enableSpark
|
||||
);
|
||||
if (this.isSparkEnabled()) {
|
||||
appInsights.trackEvent(
|
||||
@@ -375,7 +375,6 @@ export default class Explorer {
|
||||
});
|
||||
this.memoryUsageInfo = ko.observable<DataModels.MemoryUsageInfo>();
|
||||
|
||||
this.features = ko.observable();
|
||||
this.queriesClient = new QueriesClient(this);
|
||||
|
||||
this.resourceTokenDatabaseId = ko.observable<string>();
|
||||
@@ -387,11 +386,9 @@ export default class Explorer {
|
||||
this.isPublishNotebookPaneEnabled = ko.observable<boolean>(false);
|
||||
this.isCopyNotebookPaneEnabled = ko.observable<boolean>(false);
|
||||
|
||||
this.canExceedMaximumValue = ko.computed<boolean>(() =>
|
||||
this.isFeatureEnabled(Constants.Features.canExceedMaximumValue)
|
||||
);
|
||||
this.canExceedMaximumValue = ko.computed<boolean>(() => userContext.features.canExceedMaximumValue);
|
||||
|
||||
this.isSchemaEnabled = ko.computed<boolean>(() => this.isFeatureEnabled(Constants.Features.enableSchema));
|
||||
this.isSchemaEnabled = ko.computed<boolean>(() => userContext.features.enableSchema);
|
||||
|
||||
this.isAutoscaleDefaultEnabled = ko.observable<boolean>(false);
|
||||
|
||||
@@ -471,7 +468,7 @@ export default class Explorer {
|
||||
});
|
||||
|
||||
this.isFixedCollectionWithSharedThroughputSupported = ko.computed(() => {
|
||||
if (this.isFeatureEnabled(Constants.Features.enableFixedCollectionWithSharedThroughput)) {
|
||||
if (userContext.features.enableFixedCollectionWithSharedThroughput) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -530,9 +527,7 @@ export default class Explorer {
|
||||
() =>
|
||||
configContext.platform === Platform.Portal && !this.isRunningOnNationalCloud() && !this.isPreferredApiGraph()
|
||||
);
|
||||
this.isRightPanelV2Enabled = ko.computed<boolean>(() =>
|
||||
this.isFeatureEnabled(Constants.Features.enableRightPanelV2)
|
||||
);
|
||||
this.isRightPanelV2Enabled = ko.computed<boolean>(() => userContext.features.enableRightPanelV2);
|
||||
this.defaultExperience.subscribe((defaultExperience: string) => {
|
||||
if (
|
||||
defaultExperience &&
|
||||
@@ -883,42 +878,29 @@ export default class Explorer {
|
||||
});
|
||||
|
||||
// Override notebook server parameters from URL parameters
|
||||
const featureSubcription = this.features.subscribe((features) => {
|
||||
const serverInfo = this.notebookServerInfo();
|
||||
if (this.isFeatureEnabled(Constants.Features.notebookServerUrl)) {
|
||||
serverInfo.notebookServerEndpoint = features[Constants.Features.notebookServerUrl];
|
||||
}
|
||||
if (userContext.features.notebookServerUrl && userContext.features.notebookServerToken) {
|
||||
this.notebookServerInfo({
|
||||
notebookServerEndpoint: userContext.features.notebookServerUrl,
|
||||
authToken: userContext.features.notebookServerToken,
|
||||
});
|
||||
}
|
||||
|
||||
if (this.isFeatureEnabled(Constants.Features.notebookServerToken)) {
|
||||
serverInfo.authToken = features[Constants.Features.notebookServerToken];
|
||||
}
|
||||
this.notebookServerInfo(serverInfo);
|
||||
this.notebookServerInfo.valueHasMutated();
|
||||
if (userContext.features.notebookBasePath) {
|
||||
this.notebookBasePath(userContext.features.notebookBasePath);
|
||||
}
|
||||
|
||||
if (this.isFeatureEnabled(Constants.Features.notebookBasePath)) {
|
||||
this.notebookBasePath(features[Constants.Features.notebookBasePath]);
|
||||
}
|
||||
|
||||
if (this.isFeatureEnabled(Constants.Features.livyEndpoint)) {
|
||||
this.sparkClusterConnectionInfo({
|
||||
userName: undefined,
|
||||
password: undefined,
|
||||
endpoints: [
|
||||
{
|
||||
endpoint: features[Constants.Features.livyEndpoint],
|
||||
kind: DataModels.SparkClusterEndpointKind.Livy,
|
||||
},
|
||||
],
|
||||
});
|
||||
this.sparkClusterConnectionInfo.valueHasMutated();
|
||||
}
|
||||
|
||||
if (this.isFeatureEnabled(Constants.Features.enableSDKoperations)) {
|
||||
updateUserContext({ useSDKOperations: true });
|
||||
}
|
||||
|
||||
featureSubcription.dispose();
|
||||
});
|
||||
if (userContext.features.livyEndpoint) {
|
||||
this.sparkClusterConnectionInfo({
|
||||
userName: undefined,
|
||||
password: undefined,
|
||||
endpoints: [
|
||||
{
|
||||
endpoint: userContext.features.livyEndpoint,
|
||||
kind: DataModels.SparkClusterEndpointKind.Livy,
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public openEnableSynapseLinkDialog(): void {
|
||||
@@ -1002,20 +984,6 @@ export default class Explorer {
|
||||
return this.selectedNode() == null;
|
||||
}
|
||||
|
||||
public isFeatureEnabled(feature: string): boolean {
|
||||
const features = this.features();
|
||||
|
||||
if (!features) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (feature in features && features[feature]) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public logConsoleData(consoleData: ConsoleData): void {
|
||||
this.setNotificationConsoleData(consoleData);
|
||||
}
|
||||
@@ -1258,12 +1226,12 @@ export default class Explorer {
|
||||
throw error;
|
||||
} finally {
|
||||
// Overwrite with feature flags
|
||||
if (this.isFeatureEnabled(Constants.Features.notebookServerUrl)) {
|
||||
connectionInfo.notebookServerEndpoint = this.features()[Constants.Features.notebookServerUrl];
|
||||
if (userContext.features.notebookServerUrl) {
|
||||
connectionInfo.notebookServerEndpoint = userContext.features.notebookServerUrl;
|
||||
}
|
||||
|
||||
if (this.isFeatureEnabled(Constants.Features.notebookServerToken)) {
|
||||
connectionInfo.authToken = this.features()[Constants.Features.notebookServerToken];
|
||||
if (userContext.features.notebookServerToken) {
|
||||
connectionInfo.authToken = userContext.features.notebookServerToken;
|
||||
}
|
||||
|
||||
this.notebookServerInfo(connectionInfo);
|
||||
@@ -1413,7 +1381,6 @@ export default class Explorer {
|
||||
if (inputs.defaultCollectionThroughput) {
|
||||
this.collectionCreationDefaults = inputs.defaultCollectionThroughput;
|
||||
}
|
||||
this.features(inputs.features);
|
||||
this.databaseAccount(databaseAccount);
|
||||
this.subscriptionType(inputs.subscriptionType ?? SharedConstants.CollectionCreation.DefaultSubscriptionType);
|
||||
this.hasWriteAccess(inputs.hasWriteAccess ?? true);
|
||||
@@ -2367,7 +2334,7 @@ export default class Explorer {
|
||||
public onNewCollectionClicked(): void {
|
||||
if (this.isPreferredApiCassandra()) {
|
||||
this.cassandraAddCollectionPane.open();
|
||||
} else if (this.isFeatureEnabled(Constants.Features.enableReactPane)) {
|
||||
} else if (userContext.features.enableReactPane) {
|
||||
this.openAddCollectionPanel();
|
||||
} else {
|
||||
this.addCollectionPane.open(this.selectedDatabaseId());
|
||||
@@ -2501,7 +2468,7 @@ export default class Explorer {
|
||||
}
|
||||
|
||||
public openDeleteCollectionConfirmationPane(): void {
|
||||
this.isFeatureEnabled(Constants.Features.enableKOPanel)
|
||||
userContext.features.enableKOPanel
|
||||
? this.deleteCollectionConfirmationPane.open()
|
||||
: this.openSidePanel(
|
||||
"Delete Collection",
|
||||
|
||||
@@ -994,7 +994,7 @@ export default class AddCollectionPane extends ContextualPaneBase {
|
||||
this.container.openEnableSynapseLinkDialog();
|
||||
}
|
||||
|
||||
public ttl90DaysEnabled: () => boolean = () => this.container.isFeatureEnabled(Constants.Features.ttl90Days);
|
||||
public ttl90DaysEnabled: () => boolean = () => userContext.features.ttl90Days;
|
||||
|
||||
public isValid(): boolean {
|
||||
// TODO add feature flag that disables validation for customers with custom accounts
|
||||
@@ -1202,7 +1202,7 @@ export default class AddCollectionPane extends ContextualPaneBase {
|
||||
|
||||
if (this.isAnalyticalStorageOn()) {
|
||||
// TODO: always default to 90 days once the backend hotfix is deployed
|
||||
return this.container.isFeatureEnabled(Constants.Features.ttl90Days)
|
||||
return userContext.features.ttl90Days
|
||||
? Constants.AnalyticalStorageTtl.Days90
|
||||
: Constants.AnalyticalStorageTtl.Infinite;
|
||||
}
|
||||
|
||||
@@ -905,7 +905,7 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
||||
|
||||
if (this.state.enableAnalyticalStore) {
|
||||
// TODO: always default to 90 days once the backend hotfix is deployed
|
||||
return this.props.explorer.isFeatureEnabled(Constants.Features.ttl90Days)
|
||||
return userContext.features.ttl90Days
|
||||
? Constants.AnalyticalStorageTtl.Days90
|
||||
: Constants.AnalyticalStorageTtl.Infinite;
|
||||
}
|
||||
|
||||
@@ -882,8 +882,6 @@ export default class DocumentsTab extends TabsBase {
|
||||
buttons.push(DocumentsTab._createUploadButton(this.collection.container));
|
||||
}
|
||||
|
||||
const features = this.collection.container.features() || {};
|
||||
|
||||
return buttons;
|
||||
}
|
||||
|
||||
|
||||
@@ -58,9 +58,7 @@ export default class Database implements ViewModels.Database {
|
||||
});
|
||||
|
||||
const pendingNotificationsPromise: Promise<DataModels.Notification> = this.getPendingThroughputSplitNotification();
|
||||
const useDatabaseSettingsTabV1: boolean = this.container.isFeatureEnabled(
|
||||
Constants.Features.enableDatabaseSettingsTabV1
|
||||
);
|
||||
const useDatabaseSettingsTabV1 = userContext.features.enableDatabaseSettingsTabV1;
|
||||
const tabKind: ViewModels.CollectionTabKind = useDatabaseSettingsTabV1
|
||||
? ViewModels.CollectionTabKind.DatabaseSettings
|
||||
: ViewModels.CollectionTabKind.DatabaseSettingsV2;
|
||||
|
||||
@@ -3,13 +3,14 @@ import * as ko from "knockout";
|
||||
import * as Constants from "../../Common/Constants";
|
||||
import { deleteStoredProcedure } from "../../Common/dataAccess/deleteStoredProcedure";
|
||||
import { executeStoredProcedure } from "../../Common/dataAccess/executeStoredProcedure";
|
||||
import { getErrorMessage } from "../../Common/ErrorHandlingUtils";
|
||||
import * as ViewModels from "../../Contracts/ViewModels";
|
||||
import { Action, ActionModifiers } from "../../Shared/Telemetry/TelemetryConstants";
|
||||
import * as TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
|
||||
import { userContext } from "../../UserContext";
|
||||
import Explorer from "../Explorer";
|
||||
import StoredProcedureTab from "../Tabs/StoredProcedureTab";
|
||||
import TabsBase from "../Tabs/TabsBase";
|
||||
import { getErrorMessage } from "../../Common/ErrorHandlingUtils";
|
||||
|
||||
const sampleStoredProcedureBody: string = `// SAMPLE STORED PROCEDURE
|
||||
function sample(prefix) {
|
||||
@@ -56,7 +57,7 @@ export default class StoredProcedure {
|
||||
this.rid = data._rid;
|
||||
this.id = ko.observable(data.id);
|
||||
this.body = ko.observable(data.body as string);
|
||||
this.isExecuteEnabled = this.container.isFeatureEnabled(Constants.Features.executeSproc);
|
||||
this.isExecuteEnabled = userContext.features.executeSproc;
|
||||
}
|
||||
|
||||
public static create(source: ViewModels.Collection, event: MouseEvent) {
|
||||
|
||||
Reference in New Issue
Block a user