{userContext.apiType === "Postgres"
? "Welcome to Azure Cosmos DB for PostgreSQL"
: "Welcome to Azure Cosmos DB"}
From 1ee6abf89076ed8542286add3dbcfad24faa27de Mon Sep 17 00:00:00 2001
From: jawelton74 <103591340+jawelton74@users.noreply.github.com>
Date: Mon, 27 Mar 2023 10:47:04 -0700
Subject: [PATCH 10/11] Change AAD endpoint from /common to /organizations.
(#1408)
---
src/Utils/AuthorizationUtils.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/Utils/AuthorizationUtils.ts b/src/Utils/AuthorizationUtils.ts
index 0da7e310f..6e99d2351 100644
--- a/src/Utils/AuthorizationUtils.ts
+++ b/src/Utils/AuthorizationUtils.ts
@@ -49,7 +49,7 @@ export function getMsalInstance() {
cacheLocation: "localStorage",
},
auth: {
- authority: `${configContext.AAD_ENDPOINT}common`,
+ authority: `${configContext.AAD_ENDPOINT}organizations`,
clientId: "203f1145-856a-4232-83d4-a43568fba23d",
},
};
From 7f220bf8be09a57ce50e30a18c67a94822a7bfd3 Mon Sep 17 00:00:00 2001
From: sindhuba <122321535+sindhuba@users.noreply.github.com>
Date: Mon, 27 Mar 2023 15:33:55 -0700
Subject: [PATCH 11/11] Add additional teaching bubbles in Quickstart (#1407)
* Add additional teaching bubbles in Quickstart
* Run npm format
* Fix lint error
* Add unit tests
* Add Mongo teaching bubbles for Try CosmosDB and Launch full screen
* Add additional tests for UrlUtility
* Run npm format
* Add tests for Notebook Utils
---
src/Common/EnvironmentUtility.test.ts | 14 ++++
src/Common/OfferUtility.test.ts | 24 ++++++-
src/Common/UrlUtility.test.ts | 49 ++++++++++++++
.../CommandBarComponentButtonFactory.tsx | 1 +
.../InMemoryContentProviderUtils.test.ts | 23 +++++++
.../Tutorials/MongoQuickstartTutorial.tsx | 67 ++++++++++++++++---
.../Tutorials/SQLQuickstartTutorial.tsx | 64 +++++++++++++++---
src/Main.tsx | 1 +
8 files changed, 222 insertions(+), 21 deletions(-)
create mode 100644 src/Common/EnvironmentUtility.test.ts
create mode 100644 src/Common/UrlUtility.test.ts
create mode 100644 src/Explorer/Notebook/NotebookComponent/InMemoryContentProviderUtils.test.ts
diff --git a/src/Common/EnvironmentUtility.test.ts b/src/Common/EnvironmentUtility.test.ts
new file mode 100644
index 000000000..6b5b1e218
--- /dev/null
+++ b/src/Common/EnvironmentUtility.test.ts
@@ -0,0 +1,14 @@
+import * as EnvironmentUtility from "./EnvironmentUtility";
+
+describe("Environment Utility Test", () => {
+ it("Test sample URI with /", () => {
+ const uri = "test/";
+ expect(EnvironmentUtility.normalizeArmEndpoint(uri)).toEqual(uri);
+ });
+
+ it("Test sample URI without /", () => {
+ const uri = "test";
+ const expectedResult = "test/";
+ expect(EnvironmentUtility.normalizeArmEndpoint(uri)).toEqual(expectedResult);
+ });
+});
diff --git a/src/Common/OfferUtility.test.ts b/src/Common/OfferUtility.test.ts
index ce86c0d8a..d854f74d0 100644
--- a/src/Common/OfferUtility.test.ts
+++ b/src/Common/OfferUtility.test.ts
@@ -1,6 +1,6 @@
-import * as OfferUtility from "./OfferUtility";
-import { SDKOfferDefinition, Offer } from "../Contracts/DataModels";
import { OfferResponse } from "@azure/cosmos";
+import { Offer, SDKOfferDefinition } from "../Contracts/DataModels";
+import * as OfferUtility from "./OfferUtility";
describe("parseSDKOfferResponse", () => {
it("manual throughput", () => {
@@ -31,6 +31,26 @@ describe("parseSDKOfferResponse", () => {
expect(OfferUtility.parseSDKOfferResponse(mockResponse)).toEqual(expectedResult);
});
+ it("offerContent not defined", () => {
+ const mockOfferDefinition = {
+ id: "test",
+ } as SDKOfferDefinition;
+
+ const mockResponse = {
+ resource: mockOfferDefinition,
+ } as OfferResponse;
+
+ expect(OfferUtility.parseSDKOfferResponse(mockResponse)).toEqual(undefined);
+ });
+
+ it("offerDefinition is null", () => {
+ const mockResponse = {
+ resource: undefined,
+ } as OfferResponse;
+
+ expect(OfferUtility.parseSDKOfferResponse(mockResponse)).toEqual(undefined);
+ });
+
it("autoscale throughput", () => {
const mockOfferDefinition = {
content: {
diff --git a/src/Common/UrlUtility.test.ts b/src/Common/UrlUtility.test.ts
new file mode 100644
index 000000000..8170cc63f
--- /dev/null
+++ b/src/Common/UrlUtility.test.ts
@@ -0,0 +1,49 @@
+import * as UrlUtility from "./UrlUtility";
+
+describe("parseDocumentsPath", () => {
+ it("empty resource path", () => {
+ const resourcePath = "";
+
+ expect(UrlUtility.parseDocumentsPath(resourcePath)).toEqual({});
+ });
+
+ it("resourcePath does not begin or end with /", () => {
+ const resourcePath = "localhost/portal/home";
+ const expectedResult = {
+ type: "home",
+ objectBody: {
+ id: "portal",
+ self: "/localhost/portal/home/",
+ },
+ };
+
+ expect(UrlUtility.parseDocumentsPath(resourcePath)).toEqual(expectedResult);
+ });
+
+ it("resourcePath length is even", () => {
+ const resourcePath = "/localhost/portal/src/home/";
+ const expectedResult = {
+ type: "src",
+ objectBody: {
+ id: "home",
+ self: resourcePath,
+ },
+ };
+
+ expect(UrlUtility.parseDocumentsPath(resourcePath)).toEqual(expectedResult);
+ });
+
+ it("createUri", () => {
+ const baseUri = "http://foo.com/bar/";
+ const relativeUri = "/index.html";
+ const expectedUri = "http://foo.com/bar/index.html";
+
+ expect(UrlUtility.createUri(baseUri, relativeUri)).toEqual(expectedUri);
+ });
+
+ it("should throw an error if baseUri is empty", () => {
+ expect(() => {
+ UrlUtility.createUri("", "/home");
+ }).toThrow("baseUri is null or empty");
+ });
+});
diff --git a/src/Explorer/Menus/CommandBar/CommandBarComponentButtonFactory.tsx b/src/Explorer/Menus/CommandBar/CommandBarComponentButtonFactory.tsx
index c02639f09..938383d5b 100644
--- a/src/Explorer/Menus/CommandBar/CommandBarComponentButtonFactory.tsx
+++ b/src/Explorer/Menus/CommandBar/CommandBarComponentButtonFactory.tsx
@@ -202,6 +202,7 @@ export function createControlCommandBarButtons(container: Explorer): CommandButt
if (showOpenFullScreen) {
const label = "Open Full Screen";
const fullScreenButton: CommandButtonComponentProps = {
+ id: "openFullScreenBtn",
iconSrc: OpenInTabIcon,
iconAlt: label,
onCommandClick: () => {
diff --git a/src/Explorer/Notebook/NotebookComponent/InMemoryContentProviderUtils.test.ts b/src/Explorer/Notebook/NotebookComponent/InMemoryContentProviderUtils.test.ts
new file mode 100644
index 000000000..a5fd5df80
--- /dev/null
+++ b/src/Explorer/Notebook/NotebookComponent/InMemoryContentProviderUtils.test.ts
@@ -0,0 +1,23 @@
+import * as InMemoryContentProviderUtils from "./ContentProviders/InMemoryContentProviderUtils";
+
+describe("fromContentUri", () => {
+ it("fromContentUri should return valid result", () => {
+ const contentUri = "memory://resource/path";
+ const result = "resource";
+
+ expect(InMemoryContentProviderUtils.fromContentUri(contentUri)).toEqual(result);
+ });
+
+ it("fromContentUri should return undefined on invalid input", () => {
+ const contentUri = "invalid";
+
+ expect(InMemoryContentProviderUtils.fromContentUri(contentUri)).toEqual(undefined);
+ });
+
+ it("toContentUri should return valid result", () => {
+ const path = "resource/path";
+ const result = "memory://resource/path";
+
+ expect(InMemoryContentProviderUtils.toContentUri(path)).toEqual(result);
+ });
+});
diff --git a/src/Explorer/Quickstart/Tutorials/MongoQuickstartTutorial.tsx b/src/Explorer/Quickstart/Tutorials/MongoQuickstartTutorial.tsx
index d6655e14b..aa9c5e300 100644
--- a/src/Explorer/Quickstart/Tutorials/MongoQuickstartTutorial.tsx
+++ b/src/Explorer/Quickstart/Tutorials/MongoQuickstartTutorial.tsx
@@ -1,4 +1,4 @@
-import { Link, Stack, TeachingBubble, Text } from "@fluentui/react";
+import { DirectionalHint, Link, Stack, TeachingBubble, Text } from "@fluentui/react";
import { ReactTabKind, useTabs } from "hooks/useTabs";
import { useTeachingBubble } from "hooks/useTeachingBubble";
import React from "react";
@@ -18,6 +18,11 @@ export const MongoQuickstartTutorial: React.FC = (): JSX.Element => {
return <>>;
}
+ let totalSteps = 9;
+ if (userContext.isTryCosmosDBSubscription) {
+ totalSteps = 10;
+ }
+
switch (step) {
case 1:
return isSampleDBExpanded ? (
@@ -33,7 +38,7 @@ export const MongoQuickstartTutorial: React.FC = (): JSX.Element => {
},
}}
onDismiss={() => onDimissTeachingBubble()}
- footerContent="Step 1 of 8"
+ footerContent={"Step 1 of " + totalSteps}
>
Start viewing and working with your data by opening Documents under Data
@@ -55,7 +60,7 @@ export const MongoQuickstartTutorial: React.FC = (): JSX.Element => {
onClick: () => setStep(1),
}}
onDismiss={() => onDimissTeachingBubble()}
- footerContent="Step 2 of 8"
+ footerContent={"Step 2 of " + totalSteps}
>
View documents here using the documents window. You can also use your favorite MongoDB tools and drivers to do
so.
@@ -78,7 +83,7 @@ export const MongoQuickstartTutorial: React.FC = (): JSX.Element => {
onClick: () => setStep(2),
}}
onDismiss={() => onDimissTeachingBubble()}
- footerContent="Step 3 of 8"
+ footerContent={"Step 3 of " + totalSteps}
>
Add new document by copy / pasting JSON or uploading a JSON. You can also use your favorite MongoDB tools and
drivers to do so.
@@ -99,7 +104,7 @@ export const MongoQuickstartTutorial: React.FC = (): JSX.Element => {
onClick: () => setStep(3),
}}
onDismiss={() => onDimissTeachingBubble()}
- footerContent="Step 4 of 8"
+ footerContent={"Step 4 of " + totalSteps}
>
Query your data using the filter function. Azure Cosmos DB for MongoDB provides comprehensive support for
MongoDB query language constructs. You can also use your favorite MongoDB tools and drivers to do so.
@@ -120,7 +125,7 @@ export const MongoQuickstartTutorial: React.FC = (): JSX.Element => {
onClick: () => setStep(4),
}}
onDismiss={() => onDimissTeachingBubble()}
- footerContent="Step 5 of 8"
+ footerContent={"Step 5 of " + totalSteps}
>
Change throughput provisioned to your collection according to your needs
@@ -140,7 +145,7 @@ export const MongoQuickstartTutorial: React.FC = (): JSX.Element => {
onClick: () => setStep(5),
}}
onDismiss={() => onDimissTeachingBubble()}
- footerContent="Step 6 of 8"
+ footerContent={"Step 6 of " + totalSteps}
>
Use the indexing policy editor to create and edit your indexes.
@@ -160,12 +165,54 @@ export const MongoQuickstartTutorial: React.FC = (): JSX.Element => {
onClick: () => setStep(6),
}}
onDismiss={() => onDimissTeachingBubble()}
- footerContent="Step 7 of 8"
+ footerContent={"Step 7 of " + totalSteps}
>
Visualize your data, store queries in an interactive document
);
case 8:
+ return (
+
(userContext.isTryCosmosDBSubscription ? setStep(9) : setStep(10)),
+ }}
+ secondaryButtonProps={{
+ text: "Previous",
+ onClick: () => setStep(7),
+ }}
+ onDismiss={() => onDimissTeachingBubble()}
+ footerContent={"Step 8 of " + totalSteps}
+ >
+ This will open a new tab in your browser to use Cosmos DB Explorer. Using the provided URLs you can share
+ read-write or read-only access with other people.
+
+ );
+ case 9:
+ return (
+
setStep(10),
+ }}
+ secondaryButtonProps={{
+ text: "Previous",
+ onClick: () => setStep(8),
+ }}
+ calloutProps={{ directionalHint: DirectionalHint.leftCenter }}
+ onDismiss={() => onDimissTeachingBubble()}
+ footerContent={"Step 9 of " + totalSteps}
+ >
+ Unlock everything Azure Cosmos DB has to offer When you're ready, upgrade to production.
+
+ );
+ case 10:
return (
{
}}
secondaryButtonProps={{
text: "Previous",
- onClick: () => setStep(7),
+ onClick: () => (userContext.isTryCosmosDBSubscription ? setStep(9) : setStep(8)),
}}
onDismiss={() => onDimissTeachingBubble()}
- footerContent="Step 8 of 8"
+ footerContent={"Step " + totalSteps + " of " + totalSteps}
>
diff --git a/src/Explorer/Quickstart/Tutorials/SQLQuickstartTutorial.tsx b/src/Explorer/Quickstart/Tutorials/SQLQuickstartTutorial.tsx
index cced06a50..ddb35aa5e 100644
--- a/src/Explorer/Quickstart/Tutorials/SQLQuickstartTutorial.tsx
+++ b/src/Explorer/Quickstart/Tutorials/SQLQuickstartTutorial.tsx
@@ -1,4 +1,4 @@
-import { Link, Stack, TeachingBubble, Text } from "@fluentui/react";
+import { DirectionalHint, Link, Stack, TeachingBubble, Text } from "@fluentui/react";
import { ReactTabKind, useTabs } from "hooks/useTabs";
import { useTeachingBubble } from "hooks/useTeachingBubble";
import React from "react";
@@ -17,6 +17,10 @@ export const SQLQuickstartTutorial: React.FC = (): JSX.Element => {
if (userContext.apiType !== "SQL") {
return <>>;
}
+ let totalSteps = 8;
+ if (userContext.isTryCosmosDBSubscription) {
+ totalSteps = 9;
+ }
switch (step) {
case 1:
@@ -33,7 +37,7 @@ export const SQLQuickstartTutorial: React.FC = (): JSX.Element => {
},
}}
onDismiss={() => onDimissTeachingBubble()}
- footerContent="Step 1 of 7"
+ footerContent={"Step 1 of " + totalSteps}
>
Start viewing and working with your data by opening Items under Data
@@ -55,7 +59,7 @@ export const SQLQuickstartTutorial: React.FC = (): JSX.Element => {
onClick: () => setStep(1),
}}
onDismiss={() => onDimissTeachingBubble()}
- footerContent="Step 2 of 7"
+ footerContent={"Step 2 of " + totalSteps}
>
View item here using the items window. Additionally you can also filter items to be reviewed with the filter
function
@@ -78,7 +82,7 @@ export const SQLQuickstartTutorial: React.FC = (): JSX.Element => {
onClick: () => setStep(2),
}}
onDismiss={() => onDimissTeachingBubble()}
- footerContent="Step 3 of 7"
+ footerContent={"Step 3 of " + totalSteps}
>
Add new item by copy / pasting JSON; or uploading a JSON
@@ -98,7 +102,7 @@ export const SQLQuickstartTutorial: React.FC = (): JSX.Element => {
onClick: () => setStep(3),
}}
onDismiss={() => onDimissTeachingBubble()}
- footerContent="Step 4 of 7"
+ footerContent={"Step 4 of " + totalSteps}
>
Query your data using either the filter function or new query.
@@ -118,7 +122,7 @@ export const SQLQuickstartTutorial: React.FC = (): JSX.Element => {
onClick: () => setStep(4),
}}
onDismiss={() => onDimissTeachingBubble()}
- footerContent="Step 5 of 7"
+ footerContent={"Step 5 of " + totalSteps}
>
Change throughput provisioned to your container according to your needs
@@ -138,12 +142,54 @@ export const SQLQuickstartTutorial: React.FC = (): JSX.Element => {
onClick: () => setStep(5),
}}
onDismiss={() => onDimissTeachingBubble()}
- footerContent="Step 6 of 7"
+ footerContent={"Step 6 of " + totalSteps}
>
Visualize your data, store queries in an interactive document
);
case 7:
+ return (
+
(userContext.isTryCosmosDBSubscription ? setStep(8) : setStep(9)),
+ }}
+ secondaryButtonProps={{
+ text: "Previous",
+ onClick: () => setStep(6),
+ }}
+ onDismiss={() => onDimissTeachingBubble()}
+ footerContent={"Step 7 of " + totalSteps}
+ >
+ This will open a new tab in your browser to use Cosmos DB Explorer. Using the provided URLs you can share
+ read-write or read-only access with other people.
+
+ );
+ case 8:
+ return (
+
setStep(9),
+ }}
+ secondaryButtonProps={{
+ text: "Previous",
+ onClick: () => setStep(7),
+ }}
+ calloutProps={{ directionalHint: DirectionalHint.leftCenter }}
+ onDismiss={() => onDimissTeachingBubble()}
+ footerContent={"Step 8 of " + totalSteps}
+ >
+ Unlock everything Azure Cosmos DB has to offer When you're ready, upgrade to production.
+
+ );
+ case 9:
return (
{
}}
secondaryButtonProps={{
text: "Previous",
- onClick: () => setStep(6),
+ onClick: () => (userContext.isTryCosmosDBSubscription ? setStep(8) : setStep(7)),
}}
onDismiss={() => onDimissTeachingBubble()}
- footerContent="Step 7 of 7"
+ footerContent={"Step " + totalSteps + " of " + totalSteps}
>
diff --git a/src/Main.tsx b/src/Main.tsx
index 2115406ce..d8d817847 100644
--- a/src/Main.tsx
+++ b/src/Main.tsx
@@ -80,6 +80,7 @@ const App: React.FunctionComponent = () => {
return (
+
{/* Main Command Bar - Start */}
{/* Collections Tree and Tabs - Begin */}