mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2025-10-13 15:28:05 +01:00
Added VNext feature matrix
This commit is contained in:
parent
d385764027
commit
82f50f6b1f
@ -19,6 +19,7 @@ export enum Platform {
|
||||
Hosted = "Hosted",
|
||||
Emulator = "Emulator",
|
||||
Fabric = "Fabric",
|
||||
VNextEmulator = "VNextEmulator",
|
||||
}
|
||||
|
||||
export interface ConfigContext {
|
||||
@ -225,6 +226,7 @@ export async function initializeConfiguration(): Promise<ConfigContext> {
|
||||
case Platform.Fabric:
|
||||
case Platform.Hosted:
|
||||
case Platform.Emulator:
|
||||
case Platform.VNextEmulator:
|
||||
updateConfigContext({ platform });
|
||||
}
|
||||
}
|
||||
|
@ -15,6 +15,7 @@ import { useDatabases } from "Explorer/useDatabases";
|
||||
import { isFabricNative } from "Platform/Fabric/FabricUtil";
|
||||
import { isVectorSearchEnabled } from "Utils/CapabilityUtils";
|
||||
import { isRunningOnPublicCloud } from "Utils/CloudUtils";
|
||||
import { isFeatureSupported, PlatformFeature } from "Utils/PlatformFeatureUtils";
|
||||
import * as React from "react";
|
||||
import DiscardIcon from "../../../../images/discard.svg";
|
||||
import SaveIcon from "../../../../images/save-cosmos.svg";
|
||||
@ -60,15 +61,15 @@ import {
|
||||
AddMongoIndexProps,
|
||||
ChangeFeedPolicyState,
|
||||
GeospatialConfigType,
|
||||
MongoIndexTypes,
|
||||
SettingsV2TabTypes,
|
||||
TtlType,
|
||||
getMongoNotification,
|
||||
getTabTitle,
|
||||
hasDatabaseSharedThroughput,
|
||||
isDirty,
|
||||
MongoIndexTypes,
|
||||
parseConflictResolutionMode,
|
||||
parseConflictResolutionProcedure,
|
||||
SettingsV2TabTypes,
|
||||
TtlType,
|
||||
} from "./SettingsUtils";
|
||||
|
||||
interface SettingsV2TabInfo {
|
||||
@ -276,14 +277,14 @@ export class SettingsComponent extends React.Component<SettingsComponentProps, S
|
||||
this.saveSettingsButton = {
|
||||
isEnabled: this.isSaveSettingsButtonEnabled,
|
||||
isVisible: () => {
|
||||
return true;
|
||||
return isFeatureSupported(PlatformFeature.UpdateCollection);
|
||||
},
|
||||
};
|
||||
|
||||
this.discardSettingsChangesButton = {
|
||||
isEnabled: this.isDiscardSettingsButtonEnabled,
|
||||
isVisible: () => {
|
||||
return true;
|
||||
return isFeatureSupported(PlatformFeature.UpdateCollection);
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -3,7 +3,7 @@ import { Link } from "@fluentui/react/lib/Link";
|
||||
import { isPublicInternetAccessAllowed } from "Common/DatabaseAccountUtility";
|
||||
import { Environment, getEnvironment } from "Common/EnvironmentUtility";
|
||||
import { sendMessage } from "Common/MessageHandler";
|
||||
import { Platform, configContext } from "ConfigContext";
|
||||
import { configContext, Platform } from "ConfigContext";
|
||||
import { MessageTypes } from "Contracts/ExplorerContracts";
|
||||
import { useDataPlaneRbac } from "Explorer/Panes/SettingsPane/SettingsPane";
|
||||
import { getCopilotEnabled, isCopilotFeatureRegistered } from "Explorer/QueryCopilot/Shared/QueryCopilotClient";
|
||||
@ -18,6 +18,7 @@ import { LocalStorageUtility, StorageKey } from "Shared/StorageUtility";
|
||||
import { acquireMsalTokenForAccount } from "Utils/AuthorizationUtils";
|
||||
import { allowedNotebookServerUrls, validateEndpoint } from "Utils/EndpointUtils";
|
||||
import { featureRegistered } from "Utils/FeatureRegistrationUtils";
|
||||
import { isFeatureSupported, PlatformFeature } from "Utils/PlatformFeatureUtils";
|
||||
import { update } from "Utils/arm/generatedClients/cosmos/databaseAccounts";
|
||||
import { useQueryCopilot } from "hooks/useQueryCopilot";
|
||||
import * as ko from "knockout";
|
||||
@ -1187,6 +1188,7 @@ export default class Explorer {
|
||||
|
||||
// TODO: remove reference to isNotebookEnabled and isNotebooksEnabledForAccount
|
||||
const isNotebookEnabled =
|
||||
isFeatureSupported(PlatformFeature.Notebooks) &&
|
||||
configContext.platform !== Platform.Fabric &&
|
||||
(userContext.features.notebooksDownBanner ||
|
||||
useNotebook.getState().isPhoenixNotebooks ||
|
||||
@ -1194,7 +1196,11 @@ export default class Explorer {
|
||||
useNotebook.getState().setIsNotebookEnabled(isNotebookEnabled);
|
||||
useNotebook
|
||||
.getState()
|
||||
.setIsShellEnabled(useNotebook.getState().isPhoenixFeatures && isPublicInternetAccessAllowed());
|
||||
.setIsShellEnabled(
|
||||
isFeatureSupported(PlatformFeature.CloudShell) &&
|
||||
useNotebook.getState().isPhoenixFeatures &&
|
||||
isPublicInternetAccessAllowed(),
|
||||
);
|
||||
|
||||
TelemetryProcessor.trace(Action.NotebookEnabled, ActionModifiers.Mark, {
|
||||
isNotebookEnabled,
|
||||
@ -1215,6 +1221,7 @@ export default class Explorer {
|
||||
|
||||
public async configureCopilot(): Promise<void> {
|
||||
if (
|
||||
!isFeatureSupported(PlatformFeature.Copilot) ||
|
||||
userContext.apiType !== "SQL" ||
|
||||
!userContext.subscriptionId ||
|
||||
![Environment.Development, Environment.Mpac, Environment.Prod].includes(getEnvironment())
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { KeyboardAction } from "KeyboardShortcuts";
|
||||
import { isDataplaneRbacSupported } from "Utils/APITypeUtils";
|
||||
import { areAdvancedScriptsSupported, isFeatureSupported, PlatformFeature } from "Utils/PlatformFeatureUtils";
|
||||
import * as React from "react";
|
||||
import { useEffect, useState } from "react";
|
||||
import AddSqlQueryIcon from "../../../../images/AddSqlQuery_16x16.svg";
|
||||
@ -17,7 +18,7 @@ import SynapseIcon from "../../../../images/synapse-link.svg";
|
||||
import VSCodeIcon from "../../../../images/vscode.svg";
|
||||
import { AuthType } from "../../../AuthType";
|
||||
import * as Constants from "../../../Common/Constants";
|
||||
import { Platform, configContext } from "../../../ConfigContext";
|
||||
import { configContext, Platform } from "../../../ConfigContext";
|
||||
import * as ViewModels from "../../../Contracts/ViewModels";
|
||||
import { userContext } from "../../../UserContext";
|
||||
import { isRunningOnNationalCloud } from "../../../Utils/CloudUtils";
|
||||
@ -63,9 +64,11 @@ export function createStaticCommandBarButtons(
|
||||
}
|
||||
if (userContext.apiType !== "Gremlin") {
|
||||
const addVsCode = createOpenVsCodeDialogButton(container);
|
||||
if (addVsCode) {
|
||||
buttons.push(addVsCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isDataplaneRbacSupported(userContext.apiType)) {
|
||||
const [loginButtonProps, setLoginButtonProps] = useState<CommandButtonComponentProps | undefined>(undefined);
|
||||
@ -242,11 +245,17 @@ export function createDivider(): CommandButtonComponentProps {
|
||||
|
||||
function areScriptsSupported(): boolean {
|
||||
return (
|
||||
configContext.platform !== Platform.Fabric && (userContext.apiType === "SQL" || userContext.apiType === "Gremlin")
|
||||
areAdvancedScriptsSupported() &&
|
||||
configContext.platform !== Platform.Fabric &&
|
||||
(userContext.apiType === "SQL" || userContext.apiType === "Gremlin")
|
||||
);
|
||||
}
|
||||
|
||||
function createOpenSynapseLinkDialogButton(container: Explorer): CommandButtonComponentProps {
|
||||
if (!isFeatureSupported(PlatformFeature.SynapseLink)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (configContext.platform === Platform.Emulator) {
|
||||
return undefined;
|
||||
}
|
||||
@ -274,6 +283,10 @@ function createOpenSynapseLinkDialogButton(container: Explorer): CommandButtonCo
|
||||
}
|
||||
|
||||
function createOpenVsCodeDialogButton(container: Explorer): CommandButtonComponentProps {
|
||||
if (!isFeatureSupported(PlatformFeature.VSCodeIntegration)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const label = "Visual Studio Code";
|
||||
return {
|
||||
iconSrc: VSCodeIcon,
|
||||
|
@ -50,6 +50,7 @@ import * as TelemetryProcessor from "Shared/Telemetry/TelemetryProcessor";
|
||||
import { userContext } from "UserContext";
|
||||
import { getCollectionName } from "Utils/APITypeUtils";
|
||||
import { isCapabilityEnabled, isServerlessAccount, isVectorSearchEnabled } from "Utils/CapabilityUtils";
|
||||
import { isFeatureSupported, PlatformFeature } from "Utils/PlatformFeatureUtils";
|
||||
import { getUpsellMessage } from "Utils/PricingUtils";
|
||||
import { ValidCosmosDbIdDescription, ValidCosmosDbIdInputPattern } from "Utils/ValidationUtils";
|
||||
import * as AutoPilotUtils from "../../../Utils/AutoPilotUtils";
|
||||
@ -1160,11 +1161,15 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
||||
}
|
||||
|
||||
private shouldShowVectorSearchParameters() {
|
||||
return isVectorSearchEnabled() && (isServerlessAccount() || this.shouldShowCollectionThroughputInput());
|
||||
return (
|
||||
isFeatureSupported(PlatformFeature.VectorSearch) &&
|
||||
isVectorSearchEnabled() &&
|
||||
(isServerlessAccount() || this.shouldShowCollectionThroughputInput())
|
||||
);
|
||||
}
|
||||
|
||||
private shouldShowFullTextSearchParameters() {
|
||||
return !isFabricNative() && this.showFullTextSearch;
|
||||
return isFeatureSupported(PlatformFeature.FullTextSearch) && !isFabricNative() && this.showFullTextSearch;
|
||||
}
|
||||
|
||||
private parseUniqueKeys(): DataModels.UniqueKeyPolicy {
|
||||
|
@ -6,6 +6,7 @@ import { getFullTextLanguageOptions } from "Explorer/Controls/FullTextSeach/Full
|
||||
import { isFabricNative } from "Platform/Fabric/FabricUtil";
|
||||
import React from "react";
|
||||
import { userContext } from "UserContext";
|
||||
import { isFeatureSupported, PlatformFeature } from "Utils/PlatformFeatureUtils";
|
||||
|
||||
export function getPartitionKeyTooltipText(): string {
|
||||
if (userContext.apiType === "Mongo") {
|
||||
@ -85,7 +86,11 @@ export function UniqueKeysHeader(): JSX.Element {
|
||||
}
|
||||
|
||||
export function shouldShowAnalyticalStoreOptions(): boolean {
|
||||
if (isFabricNative() || configContext.platform === Platform.Emulator) {
|
||||
if (
|
||||
!isFeatureSupported(PlatformFeature.AnalyticalStore) ||
|
||||
isFabricNative() ||
|
||||
configContext.platform === Platform.Emulator
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
112
src/Utils/PlatformFeatureUtils.ts
Normal file
112
src/Utils/PlatformFeatureUtils.ts
Normal file
@ -0,0 +1,112 @@
|
||||
import { Platform, configContext } from "../ConfigContext";
|
||||
|
||||
/**
|
||||
* Feature flags enumeration - centralized feature definitions
|
||||
*/
|
||||
export enum PlatformFeature {
|
||||
// UI/Core Features
|
||||
Queries = "Queries",
|
||||
Notebooks = "Notebooks",
|
||||
SynapseLink = "SynapseLink",
|
||||
VSCodeIntegration = "VSCodeIntegration",
|
||||
GlobalSecondaryIndex = "GlobalSecondaryIndex",
|
||||
DataPlaneRbac = "DataPlaneRbac",
|
||||
EntraIDLogin = "EntraIDLogin",
|
||||
EntreIDRbac = "EntreIDRbac",
|
||||
RetrySettings = "RetrySettings",
|
||||
GraphAutoVizOption = "GraphAutoVizOption",
|
||||
CrossPartitionOption = "CrossPartitionOption",
|
||||
EnhancedQueryControl = "EnhancedQueryControl",
|
||||
ParallelismOption = "ParallelismOption",
|
||||
EnableEntraIdRbac = "EnableEntraIdRbac",
|
||||
PriorityBasedExecution = "PriorityBasedExecution",
|
||||
RegionSelection = "RegionSelection",
|
||||
Copilot = "Copilot",
|
||||
CloudShell = "CloudShell",
|
||||
ContainerPagination = "ContainerPagination",
|
||||
FullTextSearch = "FullTextSearch",
|
||||
VectorSearch = "VectorSearch",
|
||||
ThroughputBucketing = "ThroughputBucketing",
|
||||
ComputedProperties = "ComputedProperties",
|
||||
AnalyticalStore = "AnalyticalStore",
|
||||
|
||||
// CRUD Operations - Database
|
||||
CreateDatabase = "CreateDatabase",
|
||||
ReadDatabase = "ReadDatabase",
|
||||
DeleteDatabase = "DeleteDatabase",
|
||||
|
||||
// CRUD Operations - Collection
|
||||
CreateCollection = "CreateCollection",
|
||||
ReadCollection = "ReadCollection",
|
||||
UpdateCollection = "UpdateCollection",
|
||||
DeleteCollection = "DeleteCollection",
|
||||
|
||||
// CRUD Operations - Document
|
||||
CreateDocument = "CreateDocument",
|
||||
ReadDocument = "ReadDocument",
|
||||
UpdateDocument = "UpdateDocument",
|
||||
DeleteDocument = "DeleteDocument",
|
||||
|
||||
// Advanced Database Features
|
||||
StoredProcedures = "StoredProcedures",
|
||||
UDF = "UDF",
|
||||
Trigger = "Trigger",
|
||||
}
|
||||
|
||||
/**
|
||||
* Feature matrix per platform.
|
||||
* - Only list platforms that have restrictions. If a platform is not present, all features are considered supported.
|
||||
* - Start with VNextEmulator today; add more platforms/flags here later without touching calling code.
|
||||
*/
|
||||
const FEATURE_MATRIX: ReadonlyMap<Platform, ReadonlySet<PlatformFeature>> = new Map([
|
||||
[
|
||||
Platform.VNextEmulator,
|
||||
new Set<PlatformFeature>([
|
||||
PlatformFeature.Queries,
|
||||
|
||||
PlatformFeature.CreateDatabase,
|
||||
PlatformFeature.ReadDatabase,
|
||||
PlatformFeature.DeleteDatabase,
|
||||
|
||||
PlatformFeature.CreateCollection,
|
||||
PlatformFeature.ReadCollection,
|
||||
PlatformFeature.UpdateCollection,
|
||||
PlatformFeature.DeleteCollection,
|
||||
|
||||
PlatformFeature.CreateDocument,
|
||||
PlatformFeature.ReadDocument,
|
||||
PlatformFeature.UpdateDocument,
|
||||
PlatformFeature.DeleteDocument,
|
||||
]),
|
||||
],
|
||||
]);
|
||||
|
||||
/**
|
||||
* Central feature flag function - checks if a feature is enabled for current platform
|
||||
* @param feature The feature to check
|
||||
* @param platform Optional platform override, defaults to current platform
|
||||
* @returns True if the feature is enabled for the platform, false otherwise
|
||||
*/
|
||||
export const isFeatureSupported = (feature: PlatformFeature, platform?: Platform): boolean => {
|
||||
const currentPlatform = platform ?? configContext.platform;
|
||||
if (currentPlatform !== Platform.VNextEmulator) {
|
||||
return true;
|
||||
}
|
||||
// VNextEmulator: check from the feature matrix
|
||||
const vnextFeatures = FEATURE_MATRIX.get(Platform.VNextEmulator);
|
||||
return vnextFeatures?.has(feature) ?? false;
|
||||
};
|
||||
|
||||
export const areAdvancedScriptsSupported = (platform?: Platform): boolean => {
|
||||
const currentPlatform = platform ?? configContext.platform;
|
||||
if (currentPlatform !== Platform.VNextEmulator) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Otherwise, require all script features to be enabled
|
||||
return (
|
||||
isFeatureSupported(PlatformFeature.StoredProcedures, currentPlatform) &&
|
||||
isFeatureSupported(PlatformFeature.UDF, currentPlatform) &&
|
||||
isFeatureSupported(PlatformFeature.Trigger, currentPlatform)
|
||||
);
|
||||
};
|
@ -86,7 +86,7 @@ export function useKnockoutExplorer(platform: Platform): Explorer {
|
||||
let explorer: Explorer;
|
||||
if (platform === Platform.Hosted) {
|
||||
explorer = await configureHosted();
|
||||
} else if (platform === Platform.Emulator) {
|
||||
} else if (platform === Platform.Emulator || platform === Platform.VNextEmulator) {
|
||||
explorer = configureEmulator();
|
||||
} else if (platform === Platform.Portal) {
|
||||
explorer = await configurePortal();
|
||||
|
@ -121,6 +121,7 @@ app.get("/_ready", (_, res) => {
|
||||
const appConf = {
|
||||
PROXY_PATH: "/proxy",
|
||||
EMULATOR_ENDPOINT: conf.EMULATOR_ENDPOINT,
|
||||
platform: "VNextEmulator",
|
||||
};
|
||||
app.get("/config.json", (_, res) => {
|
||||
res.status(200).json(appConf).end();
|
||||
|
Loading…
x
Reference in New Issue
Block a user