diff --git a/src/Common/CosmosClient.ts b/src/Common/CosmosClient.ts index 841b41b1a..cf34b2279 100644 --- a/src/Common/CosmosClient.ts +++ b/src/Common/CosmosClient.ts @@ -2,7 +2,7 @@ import * as Cosmos from "@azure/cosmos"; import { getAuthorizationTokenUsingResourceTokens } from "Common/getAuthorizationTokenUsingResourceTokens"; import { CosmosDbArtifactType } from "Contracts/FabricMessagesContract"; import { AuthorizationToken } from "Contracts/FabricMessageTypes"; -import { checkDatabaseResourceTokensValidity, isFabricMirrored } from "Platform/Fabric/FabricUtil"; +import { checkDatabaseResourceTokensValidity, isFabricMirroredKey } from "Platform/Fabric/FabricUtil"; import { LocalStorageUtility, StorageKey } from "Shared/StorageUtility"; import { AuthType } from "../AuthType"; import { PriorityLevel } from "../Common/Constants"; @@ -43,7 +43,7 @@ export const tokenProvider = async (requestInfo: Cosmos.RequestInfo) => { return decodeURIComponent(headers.authorization); } - if (isFabricMirrored()) { + if (isFabricMirroredKey()) { switch (requestInfo.resourceType) { case Cosmos.ResourceType.conflicts: case Cosmos.ResourceType.container: diff --git a/src/Common/StyleConstants.ts b/src/Common/StyleConstants.ts index 81742d8ce..ca1205339 100644 --- a/src/Common/StyleConstants.ts +++ b/src/Common/StyleConstants.ts @@ -1,10 +1,10 @@ -import { Platform, configContext } from "../ConfigContext"; +import { isFabric } from "Platform/Fabric/FabricUtil"; // eslint-disable-next-line @typescript-eslint/no-var-requires export const StyleConstants = require("less-vars-loader!../../less/Common/Constants.less"); export function updateStyles(): void { - if (configContext.platform === Platform.Fabric) { + if (isFabric()) { StyleConstants.AccentMediumHigh = StyleConstants.FabricAccentMediumHigh; StyleConstants.AccentMedium = StyleConstants.FabricAccentMedium; StyleConstants.AccentLight = StyleConstants.FabricAccentLight; diff --git a/src/Common/dataAccess/readCollections.ts b/src/Common/dataAccess/readCollections.ts index bcf3f5c72..ecb67c876 100644 --- a/src/Common/dataAccess/readCollections.ts +++ b/src/Common/dataAccess/readCollections.ts @@ -1,7 +1,7 @@ import { ContainerResponse } from "@azure/cosmos"; import { Queries } from "Common/Constants"; import { CosmosDbArtifactType } from "Contracts/FabricMessagesContract"; -import { isFabricMirrored } from "Platform/Fabric/FabricUtil"; +import { isFabric, isFabricMirroredKey } from "Platform/Fabric/FabricUtil"; import { AuthType } from "../../AuthType"; import * as DataModels from "../../Contracts/DataModels"; import { FabricArtifactInfo, userContext } from "../../UserContext"; @@ -17,7 +17,7 @@ import { handleError } from "../ErrorHandlingUtils"; export async function readCollections(databaseId: string): Promise { const clearMessage = logConsoleProgress(`Querying containers for database ${databaseId}`); - if (isFabricMirrored() && userContext.fabricContext?.databaseName === databaseId) { + if (isFabricMirroredKey() && userContext.fabricContext?.databaseName === databaseId) { const collections: DataModels.Collection[] = []; const promises: Promise[] = []; @@ -55,7 +55,8 @@ export async function readCollections(databaseId: string): Promise => { - if (isFabricMirrored()) { + if (isFabricMirroredKey()) { // TODO This works, but is very slow, because it requests the token, so we skip for now console.error("Skiping readDatabaseOffer for Fabric"); return undefined; @@ -23,7 +23,8 @@ export const readDatabaseOffer = async (params: ReadDatabaseOfferParams): Promis if ( userContext.authType === AuthType.AAD && !userContext.features.enableSDKoperations && - userContext.apiType !== "Tables" + userContext.apiType !== "Tables" && + !isFabric() ) { return await readDatabaseOfferWithARM(params.databaseId); } diff --git a/src/Common/dataAccess/readDatabases.ts b/src/Common/dataAccess/readDatabases.ts index d3417b728..66ea1e76f 100644 --- a/src/Common/dataAccess/readDatabases.ts +++ b/src/Common/dataAccess/readDatabases.ts @@ -1,5 +1,5 @@ import { CosmosDbArtifactType } from "Contracts/FabricMessagesContract"; -import { isFabricMirrored, isFabricNative } from "Platform/Fabric/FabricUtil"; +import { isFabric, isFabricMirroredKey, isFabricNative } from "Platform/Fabric/FabricUtil"; import { AuthType } from "../../AuthType"; import * as DataModels from "../../Contracts/DataModels"; import { FabricArtifactInfo, userContext } from "../../UserContext"; @@ -16,7 +16,7 @@ export async function readDatabases(): Promise { const clearMessage = logConsoleProgress(`Querying databases`); if ( - isFabricMirrored() && + isFabricMirroredKey() && (userContext.fabricContext?.artifactInfo as FabricArtifactInfo[CosmosDbArtifactType.MIRRORED_KEY]).resourceTokenInfo .resourceTokens ) { @@ -72,7 +72,8 @@ export async function readDatabases(): Promise { if ( userContext.authType === AuthType.AAD && !userContext.features.enableSDKoperations && - userContext.apiType !== "Tables" + userContext.apiType !== "Tables" && + !isFabric() ) { databases = await readDatabasesWithARM(); } else { diff --git a/src/Explorer/ContextMenuButtonFactory.tsx b/src/Explorer/ContextMenuButtonFactory.tsx index 71025ba4c..890e2f86f 100644 --- a/src/Explorer/ContextMenuButtonFactory.tsx +++ b/src/Explorer/ContextMenuButtonFactory.tsx @@ -1,7 +1,7 @@ import { configContext, Platform } from "ConfigContext"; import { TreeNodeMenuItem } from "Explorer/Controls/TreeComponent/TreeNodeComponent"; import { useDatabases } from "Explorer/useDatabases"; -import { isFabricMirrored, isFabricNative } from "Platform/Fabric/FabricUtil"; +import { isFabric, isFabricNative } from "Platform/Fabric/FabricUtil"; import { Action } from "Shared/Telemetry/TelemetryConstants"; import { traceOpen } from "Shared/Telemetry/TelemetryProcessor"; import { ReactTabKind, useTabs } from "hooks/useTabs"; @@ -42,7 +42,7 @@ export interface DatabaseContextMenuButtonParams { * New resource tree (in ReactJS) */ export const createDatabaseContextMenu = (container: Explorer, databaseId: string): TreeNodeMenuItem[] => { - if (isFabricMirrored() && userContext.fabricContext?.isReadOnly) { + if (isFabric() && userContext.fabricContext?.isReadOnly) { return undefined; } diff --git a/src/Explorer/Explorer.tsx b/src/Explorer/Explorer.tsx index 15efabb5a..2632e6822 100644 --- a/src/Explorer/Explorer.tsx +++ b/src/Explorer/Explorer.tsx @@ -8,7 +8,11 @@ import { MessageTypes } from "Contracts/ExplorerContracts"; import { useDataPlaneRbac } from "Explorer/Panes/SettingsPane/SettingsPane"; import { getCopilotEnabled, isCopilotFeatureRegistered } from "Explorer/QueryCopilot/Shared/QueryCopilotClient"; import { IGalleryItem } from "Juno/JunoClient"; -import { isFabricMirrored, scheduleRefreshDatabaseResourceToken } from "Platform/Fabric/FabricUtil"; +import { + isFabricMirrored, + isFabricMirroredKey, + scheduleRefreshDatabaseResourceToken, +} from "Platform/Fabric/FabricUtil"; import { LocalStorageUtility, StorageKey } from "Shared/StorageUtility"; import { acquireMsalTokenForAccount } from "Utils/AuthorizationUtils"; import { allowedNotebookServerUrls, validateEndpoint } from "Utils/EndpointUtils"; @@ -351,7 +355,7 @@ export default class Explorer { }; public onRefreshResourcesClick = async (): Promise => { - if (isFabricMirrored()) { + if (isFabricMirroredKey()) { scheduleRefreshDatabaseResourceToken(true).then(() => this.refreshAllDatabases()); return; } diff --git a/src/Explorer/Menus/CommandBar/CommandBarComponentAdapter.tsx b/src/Explorer/Menus/CommandBar/CommandBarComponentAdapter.tsx index 9a5f222a3..eb596c0f7 100644 --- a/src/Explorer/Menus/CommandBar/CommandBarComponentAdapter.tsx +++ b/src/Explorer/Menus/CommandBar/CommandBarComponentAdapter.tsx @@ -6,12 +6,12 @@ import { CommandBar as FluentCommandBar, ICommandBarItemProps } from "@fluentui/react"; import { useNotebook } from "Explorer/Notebook/useNotebook"; import { KeyboardActionGroup, useKeyboardActionGroup } from "KeyboardShortcuts"; +import { isFabric } from "Platform/Fabric/FabricUtil"; import { userContext } from "UserContext"; import * as React from "react"; import create, { UseStore } from "zustand"; import { ConnectionStatusType, PoolIdType } from "../../../Common/Constants"; import { StyleConstants } from "../../../Common/StyleConstants"; -import { Platform, configContext } from "../../../ConfigContext"; import { CommandButtonComponentProps } from "../../Controls/CommandButton/CommandButtonComponent"; import Explorer from "../../Explorer"; import { useSelectedNode } from "../../useSelectedNode"; @@ -93,19 +93,18 @@ export const CommandBar: React.FC = ({ container }: Props) => { ); } - const rootStyle = - configContext.platform === Platform.Fabric - ? { - root: { - backgroundColor: "transparent", - padding: "2px 8px 0px 8px", - }, - } - : { - root: { - backgroundColor: backgroundColor, - }, - }; + const rootStyle = isFabric() + ? { + root: { + backgroundColor: "transparent", + padding: "2px 8px 0px 8px", + }, + } + : { + root: { + backgroundColor: backgroundColor, + }, + }; const allButtons = staticButtons.concat(contextButtons).concat(controlButtons); const keyboardHandlers = CommandBarUtil.createKeyboardHandlers(allButtons); diff --git a/src/Explorer/Sidebar.tsx b/src/Explorer/Sidebar.tsx index 18b0b7604..01fd8a6d1 100644 --- a/src/Explorer/Sidebar.tsx +++ b/src/Explorer/Sidebar.tsx @@ -21,7 +21,7 @@ import { CosmosFluentProvider, cosmosShorthands, tokens } from "Explorer/Theme/T import { ResourceTree } from "Explorer/Tree/ResourceTree"; import { useDatabases } from "Explorer/useDatabases"; import { KeyboardAction, KeyboardActionGroup, KeyboardActionHandler, useKeyboardActionGroup } from "KeyboardShortcuts"; -import { isFabricMirrored, isFabricNative } from "Platform/Fabric/FabricUtil"; +import { isFabric, isFabricMirrored, isFabricNative } from "Platform/Fabric/FabricUtil"; import { userContext } from "UserContext"; import { getCollectionName, getDatabaseName } from "Utils/APITypeUtils"; import { Allotment, AllotmentHandle } from "allotment"; @@ -123,7 +123,11 @@ const GlobalCommands: React.FC = ({ explorer }) => { const primaryFocusableRef = useRef(null); const actions = useMemo(() => { - if (isFabricMirrored() || userContext.apiType === "Postgres" || userContext.apiType === "VCoreMongo") { + if ( + (isFabric() && userContext.fabricContext?.isReadOnly) || + userContext.apiType === "Postgres" || + userContext.apiType === "VCoreMongo" + ) { // No Global Commands for these API types. // In fact, no sidebar for Postgres or VCoreMongo at all, but just in case, we check here anyway. return []; diff --git a/src/Explorer/Tabs/DocumentsTabV2/DocumentsTabV2.tsx b/src/Explorer/Tabs/DocumentsTabV2/DocumentsTabV2.tsx index 2cef0f663..4e7a79909 100644 --- a/src/Explorer/Tabs/DocumentsTabV2/DocumentsTabV2.tsx +++ b/src/Explorer/Tabs/DocumentsTabV2/DocumentsTabV2.tsx @@ -20,7 +20,6 @@ import { import { queryDocuments } from "Common/dataAccess/queryDocuments"; import { readDocument } from "Common/dataAccess/readDocument"; import { updateDocument } from "Common/dataAccess/updateDocument"; -import { Platform, configContext } from "ConfigContext"; import { ActionType, OpenCollectionTab, TabKind } from "Contracts/ActionContracts"; import { CommandButtonComponentProps } from "Explorer/Controls/CommandButton/CommandButtonComponent"; import { useDialog } from "Explorer/Controls/Dialog"; @@ -43,6 +42,7 @@ import { usePrevious } from "Explorer/Tabs/DocumentsTabV2/SelectionHelper"; import { CosmosFluentProvider, LayoutConstants, cosmosShorthands, tokens } from "Explorer/Theme/ThemeUtil"; import { useSelectedNode } from "Explorer/useSelectedNode"; import { KeyboardAction, KeyboardActionGroup, useKeyboardActionGroup } from "KeyboardShortcuts"; +import { isFabric } from "Platform/Fabric/FabricUtil"; import { QueryConstants } from "Shared/Constants"; import { LocalStorageUtility, StorageKey } from "Shared/StorageUtility"; import { Action } from "Shared/Telemetry/TelemetryConstants"; @@ -344,7 +344,7 @@ export const getTabsButtons = ({ onRevertExistingDocumentClick, onDeleteExistingDocumentsClick, }: ButtonsDependencies): CommandButtonComponentProps[] => { - if (configContext.platform === Platform.Fabric && userContext.fabricContext?.isReadOnly) { + if (isFabric() && userContext.fabricContext?.isReadOnly) { // All the following buttons require write access return []; } @@ -2136,8 +2136,7 @@ export const DocumentsTabComponent: React.FunctionComponent => { if (lastRequestTimestamp !== undefined && lastRequestTimestamp + DEBOUNCE_DELAY_MS > Date.now()) { return; } + if (!userContext.fabricContext || !userContext.databaseAccount) { + return; + } + lastRequestTimestamp = Date.now(); try { const resourceTokenInfo = await sendCachedDataMessage( FabricMessageTypes.GetAllResourceTokens, [], - userContext.fabricContext.artifactInfo.connectionId, + userContext.fabricContext.artifactInfo?.connectionId, ); if (!userContext.databaseAccount.properties.documentEndpoint) { @@ -34,7 +38,7 @@ const requestDatabaseResourceTokens = async (): Promise => { ...userContext.fabricContext, databaseName: resourceTokenInfo.databaseId, artifactInfo: { - ...userContext.fabricContext.artifactInfo, + ...(userContext.fabricContext.artifactInfo as FabricArtifactInfo[CosmosDbArtifactType.MIRRORED_KEY]), resourceTokenInfo, }, isReadOnly: resourceTokenInfo.isReadOnly ?? userContext.fabricContext.isReadOnly, @@ -43,7 +47,7 @@ const requestDatabaseResourceTokens = async (): Promise => { }); scheduleRefreshDatabaseResourceToken(); } catch (error) { - logConsoleError(error); + logConsoleError(error as string); throw error; } finally { lastRequestTimestamp = undefined; @@ -77,10 +81,11 @@ export const checkDatabaseResourceTokensValidity = (tokenTimestamp: number): voi } }; -export const isFabricMirrored = (): boolean => - configContext.platform === Platform.Fabric && - (userContext.fabricContext?.artifactType === CosmosDbArtifactType.MIRRORED_KEY || - userContext.fabricContext?.artifactType === CosmosDbArtifactType.MIRRORED_AAD); - +export const isFabric = (): boolean => configContext.platform === Platform.Fabric; +export const isFabricMirroredKey = (): boolean => + isFabric() && userContext.fabricContext?.artifactType === CosmosDbArtifactType.MIRRORED_KEY; +export const isFabricMirroredAAD = (): boolean => + isFabric() && userContext.fabricContext?.artifactType === CosmosDbArtifactType.MIRRORED_AAD; +export const isFabricMirrored = (): boolean => isFabricMirroredKey() || isFabricMirroredAAD(); export const isFabricNative = (): boolean => - configContext.platform === Platform.Fabric && userContext.fabricContext?.artifactType === CosmosDbArtifactType.NATIVE; + isFabric() && userContext.fabricContext?.artifactType === CosmosDbArtifactType.NATIVE; diff --git a/src/Utils/WindowUtils.ts b/src/Utils/WindowUtils.ts index 8776796f7..b437d17fa 100644 --- a/src/Utils/WindowUtils.ts +++ b/src/Utils/WindowUtils.ts @@ -1,3 +1,4 @@ +import { isFabric } from "Platform/Fabric/FabricUtil"; import { Platform, configContext } from "./../ConfigContext"; export const getDataExplorerWindow = (currentWindow: Window): Window | undefined => { @@ -7,7 +8,7 @@ export const getDataExplorerWindow = (currentWindow: Window): Window | undefined if (currentWindow.parent === currentWindow) { return undefined; } - if (configContext.platform === Platform.Fabric && currentWindow.parent.parent === currentWindow.top) { + if (isFabric() && currentWindow.parent.parent === currentWindow.top) { // in Fabric data explorer is inside an extension iframe, so we have two parent iframes return currentWindow; } diff --git a/src/hooks/useTabs.ts b/src/hooks/useTabs.ts index 59e8bcb27..8b7051a52 100644 --- a/src/hooks/useTabs.ts +++ b/src/hooks/useTabs.ts @@ -54,7 +54,7 @@ export enum ReactTabKind { export const useTabs: UseStore = create((set, get) => ({ openedTabs: [] as TabsBase[], openedReactTabs: [ReactTabKind.Home], - activeTab: undefined, + activeTab: undefined as TabsBase, activeReactTab: ReactTabKind.Home, queryCopilotTabInitialInput: "", isTabExecuting: false,