From 94b1e729d1045eb5b3866ee10ab51851847ae9c8 Mon Sep 17 00:00:00 2001 From: Laurent Nguyen Date: Tue, 15 Apr 2025 17:49:16 +0200 Subject: [PATCH] Enable original azure resource tree style for Fabric native and turn on Settings tab (#2103) * Enable original azure resource tree for Fabric native and turn on Settings page * Fix unit tests --- src/Common/dataAccess/readCollectionOffer.ts | 6 + .../Controls/Settings/SettingsComponent.tsx | 2 + .../PartitionKeyComponent.tsx | 119 ++++++----- .../SettingsComponent.test.tsx.snap | 1 + .../__snapshots__/treeNodeUtil.test.ts.snap | 194 +++++++++++++++--- src/Explorer/Tree/treeNodeUtil.test.ts | 18 +- src/Explorer/Tree/treeNodeUtil.tsx | 8 +- 7 files changed, 264 insertions(+), 84 deletions(-) diff --git a/src/Common/dataAccess/readCollectionOffer.ts b/src/Common/dataAccess/readCollectionOffer.ts index 6fb6e9e4b..d3c8e25cd 100644 --- a/src/Common/dataAccess/readCollectionOffer.ts +++ b/src/Common/dataAccess/readCollectionOffer.ts @@ -1,3 +1,4 @@ +import { isFabric } from "Platform/Fabric/FabricUtil"; import { AuthType } from "../../AuthType"; import { Offer, ReadCollectionOfferParams } from "../../Contracts/DataModels"; import { userContext } from "../../UserContext"; @@ -13,6 +14,11 @@ import { readOfferWithSDK } from "./readOfferWithSDK"; export const readCollectionOffer = async (params: ReadCollectionOfferParams): Promise => { const clearMessage = logConsoleProgress(`Querying offer for collection ${params.collectionId}`); + if (isFabric()) { + // Not exposing offers in Fabric + return undefined; + } + try { if ( userContext.authType === AuthType.AAD && diff --git a/src/Explorer/Controls/Settings/SettingsComponent.tsx b/src/Explorer/Controls/Settings/SettingsComponent.tsx index beec14495..2613fe65b 100644 --- a/src/Explorer/Controls/Settings/SettingsComponent.tsx +++ b/src/Explorer/Controls/Settings/SettingsComponent.tsx @@ -12,6 +12,7 @@ import { ThroughputBucketsComponentProps, } from "Explorer/Controls/Settings/SettingsSubComponents/ThroughputInputComponents/ThroughputBucketsComponent"; import { useDatabases } from "Explorer/useDatabases"; +import { isFabricNative } from "Platform/Fabric/FabricUtil"; import { isFullTextSearchEnabled, isVectorSearchEnabled } from "Utils/CapabilityUtils"; import { isRunningOnPublicCloud } from "Utils/CloudUtils"; import * as React from "react"; @@ -1277,6 +1278,7 @@ export class SettingsComponent extends React.Component = ({ database, collection, explorer }) => { +export const PartitionKeyComponent: React.FC = ({ + database, + collection, + explorer, + isReadOnly, +}) => { const { dataTransferJobs } = useDataTransferJobs(); const [portalDataTransferJob, setPortalDataTransferJob] = React.useState(null); React.useEffect(() => { + if (isReadOnly) { + return; + } + const loadDataTransferJobs = refreshDataTransferOperations; loadDataTransferJobs(); - }, []); + }, [isReadOnly]); React.useEffect(() => { const currentJob = findPortalDataTransferJob(); @@ -163,56 +173,61 @@ export const PartitionKeyComponent: React.FC = ({ da - - To safeguard the integrity of the data being copied to the new container, ensure that no updates are made to the - source container for the entire duration of the partition key change process. - - Learn more - - - - To change the partition key, a new destination container must be created or an existing destination container - selected. Data will then be copied to the destination container. - - {configContext.platform !== Platform.Emulator && ( - - )} - {portalDataTransferJob && ( - - {partitionKeyName} change job - - - {isCurrentJobInProgress(portalDataTransferJob) && ( - cancelRunningDataTransferJob(portalDataTransferJob)} /> - )} - - + + {!isReadOnly && ( + <> + + To safeguard the integrity of the data being copied to the new container, ensure that no updates are made to + the source container for the entire duration of the partition key change process. + + Learn more + + + + To change the partition key, a new destination container must be created or an existing destination + container selected. Data will then be copied to the destination container. + + {configContext.platform !== Platform.Emulator && ( + + )} + {portalDataTransferJob && ( + + {partitionKeyName} change job + + + {isCurrentJobInProgress(portalDataTransferJob) && ( + cancelRunningDataTransferJob(portalDataTransferJob)} /> + )} + + + )} + )} ); diff --git a/src/Explorer/Controls/Settings/__snapshots__/SettingsComponent.test.tsx.snap b/src/Explorer/Controls/Settings/__snapshots__/SettingsComponent.test.tsx.snap index 34f6dec6d..ac2aa4fa3 100644 --- a/src/Explorer/Controls/Settings/__snapshots__/SettingsComponent.test.tsx.snap +++ b/src/Explorer/Controls/Settings/__snapshots__/SettingsComponent.test.tsx.snap @@ -306,6 +306,7 @@ exports[`SettingsComponent renders 1`] = ` }, } } + isReadOnly={false} /> { it.each<[string, Platform, boolean, Partial, Partial]>([ [ - "the SQL API, on Fabric read-only", + "the SQL API, on Fabric read-only (mirrored)", Platform.Fabric, false, { capabilities: [], enableMultipleWriteLocations: true }, - { fabricContext: { isReadOnly: true } as FabricContext }, + { + fabricContext: { + isReadOnly: true, + artifactType: CosmosDbArtifactType.MIRRORED_KEY, + } as FabricContext, + }, ], [ - "the SQL API, on Fabric non read-only", + "the SQL API, on Fabric non read-only (native)", Platform.Fabric, false, { capabilities: [], enableMultipleWriteLocations: true }, - { fabricContext: { isReadOnly: false } as FabricContext }, + { + fabricContext: { + isReadOnly: false, + artifactType: CosmosDbArtifactType.NATIVE, + } as FabricContext, + }, ], [ "the SQL API, on Portal", diff --git a/src/Explorer/Tree/treeNodeUtil.tsx b/src/Explorer/Tree/treeNodeUtil.tsx index a9bf32247..4f1cb002b 100644 --- a/src/Explorer/Tree/treeNodeUtil.tsx +++ b/src/Explorer/Tree/treeNodeUtil.tsx @@ -6,7 +6,7 @@ import StoredProcedure from "Explorer/Tree/StoredProcedure"; import Trigger from "Explorer/Tree/Trigger"; import UserDefinedFunction from "Explorer/Tree/UserDefinedFunction"; import { useDatabases } from "Explorer/useDatabases"; -import { isFabricMirrored } from "Platform/Fabric/FabricUtil"; +import { isFabric, isFabricMirrored, isFabricNative } from "Platform/Fabric/FabricUtil"; import { getItemName } from "Utils/APITypeUtils"; import { isServerlessAccount } from "Utils/CapabilityUtils"; import { useTabs } from "hooks/useTabs"; @@ -23,7 +23,7 @@ import { useNotebook } from "../Notebook/useNotebook"; import { useSelectedNode } from "../useSelectedNode"; export const shouldShowScriptNodes = (): boolean => { - return !isFabricMirrored() && (userContext.apiType === "SQL" || userContext.apiType === "Gremlin"); + return !isFabric() && (userContext.apiType === "SQL" || userContext.apiType === "Gremlin"); }; const TreeDatabaseIcon = ; @@ -220,7 +220,7 @@ export const buildCollectionNode = ( ): TreeNode => { let children: TreeNode[]; // Flat Tree for Fabric - if (configContext.platform !== Platform.Fabric) { + if (!isFabricMirrored()) { children = buildCollectionNodeChildren(database, collection, isNotebookEnabled, container, refreshActiveTab); } @@ -318,7 +318,7 @@ const buildCollectionNodeChildren = ( children.push({ id, - label: database.isDatabaseShared() || isServerlessAccount() ? "Settings" : "Scale & Settings", + label: database.isDatabaseShared() || isServerlessAccount() || isFabricNative() ? "Settings" : "Scale & Settings", onClick: collection.onSettingsClick.bind(collection), isSelected: () => useSelectedNode