diff --git a/package-lock.json b/package-lock.json index 5983c0e2f..e3312c71b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -109,9 +109,9 @@ } }, "@azure/core-rest-pipeline": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/@azure/core-rest-pipeline/-/core-rest-pipeline-1.8.1.tgz", - "integrity": "sha512-R/XpxZcDgGbnneEifnsAcjLoR2NCmlDxKDmzd8oi5jx5YEnPE6gsxHQWAk2+uY55Ka717x/fdctyoCYKnumrqw==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@azure/core-rest-pipeline/-/core-rest-pipeline-1.9.0.tgz", + "integrity": "sha512-uvM3mY+Vegk0F2r4Eh0yPdsXTUyafTQkeX0USnz1Eyangxm2Bib0w0wkJVZW8fpks7Lcv0ztIdCFTrN7H8uptg==", "requires": { "@azure/abort-controller": "^1.0.0", "@azure/core-auth": "^1.3.0", @@ -188,12 +188,13 @@ } }, "@azure/cosmos": { - "version": "3.16.2", - "resolved": "https://registry.npmjs.org/@azure/cosmos/-/cosmos-3.16.2.tgz", - "integrity": "sha512-sceY5LWj0BHGj8PSyaVCfDRQLVZyoCfIY78kyIROJVEw0k+p9XFs8fhpykN8JklkCftL0WlaVY+X25SQwnhZsw==", + "version": "3.16.3", + "resolved": "https://registry.npmjs.org/@azure/cosmos/-/cosmos-3.16.3.tgz", + "integrity": "sha512-c+znFMHB03QjvLwUfFhASXJn02Ucg0T+sZ4iAC6y7jfjb4SEzxOt3YjvSKAdFzAQa3TMa/Yg9NJEHlRxPSk0/Q==", "requires": { "@azure/core-auth": "^1.3.0", "@azure/core-rest-pipeline": "^1.2.0", + "@azure/core-tracing": "^1.0.0", "debug": "^4.1.1", "fast-json-stable-stringify": "^2.1.0", "jsbi": "^3.1.3", @@ -205,10 +206,18 @@ "uuid": "^8.3.0" }, "dependencies": { + "@azure/core-tracing": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.0.1.tgz", + "integrity": "sha512-I5CGMoLtX+pI17ZdiFJZgxMJApsK6jjfm85hpgp3oazCdq5Wxgh4wMr7ge/TTWW1B5WBuvIOI1fMU/FrOAMKrw==", + "requires": { + "tslib": "^2.2.0" + } + }, "tslib": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.2.0.tgz", - "integrity": "sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w==" + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" }, "universal-user-agent": { "version": "6.0.0", @@ -8904,9 +8913,9 @@ "integrity": "sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==" }, "are-we-there-yet": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", - "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz", + "integrity": "sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g==", "optional": true, "requires": { "delegates": "^1.0.0", @@ -11065,7 +11074,7 @@ "console-control-strings": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", + "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", "optional": true }, "content-disposition": { @@ -12350,7 +12359,7 @@ "delegates": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", "optional": true }, "depd": { @@ -12383,7 +12392,7 @@ "detect-libc": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", + "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", "optional": true }, "detect-newline": { @@ -21268,9 +21277,9 @@ } }, "jsbi": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/jsbi/-/jsbi-3.1.4.tgz", - "integrity": "sha512-52QRRFSsi9impURE8ZUbzAMCLjPm4THO7H2fcuIvaaeFTbSysvkodbQQXIVsNgq/ypDbq6dJiuGKL0vZ/i9hUg==" + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/jsbi/-/jsbi-3.2.5.tgz", + "integrity": "sha512-aBE4n43IPvjaddScbvWRA2YlTzKEynHzu7MqOyTipdHucf/VxS63ViCjxYRg86M8Rxwbt/GfzHl1kKERkt45fQ==" }, "jsbn": { "version": "0.1.1", @@ -23704,9 +23713,9 @@ } }, "node-abi": { - "version": "2.26.0", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.26.0.tgz", - "integrity": "sha512-ag/Vos/mXXpWLLAYWsAoQdgS+gW7IwvgMLOgqopm/DbzAjazLltzgzpVMsFlgmo9TzG5hGXeaBZx2AI731RIsQ==", + "version": "2.30.1", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.30.1.tgz", + "integrity": "sha512-/2D0wOQPgaUWzVSVgRMx+trKJRC2UG4SUc4oCJoXx9Uxjtp0Vy3/kt7zcbxHF8+Z/pK3UloLWzBISg72brfy1w==", "optional": true, "requires": { "semver": "^5.4.1" @@ -23774,7 +23783,7 @@ "noop-logger": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/noop-logger/-/noop-logger-0.1.1.tgz", - "integrity": "sha1-lKKxYzxPExdVMAfYlm/Q6EG2pMI=", + "integrity": "sha512-6kM8CLXvuW5crTxsAtva2YLrRrDaiTIkIePWs9moLHqbFWT94WpNFjwS/5dfLfECg5i/lkmw3aoqVidxt23TEQ==", "optional": true }, "nopt": { @@ -26184,12 +26193,20 @@ }, "dependencies": { "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", "optional": true, "requires": { - "minimist": "^1.2.5" + "minimist": "^1.2.6" + }, + "dependencies": { + "minimist": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", + "optional": true + } } } } @@ -28286,9 +28303,9 @@ "optional": true }, "simple-get": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.0.tgz", - "integrity": "sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.1.tgz", + "integrity": "sha512-CQ5LTKGfCpvE1K0n2us+kuMPbk/q0EKl82s4aheV9oXjFEz6W/Y7oQFVJuU6QG77hRT4Ghb5RURteF5vnWjupA==", "optional": true, "requires": { "decompress-response": "^4.2.0", @@ -31132,18 +31149,18 @@ "integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==" }, "which-pm-runs": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz", - "integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs=", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.1.0.tgz", + "integrity": "sha512-n1brCuqClxfFfq/Rb0ICg9giSZqCS+pLtccdag6C2HyufBrh3fBOiy9nb6ggRMvWOVH5GrdJskj5iGTZNxd7SA==", "optional": true }, "wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", + "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", "optional": true, "requires": { - "string-width": "^1.0.2 || 2" + "string-width": "^1.0.2 || 2 || 3 || 4" } }, "wildcard": { diff --git a/package.json b/package.json index 4075ef0aa..4d5fde323 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "main": "index.js", "dependencies": { "@azure/arm-cosmosdb": "9.1.0", - "@azure/cosmos": "3.16.2", + "@azure/cosmos": "3.16.3", "@azure/cosmos-language-service": "0.0.5", "@azure/identity": "1.2.1", "@azure/ms-rest-nodeauth": "3.0.7", diff --git a/src/Common/dataAccess/createCollection.ts b/src/Common/dataAccess/createCollection.ts index 7c657e667..64911ff28 100644 --- a/src/Common/dataAccess/createCollection.ts +++ b/src/Common/dataAccess/createCollection.ts @@ -24,7 +24,7 @@ export const createCollection = async (params: DataModels.CreateCollectionParams ); try { let collection: DataModels.Collection; - if (userContext.authType === AuthType.AAD && !userContext.useSDKOperations) { + if (userContext.authType === AuthType.AAD && !userContext.features.enableSDKoperations) { if (params.createNewDatabase) { const createDatabaseParams: DataModels.CreateDatabaseParams = { autoPilotMaxThroughput: params.autoPilotMaxThroughput, diff --git a/src/Common/dataAccess/createDatabase.ts b/src/Common/dataAccess/createDatabase.ts index 9208119ad..d54c94133 100644 --- a/src/Common/dataAccess/createDatabase.ts +++ b/src/Common/dataAccess/createDatabase.ts @@ -25,7 +25,8 @@ export async function createDatabase(params: DataModels.CreateDatabaseParams): P if (userContext.apiType === "Tables") { throw new Error("Creating database resources is not allowed for tables accounts"); } - const database: DataModels.Database = await (userContext.authType === AuthType.AAD && !userContext.useSDKOperations + const database: DataModels.Database = await (userContext.authType === AuthType.AAD && + !userContext.features.enableSDKoperations ? createDatabaseWithARM(params) : createDatabaseWithSDK(params)); diff --git a/src/Common/dataAccess/createStoredProcedure.ts b/src/Common/dataAccess/createStoredProcedure.ts index 579835277..96ae4b7b0 100644 --- a/src/Common/dataAccess/createStoredProcedure.ts +++ b/src/Common/dataAccess/createStoredProcedure.ts @@ -20,7 +20,11 @@ export async function createStoredProcedure( ): Promise { const clearMessage = logConsoleProgress(`Creating stored procedure ${storedProcedure.id}`); try { - if (userContext.authType === AuthType.AAD && !userContext.useSDKOperations && userContext.apiType === "SQL") { + if ( + userContext.authType === AuthType.AAD && + !userContext.features.enableSDKoperations && + userContext.apiType === "SQL" + ) { try { const getResponse = await getSqlStoredProcedure( userContext.subscriptionId, diff --git a/src/Common/dataAccess/createTrigger.ts b/src/Common/dataAccess/createTrigger.ts index ad825820f..d5cdd5661 100644 --- a/src/Common/dataAccess/createTrigger.ts +++ b/src/Common/dataAccess/createTrigger.ts @@ -14,7 +14,11 @@ export async function createTrigger( ): Promise { const clearMessage = logConsoleProgress(`Creating trigger ${trigger.id}`); try { - if (userContext.authType === AuthType.AAD && !userContext.useSDKOperations && userContext.apiType === "SQL") { + if ( + userContext.authType === AuthType.AAD && + !userContext.features.enableSDKoperations && + userContext.apiType === "SQL" + ) { try { const getResponse = await getSqlTrigger( userContext.subscriptionId, diff --git a/src/Common/dataAccess/createUserDefinedFunction.ts b/src/Common/dataAccess/createUserDefinedFunction.ts index 3b7dd4a12..175b0af9f 100644 --- a/src/Common/dataAccess/createUserDefinedFunction.ts +++ b/src/Common/dataAccess/createUserDefinedFunction.ts @@ -20,7 +20,11 @@ export async function createUserDefinedFunction( ): Promise { const clearMessage = logConsoleProgress(`Creating user defined function ${userDefinedFunction.id}`); try { - if (userContext.authType === AuthType.AAD && !userContext.useSDKOperations && userContext.apiType === "SQL") { + if ( + userContext.authType === AuthType.AAD && + !userContext.features.enableSDKoperations && + userContext.apiType === "SQL" + ) { try { const getResponse = await getSqlUserDefinedFunction( userContext.subscriptionId, diff --git a/src/Common/dataAccess/deleteCollection.ts b/src/Common/dataAccess/deleteCollection.ts index 63e58b8c8..f83126dd1 100644 --- a/src/Common/dataAccess/deleteCollection.ts +++ b/src/Common/dataAccess/deleteCollection.ts @@ -12,7 +12,7 @@ import { handleError } from "../ErrorHandlingUtils"; export async function deleteCollection(databaseId: string, collectionId: string): Promise { const clearMessage = logConsoleProgress(`Deleting container ${collectionId}`); try { - if (userContext.authType === AuthType.AAD && !userContext.useSDKOperations) { + if (userContext.authType === AuthType.AAD && !userContext.features.enableSDKoperations) { await deleteCollectionWithARM(databaseId, collectionId); } else { await client().database(databaseId).container(collectionId).delete(); diff --git a/src/Common/dataAccess/deleteDatabase.ts b/src/Common/dataAccess/deleteDatabase.ts index c6c744e35..fc16fe205 100644 --- a/src/Common/dataAccess/deleteDatabase.ts +++ b/src/Common/dataAccess/deleteDatabase.ts @@ -12,10 +12,7 @@ export async function deleteDatabase(databaseId: string): Promise { const clearMessage = logConsoleProgress(`Deleting database ${databaseId}`); try { - if (userContext.apiType === "Tables") { - throw new Error("Deleting database resources is not allowed for tables accounts"); - } - if (userContext.authType === AuthType.AAD && !userContext.useSDKOperations) { + if (userContext.authType === AuthType.AAD && !userContext.features.enableSDKoperations) { await deleteDatabaseWithARM(databaseId); } else { await client().database(databaseId).delete(); diff --git a/src/Common/dataAccess/deleteStoredProcedure.ts b/src/Common/dataAccess/deleteStoredProcedure.ts index daaf8315a..6bc5f2fbd 100644 --- a/src/Common/dataAccess/deleteStoredProcedure.ts +++ b/src/Common/dataAccess/deleteStoredProcedure.ts @@ -12,7 +12,11 @@ export async function deleteStoredProcedure( ): Promise { const clearMessage = logConsoleProgress(`Deleting stored procedure ${storedProcedureId}`); try { - if (userContext.authType === AuthType.AAD && !userContext.useSDKOperations && userContext.apiType === "SQL") { + if ( + userContext.authType === AuthType.AAD && + !userContext.features.enableSDKoperations && + userContext.apiType === "SQL" + ) { await deleteSqlStoredProcedure( userContext.subscriptionId, userContext.resourceGroup, diff --git a/src/Common/dataAccess/deleteTrigger.ts b/src/Common/dataAccess/deleteTrigger.ts index b4a7aa7ad..a3b31369e 100644 --- a/src/Common/dataAccess/deleteTrigger.ts +++ b/src/Common/dataAccess/deleteTrigger.ts @@ -8,7 +8,11 @@ import { handleError } from "../ErrorHandlingUtils"; export async function deleteTrigger(databaseId: string, collectionId: string, triggerId: string): Promise { const clearMessage = logConsoleProgress(`Deleting trigger ${triggerId}`); try { - if (userContext.authType === AuthType.AAD && !userContext.useSDKOperations && userContext.apiType === "SQL") { + if ( + userContext.authType === AuthType.AAD && + !userContext.features.enableSDKoperations && + userContext.apiType === "SQL" + ) { await deleteSqlTrigger( userContext.subscriptionId, userContext.resourceGroup, diff --git a/src/Common/dataAccess/deleteUserDefinedFunction.ts b/src/Common/dataAccess/deleteUserDefinedFunction.ts index c9683c1ab..d91d9d55b 100644 --- a/src/Common/dataAccess/deleteUserDefinedFunction.ts +++ b/src/Common/dataAccess/deleteUserDefinedFunction.ts @@ -8,7 +8,11 @@ import { handleError } from "../ErrorHandlingUtils"; export async function deleteUserDefinedFunction(databaseId: string, collectionId: string, id: string): Promise { const clearMessage = logConsoleProgress(`Deleting user defined function ${id}`); try { - if (userContext.authType === AuthType.AAD && !userContext.useSDKOperations && userContext.apiType === "SQL") { + if ( + userContext.authType === AuthType.AAD && + !userContext.features.enableSDKoperations && + userContext.apiType === "SQL" + ) { await deleteSqlUserDefinedFunction( userContext.subscriptionId, userContext.resourceGroup, diff --git a/src/Common/dataAccess/readCollectionOffer.ts b/src/Common/dataAccess/readCollectionOffer.ts index c307242d8..8bd5d589e 100644 --- a/src/Common/dataAccess/readCollectionOffer.ts +++ b/src/Common/dataAccess/readCollectionOffer.ts @@ -14,7 +14,11 @@ export const readCollectionOffer = async (params: ReadCollectionOfferParams): Pr const clearMessage = logConsoleProgress(`Querying offer for collection ${params.collectionId}`); try { - if (userContext.authType === AuthType.AAD && !userContext.useSDKOperations && userContext.apiType !== "Tables") { + if ( + userContext.authType === AuthType.AAD && + !userContext.features.enableSDKoperations && + userContext.apiType !== "Tables" + ) { return await readCollectionOfferWithARM(params.databaseId, params.collectionId); } diff --git a/src/Common/dataAccess/readCollections.ts b/src/Common/dataAccess/readCollections.ts index 92be4f57e..a5c8dd928 100644 --- a/src/Common/dataAccess/readCollections.ts +++ b/src/Common/dataAccess/readCollections.ts @@ -13,7 +13,11 @@ import { handleError } from "../ErrorHandlingUtils"; export async function readCollections(databaseId: string): Promise { const clearMessage = logConsoleProgress(`Querying containers for database ${databaseId}`); try { - if (userContext.authType === AuthType.AAD && !userContext.useSDKOperations && userContext.apiType !== "Tables") { + if ( + userContext.authType === AuthType.AAD && + !userContext.features.enableSDKoperations && + userContext.apiType !== "Tables" + ) { return await readCollectionsWithARM(databaseId); } diff --git a/src/Common/dataAccess/readDatabaseOffer.ts b/src/Common/dataAccess/readDatabaseOffer.ts index d27d68078..bb7366ac9 100644 --- a/src/Common/dataAccess/readDatabaseOffer.ts +++ b/src/Common/dataAccess/readDatabaseOffer.ts @@ -13,7 +13,11 @@ export const readDatabaseOffer = async (params: ReadDatabaseOfferParams): Promis const clearMessage = logConsoleProgress(`Querying offer for database ${params.databaseId}`); try { - if (userContext.authType === AuthType.AAD && !userContext.useSDKOperations && userContext.apiType !== "Tables") { + if ( + userContext.authType === AuthType.AAD && + !userContext.features.enableSDKoperations && + userContext.apiType !== "Tables" + ) { return await readDatabaseOfferWithARM(params.databaseId); } diff --git a/src/Common/dataAccess/readDatabases.ts b/src/Common/dataAccess/readDatabases.ts index e5136676e..cd1ae1843 100644 --- a/src/Common/dataAccess/readDatabases.ts +++ b/src/Common/dataAccess/readDatabases.ts @@ -13,7 +13,11 @@ export async function readDatabases(): Promise { let databases: DataModels.Database[]; const clearMessage = logConsoleProgress(`Querying databases`); try { - if (userContext.authType === AuthType.AAD && !userContext.useSDKOperations && userContext.apiType !== "Tables") { + if ( + userContext.authType === AuthType.AAD && + !userContext.features.enableSDKoperations && + userContext.apiType !== "Tables" + ) { databases = await readDatabasesWithARM(); } else { const sdkResponse = await client().databases.readAll().fetchAll(); diff --git a/src/Common/dataAccess/readStoredProcedures.ts b/src/Common/dataAccess/readStoredProcedures.ts index 65edb54c2..2e8652933 100644 --- a/src/Common/dataAccess/readStoredProcedures.ts +++ b/src/Common/dataAccess/readStoredProcedures.ts @@ -12,7 +12,11 @@ export async function readStoredProcedures( ): Promise<(StoredProcedureDefinition & Resource)[]> { const clearMessage = logConsoleProgress(`Querying stored procedures for container ${collectionId}`); try { - if (userContext.authType === AuthType.AAD && !userContext.useSDKOperations && userContext.apiType === "SQL") { + if ( + userContext.authType === AuthType.AAD && + !userContext.features.enableSDKoperations && + userContext.apiType === "SQL" + ) { const rpResponse = await listSqlStoredProcedures( userContext.subscriptionId, userContext.resourceGroup, diff --git a/src/Common/dataAccess/readTriggers.ts b/src/Common/dataAccess/readTriggers.ts index 764f3ace1..dd51db372 100644 --- a/src/Common/dataAccess/readTriggers.ts +++ b/src/Common/dataAccess/readTriggers.ts @@ -13,7 +13,11 @@ export async function readTriggers( ): Promise { const clearMessage = logConsoleProgress(`Querying triggers for container ${collectionId}`); try { - if (userContext.authType === AuthType.AAD && !userContext.useSDKOperations && userContext.apiType === "SQL") { + if ( + userContext.authType === AuthType.AAD && + !userContext.features.enableSDKoperations && + userContext.apiType === "SQL" + ) { const rpResponse = await listSqlTriggers( userContext.subscriptionId, userContext.resourceGroup, diff --git a/src/Common/dataAccess/readUserDefinedFunctions.ts b/src/Common/dataAccess/readUserDefinedFunctions.ts index a55ad0ca6..a103291f9 100644 --- a/src/Common/dataAccess/readUserDefinedFunctions.ts +++ b/src/Common/dataAccess/readUserDefinedFunctions.ts @@ -11,9 +11,9 @@ export async function readUserDefinedFunctions( collectionId: string ): Promise<(UserDefinedFunctionDefinition & Resource)[]> { const clearMessage = logConsoleProgress(`Querying user defined functions for container ${collectionId}`); - const { authType, useSDKOperations, apiType, subscriptionId, resourceGroup, databaseAccount } = userContext; + const { authType, apiType, subscriptionId, resourceGroup, databaseAccount } = userContext; try { - if (authType === AuthType.AAD && !useSDKOperations && apiType === "SQL") { + if (authType === AuthType.AAD && !userContext.features.enableSDKoperations && apiType === "SQL") { const rpResponse = await listSqlUserDefinedFunctions( subscriptionId, resourceGroup, diff --git a/src/Common/dataAccess/updateCollection.ts b/src/Common/dataAccess/updateCollection.ts index 8b4c075e2..5a0006697 100644 --- a/src/Common/dataAccess/updateCollection.ts +++ b/src/Common/dataAccess/updateCollection.ts @@ -33,7 +33,11 @@ export async function updateCollection( const clearMessage = logConsoleProgress(`Updating container ${collectionId}`); try { - if (userContext.authType === AuthType.AAD && !userContext.useSDKOperations && userContext.apiType !== "Tables") { + if ( + userContext.authType === AuthType.AAD && + !userContext.features.enableSDKoperations && + userContext.apiType !== "Tables" + ) { collection = await updateCollectionWithARM(databaseId, collectionId, newCollection); } else { const sdkResponse = await client() diff --git a/src/Common/dataAccess/updateOffer.ts b/src/Common/dataAccess/updateOffer.ts index 88a3355d5..7f3a26da1 100644 --- a/src/Common/dataAccess/updateOffer.ts +++ b/src/Common/dataAccess/updateOffer.ts @@ -56,7 +56,7 @@ export const updateOffer = async (params: UpdateOfferParams): Promise => const clearMessage = logConsoleProgress(`Updating offer for ${offerResourceText}`); try { - if (userContext.authType === AuthType.AAD && !userContext.useSDKOperations) { + if (userContext.authType === AuthType.AAD && !userContext.features.enableSDKoperations) { if (params.collectionId) { updatedOffer = await updateCollectionOfferWithARM(params); } else if (userContext.apiType === "Tables") { diff --git a/src/Common/dataAccess/updateStoredProcedure.ts b/src/Common/dataAccess/updateStoredProcedure.ts index b3cf875a0..6e6d841e6 100644 --- a/src/Common/dataAccess/updateStoredProcedure.ts +++ b/src/Common/dataAccess/updateStoredProcedure.ts @@ -20,9 +20,9 @@ export async function updateStoredProcedure( ): Promise { const clearMessage = logConsoleProgress(`Updating stored procedure ${storedProcedure.id}`); try { - const { authType, useSDKOperations, apiType, subscriptionId, resourceGroup, databaseAccount } = userContext; + const { authType, apiType, subscriptionId, resourceGroup, databaseAccount } = userContext; - if (authType === AuthType.AAD && !useSDKOperations && apiType === "SQL") { + if (authType === AuthType.AAD && !userContext.features.enableSDKoperations && apiType === "SQL") { const getResponse = await getSqlStoredProcedure( subscriptionId, resourceGroup, diff --git a/src/Common/dataAccess/updateTrigger.ts b/src/Common/dataAccess/updateTrigger.ts index 6d5afb4be..56e27a905 100644 --- a/src/Common/dataAccess/updateTrigger.ts +++ b/src/Common/dataAccess/updateTrigger.ts @@ -13,9 +13,9 @@ export async function updateTrigger( trigger: SqlTriggerResource ): Promise { const clearMessage = logConsoleProgress(`Updating trigger ${trigger.id}`); - const { authType, useSDKOperations, apiType, subscriptionId, resourceGroup, databaseAccount } = userContext; + const { authType, apiType, subscriptionId, resourceGroup, databaseAccount } = userContext; try { - if (authType === AuthType.AAD && !useSDKOperations && apiType === "SQL") { + if (authType === AuthType.AAD && !userContext.features.enableSDKoperations && apiType === "SQL") { const getResponse = await getSqlTrigger( subscriptionId, resourceGroup, diff --git a/src/Common/dataAccess/updateUserDefinedFunction.ts b/src/Common/dataAccess/updateUserDefinedFunction.ts index f3b28bf51..21780774b 100644 --- a/src/Common/dataAccess/updateUserDefinedFunction.ts +++ b/src/Common/dataAccess/updateUserDefinedFunction.ts @@ -19,9 +19,9 @@ export async function updateUserDefinedFunction( userDefinedFunction: UserDefinedFunctionDefinition ): Promise { const clearMessage = logConsoleProgress(`Updating user defined function ${userDefinedFunction.id}`); - const { authType, useSDKOperations, apiType, subscriptionId, resourceGroup, databaseAccount } = userContext; + const { authType, apiType, subscriptionId, resourceGroup, databaseAccount } = userContext; try { - if (authType === AuthType.AAD && !useSDKOperations && apiType === "SQL") { + if (authType === AuthType.AAD && !userContext.features.enableSDKoperations && apiType === "SQL") { const getResponse = await getSqlUserDefinedFunction( subscriptionId, resourceGroup, diff --git a/src/Explorer/ContextMenuButtonFactory.tsx b/src/Explorer/ContextMenuButtonFactory.tsx index 8f85ddbdb..426287068 100644 --- a/src/Explorer/ContextMenuButtonFactory.tsx +++ b/src/Explorer/ContextMenuButtonFactory.tsx @@ -44,7 +44,7 @@ export const createDatabaseContextMenu = (container: Explorer, databaseId: strin }, ]; - if (userContext.apiType !== "Tables") { + if (userContext.apiType !== "Tables" || userContext.features.enableSDKoperations) { items.push({ iconSrc: DeleteDatabaseIcon, onClick: () => diff --git a/src/Explorer/SplashScreen/SplashScreen.tsx b/src/Explorer/SplashScreen/SplashScreen.tsx index 31f472754..26ce9d3dc 100644 --- a/src/Explorer/SplashScreen/SplashScreen.tsx +++ b/src/Explorer/SplashScreen/SplashScreen.tsx @@ -3,35 +3,25 @@ */ import { Coachmark, DirectionalHint, Image, Link, Stack, TeachingBubbleContent, Text } from "@fluentui/react"; import { useCarousel } from "hooks/useCarousel"; -import { useTabs } from "hooks/useTabs"; +import { ReactTabKind, useTabs } from "hooks/useTabs"; import * as React from "react"; import { Action } from "Shared/Telemetry/TelemetryConstants"; import { traceOpen } from "Shared/Telemetry/TelemetryProcessor"; -import AddDatabaseIcon from "../../../images/AddDatabase.svg"; -import NewQueryIcon from "../../../images/AddSqlQuery_16x16.svg"; -import NewStoredProcedureIcon from "../../../images/AddStoredProcedure.svg"; -import OpenQueryIcon from "../../../images/BrowseQuery.svg"; import ConnectIcon from "../../../images/Connect_color.svg"; import ContainersIcon from "../../../images/Containers.svg"; import LinkIcon from "../../../images/Link_blue.svg"; import NotebookIcon from "../../../images/notebook/Notebook-resource.svg"; import NotebookColorIcon from "../../../images/Notebooks.svg"; import QuickStartIcon from "../../../images/Quickstart_Lightning.svg"; -import ScaleAndSettingsIcon from "../../../images/Scale_15x15.svg"; import CollectionIcon from "../../../images/tree-collection.svg"; -import { AuthType } from "../../AuthType"; import * as Constants from "../../Common/Constants"; -import * as ViewModels from "../../Contracts/ViewModels"; -import { useSidePanel } from "../../hooks/useSidePanel"; import { userContext } from "../../UserContext"; -import { getCollectionName, getDatabaseName } from "../../Utils/APITypeUtils"; +import { getCollectionName } from "../../Utils/APITypeUtils"; import { FeaturePanelLauncher } from "../Controls/FeaturePanel/FeaturePanelLauncher"; import { DataSamplesUtil } from "../DataSamples/DataSamplesUtil"; import Explorer from "../Explorer"; import * as MostRecentActivity from "../MostRecentActivity/MostRecentActivity"; import { useNotebook } from "../Notebook/useNotebook"; -import { AddDatabasePanel } from "../Panes/AddDatabasePanel/AddDatabasePanel"; -import { BrowseQueriesPane } from "../Panes/BrowseQueriesPane/BrowseQueriesPane"; import { useDatabases } from "../useDatabases"; import { useSelectedNode } from "../useSelectedNode"; @@ -234,103 +224,13 @@ export class SplashScreen extends React.Component { iconSrc: ConnectIcon, title: "Connect", description: "Prefer using your own choice of tooling? Find the connection string you need to connect", - onClick: () => useTabs.getState().openAndActivateConnectTab(), + onClick: () => useTabs.getState().openAndActivateReactTab(ReactTabKind.Connect), }; heroes.push(connectBtn); return heroes; } - private createCommonTaskItems(): SplashScreenItem[] { - const items: SplashScreenItem[] = []; - - if (userContext.authType === AuthType.ResourceToken) { - return items; - } - - if (!useSelectedNode.getState().isDatabaseNodeOrNoneSelected()) { - if (userContext.apiType === "SQL" || userContext.apiType === "Gremlin") { - items.push({ - iconSrc: NewQueryIcon, - onClick: () => { - const selectedCollection: ViewModels.Collection = useSelectedNode.getState().findSelectedCollection(); - selectedCollection && selectedCollection.onNewQueryClick(selectedCollection, undefined); - }, - title: "New SQL Query", - description: undefined, - }); - } else if (userContext.apiType === "Mongo") { - items.push({ - iconSrc: NewQueryIcon, - onClick: () => { - const selectedCollection: ViewModels.Collection = useSelectedNode.getState().findSelectedCollection(); - selectedCollection && selectedCollection.onNewMongoQueryClick(selectedCollection, undefined); - }, - title: "New Query", - description: undefined, - }); - } - - if (userContext.apiType === "SQL") { - items.push({ - iconSrc: OpenQueryIcon, - title: "Open Query", - description: undefined, - onClick: () => - useSidePanel - .getState() - .openSidePanel("Open Saved Queries", ), - }); - } - - if (userContext.apiType !== "Cassandra") { - items.push({ - iconSrc: NewStoredProcedureIcon, - title: "New Stored Procedure", - description: undefined, - onClick: () => { - const selectedCollection: ViewModels.Collection = useSelectedNode.getState().findSelectedCollection(); - selectedCollection && selectedCollection.onNewStoredProcedureClick(selectedCollection, undefined); - }, - }); - } - - /* Scale & Settings */ - const isShared = useDatabases.getState().findSelectedDatabase()?.isDatabaseShared(); - - const label = isShared ? "Settings" : "Scale & Settings"; - items.push({ - iconSrc: ScaleAndSettingsIcon, - title: label, - description: undefined, - onClick: () => { - const selectedCollection: ViewModels.Collection = useSelectedNode.getState().findSelectedCollection(); - selectedCollection && selectedCollection.onSettingsClick(); - }, - }); - } else { - items.push({ - iconSrc: AddDatabaseIcon, - title: "New " + getDatabaseName(), - description: undefined, - onClick: async () => { - const throughputCap = userContext.databaseAccount?.properties.capacity?.totalThroughputLimit; - if (throughputCap && throughputCap !== -1) { - await useDatabases.getState().loadAllOffers(); - } - useSidePanel - .getState() - .openSidePanel( - "New " + getDatabaseName(), - - ); - }, - }); - } - - return items; - } - private decorateOpenCollectionActivity({ databaseId, collectionId }: MostRecentActivity.OpenCollectionItem) { return { iconSrc: CollectionIcon, @@ -372,29 +272,6 @@ export class SplashScreen extends React.Component { }); } - private createTipsItems(): SplashScreenItem[] { - return [ - { - iconSrc: undefined, - title: "Data Modeling", - description: "Learn more about modeling", - onClick: () => window.open(SplashScreen.dataModelingUrl), - }, - { - iconSrc: undefined, - title: "Cost & Throughput Calculation", - description: "Learn more about cost calculation", - onClick: () => window.open(SplashScreen.throughputEstimatorUrl), - }, - { - iconSrc: undefined, - title: "Configure automatic failover", - description: "Learn more about Cosmos DB high-availability", - onClick: () => window.open(SplashScreen.failoverUrl), - }, - ]; - } - private onSplashScreenItemKeyPress(event: React.KeyboardEvent, callback: () => void) { if (event.charCode === Constants.KeyCodes.Space || event.charCode === Constants.KeyCodes.Enter) { callback(); diff --git a/src/Explorer/Tabs/QueryTab/QueryTabComponent.tsx b/src/Explorer/Tabs/QueryTab/QueryTabComponent.tsx index a3146b99d..101cb1dec 100644 --- a/src/Explorer/Tabs/QueryTab/QueryTabComponent.tsx +++ b/src/Explorer/Tabs/QueryTab/QueryTabComponent.tsx @@ -600,56 +600,43 @@ export default class QueryTabComponent extends React.Component { if (queryMetrics) { aggregatedMetrics.documentLoadTime = - queryMetrics.documentLoadTime && this._normalize(queryMetrics.documentLoadTime.totalMilliseconds()) + - this._normalize(aggregatedMetrics.documentLoadTime); + this._normalize(aggregatedMetrics.documentLoadTime); aggregatedMetrics.documentWriteTime = - queryMetrics.documentWriteTime && this._normalize(queryMetrics.documentWriteTime.totalMilliseconds()) + - this._normalize(aggregatedMetrics.documentWriteTime); + this._normalize(aggregatedMetrics.documentWriteTime); aggregatedMetrics.indexHitDocumentCount = - queryMetrics.indexHitDocumentCount && this._normalize(queryMetrics.indexHitDocumentCount) + - this._normalize(aggregatedMetrics.indexHitDocumentCount); + this._normalize(aggregatedMetrics.indexHitDocumentCount); aggregatedMetrics.outputDocumentCount = - queryMetrics.outputDocumentCount && this._normalize(queryMetrics.outputDocumentCount) + this._normalize(aggregatedMetrics.outputDocumentCount); aggregatedMetrics.outputDocumentSize = - queryMetrics.outputDocumentSize && this._normalize(queryMetrics.outputDocumentSize) + this._normalize(aggregatedMetrics.outputDocumentSize); aggregatedMetrics.indexLookupTime = - queryMetrics.indexLookupTime && this._normalize(queryMetrics.indexLookupTime.totalMilliseconds()) + - this._normalize(aggregatedMetrics.indexLookupTime); + this._normalize(aggregatedMetrics.indexLookupTime); aggregatedMetrics.retrievedDocumentCount = - queryMetrics.retrievedDocumentCount && this._normalize(queryMetrics.retrievedDocumentCount) + - this._normalize(aggregatedMetrics.retrievedDocumentCount); + this._normalize(aggregatedMetrics.retrievedDocumentCount); aggregatedMetrics.retrievedDocumentSize = - queryMetrics.retrievedDocumentSize && this._normalize(queryMetrics.retrievedDocumentSize) + - this._normalize(aggregatedMetrics.retrievedDocumentSize); + this._normalize(aggregatedMetrics.retrievedDocumentSize); aggregatedMetrics.vmExecutionTime = - queryMetrics.vmExecutionTime && this._normalize(queryMetrics.vmExecutionTime.totalMilliseconds()) + - this._normalize(aggregatedMetrics.vmExecutionTime); + this._normalize(aggregatedMetrics.vmExecutionTime); aggregatedMetrics.totalQueryExecutionTime = - queryMetrics.totalQueryExecutionTime && this._normalize(queryMetrics.totalQueryExecutionTime.totalMilliseconds()) + - this._normalize(aggregatedMetrics.totalQueryExecutionTime); + this._normalize(aggregatedMetrics.totalQueryExecutionTime); aggregatedMetrics.runtimeExecutionTimes.queryEngineExecutionTime = - aggregatedMetrics.runtimeExecutionTimes && this._normalize(queryMetrics.runtimeExecutionTimes.queryEngineExecutionTime.totalMilliseconds()) + - this._normalize(aggregatedMetrics.runtimeExecutionTimes.queryEngineExecutionTime); + this._normalize(aggregatedMetrics.runtimeExecutionTimes.queryEngineExecutionTime); aggregatedMetrics.runtimeExecutionTimes.systemFunctionExecutionTime = - aggregatedMetrics.runtimeExecutionTimes && this._normalize(queryMetrics.runtimeExecutionTimes.systemFunctionExecutionTime.totalMilliseconds()) + - this._normalize(aggregatedMetrics.runtimeExecutionTimes.systemFunctionExecutionTime); + this._normalize(aggregatedMetrics.runtimeExecutionTimes.systemFunctionExecutionTime); aggregatedMetrics.runtimeExecutionTimes.userDefinedFunctionExecutionTime = - aggregatedMetrics.runtimeExecutionTimes && this._normalize(queryMetrics.runtimeExecutionTimes.userDefinedFunctionExecutionTime.totalMilliseconds()) + - this._normalize(aggregatedMetrics.runtimeExecutionTimes.userDefinedFunctionExecutionTime); + this._normalize(aggregatedMetrics.runtimeExecutionTimes.userDefinedFunctionExecutionTime); } }); diff --git a/src/Explorer/Tabs/Tabs.tsx b/src/Explorer/Tabs/Tabs.tsx index 9d980a44b..1439b2fd2 100644 --- a/src/Explorer/Tabs/Tabs.tsx +++ b/src/Explorer/Tabs/Tabs.tsx @@ -1,4 +1,6 @@ import { CollectionTabKind } from "Contracts/ViewModels"; +import Explorer from "Explorer/Explorer"; +import { SplashScreen } from "Explorer/SplashScreen/SplashScreen"; import { ConnectTab } from "Explorer/Tabs/ConnectTab"; import { useTeachingBubble } from "hooks/useTeachingBubble"; import ko from "knockout"; @@ -6,28 +8,33 @@ import React, { MutableRefObject, useEffect, useRef, useState } from "react"; import loadingIcon from "../../../images/circular_loader_black_16x16.gif"; import errorIcon from "../../../images/close-black.svg"; import { useObservable } from "../../hooks/useObservable"; -import { useTabs } from "../../hooks/useTabs"; +import { ReactTabKind, useTabs } from "../../hooks/useTabs"; import TabsBase from "./TabsBase"; type Tab = TabsBase | (TabsBase & { render: () => JSX.Element }); -export const Tabs = (): JSX.Element => { - const { openedTabs, activeTab } = useTabs(); - const isConnectTabOpen = useTabs((state) => state.isConnectTabOpen); - const isConnectTabActive = useTabs((state) => state.isConnectTabActive); +interface TabsProps { + explorer: Explorer; +} + +export const Tabs = ({ explorer }: TabsProps): JSX.Element => { + const { openedTabs, openedReactTabs, activeTab, activeReactTab } = useTabs(); + return (
- {isConnectTabActive && } + {activeReactTab !== undefined && getReactTabContent(activeReactTab, explorer)} {openedTabs.map((tab) => ( ))} @@ -37,7 +44,7 @@ export const Tabs = (): JSX.Element => { ); }; -function TabNav({ tab, active }: { tab: Tab; active: boolean }) { +function TabNav({ tab, active, tabKind }: { tab?: Tab; active: boolean; tabKind?: ReactTabKind }) { const [hovering, setHovering] = useState(false); const focusTab = useRef() as MutableRefObject; const tabId = tab ? tab.tabId : "connect"; @@ -51,8 +58,20 @@ function TabNav({ tab, active }: { tab: Tab; active: boolean }) {
  • setHovering(true)} onMouseLeave={() => setHovering(false)} - onClick={() => (tab ? tab.onTabClick() : useTabs.getState().activateConnectTab())} - onKeyPress={({ nativeEvent: e }) => (tab ? tab.onKeyPressActivate(undefined, e) : onKeyPressConnectTab(e))} + onClick={() => { + if (tab) { + tab.onTabClick(); + } else if (tabKind !== undefined) { + useTabs.getState().activateReactTab(tabKind); + } + }} + onKeyPress={({ nativeEvent: e }) => { + if (tab) { + tab.onKeyPressActivate(undefined, e); + } else if (tabKind !== undefined) { + onKeyPressReactTab(e, tabKind); + } + }} className={active ? "active tabList" : "tabList"} title={useObservable(tab?.tabPath || ko.observable(""))} aria-selected={active} @@ -65,16 +84,18 @@ function TabNav({ tab, active }: { tab: Tab; active: boolean }) {
    - + {useObservable(tab?.isExecutionError || ko.observable(false)) && } {useObservable(tab?.isExecuting || ko.observable(false)) && ( Loading )} - {useObservable(tab?.tabTitle || ko.observable("Connect"))} - - - + {useObservable(tab?.tabTitle || ko.observable(ReactTabKind[tabKind]))} + {tabKind !== ReactTabKind.Home && ( + + + + )}
    @@ -82,14 +103,24 @@ function TabNav({ tab, active }: { tab: Tab; active: boolean }) { ); } -const CloseButton = ({ tab, active, hovering }: { tab: Tab; active: boolean; hovering: boolean }) => ( +const CloseButton = ({ + tab, + active, + hovering, + tabKind, +}: { + tab: Tab; + active: boolean; + hovering: boolean; + tabKind?: ReactTabKind; +}) => ( (tab ? tab.onCloseTabButtonClick() : useTabs.getState().closeConnectTab())} + onClick={() => (tab ? tab.onCloseTabButtonClick() : useTabs.getState().closeReactTab(tabKind))} tabIndex={active ? 0 : undefined} onKeyPress={({ nativeEvent: e }) => tab.onKeyPressClose(undefined, e)} > @@ -144,9 +175,20 @@ function TabPane({ tab, active }: { tab: Tab; active: boolean }) { return
    ; } -const onKeyPressConnectTab = (e: KeyboardEvent): void => { +const onKeyPressReactTab = (e: KeyboardEvent, tabKind: ReactTabKind): void => { if (e.key === "Enter" || e.key === "Space") { - useTabs.getState().activateConnectTab(); + useTabs.getState().activateReactTab(tabKind); e.stopPropagation(); } }; + +const getReactTabContent = (activeReactTab: ReactTabKind, explorer: Explorer): JSX.Element => { + switch (activeReactTab) { + case ReactTabKind.Connect: + return ; + case ReactTabKind.Home: + return ; + default: + throw Error(`Unsupported tab kind ${ReactTabKind[activeReactTab]}`); + } +}; diff --git a/src/Explorer/Tutorials/QuickstartTutorial.tsx b/src/Explorer/Tutorials/QuickstartTutorial.tsx index 5fcb44026..516a3a518 100644 --- a/src/Explorer/Tutorials/QuickstartTutorial.tsx +++ b/src/Explorer/Tutorials/QuickstartTutorial.tsx @@ -1,9 +1,9 @@ import { Link, Stack, TeachingBubble, Text } from "@fluentui/react"; -import { useTabs } from "hooks/useTabs"; +import { ReactTabKind, useTabs } from "hooks/useTabs"; import { useTeachingBubble } from "hooks/useTeachingBubble"; import React from "react"; import { Action } from "Shared/Telemetry/TelemetryConstants"; -import { traceCancel } from "Shared/Telemetry/TelemetryProcessor"; +import { traceCancel, traceSuccess } from "Shared/Telemetry/TelemetryProcessor"; export const QuickstartTutorial: React.FC = (): JSX.Element => { const { step, isSampleDBExpanded, isDocumentsTabOpened, sampleCollection, setStep } = useTeachingBubble(); @@ -146,7 +146,10 @@ export const QuickstartTutorial: React.FC = (): JSX.Element => { hasCloseButton primaryButtonProps={{ text: "Launch connect", - onClick: () => useTabs.getState().openAndActivateConnectTab(), + onClick: () => { + traceSuccess(Action.CompleteUITour); + useTabs.getState().openAndActivateReactTab(ReactTabKind.Connect); + }, }} secondaryButtonProps={{ text: "Previous", diff --git a/src/Main.tsx b/src/Main.tsx index b68254204..20a7340ee 100644 --- a/src/Main.tsx +++ b/src/Main.tsx @@ -46,12 +46,10 @@ import "./Explorer/Menus/NotificationConsole/NotificationConsole.less"; import { NotificationConsole } from "./Explorer/Menus/NotificationConsole/NotificationConsoleComponent"; import "./Explorer/Panes/PanelComponent.less"; import { SidePanel } from "./Explorer/Panes/PanelContainerComponent"; -import { SplashScreen } from "./Explorer/SplashScreen/SplashScreen"; import "./Explorer/SplashScreen/SplashScreen.less"; import { Tabs } from "./Explorer/Tabs/Tabs"; import { useConfig } from "./hooks/useConfig"; import { useKnockoutExplorer } from "./hooks/useKnockoutExplorer"; -import { useTabs } from "./hooks/useTabs"; import "./Libs/jquery"; import "./Shared/appInsights"; @@ -59,8 +57,6 @@ initializeIcons(); const App: React.FunctionComponent = () => { const [isLeftPaneExpanded, setIsLeftPaneExpanded] = useState(true); - const openedTabs = useTabs((state) => state.openedTabs); - const isConnectTabOpen = useTabs((state) => state.isConnectTabOpen); const isCarouselOpen = useCarousel((state) => state.shouldOpen); const config = useConfig(); @@ -104,9 +100,7 @@ const App: React.FunctionComponent = () => { {/* Collections Tree Collapsed - End */}
  • - {/* Collections Tree - End */} - {openedTabs.length === 0 && !isConnectTabOpen && } - +
    {/* Collections Tree and Tabs - End */}
    void; activateNewTab: (tab: TabsBase) => void; + activateReactTab: (tabkind: ReactTabKind) => void; updateTab: (tab: TabsBase) => void; getTabs: (tabKind: ViewModels.CollectionTabKind, comparator?: (tab: TabsBase) => boolean) => TabsBase[]; refreshActiveTab: (comparator: (tab: TabsBase) => boolean) => void; closeTabsByComparator: (comparator: (tab: TabsBase) => boolean) => void; closeTab: (tab: TabsBase) => void; closeAllNotebookTabs: (hardClose: boolean) => void; - activateConnectTab: () => void; - openAndActivateConnectTab: () => void; - closeConnectTab: () => void; + openAndActivateReactTab: (tabKind: ReactTabKind) => void; + closeReactTab: (tabKind: ReactTabKind) => void; +} + +export enum ReactTabKind { + Connect, + Home, } export const useTabs: UseStore = create((set, get) => ({ openedTabs: [], + openedReactTabs: [ReactTabKind.Home], activeTab: undefined, - isConnectTabOpen: false, - isConnectTabActive: false, + activeReactTab: ReactTabKind.Home, activateTab: (tab: TabsBase): void => { if (get().openedTabs.some((openedTab) => openedTab.tabId === tab.tabId)) { - set({ activeTab: tab, isConnectTabActive: false }); + set({ activeTab: tab, activeReactTab: undefined }); tab.onActivate(); } }, activateNewTab: (tab: TabsBase): void => { - set((state) => ({ openedTabs: [...state.openedTabs, tab], activeTab: tab, isConnectTabActive: false })); + set((state) => ({ openedTabs: [...state.openedTabs, tab], activeTab: tab, activeReactTab: undefined })); tab.onActivate(); }, + activateReactTab: (tabKind: ReactTabKind): void => set({ activeTab: undefined, activeReactTab: tabKind }), updateTab: (tab: TabsBase) => { if (get().activeTab?.tabId === tab.tabId) { set({ activeTab: tab }); @@ -73,7 +79,7 @@ export const useTabs: UseStore = create((set, get) => ({ return true; }); if (updatedTabs.length === 0) { - set({ activeTab: undefined, isConnectTabActive: get().isConnectTabOpen }); + set({ activeTab: undefined, activeReactTab: ReactTabKind.Home }); } if (tab.tabId === activeTab.tabId && tabIndex !== -1) { @@ -111,21 +117,27 @@ export const useTabs: UseStore = create((set, get) => ({ }); if (get().openedTabs.length === 0) { - set({ activeTab: undefined, isConnectTabActive: get().isConnectTabOpen }); + set({ activeTab: undefined, activeReactTab: ReactTabKind.Home }); } } }, - activateConnectTab: () => { - if (get().isConnectTabOpen) { - set({ isConnectTabActive: true, activeTab: undefined }); + openAndActivateReactTab: (tabKind: ReactTabKind) => { + if (get().openedReactTabs.indexOf(tabKind) === -1) { + set((state) => ({ + openedReactTabs: [...state.openedReactTabs, tabKind], + })); } + + set({ activeTab: undefined, activeReactTab: tabKind }); }, - openAndActivateConnectTab: () => set({ isConnectTabActive: true, isConnectTabOpen: true, activeTab: undefined }), - closeConnectTab: () => { - const { isConnectTabActive, openedTabs } = get(); - if (isConnectTabActive && openedTabs?.length > 0) { - set({ activeTab: openedTabs[0] }); + closeReactTab: (tabKind: ReactTabKind) => { + const { activeReactTab, openedTabs, openedReactTabs } = get(); + if (activeReactTab === tabKind) { + openedTabs?.length > 0 + ? set({ activeTab: openedTabs[0], activeReactTab: undefined }) + : set({ activeTab: undefined, activeReactTab: openedReactTabs[0] }); } - set({ isConnectTabActive: false, isConnectTabOpen: false }); + + set({ openedReactTabs: openedReactTabs.filter((tab: ReactTabKind) => tabKind !== tab) }); }, }));