diff --git a/.github/dependabot.yml b/.github/_dependabot.yml similarity index 100% rename from .github/dependabot.yml rename to .github/_dependabot.yml diff --git a/.github/workflows/test-installers.yml b/.github/workflows/test-installers.yml index a4494080753..4d1540c9518 100644 --- a/.github/workflows/test-installers.yml +++ b/.github/workflows/test-installers.yml @@ -46,7 +46,10 @@ jobs: run: echo "[Evergreen Task](${{ github.event.inputs.evergreen_task_url }})" >> $GITHUB_STEP_SUMMARY test: name: ${{ matrix.package }} test ${{ matrix.test }} (${{ matrix.hadron-distribution }}) - timeout-minutes: 30 + # Windows specifically takes A TON of time to bootstrap itself before being + # able to run tests, so we're setting the timeout pretty high to account for + # that + timeout-minutes: 60 strategy: fail-fast: false matrix: @@ -174,7 +177,11 @@ jobs: runs-on: ${{ matrix.runs-on }} container: ${{ matrix.container }} env: - DEBUG: compass:smoketests:* + DEBUG: compass:smoketests:*,compass-e2e-tests:* + # Similar to total task timeout, setting these higher than the default + # value to account for very slow windows machines + COMPASS_E2E_MOCHA_TIMEOUT: 720000 # 12min + COMPASS_E2E_WEBDRIVER_WAITFOR_TIMEOUT: 360000 # 6min steps: - name: Checkout uses: actions/checkout@v2 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 8621680d04d..1e8129bd853 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -42,7 +42,7 @@ To enable the Chrome DevTools for the Electron renderer processes, click "Settin > [!NOTE] > For documentation regarding how to write plugin packages, check out the -> [hadron-app-registry](./packages/hadron-app-registry/README.md) documentation. +> [@mongodb-js/compass-app-registry](./packages/compass-app-registry/README.md) documentation. To run npm scripts inside specific workspaces in the monorepo you can use either `lerna --scope` or `npm --workspace` command line arguments. As an example, to run all tests in one plugin that you are working on such as the `compass-aggregations` plugin, you can run `npm run test --workspace packages/compass-aggregation` or `lerna run test --scope @mongodb-js/compass-aggregations` commands diff --git a/README.md b/README.md index b05d0667a2c..397e734975a 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,7 @@ Is there anything else you’d like to see in Compass? Let us know by submitting ### Shared Libraries and Build Tools - [**@mongodb-js/atlas-service**](packages/atlas-service): Service to handle Atlas sign in and API requests +- [**@mongodb-js/compass-app-registry**](packages/compass-app-registry): Compass App Registry - [**@mongodb-js/compass-components**](packages/compass-components): React Components used in Compass - [**@mongodb-js/compass-connection-import-export**](packages/compass-connection-import-export): UI for Compass connection import/export - [**@mongodb-js/compass-connections**](packages/compass-connections): Manage your MongoDB connections and connect in Compass @@ -67,7 +68,6 @@ Is there anything else you’d like to see in Compass? Let us know by submitting - [**bson-transpilers**](packages/bson-transpilers): Source to source compilers using ANTLR - [**compass-e2e-tests**](packages/compass-e2e-tests): E2E test suite for Compass app that follows smoke tests / feature testing matrix - [**compass-preferences-model**](packages/compass-preferences-model): Compass preferences model -- [**hadron-app-registry**](packages/hadron-app-registry): Hadron App Registry - [**hadron-build**](packages/hadron-build): Tooling for Hadron apps like Compass - [**hadron-document**](packages/hadron-document): Hadron Document - [**hadron-ipc**](packages/hadron-ipc): Simplified IPC for electron apps. diff --git a/THIRD-PARTY-NOTICES.md b/THIRD-PARTY-NOTICES.md index 601506316d8..71cd855d15c 100644 --- a/THIRD-PARTY-NOTICES.md +++ b/THIRD-PARTY-NOTICES.md @@ -1,5 +1,5 @@ The following third-party software is used by and included in **Mongodb Compass**. -This document was automatically generated on Mon Jun 16 2025. +This document was automatically generated on Thu Jun 19 2025. ## List of dependencies diff --git a/configs/eslint-config-compass/index.js b/configs/eslint-config-compass/index.js index a7f2479d9b6..21572f894e9 100644 --- a/configs/eslint-config-compass/index.js +++ b/configs/eslint-config-compass/index.js @@ -46,7 +46,7 @@ const tsxRules = { 'react-hooks/exhaustive-deps': [ 'warn', { - additionalHooks: 'useTrackOnChange', + additionalHooks: '(useTrackOnChange|useContextMenuItems)', }, ], }; diff --git a/configs/testing-library-compass/.depcheckrc b/configs/testing-library-compass/.depcheckrc index 18b9386cedf..18e3a995825 100644 --- a/configs/testing-library-compass/.depcheckrc +++ b/configs/testing-library-compass/.depcheckrc @@ -8,6 +8,7 @@ ignores: # dependency will introduce a circular one in our dependency tree, as it's only # used for testing and doesn't require compilation, we're escaping the # recursiveness issue by just not including those in the package.json + - '@mongodb-js/compass-app-registry' - '@mongodb-js/compass-logging' - '@mongodb-js/compass-telemetry' - '@mongodb-js/connection-info' @@ -15,7 +16,6 @@ ignores: - '@mongodb-js/compass-components' - '@mongodb-js/connection-storage' - 'compass-preferences-model' - - 'hadron-app-registry' - 'mongodb-data-service' ignore-patterns: - 'dist' diff --git a/configs/testing-library-compass/src/index.tsx b/configs/testing-library-compass/src/index.tsx index 6f3bf3bb79d..05f40da4ec6 100644 --- a/configs/testing-library-compass/src/index.tsx +++ b/configs/testing-library-compass/src/index.tsx @@ -60,11 +60,14 @@ import { import CompassConnections, { ConnectFnProvider, } from '@mongodb-js/compass-connections/src/index'; -import type { HadronPluginComponent, HadronPlugin } from 'hadron-app-registry'; +import type { + CompassPluginComponent, + CompassPlugin, +} from '@mongodb-js/compass-app-registry'; import AppRegistry, { AppRegistryProvider, GlobalAppRegistryProvider, -} from 'hadron-app-registry'; +} from '@mongodb-js/compass-app-registry'; import { expect } from 'chai'; import { Provider } from 'react-redux'; import ConnectionString from 'mongodb-connection-string-url'; @@ -560,9 +563,9 @@ async function renderHookWithActiveConnection( function createPluginWrapper< Props, ServiceLocators extends Record unknown>, - PluginContext extends HadronPlugin + PluginContext extends CompassPlugin >( - Plugin: HadronPluginComponent, + Plugin: CompassPluginComponent, initialPluginProps?: Props, ReactTestingLibraryWrapper: ComponentWithChildren = EmptyWrapper ) { @@ -585,9 +588,9 @@ function createPluginWrapper< function createPluginTestHelpers< Props, ServiceLocators extends Record unknown>, - PluginContext extends HadronPlugin + PluginContext extends CompassPlugin >( - Plugin: HadronPluginComponent, + Plugin: CompassPluginComponent, defaultInitialPluginProps?: Props ) { return { diff --git a/docs/tracking-plan.md b/docs/tracking-plan.md index 5ff05d555e6..8facbb105bd 100644 --- a/docs/tracking-plan.md +++ b/docs/tracking-plan.md @@ -6,7 +6,7 @@ > the tracking plan for the specific Compass version you can use the following > URL: `https://github.com/mongodb-js/compass/blob//docs/tracking-plan.md` -Generated on Mon, Jun 16, 2025 +Generated on Thu, Jun 19, 2025 ## Table of Contents diff --git a/package-lock.json b/package-lock.json index d0ac9559e2a..23553f218ea 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8310,6 +8310,10 @@ "resolved": "packages/compass-aggregations", "link": true }, + "node_modules/@mongodb-js/compass-app-registry": { + "resolved": "packages/compass-app-registry", + "link": true + }, "node_modules/@mongodb-js/compass-app-stores": { "resolved": "packages/compass-app-stores", "link": true @@ -8334,6 +8338,10 @@ "resolved": "packages/compass-connections-navigation", "link": true }, + "node_modules/@mongodb-js/compass-context-menu": { + "resolved": "packages/compass-context-menu", + "link": true + }, "node_modules/@mongodb-js/compass-crud": { "resolved": "packages/compass-crud", "link": true @@ -24876,10 +24884,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/hadron-app-registry": { - "resolved": "packages/hadron-app-registry", - "link": true - }, "node_modules/hadron-build": { "resolved": "packages/hadron-build", "link": true @@ -42869,10 +42873,11 @@ }, "packages/atlas-service": { "name": "@mongodb-js/atlas-service", - "version": "0.45.0", + "version": "0.46.0", "license": "SSPL", "dependencies": { - "@mongodb-js/compass-components": "^1.38.1", + "@mongodb-js/compass-app-registry": "^9.4.11", + "@mongodb-js/compass-components": "^1.39.0", "@mongodb-js/compass-logging": "^1.7.2", "@mongodb-js/compass-telemetry": "^1.10.0", "@mongodb-js/compass-user-data": "^0.7.2", @@ -42881,9 +42886,8 @@ "@mongodb-js/devtools-connect": "^3.7.2", "@mongodb-js/devtools-proxy-support": "^0.4.4", "@mongodb-js/oidc-plugin": "^1.1.7", - "compass-preferences-model": "^2.40.2", + "compass-preferences-model": "^2.41.0", "electron": "^36.4.0", - "hadron-app-registry": "^9.4.11", "hadron-ipc": "^3.5.2", "lodash": "^4.17.21", "react": "^17.0.2", @@ -43007,46 +43011,47 @@ "devDependencies": { "@electron/rebuild": "^4.0.1", "@electron/remote": "^2.1.2", - "@mongodb-js/atlas-service": "^0.45.0", - "@mongodb-js/compass-aggregations": "^9.62.0", - "@mongodb-js/compass-app-stores": "^7.46.0", - "@mongodb-js/compass-collection": "^4.59.0", - "@mongodb-js/compass-components": "^1.38.1", - "@mongodb-js/compass-connection-import-export": "^0.56.0", - "@mongodb-js/compass-connections": "^1.60.0", - "@mongodb-js/compass-crud": "^13.60.0", - "@mongodb-js/compass-data-modeling": "^1.11.0", - "@mongodb-js/compass-databases-collections": "^1.59.0", - "@mongodb-js/compass-explain-plan": "^6.60.0", - "@mongodb-js/compass-export-to-language": "^9.36.0", - "@mongodb-js/compass-field-store": "^9.35.0", - "@mongodb-js/compass-find-in-page": "^4.39.2", - "@mongodb-js/compass-generative-ai": "^0.40.0", - "@mongodb-js/compass-global-writes": "^1.19.0", - "@mongodb-js/compass-import-export": "^7.59.0", - "@mongodb-js/compass-indexes": "^5.59.0", - "@mongodb-js/compass-intercom": "^0.24.2", + "@mongodb-js/atlas-service": "^0.46.0", + "@mongodb-js/compass-aggregations": "^9.63.0", + "@mongodb-js/compass-app-registry": "^9.4.11", + "@mongodb-js/compass-app-stores": "^7.47.0", + "@mongodb-js/compass-collection": "^4.60.0", + "@mongodb-js/compass-components": "^1.39.0", + "@mongodb-js/compass-connection-import-export": "^0.57.0", + "@mongodb-js/compass-connections": "^1.61.0", + "@mongodb-js/compass-crud": "^13.61.0", + "@mongodb-js/compass-data-modeling": "^1.12.0", + "@mongodb-js/compass-databases-collections": "^1.60.0", + "@mongodb-js/compass-explain-plan": "^6.61.0", + "@mongodb-js/compass-export-to-language": "^9.37.0", + "@mongodb-js/compass-field-store": "^9.36.0", + "@mongodb-js/compass-find-in-page": "^4.40.0", + "@mongodb-js/compass-generative-ai": "^0.41.0", + "@mongodb-js/compass-global-writes": "^1.20.0", + "@mongodb-js/compass-import-export": "^7.60.0", + "@mongodb-js/compass-indexes": "^5.60.0", + "@mongodb-js/compass-intercom": "^0.25.0", "@mongodb-js/compass-logging": "^1.7.2", - "@mongodb-js/compass-query-bar": "^8.61.0", - "@mongodb-js/compass-saved-aggregations-queries": "^1.60.0", - "@mongodb-js/compass-schema": "^6.61.0", - "@mongodb-js/compass-schema-validation": "^6.60.0", - "@mongodb-js/compass-serverstats": "^16.59.0", - "@mongodb-js/compass-settings": "^0.58.0", - "@mongodb-js/compass-shell": "^3.59.0", - "@mongodb-js/compass-sidebar": "^5.60.0", + "@mongodb-js/compass-query-bar": "^8.62.0", + "@mongodb-js/compass-saved-aggregations-queries": "^1.61.0", + "@mongodb-js/compass-schema": "^6.62.0", + "@mongodb-js/compass-schema-validation": "^6.61.0", + "@mongodb-js/compass-serverstats": "^16.60.0", + "@mongodb-js/compass-settings": "^0.59.0", + "@mongodb-js/compass-shell": "^3.60.0", + "@mongodb-js/compass-sidebar": "^5.61.0", "@mongodb-js/compass-telemetry": "^1.10.0", "@mongodb-js/compass-utils": "^0.9.2", - "@mongodb-js/compass-welcome": "^0.58.0", - "@mongodb-js/compass-workspaces": "^0.41.0", + "@mongodb-js/compass-welcome": "^0.59.0", + "@mongodb-js/compass-workspaces": "^0.42.0", "@mongodb-js/connection-info": "^0.15.2", - "@mongodb-js/connection-storage": "^0.35.0", + "@mongodb-js/connection-storage": "^0.36.0", "@mongodb-js/devtools-proxy-support": "^0.4.4", "@mongodb-js/eslint-config-compass": "^1.3.10", "@mongodb-js/get-os-info": "^0.4.0", "@mongodb-js/mocha-config-compass": "^1.6.8", "@mongodb-js/mongodb-downloader": "^0.3.7", - "@mongodb-js/my-queries-storage": "^0.27.3", + "@mongodb-js/my-queries-storage": "^0.28.0", "@mongodb-js/prettier-config-compass": "^1.2.8", "@mongodb-js/sbom-tools": "^0.7.2", "@mongodb-js/signing-utils": "^0.3.8", @@ -43059,7 +43064,7 @@ "chai": "^4.3.4", "chalk": "^4.1.2", "clean-stack": "^2.0.0", - "compass-preferences-model": "^2.40.2", + "compass-preferences-model": "^2.41.0", "cross-spawn": "^7.0.5", "debug": "^4.3.4", "depcheck": "^1.4.1", @@ -43069,7 +43074,6 @@ "electron-mocha": "^12.2.0", "ensure-error": "^3.0.1", "glob": "^10.2.5", - "hadron-app-registry": "^9.4.11", "hadron-build": "^25.8.2", "hadron-ipc": "^3.5.2", "make-fetch-happen": "^10.2.1", @@ -43098,7 +43102,7 @@ }, "packages/compass-aggregations": { "name": "@mongodb-js/compass-aggregations", - "version": "9.62.0", + "version": "9.63.0", "license": "SSPL", "dependencies": { "@babel/generator": "^7.19.5", @@ -43107,26 +43111,26 @@ "@dnd-kit/core": "^6.0.7", "@dnd-kit/sortable": "^7.0.2", "@dnd-kit/utilities": "^3.2.1", - "@mongodb-js/atlas-service": "^0.45.0", - "@mongodb-js/compass-app-stores": "^7.46.0", - "@mongodb-js/compass-collection": "^4.59.0", - "@mongodb-js/compass-components": "^1.38.1", - "@mongodb-js/compass-connections": "^1.60.0", - "@mongodb-js/compass-crud": "^13.60.0", - "@mongodb-js/compass-editor": "^0.40.2", - "@mongodb-js/compass-field-store": "^9.35.0", - "@mongodb-js/compass-generative-ai": "^0.40.0", + "@mongodb-js/atlas-service": "^0.46.0", + "@mongodb-js/compass-app-registry": "^9.4.11", + "@mongodb-js/compass-app-stores": "^7.47.0", + "@mongodb-js/compass-collection": "^4.60.0", + "@mongodb-js/compass-components": "^1.39.0", + "@mongodb-js/compass-connections": "^1.61.0", + "@mongodb-js/compass-crud": "^13.61.0", + "@mongodb-js/compass-editor": "^0.41.0", + "@mongodb-js/compass-field-store": "^9.36.0", + "@mongodb-js/compass-generative-ai": "^0.41.0", "@mongodb-js/compass-logging": "^1.7.2", "@mongodb-js/compass-telemetry": "^1.10.0", "@mongodb-js/compass-utils": "^0.9.2", - "@mongodb-js/compass-workspaces": "^0.41.0", + "@mongodb-js/compass-workspaces": "^0.42.0", "@mongodb-js/explain-plan-helper": "^1.4.10", "@mongodb-js/mongodb-constants": "^0.11.0", - "@mongodb-js/my-queries-storage": "^0.27.3", + "@mongodb-js/my-queries-storage": "^0.28.0", "@mongodb-js/shell-bson-parser": "^1.2.0", "bson": "^6.10.3", - "compass-preferences-model": "^2.40.2", - "hadron-app-registry": "^9.4.11", + "compass-preferences-model": "^2.41.0", "hadron-document": "^8.8.12", "hadron-type-checker": "^7.4.10", "lodash": "^4.17.21", @@ -43134,7 +43138,7 @@ "mongodb-collection-model": "^5.29.2", "mongodb-data-service": "^22.28.2", "mongodb-database-model": "^2.29.2", - "mongodb-instance-model": "^12.32.2", + "mongodb-instance-model": "^12.33.0", "mongodb-ns": "^2.4.2", "mongodb-query-parser": "^4.3.0", "mongodb-schema": "^12.6.2", @@ -43329,20 +43333,77 @@ "node": ">=12" } }, + "packages/compass-app-registry": { + "name": "@mongodb-js/compass-app-registry", + "version": "9.4.11", + "license": "SSPL", + "dependencies": { + "eventemitter3": "^4.0.0", + "react": "^17.0.2", + "react-redux": "^8.1.3", + "redux": "^4.2.1", + "reflux": "^0.4.1" + }, + "devDependencies": { + "@mongodb-js/eslint-config-compass": "^1.3.10", + "@mongodb-js/mocha-config-compass": "^1.6.8", + "@mongodb-js/prettier-config-compass": "^1.2.8", + "@mongodb-js/testing-library-compass": "^1.3.2", + "@mongodb-js/tsconfig-compass": "^1.2.8", + "@types/chai": "^4.2.21", + "@types/mocha": "^9.0.0", + "@types/reflux": "^6.4.3", + "chai": "^4.1.2", + "depcheck": "^1.4.1", + "mocha": "^10.2.0", + "sinon": "^9.0.0", + "typescript": "^5.0.4" + } + }, + "packages/compass-app-registry/node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "packages/compass-app-registry/node_modules/sinon": { + "version": "9.2.4", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-9.2.4.tgz", + "integrity": "sha512-zljcULZQsJxVra28qIAL6ow1Z9tpattkCTEJR4RBP3TGc00FcttsP5pK284Nas5WjMZU5Yzy3kAIp3B3KRf5Yg==", + "deprecated": "16.1.1", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@sinonjs/commons": "^1.8.1", + "@sinonjs/fake-timers": "^6.0.1", + "@sinonjs/samsam": "^5.3.1", + "diff": "^4.0.2", + "nise": "^4.0.4", + "supports-color": "^7.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/sinon" + } + }, "packages/compass-app-stores": { "name": "@mongodb-js/compass-app-stores", - "version": "7.46.0", + "version": "7.47.0", "license": "SSPL", "dependencies": { - "@mongodb-js/compass-components": "^1.38.1", - "@mongodb-js/compass-connections": "^1.60.0", + "@mongodb-js/compass-app-registry": "^9.4.11", + "@mongodb-js/compass-components": "^1.39.0", + "@mongodb-js/compass-connections": "^1.61.0", "@mongodb-js/compass-logging": "^1.7.2", "@mongodb-js/connection-info": "^0.15.2", - "compass-preferences-model": "^2.40.2", - "hadron-app-registry": "^9.4.11", + "compass-preferences-model": "^2.41.0", "mongodb-collection-model": "^5.29.2", "mongodb-database-model": "^2.29.2", - "mongodb-instance-model": "^12.32.2", + "mongodb-instance-model": "^12.33.0", "mongodb-ns": "^2.4.2", "react": "^17.0.2" }, @@ -43394,19 +43455,19 @@ }, "packages/compass-collection": { "name": "@mongodb-js/compass-collection", - "version": "4.59.0", + "version": "4.60.0", "license": "SSPL", "dependencies": { - "@mongodb-js/compass-app-stores": "^7.46.0", - "@mongodb-js/compass-components": "^1.38.1", - "@mongodb-js/compass-connections": "^1.60.0", + "@mongodb-js/compass-app-registry": "^9.4.11", + "@mongodb-js/compass-app-stores": "^7.47.0", + "@mongodb-js/compass-components": "^1.39.0", + "@mongodb-js/compass-connections": "^1.61.0", "@mongodb-js/compass-logging": "^1.7.2", "@mongodb-js/compass-telemetry": "^1.10.0", - "@mongodb-js/compass-workspaces": "^0.41.0", + "@mongodb-js/compass-workspaces": "^0.42.0", "@mongodb-js/connection-info": "^0.15.2", "@mongodb-js/mongodb-constants": "^0.11.0", - "compass-preferences-model": "^2.40.2", - "hadron-app-registry": "^9.4.11", + "compass-preferences-model": "^2.41.0", "mongodb-collection-model": "^5.29.2", "mongodb-ns": "^2.4.2", "react": "^17.0.2", @@ -43475,7 +43536,7 @@ }, "packages/compass-components": { "name": "@mongodb-js/compass-components", - "version": "1.38.1", + "version": "1.39.0", "license": "SSPL", "dependencies": { "@dnd-kit/core": "^6.0.7", @@ -43522,6 +43583,7 @@ "@leafygreen-ui/tokens": "^2.11.3", "@leafygreen-ui/tooltip": "^13.0.2", "@leafygreen-ui/typography": "^20.0.2", + "@mongodb-js/compass-context-menu": "^0.0.1", "@react-aria/interactions": "^3.9.1", "@react-aria/utils": "^3.13.1", "@react-aria/visually-hidden": "^3.3.1", @@ -43721,13 +43783,13 @@ }, "packages/compass-connection-import-export": { "name": "@mongodb-js/compass-connection-import-export", - "version": "0.56.0", + "version": "0.57.0", "license": "SSPL", "dependencies": { - "@mongodb-js/compass-components": "^1.38.1", - "@mongodb-js/compass-connections": "^1.60.0", - "@mongodb-js/connection-storage": "^0.35.0", - "compass-preferences-model": "^2.40.2", + "@mongodb-js/compass-components": "^1.39.0", + "@mongodb-js/compass-connections": "^1.61.0", + "@mongodb-js/connection-storage": "^0.36.0", + "compass-preferences-model": "^2.41.0", "hadron-ipc": "^3.5.2", "react": "^17.0.2" }, @@ -43780,19 +43842,19 @@ }, "packages/compass-connections": { "name": "@mongodb-js/compass-connections", - "version": "1.60.0", + "version": "1.61.0", "license": "SSPL", "dependencies": { - "@mongodb-js/compass-components": "^1.38.1", + "@mongodb-js/compass-app-registry": "^9.4.11", + "@mongodb-js/compass-components": "^1.39.0", "@mongodb-js/compass-logging": "^1.7.2", "@mongodb-js/compass-telemetry": "^1.10.0", "@mongodb-js/compass-utils": "^0.9.2", - "@mongodb-js/connection-form": "^1.52.3", + "@mongodb-js/connection-form": "^1.53.0", "@mongodb-js/connection-info": "^0.15.2", - "@mongodb-js/connection-storage": "^0.35.0", + "@mongodb-js/connection-storage": "^0.36.0", "bson": "^6.10.3", - "compass-preferences-model": "^2.40.2", - "hadron-app-registry": "^9.4.11", + "compass-preferences-model": "^2.41.0", "lodash": "^4.17.21", "mongodb": "^6.16.0", "mongodb-build-info": "^1.7.2", @@ -43829,15 +43891,15 @@ }, "packages/compass-connections-navigation": { "name": "@mongodb-js/compass-connections-navigation", - "version": "1.59.0", + "version": "1.60.0", "license": "SSPL", "dependencies": { - "@mongodb-js/compass-components": "^1.38.1", - "@mongodb-js/compass-connections": "^1.60.0", - "@mongodb-js/compass-workspaces": "^0.41.0", - "@mongodb-js/connection-form": "^1.52.3", + "@mongodb-js/compass-components": "^1.39.0", + "@mongodb-js/compass-connections": "^1.61.0", + "@mongodb-js/compass-workspaces": "^0.42.0", + "@mongodb-js/connection-form": "^1.53.0", "@mongodb-js/connection-info": "^0.15.2", - "compass-preferences-model": "^2.40.2", + "compass-preferences-model": "^2.41.0", "mongodb-build-info": "^1.7.2", "react": "^17.0.2", "react-virtualized-auto-sizer": "^1.0.6", @@ -43920,30 +43982,86 @@ "node": ">=0.3.1" } }, + "packages/compass-context-menu": { + "name": "@mongodb-js/compass-context-menu", + "version": "0.0.1", + "license": "SSPL", + "dependencies": { + "react": "^17.0.2" + }, + "devDependencies": { + "@mongodb-js/eslint-config-compass": "^1.3.8", + "@mongodb-js/mocha-config-compass": "^1.6.8", + "@mongodb-js/prettier-config-compass": "^1.2.8", + "@mongodb-js/testing-library-compass": "^1.3.1", + "@mongodb-js/tsconfig-compass": "^1.2.8", + "@types/chai": "^4.2.21", + "@types/mocha": "^9.0.0", + "@types/react": "^17.0.5", + "@types/sinon-chai": "^3.2.5", + "chai": "^4.3.6", + "depcheck": "^1.4.1", + "gen-esm-wrapper": "^1.1.0", + "mocha": "^10.2.0", + "nyc": "^15.1.0", + "sinon": "^9.2.3", + "typescript": "^5.0.4" + } + }, + "packages/compass-context-menu/node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "packages/compass-context-menu/node_modules/sinon": { + "version": "9.2.4", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-9.2.4.tgz", + "integrity": "sha512-zljcULZQsJxVra28qIAL6ow1Z9tpattkCTEJR4RBP3TGc00FcttsP5pK284Nas5WjMZU5Yzy3kAIp3B3KRf5Yg==", + "deprecated": "16.1.1", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@sinonjs/commons": "^1.8.1", + "@sinonjs/fake-timers": "^6.0.1", + "@sinonjs/samsam": "^5.3.1", + "diff": "^4.0.2", + "nise": "^4.0.4", + "supports-color": "^7.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/sinon" + } + }, "packages/compass-crud": { "name": "@mongodb-js/compass-crud", - "version": "13.60.0", + "version": "13.61.0", "license": "SSPL", "dependencies": { - "@mongodb-js/compass-app-stores": "^7.46.0", - "@mongodb-js/compass-collection": "^4.59.0", - "@mongodb-js/compass-components": "^1.38.1", - "@mongodb-js/compass-connections": "^1.60.0", - "@mongodb-js/compass-editor": "^0.40.2", - "@mongodb-js/compass-field-store": "^9.35.0", + "@mongodb-js/compass-app-registry": "^9.4.11", + "@mongodb-js/compass-app-stores": "^7.47.0", + "@mongodb-js/compass-collection": "^4.60.0", + "@mongodb-js/compass-components": "^1.39.0", + "@mongodb-js/compass-connections": "^1.61.0", + "@mongodb-js/compass-editor": "^0.41.0", + "@mongodb-js/compass-field-store": "^9.36.0", "@mongodb-js/compass-logging": "^1.7.2", - "@mongodb-js/compass-query-bar": "^8.61.0", + "@mongodb-js/compass-query-bar": "^8.62.0", "@mongodb-js/compass-telemetry": "^1.10.0", - "@mongodb-js/compass-workspaces": "^0.41.0", + "@mongodb-js/compass-workspaces": "^0.42.0", "@mongodb-js/explain-plan-helper": "^1.4.10", - "@mongodb-js/my-queries-storage": "^0.27.3", + "@mongodb-js/my-queries-storage": "^0.28.0", "@mongodb-js/reflux-state-mixin": "^1.2.10", "@mongodb-js/shell-bson-parser": "^1.2.0", "ag-grid-community": "^20.2.0", "ag-grid-react": "^20.2.0", "bson": "^6.10.3", - "compass-preferences-model": "^2.40.2", - "hadron-app-registry": "^9.4.11", + "compass-preferences-model": "^2.41.0", "hadron-document": "^8.8.12", "hadron-type-checker": "^7.4.10", "jsondiffpatch": "^0.5.0", @@ -43974,10 +44092,10 @@ "electron-mocha": "^12.2.0", "enzyme": "^3.11.0", "mocha": "^10.2.0", - "mongodb-instance-model": "^12.32.2", + "mongodb-instance-model": "^12.33.0", "nyc": "^15.1.0", "react-dom": "^17.0.2", - "sinon": "^8.1.1", + "sinon": "^17.0.1", "typescript": "^5.0.4" } }, @@ -43993,6 +44111,55 @@ "bson": "^4.6.3 || ^5 || ^6" } }, + "packages/compass-crud/node_modules/@sinonjs/commons": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", + "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "type-detect": "4.0.8" + } + }, + "packages/compass-crud/node_modules/@sinonjs/fake-timers": { + "version": "11.3.1", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-11.3.1.tgz", + "integrity": "sha512-EVJO7nW5M/F5Tur0Rf2z/QoMo+1Ia963RiMtapiQrEWvY0iBUvADo8Beegwjpnle5BHkyHuoxSTW3jF43H1XRA==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@sinonjs/commons": "^3.0.1" + } + }, + "packages/compass-crud/node_modules/@sinonjs/samsam": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-8.0.2.tgz", + "integrity": "sha512-v46t/fwnhejRSFTGqbpn9u+LQ9xJDse10gNnPgAcxgdoCDMXj/G2asWAC/8Qs+BAZDicX+MNZouXT1A7c83kVw==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@sinonjs/commons": "^3.0.1", + "lodash.get": "^4.4.2", + "type-detect": "^4.1.0" + } + }, + "packages/compass-crud/node_modules/@sinonjs/samsam/node_modules/type-detect": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz", + "integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "packages/compass-crud/node_modules/just-extend": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-6.2.0.tgz", + "integrity": "sha512-cYofQu2Xpom82S6qD778jBDpwvvy39s1l/hrYij2u9AMdQcGRpaBu6kY4mVhuno5kJVi1DAz4aiphA2WI1/OAw==", + "dev": true, + "license": "MIT" + }, "packages/compass-crud/node_modules/mongodb-query-parser": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/mongodb-query-parser/-/mongodb-query-parser-4.3.0.tgz", @@ -44008,6 +44175,20 @@ "bson": "^4.6.3 || ^5 || ^6" } }, + "packages/compass-crud/node_modules/nise": { + "version": "5.1.9", + "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.9.tgz", + "integrity": "sha512-qOnoujW4SV6e40dYxJOb3uvuoPHtmLzIk4TFo+j0jPJoC+5Z9xja5qH5JZobEPsa8+YYphMrOSwnrshEhG2qww==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@sinonjs/commons": "^3.0.0", + "@sinonjs/fake-timers": "^11.2.2", + "@sinonjs/text-encoding": "^0.7.2", + "just-extend": "^6.2.0", + "path-to-regexp": "^6.2.1" + } + }, "packages/compass-crud/node_modules/numeral": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/numeral/-/numeral-2.0.6.tgz", @@ -44016,23 +44197,49 @@ "node": "*" } }, + "packages/compass-crud/node_modules/path-to-regexp": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.3.0.tgz", + "integrity": "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==", + "dev": true, + "license": "MIT" + }, + "packages/compass-crud/node_modules/sinon": { + "version": "17.0.1", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-17.0.1.tgz", + "integrity": "sha512-wmwE19Lie0MLT+ZYNpDymasPHUKTaZHUH/pKEubRXIzySv9Atnlw+BUMGCzWgV7b7wO+Hw6f1TEOr0IUnmU8/g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@sinonjs/commons": "^3.0.0", + "@sinonjs/fake-timers": "^11.2.2", + "@sinonjs/samsam": "^8.0.0", + "diff": "^5.1.0", + "nise": "^5.1.5", + "supports-color": "^7.2.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/sinon" + } + }, "packages/compass-data-modeling": { "name": "@mongodb-js/compass-data-modeling", - "version": "1.11.0", + "version": "1.12.0", "license": "SSPL", "dependencies": { - "@mongodb-js/compass-app-stores": "^7.46.0", - "@mongodb-js/compass-components": "^1.38.1", - "@mongodb-js/compass-connections": "^1.60.0", - "@mongodb-js/compass-editor": "^0.40.2", + "@mongodb-js/compass-app-registry": "^9.4.11", + "@mongodb-js/compass-app-stores": "^7.47.0", + "@mongodb-js/compass-components": "^1.39.0", + "@mongodb-js/compass-connections": "^1.61.0", + "@mongodb-js/compass-editor": "^0.41.0", "@mongodb-js/compass-logging": "^1.7.2", "@mongodb-js/compass-telemetry": "^1.10.0", "@mongodb-js/compass-user-data": "^0.7.2", - "@mongodb-js/compass-workspaces": "^0.41.0", + "@mongodb-js/compass-workspaces": "^0.42.0", "@mongodb-js/diagramming": "^1.0.2", "bson": "^6.10.3", - "compass-preferences-model": "^2.40.2", - "hadron-app-registry": "^9.4.11", + "compass-preferences-model": "^2.41.0", "lodash": "^4.17.21", "mongodb": "^6.14.1", "mongodb-ns": "^2.4.2", @@ -44350,7 +44557,7 @@ } }, "packages/compass-e2e-tests": { - "version": "1.33.0", + "version": "1.33.1", "devDependencies": { "@electron/rebuild": "^4.0.1", "@mongodb-js/compass-test-server": "^0.3.10", @@ -44367,7 +44574,7 @@ "chai": "^4.3.4", "chai-as-promised": "^7.1.1", "clipboardy": "^2.3.0", - "compass-preferences-model": "^2.40.2", + "compass-preferences-model": "^2.41.0", "cross-spawn": "^7.0.5", "debug": "^4.3.4", "depcheck": "^1.4.1", @@ -44786,7 +44993,7 @@ }, "packages/compass-editor": { "name": "@mongodb-js/compass-editor", - "version": "0.40.2", + "version": "0.41.0", "license": "SSPL", "dependencies": { "@codemirror/autocomplete": "^6.17.0", @@ -44798,7 +45005,7 @@ "@codemirror/state": "^6.1.4", "@codemirror/view": "^6.7.1", "@lezer/highlight": "^1.2.0", - "@mongodb-js/compass-components": "^1.38.1", + "@mongodb-js/compass-components": "^1.39.0", "@mongodb-js/mongodb-constants": "^0.11.0", "mongodb-query-parser": "^4.3.0", "polished": "^4.2.2", @@ -44887,21 +45094,21 @@ }, "packages/compass-explain-plan": { "name": "@mongodb-js/compass-explain-plan", - "version": "6.60.0", + "version": "6.61.0", "license": "SSPL", "dependencies": { - "@mongodb-js/compass-collection": "^4.59.0", - "@mongodb-js/compass-components": "^1.38.1", - "@mongodb-js/compass-connections": "^1.60.0", - "@mongodb-js/compass-editor": "^0.40.2", + "@mongodb-js/compass-app-registry": "^9.4.11", + "@mongodb-js/compass-collection": "^4.60.0", + "@mongodb-js/compass-components": "^1.39.0", + "@mongodb-js/compass-connections": "^1.61.0", + "@mongodb-js/compass-editor": "^0.41.0", "@mongodb-js/compass-logging": "^1.7.2", "@mongodb-js/compass-telemetry": "^1.10.0", "@mongodb-js/explain-plan-helper": "^1.4.10", - "compass-preferences-model": "^2.40.2", + "compass-preferences-model": "^2.41.0", "d3": "^3.5.17", "d3-flextree": "^2.1.2", "d3-hierarchy": "^3.1.2", - "hadron-app-registry": "^9.4.11", "lodash": "^4.17.21", "mongodb": "^6.16.0", "react": "^17.0.2", @@ -44965,19 +45172,19 @@ }, "packages/compass-export-to-language": { "name": "@mongodb-js/compass-export-to-language", - "version": "9.36.0", + "version": "9.37.0", "license": "SSPL", "dependencies": { - "@mongodb-js/compass-collection": "^4.59.0", - "@mongodb-js/compass-components": "^1.38.1", - "@mongodb-js/compass-connections": "^1.60.0", - "@mongodb-js/compass-editor": "^0.40.2", - "@mongodb-js/compass-maybe-protect-connection-string": "^0.38.2", + "@mongodb-js/compass-app-registry": "^9.4.11", + "@mongodb-js/compass-collection": "^4.60.0", + "@mongodb-js/compass-components": "^1.39.0", + "@mongodb-js/compass-connections": "^1.61.0", + "@mongodb-js/compass-editor": "^0.41.0", + "@mongodb-js/compass-maybe-protect-connection-string": "^0.39.0", "@mongodb-js/compass-telemetry": "^1.10.0", "@mongodb-js/shell-bson-parser": "^1.2.0", "bson-transpilers": "^3.2.10", - "compass-preferences-model": "^2.40.2", - "hadron-app-registry": "^9.4.11", + "compass-preferences-model": "^2.41.0", "mongodb-ns": "^2.4.2", "react": "^17.0.2", "react-redux": "^8.1.3", @@ -45039,12 +45246,12 @@ }, "packages/compass-field-store": { "name": "@mongodb-js/compass-field-store", - "version": "9.35.0", + "version": "9.36.0", "license": "SSPL", "dependencies": { - "@mongodb-js/compass-connections": "^1.60.0", + "@mongodb-js/compass-app-registry": "^9.4.11", + "@mongodb-js/compass-connections": "^1.61.0", "@mongodb-js/compass-logging": "^1.7.2", - "hadron-app-registry": "^9.4.11", "lodash": "^4.17.21", "mongodb-schema": "^12.6.2", "react": "^17.0.2", @@ -45200,11 +45407,11 @@ }, "packages/compass-find-in-page": { "name": "@mongodb-js/compass-find-in-page", - "version": "4.39.2", + "version": "4.40.0", "license": "SSPL", "dependencies": { - "@mongodb-js/compass-components": "^1.38.1", - "hadron-app-registry": "^9.4.11", + "@mongodb-js/compass-app-registry": "^9.4.11", + "@mongodb-js/compass-components": "^1.39.0", "hadron-ipc": "^3.5.2", "react": "^17.0.2", "react-redux": "^8.1.3", @@ -45264,19 +45471,19 @@ }, "packages/compass-generative-ai": { "name": "@mongodb-js/compass-generative-ai", - "version": "0.40.0", + "version": "0.41.0", "license": "SSPL", "dependencies": { - "@mongodb-js/atlas-service": "^0.45.0", - "@mongodb-js/compass-components": "^1.38.1", - "@mongodb-js/compass-connections": "^1.60.0", - "@mongodb-js/compass-intercom": "^0.24.2", + "@mongodb-js/atlas-service": "^0.46.0", + "@mongodb-js/compass-app-registry": "^9.4.11", + "@mongodb-js/compass-components": "^1.39.0", + "@mongodb-js/compass-connections": "^1.61.0", + "@mongodb-js/compass-intercom": "^0.25.0", "@mongodb-js/compass-logging": "^1.7.2", "@mongodb-js/compass-telemetry": "^1.10.0", "@mongodb-js/compass-utils": "^0.9.2", "bson": "^6.10.3", - "compass-preferences-model": "^2.40.2", - "hadron-app-registry": "^9.4.11", + "compass-preferences-model": "^2.41.0", "mongodb": "^6.16.0", "mongodb-schema": "^12.6.2", "react": "^17.0.2", @@ -45470,17 +45677,17 @@ }, "packages/compass-global-writes": { "name": "@mongodb-js/compass-global-writes", - "version": "1.19.0", + "version": "1.20.0", "license": "SSPL", "dependencies": { - "@mongodb-js/atlas-service": "^0.45.0", - "@mongodb-js/compass-collection": "^4.59.0", - "@mongodb-js/compass-components": "^1.38.1", - "@mongodb-js/compass-connections": "^1.60.0", - "@mongodb-js/compass-field-store": "^9.35.0", + "@mongodb-js/atlas-service": "^0.46.0", + "@mongodb-js/compass-app-registry": "^9.4.11", + "@mongodb-js/compass-collection": "^4.60.0", + "@mongodb-js/compass-components": "^1.39.0", + "@mongodb-js/compass-connections": "^1.61.0", + "@mongodb-js/compass-field-store": "^9.36.0", "@mongodb-js/compass-logging": "^1.7.2", "@mongodb-js/compass-telemetry": "^1.10.0", - "hadron-app-registry": "^9.4.11", "lodash": "^4.17.21", "mongodb-ns": "^2.4.2", "react": "^17.0.2", @@ -45662,22 +45869,22 @@ }, "packages/compass-import-export": { "name": "@mongodb-js/compass-import-export", - "version": "7.59.0", + "version": "7.60.0", "license": "SSPL", "dependencies": { "@electron/remote": "^2.1.2", - "@mongodb-js/compass-components": "^1.38.1", - "@mongodb-js/compass-connections": "^1.60.0", - "@mongodb-js/compass-editor": "^0.40.2", + "@mongodb-js/compass-app-registry": "^9.4.11", + "@mongodb-js/compass-components": "^1.39.0", + "@mongodb-js/compass-connections": "^1.61.0", + "@mongodb-js/compass-editor": "^0.41.0", "@mongodb-js/compass-logging": "^1.7.2", "@mongodb-js/compass-telemetry": "^1.10.0", "@mongodb-js/compass-utils": "^0.9.2", - "@mongodb-js/compass-workspaces": "^0.41.0", + "@mongodb-js/compass-workspaces": "^0.42.0", "bson": "^6.10.3", - "compass-preferences-model": "^2.40.2", + "compass-preferences-model": "^2.41.0", "debug": "^4.3.4", "electron": "^36.4.0", - "hadron-app-registry": "^9.4.11", "hadron-document": "^8.8.12", "hadron-ipc": "^3.5.2", "lodash": "^4.17.21", @@ -45881,23 +46088,23 @@ }, "packages/compass-indexes": { "name": "@mongodb-js/compass-indexes", - "version": "5.59.0", + "version": "5.60.0", "license": "SSPL", "dependencies": { - "@mongodb-js/atlas-service": "^0.45.0", - "@mongodb-js/compass-app-stores": "^7.46.0", - "@mongodb-js/compass-components": "^1.38.1", - "@mongodb-js/compass-connections": "^1.60.0", - "@mongodb-js/compass-editor": "^0.40.2", - "@mongodb-js/compass-field-store": "^9.35.0", + "@mongodb-js/atlas-service": "^0.46.0", + "@mongodb-js/compass-app-registry": "^9.4.11", + "@mongodb-js/compass-app-stores": "^7.47.0", + "@mongodb-js/compass-components": "^1.39.0", + "@mongodb-js/compass-connections": "^1.61.0", + "@mongodb-js/compass-editor": "^0.41.0", + "@mongodb-js/compass-field-store": "^9.36.0", "@mongodb-js/compass-logging": "^1.7.2", "@mongodb-js/compass-telemetry": "^1.10.0", - "@mongodb-js/compass-workspaces": "^0.41.0", + "@mongodb-js/compass-workspaces": "^0.42.0", "@mongodb-js/mongodb-constants": "^0.11.0", "@mongodb-js/shell-bson-parser": "^1.2.0", "bson": "^6.10.3", - "compass-preferences-model": "^2.40.2", - "hadron-app-registry": "^9.4.11", + "compass-preferences-model": "^2.41.0", "lodash": "^4.17.21", "mongodb": "^6.16.0", "mongodb-collection-model": "^5.29.2", @@ -46046,11 +46253,11 @@ }, "packages/compass-intercom": { "name": "@mongodb-js/compass-intercom", - "version": "0.24.2", + "version": "0.25.0", "license": "SSPL", "dependencies": { "@mongodb-js/compass-logging": "^1.7.2", - "compass-preferences-model": "^2.40.2" + "compass-preferences-model": "^2.41.0" }, "devDependencies": { "@mongodb-js/eslint-config-compass": "^1.3.10", @@ -46154,8 +46361,8 @@ "version": "1.7.2", "license": "SSPL", "dependencies": { + "@mongodb-js/compass-app-registry": "^9.4.11", "debug": "^4.3.4", - "hadron-app-registry": "^9.4.11", "hadron-ipc": "^3.5.2", "is-electron-renderer": "^2.0.1", "mongodb-log-writer": "^2.3.4", @@ -46207,10 +46414,10 @@ }, "packages/compass-maybe-protect-connection-string": { "name": "@mongodb-js/compass-maybe-protect-connection-string", - "version": "0.38.2", + "version": "0.39.0", "license": "SSPL", "dependencies": { - "compass-preferences-model": "^2.40.2", + "compass-preferences-model": "^2.41.0", "mongodb-connection-string-url": "^3.0.1" }, "devDependencies": { @@ -46258,15 +46465,15 @@ } }, "packages/compass-preferences-model": { - "version": "2.40.2", + "version": "2.41.0", "license": "SSPL", "dependencies": { - "@mongodb-js/compass-components": "^1.38.1", + "@mongodb-js/compass-app-registry": "^9.4.11", + "@mongodb-js/compass-components": "^1.39.0", "@mongodb-js/compass-logging": "^1.7.2", "@mongodb-js/compass-user-data": "^0.7.2", "@mongodb-js/devtools-proxy-support": "^0.4.4", "bson": "^6.10.3", - "hadron-app-registry": "^9.4.11", "hadron-ipc": "^3.5.2", "js-yaml": "^4.1.0", "lodash": "^4.17.21", @@ -46323,27 +46530,27 @@ }, "packages/compass-query-bar": { "name": "@mongodb-js/compass-query-bar", - "version": "8.61.0", + "version": "8.62.0", "license": "SSPL", "dependencies": { - "@mongodb-js/atlas-service": "^0.45.0", - "@mongodb-js/compass-app-stores": "^7.46.0", - "@mongodb-js/compass-collection": "^4.59.0", - "@mongodb-js/compass-components": "^1.38.1", - "@mongodb-js/compass-connections": "^1.60.0", - "@mongodb-js/compass-editor": "^0.40.2", - "@mongodb-js/compass-field-store": "^9.35.0", - "@mongodb-js/compass-generative-ai": "^0.40.0", + "@mongodb-js/atlas-service": "^0.46.0", + "@mongodb-js/compass-app-registry": "^9.4.11", + "@mongodb-js/compass-app-stores": "^7.47.0", + "@mongodb-js/compass-collection": "^4.60.0", + "@mongodb-js/compass-components": "^1.39.0", + "@mongodb-js/compass-connections": "^1.61.0", + "@mongodb-js/compass-editor": "^0.41.0", + "@mongodb-js/compass-field-store": "^9.36.0", + "@mongodb-js/compass-generative-ai": "^0.41.0", "@mongodb-js/compass-logging": "^1.7.2", "@mongodb-js/compass-telemetry": "^1.10.0", "@mongodb-js/mongodb-constants": "^0.11.0", - "@mongodb-js/my-queries-storage": "^0.27.3", + "@mongodb-js/my-queries-storage": "^0.28.0", "bson": "^6.10.3", - "compass-preferences-model": "^2.40.2", - "hadron-app-registry": "^9.4.11", + "compass-preferences-model": "^2.41.0", "lodash": "^4.17.21", "mongodb": "^6.16.0", - "mongodb-instance-model": "^12.32.2", + "mongodb-instance-model": "^12.33.0", "mongodb-ns": "^2.4.2", "mongodb-query-parser": "^4.3.0", "mongodb-query-util": "^2.4.10", @@ -46536,22 +46743,22 @@ }, "packages/compass-saved-aggregations-queries": { "name": "@mongodb-js/compass-saved-aggregations-queries", - "version": "1.60.0", + "version": "1.61.0", "license": "SSPL", "dependencies": { - "@mongodb-js/compass-app-stores": "^7.46.0", - "@mongodb-js/compass-components": "^1.38.1", - "@mongodb-js/compass-connections": "^1.60.0", + "@mongodb-js/compass-app-registry": "^9.4.11", + "@mongodb-js/compass-app-stores": "^7.47.0", + "@mongodb-js/compass-components": "^1.39.0", + "@mongodb-js/compass-connections": "^1.61.0", "@mongodb-js/compass-logging": "^1.7.2", "@mongodb-js/compass-telemetry": "^1.10.0", - "@mongodb-js/compass-workspaces": "^0.41.0", - "@mongodb-js/connection-form": "^1.52.3", + "@mongodb-js/compass-workspaces": "^0.42.0", + "@mongodb-js/connection-form": "^1.53.0", "@mongodb-js/connection-info": "^0.15.2", - "@mongodb-js/my-queries-storage": "^0.27.3", + "@mongodb-js/my-queries-storage": "^0.28.0", "bson": "^6.10.3", - "compass-preferences-model": "^2.40.2", + "compass-preferences-model": "^2.41.0", "fuse.js": "^6.5.3", - "hadron-app-registry": "^9.4.11", "mongodb-ns": "^2.4.2", "react": "^17.0.2", "react-redux": "^8.1.3", @@ -46610,22 +46817,22 @@ }, "packages/compass-schema": { "name": "@mongodb-js/compass-schema", - "version": "6.61.0", + "version": "6.62.0", "license": "SSPL", "dependencies": { - "@mongodb-js/compass-collection": "^4.59.0", - "@mongodb-js/compass-components": "^1.38.1", - "@mongodb-js/compass-connections": "^1.60.0", - "@mongodb-js/compass-editor": "^0.40.2", - "@mongodb-js/compass-field-store": "^9.35.0", + "@mongodb-js/compass-app-registry": "^9.4.11", + "@mongodb-js/compass-collection": "^4.60.0", + "@mongodb-js/compass-components": "^1.39.0", + "@mongodb-js/compass-connections": "^1.61.0", + "@mongodb-js/compass-editor": "^0.41.0", + "@mongodb-js/compass-field-store": "^9.36.0", "@mongodb-js/compass-logging": "^1.7.2", - "@mongodb-js/compass-query-bar": "^8.61.0", + "@mongodb-js/compass-query-bar": "^8.62.0", "@mongodb-js/compass-telemetry": "^1.10.0", - "@mongodb-js/connection-storage": "^0.35.0", + "@mongodb-js/connection-storage": "^0.36.0", "bson": "^6.10.3", - "compass-preferences-model": "^2.40.2", + "compass-preferences-model": "^2.41.0", "d3": "^3.5.17", - "hadron-app-registry": "^9.4.11", "hadron-document": "^8.8.12", "leaflet": "^1.5.1", "leaflet-defaulticon-compatibility": "^0.1.1", @@ -46646,7 +46853,7 @@ "devDependencies": { "@mongodb-js/eslint-config-compass": "^1.3.10", "@mongodb-js/mocha-config-compass": "^1.6.8", - "@mongodb-js/my-queries-storage": "^0.27.3", + "@mongodb-js/my-queries-storage": "^0.28.0", "@mongodb-js/prettier-config-compass": "^1.2.8", "@mongodb-js/testing-library-compass": "^1.3.2", "@mongodb-js/tsconfig-compass": "^1.2.8", @@ -46669,24 +46876,24 @@ }, "packages/compass-schema-validation": { "name": "@mongodb-js/compass-schema-validation", - "version": "6.60.0", + "version": "6.61.0", "license": "SSPL", "dependencies": { - "@mongodb-js/compass-app-stores": "^7.46.0", - "@mongodb-js/compass-collection": "^4.59.0", - "@mongodb-js/compass-components": "^1.38.1", - "@mongodb-js/compass-connections": "^1.60.0", - "@mongodb-js/compass-crud": "^13.60.0", - "@mongodb-js/compass-editor": "^0.40.2", - "@mongodb-js/compass-field-store": "^9.35.0", + "@mongodb-js/compass-app-registry": "^9.4.11", + "@mongodb-js/compass-app-stores": "^7.47.0", + "@mongodb-js/compass-collection": "^4.60.0", + "@mongodb-js/compass-components": "^1.39.0", + "@mongodb-js/compass-connections": "^1.61.0", + "@mongodb-js/compass-crud": "^13.61.0", + "@mongodb-js/compass-editor": "^0.41.0", + "@mongodb-js/compass-field-store": "^9.36.0", "@mongodb-js/compass-logging": "^1.7.2", - "@mongodb-js/compass-schema": "^6.61.0", + "@mongodb-js/compass-schema": "^6.62.0", "@mongodb-js/compass-telemetry": "^1.10.0", - "@mongodb-js/compass-workspaces": "^0.41.0", + "@mongodb-js/compass-workspaces": "^0.42.0", "@mongodb-js/mongodb-constants": "^0.11.0", "bson": "^6.10.3", - "compass-preferences-model": "^2.40.2", - "hadron-app-registry": "^9.4.11", + "compass-preferences-model": "^2.41.0", "javascript-stringify": "^2.0.1", "lodash": "^4.17.21", "mongodb": "^6.16.0", @@ -46710,7 +46917,7 @@ "electron-mocha": "^12.2.0", "hadron-ipc": "^3.5.2", "mocha": "^10.2.0", - "mongodb-instance-model": "^12.32.2", + "mongodb-instance-model": "^12.33.0", "nyc": "^15.1.0", "react-dom": "^17.0.2", "sinon": "^8.1.1", @@ -46882,18 +47089,18 @@ }, "packages/compass-serverstats": { "name": "@mongodb-js/compass-serverstats", - "version": "16.59.0", + "version": "16.60.0", "license": "SSPL", "dependencies": { - "@mongodb-js/compass-app-stores": "^7.46.0", - "@mongodb-js/compass-components": "^1.38.1", - "@mongodb-js/compass-connections": "^1.60.0", + "@mongodb-js/compass-app-registry": "^9.4.11", + "@mongodb-js/compass-app-stores": "^7.47.0", + "@mongodb-js/compass-components": "^1.39.0", + "@mongodb-js/compass-connections": "^1.61.0", "@mongodb-js/compass-telemetry": "^1.10.0", - "@mongodb-js/compass-workspaces": "^0.41.0", + "@mongodb-js/compass-workspaces": "^0.42.0", "d3": "^3.5.17", "d3-timer": "^1.0.3", "debug": "^4.3.4", - "hadron-app-registry": "^9.4.11", "lodash": "^4.17.21", "mongodb-ns": "^2.4.2", "prop-types": "^15.7.2", @@ -46930,15 +47137,15 @@ }, "packages/compass-settings": { "name": "@mongodb-js/compass-settings", - "version": "0.58.0", + "version": "0.59.0", "license": "SSPL", "dependencies": { - "@mongodb-js/atlas-service": "^0.45.0", - "@mongodb-js/compass-components": "^1.38.1", - "@mongodb-js/compass-generative-ai": "^0.40.0", + "@mongodb-js/atlas-service": "^0.46.0", + "@mongodb-js/compass-app-registry": "^9.4.11", + "@mongodb-js/compass-components": "^1.39.0", + "@mongodb-js/compass-generative-ai": "^0.41.0", "@mongodb-js/compass-logging": "^1.7.2", - "compass-preferences-model": "^2.40.2", - "hadron-app-registry": "^9.4.11", + "compass-preferences-model": "^2.41.0", "hadron-ipc": "^3.5.2", "react": "^17.0.2", "react-redux": "^8.1.3", @@ -46997,23 +47204,23 @@ }, "packages/compass-shell": { "name": "@mongodb-js/compass-shell", - "version": "3.59.0", + "version": "3.60.0", "license": "SSPL", "dependencies": { - "@mongodb-js/compass-components": "^1.38.1", - "@mongodb-js/compass-connections": "^1.60.0", - "@mongodb-js/compass-editor": "^0.40.2", + "@mongodb-js/compass-app-registry": "^9.4.11", + "@mongodb-js/compass-components": "^1.39.0", + "@mongodb-js/compass-connections": "^1.61.0", + "@mongodb-js/compass-editor": "^0.41.0", "@mongodb-js/compass-logging": "^1.7.2", "@mongodb-js/compass-telemetry": "^1.10.0", "@mongodb-js/compass-user-data": "^0.7.2", "@mongodb-js/compass-utils": "^0.9.2", - "@mongodb-js/compass-workspaces": "^0.41.0", + "@mongodb-js/compass-workspaces": "^0.42.0", "@mongosh/browser-repl": "^3.12.0", "@mongosh/logging": "^3.8.0", "@mongosh/node-runtime-worker-thread": "^3.3.10", "bson": "^6.10.3", - "compass-preferences-model": "^2.40.2", - "hadron-app-registry": "^9.4.11", + "compass-preferences-model": "^2.41.0", "react": "^17.0.2", "react-redux": "^8.1.3", "redux": "^4.2.1", @@ -47318,24 +47525,24 @@ }, "packages/compass-sidebar": { "name": "@mongodb-js/compass-sidebar", - "version": "5.60.0", + "version": "5.61.0", "license": "SSPL", "dependencies": { - "@mongodb-js/compass-app-stores": "^7.46.0", - "@mongodb-js/compass-components": "^1.38.1", - "@mongodb-js/compass-connection-import-export": "^0.56.0", - "@mongodb-js/compass-connections": "^1.60.0", - "@mongodb-js/compass-connections-navigation": "^1.59.0", + "@mongodb-js/compass-app-registry": "^9.4.11", + "@mongodb-js/compass-app-stores": "^7.47.0", + "@mongodb-js/compass-components": "^1.39.0", + "@mongodb-js/compass-connection-import-export": "^0.57.0", + "@mongodb-js/compass-connections": "^1.61.0", + "@mongodb-js/compass-connections-navigation": "^1.60.0", "@mongodb-js/compass-logging": "^1.7.2", - "@mongodb-js/compass-maybe-protect-connection-string": "^0.38.2", + "@mongodb-js/compass-maybe-protect-connection-string": "^0.39.0", "@mongodb-js/compass-telemetry": "^1.10.0", - "@mongodb-js/compass-workspaces": "^0.41.0", + "@mongodb-js/compass-workspaces": "^0.42.0", "@mongodb-js/connection-info": "^0.15.2", - "compass-preferences-model": "^2.40.2", - "hadron-app-registry": "^9.4.11", + "compass-preferences-model": "^2.41.0", "lodash": "^4.17.21", "mongodb": "^6.16.0", - "mongodb-instance-model": "^12.32.2", + "mongodb-instance-model": "^12.33.0", "mongodb-ns": "^2.4.2", "react": "^17.0.2", "react-redux": "^8.1.3", @@ -47395,7 +47602,7 @@ }, "packages/compass-smoke-tests": { "name": "@mongodb-js/compass-smoke-tests", - "version": "1.1.19", + "version": "1.1.20", "license": "SSPL", "devDependencies": { "@actions/github": "^6.0.0", @@ -47403,7 +47610,7 @@ "@mongodb-js/prettier-config-compass": "^1.2.8", "@mongodb-js/tsconfig-compass": "^1.2.8", "@types/node": "^20", - "compass-e2e-tests": "^1.33.0", + "compass-e2e-tests": "^1.33.1", "debug": "^4.3.4", "depcheck": "^1.4.1", "hadron-build": "^25.8.2", @@ -47484,8 +47691,8 @@ "version": "1.10.0", "license": "SSPL", "dependencies": { + "@mongodb-js/compass-app-registry": "^9.4.11", "@mongodb-js/compass-logging": "^1.7.2", - "hadron-app-registry": "^9.4.11", "hadron-ipc": "^3.5.2", "react": "^17.0.2" }, @@ -47777,33 +47984,34 @@ }, "packages/compass-web": { "name": "@mongodb-js/compass-web", - "version": "0.17.3", + "version": "0.17.4", "license": "SSPL", "devDependencies": { - "@mongodb-js/atlas-service": "^0.45.0", - "@mongodb-js/compass-aggregations": "^9.62.0", - "@mongodb-js/compass-app-stores": "^7.46.0", - "@mongodb-js/compass-collection": "^4.59.0", - "@mongodb-js/compass-components": "^1.38.1", - "@mongodb-js/compass-connections": "^1.60.0", - "@mongodb-js/compass-crud": "^13.60.0", - "@mongodb-js/compass-data-modeling": "^1.11.0", - "@mongodb-js/compass-databases-collections": "^1.59.0", - "@mongodb-js/compass-explain-plan": "^6.60.0", - "@mongodb-js/compass-export-to-language": "^9.36.0", - "@mongodb-js/compass-field-store": "^9.35.0", - "@mongodb-js/compass-generative-ai": "^0.40.0", - "@mongodb-js/compass-global-writes": "^1.19.0", - "@mongodb-js/compass-indexes": "^5.59.0", + "@mongodb-js/atlas-service": "^0.46.0", + "@mongodb-js/compass-aggregations": "^9.63.0", + "@mongodb-js/compass-app-registry": "^9.4.11", + "@mongodb-js/compass-app-stores": "^7.47.0", + "@mongodb-js/compass-collection": "^4.60.0", + "@mongodb-js/compass-components": "^1.39.0", + "@mongodb-js/compass-connections": "^1.61.0", + "@mongodb-js/compass-crud": "^13.61.0", + "@mongodb-js/compass-data-modeling": "^1.12.0", + "@mongodb-js/compass-databases-collections": "^1.60.0", + "@mongodb-js/compass-explain-plan": "^6.61.0", + "@mongodb-js/compass-export-to-language": "^9.37.0", + "@mongodb-js/compass-field-store": "^9.36.0", + "@mongodb-js/compass-generative-ai": "^0.41.0", + "@mongodb-js/compass-global-writes": "^1.20.0", + "@mongodb-js/compass-indexes": "^5.60.0", "@mongodb-js/compass-logging": "^1.7.2", - "@mongodb-js/compass-query-bar": "^8.61.0", - "@mongodb-js/compass-schema": "^6.61.0", - "@mongodb-js/compass-schema-validation": "^6.60.0", - "@mongodb-js/compass-sidebar": "^5.60.0", + "@mongodb-js/compass-query-bar": "^8.62.0", + "@mongodb-js/compass-schema": "^6.62.0", + "@mongodb-js/compass-schema-validation": "^6.61.0", + "@mongodb-js/compass-sidebar": "^5.61.0", "@mongodb-js/compass-telemetry": "^1.10.0", - "@mongodb-js/compass-welcome": "^0.58.0", - "@mongodb-js/compass-workspaces": "^0.41.0", - "@mongodb-js/connection-storage": "^0.35.0", + "@mongodb-js/compass-welcome": "^0.59.0", + "@mongodb-js/compass-workspaces": "^0.42.0", + "@mongodb-js/connection-storage": "^0.36.0", "@mongodb-js/devtools-proxy-support": "^0.4.4", "@mongodb-js/eslint-config-compass": "^1.3.10", "@mongodb-js/mocha-config-compass": "^1.6.8", @@ -47822,7 +48030,7 @@ "bson": "^6.2.0", "buffer": "^6.0.3", "chai": "^4.3.6", - "compass-preferences-model": "^2.40.2", + "compass-preferences-model": "^2.41.0", "crypto-browserify": "^3.12.0", "debug": "^4.3.4", "depcheck": "^1.4.1", @@ -47831,7 +48039,6 @@ "events": "^3.3.0", "express": "^4.21.1", "express-http-proxy": "^2.0.0", - "hadron-app-registry": "^9.4.11", "is-ip": "^5.0.1", "lodash": "^4.17.21", "mocha": "^10.2.0", @@ -48034,16 +48241,16 @@ }, "packages/compass-welcome": { "name": "@mongodb-js/compass-welcome", - "version": "0.58.0", + "version": "0.59.0", "license": "SSPL", "dependencies": { - "@mongodb-js/compass-components": "^1.38.1", - "@mongodb-js/compass-connections": "^1.60.0", + "@mongodb-js/compass-app-registry": "^9.4.11", + "@mongodb-js/compass-components": "^1.39.0", + "@mongodb-js/compass-connections": "^1.61.0", "@mongodb-js/compass-logging": "^1.7.2", "@mongodb-js/compass-telemetry": "^1.10.0", - "@mongodb-js/compass-workspaces": "^0.41.0", - "compass-preferences-model": "^2.40.2", - "hadron-app-registry": "^9.4.11", + "@mongodb-js/compass-workspaces": "^0.42.0", + "compass-preferences-model": "^2.41.0", "react": "^17.0.2", "redux": "^4.2.1", "redux-thunk": "^2.4.2" @@ -48098,16 +48305,16 @@ }, "packages/compass-workspaces": { "name": "@mongodb-js/compass-workspaces", - "version": "0.41.0", + "version": "0.42.0", "license": "SSPL", "dependencies": { - "@mongodb-js/compass-app-stores": "^7.46.0", - "@mongodb-js/compass-components": "^1.38.1", - "@mongodb-js/compass-connections": "^1.60.0", + "@mongodb-js/compass-app-registry": "^9.4.11", + "@mongodb-js/compass-app-stores": "^7.47.0", + "@mongodb-js/compass-components": "^1.39.0", + "@mongodb-js/compass-connections": "^1.61.0", "@mongodb-js/compass-logging": "^1.7.2", "bson": "^6.10.3", - "compass-preferences-model": "^2.40.2", - "hadron-app-registry": "^9.4.11", + "compass-preferences-model": "^2.41.0", "lodash": "^4.17.21", "mongodb-collection-model": "^5.29.2", "mongodb-database-model": "^2.29.2", @@ -48423,11 +48630,11 @@ }, "packages/connection-form": { "name": "@mongodb-js/connection-form", - "version": "1.52.3", + "version": "1.53.0", "license": "SSPL", "dependencies": { - "@mongodb-js/compass-components": "^1.38.1", - "@mongodb-js/compass-editor": "^0.40.2", + "@mongodb-js/compass-components": "^1.39.0", + "@mongodb-js/compass-editor": "^0.41.0", "@mongodb-js/connection-info": "^0.15.2", "@mongodb-js/shell-bson-parser": "^1.2.0", "lodash": "^4.17.21", @@ -48639,18 +48846,18 @@ }, "packages/connection-storage": { "name": "@mongodb-js/connection-storage", - "version": "0.35.0", + "version": "0.36.0", "license": "SSPL", "dependencies": { + "@mongodb-js/compass-app-registry": "^9.4.11", "@mongodb-js/compass-logging": "^1.7.2", "@mongodb-js/compass-telemetry": "^1.10.0", "@mongodb-js/compass-user-data": "^0.7.2", "@mongodb-js/compass-utils": "^0.9.2", "@mongodb-js/connection-info": "^0.15.2", "bson": "^6.10.3", - "compass-preferences-model": "^2.40.2", + "compass-preferences-model": "^2.41.0", "electron": "^36.4.0", - "hadron-app-registry": "^9.4.11", "hadron-ipc": "^3.5.2", "keytar": "^7.9.0", "lodash": "^4.17.21", @@ -48950,24 +49157,24 @@ }, "packages/databases-collections": { "name": "@mongodb-js/compass-databases-collections", - "version": "1.59.0", + "version": "1.60.0", "license": "SSPL", "dependencies": { - "@mongodb-js/compass-app-stores": "^7.46.0", - "@mongodb-js/compass-components": "^1.38.1", - "@mongodb-js/compass-connections": "^1.60.0", - "@mongodb-js/compass-editor": "^0.40.2", + "@mongodb-js/compass-app-registry": "^9.4.11", + "@mongodb-js/compass-app-stores": "^7.47.0", + "@mongodb-js/compass-components": "^1.39.0", + "@mongodb-js/compass-connections": "^1.61.0", + "@mongodb-js/compass-editor": "^0.41.0", "@mongodb-js/compass-logging": "^1.7.2", "@mongodb-js/compass-telemetry": "^1.10.0", - "@mongodb-js/compass-workspaces": "^0.41.0", - "@mongodb-js/databases-collections-list": "^1.57.0", - "@mongodb-js/my-queries-storage": "^0.27.3", - "compass-preferences-model": "^2.40.2", - "hadron-app-registry": "^9.4.11", + "@mongodb-js/compass-workspaces": "^0.42.0", + "@mongodb-js/databases-collections-list": "^1.58.0", + "@mongodb-js/my-queries-storage": "^0.28.0", + "compass-preferences-model": "^2.41.0", "lodash": "^4.17.21", "mongodb-collection-model": "^5.29.2", "mongodb-database-model": "^2.29.2", - "mongodb-instance-model": "^12.32.2", + "mongodb-instance-model": "^12.33.0", "mongodb-ns": "^2.4.2", "mongodb-query-parser": "^4.3.0", "prop-types": "^15.7.2", @@ -48996,15 +49203,15 @@ }, "packages/databases-collections-list": { "name": "@mongodb-js/databases-collections-list", - "version": "1.57.0", + "version": "1.58.0", "license": "SSPL", "dependencies": { - "@mongodb-js/compass-components": "^1.38.1", - "@mongodb-js/compass-connections": "^1.60.0", + "@mongodb-js/compass-components": "^1.39.0", + "@mongodb-js/compass-connections": "^1.61.0", "@mongodb-js/compass-telemetry": "^1.10.0", - "@mongodb-js/compass-workspaces": "^0.41.0", + "@mongodb-js/compass-workspaces": "^0.42.0", "@mongodb-js/connection-info": "^0.15.2", - "compass-preferences-model": "^2.40.2", + "compass-preferences-model": "^2.41.0", "mongodb-collection-model": "^5.29.2", "mongodb-database-model": "^2.29.2", "mongodb-ns": "^2.4.2", @@ -49230,6 +49437,7 @@ }, "packages/hadron-app-registry": { "version": "9.4.11", + "extraneous": true, "license": "SSPL", "dependencies": { "eventemitter3": "^4.0.0", @@ -49254,33 +49462,6 @@ "typescript": "^5.0.4" } }, - "packages/hadron-app-registry/node_modules/diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true, - "engines": { - "node": ">=0.3.1" - } - }, - "packages/hadron-app-registry/node_modules/sinon": { - "version": "9.2.4", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-9.2.4.tgz", - "integrity": "sha512-zljcULZQsJxVra28qIAL6ow1Z9tpattkCTEJR4RBP3TGc00FcttsP5pK284Nas5WjMZU5Yzy3kAIp3B3KRf5Yg==", - "dev": true, - "dependencies": { - "@sinonjs/commons": "^1.8.1", - "@sinonjs/fake-timers": "^6.0.1", - "@sinonjs/samsam": "^5.3.1", - "diff": "^4.0.2", - "nise": "^4.0.4", - "supports-color": "^7.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/sinon" - } - }, "packages/hadron-build": { "version": "25.8.2", "hasInstallScript": true, @@ -50224,11 +50405,11 @@ }, "packages/instance-model": { "name": "mongodb-instance-model", - "version": "12.32.2", + "version": "12.33.0", "license": "SSPL", "dependencies": { "ampersand-model": "^8.0.1", - "compass-preferences-model": "^2.40.2", + "compass-preferences-model": "^2.41.0", "mongodb-collection-model": "^5.29.2", "mongodb-data-service": "^22.28.2", "mongodb-database-model": "^2.29.2" @@ -50302,204 +50483,15 @@ "url": "https://opencollective.com/sinon" } }, - "packages/mongodb-test-server/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "extraneous": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "packages/mongodb-test-server/node_modules/diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "extraneous": true, - "engines": { - "node": ">=0.3.1" - } - }, - "packages/mongodb-test-server/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "extraneous": true, - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "packages/mongodb-test-server/node_modules/foreground-child": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", - "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", - "extraneous": true, - "dependencies": { - "cross-spawn": "^7.0.0", - "signal-exit": "^4.0.1" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "packages/mongodb-test-server/node_modules/glob": { - "version": "10.2.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.2.6.tgz", - "integrity": "sha512-U/rnDpXJGF414QQQZv5uVsabTVxMSwzS5CH0p3DRCIV6ownl4f7PzGnkGmvlum2wB+9RlJWJZ6ACU1INnBqiPA==", - "extraneous": true, - "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^2.0.3", - "minimatch": "^9.0.1", - "minipass": "^5.0.0 || ^6.0.2", - "path-scurry": "^1.7.0" - }, - "bin": { - "glob": "dist/cjs/src/bin.js" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "packages/mongodb-test-server/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "extraneous": true, - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "packages/mongodb-test-server/node_modules/minimatch": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.1.tgz", - "integrity": "sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==", - "extraneous": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "packages/mongodb-test-server/node_modules/minipass": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-6.0.2.tgz", - "integrity": "sha512-MzWSV5nYVT7mVyWCwn2o7JH13w2TBRmmSqSRCKzTw+lmft9X4z+3wjvs06Tzijo5z4W/kahUCDpRXTF+ZrmF/w==", - "extraneous": true, - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "packages/mongodb-test-server/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "extraneous": true, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/mongodb-test-server/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "extraneous": true, - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "packages/mongodb-test-server/node_modules/rimraf": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.1.tgz", - "integrity": "sha512-OfFZdwtd3lZ+XZzYP/6gTACubwFcHdLRqS9UX3UwpU2dnGQYkPFISRwvM3w9IiB2w7bW5qGo/uAwE4SmXXSKvg==", - "extraneous": true, - "dependencies": { - "glob": "^10.2.5" - }, - "bin": { - "rimraf": "dist/cjs/src/bin.js" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "packages/mongodb-test-server/node_modules/signal-exit": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.0.2.tgz", - "integrity": "sha512-MY2/qGx4enyjprQnFaZsHib3Yadh3IXyV2C321GY0pjGfVBu4un0uDJkwgdxqO+Rdx8JMT8IfJIRwbYVz3Ob3Q==", - "extraneous": true, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "packages/mongodb-test-server/node_modules/sinon": { - "version": "9.2.4", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-9.2.4.tgz", - "integrity": "sha512-zljcULZQsJxVra28qIAL6ow1Z9tpattkCTEJR4RBP3TGc00FcttsP5pK284Nas5WjMZU5Yzy3kAIp3B3KRf5Yg==", - "extraneous": true, - "dependencies": { - "@sinonjs/commons": "^1.8.1", - "@sinonjs/fake-timers": "^6.0.1", - "@sinonjs/samsam": "^5.3.1", - "diff": "^4.0.2", - "nise": "^4.0.4", - "supports-color": "^7.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/sinon" - } - }, - "packages/mongodb-test-server/node_modules/yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "extraneous": true, - "engines": { - "node": ">=12" - } - }, "packages/my-queries-storage": { "name": "@mongodb-js/my-queries-storage", - "version": "0.27.3", + "version": "0.28.0", "license": "SSPL", "dependencies": { - "@mongodb-js/compass-editor": "^0.40.2", + "@mongodb-js/compass-app-registry": "^9.4.11", + "@mongodb-js/compass-editor": "^0.41.0", "@mongodb-js/compass-user-data": "^0.7.2", "bson": "^6.10.3", - "hadron-app-registry": "^9.4.11", "react": "^17.0.2" }, "devDependencies": { @@ -50587,492 +50579,6 @@ "typescript": "^5.0.4" } }, - "packages/reflux-store/node_modules/acorn": { - "version": "5.7.4", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz", - "integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==", - "extraneous": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "packages/reflux-store/node_modules/acorn-jsx": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", - "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", - "extraneous": true, - "dependencies": { - "acorn": "^3.0.4" - } - }, - "packages/reflux-store/node_modules/ajv": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", - "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=", - "extraneous": true, - "dependencies": { - "co": "^4.6.0", - "json-stable-stringify": "^1.0.1" - } - }, - "packages/reflux-store/node_modules/ajv-keywords": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-1.5.1.tgz", - "integrity": "sha1-MU3QpLM2j609/NxU7eYXG4htrzw=", - "extraneous": true, - "peerDependencies": { - "ajv": ">=4.10.0" - } - }, - "packages/reflux-store/node_modules/ansi-escapes": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", - "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=", - "extraneous": true, - "engines": { - "node": ">=0.10.0" - } - }, - "packages/reflux-store/node_modules/ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "extraneous": true, - "engines": { - "node": ">=0.10.0" - } - }, - "packages/reflux-store/node_modules/chai": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/chai/-/chai-3.5.0.tgz", - "integrity": "sha1-TQJjewZ/6Vi9v906QOxW/vc3Mkc=", - "extraneous": true, - "dependencies": { - "assertion-error": "^1.0.1", - "deep-eql": "^0.1.3", - "type-detect": "^1.0.0" - }, - "engines": { - "node": ">= 0.4.0" - } - }, - "packages/reflux-store/node_modules/chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "extraneous": true, - "dependencies": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "packages/reflux-store/node_modules/cli-cursor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz", - "integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=", - "extraneous": true, - "dependencies": { - "restore-cursor": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "packages/reflux-store/node_modules/cli-width": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz", - "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==", - "extraneous": true - }, - "packages/reflux-store/node_modules/debug": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", - "integrity": "sha512-X0rGvJcskG1c3TgSCPqHJ0XJgwlcvOC7elJ5Y0hYuKBZoVqWpAMfLOeIh2UI/DCQ5ruodIjvsugZtjUYUw2pUw==", - "extraneous": true, - "dependencies": { - "ms": "0.7.1" - } - }, - "packages/reflux-store/node_modules/deep-eql": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-0.1.3.tgz", - "integrity": "sha1-71WKyrjeJSBs1xOQbXTlaTDrafI=", - "extraneous": true, - "dependencies": { - "type-detect": "0.1.1" - }, - "engines": { - "node": "*" - } - }, - "packages/reflux-store/node_modules/doctrine": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", - "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", - "extraneous": true, - "dependencies": { - "esutils": "^2.0.2", - "isarray": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "packages/reflux-store/node_modules/eslint-config-mongodb-js": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/eslint-config-mongodb-js/-/eslint-config-mongodb-js-2.3.0.tgz", - "integrity": "sha512-9zxJawyp68GNX63pfqeLV47/ShSyY7Hce3l/XhrD8dihFhygs+5C7lk12ogDePK3OmOer1pREvwgR8q0YvV4Pw==", - "extraneous": true, - "dependencies": { - "babel-eslint": "^7.1.0", - "eslint": "^3.3.1", - "eslint-plugin-chai-friendly": "^0.4.0", - "eslint-plugin-react": "^6.1.2" - } - }, - "packages/reflux-store/node_modules/eslint-plugin-react": { - "version": "6.10.3", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-6.10.3.tgz", - "integrity": "sha1-xUNb6wZ3ThLH2y9qut3L+QDNP3g=", - "extraneous": true, - "dependencies": { - "array.prototype.find": "^2.0.1", - "doctrine": "^1.2.2", - "has": "^1.0.1", - "jsx-ast-utils": "^1.3.4", - "object.assign": "^4.0.4" - }, - "engines": { - "node": ">=0.10" - }, - "peerDependencies": { - "eslint": "^2.0.0 || ^3.0.0" - } - }, - "packages/reflux-store/node_modules/espree": { - "version": "3.5.4", - "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz", - "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==", - "extraneous": true, - "dependencies": { - "acorn": "^5.5.0", - "acorn-jsx": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "packages/reflux-store/node_modules/figures": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", - "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", - "extraneous": true, - "dependencies": { - "escape-string-regexp": "^1.0.5", - "object-assign": "^4.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "packages/reflux-store/node_modules/file-entry-cache": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", - "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", - "extraneous": true, - "dependencies": { - "flat-cache": "^1.2.1", - "object-assign": "^4.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "packages/reflux-store/node_modules/flat-cache": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.4.tgz", - "integrity": "sha512-VwyB3Lkgacfik2vhqR4uv2rvebqmDvFu4jlN/C1RzWoJEo8I7z4Q404oiqYCkq41mni8EzQnm95emU9seckwtg==", - "extraneous": true, - "dependencies": { - "circular-json": "^0.3.1", - "graceful-fs": "^4.1.2", - "rimraf": "~2.6.2", - "write": "^0.2.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "packages/reflux-store/node_modules/globals": { - "version": "9.18.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", - "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", - "extraneous": true, - "engines": { - "node": ">=0.10.0" - } - }, - "packages/reflux-store/node_modules/ignore": { - "version": "3.3.10", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", - "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==", - "extraneous": true - }, - "packages/reflux-store/node_modules/inquirer": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-0.12.0.tgz", - "integrity": "sha1-HvK/1jUE3wvHV4X/+MLEHfEvB34=", - "extraneous": true, - "dependencies": { - "ansi-escapes": "^1.1.0", - "ansi-regex": "^2.0.0", - "chalk": "^1.0.0", - "cli-cursor": "^1.0.1", - "cli-width": "^2.0.0", - "figures": "^1.3.5", - "lodash": "^4.3.0", - "readline2": "^1.0.1", - "run-async": "^0.1.0", - "rx-lite": "^3.1.2", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.0", - "through": "^2.3.6" - } - }, - "packages/reflux-store/node_modules/is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "extraneous": true, - "dependencies": { - "number-is-nan": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "packages/reflux-store/node_modules/jsx-ast-utils": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-1.4.1.tgz", - "integrity": "sha1-OGchPo3Xm/Ho8jAMDPwe+xgsDfE=", - "extraneous": true, - "engines": { - "node": ">=4.0" - } - }, - "packages/reflux-store/node_modules/levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", - "extraneous": true, - "dependencies": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "packages/reflux-store/node_modules/minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "extraneous": true - }, - "packages/reflux-store/node_modules/mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "deprecated": "Legacy versions of mkdirp are no longer supported. Please update to mkdirp 1.x. (Note that the API surface has changed to use Promises in 1.x.)", - "extraneous": true, - "dependencies": { - "minimist": "0.0.8" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "packages/reflux-store/node_modules/ms": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", - "integrity": "sha512-lRLiIR9fSNpnP6TC4v8+4OU7oStC01esuNowdQ34L+Gk8e5Puoc88IqJ+XAY/B3Mn2ZKis8l8HX90oU8ivzUHg==", - "extraneous": true - }, - "packages/reflux-store/node_modules/onetime": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", - "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=", - "extraneous": true, - "engines": { - "node": ">=0.10.0" - } - }, - "packages/reflux-store/node_modules/optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", - "extraneous": true, - "dependencies": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "packages/reflux-store/node_modules/prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", - "extraneous": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "packages/reflux-store/node_modules/progress": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz", - "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=", - "extraneous": true, - "engines": { - "node": ">=0.4.0" - } - }, - "packages/reflux-store/node_modules/restore-cursor": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz", - "integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=", - "extraneous": true, - "dependencies": { - "exit-hook": "^1.0.0", - "onetime": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "packages/reflux-store/node_modules/rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", - "extraneous": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "packages/reflux-store/node_modules/run-async": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-0.1.0.tgz", - "integrity": "sha1-yK1KXhEGYeQCp9IbUw4AnyX444k=", - "extraneous": true, - "dependencies": { - "once": "^1.3.0" - } - }, - "packages/reflux-store/node_modules/slice-ansi": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", - "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=", - "extraneous": true, - "engines": { - "node": ">=0.10.0" - } - }, - "packages/reflux-store/node_modules/string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "extraneous": true, - "dependencies": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "packages/reflux-store/node_modules/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "extraneous": true, - "engines": { - "node": ">=4" - } - }, - "packages/reflux-store/node_modules/strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "extraneous": true, - "engines": { - "node": ">=0.10.0" - } - }, - "packages/reflux-store/node_modules/table": { - "version": "3.8.3", - "resolved": "https://registry.npmjs.org/table/-/table-3.8.3.tgz", - "integrity": "sha1-K7xULw/amGGnVdOUf+/Ys/UThV8=", - "extraneous": true, - "dependencies": { - "ajv": "^4.7.0", - "ajv-keywords": "^1.0.0", - "chalk": "^1.1.1", - "lodash": "^4.0.0", - "slice-ansi": "0.0.4", - "string-width": "^2.0.0" - } - }, - "packages/reflux-store/node_modules/type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", - "extraneous": true, - "dependencies": { - "prelude-ls": "~1.1.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "packages/reflux-store/node_modules/type-detect": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-1.0.0.tgz", - "integrity": "sha1-diIXzAbbJY7EiQihKY6LlRIejqI=", - "extraneous": true, - "engines": { - "node": "*" - } - }, - "packages/reflux-store/node_modules/write": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", - "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", - "extraneous": true, - "dependencies": { - "mkdirp": "^0.5.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, "packages/schema-analysis": { "name": "@mongodb-js/compass-schema-analysis", "version": "1.0.0", @@ -56903,7 +56409,8 @@ "@mongodb-js/atlas-service": { "version": "file:packages/atlas-service", "requires": { - "@mongodb-js/compass-components": "^1.38.1", + "@mongodb-js/compass-app-registry": "^9.4.11", + "@mongodb-js/compass-components": "^1.39.0", "@mongodb-js/compass-logging": "^1.7.2", "@mongodb-js/compass-telemetry": "^1.10.0", "@mongodb-js/compass-user-data": "^0.7.2", @@ -56921,10 +56428,9 @@ "@types/mocha": "^9.0.0", "@types/sinon-chai": "^3.2.5", "chai": "^4.3.6", - "compass-preferences-model": "^2.40.2", + "compass-preferences-model": "^2.41.0", "depcheck": "^1.4.1", "electron": "^36.4.0", - "hadron-app-registry": "^9.4.11", "hadron-ipc": "^3.5.2", "lodash": "^4.17.21", "mocha": "^10.2.0", @@ -56967,24 +56473,25 @@ "@dnd-kit/core": "^6.0.7", "@dnd-kit/sortable": "^7.0.2", "@dnd-kit/utilities": "^3.2.1", - "@mongodb-js/atlas-service": "^0.45.0", - "@mongodb-js/compass-app-stores": "^7.46.0", - "@mongodb-js/compass-collection": "^4.59.0", - "@mongodb-js/compass-components": "^1.38.1", - "@mongodb-js/compass-connections": "^1.60.0", - "@mongodb-js/compass-crud": "^13.60.0", - "@mongodb-js/compass-editor": "^0.40.2", - "@mongodb-js/compass-field-store": "^9.35.0", - "@mongodb-js/compass-generative-ai": "^0.40.0", + "@mongodb-js/atlas-service": "^0.46.0", + "@mongodb-js/compass-app-registry": "^9.4.11", + "@mongodb-js/compass-app-stores": "^7.47.0", + "@mongodb-js/compass-collection": "^4.60.0", + "@mongodb-js/compass-components": "^1.39.0", + "@mongodb-js/compass-connections": "^1.61.0", + "@mongodb-js/compass-crud": "^13.61.0", + "@mongodb-js/compass-editor": "^0.41.0", + "@mongodb-js/compass-field-store": "^9.36.0", + "@mongodb-js/compass-generative-ai": "^0.41.0", "@mongodb-js/compass-logging": "^1.7.2", "@mongodb-js/compass-telemetry": "^1.10.0", "@mongodb-js/compass-utils": "^0.9.2", - "@mongodb-js/compass-workspaces": "^0.41.0", + "@mongodb-js/compass-workspaces": "^0.42.0", "@mongodb-js/eslint-config-compass": "^1.3.10", "@mongodb-js/explain-plan-helper": "^1.4.10", "@mongodb-js/mocha-config-compass": "^1.6.8", "@mongodb-js/mongodb-constants": "^0.11.0", - "@mongodb-js/my-queries-storage": "^0.27.3", + "@mongodb-js/my-queries-storage": "^0.28.0", "@mongodb-js/prettier-config-compass": "^1.2.8", "@mongodb-js/shell-bson-parser": "^1.2.0", "@mongodb-js/testing-library-compass": "^1.3.2", @@ -56994,10 +56501,9 @@ "@types/semver": "^7.3.9", "bson": "^6.10.3", "chai": "^4.3.6", - "compass-preferences-model": "^2.40.2", + "compass-preferences-model": "^2.41.0", "depcheck": "^1.4.1", "electron-mocha": "^12.2.0", - "hadron-app-registry": "^9.4.11", "hadron-document": "^8.8.12", "hadron-type-checker": "^7.4.10", "lodash": "^4.17.21", @@ -57006,7 +56512,7 @@ "mongodb-collection-model": "^5.29.2", "mongodb-data-service": "^22.28.2", "mongodb-database-model": "^2.29.2", - "mongodb-instance-model": "^12.32.2", + "mongodb-instance-model": "^12.33.0", "mongodb-ns": "^2.4.2", "mongodb-query-parser": "^4.3.0", "mongodb-schema": "^12.6.2", @@ -57143,11 +56649,57 @@ } } }, + "@mongodb-js/compass-app-registry": { + "version": "file:packages/compass-app-registry", + "requires": { + "@mongodb-js/eslint-config-compass": "^1.3.10", + "@mongodb-js/mocha-config-compass": "^1.6.8", + "@mongodb-js/prettier-config-compass": "^1.2.8", + "@mongodb-js/testing-library-compass": "^1.3.2", + "@mongodb-js/tsconfig-compass": "^1.2.8", + "@types/chai": "^4.2.21", + "@types/mocha": "^9.0.0", + "@types/reflux": "^6.4.3", + "chai": "^4.1.2", + "depcheck": "^1.4.1", + "eventemitter3": "^4.0.0", + "mocha": "^10.2.0", + "react": "^17.0.2", + "react-redux": "^8.1.3", + "redux": "^4.2.1", + "reflux": "^0.4.1", + "sinon": "^9.0.0", + "typescript": "^5.0.4" + }, + "dependencies": { + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true + }, + "sinon": { + "version": "9.2.4", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-9.2.4.tgz", + "integrity": "sha512-zljcULZQsJxVra28qIAL6ow1Z9tpattkCTEJR4RBP3TGc00FcttsP5pK284Nas5WjMZU5Yzy3kAIp3B3KRf5Yg==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.8.1", + "@sinonjs/fake-timers": "^6.0.1", + "@sinonjs/samsam": "^5.3.1", + "diff": "^4.0.2", + "nise": "^4.0.4", + "supports-color": "^7.1.0" + } + } + } + }, "@mongodb-js/compass-app-stores": { "version": "file:packages/compass-app-stores", "requires": { - "@mongodb-js/compass-components": "^1.38.1", - "@mongodb-js/compass-connections": "^1.60.0", + "@mongodb-js/compass-app-registry": "^9.4.11", + "@mongodb-js/compass-components": "^1.39.0", + "@mongodb-js/compass-connections": "^1.61.0", "@mongodb-js/compass-logging": "^1.7.2", "@mongodb-js/connection-info": "^0.15.2", "@mongodb-js/eslint-config-compass": "^1.3.10", @@ -57159,14 +56711,13 @@ "@types/mocha": "^9.0.0", "@types/sinon-chai": "^3.2.5", "chai": "^4.3.6", - "compass-preferences-model": "^2.40.2", + "compass-preferences-model": "^2.41.0", "depcheck": "^1.4.1", "electron-mocha": "^12.2.0", - "hadron-app-registry": "^9.4.11", "mocha": "^10.2.0", "mongodb-collection-model": "^5.29.2", "mongodb-database-model": "^2.29.2", - "mongodb-instance-model": "^12.32.2", + "mongodb-instance-model": "^12.33.0", "mongodb-ns": "^2.4.2", "nyc": "^15.1.0", "react": "^17.0.2", @@ -57200,12 +56751,13 @@ "@mongodb-js/compass-collection": { "version": "file:packages/compass-collection", "requires": { - "@mongodb-js/compass-app-stores": "^7.46.0", - "@mongodb-js/compass-components": "^1.38.1", - "@mongodb-js/compass-connections": "^1.60.0", + "@mongodb-js/compass-app-registry": "^9.4.11", + "@mongodb-js/compass-app-stores": "^7.47.0", + "@mongodb-js/compass-components": "^1.39.0", + "@mongodb-js/compass-connections": "^1.61.0", "@mongodb-js/compass-logging": "^1.7.2", "@mongodb-js/compass-telemetry": "^1.10.0", - "@mongodb-js/compass-workspaces": "^0.41.0", + "@mongodb-js/compass-workspaces": "^0.42.0", "@mongodb-js/connection-info": "^0.15.2", "@mongodb-js/eslint-config-compass": "^1.3.10", "@mongodb-js/mocha-config-compass": "^1.6.8", @@ -57220,10 +56772,9 @@ "@types/react-dom": "^17.0.10", "@types/sinon-chai": "^3.2.5", "chai": "^4.3.6", - "compass-preferences-model": "^2.40.2", + "compass-preferences-model": "^2.41.0", "depcheck": "^1.4.1", "electron-mocha": "^12.2.0", - "hadron-app-registry": "^9.4.11", "mocha": "^10.2.0", "mongodb-collection-model": "^5.29.2", "mongodb-ns": "^2.4.2", @@ -57316,6 +56867,7 @@ "@leafygreen-ui/tokens": "^2.11.3", "@leafygreen-ui/tooltip": "^13.0.2", "@leafygreen-ui/typography": "^20.0.2", + "@mongodb-js/compass-context-menu": "^0.0.1", "@mongodb-js/eslint-config-compass": "^1.3.10", "@mongodb-js/mocha-config-compass": "^1.6.8", "@mongodb-js/prettier-config-compass": "^1.2.8", @@ -57481,27 +57033,201 @@ } } }, - "@mongodb-js/compass-connection-import-export": { - "version": "file:packages/compass-connection-import-export", + "@mongodb-js/compass-connection-import-export": { + "version": "file:packages/compass-connection-import-export", + "requires": { + "@mongodb-js/compass-components": "^1.39.0", + "@mongodb-js/compass-connections": "^1.61.0", + "@mongodb-js/connection-storage": "^0.36.0", + "@mongodb-js/eslint-config-compass": "^1.3.10", + "@mongodb-js/mocha-config-compass": "^1.6.8", + "@mongodb-js/prettier-config-compass": "^1.2.8", + "@mongodb-js/testing-library-compass": "^1.3.2", + "@mongodb-js/tsconfig-compass": "^1.2.8", + "@types/chai": "^4.2.21", + "@types/chai-dom": "^0.0.10", + "@types/mocha": "^9.0.0", + "@types/react": "^17.0.5", + "@types/sinon-chai": "^3.2.5", + "chai": "^4.3.6", + "compass-preferences-model": "^2.41.0", + "depcheck": "^1.4.1", + "gen-esm-wrapper": "^1.1.0", + "hadron-ipc": "^3.5.2", + "mocha": "^10.2.0", + "nyc": "^15.1.0", + "react": "^17.0.2", + "sinon": "^9.2.3", + "typescript": "^5.0.4" + }, + "dependencies": { + "sinon": { + "version": "9.2.4", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-9.2.4.tgz", + "integrity": "sha512-zljcULZQsJxVra28qIAL6ow1Z9tpattkCTEJR4RBP3TGc00FcttsP5pK284Nas5WjMZU5Yzy3kAIp3B3KRf5Yg==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.8.1", + "@sinonjs/fake-timers": "^6.0.1", + "@sinonjs/samsam": "^5.3.1", + "diff": "^4.0.2", + "nise": "^4.0.4", + "supports-color": "^7.1.0" + }, + "dependencies": { + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true + } + } + } + } + }, + "@mongodb-js/compass-connections": { + "version": "file:packages/compass-connections", + "requires": { + "@mongodb-js/compass-app-registry": "^9.4.11", + "@mongodb-js/compass-components": "^1.39.0", + "@mongodb-js/compass-logging": "^1.7.2", + "@mongodb-js/compass-telemetry": "^1.10.0", + "@mongodb-js/compass-utils": "^0.9.2", + "@mongodb-js/connection-form": "^1.53.0", + "@mongodb-js/connection-info": "^0.15.2", + "@mongodb-js/connection-storage": "^0.36.0", + "@mongodb-js/eslint-config-compass": "^1.3.10", + "@mongodb-js/mocha-config-compass": "^1.6.8", + "@mongodb-js/prettier-config-compass": "^1.2.8", + "@mongodb-js/testing-library-compass": "^1.3.2", + "@mongodb-js/tsconfig-compass": "^1.2.8", + "@types/chai": "^4.2.21", + "@types/chai-dom": "^0.0.10", + "@types/mocha": "^9.0.0", + "@types/react": "^17.0.5", + "@types/react-dom": "^17.0.10", + "@types/semver": "^7.3.9", + "@types/sinon-chai": "^3.2.5", + "bson": "^6.10.3", + "chai": "^4.3.4", + "compass-preferences-model": "^2.41.0", + "depcheck": "^1.4.1", + "electron-mocha": "^12.2.0", + "lodash": "^4.17.21", + "mocha": "^10.2.0", + "mongodb": "^6.16.0", + "mongodb-build-info": "^1.7.2", + "mongodb-connection-string-url": "^3.0.1", + "mongodb-data-service": "^22.28.2", + "nyc": "^15.1.0", + "react": "^17.0.2", + "react-dom": "^17.0.2", + "react-redux": "^8.1.3", + "redux": "^4.2.1", + "redux-thunk": "^2.4.2", + "semver": "^7.6.2", + "sinon": "^9.2.3", + "xvfb-maybe": "^0.2.1" + }, + "dependencies": { + "sinon": { + "version": "9.2.4", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-9.2.4.tgz", + "integrity": "sha512-zljcULZQsJxVra28qIAL6ow1Z9tpattkCTEJR4RBP3TGc00FcttsP5pK284Nas5WjMZU5Yzy3kAIp3B3KRf5Yg==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.8.1", + "@sinonjs/fake-timers": "^6.0.1", + "@sinonjs/samsam": "^5.3.1", + "diff": "^4.0.2", + "nise": "^4.0.4", + "supports-color": "^7.1.0" + }, + "dependencies": { + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true + } + } + } + } + }, + "@mongodb-js/compass-connections-navigation": { + "version": "file:packages/compass-connections-navigation", + "requires": { + "@mongodb-js/compass-components": "^1.39.0", + "@mongodb-js/compass-connections": "^1.61.0", + "@mongodb-js/compass-workspaces": "^0.42.0", + "@mongodb-js/connection-form": "^1.53.0", + "@mongodb-js/connection-info": "^0.15.2", + "@mongodb-js/eslint-config-compass": "^1.3.10", + "@mongodb-js/mocha-config-compass": "^1.6.8", + "@mongodb-js/prettier-config-compass": "^1.2.8", + "@mongodb-js/testing-library-compass": "^1.3.2", + "@mongodb-js/tsconfig-compass": "^1.2.8", + "@types/chai": "^4.2.21", + "@types/chai-dom": "^0.0.10", + "@types/mocha": "^9.0.0", + "@types/react": "^17.0.5", + "@types/react-dom": "^17.0.10", + "@types/react-virtualized-auto-sizer": "^1.0.1", + "@types/react-window": "^1.8.5", + "@types/sinon-chai": "^3.2.5", + "chai": "^4.3.4", + "compass-preferences-model": "^2.41.0", + "depcheck": "^1.4.1", + "mocha": "^10.2.0", + "mongodb-build-info": "^1.7.2", + "nyc": "^15.1.0", + "react": "^17.0.2", + "react-dom": "^17.0.2", + "react-virtualized-auto-sizer": "^1.0.6", + "react-window": "^1.8.6", + "sinon": "^9.2.3", + "typescript": "^5.0.4" + }, + "dependencies": { + "sinon": { + "version": "9.2.4", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-9.2.4.tgz", + "integrity": "sha512-zljcULZQsJxVra28qIAL6ow1Z9tpattkCTEJR4RBP3TGc00FcttsP5pK284Nas5WjMZU5Yzy3kAIp3B3KRf5Yg==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.8.1", + "@sinonjs/fake-timers": "^6.0.1", + "@sinonjs/samsam": "^5.3.1", + "diff": "^4.0.2", + "nise": "^4.0.4", + "supports-color": "^7.1.0" + }, + "dependencies": { + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true + } + } + } + } + }, + "@mongodb-js/compass-context-menu": { + "version": "file:packages/compass-context-menu", "requires": { - "@mongodb-js/compass-components": "^1.38.1", - "@mongodb-js/compass-connections": "^1.60.0", - "@mongodb-js/connection-storage": "^0.35.0", - "@mongodb-js/eslint-config-compass": "^1.3.10", + "@mongodb-js/eslint-config-compass": "^1.3.8", "@mongodb-js/mocha-config-compass": "^1.6.8", "@mongodb-js/prettier-config-compass": "^1.2.8", - "@mongodb-js/testing-library-compass": "^1.3.2", + "@mongodb-js/testing-library-compass": "^1.3.1", "@mongodb-js/tsconfig-compass": "^1.2.8", "@types/chai": "^4.2.21", - "@types/chai-dom": "^0.0.10", "@types/mocha": "^9.0.0", "@types/react": "^17.0.5", "@types/sinon-chai": "^3.2.5", "chai": "^4.3.6", - "compass-preferences-model": "^2.40.2", "depcheck": "^1.4.1", "gen-esm-wrapper": "^1.1.0", - "hadron-ipc": "^3.5.2", "mocha": "^10.2.0", "nyc": "^15.1.0", "react": "^17.0.2", @@ -57509,6 +57235,12 @@ "typescript": "^5.0.4" }, "dependencies": { + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true + }, "sinon": { "version": "9.2.4", "resolved": "https://registry.npmjs.org/sinon/-/sinon-9.2.4.tgz", @@ -57521,142 +57253,6 @@ "diff": "^4.0.2", "nise": "^4.0.4", "supports-color": "^7.1.0" - }, - "dependencies": { - "diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true - } - } - } - } - }, - "@mongodb-js/compass-connections": { - "version": "file:packages/compass-connections", - "requires": { - "@mongodb-js/compass-components": "^1.38.1", - "@mongodb-js/compass-logging": "^1.7.2", - "@mongodb-js/compass-telemetry": "^1.10.0", - "@mongodb-js/compass-utils": "^0.9.2", - "@mongodb-js/connection-form": "^1.52.3", - "@mongodb-js/connection-info": "^0.15.2", - "@mongodb-js/connection-storage": "^0.35.0", - "@mongodb-js/eslint-config-compass": "^1.3.10", - "@mongodb-js/mocha-config-compass": "^1.6.8", - "@mongodb-js/prettier-config-compass": "^1.2.8", - "@mongodb-js/testing-library-compass": "^1.3.2", - "@mongodb-js/tsconfig-compass": "^1.2.8", - "@types/chai": "^4.2.21", - "@types/chai-dom": "^0.0.10", - "@types/mocha": "^9.0.0", - "@types/react": "^17.0.5", - "@types/react-dom": "^17.0.10", - "@types/semver": "^7.3.9", - "@types/sinon-chai": "^3.2.5", - "bson": "^6.10.3", - "chai": "^4.3.4", - "compass-preferences-model": "^2.40.2", - "depcheck": "^1.4.1", - "electron-mocha": "^12.2.0", - "hadron-app-registry": "^9.4.11", - "lodash": "^4.17.21", - "mocha": "^10.2.0", - "mongodb": "^6.16.0", - "mongodb-build-info": "^1.7.2", - "mongodb-connection-string-url": "^3.0.1", - "mongodb-data-service": "^22.28.2", - "nyc": "^15.1.0", - "react": "^17.0.2", - "react-dom": "^17.0.2", - "react-redux": "^8.1.3", - "redux": "^4.2.1", - "redux-thunk": "^2.4.2", - "semver": "^7.6.2", - "sinon": "^9.2.3", - "xvfb-maybe": "^0.2.1" - }, - "dependencies": { - "sinon": { - "version": "9.2.4", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-9.2.4.tgz", - "integrity": "sha512-zljcULZQsJxVra28qIAL6ow1Z9tpattkCTEJR4RBP3TGc00FcttsP5pK284Nas5WjMZU5Yzy3kAIp3B3KRf5Yg==", - "dev": true, - "requires": { - "@sinonjs/commons": "^1.8.1", - "@sinonjs/fake-timers": "^6.0.1", - "@sinonjs/samsam": "^5.3.1", - "diff": "^4.0.2", - "nise": "^4.0.4", - "supports-color": "^7.1.0" - }, - "dependencies": { - "diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true - } - } - } - } - }, - "@mongodb-js/compass-connections-navigation": { - "version": "file:packages/compass-connections-navigation", - "requires": { - "@mongodb-js/compass-components": "^1.38.1", - "@mongodb-js/compass-connections": "^1.60.0", - "@mongodb-js/compass-workspaces": "^0.41.0", - "@mongodb-js/connection-form": "^1.52.3", - "@mongodb-js/connection-info": "^0.15.2", - "@mongodb-js/eslint-config-compass": "^1.3.10", - "@mongodb-js/mocha-config-compass": "^1.6.8", - "@mongodb-js/prettier-config-compass": "^1.2.8", - "@mongodb-js/testing-library-compass": "^1.3.2", - "@mongodb-js/tsconfig-compass": "^1.2.8", - "@types/chai": "^4.2.21", - "@types/chai-dom": "^0.0.10", - "@types/mocha": "^9.0.0", - "@types/react": "^17.0.5", - "@types/react-dom": "^17.0.10", - "@types/react-virtualized-auto-sizer": "^1.0.1", - "@types/react-window": "^1.8.5", - "@types/sinon-chai": "^3.2.5", - "chai": "^4.3.4", - "compass-preferences-model": "^2.40.2", - "depcheck": "^1.4.1", - "mocha": "^10.2.0", - "mongodb-build-info": "^1.7.2", - "nyc": "^15.1.0", - "react": "^17.0.2", - "react-dom": "^17.0.2", - "react-virtualized-auto-sizer": "^1.0.6", - "react-window": "^1.8.6", - "sinon": "^9.2.3", - "typescript": "^5.0.4" - }, - "dependencies": { - "sinon": { - "version": "9.2.4", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-9.2.4.tgz", - "integrity": "sha512-zljcULZQsJxVra28qIAL6ow1Z9tpattkCTEJR4RBP3TGc00FcttsP5pK284Nas5WjMZU5Yzy3kAIp3B3KRf5Yg==", - "dev": true, - "requires": { - "@sinonjs/commons": "^1.8.1", - "@sinonjs/fake-timers": "^6.0.1", - "@sinonjs/samsam": "^5.3.1", - "diff": "^4.0.2", - "nise": "^4.0.4", - "supports-color": "^7.1.0" - }, - "dependencies": { - "diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true - } } } } @@ -57664,21 +57260,22 @@ "@mongodb-js/compass-crud": { "version": "file:packages/compass-crud", "requires": { - "@mongodb-js/compass-app-stores": "^7.46.0", - "@mongodb-js/compass-collection": "^4.59.0", - "@mongodb-js/compass-components": "^1.38.1", - "@mongodb-js/compass-connections": "^1.60.0", - "@mongodb-js/compass-editor": "^0.40.2", - "@mongodb-js/compass-field-store": "^9.35.0", + "@mongodb-js/compass-app-registry": "^9.4.11", + "@mongodb-js/compass-app-stores": "^7.47.0", + "@mongodb-js/compass-collection": "^4.60.0", + "@mongodb-js/compass-components": "^1.39.0", + "@mongodb-js/compass-connections": "^1.61.0", + "@mongodb-js/compass-editor": "^0.41.0", + "@mongodb-js/compass-field-store": "^9.36.0", "@mongodb-js/compass-logging": "^1.7.2", - "@mongodb-js/compass-query-bar": "^8.61.0", + "@mongodb-js/compass-query-bar": "^8.62.0", "@mongodb-js/compass-telemetry": "^1.10.0", "@mongodb-js/compass-test-server": "^0.3.10", - "@mongodb-js/compass-workspaces": "^0.41.0", + "@mongodb-js/compass-workspaces": "^0.42.0", "@mongodb-js/eslint-config-compass": "^1.3.10", "@mongodb-js/explain-plan-helper": "^1.4.10", "@mongodb-js/mocha-config-compass": "^1.6.8", - "@mongodb-js/my-queries-storage": "^0.27.3", + "@mongodb-js/my-queries-storage": "^0.28.0", "@mongodb-js/prettier-config-compass": "^1.2.8", "@mongodb-js/reflux-state-mixin": "^1.2.10", "@mongodb-js/shell-bson-parser": "^1.2.0", @@ -57691,12 +57288,11 @@ "bson": "^6.10.3", "chai": "^4.1.2", "chai-as-promised": "^7.1.1", - "compass-preferences-model": "^2.40.2", + "compass-preferences-model": "^2.41.0", "depcheck": "^1.4.1", "electron": "^36.4.0", "electron-mocha": "^12.2.0", "enzyme": "^3.11.0", - "hadron-app-registry": "^9.4.11", "hadron-document": "^8.8.12", "hadron-type-checker": "^7.4.10", "jsondiffpatch": "^0.5.0", @@ -57704,7 +57300,7 @@ "mocha": "^10.2.0", "mongodb": "^6.16.0", "mongodb-data-service": "^22.28.2", - "mongodb-instance-model": "^12.32.2", + "mongodb-instance-model": "^12.33.0", "mongodb-ns": "^2.4.2", "mongodb-query-parser": "^4.3.0", "numeral": "^2.0.6", @@ -57714,7 +57310,7 @@ "react-dom": "^17.0.2", "reflux": "^0.4.1", "semver": "^7.6.2", - "sinon": "^8.1.1", + "sinon": "^17.0.1", "typescript": "^5.0.4" }, "dependencies": { @@ -57726,6 +57322,49 @@ "acorn": "^8.1.0" } }, + "@sinonjs/commons": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", + "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", + "dev": true, + "requires": { + "type-detect": "4.0.8" + } + }, + "@sinonjs/fake-timers": { + "version": "11.3.1", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-11.3.1.tgz", + "integrity": "sha512-EVJO7nW5M/F5Tur0Rf2z/QoMo+1Ia963RiMtapiQrEWvY0iBUvADo8Beegwjpnle5BHkyHuoxSTW3jF43H1XRA==", + "dev": true, + "requires": { + "@sinonjs/commons": "^3.0.1" + } + }, + "@sinonjs/samsam": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-8.0.2.tgz", + "integrity": "sha512-v46t/fwnhejRSFTGqbpn9u+LQ9xJDse10gNnPgAcxgdoCDMXj/G2asWAC/8Qs+BAZDicX+MNZouXT1A7c83kVw==", + "dev": true, + "requires": { + "@sinonjs/commons": "^3.0.1", + "lodash.get": "^4.4.2", + "type-detect": "^4.1.0" + }, + "dependencies": { + "type-detect": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz", + "integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==", + "dev": true + } + } + }, + "just-extend": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-6.2.0.tgz", + "integrity": "sha512-cYofQu2Xpom82S6qD778jBDpwvvy39s1l/hrYij2u9AMdQcGRpaBu6kY4mVhuno5kJVi1DAz4aiphA2WI1/OAw==", + "dev": true + }, "mongodb-query-parser": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/mongodb-query-parser/-/mongodb-query-parser-4.3.0.tgz", @@ -57737,24 +57376,58 @@ "lodash": "^4.17.21" } }, + "nise": { + "version": "5.1.9", + "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.9.tgz", + "integrity": "sha512-qOnoujW4SV6e40dYxJOb3uvuoPHtmLzIk4TFo+j0jPJoC+5Z9xja5qH5JZobEPsa8+YYphMrOSwnrshEhG2qww==", + "dev": true, + "requires": { + "@sinonjs/commons": "^3.0.0", + "@sinonjs/fake-timers": "^11.2.2", + "@sinonjs/text-encoding": "^0.7.2", + "just-extend": "^6.2.0", + "path-to-regexp": "^6.2.1" + } + }, "numeral": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/numeral/-/numeral-2.0.6.tgz", "integrity": "sha512-qaKRmtYPZ5qdw4jWJD6bxEf1FJEqllJrwxCLIm0sQU/A7v2/czigzOb+C2uSiFsa9lBUzeH7M1oK+Q+OLxL3kA==" + }, + "path-to-regexp": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.3.0.tgz", + "integrity": "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==", + "dev": true + }, + "sinon": { + "version": "17.0.1", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-17.0.1.tgz", + "integrity": "sha512-wmwE19Lie0MLT+ZYNpDymasPHUKTaZHUH/pKEubRXIzySv9Atnlw+BUMGCzWgV7b7wO+Hw6f1TEOr0IUnmU8/g==", + "dev": true, + "requires": { + "@sinonjs/commons": "^3.0.0", + "@sinonjs/fake-timers": "^11.2.2", + "@sinonjs/samsam": "^8.0.0", + "diff": "^5.1.0", + "nise": "^5.1.5", + "supports-color": "^7.2.0" + } } } }, "@mongodb-js/compass-data-modeling": { "version": "file:packages/compass-data-modeling", "requires": { - "@mongodb-js/compass-app-stores": "^7.46.0", - "@mongodb-js/compass-components": "^1.38.1", - "@mongodb-js/compass-connections": "^1.60.0", - "@mongodb-js/compass-editor": "^0.40.2", + "@mongodb-js/compass-app-registry": "^9.4.11", + "@mongodb-js/compass-app-stores": "^7.47.0", + "@mongodb-js/compass-components": "^1.39.0", + "@mongodb-js/compass-connections": "^1.61.0", + "@mongodb-js/compass-editor": "^0.41.0", "@mongodb-js/compass-logging": "^1.7.2", "@mongodb-js/compass-telemetry": "^1.10.0", "@mongodb-js/compass-user-data": "^0.7.2", - "@mongodb-js/compass-workspaces": "^0.41.0", + "@mongodb-js/compass-workspaces": "^0.42.0", "@mongodb-js/diagramming": "^1.0.2", "@mongodb-js/eslint-config-compass": "^1.3.10", "@mongodb-js/mocha-config-compass": "^1.6.8", @@ -57769,9 +57442,8 @@ "@types/sinon-chai": "^3.2.5", "bson": "^6.10.3", "chai": "^4.3.6", - "compass-preferences-model": "^2.40.2", + "compass-preferences-model": "^2.41.0", "depcheck": "^1.4.1", - "hadron-app-registry": "^9.4.11", "lodash": "^4.17.21", "mocha": "^10.2.0", "mongodb": "^6.14.1", @@ -57993,31 +57665,31 @@ "@mongodb-js/compass-databases-collections": { "version": "file:packages/databases-collections", "requires": { - "@mongodb-js/compass-app-stores": "^7.46.0", - "@mongodb-js/compass-components": "^1.38.1", - "@mongodb-js/compass-connections": "^1.60.0", - "@mongodb-js/compass-editor": "^0.40.2", + "@mongodb-js/compass-app-registry": "^9.4.11", + "@mongodb-js/compass-app-stores": "^7.47.0", + "@mongodb-js/compass-components": "^1.39.0", + "@mongodb-js/compass-connections": "^1.61.0", + "@mongodb-js/compass-editor": "^0.41.0", "@mongodb-js/compass-logging": "^1.7.2", "@mongodb-js/compass-telemetry": "^1.10.0", - "@mongodb-js/compass-workspaces": "^0.41.0", - "@mongodb-js/databases-collections-list": "^1.57.0", + "@mongodb-js/compass-workspaces": "^0.42.0", + "@mongodb-js/databases-collections-list": "^1.58.0", "@mongodb-js/eslint-config-compass": "^1.3.10", "@mongodb-js/mocha-config-compass": "^1.6.8", - "@mongodb-js/my-queries-storage": "^0.27.3", + "@mongodb-js/my-queries-storage": "^0.28.0", "@mongodb-js/prettier-config-compass": "^1.2.8", "@mongodb-js/testing-library-compass": "^1.3.2", "@mongodb-js/tsconfig-compass": "^1.2.8", "bson": "^6.10.3", "chai": "^4.2.0", - "compass-preferences-model": "^2.40.2", + "compass-preferences-model": "^2.41.0", "depcheck": "^1.4.1", "enzyme": "^3.11.0", - "hadron-app-registry": "^9.4.11", "lodash": "^4.17.21", "mocha": "^10.2.0", "mongodb-collection-model": "^5.29.2", "mongodb-database-model": "^2.29.2", - "mongodb-instance-model": "^12.32.2", + "mongodb-instance-model": "^12.33.0", "mongodb-ns": "^2.4.2", "mongodb-query-parser": "^4.3.0", "nyc": "^15.1.0", @@ -58085,7 +57757,7 @@ "@codemirror/state": "^6.1.4", "@codemirror/view": "^6.7.1", "@lezer/highlight": "^1.2.0", - "@mongodb-js/compass-components": "^1.38.1", + "@mongodb-js/compass-components": "^1.39.0", "@mongodb-js/eslint-config-compass": "^1.3.10", "@mongodb-js/mocha-config-compass": "^1.6.8", "@mongodb-js/mongodb-constants": "^0.11.0", @@ -58161,10 +57833,11 @@ "@mongodb-js/compass-explain-plan": { "version": "file:packages/compass-explain-plan", "requires": { - "@mongodb-js/compass-collection": "^4.59.0", - "@mongodb-js/compass-components": "^1.38.1", - "@mongodb-js/compass-connections": "^1.60.0", - "@mongodb-js/compass-editor": "^0.40.2", + "@mongodb-js/compass-app-registry": "^9.4.11", + "@mongodb-js/compass-collection": "^4.60.0", + "@mongodb-js/compass-components": "^1.39.0", + "@mongodb-js/compass-connections": "^1.61.0", + "@mongodb-js/compass-editor": "^0.41.0", "@mongodb-js/compass-logging": "^1.7.2", "@mongodb-js/compass-telemetry": "^1.10.0", "@mongodb-js/eslint-config-compass": "^1.3.10", @@ -58177,14 +57850,13 @@ "@types/d3-flextree": "^2.1.0", "@types/d3-hierarchy": "^3.1.2", "chai": "^4.2.0", - "compass-preferences-model": "^2.40.2", + "compass-preferences-model": "^2.41.0", "d3": "^3.5.17", "d3-flextree": "^2.1.2", "d3-hierarchy": "^3.1.2", "depcheck": "^1.4.1", "electron": "^36.4.0", "electron-mocha": "^12.2.0", - "hadron-app-registry": "^9.4.11", "lodash": "^4.17.21", "mocha": "^10.2.0", "mongodb": "^6.16.0", @@ -58230,11 +57902,12 @@ "@mongodb-js/compass-export-to-language": { "version": "file:packages/compass-export-to-language", "requires": { - "@mongodb-js/compass-collection": "^4.59.0", - "@mongodb-js/compass-components": "^1.38.1", - "@mongodb-js/compass-connections": "^1.60.0", - "@mongodb-js/compass-editor": "^0.40.2", - "@mongodb-js/compass-maybe-protect-connection-string": "^0.38.2", + "@mongodb-js/compass-app-registry": "^9.4.11", + "@mongodb-js/compass-collection": "^4.60.0", + "@mongodb-js/compass-components": "^1.39.0", + "@mongodb-js/compass-connections": "^1.61.0", + "@mongodb-js/compass-editor": "^0.41.0", + "@mongodb-js/compass-maybe-protect-connection-string": "^0.39.0", "@mongodb-js/compass-telemetry": "^1.10.0", "@mongodb-js/eslint-config-compass": "^1.3.10", "@mongodb-js/mocha-config-compass": "^1.6.8", @@ -58244,9 +57917,8 @@ "@mongodb-js/tsconfig-compass": "^1.2.8", "bson-transpilers": "^3.2.10", "chai": "^4.3.6", - "compass-preferences-model": "^2.40.2", + "compass-preferences-model": "^2.41.0", "depcheck": "^1.4.1", - "hadron-app-registry": "^9.4.11", "mocha": "^10.2.0", "mongodb-ns": "^2.4.2", "nyc": "^15.1.0", @@ -58293,7 +57965,8 @@ "@mongodb-js/compass-field-store": { "version": "file:packages/compass-field-store", "requires": { - "@mongodb-js/compass-connections": "^1.60.0", + "@mongodb-js/compass-app-registry": "^9.4.11", + "@mongodb-js/compass-connections": "^1.61.0", "@mongodb-js/compass-logging": "^1.7.2", "@mongodb-js/eslint-config-compass": "^1.3.10", "@mongodb-js/mocha-config-compass": "^1.6.8", @@ -58306,7 +57979,6 @@ "chai": "^4.3.6", "depcheck": "^1.4.1", "electron-mocha": "^12.2.0", - "hadron-app-registry": "^9.4.11", "lodash": "^4.17.21", "mocha": "^10.2.0", "mongodb-schema": "^12.6.2", @@ -58415,7 +58087,8 @@ "@mongodb-js/compass-find-in-page": { "version": "file:packages/compass-find-in-page", "requires": { - "@mongodb-js/compass-components": "^1.38.1", + "@mongodb-js/compass-app-registry": "^9.4.11", + "@mongodb-js/compass-components": "^1.39.0", "@mongodb-js/eslint-config-compass": "^1.3.10", "@mongodb-js/mocha-config-compass": "^1.6.8", "@mongodb-js/prettier-config-compass": "^1.2.8", @@ -58431,7 +58104,6 @@ "depcheck": "^1.4.1", "electron": "^36.4.0", "electron-mocha": "^12.2.0", - "hadron-app-registry": "^9.4.11", "hadron-ipc": "^3.5.2", "mocha": "^10.2.0", "nyc": "^15.1.0", @@ -58472,10 +58144,11 @@ "@mongodb-js/compass-generative-ai": { "version": "file:packages/compass-generative-ai", "requires": { - "@mongodb-js/atlas-service": "^0.45.0", - "@mongodb-js/compass-components": "^1.38.1", - "@mongodb-js/compass-connections": "^1.60.0", - "@mongodb-js/compass-intercom": "^0.24.2", + "@mongodb-js/atlas-service": "^0.46.0", + "@mongodb-js/compass-app-registry": "^9.4.11", + "@mongodb-js/compass-components": "^1.39.0", + "@mongodb-js/compass-connections": "^1.61.0", + "@mongodb-js/compass-intercom": "^0.25.0", "@mongodb-js/compass-logging": "^1.7.2", "@mongodb-js/compass-telemetry": "^1.10.0", "@mongodb-js/compass-utils": "^0.9.2", @@ -58492,10 +58165,9 @@ "@types/sinon-chai": "^3.2.5", "bson": "^6.10.3", "chai": "^4.3.6", - "compass-preferences-model": "^2.40.2", + "compass-preferences-model": "^2.41.0", "depcheck": "^1.4.1", "electron-mocha": "^12.2.0", - "hadron-app-registry": "^9.4.11", "mocha": "^10.2.0", "mongodb": "^6.16.0", "mongodb-schema": "^12.6.2", @@ -58627,11 +58299,12 @@ "@mongodb-js/compass-global-writes": { "version": "file:packages/compass-global-writes", "requires": { - "@mongodb-js/atlas-service": "^0.45.0", - "@mongodb-js/compass-collection": "^4.59.0", - "@mongodb-js/compass-components": "^1.38.1", - "@mongodb-js/compass-connections": "^1.60.0", - "@mongodb-js/compass-field-store": "^9.35.0", + "@mongodb-js/atlas-service": "^0.46.0", + "@mongodb-js/compass-app-registry": "^9.4.11", + "@mongodb-js/compass-collection": "^4.60.0", + "@mongodb-js/compass-components": "^1.39.0", + "@mongodb-js/compass-connections": "^1.61.0", + "@mongodb-js/compass-field-store": "^9.36.0", "@mongodb-js/compass-logging": "^1.7.2", "@mongodb-js/compass-telemetry": "^1.10.0", "@mongodb-js/eslint-config-compass": "^1.3.10", @@ -58647,7 +58320,6 @@ "@types/sinon-chai": "^3.2.5", "chai": "^4.3.6", "depcheck": "^1.4.1", - "hadron-app-registry": "^9.4.11", "lodash": "^4.17.21", "mocha": "^10.2.0", "mongodb-ns": "^2.4.2", @@ -58743,14 +58415,15 @@ "version": "file:packages/compass-import-export", "requires": { "@electron/remote": "^2.1.2", - "@mongodb-js/compass-components": "^1.38.1", - "@mongodb-js/compass-connections": "^1.60.0", - "@mongodb-js/compass-editor": "^0.40.2", + "@mongodb-js/compass-app-registry": "^9.4.11", + "@mongodb-js/compass-components": "^1.39.0", + "@mongodb-js/compass-connections": "^1.61.0", + "@mongodb-js/compass-editor": "^0.41.0", "@mongodb-js/compass-logging": "^1.7.2", "@mongodb-js/compass-telemetry": "^1.10.0", "@mongodb-js/compass-test-server": "^0.3.10", "@mongodb-js/compass-utils": "^0.9.2", - "@mongodb-js/compass-workspaces": "^0.41.0", + "@mongodb-js/compass-workspaces": "^0.42.0", "@mongodb-js/eslint-config-compass": "^1.3.10", "@mongodb-js/mocha-config-compass": "^1.6.8", "@mongodb-js/prettier-config-compass": "^1.2.8", @@ -58769,12 +58442,11 @@ "bson": "^6.10.3", "chai": "^4.3.6", "chai-as-promised": "^7.1.1", - "compass-preferences-model": "^2.40.2", + "compass-preferences-model": "^2.41.0", "debug": "^4.3.4", "depcheck": "^1.4.1", "electron": "^36.4.0", "electron-mocha": "^12.2.0", - "hadron-app-registry": "^9.4.11", "hadron-document": "^8.8.12", "hadron-ipc": "^3.5.2", "lodash": "^4.17.21", @@ -58914,15 +58586,16 @@ "@mongodb-js/compass-indexes": { "version": "file:packages/compass-indexes", "requires": { - "@mongodb-js/atlas-service": "^0.45.0", - "@mongodb-js/compass-app-stores": "^7.46.0", - "@mongodb-js/compass-components": "^1.38.1", - "@mongodb-js/compass-connections": "^1.60.0", - "@mongodb-js/compass-editor": "^0.40.2", - "@mongodb-js/compass-field-store": "^9.35.0", + "@mongodb-js/atlas-service": "^0.46.0", + "@mongodb-js/compass-app-registry": "^9.4.11", + "@mongodb-js/compass-app-stores": "^7.47.0", + "@mongodb-js/compass-components": "^1.39.0", + "@mongodb-js/compass-connections": "^1.61.0", + "@mongodb-js/compass-editor": "^0.41.0", + "@mongodb-js/compass-field-store": "^9.36.0", "@mongodb-js/compass-logging": "^1.7.2", "@mongodb-js/compass-telemetry": "^1.10.0", - "@mongodb-js/compass-workspaces": "^0.41.0", + "@mongodb-js/compass-workspaces": "^0.42.0", "@mongodb-js/eslint-config-compass": "^1.3.10", "@mongodb-js/mocha-config-compass": "^1.6.8", "@mongodb-js/mongodb-constants": "^0.11.0", @@ -58933,11 +58606,10 @@ "@types/numeral": "^2.0.5", "bson": "^6.10.3", "chai": "^4.2.0", - "compass-preferences-model": "^2.40.2", + "compass-preferences-model": "^2.41.0", "depcheck": "^1.4.1", "electron": "^36.4.0", "electron-mocha": "^12.2.0", - "hadron-app-registry": "^9.4.11", "lodash": "^4.17.21", "mocha": "^10.2.0", "mongodb": "^6.16.0", @@ -59027,7 +58699,7 @@ "@types/mocha": "^9.0.0", "@types/sinon-chai": "^3.2.5", "chai": "^4.3.6", - "compass-preferences-model": "^2.40.2", + "compass-preferences-model": "^2.41.0", "depcheck": "^1.4.1", "gen-esm-wrapper": "^1.1.0", "nyc": "^15.1.0", @@ -59119,6 +58791,7 @@ "@mongodb-js/compass-logging": { "version": "file:packages/compass-logging", "requires": { + "@mongodb-js/compass-app-registry": "^9.4.11", "@mongodb-js/eslint-config-compass": "^1.3.10", "@mongodb-js/mocha-config-compass": "^1.6.8", "@mongodb-js/prettier-config-compass": "^1.2.8", @@ -59130,7 +58803,6 @@ "chai": "^4.3.4", "debug": "^4.3.4", "depcheck": "^1.4.1", - "hadron-app-registry": "^9.4.11", "hadron-ipc": "^3.5.2", "is-electron-renderer": "^2.0.1", "mocha": "^10.2.0", @@ -59176,7 +58848,7 @@ "@types/mocha": "^9.0.0", "@types/sinon-chai": "^3.2.5", "chai": "^4.3.6", - "compass-preferences-model": "^2.40.2", + "compass-preferences-model": "^2.41.0", "depcheck": "^1.4.1", "gen-esm-wrapper": "^1.1.0", "mocha": "^10.2.0", @@ -59213,34 +58885,34 @@ "@mongodb-js/compass-query-bar": { "version": "file:packages/compass-query-bar", "requires": { - "@mongodb-js/atlas-service": "^0.45.0", - "@mongodb-js/compass-app-stores": "^7.46.0", - "@mongodb-js/compass-collection": "^4.59.0", - "@mongodb-js/compass-components": "^1.38.1", - "@mongodb-js/compass-connections": "^1.60.0", - "@mongodb-js/compass-editor": "^0.40.2", - "@mongodb-js/compass-field-store": "^9.35.0", - "@mongodb-js/compass-generative-ai": "^0.40.0", + "@mongodb-js/atlas-service": "^0.46.0", + "@mongodb-js/compass-app-registry": "^9.4.11", + "@mongodb-js/compass-app-stores": "^7.47.0", + "@mongodb-js/compass-collection": "^4.60.0", + "@mongodb-js/compass-components": "^1.39.0", + "@mongodb-js/compass-connections": "^1.61.0", + "@mongodb-js/compass-editor": "^0.41.0", + "@mongodb-js/compass-field-store": "^9.36.0", + "@mongodb-js/compass-generative-ai": "^0.41.0", "@mongodb-js/compass-logging": "^1.7.2", "@mongodb-js/compass-telemetry": "^1.10.0", "@mongodb-js/eslint-config-compass": "^1.3.10", "@mongodb-js/mocha-config-compass": "^1.6.8", "@mongodb-js/mongodb-constants": "^0.11.0", - "@mongodb-js/my-queries-storage": "^0.27.3", + "@mongodb-js/my-queries-storage": "^0.28.0", "@mongodb-js/prettier-config-compass": "^1.2.8", "@mongodb-js/testing-library-compass": "^1.3.2", "@mongodb-js/tsconfig-compass": "^1.2.8", "bson": "^6.10.3", "chai": "^4.2.0", - "compass-preferences-model": "^2.40.2", + "compass-preferences-model": "^2.41.0", "depcheck": "^1.4.1", "electron": "^36.4.0", "electron-mocha": "^12.2.0", - "hadron-app-registry": "^9.4.11", "lodash": "^4.17.21", "mocha": "^10.2.0", "mongodb": "^6.16.0", - "mongodb-instance-model": "^12.32.2", + "mongodb-instance-model": "^12.33.0", "mongodb-ns": "^2.4.2", "mongodb-query-parser": "^4.3.0", "mongodb-query-util": "^2.4.10", @@ -59378,17 +59050,18 @@ "@mongodb-js/compass-saved-aggregations-queries": { "version": "file:packages/compass-saved-aggregations-queries", "requires": { - "@mongodb-js/compass-app-stores": "^7.46.0", - "@mongodb-js/compass-components": "^1.38.1", - "@mongodb-js/compass-connections": "^1.60.0", + "@mongodb-js/compass-app-registry": "^9.4.11", + "@mongodb-js/compass-app-stores": "^7.47.0", + "@mongodb-js/compass-components": "^1.39.0", + "@mongodb-js/compass-connections": "^1.61.0", "@mongodb-js/compass-logging": "^1.7.2", "@mongodb-js/compass-telemetry": "^1.10.0", - "@mongodb-js/compass-workspaces": "^0.41.0", - "@mongodb-js/connection-form": "^1.52.3", + "@mongodb-js/compass-workspaces": "^0.42.0", + "@mongodb-js/connection-form": "^1.53.0", "@mongodb-js/connection-info": "^0.15.2", "@mongodb-js/eslint-config-compass": "^1.3.10", "@mongodb-js/mocha-config-compass": "^1.6.8", - "@mongodb-js/my-queries-storage": "^0.27.3", + "@mongodb-js/my-queries-storage": "^0.28.0", "@mongodb-js/prettier-config-compass": "^1.2.8", "@mongodb-js/testing-library-compass": "^1.3.2", "@mongodb-js/tsconfig-compass": "^1.2.8", @@ -59400,11 +59073,10 @@ "@types/sinon-chai": "^3.2.5", "bson": "^6.10.3", "chai": "^4.3.4", - "compass-preferences-model": "^2.40.2", + "compass-preferences-model": "^2.41.0", "depcheck": "^1.4.1", "electron-mocha": "^12.2.0", "fuse.js": "^6.5.3", - "hadron-app-registry": "^9.4.11", "mocha": "^10.2.0", "mongodb-ns": "^2.4.2", "nyc": "^15.1.0", @@ -59445,18 +59117,19 @@ "@mongodb-js/compass-schema": { "version": "file:packages/compass-schema", "requires": { - "@mongodb-js/compass-collection": "^4.59.0", - "@mongodb-js/compass-components": "^1.38.1", - "@mongodb-js/compass-connections": "^1.60.0", - "@mongodb-js/compass-editor": "^0.40.2", - "@mongodb-js/compass-field-store": "^9.35.0", + "@mongodb-js/compass-app-registry": "^9.4.11", + "@mongodb-js/compass-collection": "^4.60.0", + "@mongodb-js/compass-components": "^1.39.0", + "@mongodb-js/compass-connections": "^1.61.0", + "@mongodb-js/compass-editor": "^0.41.0", + "@mongodb-js/compass-field-store": "^9.36.0", "@mongodb-js/compass-logging": "^1.7.2", - "@mongodb-js/compass-query-bar": "^8.61.0", + "@mongodb-js/compass-query-bar": "^8.62.0", "@mongodb-js/compass-telemetry": "^1.10.0", - "@mongodb-js/connection-storage": "^0.35.0", + "@mongodb-js/connection-storage": "^0.36.0", "@mongodb-js/eslint-config-compass": "^1.3.10", "@mongodb-js/mocha-config-compass": "^1.6.8", - "@mongodb-js/my-queries-storage": "^0.27.3", + "@mongodb-js/my-queries-storage": "^0.28.0", "@mongodb-js/prettier-config-compass": "^1.2.8", "@mongodb-js/testing-library-compass": "^1.3.2", "@mongodb-js/tsconfig-compass": "^1.2.8", @@ -59468,11 +59141,10 @@ "@types/react-dom": "^17.0.10", "bson": "^6.10.3", "chai": "^4.3.4", - "compass-preferences-model": "^2.40.2", + "compass-preferences-model": "^2.41.0", "d3": "^3.5.17", "depcheck": "^1.4.1", "electron-mocha": "^12.2.0", - "hadron-app-registry": "^9.4.11", "hadron-document": "^8.8.12", "leaflet": "^1.5.1", "leaflet-defaulticon-compatibility": "^0.1.1", @@ -59594,17 +59266,18 @@ "@mongodb-js/compass-schema-validation": { "version": "file:packages/compass-schema-validation", "requires": { - "@mongodb-js/compass-app-stores": "^7.46.0", - "@mongodb-js/compass-collection": "^4.59.0", - "@mongodb-js/compass-components": "^1.38.1", - "@mongodb-js/compass-connections": "^1.60.0", - "@mongodb-js/compass-crud": "^13.60.0", - "@mongodb-js/compass-editor": "^0.40.2", - "@mongodb-js/compass-field-store": "^9.35.0", + "@mongodb-js/compass-app-registry": "^9.4.11", + "@mongodb-js/compass-app-stores": "^7.47.0", + "@mongodb-js/compass-collection": "^4.60.0", + "@mongodb-js/compass-components": "^1.39.0", + "@mongodb-js/compass-connections": "^1.61.0", + "@mongodb-js/compass-crud": "^13.61.0", + "@mongodb-js/compass-editor": "^0.41.0", + "@mongodb-js/compass-field-store": "^9.36.0", "@mongodb-js/compass-logging": "^1.7.2", - "@mongodb-js/compass-schema": "^6.61.0", + "@mongodb-js/compass-schema": "^6.62.0", "@mongodb-js/compass-telemetry": "^1.10.0", - "@mongodb-js/compass-workspaces": "^0.41.0", + "@mongodb-js/compass-workspaces": "^0.42.0", "@mongodb-js/eslint-config-compass": "^1.3.10", "@mongodb-js/mocha-config-compass": "^1.6.8", "@mongodb-js/mongodb-constants": "^0.11.0", @@ -59613,17 +59286,16 @@ "@mongodb-js/tsconfig-compass": "^1.2.8", "bson": "^6.10.3", "chai": "^4.2.0", - "compass-preferences-model": "^2.40.2", + "compass-preferences-model": "^2.41.0", "depcheck": "^1.4.1", "electron": "^36.4.0", "electron-mocha": "^12.2.0", - "hadron-app-registry": "^9.4.11", "hadron-ipc": "^3.5.2", "javascript-stringify": "^2.0.1", "lodash": "^4.17.21", "mocha": "^10.2.0", "mongodb": "^6.16.0", - "mongodb-instance-model": "^12.32.2", + "mongodb-instance-model": "^12.33.0", "mongodb-ns": "^2.4.2", "mongodb-query-parser": "^4.3.0", "nyc": "^15.1.0", @@ -59825,11 +59497,12 @@ "@mongodb-js/compass-serverstats": { "version": "file:packages/compass-serverstats", "requires": { - "@mongodb-js/compass-app-stores": "^7.46.0", - "@mongodb-js/compass-components": "^1.38.1", - "@mongodb-js/compass-connections": "^1.60.0", + "@mongodb-js/compass-app-registry": "^9.4.11", + "@mongodb-js/compass-app-stores": "^7.47.0", + "@mongodb-js/compass-components": "^1.39.0", + "@mongodb-js/compass-connections": "^1.61.0", "@mongodb-js/compass-telemetry": "^1.10.0", - "@mongodb-js/compass-workspaces": "^0.41.0", + "@mongodb-js/compass-workspaces": "^0.42.0", "@mongodb-js/eslint-config-compass": "^1.3.10", "@mongodb-js/mocha-config-compass": "^1.6.8", "@mongodb-js/prettier-config-compass": "^1.2.8", @@ -59843,7 +59516,6 @@ "depcheck": "^1.4.1", "electron-mocha": "^12.2.0", "enzyme": "^3.11.0", - "hadron-app-registry": "^9.4.11", "lodash": "^4.17.21", "mocha": "^10.2.0", "mongodb-ns": "^2.4.2", @@ -59871,9 +59543,10 @@ "@mongodb-js/compass-settings": { "version": "file:packages/compass-settings", "requires": { - "@mongodb-js/atlas-service": "^0.45.0", - "@mongodb-js/compass-components": "^1.38.1", - "@mongodb-js/compass-generative-ai": "^0.40.0", + "@mongodb-js/atlas-service": "^0.46.0", + "@mongodb-js/compass-app-registry": "^9.4.11", + "@mongodb-js/compass-components": "^1.39.0", + "@mongodb-js/compass-generative-ai": "^0.41.0", "@mongodb-js/compass-logging": "^1.7.2", "@mongodb-js/eslint-config-compass": "^1.3.10", "@mongodb-js/mocha-config-compass": "^1.6.8", @@ -59887,10 +59560,9 @@ "@types/react-dom": "^17.0.10", "@types/sinon-chai": "^3.2.5", "chai": "^4.3.6", - "compass-preferences-model": "^2.40.2", + "compass-preferences-model": "^2.41.0", "depcheck": "^1.4.1", "electron-mocha": "^12.2.0", - "hadron-app-registry": "^9.4.11", "hadron-ipc": "^3.5.2", "mocha": "^10.2.0", "nyc": "^15.1.0", @@ -59931,14 +59603,15 @@ "@mongodb-js/compass-shell": { "version": "file:packages/compass-shell", "requires": { - "@mongodb-js/compass-components": "^1.38.1", - "@mongodb-js/compass-connections": "^1.60.0", - "@mongodb-js/compass-editor": "^0.40.2", + "@mongodb-js/compass-app-registry": "^9.4.11", + "@mongodb-js/compass-components": "^1.39.0", + "@mongodb-js/compass-connections": "^1.61.0", + "@mongodb-js/compass-editor": "^0.41.0", "@mongodb-js/compass-logging": "^1.7.2", "@mongodb-js/compass-telemetry": "^1.10.0", "@mongodb-js/compass-user-data": "^0.7.2", "@mongodb-js/compass-utils": "^0.9.2", - "@mongodb-js/compass-workspaces": "^0.41.0", + "@mongodb-js/compass-workspaces": "^0.42.0", "@mongodb-js/eslint-config-compass": "^1.3.10", "@mongodb-js/mocha-config-compass": "^1.6.8", "@mongodb-js/prettier-config-compass": "^1.2.8", @@ -59949,11 +59622,10 @@ "@mongosh/node-runtime-worker-thread": "^3.3.10", "bson": "^6.10.3", "chai": "^4.2.0", - "compass-preferences-model": "^2.40.2", + "compass-preferences-model": "^2.41.0", "depcheck": "^1.4.1", "electron": "^36.4.0", "electron-mocha": "^12.2.0", - "hadron-app-registry": "^9.4.11", "mocha": "^10.2.0", "nyc": "^15.1.0", "react": "^17.0.2", @@ -60168,15 +59840,16 @@ "@mongodb-js/compass-sidebar": { "version": "file:packages/compass-sidebar", "requires": { - "@mongodb-js/compass-app-stores": "^7.46.0", - "@mongodb-js/compass-components": "^1.38.1", - "@mongodb-js/compass-connection-import-export": "^0.56.0", - "@mongodb-js/compass-connections": "^1.60.0", - "@mongodb-js/compass-connections-navigation": "^1.59.0", + "@mongodb-js/compass-app-registry": "^9.4.11", + "@mongodb-js/compass-app-stores": "^7.47.0", + "@mongodb-js/compass-components": "^1.39.0", + "@mongodb-js/compass-connection-import-export": "^0.57.0", + "@mongodb-js/compass-connections": "^1.61.0", + "@mongodb-js/compass-connections-navigation": "^1.60.0", "@mongodb-js/compass-logging": "^1.7.2", - "@mongodb-js/compass-maybe-protect-connection-string": "^0.38.2", + "@mongodb-js/compass-maybe-protect-connection-string": "^0.39.0", "@mongodb-js/compass-telemetry": "^1.10.0", - "@mongodb-js/compass-workspaces": "^0.41.0", + "@mongodb-js/compass-workspaces": "^0.42.0", "@mongodb-js/connection-info": "^0.15.2", "@mongodb-js/eslint-config-compass": "^1.3.10", "@mongodb-js/mocha-config-compass": "^1.6.8", @@ -60190,15 +59863,14 @@ "@types/react-dom": "^17.0.10", "@types/sinon-chai": "^3.2.5", "chai": "^4.3.6", - "compass-preferences-model": "^2.40.2", + "compass-preferences-model": "^2.41.0", "depcheck": "^1.4.1", "electron-mocha": "^12.2.0", - "hadron-app-registry": "^9.4.11", "lodash": "^4.17.21", "mocha": "^10.2.0", "mongodb": "^6.16.0", "mongodb-data-service": "^22.28.2", - "mongodb-instance-model": "^12.32.2", + "mongodb-instance-model": "^12.33.0", "mongodb-ns": "^2.4.2", "nyc": "^15.1.0", "react": "^17.0.2", @@ -60243,7 +59915,7 @@ "@mongodb-js/prettier-config-compass": "^1.2.8", "@mongodb-js/tsconfig-compass": "^1.2.8", "@types/node": "^20", - "compass-e2e-tests": "^1.33.0", + "compass-e2e-tests": "^1.33.1", "debug": "^4.3.4", "depcheck": "^1.4.1", "hadron-build": "^25.8.2", @@ -60304,6 +59976,7 @@ "@mongodb-js/compass-telemetry": { "version": "file:packages/compass-telemetry", "requires": { + "@mongodb-js/compass-app-registry": "^9.4.11", "@mongodb-js/compass-logging": "^1.7.2", "@mongodb-js/eslint-config-compass": "^1.3.10", "@mongodb-js/mocha-config-compass": "^1.6.8", @@ -60315,7 +59988,6 @@ "chai": "^4.3.6", "depcheck": "^1.4.1", "gen-esm-wrapper": "^1.1.0", - "hadron-app-registry": "^9.4.11", "hadron-ipc": "^3.5.2", "mocha": "^10.2.0", "nyc": "^15.1.0", @@ -60558,30 +60230,31 @@ "@mongodb-js/compass-web": { "version": "file:packages/compass-web", "requires": { - "@mongodb-js/atlas-service": "^0.45.0", - "@mongodb-js/compass-aggregations": "^9.62.0", - "@mongodb-js/compass-app-stores": "^7.46.0", - "@mongodb-js/compass-collection": "^4.59.0", - "@mongodb-js/compass-components": "^1.38.1", - "@mongodb-js/compass-connections": "^1.60.0", - "@mongodb-js/compass-crud": "^13.60.0", - "@mongodb-js/compass-data-modeling": "^1.11.0", - "@mongodb-js/compass-databases-collections": "^1.59.0", - "@mongodb-js/compass-explain-plan": "^6.60.0", - "@mongodb-js/compass-export-to-language": "^9.36.0", - "@mongodb-js/compass-field-store": "^9.35.0", - "@mongodb-js/compass-generative-ai": "^0.40.0", - "@mongodb-js/compass-global-writes": "^1.19.0", - "@mongodb-js/compass-indexes": "^5.59.0", + "@mongodb-js/atlas-service": "^0.46.0", + "@mongodb-js/compass-aggregations": "^9.63.0", + "@mongodb-js/compass-app-registry": "^9.4.11", + "@mongodb-js/compass-app-stores": "^7.47.0", + "@mongodb-js/compass-collection": "^4.60.0", + "@mongodb-js/compass-components": "^1.39.0", + "@mongodb-js/compass-connections": "^1.61.0", + "@mongodb-js/compass-crud": "^13.61.0", + "@mongodb-js/compass-data-modeling": "^1.12.0", + "@mongodb-js/compass-databases-collections": "^1.60.0", + "@mongodb-js/compass-explain-plan": "^6.61.0", + "@mongodb-js/compass-export-to-language": "^9.37.0", + "@mongodb-js/compass-field-store": "^9.36.0", + "@mongodb-js/compass-generative-ai": "^0.41.0", + "@mongodb-js/compass-global-writes": "^1.20.0", + "@mongodb-js/compass-indexes": "^5.60.0", "@mongodb-js/compass-logging": "^1.7.2", - "@mongodb-js/compass-query-bar": "^8.61.0", - "@mongodb-js/compass-schema": "^6.61.0", - "@mongodb-js/compass-schema-validation": "^6.60.0", - "@mongodb-js/compass-sidebar": "^5.60.0", + "@mongodb-js/compass-query-bar": "^8.62.0", + "@mongodb-js/compass-schema": "^6.62.0", + "@mongodb-js/compass-schema-validation": "^6.61.0", + "@mongodb-js/compass-sidebar": "^5.61.0", "@mongodb-js/compass-telemetry": "^1.10.0", - "@mongodb-js/compass-welcome": "^0.58.0", - "@mongodb-js/compass-workspaces": "^0.41.0", - "@mongodb-js/connection-storage": "^0.35.0", + "@mongodb-js/compass-welcome": "^0.59.0", + "@mongodb-js/compass-workspaces": "^0.42.0", + "@mongodb-js/connection-storage": "^0.36.0", "@mongodb-js/devtools-proxy-support": "^0.4.4", "@mongodb-js/eslint-config-compass": "^1.3.10", "@mongodb-js/mocha-config-compass": "^1.6.8", @@ -60600,7 +60273,7 @@ "bson": "^6.2.0", "buffer": "^6.0.3", "chai": "^4.3.6", - "compass-preferences-model": "^2.40.2", + "compass-preferences-model": "^2.41.0", "crypto-browserify": "^3.12.0", "debug": "^4.3.4", "depcheck": "^1.4.1", @@ -60609,7 +60282,6 @@ "events": "^3.3.0", "express": "^4.21.1", "express-http-proxy": "^2.0.0", - "hadron-app-registry": "^9.4.11", "is-ip": "^5.0.1", "lodash": "^4.17.21", "mocha": "^10.2.0", @@ -60784,11 +60456,12 @@ "@mongodb-js/compass-welcome": { "version": "file:packages/compass-welcome", "requires": { - "@mongodb-js/compass-components": "^1.38.1", - "@mongodb-js/compass-connections": "^1.60.0", + "@mongodb-js/compass-app-registry": "^9.4.11", + "@mongodb-js/compass-components": "^1.39.0", + "@mongodb-js/compass-connections": "^1.61.0", "@mongodb-js/compass-logging": "^1.7.2", "@mongodb-js/compass-telemetry": "^1.10.0", - "@mongodb-js/compass-workspaces": "^0.41.0", + "@mongodb-js/compass-workspaces": "^0.42.0", "@mongodb-js/eslint-config-compass": "^1.3.10", "@mongodb-js/mocha-config-compass": "^1.6.8", "@mongodb-js/prettier-config-compass": "^1.2.8", @@ -60800,10 +60473,9 @@ "@types/react": "^17.0.5", "@types/sinon-chai": "^3.2.5", "chai": "^4.3.6", - "compass-preferences-model": "^2.40.2", + "compass-preferences-model": "^2.41.0", "depcheck": "^1.4.1", "electron-mocha": "^12.2.0", - "hadron-app-registry": "^9.4.11", "mocha": "^10.2.0", "nyc": "^15.1.0", "react": "^17.0.2", @@ -60841,9 +60513,10 @@ "@mongodb-js/compass-workspaces": { "version": "file:packages/compass-workspaces", "requires": { - "@mongodb-js/compass-app-stores": "^7.46.0", - "@mongodb-js/compass-components": "^1.38.1", - "@mongodb-js/compass-connections": "^1.60.0", + "@mongodb-js/compass-app-registry": "^9.4.11", + "@mongodb-js/compass-app-stores": "^7.47.0", + "@mongodb-js/compass-components": "^1.39.0", + "@mongodb-js/compass-connections": "^1.61.0", "@mongodb-js/compass-logging": "^1.7.2", "@mongodb-js/eslint-config-compass": "^1.3.10", "@mongodb-js/mocha-config-compass": "^1.6.8", @@ -60858,10 +60531,9 @@ "@types/sinon-chai": "^3.2.5", "bson": "^6.10.3", "chai": "^4.3.6", - "compass-preferences-model": "^2.40.2", + "compass-preferences-model": "^2.41.0", "depcheck": "^1.4.1", "electron-mocha": "^12.2.0", - "hadron-app-registry": "^9.4.11", "lodash": "^4.17.21", "mocha": "^10.2.0", "mongodb-collection-model": "^5.29.2", @@ -60981,8 +60653,8 @@ "@mongodb-js/connection-form": { "version": "file:packages/connection-form", "requires": { - "@mongodb-js/compass-components": "^1.38.1", - "@mongodb-js/compass-editor": "^0.40.2", + "@mongodb-js/compass-components": "^1.39.0", + "@mongodb-js/compass-editor": "^0.41.0", "@mongodb-js/connection-info": "^0.15.2", "@mongodb-js/eslint-config-compass": "^1.3.10", "@mongodb-js/mocha-config-compass": "^1.6.8", @@ -61182,6 +60854,7 @@ "@mongodb-js/connection-storage": { "version": "file:packages/connection-storage", "requires": { + "@mongodb-js/compass-app-registry": "^9.4.11", "@mongodb-js/compass-logging": "^1.7.2", "@mongodb-js/compass-telemetry": "^1.10.0", "@mongodb-js/compass-user-data": "^0.7.2", @@ -61196,10 +60869,9 @@ "@types/sinon-chai": "^3.2.5", "bson": "^6.10.3", "chai": "^4.3.6", - "compass-preferences-model": "^2.40.2", + "compass-preferences-model": "^2.41.0", "depcheck": "^1.4.1", "electron": "^36.4.0", - "hadron-app-registry": "^9.4.11", "hadron-ipc": "^3.5.2", "keytar": "^7.9.0", "lodash": "^4.17.21", @@ -61236,10 +60908,10 @@ "@mongodb-js/databases-collections-list": { "version": "file:packages/databases-collections-list", "requires": { - "@mongodb-js/compass-components": "^1.38.1", - "@mongodb-js/compass-connections": "^1.60.0", + "@mongodb-js/compass-components": "^1.39.0", + "@mongodb-js/compass-connections": "^1.61.0", "@mongodb-js/compass-telemetry": "^1.10.0", - "@mongodb-js/compass-workspaces": "^0.41.0", + "@mongodb-js/compass-workspaces": "^0.42.0", "@mongodb-js/connection-info": "^0.15.2", "@mongodb-js/eslint-config-compass": "^1.3.10", "@mongodb-js/mocha-config-compass": "^1.6.8", @@ -61252,7 +60924,7 @@ "@types/react": "^17.0.5", "@types/sinon-chai": "^3.2.5", "chai": "^4.3.4", - "compass-preferences-model": "^2.40.2", + "compass-preferences-model": "^2.41.0", "depcheck": "^1.4.1", "mocha": "^10.2.0", "mongodb-collection-model": "^5.29.2", @@ -61868,7 +61540,8 @@ "@mongodb-js/my-queries-storage": { "version": "file:packages/my-queries-storage", "requires": { - "@mongodb-js/compass-editor": "^0.40.2", + "@mongodb-js/compass-app-registry": "^9.4.11", + "@mongodb-js/compass-editor": "^0.41.0", "@mongodb-js/compass-user-data": "^0.7.2", "@mongodb-js/eslint-config-compass": "^1.3.10", "@mongodb-js/mocha-config-compass": "^1.6.8", @@ -61881,7 +61554,6 @@ "chai": "^4.3.6", "depcheck": "^1.4.1", "gen-esm-wrapper": "^1.1.0", - "hadron-app-registry": "^9.4.11", "mocha": "^10.2.0", "nyc": "^15.1.0", "react": "^17.0.2", @@ -69476,7 +69148,7 @@ "chai": "^4.3.4", "chai-as-promised": "^7.1.1", "clipboardy": "^2.3.0", - "compass-preferences-model": "^2.40.2", + "compass-preferences-model": "^2.41.0", "cross-spawn": "^7.0.5", "debug": "^4.3.4", "depcheck": "^1.4.1", @@ -69779,7 +69451,8 @@ "compass-preferences-model": { "version": "file:packages/compass-preferences-model", "requires": { - "@mongodb-js/compass-components": "^1.38.1", + "@mongodb-js/compass-app-registry": "^9.4.11", + "@mongodb-js/compass-components": "^1.39.0", "@mongodb-js/compass-logging": "^1.7.2", "@mongodb-js/compass-user-data": "^0.7.2", "@mongodb-js/devtools-proxy-support": "^0.4.4", @@ -69792,7 +69465,6 @@ "bson": "^6.10.3", "chai": "^4.3.6", "depcheck": "^1.4.1", - "hadron-app-registry": "^9.4.11", "hadron-ipc": "^3.5.2", "js-yaml": "^4.1.0", "lodash": "^4.17.21", @@ -74961,51 +74633,6 @@ "duplexer": "^0.1.2" } }, - "hadron-app-registry": { - "version": "file:packages/hadron-app-registry", - "requires": { - "@mongodb-js/eslint-config-compass": "^1.3.10", - "@mongodb-js/mocha-config-compass": "^1.6.8", - "@mongodb-js/prettier-config-compass": "^1.2.8", - "@mongodb-js/testing-library-compass": "^1.3.2", - "@mongodb-js/tsconfig-compass": "^1.2.8", - "@types/chai": "^4.2.21", - "@types/mocha": "^9.0.0", - "@types/reflux": "^6.4.3", - "chai": "^4.1.2", - "depcheck": "^1.4.1", - "eventemitter3": "^4.0.0", - "mocha": "^10.2.0", - "react": "^17.0.2", - "react-redux": "^8.1.3", - "redux": "^4.2.1", - "reflux": "^0.4.1", - "sinon": "^9.0.0", - "typescript": "^5.0.4" - }, - "dependencies": { - "diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true - }, - "sinon": { - "version": "9.2.4", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-9.2.4.tgz", - "integrity": "sha512-zljcULZQsJxVra28qIAL6ow1Z9tpattkCTEJR4RBP3TGc00FcttsP5pK284Nas5WjMZU5Yzy3kAIp3B3KRf5Yg==", - "dev": true, - "requires": { - "@sinonjs/commons": "^1.8.1", - "@sinonjs/fake-timers": "^6.0.1", - "@sinonjs/samsam": "^5.3.1", - "diff": "^4.0.2", - "nise": "^4.0.4", - "supports-color": "^7.1.0" - } - } - } - }, "hadron-build": { "version": "file:packages/hadron-build", "requires": { @@ -80210,47 +79837,48 @@ "requires": { "@electron/rebuild": "^4.0.1", "@electron/remote": "^2.1.2", - "@mongodb-js/atlas-service": "^0.45.0", - "@mongodb-js/compass-aggregations": "^9.62.0", - "@mongodb-js/compass-app-stores": "^7.46.0", - "@mongodb-js/compass-collection": "^4.59.0", - "@mongodb-js/compass-components": "^1.38.1", - "@mongodb-js/compass-connection-import-export": "^0.56.0", - "@mongodb-js/compass-connections": "^1.60.0", - "@mongodb-js/compass-crud": "^13.60.0", - "@mongodb-js/compass-data-modeling": "^1.11.0", - "@mongodb-js/compass-databases-collections": "^1.59.0", - "@mongodb-js/compass-explain-plan": "^6.60.0", - "@mongodb-js/compass-export-to-language": "^9.36.0", - "@mongodb-js/compass-field-store": "^9.35.0", - "@mongodb-js/compass-find-in-page": "^4.39.2", - "@mongodb-js/compass-generative-ai": "^0.40.0", - "@mongodb-js/compass-global-writes": "^1.19.0", - "@mongodb-js/compass-import-export": "^7.59.0", - "@mongodb-js/compass-indexes": "^5.59.0", - "@mongodb-js/compass-intercom": "^0.24.2", + "@mongodb-js/atlas-service": "^0.46.0", + "@mongodb-js/compass-aggregations": "^9.63.0", + "@mongodb-js/compass-app-registry": "^9.4.11", + "@mongodb-js/compass-app-stores": "^7.47.0", + "@mongodb-js/compass-collection": "^4.60.0", + "@mongodb-js/compass-components": "^1.39.0", + "@mongodb-js/compass-connection-import-export": "^0.57.0", + "@mongodb-js/compass-connections": "^1.61.0", + "@mongodb-js/compass-crud": "^13.61.0", + "@mongodb-js/compass-data-modeling": "^1.12.0", + "@mongodb-js/compass-databases-collections": "^1.60.0", + "@mongodb-js/compass-explain-plan": "^6.61.0", + "@mongodb-js/compass-export-to-language": "^9.37.0", + "@mongodb-js/compass-field-store": "^9.36.0", + "@mongodb-js/compass-find-in-page": "^4.40.0", + "@mongodb-js/compass-generative-ai": "^0.41.0", + "@mongodb-js/compass-global-writes": "^1.20.0", + "@mongodb-js/compass-import-export": "^7.60.0", + "@mongodb-js/compass-indexes": "^5.60.0", + "@mongodb-js/compass-intercom": "^0.25.0", "@mongodb-js/compass-logging": "^1.7.2", - "@mongodb-js/compass-query-bar": "^8.61.0", - "@mongodb-js/compass-saved-aggregations-queries": "^1.60.0", - "@mongodb-js/compass-schema": "^6.61.0", - "@mongodb-js/compass-schema-validation": "^6.60.0", - "@mongodb-js/compass-serverstats": "^16.59.0", - "@mongodb-js/compass-settings": "^0.58.0", - "@mongodb-js/compass-shell": "^3.59.0", - "@mongodb-js/compass-sidebar": "^5.60.0", + "@mongodb-js/compass-query-bar": "^8.62.0", + "@mongodb-js/compass-saved-aggregations-queries": "^1.61.0", + "@mongodb-js/compass-schema": "^6.62.0", + "@mongodb-js/compass-schema-validation": "^6.61.0", + "@mongodb-js/compass-serverstats": "^16.60.0", + "@mongodb-js/compass-settings": "^0.59.0", + "@mongodb-js/compass-shell": "^3.60.0", + "@mongodb-js/compass-sidebar": "^5.61.0", "@mongodb-js/compass-telemetry": "^1.10.0", "@mongodb-js/compass-utils": "^0.9.2", - "@mongodb-js/compass-welcome": "^0.58.0", - "@mongodb-js/compass-workspaces": "^0.41.0", + "@mongodb-js/compass-welcome": "^0.59.0", + "@mongodb-js/compass-workspaces": "^0.42.0", "@mongodb-js/connection-info": "^0.15.2", - "@mongodb-js/connection-storage": "^0.35.0", + "@mongodb-js/connection-storage": "^0.36.0", "@mongodb-js/device-id": "^0.2.0", "@mongodb-js/devtools-proxy-support": "^0.4.4", "@mongodb-js/eslint-config-compass": "^1.3.10", "@mongodb-js/get-os-info": "^0.4.0", "@mongodb-js/mocha-config-compass": "^1.6.8", "@mongodb-js/mongodb-downloader": "^0.3.7", - "@mongodb-js/my-queries-storage": "^0.27.3", + "@mongodb-js/my-queries-storage": "^0.28.0", "@mongodb-js/prettier-config-compass": "^1.2.8", "@mongodb-js/sbom-tools": "^0.7.2", "@mongodb-js/signing-utils": "^0.3.8", @@ -80265,7 +79893,7 @@ "chalk": "^4.1.2", "clean-stack": "^2.0.0", "clipboard": "^2.0.6", - "compass-preferences-model": "^2.40.2", + "compass-preferences-model": "^2.41.0", "cross-spawn": "^7.0.5", "debug": "^4.3.4", "depcheck": "^1.4.1", @@ -80275,7 +79903,6 @@ "electron-mocha": "^12.2.0", "ensure-error": "^3.0.1", "glob": "^10.2.5", - "hadron-app-registry": "^9.4.11", "hadron-build": "^25.8.2", "hadron-ipc": "^3.5.2", "kerberos": "^2.2.1", @@ -80632,7 +80259,7 @@ "@mongodb-js/prettier-config-compass": "^1.2.8", "ampersand-model": "^8.0.1", "chai": "^4.3.4", - "compass-preferences-model": "^2.40.2", + "compass-preferences-model": "^2.41.0", "depcheck": "^1.4.1", "mocha": "^10.2.0", "mongodb-collection-model": "^5.29.2", diff --git a/packages/atlas-service/package.json b/packages/atlas-service/package.json index 415887b1cc9..9f39fb05b59 100644 --- a/packages/atlas-service/package.json +++ b/packages/atlas-service/package.json @@ -13,7 +13,7 @@ "email": "compass@mongodb.com" }, "homepage": "https://github.com/mongodb-js/compass", - "version": "0.45.0", + "version": "0.46.0", "repository": { "type": "git", "url": "https://github.com/mongodb-js/compass.git" @@ -71,7 +71,8 @@ "typescript": "^5.0.4" }, "dependencies": { - "@mongodb-js/compass-components": "^1.38.1", + "@mongodb-js/compass-app-registry": "^9.4.11", + "@mongodb-js/compass-components": "^1.39.0", "@mongodb-js/compass-logging": "^1.7.2", "@mongodb-js/compass-telemetry": "^1.10.0", "@mongodb-js/compass-user-data": "^0.7.2", @@ -80,8 +81,7 @@ "@mongodb-js/devtools-connect": "^3.7.2", "@mongodb-js/devtools-proxy-support": "^0.4.4", "@mongodb-js/oidc-plugin": "^1.1.7", - "hadron-app-registry": "^9.4.11", - "compass-preferences-model": "^2.40.2", + "compass-preferences-model": "^2.41.0", "electron": "^36.4.0", "hadron-ipc": "^3.5.2", "lodash": "^4.17.21", diff --git a/packages/atlas-service/src/provider.tsx b/packages/atlas-service/src/provider.tsx index 92ec08bfac8..c4786939a91 100644 --- a/packages/atlas-service/src/provider.tsx +++ b/packages/atlas-service/src/provider.tsx @@ -6,7 +6,7 @@ import { useLogger } from '@mongodb-js/compass-logging/provider'; import { createServiceLocator, createServiceProvider, -} from 'hadron-app-registry'; +} from '@mongodb-js/compass-app-registry'; const AtlasAuthServiceContext = createContext(null); diff --git a/packages/atlas-service/src/renderer.ts b/packages/atlas-service/src/renderer.ts index f69e1ce5225..351168ad3a5 100644 --- a/packages/atlas-service/src/renderer.ts +++ b/packages/atlas-service/src/renderer.ts @@ -1,8 +1,8 @@ -import { registerHadronPlugin } from 'hadron-app-registry'; +import { registerCompassPlugin } from '@mongodb-js/compass-app-registry'; import { activatePlugin } from './store/atlas-signin-store'; import { atlasAuthServiceLocator } from './provider'; -export const AtlasAuthPlugin = registerHadronPlugin( +export const AtlasAuthPlugin = registerCompassPlugin( { name: 'AtlasAuth', component: () => null, diff --git a/packages/atlas-service/src/store/atlas-signin-store.spec.ts b/packages/atlas-service/src/store/atlas-signin-store.spec.ts index da0e727c095..9e85859043a 100644 --- a/packages/atlas-service/src/store/atlas-signin-store.spec.ts +++ b/packages/atlas-service/src/store/atlas-signin-store.spec.ts @@ -1,7 +1,7 @@ import { expect } from 'chai'; import type { AtlasAuthPluginServices } from './atlas-signin-store'; import { activatePlugin } from './atlas-signin-store'; -import type { ActivateHelpers } from 'hadron-app-registry'; +import type { ActivateHelpers } from '@mongodb-js/compass-app-registry'; import { waitFor } from '@mongodb-js/testing-library-compass'; const activateHelpers = { diff --git a/packages/atlas-service/src/store/atlas-signin-store.ts b/packages/atlas-service/src/store/atlas-signin-store.ts index 3d7692caea4..1807cb1ce8a 100644 --- a/packages/atlas-service/src/store/atlas-signin-store.ts +++ b/packages/atlas-service/src/store/atlas-signin-store.ts @@ -7,7 +7,7 @@ import reducer, { } from './atlas-signin-reducer'; import { type AtlasAuthService } from '../provider'; import { ipcRenderer } from 'hadron-ipc'; -import type { ActivateHelpers } from 'hadron-app-registry'; +import type { ActivateHelpers } from '@mongodb-js/compass-app-registry'; let store: AtlasServiceStore; export function getStore() { diff --git a/packages/compass-aggregations/README.md b/packages/compass-aggregations/README.md index 3219943f4eb..6757cdea936 100644 --- a/packages/compass-aggregations/README.md +++ b/packages/compass-aggregations/README.md @@ -68,7 +68,7 @@ This is for: Setting values via configure: ```js -import AppRegistry from 'hadron-app-registry'; +import AppRegistry from '@mongodb-js/compass-app-registry'; import AggregationsPlugin, { configureStore as configureAggregationsStore } from '@mongodb-js/compass-aggregations'; @@ -108,7 +108,7 @@ const exportToLanguageStore = configureExportToLanguageStore({ ``` -### Hadron/Electron +### Compass/Electron ```js const role = appRegistry.getRole('Collection.Tab')[0]; @@ -167,7 +167,7 @@ provider.aggregate(namespace, pipeline, options, callback); ### App Registry Events Emmitted Various actions within this plugin will emit events for other parts of the -application can be listened to via [hadron-app-registry][hadron-app-registry]. +application can be listened to via [compass-app-registry][compass-app-registry]. `Local` events are scoped to a `Tab`. `Global` events are scoped to the whole Compass application. @@ -250,4 +250,4 @@ npm run analyze npm i -S @mongodb-js/compass-aggregations ``` -[hadron-app-registry]: https://github.com/mongodb-js/hadron-app-registry +[compass-app-registry]: https://github.com/mongodb-js/compass/tree/main/packages/compass-app-registry diff --git a/packages/compass-aggregations/package.json b/packages/compass-aggregations/package.json index 9d567feb786..1aeb06538ec 100644 --- a/packages/compass-aggregations/package.json +++ b/packages/compass-aggregations/package.json @@ -2,7 +2,7 @@ "name": "@mongodb-js/compass-aggregations", "description": "Compass Aggregation Pipeline Builder", "private": true, - "version": "9.62.0", + "version": "9.63.0", "main": "dist/index.js", "compass:main": "src/index.ts", "types": "dist/index.d.ts", @@ -57,26 +57,26 @@ "@dnd-kit/core": "^6.0.7", "@dnd-kit/sortable": "^7.0.2", "@dnd-kit/utilities": "^3.2.1", - "@mongodb-js/atlas-service": "^0.45.0", - "@mongodb-js/compass-app-stores": "^7.46.0", - "@mongodb-js/compass-collection": "^4.59.0", - "@mongodb-js/compass-components": "^1.38.1", - "@mongodb-js/compass-connections": "^1.60.0", - "@mongodb-js/compass-crud": "^13.60.0", - "@mongodb-js/compass-editor": "^0.40.2", - "@mongodb-js/compass-field-store": "^9.35.0", - "@mongodb-js/compass-generative-ai": "^0.40.0", + "@mongodb-js/atlas-service": "^0.46.0", + "@mongodb-js/compass-app-stores": "^7.47.0", + "@mongodb-js/compass-collection": "^4.60.0", + "@mongodb-js/compass-components": "^1.39.0", + "@mongodb-js/compass-connections": "^1.61.0", + "@mongodb-js/compass-crud": "^13.61.0", + "@mongodb-js/compass-editor": "^0.41.0", + "@mongodb-js/compass-field-store": "^9.36.0", + "@mongodb-js/compass-generative-ai": "^0.41.0", "@mongodb-js/compass-logging": "^1.7.2", "@mongodb-js/compass-telemetry": "^1.10.0", "@mongodb-js/compass-utils": "^0.9.2", - "@mongodb-js/compass-workspaces": "^0.41.0", + "@mongodb-js/compass-workspaces": "^0.42.0", "@mongodb-js/explain-plan-helper": "^1.4.10", "@mongodb-js/mongodb-constants": "^0.11.0", - "@mongodb-js/my-queries-storage": "^0.27.3", + "@mongodb-js/my-queries-storage": "^0.28.0", "@mongodb-js/shell-bson-parser": "^1.2.0", "bson": "^6.10.3", - "compass-preferences-model": "^2.40.2", - "hadron-app-registry": "^9.4.11", + "compass-preferences-model": "^2.41.0", + "@mongodb-js/compass-app-registry": "^9.4.11", "hadron-document": "^8.8.12", "hadron-type-checker": "^7.4.10", "lodash": "^4.17.21", @@ -84,7 +84,7 @@ "mongodb-collection-model": "^5.29.2", "mongodb-data-service": "^22.28.2", "mongodb-database-model": "^2.29.2", - "mongodb-instance-model": "^12.32.2", + "mongodb-instance-model": "^12.33.0", "mongodb-ns": "^2.4.2", "mongodb-query-parser": "^4.3.0", "mongodb-schema": "^12.6.2", diff --git a/packages/compass-aggregations/src/components/stage-preview/stage-preview-header.tsx b/packages/compass-aggregations/src/components/stage-preview/stage-preview-header.tsx index df18e022c9a..f133bf46bcb 100644 --- a/packages/compass-aggregations/src/components/stage-preview/stage-preview-header.tsx +++ b/packages/compass-aggregations/src/components/stage-preview/stage-preview-header.tsx @@ -1,16 +1,10 @@ import React from 'react'; import { connect } from 'react-redux'; -import { Body, Link, Tooltip, css } from '@mongodb-js/compass-components'; +import { Body, Link, Tooltip } from '@mongodb-js/compass-components'; import type { RootState } from '../../modules'; import { getStageInfo } from '../../utils/stage'; import type { StoreStage } from '../../modules/pipeline-builder/stage-editor'; -const toolbarTextStyles = css({ - whiteSpace: 'nowrap', - overflow: 'hidden', - textOverflow: 'ellipsis', -}); - const OperatorLink: React.FunctionComponent<{ stageOperator: string; description?: string; @@ -56,7 +50,7 @@ function StagePreviewHeader({ return null; } return ( - + {destination ? ( `Documents will be saved to ${destination}.` ) : ( diff --git a/packages/compass-aggregations/src/index.ts b/packages/compass-aggregations/src/index.ts index bf9a7c4d3f0..0a8a49e1e39 100644 --- a/packages/compass-aggregations/src/index.ts +++ b/packages/compass-aggregations/src/index.ts @@ -1,5 +1,5 @@ import React from 'react'; -import { registerHadronPlugin } from 'hadron-app-registry'; +import { registerCompassPlugin } from '@mongodb-js/compass-app-registry'; import { AggregationsPlugin } from './plugin'; import { activateAggregationsPlugin } from './stores/store'; import { Aggregations } from './components/aggregations'; @@ -29,7 +29,7 @@ import { atlasAiServiceLocator } from '@mongodb-js/compass-generative-ai/provide import { pipelineStorageLocator } from '@mongodb-js/my-queries-storage/provider'; import { AggregationsTabTitle } from './plugin-title'; -const CompassAggregationsHadronPlugin = registerHadronPlugin( +const CompassAggregationsPluginProvider = registerCompassPlugin( { name: 'CompassAggregations', component: function AggregationsProvider({ children }) { @@ -58,12 +58,12 @@ const CompassAggregationsHadronPlugin = registerHadronPlugin( export const CompassAggregationsPlugin = { name: 'Aggregations' as const, - provider: CompassAggregationsHadronPlugin, + provider: CompassAggregationsPluginProvider, content: AggregationsPlugin, header: AggregationsTabTitle, }; -export const CreateViewPlugin = registerHadronPlugin( +export const CreateViewPlugin = registerCompassPlugin( { name: 'CreateView', component: CreateViewModal, diff --git a/packages/compass-aggregations/src/modules/index.ts b/packages/compass-aggregations/src/modules/index.ts index 1f5de34002b..21173f150b2 100644 --- a/packages/compass-aggregations/src/modules/index.ts +++ b/packages/compass-aggregations/src/modules/index.ts @@ -40,7 +40,7 @@ import searchIndexes from './search-indexes'; import type { WorkspacesService } from '@mongodb-js/compass-workspaces/provider'; import type { PreferencesAccess } from 'compass-preferences-model'; import type { Logger } from '@mongodb-js/compass-logging/provider'; -import type AppRegistry from 'hadron-app-registry'; +import type AppRegistry from '@mongodb-js/compass-app-registry'; import type { AtlasAiService } from '@mongodb-js/compass-generative-ai/provider'; import type { MongoDBInstance } from 'mongodb-instance-model'; import type { DataService } from '../modules/data-service'; diff --git a/packages/compass-aggregations/src/modules/pipeline-builder/stage-editor.spec.ts b/packages/compass-aggregations/src/modules/pipeline-builder/stage-editor.spec.ts index b85472af616..b2c032fca55 100644 --- a/packages/compass-aggregations/src/modules/pipeline-builder/stage-editor.spec.ts +++ b/packages/compass-aggregations/src/modules/pipeline-builder/stage-editor.spec.ts @@ -29,7 +29,7 @@ import { getId } from './stage-ids'; import { defaultPreferencesInstance } from 'compass-preferences-model'; import { createNoopLogger } from '@mongodb-js/compass-logging/provider'; import { createNoopTrack } from '@mongodb-js/compass-telemetry/provider'; -import AppRegistry from 'hadron-app-registry'; +import AppRegistry from '@mongodb-js/compass-app-registry'; import { ConnectionScopedAppRegistryImpl } from '@mongodb-js/compass-connections/provider'; import { createDefaultConnectionInfo } from '@mongodb-js/testing-library-compass'; diff --git a/packages/compass-aggregations/src/modules/update-view.spec.ts b/packages/compass-aggregations/src/modules/update-view.spec.ts index 9c016fcf712..4e0c6603d4f 100644 --- a/packages/compass-aggregations/src/modules/update-view.spec.ts +++ b/packages/compass-aggregations/src/modules/update-view.spec.ts @@ -3,7 +3,7 @@ import { expect } from 'chai'; import { ERROR_UPDATING_VIEW, updateView } from './update-view'; import { createNoopLogger } from '@mongodb-js/compass-logging/provider'; import { createNoopTrack } from '@mongodb-js/compass-telemetry/provider'; -import AppRegistry from 'hadron-app-registry'; +import AppRegistry from '@mongodb-js/compass-app-registry'; import { type ConnectionInfoRef, ConnectionScopedAppRegistryImpl, diff --git a/packages/compass-aggregations/src/stores/create-view.spec.ts b/packages/compass-aggregations/src/stores/create-view.spec.ts index 9b39f7a7d8d..e7f456dd1bc 100644 --- a/packages/compass-aggregations/src/stores/create-view.spec.ts +++ b/packages/compass-aggregations/src/stores/create-view.spec.ts @@ -1,4 +1,4 @@ -import type AppRegistry from 'hadron-app-registry'; +import type AppRegistry from '@mongodb-js/compass-app-registry'; import { expect } from 'chai'; import { changeViewName, createView } from '../modules/create-view'; import Sinon from 'sinon'; diff --git a/packages/compass-aggregations/src/stores/create-view.ts b/packages/compass-aggregations/src/stores/create-view.ts index 684339c52b1..767b9cf042a 100644 --- a/packages/compass-aggregations/src/stores/create-view.ts +++ b/packages/compass-aggregations/src/stores/create-view.ts @@ -4,11 +4,11 @@ import type { ThunkAction } from 'redux-thunk'; import thunk from 'redux-thunk'; import type { CreateViewAction } from '../modules/create-view'; import reducer, { open } from '../modules/create-view'; -import type AppRegistry from 'hadron-app-registry'; +import type AppRegistry from '@mongodb-js/compass-app-registry'; import type { Logger } from '@mongodb-js/compass-logging/provider'; import type { WorkspacesService } from '@mongodb-js/compass-workspaces/provider'; import type { ConnectionsService } from '@mongodb-js/compass-connections/provider'; -import type { ActivateHelpers } from 'hadron-app-registry'; +import type { ActivateHelpers } from '@mongodb-js/compass-app-registry'; import type { TrackFunction } from '@mongodb-js/compass-telemetry'; type CreateViewServices = { diff --git a/packages/compass-aggregations/src/stores/store.spec.ts b/packages/compass-aggregations/src/stores/store.spec.ts index b2724ab3d9b..e08e485d6ac 100644 --- a/packages/compass-aggregations/src/stores/store.spec.ts +++ b/packages/compass-aggregations/src/stores/store.spec.ts @@ -1,4 +1,4 @@ -import type AppRegistry from 'hadron-app-registry'; +import type AppRegistry from '@mongodb-js/compass-app-registry'; import rootReducer from '../modules'; import { expect } from 'chai'; import configureStore from '../../test/configure-store'; diff --git a/packages/compass-aggregations/src/stores/store.ts b/packages/compass-aggregations/src/stores/store.ts index cbefaaa7dae..6111aa30702 100644 --- a/packages/compass-aggregations/src/stores/store.ts +++ b/packages/compass-aggregations/src/stores/store.ts @@ -15,7 +15,7 @@ import { mapStoreStagesToStageIdAndType, } from '../modules/pipeline-builder/stage-editor'; import { updatePipelinePreview } from '../modules/pipeline-builder/builder-helpers'; -import type AppRegistry from 'hadron-app-registry'; +import type AppRegistry from '@mongodb-js/compass-app-registry'; import type { ENVS } from '@mongodb-js/mongodb-constants'; import { setCollectionFields, @@ -26,7 +26,7 @@ import { INITIAL_STATE as SEARCH_INDEXES_INITIAL_STATE } from '../modules/search import { INITIAL_PANEL_OPEN_LOCAL_STORAGE_KEY } from '../modules/side-panel'; import type { DataService } from '../modules/data-service'; import type { WorkspacesService } from '@mongodb-js/compass-workspaces/provider'; -import type { ActivateHelpers } from 'hadron-app-registry'; +import type { ActivateHelpers } from '@mongodb-js/compass-app-registry'; import type { MongoDBInstance } from 'mongodb-instance-model'; import type Database from 'mongodb-database-model'; import type { CollectionTabPluginMetadata } from '@mongodb-js/compass-collection'; diff --git a/packages/hadron-app-registry/.depcheckrc b/packages/compass-app-registry/.depcheckrc similarity index 100% rename from packages/hadron-app-registry/.depcheckrc rename to packages/compass-app-registry/.depcheckrc diff --git a/packages/hadron-app-registry/.eslintignore b/packages/compass-app-registry/.eslintignore similarity index 100% rename from packages/hadron-app-registry/.eslintignore rename to packages/compass-app-registry/.eslintignore diff --git a/packages/hadron-app-registry/.eslintrc.js b/packages/compass-app-registry/.eslintrc.js similarity index 100% rename from packages/hadron-app-registry/.eslintrc.js rename to packages/compass-app-registry/.eslintrc.js diff --git a/packages/hadron-app-registry/.gitignore b/packages/compass-app-registry/.gitignore similarity index 100% rename from packages/hadron-app-registry/.gitignore rename to packages/compass-app-registry/.gitignore diff --git a/packages/hadron-app-registry/.mocharc.js b/packages/compass-app-registry/.mocharc.js similarity index 100% rename from packages/hadron-app-registry/.mocharc.js rename to packages/compass-app-registry/.mocharc.js diff --git a/packages/hadron-app-registry/.npmignore b/packages/compass-app-registry/.npmignore similarity index 100% rename from packages/hadron-app-registry/.npmignore rename to packages/compass-app-registry/.npmignore diff --git a/packages/hadron-app-registry/README.md b/packages/compass-app-registry/README.md similarity index 95% rename from packages/hadron-app-registry/README.md rename to packages/compass-app-registry/README.md index c28398aa4dd..6b74d0c3162 100644 --- a/packages/hadron-app-registry/README.md +++ b/packages/compass-app-registry/README.md @@ -1,4 +1,4 @@ -# hadron-app-registry +# @mongodb-js/compass-app-registry ## Concepts @@ -54,15 +54,15 @@ import { globalAppRegistry, AppRegistry, AppRegistryProvider, - registerHadronPlugin, -} from 'hadron-app-registry'; + registerCompassPlugin, +} from '@mongodb-js/compass-app-registry'; import CompassLogging from '@mongodb-js/compass-logging'; import { LoggingProvider, loggingLocator, } from '@mongodb-js/compass-logging/provider'; -const PluginWithLogger = registerHadronPlugin( +const PluginWithLogger = registerCompassPlugin( { name: 'LoggingPlugin', component: function () { @@ -93,7 +93,7 @@ intended to use. Typically, these functions are implemented using React contexts. ```typescript -import { createServiceLocator } from 'hadron-app-registry'; +import { createServiceLocator } from '@mongodb-js/compass-app-registry'; const ConnectionStorageContext = createContext(null); @@ -133,7 +133,7 @@ associated with it is destroyed). In order to make this easier, helpers are provided that automatically register cleanup functions: ```js -const Plugin = registerHadronPlugin({ +const Plugin = registerCompassPlugin({ name: 'TestPlugin', component: TestPluginComponent, activate(props, services, { on, addCleanup, cleanup }) { diff --git a/packages/hadron-app-registry/package.json b/packages/compass-app-registry/package.json similarity index 92% rename from packages/hadron-app-registry/package.json rename to packages/compass-app-registry/package.json index 4d7fe53356d..99c1df4a38e 100644 --- a/packages/hadron-app-registry/package.json +++ b/packages/compass-app-registry/package.json @@ -1,7 +1,10 @@ { - "name": "hadron-app-registry", - "description": "Hadron App Registry", - "author": "Durran Jordan ", + "name": "@mongodb-js/compass-app-registry", + "description": "Compass App Registry", + "author": { + "name": "MongoDB Inc", + "email": "compass@mongodb.com" + }, "bugs": { "url": "https://jira.mongodb.org/projects/COMPASS/issues", "email": "compass@mongodb.com" diff --git a/packages/hadron-app-registry/src/app-registry.spec.ts b/packages/compass-app-registry/src/app-registry.spec.ts similarity index 100% rename from packages/hadron-app-registry/src/app-registry.spec.ts rename to packages/compass-app-registry/src/app-registry.spec.ts diff --git a/packages/hadron-app-registry/src/app-registry.ts b/packages/compass-app-registry/src/app-registry.ts similarity index 100% rename from packages/hadron-app-registry/src/app-registry.ts rename to packages/compass-app-registry/src/app-registry.ts diff --git a/packages/hadron-app-registry/src/index.ts b/packages/compass-app-registry/src/index.ts similarity index 76% rename from packages/hadron-app-registry/src/index.ts rename to packages/compass-app-registry/src/index.ts index 3dbc0835869..0a2259e67b6 100644 --- a/packages/hadron-app-registry/src/index.ts +++ b/packages/compass-app-registry/src/index.ts @@ -7,15 +7,15 @@ export { GlobalAppRegistryProvider, } from './react-context'; export type { - HadronPluginComponent, - HadronPluginConfig, + CompassPluginComponent, + CompassPluginConfig, ActivateHelpers, } from './register-plugin'; export { - registerHadronPlugin, + registerCompassPlugin, createActivateHelpers, createServiceLocator, createServiceProvider, } from './register-plugin'; -export type { Plugin as HadronPlugin } from './app-registry'; +export type { Plugin as CompassPlugin } from './app-registry'; export default AppRegistry; diff --git a/packages/hadron-app-registry/src/react-context.tsx b/packages/compass-app-registry/src/react-context.tsx similarity index 100% rename from packages/hadron-app-registry/src/react-context.tsx rename to packages/compass-app-registry/src/react-context.tsx diff --git a/packages/hadron-app-registry/src/register-plugin.spec.tsx b/packages/compass-app-registry/src/register-plugin.spec.tsx similarity index 95% rename from packages/hadron-app-registry/src/register-plugin.spec.tsx rename to packages/compass-app-registry/src/register-plugin.spec.tsx index 94a2a34a978..17beaf75718 100644 --- a/packages/hadron-app-registry/src/register-plugin.spec.tsx +++ b/packages/compass-app-registry/src/register-plugin.spec.tsx @@ -4,7 +4,7 @@ import { expect } from 'chai'; import sinon from 'sinon'; import { AppRegistryProvider, - registerHadronPlugin, + registerCompassPlugin, createActivateHelpers, createServiceLocator, } from './'; @@ -12,13 +12,13 @@ import { createStore } from 'redux'; import { connect } from 'react-redux'; import { EventEmitter } from 'events'; -describe('registerHadronPlugin', function () { +describe('registerCompassPlugin', function () { afterEach(cleanup); it('allows registering plugins with a reflux-ish store', function () { const component = sinon.stub().callsFake(() => <>); const activate = sinon.stub().returns({ store: { state: { foo: 'bar' } } }); - const Plugin = registerHadronPlugin({ + const Plugin = registerCompassPlugin({ name: 'refluxish', component, activate, @@ -44,7 +44,7 @@ describe('registerHadronPlugin', function () { const component = sinon.stub().callsFake(() => <>); const store = { state: { foo: 'bar' } }; const activate = sinon.stub().returns({ store }); - const Plugin = registerHadronPlugin({ + const Plugin = registerCompassPlugin({ name: 'reflux', component, activate, @@ -77,7 +77,7 @@ describe('registerHadronPlugin', function () { } ); const activate = sinon.stub().returns({ store }); - const Plugin = registerHadronPlugin({ + const Plugin = registerCompassPlugin({ name: 'redux', component: connector(component), activate, @@ -112,7 +112,7 @@ describe('registerHadronPlugin', function () { const component = sinon.stub().callsFake(() => <>); const store = createStore(() => ({})); const activate = sinon.stub().returns({ store }); - const Plugin = registerHadronPlugin( + const Plugin = registerCompassPlugin( { name: 'service1', component: connector(component), diff --git a/packages/hadron-app-registry/src/register-plugin.tsx b/packages/compass-app-registry/src/register-plugin.tsx similarity index 93% rename from packages/hadron-app-registry/src/register-plugin.tsx rename to packages/compass-app-registry/src/register-plugin.tsx index 5810b768769..66b329948ba 100644 --- a/packages/hadron-app-registry/src/register-plugin.tsx +++ b/packages/compass-app-registry/src/register-plugin.tsx @@ -127,7 +127,7 @@ type Services unknown>> = { [SvcName in keyof S]: ReturnType; }; -export type HadronPluginConfig< +export type CompassPluginConfig< T, S extends Record unknown>, A extends Plugin @@ -188,7 +188,7 @@ export function createServiceLocator< if (!serviceLocationInProgress) { throw new Error( `Using service locator function "${name}" outside of the service location lifecycle. ` + - `Make sure that service locator function is passed as a second argument to the registerHadronPlugin method and is not used directly in a React render method.` + `Make sure that service locator function is passed as a second argument to the registerCompassPlugin method and is not used directly in a React render method.` ); } return fn.call(this, ...args); @@ -202,7 +202,7 @@ export function createServiceLocator< * need access to other service locators to facilitate service injections. In * these cases service provider can be wrapped with the createServiceProvider * function to allow usage of serviceLocator functions in providers outside of - * the usual hadron plugin "activate" lifecycle. + * the usual compass plugin "activate" lifecycle. */ export function createServiceProvider>( fn: T @@ -226,12 +226,12 @@ function isServiceLocator(val: any): boolean { return Object.prototype.hasOwnProperty.call(val, kLocator); } -function useHadronPluginActivate< +function useCompassPluginActivate< T, S extends Record unknown>, A extends Plugin >( - config: HadronPluginConfig, + config: CompassPluginConfig, services: S | undefined, props: T, mockOptions?: MockOptions @@ -306,7 +306,7 @@ function useHadronPluginActivate< return { store, actions, context }; } -export type HadronPluginComponent< +export type CompassPluginComponent< T, S extends Record unknown>, A extends Plugin @@ -320,7 +320,7 @@ export type HadronPluginComponent< * first render in their lifecycle * * @example - * const Plugin = registerHadronPlugin(...); + * const Plugin = registerCompassPlugin(...); * * function Component() { * Plugin.useActivate(); @@ -338,7 +338,7 @@ export type HadronPluginComponent< * registries available in the plugin context * * @example - * const PluginWithLogger = registerHadronPlugin({ ... }, { logger: loggerLocator }); + * const PluginWithLogger = registerCompassPlugin({ ... }, { logger: loggerLocator }); * * const MockPlugin = PluginWithLogger.withMockServices({ logger: Sinon.stub() }); * @@ -351,20 +351,20 @@ export type HadronPluginComponent< withMockServices( mocks: Partial>, options?: Partial> - ): HadronPluginComponent; + ): CompassPluginComponent; }; /** - * Creates a hadron plugin that will be automatically activated on first render + * Creates a compass plugin that will be automatically activated on first render * and cleaned up when localAppRegistry unmounts * - * @param config Hadron plugin configuration + * @param config Compass plugin configuration * @param services Map of service locator functions that plugin depends on * - * @returns Hadron plugin component + * @returns Compass plugin component * * @example - * const CreateCollectionPlugin = registerHadronPlugin({ + * const CreateCollectionPlugin = registerCompassPlugin({ * name: 'CreateCollection', * component: CreateCollectionModal, * activate(opts, { globalAppRegistry }) { @@ -399,7 +399,7 @@ export type HadronPluginComponent< * // plugin.js * import { logging } from '@mongodb-js/compass-logging/provider' * - * const PluginWithLogger = registerHadronPlugin({ + * const PluginWithLogger = registerCompassPlugin({ * name: 'LoggingPlugin', * component: () => null, * activate(opts, { logging }) { @@ -407,14 +407,14 @@ export type HadronPluginComponent< * } * }, { logging }) */ -export function registerHadronPlugin< +export function registerCompassPlugin< T, S extends Record unknown>, A extends Plugin >( - config: HadronPluginConfig, + config: CompassPluginConfig, services?: S -): HadronPluginComponent { +): CompassPluginComponent { const Component = config.component; const Plugin = (props: React.PropsWithChildren) => { const isMockedEnvironment = useMockOption('mockedEnvironment'); @@ -437,7 +437,7 @@ export function registerHadronPlugin< // thinks so: values returned by `useMock*` hooks are constant in React // runtime // eslint-disable-next-line react-hooks/rules-of-hooks - const { store, actions, context } = useHadronPluginActivate( + const { store, actions, context } = useCompassPluginActivate( config, services, props @@ -460,12 +460,12 @@ export function registerHadronPlugin< return Object.assign(Plugin, { displayName: config.name, useActivate: (props: T): A => { - return useHadronPluginActivate(config, services, props) as A; + return useCompassPluginActivate(config, services, props) as A; }, withMockServices( mocks: Partial> = {}, options?: Partial> - ): HadronPluginComponent { + ): CompassPluginComponent { const { // In case globalAppRegistry mock is not provided, we use the one // created in scope so that plugins don't leak their events and @@ -513,7 +513,7 @@ export function registerHadronPlugin< return Object.assign(MockPluginWithContext, { displayName: config.name, useActivate: (props: T): A => { - return useHadronPluginActivate( + return useCompassPluginActivate( config, services, props, diff --git a/packages/hadron-app-registry/tsconfig-lint.json b/packages/compass-app-registry/tsconfig-lint.json similarity index 100% rename from packages/hadron-app-registry/tsconfig-lint.json rename to packages/compass-app-registry/tsconfig-lint.json diff --git a/packages/hadron-app-registry/tsconfig.json b/packages/compass-app-registry/tsconfig.json similarity index 100% rename from packages/hadron-app-registry/tsconfig.json rename to packages/compass-app-registry/tsconfig.json diff --git a/packages/compass-app-stores/package.json b/packages/compass-app-stores/package.json index f10f16e798d..643729b266d 100644 --- a/packages/compass-app-stores/package.json +++ b/packages/compass-app-stores/package.json @@ -11,7 +11,7 @@ "email": "compass@mongodb.com" }, "homepage": "https://github.com/mongodb-js/compass", - "version": "7.46.0", + "version": "7.47.0", "repository": { "type": "git", "url": "https://github.com/mongodb-js/compass.git" @@ -71,15 +71,15 @@ "xvfb-maybe": "^0.2.1" }, "dependencies": { - "@mongodb-js/compass-components": "^1.38.1", - "@mongodb-js/compass-connections": "^1.60.0", + "@mongodb-js/compass-components": "^1.39.0", + "@mongodb-js/compass-connections": "^1.61.0", "@mongodb-js/compass-logging": "^1.7.2", "@mongodb-js/connection-info": "^0.15.2", - "hadron-app-registry": "^9.4.11", + "@mongodb-js/compass-app-registry": "^9.4.11", "mongodb-collection-model": "^5.29.2", "mongodb-database-model": "^2.29.2", - "mongodb-instance-model": "^12.32.2", - "compass-preferences-model": "^2.40.2", + "mongodb-instance-model": "^12.33.0", + "compass-preferences-model": "^2.41.0", "mongodb-ns": "^2.4.2", "react": "^17.0.2" }, diff --git a/packages/compass-app-stores/src/plugin.tsx b/packages/compass-app-stores/src/plugin.tsx index 2a8b12d599a..e2ef6552d43 100644 --- a/packages/compass-app-stores/src/plugin.tsx +++ b/packages/compass-app-stores/src/plugin.tsx @@ -1,9 +1,9 @@ import React from 'react'; import type { Logger } from '@mongodb-js/compass-logging/provider'; import { createLoggerLocator } from '@mongodb-js/compass-logging/provider'; -import type AppRegistry from 'hadron-app-registry'; -import type { ActivateHelpers } from 'hadron-app-registry'; -import { registerHadronPlugin } from 'hadron-app-registry'; +import type AppRegistry from '@mongodb-js/compass-app-registry'; +import type { ActivateHelpers } from '@mongodb-js/compass-app-registry'; +import { registerCompassPlugin } from '@mongodb-js/compass-app-registry'; import { MongoDBInstancesManagerContext } from './provider'; import { createInstancesStore } from './stores'; import type { ConnectionsService } from '@mongodb-js/compass-connections/provider'; @@ -28,7 +28,7 @@ function MongoDBInstancesManagerProvider({ ); } -export const CompassInstanceStorePlugin = registerHadronPlugin( +export const CompassInstanceStorePlugin = registerCompassPlugin( { name: 'CompassInstanceStore', component: MongoDBInstancesManagerProvider as React.FunctionComponent< diff --git a/packages/compass-app-stores/src/provider.tsx b/packages/compass-app-stores/src/provider.tsx index 7b0cf82f7d6..9bbfc34616c 100644 --- a/packages/compass-app-stores/src/provider.tsx +++ b/packages/compass-app-stores/src/provider.tsx @@ -5,7 +5,7 @@ import { import { createServiceLocator, createServiceProvider, -} from 'hadron-app-registry'; +} from '@mongodb-js/compass-app-registry'; import type { MongoDBInstanceProps } from 'mongodb-instance-model'; import { MongoDBInstance } from 'mongodb-instance-model'; import React, { diff --git a/packages/compass-app-stores/src/stores/instance-store.spec.ts b/packages/compass-app-stores/src/stores/instance-store.spec.ts index 768a609945e..e486dbc4c9d 100644 --- a/packages/compass-app-stores/src/stores/instance-store.spec.ts +++ b/packages/compass-app-stores/src/stores/instance-store.spec.ts @@ -1,4 +1,4 @@ -import type AppRegistry from 'hadron-app-registry'; +import type AppRegistry from '@mongodb-js/compass-app-registry'; import { CompassInstanceStorePlugin } from '../plugin'; import sinon from 'sinon'; import { expect } from 'chai'; diff --git a/packages/compass-app-stores/src/stores/instance-store.ts b/packages/compass-app-stores/src/stores/instance-store.ts index e91ee2f3b67..27fa52958a9 100644 --- a/packages/compass-app-stores/src/stores/instance-store.ts +++ b/packages/compass-app-stores/src/stores/instance-store.ts @@ -5,7 +5,10 @@ import type { ConnectionsService, DataService, } from '@mongodb-js/compass-connections/provider'; -import type { ActivateHelpers, AppRegistry } from 'hadron-app-registry'; +import type { + ActivateHelpers, + AppRegistry, +} from '@mongodb-js/compass-app-registry'; import type { Logger } from '@mongodb-js/compass-logging/provider'; import { openToast } from '@mongodb-js/compass-components'; import { MongoDBInstancesManager } from '../instances-manager'; diff --git a/packages/compass-collection/package.json b/packages/compass-collection/package.json index b8f884db658..6397f204b1a 100644 --- a/packages/compass-collection/package.json +++ b/packages/compass-collection/package.json @@ -11,7 +11,7 @@ "email": "compass@mongodb.com" }, "homepage": "https://github.com/mongodb-js/compass", - "version": "4.59.0", + "version": "4.60.0", "repository": { "type": "git", "url": "https://github.com/mongodb-js/compass.git" @@ -48,16 +48,16 @@ "reformat": "npm run eslint . -- --fix && npm run prettier -- --write ." }, "dependencies": { - "@mongodb-js/compass-app-stores": "^7.46.0", - "@mongodb-js/compass-components": "^1.38.1", - "@mongodb-js/compass-connections": "^1.60.0", + "@mongodb-js/compass-app-stores": "^7.47.0", + "@mongodb-js/compass-components": "^1.39.0", + "@mongodb-js/compass-connections": "^1.61.0", "@mongodb-js/compass-logging": "^1.7.2", "@mongodb-js/compass-telemetry": "^1.10.0", - "@mongodb-js/compass-workspaces": "^0.41.0", + "@mongodb-js/compass-workspaces": "^0.42.0", "@mongodb-js/connection-info": "^0.15.2", "@mongodb-js/mongodb-constants": "^0.11.0", - "compass-preferences-model": "^2.40.2", - "hadron-app-registry": "^9.4.11", + "compass-preferences-model": "^2.41.0", + "@mongodb-js/compass-app-registry": "^9.4.11", "mongodb-collection-model": "^5.29.2", "mongodb-ns": "^2.4.2", "react": "^17.0.2", diff --git a/packages/compass-collection/src/components/collection-tab-provider.tsx b/packages/compass-collection/src/components/collection-tab-provider.tsx index b4a1fe94266..531e5c9fbf9 100644 --- a/packages/compass-collection/src/components/collection-tab-provider.tsx +++ b/packages/compass-collection/src/components/collection-tab-provider.tsx @@ -1,11 +1,11 @@ import React, { useContext, useRef } from 'react'; import type { CollectionTabPluginMetadata } from '../modules/collection-tab'; -import type { HadronPluginComponent } from 'hadron-app-registry'; +import type { CompassPluginComponent } from '@mongodb-js/compass-app-registry'; import type { CollectionSubtab } from '@mongodb-js/compass-workspaces'; export interface CollectionTabPlugin { name: CollectionSubtab; - provider: HadronPluginComponent; + provider: CompassPluginComponent; content: React.FunctionComponent; header: React.FunctionComponent; } diff --git a/packages/compass-collection/src/index.ts b/packages/compass-collection/src/index.ts index 966639c078c..dc087a96e0b 100644 --- a/packages/compass-collection/src/index.ts +++ b/packages/compass-collection/src/index.ts @@ -1,33 +1,39 @@ +import React from 'react'; import CollectionTab from './components/collection-tab'; import { activatePlugin as activateCollectionTabPlugin } from './stores/collection-tab'; -import { registerHadronPlugin } from 'hadron-app-registry'; +import { registerCompassPlugin } from '@mongodb-js/compass-app-registry'; import { dataServiceLocator, type DataServiceLocator, type DataService, } from '@mongodb-js/compass-connections/provider'; import { collectionModelLocator } from '@mongodb-js/compass-app-stores/provider'; -import type { WorkspaceComponent } from '@mongodb-js/compass-workspaces'; +import type { WorkspacePlugin } from '@mongodb-js/compass-workspaces'; import { workspacesServiceLocator } from '@mongodb-js/compass-workspaces/provider'; +import { + CollectionWorkspaceTitle, + CollectionPluginTitleComponent, +} from './plugin-tab-title'; -export const CollectionTabPlugin = registerHadronPlugin( - { - name: 'CollectionTab', - component: CollectionTab, - activate: activateCollectionTabPlugin, - }, - { - dataService: dataServiceLocator as DataServiceLocator, - collection: collectionModelLocator, - workspaces: workspacesServiceLocator, - } -); - -export const WorkspaceTab: WorkspaceComponent<'Collection'> = { - name: 'Collection' as const, - component: CollectionTabPlugin, +export const WorkspaceTab: WorkspacePlugin = { + name: CollectionWorkspaceTitle, + provider: registerCompassPlugin( + { + name: CollectionWorkspaceTitle, + component: function CollectionProvider({ children }) { + return React.createElement(React.Fragment, null, children); + }, + activate: activateCollectionTabPlugin, + }, + { + dataService: dataServiceLocator as DataServiceLocator, + collection: collectionModelLocator, + workspaces: workspacesServiceLocator, + } + ), + content: CollectionTab, + header: CollectionPluginTitleComponent, }; -export default CollectionTabPlugin; export type { CollectionTabPluginMetadata } from './modules/collection-tab'; export { CollectionTabsProvider } from './components/collection-tab-provider'; diff --git a/packages/compass-collection/src/modules/collection-tab.ts b/packages/compass-collection/src/modules/collection-tab.ts index 0edeba38b05..cfa162fd848 100644 --- a/packages/compass-collection/src/modules/collection-tab.ts +++ b/packages/compass-collection/src/modules/collection-tab.ts @@ -1,7 +1,7 @@ import type { Reducer, AnyAction, Action } from 'redux'; import type { CollectionMetadata } from 'mongodb-collection-model'; import type { ThunkAction } from 'redux-thunk'; -import type AppRegistry from 'hadron-app-registry'; +import type AppRegistry from '@mongodb-js/compass-app-registry'; import type { workspacesServiceLocator } from '@mongodb-js/compass-workspaces/provider'; import type { CollectionSubtab } from '@mongodb-js/compass-workspaces'; import type { DataService } from '@mongodb-js/compass-connections/provider'; diff --git a/packages/compass-collection/src/plugin-tab-title.tsx b/packages/compass-collection/src/plugin-tab-title.tsx new file mode 100644 index 00000000000..c0e29b8efcd --- /dev/null +++ b/packages/compass-collection/src/plugin-tab-title.tsx @@ -0,0 +1,90 @@ +import React from 'react'; +import { connect } from 'react-redux'; +import toNS from 'mongodb-ns'; +import { + useConnectionInfo, + useConnectionsListRef, + useTabConnectionTheme, +} from '@mongodb-js/compass-connections/provider'; +import { + WorkspaceTab, + type WorkspaceTabCoreProps, +} from '@mongodb-js/compass-components'; +import type { WorkspacePluginProps } from '@mongodb-js/compass-workspaces'; + +import { type CollectionState } from './modules/collection-tab'; + +export const CollectionWorkspaceTitle = 'Collection' as const; + +type PluginTitleProps = { + isTimeSeries?: boolean; + isReadonly?: boolean; + sourceName?: string | null; +} & WorkspaceTabCoreProps & + WorkspacePluginProps; + +function _PluginTitle({ + editViewName, + isNonExistent, + isReadonly, + isTimeSeries, + sourceName, + namespace, + ...tabProps +}: PluginTitleProps) { + const { getThemeOf } = useTabConnectionTheme(); + const { getConnectionById } = useConnectionsListRef(); + const { id: connectionId } = useConnectionInfo(); + + const { database, collection, ns } = toNS(namespace); + const connectionName = getConnectionById(connectionId)?.title || ''; + const collectionType = isTimeSeries + ? 'timeseries' + : isReadonly + ? 'view' + : 'collection'; + // Similar to what we have in the collection breadcrumbs. + const tooltip: [string, string][] = [ + ['Connection', connectionName || ''], + ['Database', database], + ]; + if (sourceName) { + tooltip.push(['View', collection]); + tooltip.push(['Derived from', toNS(sourceName).collection]); + } else if (editViewName) { + tooltip.push(['View', toNS(editViewName).collection]); + tooltip.push(['Derived from', collection]); + } else { + tooltip.push(['Collection', collection]); + } + + return ( + + ); +} + +export const CollectionPluginTitleComponent = connect( + (state: CollectionState) => ({ + isTimeSeries: state.metadata?.isTimeSeries, + isReadonly: state.metadata?.isReadonly, + sourceName: state.metadata?.sourceName, + }) +)(_PluginTitle); diff --git a/packages/compass-collection/src/stores/collection-tab.spec.ts b/packages/compass-collection/src/stores/collection-tab.spec.ts index 8f6445a7633..69bc0ff56e5 100644 --- a/packages/compass-collection/src/stores/collection-tab.spec.ts +++ b/packages/compass-collection/src/stores/collection-tab.spec.ts @@ -3,7 +3,7 @@ import { activatePlugin } from './collection-tab'; import { selectTab } from '../modules/collection-tab'; import { waitFor } from '@mongodb-js/testing-library-compass'; import Sinon from 'sinon'; -import AppRegistry from 'hadron-app-registry'; +import AppRegistry from '@mongodb-js/compass-app-registry'; import { expect } from 'chai'; import type { workspacesServiceLocator } from '@mongodb-js/compass-workspaces/provider'; diff --git a/packages/compass-collection/src/stores/collection-tab.ts b/packages/compass-collection/src/stores/collection-tab.ts index 991887b1fb4..d04359af108 100644 --- a/packages/compass-collection/src/stores/collection-tab.ts +++ b/packages/compass-collection/src/stores/collection-tab.ts @@ -1,4 +1,4 @@ -import type AppRegistry from 'hadron-app-registry'; +import type AppRegistry from '@mongodb-js/compass-app-registry'; import type { DataService } from '@mongodb-js/compass-connections/provider'; import { createStore, applyMiddleware } from 'redux'; import thunk from 'redux-thunk'; @@ -7,7 +7,7 @@ import reducer, { collectionMetadataFetched, } from '../modules/collection-tab'; import type { Collection } from '@mongodb-js/compass-app-stores/provider'; -import type { ActivateHelpers } from 'hadron-app-registry'; +import type { ActivateHelpers } from '@mongodb-js/compass-app-registry'; import type { workspacesServiceLocator } from '@mongodb-js/compass-workspaces/provider'; export type CollectionTabOptions = { diff --git a/packages/compass-components/package.json b/packages/compass-components/package.json index 0e78208a495..e5f44908ba0 100644 --- a/packages/compass-components/package.json +++ b/packages/compass-components/package.json @@ -1,6 +1,6 @@ { "name": "@mongodb-js/compass-components", - "version": "1.38.1", + "version": "1.39.0", "description": "React Components used in Compass", "license": "SSPL", "main": "lib/index.js", @@ -75,6 +75,7 @@ "@leafygreen-ui/tokens": "^2.11.3", "@leafygreen-ui/tooltip": "^13.0.2", "@leafygreen-ui/typography": "^20.0.2", + "@mongodb-js/compass-context-menu": "^0.0.1", "@react-aria/interactions": "^3.9.1", "@react-aria/utils": "^3.13.1", "@react-aria/visually-hidden": "^3.3.1", diff --git a/packages/compass-components/src/components/compass-components-provider.tsx b/packages/compass-components/src/components/compass-components-provider.tsx index 18bac239d30..7a2fdf20117 100644 --- a/packages/compass-components/src/components/compass-components-provider.tsx +++ b/packages/compass-components/src/components/compass-components-provider.tsx @@ -6,6 +6,7 @@ import { GuideCueProvider } from './guide-cue/guide-cue'; import { SignalHooksProvider } from './signal-popover'; import { RequiredURLSearchParamsProvider } from './links/link'; import { StackedComponentProvider } from '../hooks/use-stacked-component'; +import { ContextMenuProvider } from './context-menu'; type GuideCueProviderProps = React.ComponentProps; @@ -135,15 +136,17 @@ export const CompassComponentsProvider = ({ > - - {typeof children === 'function' - ? children({ - darkMode, - portalContainerRef: setPortalContainer, - scrollContainerRef: setScrollContainer, - }) - : children} - + + + {typeof children === 'function' + ? children({ + darkMode, + portalContainerRef: setPortalContainer, + scrollContainerRef: setScrollContainer, + }) + : children} + + diff --git a/packages/compass-components/src/components/content-with-fallback.spec.tsx b/packages/compass-components/src/components/content-with-fallback.spec.tsx index bd4daa3861c..5b989316f5b 100644 --- a/packages/compass-components/src/components/content-with-fallback.spec.tsx +++ b/packages/compass-components/src/components/content-with-fallback.spec.tsx @@ -58,7 +58,10 @@ describe('ContentWithFallback', function () { { container } ); - expect(container).to.be.empty; + expect(container.children.length).to.equal(1); + expect(container.children[0].getAttribute('data-testid')).to.equal( + 'context-menu' + ); }); it('should render fallback when the timeout passes', async function () { diff --git a/packages/compass-components/src/components/context-menu.spec.tsx b/packages/compass-components/src/components/context-menu.spec.tsx new file mode 100644 index 00000000000..13fd851ec0c --- /dev/null +++ b/packages/compass-components/src/components/context-menu.spec.tsx @@ -0,0 +1,166 @@ +import React from 'react'; +import { render, screen, userEvent } from '@mongodb-js/testing-library-compass'; +import { expect } from 'chai'; +import sinon from 'sinon'; +import { ContextMenuProvider } from '@mongodb-js/compass-context-menu'; +import { useContextMenuItems, ContextMenu } from './context-menu'; +import type { ContextMenuItem } from '@mongodb-js/compass-context-menu'; + +describe('useContextMenuItems', function () { + const menuTestTriggerId = 'test-trigger'; + + const TestComponent = ({ + items, + children, + 'data-testid': dataTestId = menuTestTriggerId, + }: { + items: ContextMenuItem[]; + children?: React.ReactNode; + 'data-testid'?: string; + }) => { + const ref = useContextMenuItems(() => items, [items]); + + return ( +
+ Test Component + {children} +
+ ); + }; + + it('works with nested providers, using the parent provider', function () { + const items = [ + { + label: 'Test Item', + onAction: () => {}, + }, + ]; + + const { container } = render( + + + + + + ); + + // Should only find one context menu (from the parent provider) + expect( + container.querySelectorAll('[data-testid="context-menu"]') + ).to.have.length(1); + // Should still render the trigger + expect(screen.getByTestId(menuTestTriggerId)).to.exist; + }); + + it('renders without error', function () { + const items = [ + { + label: 'Test Item', + onAction: () => {}, + }, + ]; + + render(); + + expect(screen.getByTestId(menuTestTriggerId)).to.exist; + }); + + it('shows context menu with items on right click', function () { + const items = [ + { + label: 'Test Item 1', + onAction: () => {}, + }, + { + label: 'Test Item 2', + onAction: () => {}, + }, + ]; + + render(); + + const trigger = screen.getByTestId(menuTestTriggerId); + userEvent.click(trigger, { button: 2 }); + + // The menu items should be rendered + expect(screen.getByTestId('menu-group-0-item-0')).to.exist; + expect(screen.getByTestId('menu-group-0-item-1')).to.exist; + }); + + it('triggers the correct action when menu item is clicked', function () { + const onAction = sinon.spy(); + const items = [ + { + label: 'Test Item 1', + onAction: () => onAction(1), + }, + { + label: 'Test Item 2', + onAction: () => onAction(2), + }, + ]; + + render(); + + const trigger = screen.getByTestId(menuTestTriggerId); + userEvent.click(trigger, { button: 2 }); + + const menuItem = screen.getByTestId('menu-group-0-item-1'); + userEvent.click(menuItem); + + expect(onAction).to.have.been.calledOnceWithExactly(2); + }); + + describe('with nested components', function () { + const childTriggerId = 'child-trigger'; + + beforeEach(function () { + const items = [ + { + label: 'Test Item 1', + onAction: () => {}, + }, + { + label: 'Test Item 2', + onAction: () => {}, + }, + ]; + + const childItems = [ + { + label: 'Child Item 1', + onAction: () => {}, + }, + ]; + + render( + + + + ); + }); + + it('renders menu items with separators', function () { + const trigger = screen.getByTestId(childTriggerId); + userEvent.click(trigger, { button: 2 }); + + // Should find the menu item and the separator + expect(screen.getByTestId('menu-group-0').children.length).to.equal(2); + expect( + screen.getByTestId('menu-group-0').children.item(0)?.textContent + ).to.equal('Child Item 1'); + + expect(screen.getByTestId('menu-group-0-separator')).to.exist; + + expect(screen.getByTestId('menu-group-1').children.length).to.equal(2); + expect( + screen.getByTestId('menu-group-1').children.item(0)?.textContent + ).to.equal('Test Item 1'); + expect( + screen.getByTestId('menu-group-1').children.item(1)?.textContent + ).to.equal('Test Item 2'); + + expect(screen.queryByTestId('menu-group-1-separator')).not.to.exist; + }); + }); +}); diff --git a/packages/compass-components/src/components/context-menu.tsx b/packages/compass-components/src/components/context-menu.tsx new file mode 100644 index 00000000000..0346589e318 --- /dev/null +++ b/packages/compass-components/src/components/context-menu.tsx @@ -0,0 +1,98 @@ +import React, { useEffect, useMemo } from 'react'; +import { Menu, MenuItem, MenuSeparator } from './leafygreen'; +import type { ContextMenuItem } from '@mongodb-js/compass-context-menu'; +import { useContextMenu } from '@mongodb-js/compass-context-menu'; +import { ContextMenuProvider as ContextMenuProviderBase } from '@mongodb-js/compass-context-menu'; +import type { + ContextMenuItemGroup, + ContextMenuWrapperProps, +} from '@mongodb-js/compass-context-menu'; + +export function ContextMenuProvider({ + children, +}: { + children: React.ReactNode; +}) { + return ( + + {children} + + ); +} + +export function ContextMenu({ menu }: ContextMenuWrapperProps) { + const position = menu.position; + const itemGroups = menu.itemGroups; + + useEffect(() => { + if (!menu.isOpen) { + menu.close(); + } + }, [menu.isOpen]); + + return ( +
+ + {itemGroups.map( + (itemGroup: ContextMenuItemGroup, groupIndex: number) => { + return ( +
+ {itemGroup.items.map( + (item: ContextMenuItem, itemIndex: number) => { + return ( + { + item.onAction?.(evt); + menu.close(); + }} + > + {item.label} + + ); + } + )} + {groupIndex < itemGroups.length - 1 && ( +
+ +
+ )} +
+ ); + } + )} +
+
+ ); +} + +export function useContextMenuItems( + getItems: () => ContextMenuItem[], + dependencies: React.DependencyList | undefined +): React.RefCallback { + // eslint-disable-next-line react-hooks/exhaustive-deps + const memoizedItems = useMemo(getItems, dependencies); + const contextMenu = useContextMenu(); + return contextMenu.registerItems(memoizedItems); +} diff --git a/packages/compass-components/src/components/document-list/element.spec.tsx b/packages/compass-components/src/components/document-list/element.spec.tsx new file mode 100644 index 00000000000..88fa527f257 --- /dev/null +++ b/packages/compass-components/src/components/document-list/element.spec.tsx @@ -0,0 +1,121 @@ +import React from 'react'; +import { render, screen, userEvent } from '@mongodb-js/testing-library-compass'; +import { expect } from 'chai'; +import sinon from 'sinon'; +import HadronDocument from 'hadron-document'; +import { HadronElement } from './element'; +import type { Element } from 'hadron-document'; + +describe('HadronElement', function () { + describe('context menu', function () { + let doc: HadronDocument; + let element: Element; + let windowOpenStub: sinon.SinonStub; + let clipboardWriteTextStub: sinon.SinonStub; + + beforeEach(function () { + doc = new HadronDocument({ field: 'value' }); + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + element = doc.elements.at(0)!; + windowOpenStub = sinon.stub(window, 'open'); + clipboardWriteTextStub = sinon.stub(navigator.clipboard, 'writeText'); + }); + + afterEach(function () { + windowOpenStub.restore(); + clipboardWriteTextStub.restore(); + }); + + it('copies field and value when "Copy field & value" is clicked', function () { + render( + {}} + /> + ); + + // Open context menu and click the copy option + const elementNode = screen.getByTestId('hadron-document-element'); + userEvent.click(elementNode, { button: 2 }); + userEvent.click(screen.getByText('Copy field & value'), undefined, { + skipPointerEventsCheck: true, + }); + + expect(clipboardWriteTextStub).to.have.been.calledWith('field: "value"'); + }); + + it('shows "Open URL in browser" for URL string values', function () { + const urlDoc = new HadronDocument({ link: 'https://mongodb.com' }); + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + const urlElement = urlDoc.elements.at(0)!; + + render( + {}} + /> + ); + + // Open context menu + const elementNode = screen.getByTestId('hadron-document-element'); + userEvent.click(elementNode, { button: 2 }); + + // Check if the menu item exists + expect(screen.getByText('Open URL in browser')).to.exist; + }); + + it('opens URL in new tab when "Open URL in browser" is clicked', function () { + const urlDoc = new HadronDocument({ link: 'https://mongodb.com' }); + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + const urlElement = urlDoc.elements.at(0)!; + + render( + {}} + /> + ); + + // Open context menu and click the open URL option + const elementNode = screen.getByTestId('hadron-document-element'); + userEvent.click(elementNode, { button: 2 }); + userEvent.click(screen.getByText('Open URL in browser'), undefined, { + skipPointerEventsCheck: true, + }); + + expect(windowOpenStub).to.have.been.calledWith( + 'https://mongodb.com', + '_blank', + 'noopener' + ); + }); + + it('does not show "Open URL in browser" for non-URL string values', function () { + render( + {}} + /> + ); + + // Open context menu + const elementNode = screen.getByTestId('hadron-document-element'); + userEvent.click(elementNode, { button: 2 }); + + // Check that the menu item doesn't exist + expect(screen.queryByText('Open URL in browser')).to.not.exist; + }); + }); +}); diff --git a/packages/compass-components/src/components/document-list/element.tsx b/packages/compass-components/src/components/document-list/element.tsx index b79c96f4015..7c3879ecba9 100644 --- a/packages/compass-components/src/components/document-list/element.tsx +++ b/packages/compass-components/src/components/document-list/element.tsx @@ -15,6 +15,7 @@ import { ElementEvents, ElementEditor, DEFAULT_VISIBLE_ELEMENTS, + objectToIdiomaticEJSON, } from 'hadron-document'; import BSONValue from '../bson-value'; import { spacing } from '@leafygreen-ui/tokens'; @@ -28,6 +29,7 @@ import { palette } from '@leafygreen-ui/palette'; import { Icon } from '../leafygreen'; import { useDarkMode } from '../../hooks/use-theme'; import VisibleFieldsToggle from './visible-field-toggle'; +import { useFieldContextMenu } from '../../hooks/use-element-context-menu'; function getEditorByType(type: HadronElementType['type']) { switch (type) { @@ -447,6 +449,12 @@ export const HadronElement: React.FunctionComponent<{ collapse, } = useHadronElement(element); + // Add context menu hook for the field + const fieldContextMenuRef = useFieldContextMenu({ + element, + fieldName: key.value, + }); + const toggleExpanded = () => { if (expanded) { collapse(); @@ -493,6 +501,7 @@ export const HadronElement: React.FunctionComponent<{ : elementInvalidLightMode; const elementProps = { + ref: fieldContextMenuRef, className: cx( hadronElement, darkMode ? hadronElementDarkMode : hadronElementLightMode, @@ -531,6 +540,7 @@ export const HadronElement: React.FunctionComponent<{ data-field={key.value} data-id={element.uuid} {...elementProps} + ref={fieldContextMenuRef} > {editable && (
diff --git a/packages/compass-components/src/components/workspace-tabs/tab.tsx b/packages/compass-components/src/components/workspace-tabs/tab.tsx index 14892ec71b2..227eee98332 100644 --- a/packages/compass-components/src/components/workspace-tabs/tab.tsx +++ b/packages/compass-components/src/components/workspace-tabs/tab.tsx @@ -5,6 +5,7 @@ import { spacing } from '@leafygreen-ui/tokens'; import type { GlyphName } from '@leafygreen-ui/icon'; import { useSortable } from '@dnd-kit/sortable'; import { CSS as cssDndKit } from '@dnd-kit/utilities'; +import { useId } from '@react-aria/utils'; import { useDarkMode } from '../../hooks/use-theme'; import { Icon, IconButton } from '../leafygreen'; import { mergeProps } from '../../utils/merge-props'; @@ -149,6 +150,10 @@ const draggingTabStyles = css({ cursor: 'grabbing !important', }); +const nonExistentStyles = css({ + color: palette.gray.base, +}); + const tabIconStyles = css({ color: 'currentColor', marginLeft: spacing[300], @@ -185,25 +190,34 @@ const workspaceTabTooltipStyles = css({ textWrap: 'wrap', }); -type TabProps = { +// The plugins provide these essential props use to render the tab. +// The workspace-tabs component provides the other parts of TabProps. +export type WorkspaceTabPluginProps = { connectionName?: string; type: string; - title: string; + title: React.ReactNode; + isNonExistent?: boolean; + iconGlyph: GlyphName | 'Logo' | 'Server'; + tooltip?: [string, string][]; + tabTheme?: Partial; +}; + +export type WorkspaceTabCoreProps = { isSelected: boolean; isDragging: boolean; onSelect: () => void; onClose: () => void; - iconGlyph: GlyphName | 'Logo' | 'Server'; tabContentId: string; - tooltip?: [string, string][]; - tabTheme?: Partial; }; +type TabProps = WorkspaceTabCoreProps & WorkspaceTabPluginProps; + function Tab({ connectionName, type, title, tooltip, + isNonExistent, isSelected, isDragging, onSelect, @@ -213,7 +227,7 @@ function Tab({ tabTheme, className: tabClassName, ...props -}: TabProps & React.HTMLProps) { +}: TabProps & Omit, 'title'>) { const darkMode = useDarkMode(); const defaultActionProps = useDefaultAction(onSelect); const { listeners, setNodeRef, transform, transition } = useSortable({ @@ -240,6 +254,8 @@ function Tab({ cursor: 'grabbing !important', }; + const tabId = useId(); + return ( {iconGlyph === 'Logo' && ( diff --git a/packages/compass-components/src/components/workspace-tabs/workspace-tabs.spec.tsx b/packages/compass-components/src/components/workspace-tabs/workspace-tabs.spec.tsx index ec0868042c2..b882fd1e025 100644 --- a/packages/compass-components/src/components/workspace-tabs/workspace-tabs.spec.tsx +++ b/packages/compass-components/src/components/workspace-tabs/workspace-tabs.spec.tsx @@ -9,14 +9,23 @@ import { expect } from 'chai'; import sinon from 'sinon'; import { WorkspaceTabs } from './workspace-tabs'; -import type { TabProps } from './workspace-tabs'; +import { Tab, type WorkspaceTabCoreProps } from './tab'; -function mockTab(tabId: number): TabProps { +function mockTab(tabId: number): { + id: string; + renderTab: (tabProps: WorkspaceTabCoreProps) => ReturnType; +} { return { - type: 'Documents', - title: `mock-tab-${tabId}`, id: `${tabId}-content`, - iconGlyph: 'Folder', + renderTab: (tabProps: WorkspaceTabCoreProps) => ( + + ), }; } diff --git a/packages/compass-components/src/components/workspace-tabs/workspace-tabs.tsx b/packages/compass-components/src/components/workspace-tabs/workspace-tabs.tsx index d85852a4a04..5d48e3f4388 100644 --- a/packages/compass-components/src/components/workspace-tabs/workspace-tabs.tsx +++ b/packages/compass-components/src/components/workspace-tabs/workspace-tabs.tsx @@ -8,7 +8,6 @@ import React, { import { css, cx } from '@leafygreen-ui/emotion'; import { palette } from '@leafygreen-ui/palette'; import { spacing } from '@leafygreen-ui/tokens'; -import type { GlyphName } from '@leafygreen-ui/icon'; import { rgba } from 'polished'; import { @@ -28,7 +27,8 @@ import { useDarkMode } from '../../hooks/use-theme'; import { FocusState, useFocusState } from '../../hooks/use-focus-hover'; import { Icon, IconButton } from '../leafygreen'; import { mergeProps } from '../../utils/merge-props'; -import { Tab } from './tab'; +import type { Tab } from './tab'; +import type { WorkspaceTabCoreProps } from './tab'; import { useHotkeys } from '../../hooks/use-hotkeys'; export const scrollbarThumbLightTheme = rgba(palette.gray.base, 0.65); @@ -139,8 +139,13 @@ function useTabListKeyboardNavigation({ return [{ onKeyDown }]; } +type TabItem = { + id: string; + renderTab: (props: WorkspaceTabCoreProps) => ReturnType; +}; + type SortableItemProps = { - tab: TabProps; + tab: TabItem; index: number; selectedTabIndex: number; activeId: UniqueIdentifier | null; @@ -149,7 +154,7 @@ type SortableItemProps = { }; type SortableListProps = { - tabs: TabProps[]; + tabs: TabItem[]; selectedTabIndex: number; onMove: (oldTabIndex: number, newTabIndex: number) => void; onSelect: (tabIndex: number) => void; @@ -164,19 +169,10 @@ type WorkspaceTabsProps = { onSelectPrevTab: () => void; onCloseTab: (tabIndex: number) => void; onMoveTab: (oldTabIndex: number, newTabIndex: number) => void; - tabs: TabProps[]; + tabs: TabItem[]; selectedTabIndex: number; }; -export type TabProps = { - id: string; - type: string; - title: string; - tooltip?: [string, string][]; - connectionId?: string; - iconGlyph: GlyphName | 'Logo' | 'Server'; -} & Omit, 'id' | 'title'>; - export function useRovingTabIndex({ currentTabbable, }: { @@ -263,7 +259,7 @@ const SortableList = ({ >
- {tabs.map((tab: TabProps, index: number) => ( + {tabs.map((tab: TabItem, index: number) => ( { - const { id: tabId } = tabProps; - const onTabSelected = useCallback(() => { onSelect(index); }, [onSelect, index]); @@ -305,16 +299,13 @@ const SortableItem = ({ const isDragging = useMemo(() => tabId === activeId, [tabId, activeId]); - return ( - - ); + return renderTab({ + isSelected, + isDragging, + tabContentId: tabId, + onSelect: onTabSelected, + onClose: onTabClosed, + }); }; function WorkspaceTabs({ diff --git a/packages/compass-components/src/hooks/use-element-context-menu.ts b/packages/compass-components/src/hooks/use-element-context-menu.ts new file mode 100644 index 00000000000..4e0948d8ddc --- /dev/null +++ b/packages/compass-components/src/hooks/use-element-context-menu.ts @@ -0,0 +1,62 @@ +import { useContextMenuItems } from '../components/context-menu'; +import { Element } from 'hadron-document'; +import { objectToIdiomaticEJSON } from 'hadron-document'; + +// Helper function to check if a string is a URL +export const isValidUrl = (str: string): boolean => { + try { + const url = new URL(str); + return url.protocol === 'http:' || url.protocol === 'https:'; + } catch { + return false; + } +}; + +export interface useFieldContextMenuProps { + element: Element | undefined | null; + fieldName: string; +} + +export function useFieldContextMenu({ + element, + fieldName, +}: useFieldContextMenuProps) { + return useContextMenuItems([ + ...(element + ? [ + { + label: 'Copy field & value', + onAction: () => { + const fieldStr = `${fieldName}: ${objectToIdiomaticEJSON( + element.currentValue + )}`; + void navigator.clipboard.writeText(fieldStr); + }, + }, + { + label: 'Copy value', + onAction: () => { + const valueStr = objectToIdiomaticEJSON(element.currentValue); + void navigator.clipboard.writeText(valueStr); + }, + }, + ...(element.currentType === 'String' && + typeof element.currentValue === 'string' && + isValidUrl(element.currentValue) + ? [ + { + label: 'Open URL in browser', + onAction: () => { + window.open( + element.currentValue as string, + '_blank', + 'noopener' + ); + }, + }, + ] + : []), + ] + : []), + ]); +} diff --git a/packages/compass-components/src/index.ts b/packages/compass-components/src/index.ts index d577dd2bf13..60d9da62136 100644 --- a/packages/compass-components/src/index.ts +++ b/packages/compass-components/src/index.ts @@ -38,7 +38,11 @@ export { import { ResizeHandle, ResizeDirection } from './components/resize-handle'; import { Accordion } from './components/accordion'; import { CollapsibleFieldSet } from './components/collapsible-field-set'; -export { type TabTheme } from './components/workspace-tabs/tab'; +export { + Tab as WorkspaceTab, + type TabTheme, + type WorkspaceTabCoreProps, +} from './components/workspace-tabs/tab'; import { WorkspaceTabs } from './components/workspace-tabs/workspace-tabs'; import ResizableSidebar, { defaultSidebarWidth, @@ -93,6 +97,8 @@ export { ModalHeader } from './components/modals/modal-header'; export { FormModal } from './components/modals/form-modal'; export { InfoModal } from './components/modals/info-modal'; +export { useContextMenuItems } from './components/context-menu'; + export type { FileInputBackend, ItemAction, @@ -213,3 +219,4 @@ export { export { SelectList } from './components/select-list'; export { ParagraphSkeleton } from '@leafygreen-ui/skeleton-loader'; export { InsightsChip } from './components/insights-chip'; +export { useFieldContextMenu } from './hooks/use-element-context-menu'; diff --git a/packages/compass-connection-import-export/package.json b/packages/compass-connection-import-export/package.json index 8c80f706cde..329fa013bc6 100644 --- a/packages/compass-connection-import-export/package.json +++ b/packages/compass-connection-import-export/package.json @@ -14,7 +14,7 @@ "email": "compass@mongodb.com" }, "homepage": "https://github.com/mongodb-js/compass", - "version": "0.56.0", + "version": "0.57.0", "repository": { "type": "git", "url": "https://github.com/mongodb-js/compass.git" @@ -51,10 +51,10 @@ "reformat": "npm run eslint . -- --fix && npm run prettier -- --write ." }, "dependencies": { - "@mongodb-js/compass-components": "^1.38.1", - "@mongodb-js/compass-connections": "^1.60.0", - "@mongodb-js/connection-storage": "^0.35.0", - "compass-preferences-model": "^2.40.2", + "@mongodb-js/compass-components": "^1.39.0", + "@mongodb-js/compass-connections": "^1.61.0", + "@mongodb-js/connection-storage": "^0.36.0", + "compass-preferences-model": "^2.41.0", "hadron-ipc": "^3.5.2", "react": "^17.0.2" }, diff --git a/packages/compass-connections-navigation/package.json b/packages/compass-connections-navigation/package.json index a9541e008d3..eb7929a7f6e 100644 --- a/packages/compass-connections-navigation/package.json +++ b/packages/compass-connections-navigation/package.json @@ -13,7 +13,7 @@ "email": "compass@mongodb.com" }, "homepage": "https://github.com/mongodb-js/compass", - "version": "1.59.0", + "version": "1.60.0", "repository": { "type": "git", "url": "https://github.com/mongodb-js/compass.git" @@ -49,12 +49,12 @@ "reformat": "npm run eslint . -- --fix && npm run prettier -- --write ." }, "dependencies": { - "@mongodb-js/compass-connections": "^1.60.0", - "@mongodb-js/compass-components": "^1.38.1", + "@mongodb-js/compass-connections": "^1.61.0", + "@mongodb-js/compass-components": "^1.39.0", "@mongodb-js/connection-info": "^0.15.2", - "@mongodb-js/connection-form": "^1.52.3", - "@mongodb-js/compass-workspaces": "^0.41.0", - "compass-preferences-model": "^2.40.2", + "@mongodb-js/connection-form": "^1.53.0", + "@mongodb-js/compass-workspaces": "^0.42.0", + "compass-preferences-model": "^2.41.0", "mongodb-build-info": "^1.7.2", "react": "^17.0.2", "react-virtualized-auto-sizer": "^1.0.6", diff --git a/packages/compass-connections/package.json b/packages/compass-connections/package.json index 5fb92e78518..fd03e27c807 100644 --- a/packages/compass-connections/package.json +++ b/packages/compass-connections/package.json @@ -13,7 +13,7 @@ "email": "compass@mongodb.com" }, "homepage": "https://github.com/mongodb-js/compass", - "version": "1.60.0", + "version": "1.61.0", "repository": { "type": "git", "url": "https://github.com/mongodb-js/compass.git" @@ -51,16 +51,16 @@ "reformat": "npm run eslint . -- --fix && npm run prettier -- --write ." }, "dependencies": { - "@mongodb-js/compass-components": "^1.38.1", + "@mongodb-js/compass-components": "^1.39.0", "@mongodb-js/compass-logging": "^1.7.2", "@mongodb-js/compass-telemetry": "^1.10.0", "@mongodb-js/compass-utils": "^0.9.2", - "@mongodb-js/connection-form": "^1.52.3", + "@mongodb-js/connection-form": "^1.53.0", "@mongodb-js/connection-info": "^0.15.2", - "@mongodb-js/connection-storage": "^0.35.0", + "@mongodb-js/connection-storage": "^0.36.0", "bson": "^6.10.3", - "compass-preferences-model": "^2.40.2", - "hadron-app-registry": "^9.4.11", + "compass-preferences-model": "^2.41.0", + "@mongodb-js/compass-app-registry": "^9.4.11", "lodash": "^4.17.21", "mongodb": "^6.16.0", "mongodb-build-info": "^1.7.2", diff --git a/packages/compass-connections/src/connection-info-provider.tsx b/packages/compass-connections/src/connection-info-provider.tsx index c41325085d6..9783d6718ed 100644 --- a/packages/compass-connections/src/connection-info-provider.tsx +++ b/packages/compass-connections/src/connection-info-provider.tsx @@ -3,7 +3,7 @@ import { type ConnectionInfo } from '@mongodb-js/connection-info'; import { createServiceLocator, createServiceProvider, -} from 'hadron-app-registry'; +} from '@mongodb-js/compass-app-registry'; import { useConnectionForId, useConnectionInfoForId, diff --git a/packages/compass-connections/src/connection-scoped-app-registry.ts b/packages/compass-connections/src/connection-scoped-app-registry.ts index 43d1981e247..df1ce490262 100644 --- a/packages/compass-connections/src/connection-scoped-app-registry.ts +++ b/packages/compass-connections/src/connection-scoped-app-registry.ts @@ -2,7 +2,7 @@ import { type AppRegistry, createServiceLocator, useGlobalAppRegistry, -} from 'hadron-app-registry'; +} from '@mongodb-js/compass-app-registry'; import type { ConnectionInfoRef } from './connection-info-provider'; import { connectionInfoRefLocator } from './connection-info-provider'; diff --git a/packages/compass-connections/src/index.tsx b/packages/compass-connections/src/index.tsx index aab107b17a2..299165f51ee 100644 --- a/packages/compass-connections/src/index.tsx +++ b/packages/compass-connections/src/index.tsx @@ -1,5 +1,5 @@ import { preferencesLocator } from 'compass-preferences-model/provider'; -import { registerHadronPlugin } from 'hadron-app-registry'; +import { registerCompassPlugin } from '@mongodb-js/compass-app-registry'; import type { connect as devtoolsConnect } from 'mongodb-data-service'; import React, { useContext, useRef } from 'react'; import { createLoggerLocator } from '@mongodb-js/compass-logging/provider'; @@ -76,7 +76,7 @@ const ConnectionsComponent: React.FunctionComponent<{ ); }; -const CompassConnectionsPlugin = registerHadronPlugin( +const CompassConnectionsPlugin = registerCompassPlugin( { name: 'CompassConnections', component: ConnectionsComponent, diff --git a/packages/compass-connections/src/provider.ts b/packages/compass-connections/src/provider.ts index e01a522615a..1e1a3226ab7 100644 --- a/packages/compass-connections/src/provider.ts +++ b/packages/compass-connections/src/provider.ts @@ -1,4 +1,4 @@ -import { createServiceLocator } from 'hadron-app-registry'; +import { createServiceLocator } from '@mongodb-js/compass-app-registry'; import { useConnectionInfo } from './connection-info-provider'; import type { DataService } from 'mongodb-data-service'; import { getDataServiceForConnection } from './stores/connections-store-redux'; diff --git a/packages/compass-connections/src/stores/connections-store-redux.ts b/packages/compass-connections/src/stores/connections-store-redux.ts index dcf83927a44..55eabbc396d 100644 --- a/packages/compass-connections/src/stores/connections-store-redux.ts +++ b/packages/compass-connections/src/stores/connections-store-redux.ts @@ -1,4 +1,4 @@ -import type AppRegistry from 'hadron-app-registry'; +import type AppRegistry from '@mongodb-js/compass-app-registry'; import type { Reducer, AnyAction, Action } from 'redux'; import { createStore, applyMiddleware } from 'redux'; import type { ThunkAction } from 'redux-thunk'; diff --git a/packages/compass-connections/src/stores/store-context.tsx b/packages/compass-connections/src/stores/store-context.tsx index 5619ac8fba4..0e107a0df3b 100644 --- a/packages/compass-connections/src/stores/store-context.tsx +++ b/packages/compass-connections/src/stores/store-context.tsx @@ -39,7 +39,7 @@ import { getConnectionTitle, type ConnectionInfo, } from '@mongodb-js/connection-info'; -import { createServiceLocator } from 'hadron-app-registry'; +import { createServiceLocator } from '@mongodb-js/compass-app-registry'; import { isEqual } from 'lodash'; type ConnectionsStore = ReturnType extends Store< diff --git a/packages/compass-context-menu/.depcheckrc b/packages/compass-context-menu/.depcheckrc new file mode 100644 index 00000000000..ab0ef21b740 --- /dev/null +++ b/packages/compass-context-menu/.depcheckrc @@ -0,0 +1,8 @@ +ignores: + - '@mongodb-js/prettier-config-compass' + - '@mongodb-js/tsconfig-compass' + - '@types/chai' + - '@types/sinon-chai' + - 'sinon' +ignore-patterns: + - 'dist' diff --git a/packages/compass-context-menu/.eslintignore b/packages/compass-context-menu/.eslintignore new file mode 100644 index 00000000000..85a8a75e68c --- /dev/null +++ b/packages/compass-context-menu/.eslintignore @@ -0,0 +1,2 @@ +.nyc-output +dist diff --git a/packages/compass-context-menu/.eslintrc.js b/packages/compass-context-menu/.eslintrc.js new file mode 100644 index 00000000000..9c3ab95632f --- /dev/null +++ b/packages/compass-context-menu/.eslintrc.js @@ -0,0 +1,9 @@ +'use strict'; +module.exports = { + root: true, + extends: ['@mongodb-js/eslint-config-compass'], + parserOptions: { + tsconfigRootDir: __dirname, + project: ['./tsconfig-lint.json'], + }, +}; diff --git a/packages/compass-context-menu/.mocharc.js b/packages/compass-context-menu/.mocharc.js new file mode 100644 index 00000000000..5a33f216327 --- /dev/null +++ b/packages/compass-context-menu/.mocharc.js @@ -0,0 +1,2 @@ +'use strict'; +module.exports = require('@mongodb-js/mocha-config-compass/react'); diff --git a/packages/compass-context-menu/package.json b/packages/compass-context-menu/package.json new file mode 100644 index 00000000000..67099115f92 --- /dev/null +++ b/packages/compass-context-menu/package.json @@ -0,0 +1,72 @@ +{ + "name": "@mongodb-js/compass-context-menu", + "author": { + "name": "MongoDB Inc", + "email": "compass@mongodb.com" + }, + "publishConfig": { + "access": "public" + }, + "bugs": { + "url": "https://jira.mongodb.org/projects/COMPASS/issues", + "email": "compass@mongodb.com" + }, + "homepage": "https://github.com/mongodb-js/compass", + "version": "0.0.1", + "repository": { + "type": "git", + "url": "https://github.com/mongodb-js/compass.git" + }, + "files": [ + "dist" + ], + "license": "SSPL", + "main": "dist/index.js", + "compass:main": "src/index.ts", + "exports": { + "import": "./dist/.esm-wrapper.mjs", + "require": "./dist/index.js" + }, + "compass:exports": { + ".": "./src/index.ts" + }, + "types": "./dist/index.d.ts", + "scripts": { + "bootstrap": "npm run compile", + "prepublishOnly": "npm run compile && compass-scripts check-exports-exist", + "compile": "tsc -p tsconfig.json && gen-esm-wrapper . ./dist/.esm-wrapper.mjs", + "typecheck": "tsc -p tsconfig-lint.json --noEmit", + "eslint": "eslint-compass", + "prettier": "prettier-compass", + "lint": "npm run eslint . && npm run prettier -- --check .", + "depcheck": "compass-scripts check-peer-deps && depcheck", + "check": "npm run typecheck && npm run lint && npm run depcheck", + "check-ci": "npm run check", + "test": "mocha", + "test-cov": "nyc --compact=false --produce-source-map=false -x \"**/*.spec.*\" --reporter=lcov --reporter=text --reporter=html npm run test", + "test-watch": "npm run test -- --watch", + "test-ci": "npm run test-cov", + "reformat": "npm run eslint . -- --fix && npm run prettier -- --write ." + }, + "dependencies": { + "react": "^17.0.2" + }, + "devDependencies": { + "@mongodb-js/eslint-config-compass": "^1.3.8", + "@mongodb-js/mocha-config-compass": "^1.6.8", + "@mongodb-js/prettier-config-compass": "^1.2.8", + "@mongodb-js/testing-library-compass": "^1.3.1", + "@mongodb-js/tsconfig-compass": "^1.2.8", + "@types/chai": "^4.2.21", + "@types/mocha": "^9.0.0", + "@types/react": "^17.0.5", + "@types/sinon-chai": "^3.2.5", + "chai": "^4.3.6", + "depcheck": "^1.4.1", + "gen-esm-wrapper": "^1.1.0", + "mocha": "^10.2.0", + "nyc": "^15.1.0", + "sinon": "^9.2.3", + "typescript": "^5.0.4" + } +} diff --git a/packages/compass-context-menu/src/context-menu-content.ts b/packages/compass-context-menu/src/context-menu-content.ts new file mode 100644 index 00000000000..c301983a679 --- /dev/null +++ b/packages/compass-context-menu/src/context-menu-content.ts @@ -0,0 +1,24 @@ +import type { ContextMenuItemGroup } from './types'; + +const CONTEXT_MENUS_SYMBOL = Symbol('context_menus'); + +export type EnhancedMouseEvent = MouseEvent & { + [CONTEXT_MENUS_SYMBOL]?: ContextMenuItemGroup[]; +}; + +export function getContextMenuContent( + event: EnhancedMouseEvent +): ContextMenuItemGroup[] { + return event[CONTEXT_MENUS_SYMBOL] ?? []; +} + +export function appendContextMenuContent( + event: EnhancedMouseEvent, + content: ContextMenuItemGroup +) { + // Initialize if not already patched + if (!event[CONTEXT_MENUS_SYMBOL]) { + event[CONTEXT_MENUS_SYMBOL] = []; + } + event[CONTEXT_MENUS_SYMBOL].push(content); +} diff --git a/packages/compass-context-menu/src/context-menu-provider.spec.tsx b/packages/compass-context-menu/src/context-menu-provider.spec.tsx new file mode 100644 index 00000000000..88d85c1fbcf --- /dev/null +++ b/packages/compass-context-menu/src/context-menu-provider.spec.tsx @@ -0,0 +1,51 @@ +import React from 'react'; +import { testingLibrary } from '@mongodb-js/testing-library-compass'; +import { expect } from 'chai'; +import { ContextMenuProvider } from './context-menu-provider'; +import type { ContextMenuWrapperProps } from './types'; + +// We need to import from testing-library-compass directly to avoid the extra wrapping. +const { render } = testingLibrary; + +describe('ContextMenuProvider', function () { + const TestMenu: React.FC = () => ( +
Test Menu
+ ); + + const TestComponent = () => ( +
Test Content
+ ); + + describe('when nested', function () { + it('uses parent provider and does not render duplicate menu wrapper', function () { + const { container } = render( + +
+ + + +
+
+ ); + + // Should only find one test-menu element (from the parent provider) + expect( + container.querySelectorAll('[data-testid="test-menu"]') + ).to.have.length(1); + // Should still render the content + expect(container.querySelector('[data-testid="test-content"]')).to.exist; + }); + }); + + describe('when not nested', function () { + it('renders without error', function () { + render( + + + + ); + + expect(document.querySelector('[data-testid="test-content"]')).to.exist; + }); + }); +}); diff --git a/packages/compass-context-menu/src/context-menu-provider.tsx b/packages/compass-context-menu/src/context-menu-provider.tsx new file mode 100644 index 00000000000..0c2134f7ec4 --- /dev/null +++ b/packages/compass-context-menu/src/context-menu-provider.tsx @@ -0,0 +1,98 @@ +import React, { + useCallback, + useEffect, + useState, + useMemo, + createContext, + useContext, +} from 'react'; +import type { ContextMenuContextType, ContextMenuState } from './types'; +import type { EnhancedMouseEvent } from './context-menu-content'; +import { getContextMenuContent } from './context-menu-content'; + +export const ContextMenuContext = createContext( + null +); + +export function ContextMenuProvider({ + children, + menuWrapper, +}: { + children: React.ReactNode; + menuWrapper: React.ComponentType<{ + menu: ContextMenuState & { close: () => void }; + }>; +}) { + // Check if there's already a parent context menu provider + const parentContext = useContext(ContextMenuContext); + + const [menu, setMenu] = useState({ + isOpen: false, + itemGroups: [], + position: { x: 0, y: 0 }, + }); + const close = useCallback(() => setMenu({ ...menu, isOpen: false }), [menu]); + + const handleClosingEvent = useCallback( + (event: Event) => { + if (!event.defaultPrevented) { + setMenu({ ...menu, isOpen: false }); + } + }, + [menu] + ); + + useEffect(() => { + // Don't set up event listeners if we have a parent context + if (parentContext) return; + + function handleContextMenu(event: MouseEvent) { + event.preventDefault(); + + const itemGroups = getContextMenuContent(event as EnhancedMouseEvent); + + if (itemGroups.length === 0) { + return; + } + + setMenu({ + isOpen: true, + itemGroups, + position: { + // TODO: Fix handling offset while scrolling + x: event.clientX, + y: event.clientY, + }, + }); + } + + document.addEventListener('contextmenu', handleContextMenu); + window.addEventListener('resize', handleClosingEvent); + + return () => { + document.removeEventListener('contextmenu', handleContextMenu); + window.removeEventListener('resize', handleClosingEvent); + }; + }, [handleClosingEvent, parentContext]); + + const value = useMemo( + () => ({ + close, + }), + [close] + ); + + // If we have a parent context, just render children without the wrapper + if (parentContext) { + return <>{children}; + } + + const Wrapper = menuWrapper ?? React.Fragment; + + return ( + + {children} + + + ); +} diff --git a/packages/compass-context-menu/src/index.ts b/packages/compass-context-menu/src/index.ts new file mode 100644 index 00000000000..7a0e27824fb --- /dev/null +++ b/packages/compass-context-menu/src/index.ts @@ -0,0 +1,10 @@ +export { useContextMenu } from './use-context-menu'; +export { + ContextMenuProvider, + ContextMenuContext, +} from './context-menu-provider'; +export type { + ContextMenuItem, + ContextMenuItemGroup, + ContextMenuWrapperProps, +} from './types'; diff --git a/packages/compass-context-menu/src/types.ts b/packages/compass-context-menu/src/types.ts new file mode 100644 index 00000000000..163abe56132 --- /dev/null +++ b/packages/compass-context-menu/src/types.ts @@ -0,0 +1,26 @@ +export interface ContextMenuItemGroup { + items: ContextMenuItem[]; + originListener: (event: MouseEvent) => void; +} + +export type ContextMenuState = { + isOpen: boolean; + itemGroups: ContextMenuItemGroup[]; + position: { + x: number; + y: number; + }; +}; + +export type ContextMenuWrapperProps = { + menu: ContextMenuState & { close: () => void }; +}; + +export type ContextMenuContextType = { + close(): void; +}; + +export type ContextMenuItem = { + label: string; + onAction: (event: React.KeyboardEvent | React.MouseEvent) => void; +}; diff --git a/packages/compass-context-menu/src/use-context-menu.spec.tsx b/packages/compass-context-menu/src/use-context-menu.spec.tsx new file mode 100644 index 00000000000..9459f924b05 --- /dev/null +++ b/packages/compass-context-menu/src/use-context-menu.spec.tsx @@ -0,0 +1,267 @@ +import React from 'react'; +import { + screen, + userEvent, + testingLibrary, +} from '@mongodb-js/testing-library-compass'; +import { expect } from 'chai'; +import sinon from 'sinon'; +import { useContextMenu } from './use-context-menu'; +import { ContextMenuProvider } from './context-menu-provider'; +import type { ContextMenuItem, ContextMenuWrapperProps } from './types'; + +// We need to import from testing-library-compass directly to avoid the extra wrapping. +const { render } = testingLibrary; + +describe('useContextMenu', function () { + const TestMenu: React.FC = ({ menu }) => ( +
+ {menu.itemGroups.flatMap((group, groupIdx) => + group.items.map((item, idx) => ( +
item.onAction?.(event)} + onKeyDown={(event) => { + if (event.key === 'Enter') { + item.onAction?.(event); + } + }} + > + {item.label} +
+ )) + )} +
+ ); + + const TestComponent = ({ + onRegister, + onAction, + }: { + onRegister?: (ref: any) => void; + onAction?: (id: number) => void; + }) => { + const contextMenu = useContextMenu(); + const items: ContextMenuItem[] = [ + { + label: 'Test Item', + onAction: () => onAction?.(1), + }, + ]; + const ref = contextMenu.registerItems(items); + + React.useEffect(() => { + onRegister?.(ref); + }, [ref, onRegister]); + + return ( +
+ Test Component +
+ ); + }; + + const ParentComponent = ({ + onAction, + children, + }: { + onAction?: (id: number) => void; + children?: React.ReactNode; + }) => { + const contextMenu = useContextMenu(); + const parentItems: ContextMenuItem[] = [ + { + label: 'Parent Item 1', + onAction: () => onAction?.(1), + }, + { + label: 'Parent Item 2', + onAction: () => onAction?.(2), + }, + ]; + const ref = contextMenu.registerItems(parentItems); + + return ( +
+
Parent Component
+ {children} +
+ ); + }; + + const ChildComponent = ({ + onAction, + }: { + onAction?: (id: number) => void; + }) => { + const contextMenu = useContextMenu(); + const childItems: ContextMenuItem[] = [ + { + label: 'Child Item 1', + onAction: () => onAction?.(1), + }, + { + label: 'Child Item 2', + onAction: () => onAction?.(2), + }, + ]; + const ref = contextMenu.registerItems(childItems); + + return ( +
+ Child Component +
+ ); + }; + + describe('when used outside provider', function () { + it('throws an error', function () { + expect(() => { + render(); + }).to.throw('useContextMenu called outside of the provider'); + }); + }); + + describe('with a valid provider', function () { + beforeEach(() => { + // Create the container for the context menu portal + const container = document.createElement('div'); + container.id = 'context-menu-container'; + document.body.appendChild(container); + }); + + afterEach(() => { + // Clean up the container + const container = document.getElementById('context-menu-container'); + if (container) { + document.body.removeChild(container); + } + }); + + it('renders without error', function () { + render( + + + + ); + + expect(screen.getByTestId('test-trigger')).to.exist; + }); + + it('registers context menu event listener', function () { + const onRegister = sinon.spy(); + + render( + + + + ); + + expect(onRegister).to.have.been.calledOnce; + expect(onRegister.firstCall.args[0]).to.be.a('function'); + }); + + it('shows context menu on right click', function () { + render( + + + + ); + + const trigger = screen.getByTestId('test-trigger'); + userEvent.click(trigger, { button: 2 }); + + // The menu should be rendered in the portal + expect(screen.getByTestId('menu-item-Test Item')).to.exist; + }); + + describe('with nested context menus', function () { + it('shows only parent items when right clicking parent area', function () { + render( + + + + ); + + const parentTrigger = screen.getByTestId('parent-trigger'); + userEvent.click(parentTrigger, { button: 2 }); + + // Should show parent items + expect(screen.getByTestId('menu-item-Parent Item 1')).to.exist; + expect(screen.getByTestId('menu-item-Parent Item 2')).to.exist; + + // Should not show child items + expect(() => screen.getByTestId('menu-item-Child Item 1')).to.throw; + expect(() => screen.getByTestId('menu-item-Child Item 2')).to.throw; + }); + + it('shows both parent and child items when right clicking child area', function () { + render( + + + + + + ); + + const childTrigger = screen.getByTestId('child-trigger'); + userEvent.click(childTrigger, { button: 2 }); + + // Should show both parent and child items + expect(screen.getByTestId('menu-item-Parent Item 1')).to.exist; + expect(screen.getByTestId('menu-item-Parent Item 2')).to.exist; + expect(screen.getByTestId('menu-item-Child Item 1')).to.exist; + expect(screen.getByTestId('menu-item-Child Item 2')).to.exist; + }); + + it('triggers only the child action when clicking child menu item', function () { + const parentOnAction = sinon.spy(); + const childOnAction = sinon.spy(); + + render( + + + + + + ); + + const childTrigger = screen.getByTestId('child-trigger'); + userEvent.click(childTrigger, { button: 2 }); + + const childItem1 = screen.getByTestId('menu-item-Child Item 1'); + userEvent.click(childItem1); + + expect(childOnAction).to.have.been.calledOnceWithExactly(1); + expect(parentOnAction).to.not.have.been.called; + expect(() => screen.getByTestId('test-menu')).to.throw; + }); + + it('triggers only the parent action when clicking a parent menu item from child context', function () { + const parentOnAction = sinon.spy(); + const childOnAction = sinon.spy(); + + render( + + + + + + ); + + const childTrigger = screen.getByTestId('child-trigger'); + userEvent.click(childTrigger, { button: 2 }); + + const parentItem1 = screen.getByTestId('menu-item-Parent Item 1'); + userEvent.click(parentItem1); + + expect(parentOnAction).to.have.been.calledOnceWithExactly(1); + expect(childOnAction).to.not.have.been.called; + expect(() => screen.getByTestId('test-menu')).to.throw; + }); + }); + }); +}); diff --git a/packages/compass-context-menu/src/use-context-menu.tsx b/packages/compass-context-menu/src/use-context-menu.tsx new file mode 100644 index 00000000000..a0b874b656c --- /dev/null +++ b/packages/compass-context-menu/src/use-context-menu.tsx @@ -0,0 +1,61 @@ +import type { RefCallback } from 'react'; +import { useContext, useMemo, useRef } from 'react'; +import { ContextMenuContext } from './context-menu-provider'; +import { appendContextMenuContent } from './context-menu-content'; +import type { ContextMenuItem } from './types'; + +export type ContextMenuMethods = { + /** + * Close the context menu. + */ + close: () => void; + /** + * Register the menu items for the context menu. + * @returns a callback ref to be passed onto the element responsible for triggering the menu. + */ + registerItems: (items: T[]) => RefCallback; +}; + +export function useContextMenu< + T extends ContextMenuItem = ContextMenuItem +>(): ContextMenuMethods { + const context = useContext(ContextMenuContext); + const previous = useRef void]>( + null + ); + + return useMemo(() => { + if (!context) { + throw new Error('useContextMenu called outside of the provider'); + } + + return { + close: context.close.bind(context), + /** + * @returns a callback ref, passed onto the element responsible for triggering the menu. + */ + registerItems(items: ContextMenuItem[]) { + function listener(event: MouseEvent): void { + appendContextMenuContent(event, { + items, + originListener: listener, + }); + } + + return (trigger: HTMLElement | null) => { + if (previous.current) { + const [previousTrigger, previousListener] = previous.current; + previousTrigger.removeEventListener( + 'contextmenu', + previousListener + ); + } + if (trigger) { + trigger.addEventListener('contextmenu', listener); + previous.current = [trigger, listener]; + } + }; + }, + }; + }, [context]); +} diff --git a/packages/compass-context-menu/tsconfig-lint.json b/packages/compass-context-menu/tsconfig-lint.json new file mode 100644 index 00000000000..6bdef84f322 --- /dev/null +++ b/packages/compass-context-menu/tsconfig-lint.json @@ -0,0 +1,5 @@ +{ + "extends": "./tsconfig.json", + "include": ["**/*"], + "exclude": ["node_modules", "dist"] +} diff --git a/packages/compass-context-menu/tsconfig.json b/packages/compass-context-menu/tsconfig.json new file mode 100644 index 00000000000..79bc84584ce --- /dev/null +++ b/packages/compass-context-menu/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "@mongodb-js/tsconfig-compass/tsconfig.react.json", + "compilerOptions": { + "outDir": "dist" + }, + "include": ["src/**/*"], + "exclude": ["./src/**/*.spec.*"] +} diff --git a/packages/compass-crud/README.md b/packages/compass-crud/README.md index 7322f081e3d..9cba8e59498 100644 --- a/packages/compass-crud/README.md +++ b/packages/compass-crud/README.md @@ -28,7 +28,7 @@ Compass. | `CRUD.LoadMoreDocumentsStore` | Triggers when more documents are fetched via scrolling. | Components from this plugin can be interracted with using -[hadron-app][hadron-app] and [hadron-app-registry][hadron-app-registry]. Here are +[hadron-app][hadron-app] and [compass-app-registry][compass-app-registry]. Here are a few examples of working with `compass-crud`'s `Action` and `Roles`. Render an editable document in a React component. @@ -89,7 +89,7 @@ CrudActions.insertDocument((doc) => { ### App Registry Events Emmitted Various actions within this plugin will emit events for other parts of the -application can be listened to via [hadron-app-registry][hadron-app-registry]. +application can be listened to via [compass-app-registry][compass-app-registry]. `Local` events are scoped to a `Tab`. `Global` events are scoped to the whole Compass application. @@ -163,11 +163,11 @@ npm install -S @mongodb-js/compass-crud ## See Also - [compass][compass] -- [hadron-app-registry][hadron-app-registry] +- [compass-app-registry][compass-app-registry] - [hadron-app][hadron-app] [npm_img]: https://img.shields.io/npm/v/@mongodb-js/compass-crud.svg?style=flat-square [npm_url]: https://www.npmjs.org/package/@mongodb-js/compass-crud -[hadron-app]: https://github.com/mongodb-js/compass/packages/hadron-app -[hadron-app-registry]: https://github.com/mongodb-js/compass/packages/hadron-app-registry -[compass]: https://github.com/mongodb-js/compass/packages/compass +[hadron-app]: https://github.com/mongodb-js/compass/tree/main/packages/hadron-app +[compass-app-registry]: https://github.com/mongodb-js/compass/tree/main/packages/compass-app-registry +[compass]: https://github.com/mongodb-js/compass/tree/main/packages/compass diff --git a/packages/compass-crud/package.json b/packages/compass-crud/package.json index 68f275384b2..d9f0e14c983 100644 --- a/packages/compass-crud/package.json +++ b/packages/compass-crud/package.json @@ -6,7 +6,7 @@ "email": "compass@mongodb.com" }, "private": true, - "version": "13.60.0", + "version": "13.61.0", "repository": { "type": "git", "url": "https://github.com/mongodb-js/compass.git" @@ -63,32 +63,32 @@ "electron-mocha": "^12.2.0", "enzyme": "^3.11.0", "mocha": "^10.2.0", - "mongodb-instance-model": "^12.32.2", + "mongodb-instance-model": "^12.33.0", "nyc": "^15.1.0", "react-dom": "^17.0.2", - "sinon": "^8.1.1", + "sinon": "^17.0.1", "typescript": "^5.0.4" }, "dependencies": { - "@mongodb-js/compass-app-stores": "^7.46.0", - "@mongodb-js/compass-collection": "^4.59.0", - "@mongodb-js/compass-components": "^1.38.1", - "@mongodb-js/compass-connections": "^1.60.0", - "@mongodb-js/compass-editor": "^0.40.2", - "@mongodb-js/compass-field-store": "^9.35.0", + "@mongodb-js/compass-app-stores": "^7.47.0", + "@mongodb-js/compass-collection": "^4.60.0", + "@mongodb-js/compass-components": "^1.39.0", + "@mongodb-js/compass-connections": "^1.61.0", + "@mongodb-js/compass-editor": "^0.41.0", + "@mongodb-js/compass-field-store": "^9.36.0", "@mongodb-js/compass-logging": "^1.7.2", - "@mongodb-js/compass-query-bar": "^8.61.0", + "@mongodb-js/compass-query-bar": "^8.62.0", "@mongodb-js/compass-telemetry": "^1.10.0", - "@mongodb-js/compass-workspaces": "^0.41.0", + "@mongodb-js/compass-workspaces": "^0.42.0", "@mongodb-js/explain-plan-helper": "^1.4.10", - "@mongodb-js/my-queries-storage": "^0.27.3", + "@mongodb-js/my-queries-storage": "^0.28.0", "@mongodb-js/reflux-state-mixin": "^1.2.10", "@mongodb-js/shell-bson-parser": "^1.2.0", "ag-grid-community": "^20.2.0", "ag-grid-react": "^20.2.0", "bson": "^6.10.3", - "compass-preferences-model": "^2.40.2", - "hadron-app-registry": "^9.4.11", + "compass-preferences-model": "^2.41.0", + "@mongodb-js/compass-app-registry": "^9.4.11", "hadron-document": "^8.8.12", "hadron-type-checker": "^7.4.10", "jsondiffpatch": "^0.5.0", diff --git a/packages/compass-crud/src/components/document-json-view-item.spec.tsx b/packages/compass-crud/src/components/document-json-view-item.spec.tsx new file mode 100644 index 00000000000..767ab08350b --- /dev/null +++ b/packages/compass-crud/src/components/document-json-view-item.spec.tsx @@ -0,0 +1,107 @@ +import React from 'react'; +import { render, screen, userEvent } from '@mongodb-js/testing-library-compass'; +import { expect } from 'chai'; +import sinon from 'sinon'; +import HadronDocument from 'hadron-document'; +import { DocumentJsonViewItem } from './document-json-view-item'; + +describe('DocumentJsonViewItem', function () { + let doc: HadronDocument; + let copyToClipboardStub: sinon.SinonStub; + let openInsertDocumentDialogStub: sinon.SinonStub; + + beforeEach(function () { + doc = new HadronDocument({ + _id: 1, + name: 'test', + url: 'https://mongodb.com', + nested: { field: 'value' }, + }); + + copyToClipboardStub = sinon.stub(); + openInsertDocumentDialogStub = sinon.stub(); + }); + + afterEach(function () { + sinon.restore(); + }); + + it('renders the JSON editor component', function () { + render( + + ); + + // Should render without error + expect(document.querySelector('[data-testid="editable-json"]')).to.exist; + }); + + it('renders context menu when right-clicked', function () { + const { container } = render( + + ); + + const element = container.firstChild as HTMLElement; + + // Right-click to open context menu + userEvent.click(element, { button: 2 }); + + // Should show context menu with expected items + expect(screen.getByText('Copy document')).to.exist; + expect(screen.getByText('Clone document...')).to.exist; + expect(screen.getByText('Delete document')).to.exist; + }); + + it('renders scroll trigger when docIndex is 0', function () { + const scrollTriggerRef = React.createRef(); + + render( + + ); + + expect(scrollTriggerRef.current).to.exist; + }); + + it('does not render scroll trigger when docIndex is not 0', function () { + const scrollTriggerRef = React.createRef(); + + render( + + ); + + expect(scrollTriggerRef.current).to.be.null; + }); +}); diff --git a/packages/compass-crud/src/components/document-json-view-item.tsx b/packages/compass-crud/src/components/document-json-view-item.tsx new file mode 100644 index 00000000000..003f82ab73a --- /dev/null +++ b/packages/compass-crud/src/components/document-json-view-item.tsx @@ -0,0 +1,72 @@ +import React from 'react'; +import type HadronDocument from 'hadron-document'; +import { css, KeylineCard } from '@mongodb-js/compass-components'; + +import JSONEditor, { type JSONEditorProps } from './json-editor'; +import { useDocumentItemContextMenu } from './use-document-item-context-menu'; + +const keylineCardStyles = css({ + overflow: 'hidden', + position: 'relative', +}); + +export type DocumentJsonViewItemProps = { + doc: HadronDocument; + docRef: React.Ref; + docIndex: number; + namespace: string; + isEditable: boolean; + isTimeSeries?: boolean; + scrollTriggerRef?: React.Ref; +} & Pick< + JSONEditorProps, + | 'copyToClipboard' + | 'removeDocument' + | 'replaceDocument' + | 'updateDocument' + | 'openInsertDocumentDialog' +>; + +const DocumentJsonViewItem: React.FC = ({ + doc, + docRef, + docIndex, + namespace, + isEditable, + isTimeSeries, + scrollTriggerRef, + copyToClipboard, + removeDocument, + replaceDocument, + updateDocument, + openInsertDocumentDialog, +}) => { + const ref = useDocumentItemContextMenu({ + doc, + isEditable, + copyToClipboard, + openInsertDocumentDialog, + }); + + return ( +
+ + {scrollTriggerRef && docIndex === 0 &&
} + + +
+ ); +}; + +export { DocumentJsonViewItem }; diff --git a/packages/compass-crud/src/components/document-list-view-item.spec.tsx b/packages/compass-crud/src/components/document-list-view-item.spec.tsx new file mode 100644 index 00000000000..5ad9ffa8798 --- /dev/null +++ b/packages/compass-crud/src/components/document-list-view-item.spec.tsx @@ -0,0 +1,104 @@ +import React from 'react'; +import { render, screen, userEvent } from '@mongodb-js/testing-library-compass'; +import { expect } from 'chai'; +import sinon from 'sinon'; +import HadronDocument from 'hadron-document'; +import { DocumentListViewItem } from './document-list-view-item'; + +describe('DocumentListViewItem', function () { + let doc: HadronDocument; + let copyToClipboardStub: sinon.SinonStub; + let openInsertDocumentDialogStub: sinon.SinonStub; + + beforeEach(function () { + doc = new HadronDocument({ + _id: 1, + name: 'test', + url: 'https://mongodb.com', + nested: { field: 'value' }, + }); + + copyToClipboardStub = sinon.stub(); + openInsertDocumentDialogStub = sinon.stub(); + }); + + afterEach(function () { + sinon.restore(); + }); + + it('renders the document component', function () { + render( + + ); + + // Should render without error + expect(document.querySelector('[data-testid="editable-document"]')).to + .exist; + }); + + it('renders context menu when right-clicked', function () { + const { container } = render( + + ); + + const element = container.firstChild as HTMLElement; + + // Right-click to open context menu + userEvent.click(element, { button: 2 }); + + // Should show context menu with expected items + expect(screen.getByText('Copy document')).to.exist; + expect(screen.getByText('Clone document...')).to.exist; + expect(screen.getByText('Delete document')).to.exist; + }); + + it('renders scroll trigger when docIndex is 0', function () { + const scrollTriggerRef = React.createRef(); + + render( + + ); + + expect(scrollTriggerRef.current).to.exist; + }); + + it('does not render scroll trigger when docIndex is not 0', function () { + const scrollTriggerRef = React.createRef(); + + render( + + ); + + expect(scrollTriggerRef.current).to.be.null; + }); +}); diff --git a/packages/compass-crud/src/components/document-list-view-item.tsx b/packages/compass-crud/src/components/document-list-view-item.tsx new file mode 100644 index 00000000000..288ce2b8621 --- /dev/null +++ b/packages/compass-crud/src/components/document-list-view-item.tsx @@ -0,0 +1,63 @@ +import React from 'react'; +import type HadronDocument from 'hadron-document'; +import { KeylineCard } from '@mongodb-js/compass-components'; +import Document, { type DocumentProps } from './document'; +import { useDocumentItemContextMenu } from './use-document-item-context-menu'; + +export type DocumentListViewItemProps = { + doc: HadronDocument; + docRef: React.Ref; + docIndex: number; + isEditable: boolean; + isTimeSeries?: boolean; + scrollTriggerRef?: React.Ref; +} & Pick< + DocumentProps, + | 'copyToClipboard' + | 'removeDocument' + | 'replaceDocument' + | 'updateDocument' + | 'openInsertDocumentDialog' +>; + +const DocumentListViewItem: React.FC = ({ + doc, + docRef, + docIndex, + isEditable, + isTimeSeries, + scrollTriggerRef, + copyToClipboard, + removeDocument, + replaceDocument, + updateDocument, + openInsertDocumentDialog, +}) => { + const ref = useDocumentItemContextMenu({ + doc, + isEditable, + copyToClipboard, + openInsertDocumentDialog, + }); + + return ( +
+ + {scrollTriggerRef && docIndex === 0 &&
} + + +
+ ); +}; + +export { DocumentListViewItem }; diff --git a/packages/compass-crud/src/components/document-list-view.spec.tsx b/packages/compass-crud/src/components/document-list-view.spec.tsx index 536f48e66c2..5938ac2ab06 100644 --- a/packages/compass-crud/src/components/document-list-view.spec.tsx +++ b/packages/compass-crud/src/components/document-list-view.spec.tsx @@ -1,28 +1,32 @@ import React from 'react'; import { mount } from 'enzyme'; +import type { ReactWrapper } from 'enzyme'; import HadronDocument from 'hadron-document'; import { expect } from 'chai'; -import sinon from 'sinon'; import DocumentListView from './document-list-view'; +import { CompassComponentsProvider } from '@mongodb-js/compass-components'; describe('', function () { describe('#render', function () { context('when the documents have objects for ids', function () { const docs = [{ _id: { name: 'test-1' } }, { _id: { name: 'test-2' } }]; const hadronDocs = docs.map((doc) => new HadronDocument(doc)); - const component = mount( - - ); + let component: ReactWrapper; + beforeEach(function () { + component = mount( + , + { wrappingComponent: CompassComponentsProvider } + ); + }); + + afterEach(function () { + component?.unmount(); + }); it('renders all the documents', function () { const wrapper = component.find('[data-testid="readonly-document"]'); diff --git a/packages/compass-crud/src/components/editable-document.spec.tsx b/packages/compass-crud/src/components/editable-document.spec.tsx index 19667f66d2e..25643935ce4 100644 --- a/packages/compass-crud/src/components/editable-document.spec.tsx +++ b/packages/compass-crud/src/components/editable-document.spec.tsx @@ -6,6 +6,7 @@ import { expect } from 'chai'; import sinon from 'sinon'; import EditableDocument from './editable-document'; +import { ContextMenuProvider } from '@mongodb-js/compass-context-menu'; describe('', function () { describe('#render', function () { @@ -22,7 +23,8 @@ describe('', function () { updateDocument={sinon.spy(action)} copyToClipboard={sinon.spy(action)} openInsertDocumentDialog={sinon.spy(action)} - /> + />, + { wrappingComponent: ContextMenuProvider } ); }); diff --git a/packages/compass-crud/src/components/table-view/cell-renderer.tsx b/packages/compass-crud/src/components/table-view/cell-renderer.tsx index 86f7051852d..0ae6e755e7d 100644 --- a/packages/compass-crud/src/components/table-view/cell-renderer.tsx +++ b/packages/compass-crud/src/components/table-view/cell-renderer.tsx @@ -1,16 +1,21 @@ -import React from 'react'; -import PropTypes from 'prop-types'; +import React, { + useMemo, + useCallback, + useEffect, + useReducer, + useState, +} from 'react'; import { BSONValue, css, Icon, IconButton, - LeafyGreenProvider, spacing, withDarkMode, + useFieldContextMenu, + LeafyGreenProvider, } from '@mongodb-js/compass-components'; -import { Element } from 'hadron-document'; -import type { ICellRendererReactComp } from 'ag-grid-react'; +import { type Document, Element } from 'hadron-document'; import type { ICellRendererParams } from 'ag-grid-community'; import type { GridActions, TableHeaderType } from '../../stores/grid-store'; import type { CrudActions } from '../../stores/crud-store'; @@ -61,6 +66,11 @@ const UNEDITABLE = 'is-uneditable'; */ const INVALID = 'is-invalid'; +/** + * The valid constant. + */ +const VALID = 'valid'; + /** * The deleted constant. */ @@ -81,182 +91,116 @@ const decrypdedIconStyles = css({ display: 'flex', }); -export type CellRendererProps = Omit & { - context: GridContext; - parentType: TableHeaderType; - elementAdded: GridActions['elementAdded']; - elementRemoved: GridActions['elementRemoved']; - elementTypeChanged: GridActions['elementTypeChanged']; - drillDown: CrudActions['drillDown']; - tz: string; - darkMode?: boolean; -}; - -/** - * The custom cell renderer that renders a cell in the table view. - */ -class CellRenderer - extends React.Component - implements ICellRendererReactComp -{ - element: Element; - isEmpty: boolean; - isDeleted: boolean; - editable: boolean; - - constructor(props: CellRendererProps) { - super(props); - - this.isEmpty = props.value === undefined || props.value === null; - this.isDeleted = false; - this.element = props.value; +interface CellContentProps { + element: Element | undefined | null; + fieldName: string; + cellState: + | typeof UNEDITABLE + | typeof EMPTY + | typeof INVALID + | typeof DELETED + | typeof ADDED + | typeof EDITED + | typeof VALID; + onUndo: (event: React.MouseEvent) => void; + onExpand: (event: React.MouseEvent) => void; +} - /* Can't get the editable() function from here, so have to reevaluate */ - this.editable = true; - if (props.context.path.length > 0 && props.column.getColId() !== '$_id') { - const parent = props.node.data.hadronDocument.getChild( - props.context.path - ); - if ( - !parent || - (props.parentType && parent.currentType !== props.parentType) - ) { - this.editable = false; - } else if (parent.currentType === 'Array') { - let maxKey = 0; - if (parent.elements.lastElement) { - maxKey = +parent.elements.lastElement.currentKey + 1; - } - if (+props.column.getColId() > maxKey) { - this.editable = false; - } - } +const CellContent: React.FC = ({ + element, + cellState, + onUndo, + onExpand, + fieldName, +}) => { + const [, forceUpdate] = useReducer((x: number) => x + 1, 0); + const isEmpty = element === undefined || element === null; + const handleElementEvent = useCallback(() => { + forceUpdate(); + }, []); + + // Context menu functionality + const cellContextMenuRef = useFieldContextMenu({ + element, + fieldName, + }); + + // Subscribe to element events + useEffect(() => { + if (!isEmpty && element) { + element.on(Element.Events.Added, handleElementEvent); + element.on(Element.Events.Converted, handleElementEvent); + element.on(Element.Events.Edited, handleElementEvent); + element.on(Element.Events.Reverted, handleElementEvent); + + return () => { + element.removeListener(Element.Events.Added, handleElementEvent); + element.removeListener(Element.Events.Converted, handleElementEvent); + element.removeListener(Element.Events.Edited, handleElementEvent); + element.removeListener(Element.Events.Reverted, handleElementEvent); + }; } - } + }, [isEmpty, element, handleElementEvent]); - componentDidMount() { - if (!this.isEmpty) { - this.subscribeElementEvents(); + const elementLength = useMemo((): number | undefined => { + if (!element) { + return undefined; } - } - componentWillUnmount() { - if (!this.isEmpty) { - this.unsubscribeElementEvents(); + if (element.currentType === 'Object') { + return Object.keys(element.generateObject() as object).length; } - } - - subscribeElementEvents() { - this.element.on(Element.Events.Added, this.handleElementEvent); - this.element.on(Element.Events.Converted, this.handleElementEvent); - this.element.on(Element.Events.Edited, this.handleElementEvent); - this.element.on(Element.Events.Reverted, this.handleElementEvent); - } - - unsubscribeElementEvents() { - this.element.removeListener(Element.Events.Added, this.handleElementEvent); - this.element.removeListener( - Element.Events.Converted, - this.handleElementEvent - ); - this.element.removeListener(Element.Events.Edited, this.handleElementEvent); - this.element.removeListener( - Element.Events.Reverted, - this.handleElementEvent - ); - } - - handleElementEvent = () => { - this.forceUpdate(); - }; - - handleUndo = (event: React.MouseEvent) => { - event.stopPropagation(); - const oid = this.props.node.data.hadronDocument.getStringId(); - if (this.element.isAdded()) { - this.isDeleted = true; - const isArray = - !this.element.parent?.isRoot() && - this.element.parent?.currentType === 'Array'; - this.props.elementRemoved(String(this.element.currentKey), oid, isArray); - } else if (this.element.isRemoved()) { - this.props.elementAdded( - String(this.element.currentKey), - this.element.currentType, - oid - ); - } else { - this.props.elementTypeChanged( - String(this.element.currentKey), - this.element.type, - oid - ); + if (element.currentType === 'Array' && element.elements) { + return element.elements.size; } - this.element.revert(); - }; + }, [element]); - handleDrillDown(event: React.MouseEvent) { - event.stopPropagation(); - this.props.drillDown(this.props.node.data.hadronDocument, this.element); - } - - handleClicked() { - if (this.props.node.data.state === 'editing') { - this.props.api.startEditingCell({ - rowIndex: this.props.node.rowIndex, - colKey: this.props.column.getColId(), - }); + const renderContent = useMemo(() => { + if (cellState === EMPTY || !element) { + return 'No field'; } - } - refresh() { - return true; - } - - renderInvalidCell() { - let valueClass = `${VALUE_CLASS}-is-${this.element.currentType.toLowerCase()}`; - valueClass = `${valueClass} ${INVALID_VALUE}`; + if (cellState === UNEDITABLE) { + return ''; + } - /* Return internal div because invalid cells should only hightlight text? */ + if (cellState === DELETED) { + return 'Deleted field'; + } - return
{this.element.currentValue}
; - } + if (cellState === INVALID) { + let valueClass = `${VALUE_CLASS}-is-${element.currentType.toLowerCase()}`; + valueClass = `${valueClass} ${INVALID_VALUE}`; - getLength(): number | undefined { - if (this.element.currentType === 'Object') { - return Object.keys(this.element.generateObject() as object).length; - } - if (this.element.currentType === 'Array') { - return this.element.elements!.size; + return
{element.currentValue}
; } - } - renderValidCell() { let className = VALUE_BASE; - let element: string | JSX.Element = ''; - if (this.element.isAdded()) { - className = `${className} ${VALUE_BASE}-${ADDED}`; - } else if (this.element.isEdited()) { - className = `${className} ${VALUE_BASE}-${EDITED}`; + let elementContent: string | JSX.Element = ''; + if (cellState === ADDED || cellState === EDITED) { + className = `${className} ${VALUE_BASE}-${cellState}`; } - if (this.element.currentType === 'Object') { - element = `{} ${this.getLength() as number} fields`; - } else if (this.element.currentType === 'Array') { - element = `[] ${this.getLength() as number} elements`; + const isArrayOrObject = + element.currentType === 'Array' || element.currentType === 'Object'; + + if (elementLength !== undefined && isArrayOrObject) { + if (element.currentType === 'Object') { + elementContent = `{} ${elementLength} fields`; + } else if (element.currentType === 'Array') { + elementContent = `[] ${elementLength} elements`; + } } else { - element = ( - + elementContent = ( + //@ts-expect-error Types for this are currently not consistent + ); } return (
-
- {this.props.value.decrypted && ( +
+ {element.decrypted && ( )} - {element} + {elementContent}
); - } - - renderUndo(canUndo: boolean, canExpand: boolean) { - let undoButtonClass = `${BUTTON_CLASS} ${BUTTON_CLASS}-undo`; - if (canUndo && canExpand) { - undoButtonClass = `${undoButtonClass} ${BUTTON_CLASS}-left`; - } + }, [element, elementLength, cellState, cellContextMenuRef]); + + const canUndo = + cellState === ADDED || + cellState === EDITED || + cellState === INVALID || + cellState === DELETED; + + const canExpand = + (cellState === VALID || cellState === ADDED || cellState === EDITED) && + (element?.currentType === 'Object' || element?.currentType === 'Array'); + + return ( + <> + {canUndo && } + {canExpand && } + {renderContent} + + ); +}; - if (!canUndo) { - return null; - } - return ( - - - - ); - } +export type CellRendererProps = Omit & { + context: GridContext; + parentType: TableHeaderType; + elementAdded: GridActions['elementAdded']; + elementRemoved: GridActions['elementRemoved']; + elementTypeChanged: GridActions['elementTypeChanged']; + drillDown: CrudActions['drillDown']; + tz: string; + darkMode?: boolean; +}; - renderExpand(canExpand: boolean) { - if (!canExpand) { - return null; +/** + * The custom cell renderer that renders a cell in the table view. + */ +const CellRenderer: React.FC = ({ + value, + context, + column, + node, + parentType, + elementAdded, + elementRemoved, + elementTypeChanged, + drillDown, + api, + darkMode, +}) => { + const element = value as Element | undefined | null; + + const [isDeleted, setIsDeleted] = useState(false); + + const isEditable = useMemo(() => { + /* Can't get the editable() function from here, so have to reevaluate */ + let editable = true; + if (context.path.length > 0 && column.getColId() !== '$_id') { + const parent = node.data.hadronDocument.getChild(context.path); + if (!parent || (parentType && parent.currentType !== parentType)) { + editable = false; + } else if (parent.currentType === 'Array') { + let maxKey = 0; + if (parent.elements.lastElement) { + maxKey = +parent.elements.lastElement.currentKey + 1; + } + if (+column.getColId() > maxKey) { + editable = false; + } + } } - return ( - - - - - - ); + return editable; + }, [context.path, column, node.data.hadronDocument, parentType]); + + // Determine cell state + let cellState: + | typeof UNEDITABLE + | typeof EMPTY + | typeof INVALID + | typeof DELETED + | typeof ADDED + | typeof EDITED + | typeof VALID; + + if (!isEditable) { + cellState = UNEDITABLE; + } else if (!element || isDeleted) { + cellState = EMPTY; + } else if (!element.isCurrentTypeValid()) { + cellState = INVALID; + } else if (element.isRemoved()) { + cellState = DELETED; + } else if (element.isAdded()) { + cellState = ADDED; + } else if (element.isModified()) { + cellState = EDITED; + } else { + cellState = VALID; } - render() { - let element; - let className = BEM_BASE; - let canUndo = false; - let canExpand = false; - - if (!this.editable) { - element = ''; - className = `${className}-${UNEDITABLE}`; - } else if (this.isEmpty || this.isDeleted) { - element = 'No field'; - className = `${className}-${EMPTY}`; - } else if (!this.element.isCurrentTypeValid()) { - element = this.renderInvalidCell(); - className = `${className}-${INVALID}`; - canUndo = true; - } else if (this.element.isRemoved()) { - element = 'Deleted field'; - className = `${className}-${DELETED}`; - canUndo = true; - } else { - element = this.renderValidCell(); - if (this.element.isAdded()) { - className = `${className}-${ADDED}`; - canUndo = true; - } else if (this.element.isModified()) { - className = `${className}-${EDITED}`; - canUndo = true; + const handleUndo = useCallback( + (event: React.MouseEvent) => { + event.stopPropagation(); + if (!element) { + return; } - canExpand = - this.element.currentType === 'Object' || - this.element.currentType === 'Array'; + const oid: string = node.data.hadronDocument.getStringId(); + if (cellState === ADDED) { + setIsDeleted(true); + const isArray = + !element.parent?.isRoot() && element.parent?.currentType === 'Array'; + elementRemoved(String(element.currentKey), oid, isArray); + } else if (cellState === DELETED) { + elementAdded(String(element.currentKey), element.currentType, oid); + } else { + elementTypeChanged(String(element.currentKey), element.type, oid); + } + element.revert(); + }, + [ + element, + node.data.hadronDocument, + cellState, + elementRemoved, + elementAdded, + elementTypeChanged, + ] + ); + + const handleDrillDown = useCallback( + (event: React.MouseEvent) => { + event.stopPropagation(); + if (!element) { + return; + } + drillDown(node.data.hadronDocument as Document, element); + }, + [drillDown, node.data.hadronDocument, element] + ); + + const handleClicked = useCallback(() => { + if (node.data.state === 'editing') { + api.startEditingCell({ + rowIndex: node.rowIndex, + colKey: column.getColId(), + }); } + }, [node, api, column]); - return ( - // `ag-grid` renders this component outside of the context chain - // so we re-supply the dark mode theme here. - + return ( + // `ag-grid` renders this component outside of the context chain + // so we re-supply the dark mode theme here. + +
{/* eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/interactive-supports-focus*/}
- {this.renderUndo(canUndo, canExpand)} - {this.renderExpand(canExpand)} - {element} +
- - ); +
+
+ ); +}; + +export default withDarkMode(CellRenderer); + +interface CellUndoButtonProps { + alignLeft: boolean; + onClick: (event: React.MouseEvent) => void; +} + +const CellUndoButton: React.FC = ({ + alignLeft, + onClick, +}) => { + let undoButtonClass = `${BUTTON_CLASS} ${BUTTON_CLASS}-undo`; + if (alignLeft) { + undoButtonClass = `${undoButtonClass} ${BUTTON_CLASS}-left`; } - static propTypes = { - api: PropTypes.any, - value: PropTypes.any, - node: PropTypes.any, - column: PropTypes.any, - context: PropTypes.any, - parentType: PropTypes.any.isRequired, - elementAdded: PropTypes.func.isRequired, - elementRemoved: PropTypes.func.isRequired, - elementTypeChanged: PropTypes.func.isRequired, - drillDown: PropTypes.func.isRequired, - tz: PropTypes.string.isRequired, - darkMode: PropTypes.bool, - }; - - static displayName = 'CellRenderer'; + return ( + + + + ); +}; + +interface CellExpandButtonProps { + onClick: (event: React.MouseEvent) => void; } -export default withDarkMode(CellRenderer); +const CellExpandButton: React.FC = ({ onClick }) => { + return ( + + + + ); +}; diff --git a/packages/compass-crud/src/components/table-view/full-width-cell-renderer.tsx b/packages/compass-crud/src/components/table-view/full-width-cell-renderer.tsx index 5aecf2391f7..2c98c513772 100644 --- a/packages/compass-crud/src/components/table-view/full-width-cell-renderer.tsx +++ b/packages/compass-crud/src/components/table-view/full-width-cell-renderer.tsx @@ -9,6 +9,7 @@ import type { CellEditorProps } from './cell-editor'; import type { GridActions } from '../../stores/grid-store'; import type { Element } from 'hadron-document'; import type { BSONObject, CrudActions } from '../../stores/crud-store'; +import { CompassComponentsProvider } from '@mongodb-js/compass-components'; export type FullWidthCellRendererProps = Pick< CellEditorProps, @@ -127,30 +128,32 @@ class FullWidthCellRenderer extends React.Component< // this is needed cause ag-grid renders this component outside // of the context chain - { - this.props.api.stopEditing(); - if (force) { - void this.props.replaceDocument(this.doc); - } else { - void this.props.updateDocument(this.doc); - } - }} - onDelete={() => { - this.props.api.stopEditing(); - void this.props.removeDocument(this.doc); - }} - onCancel={() => { - if (this.state.mode === 'editing') { - this.handleCancelUpdate(); - } else { - this.handleCancelRemove(); - } - }} - /> + + { + this.props.api.stopEditing(); + if (force) { + void this.props.replaceDocument(this.doc); + } else { + void this.props.updateDocument(this.doc); + } + }} + onDelete={() => { + this.props.api.stopEditing(); + void this.props.removeDocument(this.doc); + }} + onCancel={() => { + if (this.state.mode === 'editing') { + this.handleCancelUpdate(); + } else { + this.handleCancelRemove(); + } + }} + /> + ); } diff --git a/packages/compass-crud/src/components/use-document-item-context-menu.spec.tsx b/packages/compass-crud/src/components/use-document-item-context-menu.spec.tsx new file mode 100644 index 00000000000..0edf522414e --- /dev/null +++ b/packages/compass-crud/src/components/use-document-item-context-menu.spec.tsx @@ -0,0 +1,255 @@ +import React from 'react'; +import { render, screen, userEvent } from '@mongodb-js/testing-library-compass'; +import { expect } from 'chai'; +import sinon from 'sinon'; +import HadronDocument from 'hadron-document'; +import { useDocumentItemContextMenu } from './use-document-item-context-menu'; + +// Test component that uses the hook +const TestComponent: React.FC<{ + doc: HadronDocument; + isEditable: boolean; + copyToClipboard?: (doc: HadronDocument) => void; + openInsertDocumentDialog?: ( + doc: Record, + cloned: boolean + ) => void; +}> = ({ doc, isEditable, copyToClipboard, openInsertDocumentDialog }) => { + const ref = useDocumentItemContextMenu({ + doc, + isEditable, + copyToClipboard, + openInsertDocumentDialog, + }); + + return ( +
+ Test Content +
+ ); +}; + +describe('useDocumentItemContextMenu', function () { + let doc: HadronDocument; + let copyToClipboardStub: sinon.SinonStub; + let openInsertDocumentDialogStub: sinon.SinonStub; + let collapseStub: sinon.SinonStub; + let expandStub: sinon.SinonStub; + let startEditingStub: sinon.SinonStub; + let markForDeletionStub: sinon.SinonStub; + let generateObjectStub: sinon.SinonStub; + + beforeEach(function () { + doc = new HadronDocument({ + _id: 1, + name: 'test', + nested: { field: 'value' }, + }); + + copyToClipboardStub = sinon.stub(); + openInsertDocumentDialogStub = sinon.stub(); + + // Set up document methods as stubs + collapseStub = sinon.stub(doc, 'collapse'); + expandStub = sinon.stub(doc, 'expand'); + startEditingStub = sinon.stub(doc, 'startEditing'); + markForDeletionStub = sinon.stub(doc, 'markForDeletion'); + generateObjectStub = sinon.stub(doc, 'generateObject').returns({ + _id: 1, + name: 'test', + nested: { field: 'value' }, + }); + }); + + afterEach(function () { + sinon.restore(); + }); + + describe('when editable', function () { + it('shows all menu items when document is editable and not editing', function () { + doc.expanded = false; + doc.editing = false; + + render( + + ); + + // Right-click to open context menu + userEvent.click(screen.getByTestId('test-container'), { button: 2 }); + + // Should show all operations + expect(screen.getByText('Expand all fields')).to.exist; + expect(screen.getByText('Edit document')).to.exist; + expect(screen.getByText('Copy document')).to.exist; + expect(screen.getByText('Clone document...')).to.exist; + expect(screen.getByText('Delete document')).to.exist; + }); + + it('hides edit document when document is editing', function () { + doc.expanded = false; + doc.editing = true; + + render( + + ); + + // Right-click to open context menu + userEvent.click(screen.getByTestId('test-container'), { button: 2 }); + + // Should hide edit document when editing + expect(screen.queryByText('Edit document')).to.not.exist; + // But show other operations + expect(screen.getByText('Expand all fields')).to.exist; + expect(screen.getByText('Copy document')).to.exist; + expect(screen.getByText('Clone document...')).to.exist; + expect(screen.getByText('Delete document')).to.exist; + }); + }); + + describe('when read-only', function () { + it('shows only non-mutating operations when not editable', function () { + doc.expanded = false; + doc.editing = false; + + render( + + ); + + // Right-click to open context menu + userEvent.click(screen.getByTestId('test-container'), { button: 2 }); + + // Should show non-mutating operations + expect(screen.getByText('Expand all fields')).to.exist; + expect(screen.getByText('Copy document')).to.exist; + + // Should hide mutating operations + expect(screen.queryByText('Edit document')).to.not.exist; + expect(screen.queryByText('Clone document...')).to.not.exist; + expect(screen.queryByText('Delete document')).to.not.exist; + }); + + it('collapses document when collapse is clicked', function () { + doc.expanded = true; + + // Render with expanded document + render( + + ); + + // Right-click to open context menu + userEvent.click(screen.getByTestId('test-container'), { button: 2 }); + + // Click collapse + userEvent.click(screen.getByText('Collapse all fields'), undefined, { + skipPointerEventsCheck: true, + }); + + expect(collapseStub).to.have.been.calledOnce; + }); + }); + + describe('functionality', function () { + beforeEach(function () { + render( + + ); + }); + + it('toggles expand/collapse correctly', function () { + doc.expanded = false; + + // Right-click to open context menu + userEvent.click(screen.getByTestId('test-container'), { button: 2 }); + + // Click expand + userEvent.click(screen.getByText('Expand all fields')); + + expect(expandStub).to.have.been.calledOnce; + }); + + it('starts editing when edit is clicked', function () { + doc.editing = false; + + // Right-click to open context menu + userEvent.click(screen.getByTestId('test-container'), { button: 2 }); + + // Click edit + userEvent.click(screen.getByText('Edit document'), undefined, { + skipPointerEventsCheck: true, + }); + + expect(startEditingStub).to.have.been.calledOnce; + }); + + it('calls copyToClipboard when copy is clicked', function () { + // Right-click to open context menu + userEvent.click(screen.getByTestId('test-container'), { button: 2 }); + + // Click copy + userEvent.click(screen.getByText('Copy document'), undefined, { + skipPointerEventsCheck: true, + }); + + expect(copyToClipboardStub).to.have.been.calledWith(doc); + }); + + it('calls openInsertDocumentDialog with cloned document when clone is clicked', function () { + // Right-click to open context menu + userEvent.click(screen.getByTestId('test-container'), { button: 2 }); + + // Click clone + userEvent.click(screen.getByText('Clone document...'), undefined, { + skipPointerEventsCheck: true, + }); + + expect(generateObjectStub).to.have.been.calledWith({ + excludeInternalFields: true, + }); + expect(openInsertDocumentDialogStub).to.have.been.calledWith( + { + _id: 1, + name: 'test', + nested: { field: 'value' }, + }, + true + ); + }); + + it('marks document for deletion when delete is clicked', function () { + // Right-click to open context menu + userEvent.click(screen.getByTestId('test-container'), { button: 2 }); + + // Click delete + userEvent.click(screen.getByText('Delete document'), undefined, { + skipPointerEventsCheck: true, + }); + + expect(markForDeletionStub).to.have.been.calledOnce; + }); + }); +}); diff --git a/packages/compass-crud/src/components/use-document-item-context-menu.tsx b/packages/compass-crud/src/components/use-document-item-context-menu.tsx new file mode 100644 index 00000000000..f457afd7dd7 --- /dev/null +++ b/packages/compass-crud/src/components/use-document-item-context-menu.tsx @@ -0,0 +1,67 @@ +import type HadronDocument from 'hadron-document'; +import { useContextMenuItems } from '@mongodb-js/compass-components'; + +export interface UseDocumentItemContextMenuProps { + doc: HadronDocument; + isEditable: boolean; + copyToClipboard?: (doc: HadronDocument) => void; + openInsertDocumentDialog?: ( + doc: Record, + cloned: boolean + ) => void; +} + +export function useDocumentItemContextMenu({ + doc, + isEditable, + copyToClipboard, + openInsertDocumentDialog, +}: UseDocumentItemContextMenuProps) { + return useContextMenuItems([ + { + label: doc.expanded ? 'Collapse all fields' : 'Expand all fields', + onAction: () => { + if (doc.expanded) { + doc.collapse(); + } else { + doc.expand(); + } + }, + }, + ...(isEditable && !doc.editing + ? [ + { + label: 'Edit document', + onAction: () => { + doc.startEditing(); + }, + }, + ] + : []), + { + label: 'Copy document', + onAction: () => { + copyToClipboard?.(doc); + }, + }, + ...(isEditable + ? [ + { + label: 'Clone document...', + onAction: () => { + const clonedDoc = doc.generateObject({ + excludeInternalFields: true, + }); + openInsertDocumentDialog?.(clonedDoc, true); + }, + }, + { + label: 'Delete document', + onAction: () => { + doc.markForDeletion(); + }, + }, + ] + : []), + ]); +} diff --git a/packages/compass-crud/src/components/virtualized-document-json-view.tsx b/packages/compass-crud/src/components/virtualized-document-json-view.tsx index 8cffcf8f26f..609bb657836 100644 --- a/packages/compass-crud/src/components/virtualized-document-json-view.tsx +++ b/packages/compass-crud/src/components/virtualized-document-json-view.tsx @@ -2,19 +2,14 @@ import React, { useCallback } from 'react'; import type HadronDocument from 'hadron-document'; import { css, - KeylineCard, spacing, VirtualList, type VirtualListRef, type VirtualListItemRenderer, } from '@mongodb-js/compass-components'; -import JSONEditor, { type JSONEditorProps } from './json-editor'; - -const keylineCardStyles = css({ - overflow: 'hidden', - position: 'relative', -}); +import type { JSONEditorProps } from './json-editor'; +import { DocumentJsonViewItem } from './document-json-view-item'; const spacingStyles = css({ padding: spacing[400], @@ -75,23 +70,26 @@ const VirtualizedDocumentJsonView: React.FC< listRef, }) => { const renderItem: VirtualListItemRenderer = useCallback( - (doc, docRef, docIndex) => { + ( + doc: HadronDocument, + docRef: React.Ref, + docIndex: number + ) => { return ( - - {scrollTriggerRef && docIndex === 0 &&
} - - + ); }, [ diff --git a/packages/compass-crud/src/components/virtualized-document-list-view.tsx b/packages/compass-crud/src/components/virtualized-document-list-view.tsx index 5ddfa237fb4..6cd5567a948 100644 --- a/packages/compass-crud/src/components/virtualized-document-list-view.tsx +++ b/packages/compass-crud/src/components/virtualized-document-list-view.tsx @@ -2,7 +2,6 @@ import React, { useCallback, useMemo } from 'react'; import HadronDocument from 'hadron-document'; import { css, - KeylineCard, spacing, VirtualList, type VirtualListItemRenderer, @@ -10,7 +9,8 @@ import { } from '@mongodb-js/compass-components'; import { type BSONObject } from '../stores/crud-store'; -import Document, { type DocumentProps } from './document'; +import type { DocumentProps } from './document'; +import { DocumentListViewItem } from './document-list-view-item'; const spacingStyles = css({ padding: spacing[400], @@ -90,22 +90,25 @@ const VirtualizedDocumentListView: React.FC< }, [_docs]); const renderItem: VirtualListItemRenderer = useCallback( - (doc, docRef, docIndex) => { + ( + doc: HadronDocument, + docRef: React.Ref, + docIndex: number + ) => { return ( - - {scrollTriggerRef && docIndex === 0 &&
} - - + ); }, [ diff --git a/packages/compass-crud/src/index.ts b/packages/compass-crud/src/index.ts index c539352679f..36ca93f22da 100644 --- a/packages/compass-crud/src/index.ts +++ b/packages/compass-crud/src/index.ts @@ -22,7 +22,7 @@ import { collectionModelLocator, mongoDBInstanceLocator, } from '@mongodb-js/compass-app-stores/provider'; -import { registerHadronPlugin } from 'hadron-app-registry'; +import { registerCompassPlugin } from '@mongodb-js/compass-app-registry'; import { preferencesLocator } from 'compass-preferences-model/provider'; import { createLoggerLocator } from '@mongodb-js/compass-logging/provider'; import { @@ -34,7 +34,7 @@ import { queryBarServiceLocator } from '@mongodb-js/compass-query-bar'; import { telemetryLocator } from '@mongodb-js/compass-telemetry/provider'; import { CrudTabTitle } from './plugin-title'; -const CompassDocumentsHadronPlugin = registerHadronPlugin( +const CompassDocumentsPluginProvider = registerCompassPlugin( { name: 'CompassDocuments', component: function CrudProvider({ children, ...props }) { @@ -71,7 +71,7 @@ const CompassDocumentsHadronPlugin = registerHadronPlugin( export const CompassDocumentsPlugin = { name: 'Documents' as const, - provider: CompassDocumentsHadronPlugin, + provider: CompassDocumentsPluginProvider, content: DocumentList as any, // as any because of reflux store header: CrudTabTitle as any, // as any because of reflux store }; diff --git a/packages/compass-crud/src/stores/crud-store.spec.ts b/packages/compass-crud/src/stores/crud-store.spec.ts index 87f084f5c11..6a16a83cc8e 100644 --- a/packages/compass-crud/src/stores/crud-store.spec.ts +++ b/packages/compass-crud/src/stores/crud-store.spec.ts @@ -1,7 +1,9 @@ import util from 'util'; import type { DataService } from 'mongodb-data-service'; import { connect } from 'mongodb-data-service'; -import AppRegistry, { createActivateHelpers } from 'hadron-app-registry'; +import AppRegistry, { + createActivateHelpers, +} from '@mongodb-js/compass-app-registry'; import HadronDocument, { Element } from 'hadron-document'; import { MongoDBInstance } from 'mongodb-instance-model'; import { once } from 'events'; diff --git a/packages/compass-crud/src/stores/crud-store.ts b/packages/compass-crud/src/stores/crud-store.ts index c2c98a61370..81bc2087c3d 100644 --- a/packages/compass-crud/src/stores/crud-store.ts +++ b/packages/compass-crud/src/stores/crud-store.ts @@ -41,8 +41,8 @@ import type { UpdatePreview } from 'mongodb-data-service'; import type { GridStore, TableHeaderType } from './grid-store'; import configureGridStore from './grid-store'; import type { TypeCastMap } from 'hadron-type-checker'; -import type AppRegistry from 'hadron-app-registry'; -import type { ActivateHelpers } from 'hadron-app-registry'; +import type AppRegistry from '@mongodb-js/compass-app-registry'; +import type { ActivateHelpers } from '@mongodb-js/compass-app-registry'; import { BaseRefluxStore } from './base-reflux-store'; import { openToast, showConfirmation } from '@mongodb-js/compass-components'; import { diff --git a/packages/compass-data-modeling/package.json b/packages/compass-data-modeling/package.json index 8a265d09cb5..dcfb28826eb 100644 --- a/packages/compass-data-modeling/package.json +++ b/packages/compass-data-modeling/package.json @@ -11,7 +11,7 @@ "email": "compass@mongodb.com" }, "homepage": "https://github.com/mongodb-js/compass", - "version": "1.11.0", + "version": "1.12.0", "repository": { "type": "git", "url": "https://github.com/mongodb-js/compass.git" @@ -54,18 +54,18 @@ "reformat": "npm run eslint . -- --fix && npm run prettier -- --write ." }, "dependencies": { - "@mongodb-js/compass-app-stores": "^7.46.0", - "@mongodb-js/compass-components": "^1.38.1", - "@mongodb-js/compass-connections": "^1.60.0", - "@mongodb-js/compass-editor": "^0.40.2", + "@mongodb-js/compass-app-stores": "^7.47.0", + "@mongodb-js/compass-components": "^1.39.0", + "@mongodb-js/compass-connections": "^1.61.0", + "@mongodb-js/compass-editor": "^0.41.0", "@mongodb-js/diagramming": "^1.0.2", "@mongodb-js/compass-logging": "^1.7.2", "@mongodb-js/compass-telemetry": "^1.10.0", "@mongodb-js/compass-user-data": "^0.7.2", - "@mongodb-js/compass-workspaces": "^0.41.0", + "@mongodb-js/compass-workspaces": "^0.42.0", "bson": "^6.10.3", - "compass-preferences-model": "^2.40.2", - "hadron-app-registry": "^9.4.11", + "compass-preferences-model": "^2.41.0", + "@mongodb-js/compass-app-registry": "^9.4.11", "lodash": "^4.17.21", "mongodb": "^6.14.1", "mongodb-ns": "^2.4.2", diff --git a/packages/compass-data-modeling/src/components/diagram-editor.tsx b/packages/compass-data-modeling/src/components/diagram-editor.tsx index bddf93a84ea..39a77bc9654 100644 --- a/packages/compass-data-modeling/src/components/diagram-editor.tsx +++ b/packages/compass-data-modeling/src/components/diagram-editor.tsx @@ -1,4 +1,4 @@ -import React, { useMemo, useState } from 'react'; +import React, { useCallback, useMemo, useRef, useState } from 'react'; import { connect } from 'react-redux'; import type { DataModelingState } from '../store/reducer'; import { @@ -27,6 +27,7 @@ import { Diagram, type NodeProps, type EdgeProps, + useDiagram, } from '@mongodb-js/diagramming'; import type { Edit, StaticModel } from '../services/data-model-storage'; import { UUID } from 'bson'; @@ -132,6 +133,20 @@ const DiagramEditor: React.FunctionComponent<{ onApplyClick, }) => { const isDarkMode = useDarkMode(); + const diagramContainerRef = useRef(null); + const diagram = useDiagram(); + + const setDiagramContainerRef = useCallback( + (ref: HTMLDivElement | null) => { + if (ref) { + // For debugging purposes, we attach the diagram to the ref. + (ref as any)._diagram = diagram; + } + diagramContainerRef.current = ref; + }, + [diagram] + ); + const [applyInput, setApplyInput] = useState('{}'); const isEditValid = useMemo(() => { @@ -265,6 +280,7 @@ const DiagramEditor: React.FunctionComponent<{ if (step === 'EDITING') { content = (
diff --git a/packages/compass-data-modeling/src/index.spec.tsx b/packages/compass-data-modeling/src/index.spec.tsx index 3c3cf401c05..3aabdc09919 100644 --- a/packages/compass-data-modeling/src/index.spec.tsx +++ b/packages/compass-data-modeling/src/index.spec.tsx @@ -1,12 +1,18 @@ import React from 'react'; import { expect } from 'chai'; import { render } from '@mongodb-js/testing-library-compass'; -import CompassPlugin from './index'; +import { WorkspaceTab } from './index'; describe('Compass Plugin', function () { - const Plugin = CompassPlugin.withMockServices({}); + const Plugin = WorkspaceTab.provider.withMockServices({}); it('renders a Plugin', function () { - expect(() => render()).to.not.throw(); + expect(() => + render( + + + + ) + ).to.not.throw(); }); }); diff --git a/packages/compass-data-modeling/src/index.ts b/packages/compass-data-modeling/src/index.ts index a9f5f0c5fda..11d8c5db407 100644 --- a/packages/compass-data-modeling/src/index.ts +++ b/packages/compass-data-modeling/src/index.ts @@ -1,33 +1,35 @@ -import { registerHadronPlugin } from 'hadron-app-registry'; +import React from 'react'; +import { registerCompassPlugin } from '@mongodb-js/compass-app-registry'; import { preferencesLocator } from 'compass-preferences-model/provider'; import { connectionsLocator } from '@mongodb-js/compass-connections/provider'; import { telemetryLocator } from '@mongodb-js/compass-telemetry/provider'; import { createLoggerLocator } from '@mongodb-js/compass-logging/provider'; -import type { WorkspaceComponent } from '@mongodb-js/compass-workspaces'; +import type { WorkspacePlugin } from '@mongodb-js/compass-workspaces'; import DataModelingComponent from './components/data-modeling'; import { mongoDBInstancesManagerLocator } from '@mongodb-js/compass-app-stores/provider'; import { dataModelStorageServiceLocator } from './provider'; import { activateDataModelingStore } from './store'; +import { PluginTabTitleComponent, WorkspaceName } from './plugin-tab-title'; -const DataModelingPlugin = registerHadronPlugin( - { - name: 'DataModeling', - component: DataModelingComponent, - activate: activateDataModelingStore, - }, - { - preferences: preferencesLocator, - connections: connectionsLocator, - instanceManager: mongoDBInstancesManagerLocator, - dataModelStorage: dataModelStorageServiceLocator, - track: telemetryLocator, - logger: createLoggerLocator('COMPASS-DATA-MODELING'), - } -); - -export const WorkspaceTab: WorkspaceComponent<'Data Modeling'> = { - name: 'Data Modeling', - component: DataModelingPlugin, +export const WorkspaceTab: WorkspacePlugin = { + name: WorkspaceName, + provider: registerCompassPlugin( + { + name: 'DataModeling', + component: function DataModelingProvider({ children }) { + return React.createElement(React.Fragment, null, children); + }, + activate: activateDataModelingStore, + }, + { + preferences: preferencesLocator, + connections: connectionsLocator, + instanceManager: mongoDBInstancesManagerLocator, + dataModelStorage: dataModelStorageServiceLocator, + track: telemetryLocator, + logger: createLoggerLocator('COMPASS-DATA-MODELING'), + } + ), + content: DataModelingComponent, + header: PluginTabTitleComponent, }; - -export default DataModelingPlugin; diff --git a/packages/compass-data-modeling/src/plugin-tab-title.tsx b/packages/compass-data-modeling/src/plugin-tab-title.tsx new file mode 100644 index 00000000000..40aac13afbf --- /dev/null +++ b/packages/compass-data-modeling/src/plugin-tab-title.tsx @@ -0,0 +1,37 @@ +import React from 'react'; +import { connect } from 'react-redux'; + +import { + WorkspaceTab, + type WorkspaceTabCoreProps, +} from '@mongodb-js/compass-components'; +import type { DataModelingState } from './store/reducer'; +import type { WorkspacePluginProps } from '@mongodb-js/compass-workspaces'; + +export const WorkspaceName = 'Data Modeling' as const; + +type WorkspaceProps = WorkspacePluginProps; +type PluginTabTitleProps = { + tabTitle: string; +} & WorkspaceTabCoreProps & + WorkspaceProps; + +function _TabTitle({ tabTitle, ...props }: PluginTabTitleProps) { + return ( + + ); +} + +export const PluginTabTitleComponent = connect((state: DataModelingState) => { + return { + tabTitle: + state.step === 'NO_DIAGRAM_SELECTED' + ? WorkspaceName + : state.diagram?.name ?? WorkspaceName, + }; +})(_TabTitle); diff --git a/packages/compass-data-modeling/src/provider/index.tsx b/packages/compass-data-modeling/src/provider/index.tsx index ec5b683ac66..72fdb9045b7 100644 --- a/packages/compass-data-modeling/src/provider/index.tsx +++ b/packages/compass-data-modeling/src/provider/index.tsx @@ -3,7 +3,7 @@ import type { DataModelStorage, MongoDBDataModelDescription, } from '../services/data-model-storage'; -import { createServiceLocator } from 'hadron-app-registry'; +import { createServiceLocator } from '@mongodb-js/compass-app-registry'; export type DataModelStorageServiceState = { status: 'INITIAL' | 'LOADING' | 'REFRESHING' | 'READY' | 'ERROR'; diff --git a/packages/compass-data-modeling/src/store/index.ts b/packages/compass-data-modeling/src/store/index.ts index 2457a9e49de..92b84772321 100644 --- a/packages/compass-data-modeling/src/store/index.ts +++ b/packages/compass-data-modeling/src/store/index.ts @@ -7,7 +7,7 @@ import type { DataModelStorageService } from '../provider'; import { applyMiddleware, createStore } from 'redux'; import reducer from './reducer'; import thunk from 'redux-thunk'; -import type { ActivateHelpers } from 'hadron-app-registry'; +import type { ActivateHelpers } from '@mongodb-js/compass-app-registry'; export type DataModelingStoreOptions = Record; diff --git a/packages/compass-data-modeling/test/setup-store.tsx b/packages/compass-data-modeling/test/setup-store.tsx index 270f5874233..9939c2453b3 100644 --- a/packages/compass-data-modeling/test/setup-store.tsx +++ b/packages/compass-data-modeling/test/setup-store.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { renderWithConnections } from '@mongodb-js/testing-library-compass'; -import { createActivateHelpers } from 'hadron-app-registry'; +import { createActivateHelpers } from '@mongodb-js/compass-app-registry'; import { createNoopTrack } from '@mongodb-js/compass-telemetry/provider'; import { createNoopLogger } from '@mongodb-js/compass-logging/provider'; import { TestMongoDBInstanceManager } from '@mongodb-js/compass-app-stores/provider'; diff --git a/packages/compass-e2e-tests/helpers/selectors.ts b/packages/compass-e2e-tests/helpers/selectors.ts index f129f846383..0f66ed83304 100644 --- a/packages/compass-e2e-tests/helpers/selectors.ts +++ b/packages/compass-e2e-tests/helpers/selectors.ts @@ -1451,5 +1451,3 @@ export const DataModelsListItem = (diagramName: string) => export const DataModelsListItemActions = (diagramName: string) => `${DataModelsListItem(diagramName)} [aria-label="Show actions"]`; export const DataModelsListItemDeleteButton = `[data-action="delete"]`; -export const DataModelingDiagram = '.react-flow'; -export const DataModelingDiagramNode = '.react-flow__node > div'; diff --git a/packages/compass-e2e-tests/helpers/test-runner-context.ts b/packages/compass-e2e-tests/helpers/test-runner-context.ts index b05e059ba32..b0ca880726b 100644 --- a/packages/compass-e2e-tests/helpers/test-runner-context.ts +++ b/packages/compass-e2e-tests/helpers/test-runner-context.ts @@ -49,9 +49,9 @@ function buildCommonArgs(yargs: Argv) { .option('mocha-timeout', { type: 'number', description: 'Set a custom default mocha timeout', - // Kinda arbitrary, but longer than webdriver-waitfor-timeout so the test - // can fail before Mocha times out - default: 240_000, + // 4min, kinda arbitrary, but longer than webdriver-waitfor-timeout so the + // test can fail before Mocha times out + default: 1000 * 60 * 4, }) .option('mocha-bail', { type: 'boolean', diff --git a/packages/compass-e2e-tests/package.json b/packages/compass-e2e-tests/package.json index 6b091c42a72..50452fbd24d 100644 --- a/packages/compass-e2e-tests/package.json +++ b/packages/compass-e2e-tests/package.json @@ -1,6 +1,6 @@ { "name": "compass-e2e-tests", - "version": "1.33.0", + "version": "1.33.1", "private": true, "description": "E2E test suite for Compass app that follows smoke tests / feature testing matrix", "scripts": { @@ -46,7 +46,7 @@ "chai": "^4.3.4", "chai-as-promised": "^7.1.1", "clipboardy": "^2.3.0", - "compass-preferences-model": "^2.40.2", + "compass-preferences-model": "^2.41.0", "cross-spawn": "^7.0.5", "debug": "^4.3.4", "depcheck": "^1.4.1", diff --git a/packages/compass-e2e-tests/tests/collection-import.test.ts b/packages/compass-e2e-tests/tests/collection-import.test.ts index 0ade8112284..58cdeeec56a 100644 --- a/packages/compass-e2e-tests/tests/collection-import.test.ts +++ b/packages/compass-e2e-tests/tests/collection-import.test.ts @@ -1471,7 +1471,11 @@ describe('Collection import', function () { // Confirm import. await browser.clickVisible(Selectors.ImportConfirm); // Wait for the in progress toast to appear. - await browser.$(Selectors.ImportToastAbort).waitForDisplayed(); + await browser.$(Selectors.ImportToastAbort).waitForDisplayed({ + // This is defaulted to 100, which can cause a race condition as the import could succeed. + // So we make it quicker. This could still cause flakes, but it is less likely. + interval: 1, + }); await browser.disconnectAll({ closeToasts: false }); diff --git a/packages/compass-e2e-tests/tests/data-modeling-tab.test.ts b/packages/compass-e2e-tests/tests/data-modeling-tab.test.ts index 3ded8ff12d0..da4361584e0 100644 --- a/packages/compass-e2e-tests/tests/data-modeling-tab.test.ts +++ b/packages/compass-e2e-tests/tests/data-modeling-tab.test.ts @@ -14,11 +14,23 @@ import { createNumbersCollection, } from '../helpers/insert-data'; +type DiagramInstance = { + getNodes: () => Array<{ + id: string; + }>; +}; + async function getDiagramNodes(browser: CompassBrowser): Promise { - await browser.waitForAnimations(Selectors.DataModelingDiagram); - return await browser - .$$(Selectors.DataModelingDiagramNode) - .map((element) => element.getAttribute('title')); + const nodes = await browser.execute(function (selector) { + const node = document.querySelector(selector); + if (!node) { + throw new Error(`Element with selector ${selector} not found`); + } + return ( + node as Element & { _diagram: DiagramInstance } + )._diagram.getNodes(); + }, Selectors.DataModelEditor); + return nodes.map((x) => x.id); } describe('Data Modeling tab', function () { @@ -107,6 +119,7 @@ describe('Data Modeling tab', function () { JSON.stringify(newModel) ); await browser.clickVisible(Selectors.DataModelEditorApplyButton); + await browser.waitForAnimations(dataModelEditor); // Verify that the model is updated nodes = await getDiagramNodes(browser); @@ -114,6 +127,7 @@ describe('Data Modeling tab', function () { // Undo the change await browser.clickVisible(Selectors.DataModelUndoButton); + await browser.waitForAnimations(dataModelEditor); nodes = await getDiagramNodes(browser); expect(nodes).to.have.lengthOf(2); expect(nodes).to.deep.equal([ @@ -124,6 +138,7 @@ describe('Data Modeling tab', function () { // Redo the change await browser.waitForAriaDisabled(Selectors.DataModelRedoButton, false); await browser.clickVisible(Selectors.DataModelRedoButton); + await browser.waitForAnimations(dataModelEditor); nodes = await getDiagramNodes(browser); expect(nodes).to.have.lengthOf(0); diff --git a/packages/compass-e2e-tests/tests/proxy.test.ts b/packages/compass-e2e-tests/tests/proxy.test.ts index 059e678cf9d..0e9450b3f02 100644 --- a/packages/compass-e2e-tests/tests/proxy.test.ts +++ b/packages/compass-e2e-tests/tests/proxy.test.ts @@ -65,10 +65,12 @@ describe('Proxy support', function () { browser = compass.browser; const result = await browser.execute(async function () { - const response = await fetch('http://compass.mongodb.com/'); + const response = await fetch('http://proxy-test-compass.mongodb.com/'); return await response.text(); }); - expect(result).to.equal('hello, http://compass.mongodb.com/ (proxy1)'); + expect(result).to.equal( + 'hello, http://proxy-test-compass.mongodb.com/ (proxy1)' + ); }); it('can change the proxy option dynamically', async function () { @@ -80,10 +82,12 @@ describe('Proxy support', function () { `http://localhost:${port(httpProxyServer2)}` ); const result = await browser.execute(async function () { - const response = await fetch('http://compass.mongodb.com/'); + const response = await fetch('http://proxy-test-compass.mongodb.com/'); return await response.text(); }); - expect(result).to.equal('hello, http://compass.mongodb.com/ (proxy2)'); + expect(result).to.equal( + 'hello, http://proxy-test-compass.mongodb.com/ (proxy2)' + ); }); context('when connecting to a cluster', function () { diff --git a/packages/compass-editor/package.json b/packages/compass-editor/package.json index 3014f9c0b0a..6775016c10a 100644 --- a/packages/compass-editor/package.json +++ b/packages/compass-editor/package.json @@ -13,7 +13,7 @@ "email": "compass@mongodb.com" }, "homepage": "https://github.com/mongodb-js/compass", - "version": "0.40.2", + "version": "0.41.0", "repository": { "type": "git", "url": "https://github.com/mongodb-js/compass.git" @@ -71,7 +71,7 @@ "@codemirror/state": "^6.1.4", "@codemirror/view": "^6.7.1", "@lezer/highlight": "^1.2.0", - "@mongodb-js/compass-components": "^1.38.1", + "@mongodb-js/compass-components": "^1.39.0", "@mongodb-js/mongodb-constants": "^0.11.0", "mongodb-query-parser": "^4.3.0", "polished": "^4.2.2", diff --git a/packages/compass-explain-plan/package.json b/packages/compass-explain-plan/package.json index fcd422e9176..d8074f2b291 100644 --- a/packages/compass-explain-plan/package.json +++ b/packages/compass-explain-plan/package.json @@ -6,7 +6,7 @@ "email": "compass@mongodb.com" }, "private": true, - "version": "6.60.0", + "version": "6.61.0", "repository": { "type": "git", "url": "https://github.com/mongodb-js/compass.git" @@ -68,18 +68,18 @@ "xvfb-maybe": "^0.2.1" }, "dependencies": { - "@mongodb-js/compass-collection": "^4.59.0", - "@mongodb-js/compass-components": "^1.38.1", - "@mongodb-js/compass-connections": "^1.60.0", - "@mongodb-js/compass-editor": "^0.40.2", + "@mongodb-js/compass-collection": "^4.60.0", + "@mongodb-js/compass-components": "^1.39.0", + "@mongodb-js/compass-connections": "^1.61.0", + "@mongodb-js/compass-editor": "^0.41.0", "@mongodb-js/compass-logging": "^1.7.2", "@mongodb-js/compass-telemetry": "^1.10.0", "@mongodb-js/explain-plan-helper": "^1.4.10", - "compass-preferences-model": "^2.40.2", + "compass-preferences-model": "^2.41.0", "d3": "^3.5.17", "d3-flextree": "^2.1.2", "d3-hierarchy": "^3.1.2", - "hadron-app-registry": "^9.4.11", + "@mongodb-js/compass-app-registry": "^9.4.11", "lodash": "^4.17.21", "mongodb": "^6.16.0", "react": "^17.0.2", diff --git a/packages/compass-explain-plan/src/index.ts b/packages/compass-explain-plan/src/index.ts index c1809dd2ecc..605d9e363dc 100644 --- a/packages/compass-explain-plan/src/index.ts +++ b/packages/compass-explain-plan/src/index.ts @@ -1,6 +1,6 @@ import ExplainPlanModal from './components/explain-plan-modal'; import { activatePlugin } from './stores'; -import { registerHadronPlugin } from 'hadron-app-registry'; +import { registerCompassPlugin } from '@mongodb-js/compass-app-registry'; import { connectionInfoRefLocator, dataServiceLocator, @@ -10,7 +10,7 @@ import { createLoggerLocator } from '@mongodb-js/compass-logging/provider'; import { telemetryLocator } from '@mongodb-js/compass-telemetry/provider'; import { preferencesLocator } from 'compass-preferences-model/provider'; -const ExplainPlanModalPlugin = registerHadronPlugin( +const ExplainPlanModalPlugin = registerCompassPlugin( { name: 'ExplainPlanModal', component: ExplainPlanModal, diff --git a/packages/compass-explain-plan/src/stores/explain-plan-modal-store.spec.ts b/packages/compass-explain-plan/src/stores/explain-plan-modal-store.spec.ts index c2cd4656cac..1a2b1cd293e 100644 --- a/packages/compass-explain-plan/src/stores/explain-plan-modal-store.spec.ts +++ b/packages/compass-explain-plan/src/stores/explain-plan-modal-store.spec.ts @@ -1,4 +1,6 @@ -import AppRegistry, { createActivateHelpers } from 'hadron-app-registry'; +import AppRegistry, { + createActivateHelpers, +} from '@mongodb-js/compass-app-registry'; import { closeExplainPlanModal, openExplainPlanModal, diff --git a/packages/compass-explain-plan/src/stores/index.ts b/packages/compass-explain-plan/src/stores/index.ts index 2ba90aaee4b..c880f98e3f2 100644 --- a/packages/compass-explain-plan/src/stores/index.ts +++ b/packages/compass-explain-plan/src/stores/index.ts @@ -1,13 +1,13 @@ import { applyMiddleware, createStore } from 'redux'; import thunk from 'redux-thunk'; -import type { ActivateHelpers } from 'hadron-app-registry'; +import type { ActivateHelpers } from '@mongodb-js/compass-app-registry'; import { reducer, INITIAL_STATE, openExplainPlanModal, } from './explain-plan-modal-store'; import type { AggregateOptions, Document, FindOptions } from 'mongodb'; -import type AppRegistry from 'hadron-app-registry'; +import type AppRegistry from '@mongodb-js/compass-app-registry'; import type { CollectionTabPluginMetadata } from '@mongodb-js/compass-collection'; import type { ConnectionInfoRef, diff --git a/packages/compass-export-to-language/package.json b/packages/compass-export-to-language/package.json index 4e43fea3cdd..76bb8de821e 100644 --- a/packages/compass-export-to-language/package.json +++ b/packages/compass-export-to-language/package.json @@ -11,7 +11,7 @@ "email": "compass@mongodb.com" }, "homepage": "https://github.com/mongodb-js/compass", - "version": "9.36.0", + "version": "9.37.0", "repository": { "type": "git", "url": "https://github.com/mongodb-js/compass.git" @@ -48,16 +48,16 @@ "reformat": "npm run eslint . -- --fix && npm run prettier -- --write ." }, "dependencies": { - "@mongodb-js/compass-collection": "^4.59.0", - "@mongodb-js/compass-components": "^1.38.1", - "@mongodb-js/compass-connections": "^1.60.0", - "@mongodb-js/compass-editor": "^0.40.2", - "@mongodb-js/compass-maybe-protect-connection-string": "^0.38.2", + "@mongodb-js/compass-collection": "^4.60.0", + "@mongodb-js/compass-components": "^1.39.0", + "@mongodb-js/compass-connections": "^1.61.0", + "@mongodb-js/compass-editor": "^0.41.0", + "@mongodb-js/compass-maybe-protect-connection-string": "^0.39.0", "@mongodb-js/compass-telemetry": "^1.10.0", "@mongodb-js/shell-bson-parser": "^1.2.0", "bson-transpilers": "^3.2.10", - "compass-preferences-model": "^2.40.2", - "hadron-app-registry": "^9.4.11", + "compass-preferences-model": "^2.41.0", + "@mongodb-js/compass-app-registry": "^9.4.11", "mongodb-ns": "^2.4.2", "react": "^17.0.2", "react-redux": "^8.1.3", diff --git a/packages/compass-export-to-language/src/index.ts b/packages/compass-export-to-language/src/index.ts index 0bdfcf2473f..e38df702136 100644 --- a/packages/compass-export-to-language/src/index.ts +++ b/packages/compass-export-to-language/src/index.ts @@ -1,4 +1,4 @@ -import { registerHadronPlugin } from 'hadron-app-registry'; +import { registerCompassPlugin } from '@mongodb-js/compass-app-registry'; import ExportToLanguageModal from './components/modal'; import { activatePlugin } from './stores'; import { @@ -6,7 +6,7 @@ import { type DataServiceLocator, } from '@mongodb-js/compass-connections/provider'; -const ExportToLanguagePlugin = registerHadronPlugin( +const ExportToLanguagePlugin = registerCompassPlugin( { name: 'ExportToLanguage', component: ExportToLanguageModal, diff --git a/packages/compass-export-to-language/src/stores/index.ts b/packages/compass-export-to-language/src/stores/index.ts index 7e484882966..70beb1f48cc 100644 --- a/packages/compass-export-to-language/src/stores/index.ts +++ b/packages/compass-export-to-language/src/stores/index.ts @@ -4,8 +4,8 @@ import type { QueryExpression, InputExpression } from '../modules/transpiler'; import { isValidExportMode } from '../modules/transpiler'; import type { CollectionTabPluginMetadata } from '@mongodb-js/compass-collection'; import type { DataService } from '@mongodb-js/compass-connections/provider'; -import type { ActivateHelpers } from 'hadron-app-registry'; -import type AppRegistry from 'hadron-app-registry'; +import type { ActivateHelpers } from '@mongodb-js/compass-app-registry'; +import type AppRegistry from '@mongodb-js/compass-app-registry'; function isAction( action: Action, diff --git a/packages/compass-field-store/package.json b/packages/compass-field-store/package.json index d0114bf33d2..0260630b2ce 100644 --- a/packages/compass-field-store/package.json +++ b/packages/compass-field-store/package.json @@ -11,7 +11,7 @@ "email": "compass@mongodb.com" }, "homepage": "https://github.com/mongodb-js/compass", - "version": "9.35.0", + "version": "9.36.0", "repository": { "type": "git", "url": "https://github.com/mongodb-js/compass.git" @@ -67,9 +67,9 @@ "xvfb-maybe": "^0.2.1" }, "dependencies": { - "@mongodb-js/compass-connections": "^1.60.0", + "@mongodb-js/compass-connections": "^1.61.0", "@mongodb-js/compass-logging": "^1.7.2", - "hadron-app-registry": "^9.4.11", + "@mongodb-js/compass-app-registry": "^9.4.11", "lodash": "^4.17.21", "mongodb-schema": "^12.6.2", "react": "^17.0.2", diff --git a/packages/compass-field-store/src/index.tsx b/packages/compass-field-store/src/index.tsx index 71bdc65fecc..992a01f05bc 100644 --- a/packages/compass-field-store/src/index.tsx +++ b/packages/compass-field-store/src/index.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { registerHadronPlugin } from 'hadron-app-registry'; +import { registerCompassPlugin } from '@mongodb-js/compass-app-registry'; import { activatePlugin } from './stores/store'; import { connectionsLocator } from '@mongodb-js/compass-connections/provider'; import { createLoggerLocator } from '@mongodb-js/compass-logging/provider'; @@ -11,7 +11,7 @@ const FieldStoreComponent: React.FunctionComponent = ({ children }) => { return <>{children}; }; -const FieldStorePlugin = registerHadronPlugin( +const FieldStorePlugin = registerCompassPlugin( { name: 'FieldStore', component: FieldStoreComponent, diff --git a/packages/compass-field-store/src/stores/field-store-service.ts b/packages/compass-field-store/src/stores/field-store-service.ts index 4077ab1bba8..c299863e434 100644 --- a/packages/compass-field-store/src/stores/field-store-service.ts +++ b/packages/compass-field-store/src/stores/field-store-service.ts @@ -1,5 +1,5 @@ import { type Schema } from 'mongodb-schema'; -import { createServiceLocator } from 'hadron-app-registry'; +import { createServiceLocator } from '@mongodb-js/compass-app-registry'; import { useConnectionInfoRef, type ConnectionInfoRef, diff --git a/packages/compass-field-store/src/stores/store.ts b/packages/compass-field-store/src/stores/store.ts index 2356fdc764f..09971e373c2 100644 --- a/packages/compass-field-store/src/stores/store.ts +++ b/packages/compass-field-store/src/stores/store.ts @@ -2,7 +2,7 @@ import { applyMiddleware, createStore } from 'redux'; import reducer, { connectionDisconnected } from '../modules'; import { FieldStoreContext } from './context'; import type { ConnectionsService } from '@mongodb-js/compass-connections/provider'; -import type { ActivateHelpers } from 'hadron-app-registry'; +import type { ActivateHelpers } from '@mongodb-js/compass-app-registry'; import thunk from 'redux-thunk'; import type { Logger } from '@mongodb-js/compass-logging/provider'; diff --git a/packages/compass-find-in-page/package.json b/packages/compass-find-in-page/package.json index 2fca8bd2f62..3cb6bb0f723 100644 --- a/packages/compass-find-in-page/package.json +++ b/packages/compass-find-in-page/package.json @@ -6,7 +6,7 @@ "email": "compass@mongodb.com" }, "private": true, - "version": "4.39.2", + "version": "4.40.0", "repository": { "type": "git", "url": "https://github.com/mongodb-js/compass.git" @@ -71,8 +71,8 @@ "xvfb-maybe": "^0.2.1" }, "dependencies": { - "@mongodb-js/compass-components": "^1.38.1", - "hadron-app-registry": "^9.4.11", + "@mongodb-js/compass-components": "^1.39.0", + "@mongodb-js/compass-app-registry": "^9.4.11", "hadron-ipc": "^3.5.2", "react": "^17.0.2", "react-redux": "^8.1.3", diff --git a/packages/compass-find-in-page/src/index.ts b/packages/compass-find-in-page/src/index.ts index 1efd23c6530..78022021267 100644 --- a/packages/compass-find-in-page/src/index.ts +++ b/packages/compass-find-in-page/src/index.ts @@ -1,8 +1,8 @@ -import { registerHadronPlugin } from 'hadron-app-registry'; +import { registerCompassPlugin } from '@mongodb-js/compass-app-registry'; import CompassFindInPage from './components/compass-find-in-page'; import { activatePlugin } from './stores/store'; -export const CompassFindInPagePlugin = registerHadronPlugin({ +export const CompassFindInPagePlugin = registerCompassPlugin({ name: 'CompassFindInPage', component: CompassFindInPage, activate: activatePlugin, diff --git a/packages/compass-generative-ai/package.json b/packages/compass-generative-ai/package.json index 00f4fcf77a3..62f4da67a98 100644 --- a/packages/compass-generative-ai/package.json +++ b/packages/compass-generative-ai/package.json @@ -11,7 +11,7 @@ "email": "compass@mongodb.com" }, "homepage": "https://github.com/mongodb-js/compass", - "version": "0.40.0", + "version": "0.41.0", "repository": { "type": "git", "url": "https://github.com/mongodb-js/compass.git" @@ -52,16 +52,16 @@ "reformat": "npm run eslint . -- --fix && npm run prettier -- --write ." }, "dependencies": { - "@mongodb-js/atlas-service": "^0.45.0", - "@mongodb-js/compass-components": "^1.38.1", - "@mongodb-js/compass-connections": "^1.60.0", - "@mongodb-js/compass-intercom": "^0.24.2", + "@mongodb-js/atlas-service": "^0.46.0", + "@mongodb-js/compass-components": "^1.39.0", + "@mongodb-js/compass-connections": "^1.61.0", + "@mongodb-js/compass-intercom": "^0.25.0", "@mongodb-js/compass-logging": "^1.7.2", "@mongodb-js/compass-telemetry": "^1.10.0", "@mongodb-js/compass-utils": "^0.9.2", "bson": "^6.10.3", - "compass-preferences-model": "^2.40.2", - "hadron-app-registry": "^9.4.11", + "compass-preferences-model": "^2.41.0", + "@mongodb-js/compass-app-registry": "^9.4.11", "mongodb": "^6.16.0", "mongodb-schema": "^12.6.2", "react": "^17.0.2", diff --git a/packages/compass-generative-ai/src/index.ts b/packages/compass-generative-ai/src/index.ts index 6e1dae845ad..da945a0f8c7 100644 --- a/packages/compass-generative-ai/src/index.ts +++ b/packages/compass-generative-ai/src/index.ts @@ -1,11 +1,11 @@ -import { registerHadronPlugin } from 'hadron-app-registry'; +import { registerCompassPlugin } from '@mongodb-js/compass-app-registry'; import { atlasAuthServiceLocator } from '@mongodb-js/atlas-service/provider'; import { AtlasAiPlugin } from './components'; import { atlasAiServiceLocator } from './provider'; import { preferencesLocator } from 'compass-preferences-model/provider'; import { activatePlugin } from './store/atlas-ai-store'; -export const CompassGenerativeAIPlugin = registerHadronPlugin( +export const CompassGenerativeAIPlugin = registerCompassPlugin( { name: 'CompassGenerativeAI', component: AtlasAiPlugin, diff --git a/packages/compass-generative-ai/src/provider.tsx b/packages/compass-generative-ai/src/provider.tsx index 05f3bd58db6..9a6d6dbfb56 100644 --- a/packages/compass-generative-ai/src/provider.tsx +++ b/packages/compass-generative-ai/src/provider.tsx @@ -6,7 +6,7 @@ import { atlasServiceLocator } from '@mongodb-js/atlas-service/provider'; import { createServiceLocator, createServiceProvider, -} from 'hadron-app-registry'; +} from '@mongodb-js/compass-app-registry'; const AtlasAiServiceContext = createContext(null); diff --git a/packages/compass-generative-ai/src/store/atlas-ai-store.ts b/packages/compass-generative-ai/src/store/atlas-ai-store.ts index 25e7c9cb4be..56370e8f2f9 100644 --- a/packages/compass-generative-ai/src/store/atlas-ai-store.ts +++ b/packages/compass-generative-ai/src/store/atlas-ai-store.ts @@ -10,7 +10,7 @@ import type { AtlasAuthService } from '@mongodb-js/atlas-service/provider'; import type { AtlasAiService } from '../atlas-ai-service'; import type { PreferencesAccess } from 'compass-preferences-model'; import type { AtlasAiPluginProps } from '../components/plugin'; -import type { ActivateHelpers } from 'hadron-app-registry'; +import type { ActivateHelpers } from '@mongodb-js/compass-app-registry'; export let store: CompassGenerativeAIServiceStore; diff --git a/packages/compass-global-writes/package.json b/packages/compass-global-writes/package.json index 346a2825c83..0d8ccdfd726 100644 --- a/packages/compass-global-writes/package.json +++ b/packages/compass-global-writes/package.json @@ -11,7 +11,7 @@ "email": "compass@mongodb.com" }, "homepage": "https://github.com/mongodb-js/compass", - "version": "1.19.0", + "version": "1.20.0", "repository": { "type": "git", "url": "https://github.com/mongodb-js/compass.git" @@ -49,15 +49,15 @@ "reformat": "npm run eslint . -- --fix && npm run prettier -- --write ." }, "dependencies": { - "@mongodb-js/atlas-service": "^0.45.0", - "@mongodb-js/compass-collection": "^4.59.0", - "@mongodb-js/compass-components": "^1.38.1", - "@mongodb-js/compass-connections": "^1.60.0", + "@mongodb-js/atlas-service": "^0.46.0", + "@mongodb-js/compass-collection": "^4.60.0", + "@mongodb-js/compass-components": "^1.39.0", + "@mongodb-js/compass-connections": "^1.61.0", "@mongodb-js/compass-logging": "^1.7.2", "@mongodb-js/compass-telemetry": "^1.10.0", - "hadron-app-registry": "^9.4.11", + "@mongodb-js/compass-app-registry": "^9.4.11", "lodash": "^4.17.21", - "@mongodb-js/compass-field-store": "^9.35.0", + "@mongodb-js/compass-field-store": "^9.36.0", "mongodb-ns": "^2.4.2", "react": "^17.0.2", "react-redux": "^8.1.3", diff --git a/packages/compass-global-writes/src/index.ts b/packages/compass-global-writes/src/index.ts index a0cadcc0b76..2a02dadad29 100644 --- a/packages/compass-global-writes/src/index.ts +++ b/packages/compass-global-writes/src/index.ts @@ -1,5 +1,5 @@ import React from 'react'; -import { registerHadronPlugin } from 'hadron-app-registry'; +import { registerCompassPlugin } from '@mongodb-js/compass-app-registry'; import GlobalWrites from './components'; import { GlobalWritesTabTitle } from './plugin-title'; @@ -9,7 +9,7 @@ import { telemetryLocator } from '@mongodb-js/compass-telemetry/provider'; import { connectionInfoRefLocator } from '@mongodb-js/compass-connections/provider'; import { atlasServiceLocator } from '@mongodb-js/atlas-service/provider'; -const CompassGlobalWritesHadronPlugin = registerHadronPlugin( +const CompassGlobalWritesPluginProvider = registerCompassPlugin( { name: 'CompassGlobalWrites', component: function GlobalWritesProvider({ children }) { @@ -27,7 +27,7 @@ const CompassGlobalWritesHadronPlugin = registerHadronPlugin( export const CompassGlobalWritesPlugin = { name: 'GlobalWrites' as const, - provider: CompassGlobalWritesHadronPlugin, + provider: CompassGlobalWritesPluginProvider, content: GlobalWrites as React.FunctionComponent, header: GlobalWritesTabTitle as React.FunctionComponent, }; diff --git a/packages/compass-global-writes/src/store/index.ts b/packages/compass-global-writes/src/store/index.ts index c37217bc185..d390a63d392 100644 --- a/packages/compass-global-writes/src/store/index.ts +++ b/packages/compass-global-writes/src/store/index.ts @@ -1,6 +1,6 @@ import { createStore, applyMiddleware, type Action, type Store } from 'redux'; import thunk from 'redux-thunk'; -import type { ActivateHelpers } from 'hadron-app-registry'; +import type { ActivateHelpers } from '@mongodb-js/compass-app-registry'; import type { Logger } from '@mongodb-js/compass-logging'; import type { TrackFunction } from '@mongodb-js/compass-telemetry'; import type { ConnectionInfoRef } from '@mongodb-js/compass-connections/provider'; diff --git a/packages/compass-global-writes/tests/create-store.tsx b/packages/compass-global-writes/tests/create-store.tsx index 631a6d6d5d9..ad868e95b51 100644 --- a/packages/compass-global-writes/tests/create-store.tsx +++ b/packages/compass-global-writes/tests/create-store.tsx @@ -4,7 +4,7 @@ import type { GlobalWritesPluginServices, } from '../src/store'; import { activateGlobalWritesPlugin } from '../src/store'; -import { createActivateHelpers } from 'hadron-app-registry'; +import { createActivateHelpers } from '@mongodb-js/compass-app-registry'; import { createNoopLogger } from '@mongodb-js/compass-logging/provider'; import { createNoopTrack } from '@mongodb-js/compass-telemetry/provider'; import type { ConnectionInfo } from '@mongodb-js/compass-connections/provider'; diff --git a/packages/compass-import-export/package.json b/packages/compass-import-export/package.json index 58c6d475189..3dda1716afd 100644 --- a/packages/compass-import-export/package.json +++ b/packages/compass-import-export/package.json @@ -11,7 +11,7 @@ "email": "compass@mongodb.com" }, "homepage": "https://github.com/mongodb-js/compass", - "version": "7.59.0", + "version": "7.60.0", "repository": { "type": "git", "url": "https://github.com/mongodb-js/compass.git" @@ -49,18 +49,18 @@ }, "dependencies": { "@electron/remote": "^2.1.2", - "@mongodb-js/compass-components": "^1.38.1", - "@mongodb-js/compass-connections": "^1.60.0", - "@mongodb-js/compass-editor": "^0.40.2", + "@mongodb-js/compass-components": "^1.39.0", + "@mongodb-js/compass-connections": "^1.61.0", + "@mongodb-js/compass-editor": "^0.41.0", "@mongodb-js/compass-logging": "^1.7.2", "@mongodb-js/compass-telemetry": "^1.10.0", "@mongodb-js/compass-utils": "^0.9.2", - "@mongodb-js/compass-workspaces": "^0.41.0", + "@mongodb-js/compass-workspaces": "^0.42.0", "bson": "^6.10.3", - "compass-preferences-model": "^2.40.2", + "compass-preferences-model": "^2.41.0", "debug": "^4.3.4", "electron": "^36.4.0", - "hadron-app-registry": "^9.4.11", + "@mongodb-js/compass-app-registry": "^9.4.11", "hadron-document": "^8.8.12", "hadron-ipc": "^3.5.2", "lodash": "^4.17.21", diff --git a/packages/compass-import-export/src/index.ts b/packages/compass-import-export/src/index.ts index e1231263b6c..05e2fcd0d81 100644 --- a/packages/compass-import-export/src/index.ts +++ b/packages/compass-import-export/src/index.ts @@ -1,4 +1,4 @@ -import { registerHadronPlugin } from 'hadron-app-registry'; +import { registerCompassPlugin } from '@mongodb-js/compass-app-registry'; import ImportPluginComponent from './import-plugin'; import { activatePlugin as activateImportPlugin } from './stores/import-store'; import ExportPluginComponent from './export-plugin'; @@ -12,7 +12,7 @@ import { connectionsLocator } from '@mongodb-js/compass-connections/provider'; /** * The import plugin. */ -export const ImportPlugin = registerHadronPlugin( +export const ImportPlugin = registerCompassPlugin( { name: 'Import', component: ImportPluginComponent, @@ -30,7 +30,7 @@ export const ImportPlugin = registerHadronPlugin( /** * The export plugin. */ -export const ExportPlugin = registerHadronPlugin( +export const ExportPlugin = registerCompassPlugin( { name: 'Export', component: ExportPluginComponent, diff --git a/packages/compass-import-export/src/stores/export-store.spec.tsx b/packages/compass-import-export/src/stores/export-store.spec.tsx index 67a14fe459d..580c0b07e8b 100644 --- a/packages/compass-import-export/src/stores/export-store.spec.tsx +++ b/packages/compass-import-export/src/stores/export-store.spec.tsx @@ -1,4 +1,4 @@ -import type AppRegistry from 'hadron-app-registry'; +import type AppRegistry from '@mongodb-js/compass-app-registry'; import { expect } from 'chai'; import { createPluginTestHelpers, diff --git a/packages/compass-import-export/src/stores/export-store.ts b/packages/compass-import-export/src/stores/export-store.ts index 13e14232550..3c3208615f8 100644 --- a/packages/compass-import-export/src/stores/export-store.ts +++ b/packages/compass-import-export/src/stores/export-store.ts @@ -1,4 +1,4 @@ -import type AppRegistry from 'hadron-app-registry'; +import type AppRegistry from '@mongodb-js/compass-app-registry'; import type { Action, AnyAction } from 'redux'; import { createStore, applyMiddleware, combineReducers } from 'redux'; import type { ThunkAction } from 'redux-thunk'; @@ -11,7 +11,7 @@ import { } from '../modules/export'; import type { PreferencesAccess } from 'compass-preferences-model'; import type { Logger } from '@mongodb-js/compass-logging/provider'; -import type { ActivateHelpers } from 'hadron-app-registry'; +import type { ActivateHelpers } from '@mongodb-js/compass-app-registry'; import type { ConnectionsService } from '@mongodb-js/compass-connections/provider'; import type { TrackFunction } from '@mongodb-js/compass-telemetry'; diff --git a/packages/compass-import-export/src/stores/import-store.spec.tsx b/packages/compass-import-export/src/stores/import-store.spec.tsx index 4aff691c95e..ecbf29c0280 100644 --- a/packages/compass-import-export/src/stores/import-store.spec.tsx +++ b/packages/compass-import-export/src/stores/import-store.spec.tsx @@ -1,4 +1,4 @@ -import type AppRegistry from 'hadron-app-registry'; +import type AppRegistry from '@mongodb-js/compass-app-registry'; import { expect } from 'chai'; import { createPluginTestHelpers, diff --git a/packages/compass-import-export/src/stores/import-store.ts b/packages/compass-import-export/src/stores/import-store.ts index b617d30751a..4b885840986 100644 --- a/packages/compass-import-export/src/stores/import-store.ts +++ b/packages/compass-import-export/src/stores/import-store.ts @@ -1,4 +1,4 @@ -import type AppRegistry from 'hadron-app-registry'; +import type AppRegistry from '@mongodb-js/compass-app-registry'; import type { Action, AnyAction } from 'redux'; import { createStore, applyMiddleware, combineReducers } from 'redux'; import type { ThunkAction } from 'redux-thunk'; @@ -12,7 +12,7 @@ import { import type { WorkspacesService } from '@mongodb-js/compass-workspaces/provider'; import type { Logger } from '@mongodb-js/compass-logging/provider'; import type { ConnectionsService } from '@mongodb-js/compass-connections/provider'; -import type { ActivateHelpers } from 'hadron-app-registry'; +import type { ActivateHelpers } from '@mongodb-js/compass-app-registry'; import type { TrackFunction } from '@mongodb-js/compass-telemetry'; export type ImportPluginServices = { diff --git a/packages/compass-indexes/package.json b/packages/compass-indexes/package.json index 79b572dfce1..8611bcfbc5f 100644 --- a/packages/compass-indexes/package.json +++ b/packages/compass-indexes/package.json @@ -6,7 +6,7 @@ "email": "compass@mongodb.com" }, "private": true, - "version": "5.59.0", + "version": "5.60.0", "repository": { "type": "git", "url": "https://github.com/mongodb-js/compass.git" @@ -66,20 +66,20 @@ "xvfb-maybe": "^0.2.1" }, "dependencies": { - "@mongodb-js/atlas-service": "^0.45.0", - "@mongodb-js/compass-app-stores": "^7.46.0", - "@mongodb-js/compass-components": "^1.38.1", - "@mongodb-js/compass-connections": "^1.60.0", - "@mongodb-js/compass-editor": "^0.40.2", - "@mongodb-js/compass-field-store": "^9.35.0", + "@mongodb-js/atlas-service": "^0.46.0", + "@mongodb-js/compass-app-stores": "^7.47.0", + "@mongodb-js/compass-components": "^1.39.0", + "@mongodb-js/compass-connections": "^1.61.0", + "@mongodb-js/compass-editor": "^0.41.0", + "@mongodb-js/compass-field-store": "^9.36.0", "@mongodb-js/compass-logging": "^1.7.2", "@mongodb-js/compass-telemetry": "^1.10.0", - "@mongodb-js/compass-workspaces": "^0.41.0", + "@mongodb-js/compass-workspaces": "^0.42.0", "@mongodb-js/mongodb-constants": "^0.11.0", "@mongodb-js/shell-bson-parser": "^1.2.0", "bson": "^6.10.3", - "compass-preferences-model": "^2.40.2", - "hadron-app-registry": "^9.4.11", + "compass-preferences-model": "^2.41.0", + "@mongodb-js/compass-app-registry": "^9.4.11", "lodash": "^4.17.21", "mongodb": "^6.16.0", "mongodb-collection-model": "^5.29.2", diff --git a/packages/compass-indexes/src/components/create-index-form/create-index-form.tsx b/packages/compass-indexes/src/components/create-index-form/create-index-form.tsx index fbe8f45a32c..bdc9d8541e9 100644 --- a/packages/compass-indexes/src/components/create-index-form/create-index-form.tsx +++ b/packages/compass-indexes/src/components/create-index-form/create-index-form.tsx @@ -65,7 +65,6 @@ function CreateIndexForm({ onRemoveFieldClick, onTabClick, showIndexesGuidanceVariant, - query, }: CreateIndexFormProps) { const { id: connectionId } = useConnectionInfo(); const rollingIndexesFeatureEnabled = !!usePreference('enableRollingIndexes'); @@ -93,9 +92,6 @@ function CreateIndexForm({ showIndexesGuidanceVariant && currentTab === 'IndexFlow'; const showIndexesGuidanceQueryFlow = showIndexesGuidanceVariant && currentTab === 'QueryFlow'; - const [inputQuery, setInputQuery] = React.useState( - query ? JSON.stringify(query, null, 2) : '' - ); const { database: dbName, collection: collectionName } = toNS(namespace); @@ -180,9 +176,6 @@ function CreateIndexForm({ serverVersion={serverVersion} dbName={dbName} collectionName={collectionName} - initialQuery={query} - inputQuery={inputQuery} - setInputQuery={setInputQuery} /> )} diff --git a/packages/compass-indexes/src/components/create-index-form/index-flow-section.spec.tsx b/packages/compass-indexes/src/components/create-index-form/index-flow-section.spec.tsx index 8e4c9f15e22..283d10d49be 100644 --- a/packages/compass-indexes/src/components/create-index-form/index-flow-section.spec.tsx +++ b/packages/compass-indexes/src/components/create-index-form/index-flow-section.spec.tsx @@ -2,7 +2,7 @@ import React from 'react'; import { render, screen } from '@mongodb-js/testing-library-compass'; import IndexFlowSection from './index-flow-section'; import { expect } from 'chai'; -import type { Field } from '../../modules/create-index'; +import { ActionTypes, type Field } from '../../modules/create-index'; import { Provider } from 'react-redux'; import { setupStore } from '../../../test/setup-store'; @@ -85,7 +85,15 @@ describe('IndexFlowSection', () => { beforeEach(() => { renderComponent({ fields }); + screen.getByTestId('index-flow-section-covered-queries-button').click(); + store.dispatch({ + type: ActionTypes.FieldsChanged, + fields, + }); + store.dispatch({ + type: ActionTypes.CoveredQueriesFetched, + }); }); it('renders the covered queries examples', () => { @@ -133,7 +141,16 @@ describe('IndexFlowSection', () => { beforeEach(() => { renderComponent({ fields }); + screen.getByTestId('index-flow-section-covered-queries-button').click(); + + store.dispatch({ + type: ActionTypes.FieldsChanged, + fields, + }); + store.dispatch({ + type: ActionTypes.CoveredQueriesFetched, + }); }); it('renders the covered queries examples', () => { @@ -179,7 +196,15 @@ describe('IndexFlowSection', () => { beforeEach(() => { renderComponent({ fields }); + screen.getByTestId('index-flow-section-covered-queries-button').click(); + store.dispatch({ + type: ActionTypes.FieldsChanged, + fields, + }); + store.dispatch({ + type: ActionTypes.CoveredQueriesFetched, + }); }); it('renders the covered queries examples', () => { @@ -208,7 +233,15 @@ describe('IndexFlowSection', () => { beforeEach(() => { renderComponent({ fields }); + screen.getByTestId('index-flow-section-covered-queries-button').click(); + store.dispatch({ + type: ActionTypes.FieldsChanged, + fields, + }); + store.dispatch({ + type: ActionTypes.CoveredQueriesFetched, + }); }); it('renders the covered queries examples', () => { diff --git a/packages/compass-indexes/src/components/create-index-form/index-flow-section.tsx b/packages/compass-indexes/src/components/create-index-form/index-flow-section.tsx index 94e04337a16..1391fc01dbe 100644 --- a/packages/compass-indexes/src/components/create-index-form/index-flow-section.tsx +++ b/packages/compass-indexes/src/components/create-index-form/index-flow-section.tsx @@ -13,10 +13,10 @@ import { Tooltip, useDarkMode, } from '@mongodb-js/compass-components'; -import React, { useState, useCallback, useEffect } from 'react'; +import React, { useState, useCallback } from 'react'; import { - errorCleared, errorEncountered, + fetchCoveredQueries, type Field, } from '../../modules/create-index'; import MDBCodeViewer from './mdb-code-viewer'; @@ -24,6 +24,7 @@ import { areAllFieldsFilledIn } from '../../utils/create-index-modal-validation' import { connect } from 'react-redux'; import type { TrackFunction } from '@mongodb-js/compass-telemetry/provider'; import { useTelemetry } from '@mongodb-js/compass-telemetry/provider'; +import type { RootState } from '../../modules'; const flexContainerStyles = css({ display: 'flex', @@ -106,13 +107,18 @@ export type IndexFlowSectionProps = { dbName: string; collectionName: string; onErrorEncountered: (error: string) => void; - onErrorCleared: () => void; + onCoveredQueriesFetched: () => void; + coveredQueriesArr: Array> | null; + hasIndexFieldChanges: boolean; }; -const generateCoveredQueries = ( - coveredQueriesArr: Array>, +export const generateCoveredQueries = ( + coveredQueriesArr: Array> | null, track: TrackFunction ) => { + if (!coveredQueriesArr) { + return; + } const rows = []; for (let i = 0; i < coveredQueriesArr.length; i++) { const currentRow = Object.assign({}, ...coveredQueriesArr.slice(0, i + 1)); @@ -135,9 +141,12 @@ const generateCoveredQueries = ( return <>{rows}; }; -const generateOptimalQueries = ( - coveredQueriesArr: Array> +export const generateOptimalQueries = ( + coveredQueriesArr: Array> | null ) => { + if (!coveredQueriesArr) { + return; + } const numOfFields = coveredQueriesArr.length; // Do not show for 1 field or less @@ -187,18 +196,25 @@ const generateOptimalQueries = ( ); }; +export const generateCoveredQueriesArr = (fields: Field[]) => { + return fields.map((field, index) => { + return { [field.name]: index + 1 }; + }); +}; + const IndexFlowSection = ({ createIndexFieldsComponent, fields, dbName, collectionName, onErrorEncountered, - onErrorCleared, + onCoveredQueriesFetched, + coveredQueriesArr, + hasIndexFieldChanges, }: IndexFlowSectionProps) => { const darkMode = useDarkMode(); const [isCodeEquivalentToggleChecked, setIsCodeEquivalentToggleChecked] = useState(false); - const [hasFieldChanges, setHasFieldChanges] = useState(false); const hasUnsupportedQueryTypes = fields.some((field) => { return field.type === '2dsphere' || field.type === 'text'; @@ -208,7 +224,7 @@ const IndexFlowSection = ({ const isCoveredQueriesButtonDisabled = !areAllFieldsFilledIn(fields) || hasUnsupportedQueryTypes || - !hasFieldChanges; + !hasIndexFieldChanges; const indexNameTypeMap = fields.reduce>( (accumulator, currentValue) => { @@ -220,45 +236,21 @@ const IndexFlowSection = ({ {} ); - const [coveredQueriesObj, setCoveredQueriesObj] = useState<{ - coveredQueries: JSX.Element; - optimalQueries: string | JSX.Element; - showCoveredQueries: boolean; - }>({ - coveredQueries: <>, - optimalQueries: '', - showCoveredQueries: false, - }); - const onCoveredQueriesButtonClick = useCallback(() => { - const coveredQueriesArr = fields.map((field, index) => { - return { [field.name]: index + 1 }; - }); - track('Covered Queries Button Clicked', { context: 'Create Index Modal', }); try { - setCoveredQueriesObj({ - coveredQueries: generateCoveredQueries(coveredQueriesArr, track), - optimalQueries: generateOptimalQueries(coveredQueriesArr), - showCoveredQueries: true, - }); + onCoveredQueriesFetched(); } catch (e) { onErrorEncountered(e instanceof Error ? e.message : String(e)); } + }, [onCoveredQueriesFetched, onErrorEncountered, track]); - setHasFieldChanges(false); - }, [fields, onErrorEncountered, track]); - - useEffect(() => { - setHasFieldChanges(true); - onErrorCleared(); - }, [fields, onErrorCleared]); - - const { coveredQueries, optimalQueries, showCoveredQueries } = - coveredQueriesObj; + const coveredQueries = generateCoveredQueries(coveredQueriesArr, track); + const optimalQueries = generateOptimalQueries(coveredQueriesArr); + const showCoveredQueries = coveredQueriesArr !== null; return (
@@ -422,13 +414,17 @@ const IndexFlowSection = ({ ); }; -const mapState = () => { - return {}; +const mapState = ({ createIndex }: RootState) => { + const { coveredQueriesArr, hasIndexFieldChanges } = createIndex; + return { + coveredQueriesArr, + hasIndexFieldChanges, + }; }; const mapDispatch = { onErrorEncountered: errorEncountered, - onErrorCleared: errorCleared, + onCoveredQueriesFetched: fetchCoveredQueries, }; export default connect(mapState, mapDispatch)(IndexFlowSection); diff --git a/packages/compass-indexes/src/components/create-index-form/query-flow-section.spec.tsx b/packages/compass-indexes/src/components/create-index-form/query-flow-section.spec.tsx index 8957cc87b63..d151f7b0520 100644 --- a/packages/compass-indexes/src/components/create-index-form/query-flow-section.spec.tsx +++ b/packages/compass-indexes/src/components/create-index-form/query-flow-section.spec.tsx @@ -18,9 +18,6 @@ describe('QueryFlowSection', () => { serverVersion="5.0.0" dbName={dbName} collectionName={collectionName} - initialQuery={null} - inputQuery={''} - setInputQuery={() => {}} /> ); diff --git a/packages/compass-indexes/src/components/create-index-form/query-flow-section.tsx b/packages/compass-indexes/src/components/create-index-form/query-flow-section.tsx index 0d5dfd4d7d1..f07081d3d77 100644 --- a/packages/compass-indexes/src/components/create-index-form/query-flow-section.tsx +++ b/packages/compass-indexes/src/components/create-index-form/query-flow-section.tsx @@ -8,8 +8,7 @@ import { ParagraphSkeleton, useDarkMode, } from '@mongodb-js/compass-components'; -import type { Document } from 'mongodb'; -import React, { useMemo, useCallback, useEffect } from 'react'; +import React, { useMemo, useCallback } from 'react'; import { css, spacing } from '@mongodb-js/compass-components'; import { CodemirrorMultilineEditor, @@ -20,8 +19,10 @@ import type { RootState } from '../../modules'; import { fetchIndexSuggestions } from '../../modules/create-index'; import type { IndexSuggestionState, + QueryUpdatedProps, SuggestedIndexFetchedProps, } from '../../modules/create-index'; +import { queryUpdated } from '../../modules/create-index'; import { connect } from 'react-redux'; import { parseFilter } from 'mongodb-query-parser'; import { useTelemetry } from '@mongodb-js/compass-telemetry/provider'; @@ -105,30 +106,27 @@ const QueryFlowSection = ({ indexSuggestions, fetchingSuggestionsState, initialQuery, - inputQuery, - setInputQuery, + query, + hasQueryChanges, + onQueryUpdated, }: { schemaFields: { name: string; description?: string }[]; serverVersion: string; dbName: string; collectionName: string; onSuggestedIndexButtonClick: ({ - dbName, - collectionName, - inputQuery, + query, }: SuggestedIndexFetchedProps) => Promise; indexSuggestions: Record | null; fetchingSuggestionsState: IndexSuggestionState; - initialQuery: Document | null; - inputQuery: string; - setInputQuery: (query: string) => void; + initialQuery: string | null; + query: string; + hasQueryChanges: boolean; + onQueryUpdated: ({ query }: QueryUpdatedProps) => void; }) => { const track = useTelemetry(); const darkMode = useDarkMode(); - const [hasNewChanges, setHasNewChanges] = React.useState( - initialQuery !== null - ); const [isShowSuggestionsButtonDisabled, setIsShowSuggestionsButtonDisabled] = React.useState(true); @@ -149,15 +147,12 @@ const QueryFlowSection = ({ }); const generateSuggestedIndexes = useCallback(() => { - const sanitizedInputQuery = inputQuery.trim(); + const sanitizedInputQuery = query.trim(); void onSuggestedIndexButtonClick({ - dbName, - collectionName, - inputQuery: sanitizedInputQuery, + query: sanitizedInputQuery, }); - setHasNewChanges(false); - }, [inputQuery, dbName, collectionName, onSuggestedIndexButtonClick]); + }, [query, onSuggestedIndexButtonClick]); const handleSuggestedIndexButtonClick = () => { generateSuggestedIndexes(); @@ -166,20 +161,21 @@ const QueryFlowSection = ({ }); }; - const handleQueryInputChange = useCallback((text: string) => { - setInputQuery(text); - setHasNewChanges(true); - }, []); + const handleQueryInputChange = useCallback( + (text: string) => { + onQueryUpdated({ query: text }); + }, + [onQueryUpdated] + ); const isFetchingIndexSuggestions = fetchingSuggestionsState === 'fetching'; - // Validate query upon typing useMemo(() => { - let _isShowSuggestionsButtonDisabled = !hasNewChanges; + let _isShowSuggestionsButtonDisabled = !hasQueryChanges; try { - parseFilter(inputQuery); + parseFilter(query); - if (!inputQuery.startsWith('{') || !inputQuery.endsWith('}')) { + if (!query.startsWith('{') || !query.endsWith('}')) { _isShowSuggestionsButtonDisabled = true; } } catch { @@ -187,13 +183,7 @@ const QueryFlowSection = ({ } finally { setIsShowSuggestionsButtonDisabled(_isShowSuggestionsButtonDisabled); } - }, [hasNewChanges, inputQuery]); - - useEffect(() => { - if (initialQuery !== null) { - generateSuggestedIndexes(); - } - }, [initialQuery]); + }, [hasQueryChanges, query]); return ( <> @@ -221,7 +211,7 @@ const QueryFlowSection = ({ showAnnotationsGutter={false} copyable={false} formattable={false} - text={inputQuery} + text={query} onChangeText={(text) => handleQueryInputChange(text)} placeholder="Type a query: { field: 'value' }" completer={completer} @@ -282,17 +272,27 @@ const QueryFlowSection = ({ }; const mapState = ({ createIndex }: RootState) => { - const { indexSuggestions, sampleDocs, fetchingSuggestionsState } = - createIndex; + const { + indexSuggestions, + sampleDocs, + fetchingSuggestionsState, + query, + initialQuery, + hasQueryChanges, + } = createIndex; return { indexSuggestions, sampleDocs, fetchingSuggestionsState, + query, + initialQuery, + hasQueryChanges, }; }; const mapDispatch = { onSuggestedIndexButtonClick: fetchIndexSuggestions, + onQueryUpdated: queryUpdated, }; export default connect(mapState, mapDispatch)(QueryFlowSection); diff --git a/packages/compass-indexes/src/components/create-index-modal/create-index-modal.tsx b/packages/compass-indexes/src/components/create-index-modal/create-index-modal.tsx index fc9a8842cd5..b49fe7b8ae7 100644 --- a/packages/compass-indexes/src/components/create-index-modal/create-index-modal.tsx +++ b/packages/compass-indexes/src/components/create-index-modal/create-index-modal.tsx @@ -30,14 +30,12 @@ import { import { useConnectionInfoRef } from '@mongodb-js/compass-connections/provider'; import { usePreference } from 'compass-preferences-model/provider'; import CreateIndexModalHeader from './create-index-modal-header'; -import type { Document } from 'mongodb'; type CreateIndexModalProps = React.ComponentProps & { isVisible: boolean; namespace: string; error: string | null; currentTab: Tab; - query: Document | null; onErrorBannerCloseClick: () => void; onCreateIndexClick: () => void; onCancelCreateIndexClick: () => void; @@ -52,7 +50,6 @@ function CreateIndexModal({ onErrorBannerCloseClick, onCreateIndexClick, onCancelCreateIndexClick, - query, ...props }: CreateIndexModalProps) { const connectionInfoRef = useConnectionInfoRef(); @@ -117,7 +114,6 @@ function CreateIndexModal({ namespace={namespace} showIndexesGuidanceVariant={showIndexesGuidanceVariant} currentTab={currentTab} - query={query} /> @@ -134,7 +130,7 @@ function CreateIndexModal({ } const mapState = ({ namespace, serverVersion, createIndex }: RootState) => { - const { fields, error, isVisible, currentTab, query } = createIndex; + const { fields, error, isVisible, currentTab } = createIndex; return { fields, error, @@ -142,7 +138,6 @@ const mapState = ({ namespace, serverVersion, createIndex }: RootState) => { namespace, serverVersion, currentTab, - query, }; }; diff --git a/packages/compass-indexes/src/components/indexes/indexes.tsx b/packages/compass-indexes/src/components/indexes/indexes.tsx index 285f90aa86d..0e512e13ce2 100644 --- a/packages/compass-indexes/src/components/indexes/indexes.tsx +++ b/packages/compass-indexes/src/components/indexes/indexes.tsx @@ -181,7 +181,7 @@ export function Indexes({ - +
); } diff --git a/packages/compass-indexes/src/index.spec.tsx b/packages/compass-indexes/src/index.spec.tsx index 49fc9210b31..e65cf9d14e2 100644 --- a/packages/compass-indexes/src/index.spec.tsx +++ b/packages/compass-indexes/src/index.spec.tsx @@ -2,7 +2,7 @@ import React from 'react'; import Sinon from 'sinon'; import { CompassIndexesPlugin as CompassIndexesSubtab, - CompassIndexesHadronPlugin, + CompassIndexesPluginProvider, } from './index'; import { createDefaultConnectionInfo, @@ -35,7 +35,7 @@ describe('CompassIndexesPlugin', function () { }; const renderHelpers = createPluginTestHelpers( - CompassIndexesHadronPlugin.withMockServices({ + CompassIndexesPluginProvider.withMockServices({ dataService, atlasService, instance: { diff --git a/packages/compass-indexes/src/index.ts b/packages/compass-indexes/src/index.ts index 618264908c1..45536723d98 100644 --- a/packages/compass-indexes/src/index.ts +++ b/packages/compass-indexes/src/index.ts @@ -1,5 +1,5 @@ import React from 'react'; -import { registerHadronPlugin } from 'hadron-app-registry'; +import { registerCompassPlugin } from '@mongodb-js/compass-app-registry'; import { activateIndexesPlugin, type IndexesDataServiceProps, @@ -20,7 +20,7 @@ import { IndexesTabTitle } from './plugin-title'; import { atlasServiceLocator } from '@mongodb-js/atlas-service/provider'; import { preferencesLocator } from 'compass-preferences-model/provider'; -export const CompassIndexesHadronPlugin = registerHadronPlugin( +export const CompassIndexesPluginProvider = registerCompassPlugin( { name: 'CompassIndexes', component: function IndexesProvider({ children }) { @@ -43,7 +43,7 @@ export const CompassIndexesHadronPlugin = registerHadronPlugin( export const CompassIndexesPlugin = { name: 'Indexes' as const, - provider: CompassIndexesHadronPlugin, + provider: CompassIndexesPluginProvider, content: Indexes as React.FunctionComponent, header: IndexesTabTitle as React.FunctionComponent, }; diff --git a/packages/compass-indexes/src/modules/create-index.spec.ts b/packages/compass-indexes/src/modules/create-index.spec.ts index ce88ec3ec2c..b0cb75a9c27 100644 --- a/packages/compass-indexes/src/modules/create-index.spec.ts +++ b/packages/compass-indexes/src/modules/create-index.spec.ts @@ -209,25 +209,25 @@ describe('create-index module', function () { describe('createIndexOpened', function () { const query = EJSON.serialize({}); it('sets isVisible=true', function () { - store.dispatch(createIndexOpened()); + void store.dispatch(createIndexOpened()); expect(store.getState().createIndex.isVisible).to.equal(true); }); it('sets isVisible=true with a query', function () { - store.dispatch(createIndexOpened({ query })); + void store.dispatch(createIndexOpened({ query })); expect(store.getState().createIndex.isVisible).to.equal(true); }); it('sets currentTab=IndexFlow if no query is provided', function () { - store.dispatch(createIndexOpened()); + void store.dispatch(createIndexOpened()); expect(store.getState().createIndex.currentTab).to.equal('IndexFlow'); }); it('sets currentTab=QueryFlow if a query is provided', function () { - store.dispatch(createIndexOpened({ query })); + void store.dispatch(createIndexOpened({ query })); expect(store.getState().createIndex.currentTab).to.equal('QueryFlow'); }); diff --git a/packages/compass-indexes/src/modules/create-index.tsx b/packages/compass-indexes/src/modules/create-index.tsx index 4e239d7f8e0..061c567150e 100644 --- a/packages/compass-indexes/src/modules/create-index.tsx +++ b/packages/compass-indexes/src/modules/create-index.tsx @@ -10,6 +10,7 @@ import type { IndexesThunkAction, RootState } from '.'; import { createRegularIndex } from './regular-indexes'; import * as mql from 'mongodb-mql-engines'; import _parseShellBSON, { ParseMode } from '@mongodb-js/shell-bson-parser'; +import toNS from 'mongodb-ns'; export enum ActionTypes { FieldAdded = 'compass-indexes/create-index/fields/field-added', @@ -30,8 +31,13 @@ export enum ActionTypes { TabUpdated = 'compass-indexes/create-index/tab-updated', + // Query Flow SuggestedIndexesRequested = 'compass-indexes/create-index/suggested-indexes-requested', SuggestedIndexesFetched = 'compass-indexes/create-index/suggested-indexes-fetched', + QueryUpdatedAction = 'compass-indexes/create-index/clear-has-query-changes', + + // Index Flow + CoveredQueriesFetched = 'compass-indexes/create-index/covered-queries-fetched', } // fields @@ -76,7 +82,7 @@ type ErrorClearedAction = { export type CreateIndexOpenedAction = { type: ActionTypes.CreateIndexOpened; - query?: Document; + initialQuery?: Document; }; type CreateIndexClosedAction = { @@ -313,7 +319,19 @@ export type State = { sampleDocs: Array | null; // base query to be used for query flow index creation - query: Document | null; + query: string; + + // the initial query that user had prefilled from the insights nudge in the documents tab + initialQuery: string; + + // to determine whether there has been new query changes since user last pressed the button + hasQueryChanges: boolean; + + // covered queries array for the index flow to keep track of what the user last sees after pressing the covered queries button + coveredQueriesArr: Array> | null; + + // to determine whether there has been new index field changes since user last pressed the button + hasIndexFieldChanges: boolean; }; export const INITIAL_STATE: State = { @@ -323,10 +341,18 @@ export const INITIAL_STATE: State = { fields: INITIAL_FIELDS_STATE, options: INITIAL_OPTIONS_STATE, currentTab: 'IndexFlow', + + // Query flow fetchingSuggestionsState: 'initial', indexSuggestions: null, sampleDocs: null, - query: null, + query: '', + initialQuery: '', + hasQueryChanges: false, + + // Index flow + coveredQueriesArr: null, + hasIndexFieldChanges: false, }; function getInitialState(): State { @@ -338,10 +364,27 @@ function getInitialState(): State { //------- -export const createIndexOpened = (query?: Document) => ({ - type: ActionTypes.CreateIndexOpened, - query, -}); +export const createIndexOpened = ( + initialQuery?: Document +): IndexesThunkAction< + Promise, + SuggestedIndexFetchedAction | CreateIndexOpenedAction +> => { + return async (dispatch) => { + dispatch({ + type: ActionTypes.CreateIndexOpened, + initialQuery, + }); + + if (initialQuery) { + await dispatch( + fetchIndexSuggestions({ + query: JSON.stringify(initialQuery, null, 2) || '', + }) + ); + } + }; +}; export const createIndexClosed = () => ({ type: ActionTypes.CreateIndexClosed, @@ -373,20 +416,25 @@ export type SuggestedIndexFetchedAction = { }; export type SuggestedIndexFetchedProps = { - dbName: string; - collectionName: string; - inputQuery: string; + query: string; +}; + +export type CoveredQueriesFetchedAction = { + type: ActionTypes.CoveredQueriesFetched; +}; + +export type QueryUpdatedProps = { + query: string; +}; + +export type QueryUpdatedAction = { + type: ActionTypes.QueryUpdatedAction; + query: string; }; export const fetchIndexSuggestions = ({ - dbName, - collectionName, - inputQuery, -}: { - dbName: string; - collectionName: string; - inputQuery: string; -}): IndexesThunkAction< + query, +}: SuggestedIndexFetchedProps): IndexesThunkAction< Promise, SuggestedIndexFetchedAction | SuggestedIndexesRequestedAction > => { @@ -394,12 +442,11 @@ export const fetchIndexSuggestions = ({ dispatch({ type: ActionTypes.SuggestedIndexesRequested, }); - const namespace = `${dbName}.${collectionName}`; + const namespace = getState().namespace; // Get sample documents from state if it's already there, otherwise fetch it let sampleDocuments: Array | null = getState().createIndex.sampleDocs || null; - // If it's null, that means it has not been fetched before if (sampleDocuments === null) { try { @@ -426,16 +473,17 @@ export const fetchIndexSuggestions = ({ // Analyze namespace and fetch suggestions try { + const { database, collection } = toNS(getState().namespace); const analyzedNamespace = mql.analyzeNamespace( - { database: dbName, collection: collectionName }, + { database, collection }, sampleDocuments ); - const query = mql.parseQuery( - _parseShellBSON(inputQuery, { mode: ParseMode.Loose }), + const parsedQuery = mql.parseQuery( + _parseShellBSON(query, { mode: ParseMode.Loose }), analyzedNamespace ); - const results = await mql.suggestIndex([query]); + const results = await mql.suggestIndex([parsedQuery]); const indexSuggestions = results?.index; if ( @@ -461,6 +509,17 @@ export const fetchIndexSuggestions = ({ }; }; +export const fetchCoveredQueries = (): CoveredQueriesFetchedAction => ({ + type: ActionTypes.CoveredQueriesFetched, +}); + +export const queryUpdated = ({ + query, +}: QueryUpdatedProps): QueryUpdatedAction => ({ + type: ActionTypes.QueryUpdatedAction, + query, +}); + function isEmptyValue(value: unknown) { if (value === '') { return true; @@ -639,6 +698,8 @@ const reducer: Reducer = (state = INITIAL_STATE, action) => { return { ...state, fields: [...state.fields, { name: '', type: '' }], + hasIndexFieldChanges: true, + error: null, }; } @@ -648,6 +709,8 @@ const reducer: Reducer = (state = INITIAL_STATE, action) => { return { ...state, fields, + hasIndexFieldChanges: true, + error: null, }; } @@ -661,6 +724,8 @@ const reducer: Reducer = (state = INITIAL_STATE, action) => { return { ...state, fields, + hasIndexFieldChanges: true, + error: null, }; } @@ -668,6 +733,8 @@ const reducer: Reducer = (state = INITIAL_STATE, action) => { return { ...state, fields: action.fields, + hasIndexFieldChanges: true, + error: null, }; } @@ -705,11 +772,17 @@ const reducer: Reducer = (state = INITIAL_STATE, action) => { if ( isAction(action, ActionTypes.CreateIndexOpened) ) { + const parsedInitialQuery = action.initialQuery + ? JSON.stringify(action.initialQuery, null, 2) + : ''; + return { ...getInitialState(), isVisible: true, - query: action.query ?? null, - currentTab: action.query ? 'QueryFlow' : 'IndexFlow', + // get it from the current query or initial query from insights nudge + query: state.query || parsedInitialQuery, + initialQuery: parsedInitialQuery, + currentTab: action.initialQuery ? 'QueryFlow' : 'IndexFlow', }; } @@ -733,6 +806,7 @@ const reducer: Reducer = (state = INITIAL_STATE, action) => { return { ...state, isVisible: false, + query: '', }; } @@ -781,6 +855,31 @@ const reducer: Reducer = (state = INITIAL_STATE, action) => { error: action.error, indexSuggestions: action.indexSuggestions, sampleDocs: action.sampleDocs, + hasQueryChanges: false, + }; + } + + if ( + isAction( + action, + ActionTypes.CoveredQueriesFetched + ) + ) { + return { + ...state, + coveredQueriesArr: state.fields.map((field, index) => { + return { [field.name]: index + 1 }; + }), + hasIndexFieldChanges: false, + }; + } + + if (isAction(action, ActionTypes.QueryUpdatedAction)) { + return { + ...state, + query: action.query, + hasQueryChanges: true, + error: null, }; } diff --git a/packages/compass-indexes/src/modules/index.ts b/packages/compass-indexes/src/modules/index.ts index 079984a1473..e2b6d34e56d 100644 --- a/packages/compass-indexes/src/modules/index.ts +++ b/packages/compass-indexes/src/modules/index.ts @@ -1,6 +1,6 @@ import { combineReducers } from 'redux'; import type { Action, AnyAction } from 'redux'; -import type AppRegistry from 'hadron-app-registry'; +import type AppRegistry from '@mongodb-js/compass-app-registry'; import isWritable from './is-writable'; import indexView from './index-view'; import isReadonlyView from './is-readonly-view'; diff --git a/packages/compass-indexes/src/stores/store.spec.ts b/packages/compass-indexes/src/stores/store.spec.ts index b2dced9256b..4dc569269a7 100644 --- a/packages/compass-indexes/src/stores/store.spec.ts +++ b/packages/compass-indexes/src/stores/store.spec.ts @@ -1,5 +1,5 @@ import { EventEmitter } from 'events'; -import AppRegistry from 'hadron-app-registry'; +import AppRegistry from '@mongodb-js/compass-app-registry'; import { expect } from 'chai'; import { type IndexesStore } from './store'; import { setupStore } from '../../test/setup-store'; diff --git a/packages/compass-indexes/src/stores/store.ts b/packages/compass-indexes/src/stores/store.ts index ddfd17d042b..dcb4ea04588 100644 --- a/packages/compass-indexes/src/stores/store.ts +++ b/packages/compass-indexes/src/stores/store.ts @@ -17,8 +17,8 @@ import { stopPollingSearchIndexes, } from '../modules/search-indexes'; import type { DataService } from 'mongodb-data-service'; -import type AppRegistry from 'hadron-app-registry'; -import type { ActivateHelpers } from 'hadron-app-registry'; +import type AppRegistry from '@mongodb-js/compass-app-registry'; +import type { ActivateHelpers } from '@mongodb-js/compass-app-registry'; import type { Collection, MongoDBInstance, @@ -132,7 +132,7 @@ export function activateIndexesPlugin( localAppRegistry, 'open-create-index-modal', (openCreateModalRequest?: { query: Document }) => { - store.dispatch(createIndexOpened(openCreateModalRequest?.query)); + void store.dispatch(createIndexOpened(openCreateModalRequest?.query)); } ); diff --git a/packages/compass-indexes/test/setup-store.ts b/packages/compass-indexes/test/setup-store.ts index 1d935f40cd8..e0034988b0b 100644 --- a/packages/compass-indexes/test/setup-store.ts +++ b/packages/compass-indexes/test/setup-store.ts @@ -1,6 +1,6 @@ import { EventEmitter } from 'events'; import Sinon from 'sinon'; -import type AppRegistry from 'hadron-app-registry'; +import type AppRegistry from '@mongodb-js/compass-app-registry'; import type { IndexesDataService, IndexesPluginOptions, @@ -8,7 +8,7 @@ import type { IndexesStore, } from '../src/stores/store'; import { activateIndexesPlugin } from '../src/stores/store'; -import { createActivateHelpers } from 'hadron-app-registry'; +import { createActivateHelpers } from '@mongodb-js/compass-app-registry'; import { createNoopLogger } from '@mongodb-js/compass-logging/provider'; import { createNoopTrack } from '@mongodb-js/compass-telemetry/provider'; import type { ConnectionInfoRef } from '@mongodb-js/compass-connections/provider'; diff --git a/packages/compass-intercom/package.json b/packages/compass-intercom/package.json index 5f50d5631bf..3e582a546c9 100644 --- a/packages/compass-intercom/package.json +++ b/packages/compass-intercom/package.json @@ -13,7 +13,7 @@ "email": "compass@mongodb.com" }, "homepage": "https://github.com/mongodb-js/compass", - "version": "0.24.2", + "version": "0.25.0", "repository": { "type": "git", "url": "https://github.com/mongodb-js/compass.git" @@ -65,7 +65,7 @@ "typescript": "^5.0.4" }, "dependencies": { - "compass-preferences-model": "^2.40.2", + "compass-preferences-model": "^2.41.0", "@mongodb-js/compass-logging": "^1.7.2" } } diff --git a/packages/compass-intercom/src/setup-intercom.spec.ts b/packages/compass-intercom/src/setup-intercom.spec.ts index 8e0133ad280..2a69c55063e 100644 --- a/packages/compass-intercom/src/setup-intercom.spec.ts +++ b/packages/compass-intercom/src/setup-intercom.spec.ts @@ -2,7 +2,7 @@ import type { SinonStub } from 'sinon'; import sinon from 'sinon'; -import { setupIntercom } from './setup-intercom'; +import { setupIntercom, resetIntercomAllowedCache } from './setup-intercom'; import { expect } from 'chai'; import type { IntercomScript } from './intercom-script'; import type { PreferencesAccess } from 'compass-preferences-model'; @@ -11,6 +11,36 @@ import { type User, } from 'compass-preferences-model'; +// Picking something which won't be blocked by CORS +const FAKE_HADRON_AUTO_UPDATE_ENDPOINT = 'https://compass.mongodb.com'; + +function createMockFetch({ + integrations, +}: { + integrations: Record; +}): typeof globalThis.fetch { + return (url) => { + if (typeof url !== 'string') { + throw new Error('Expected url to be a string'); + } + if (url.startsWith(FAKE_HADRON_AUTO_UPDATE_ENDPOINT)) { + if (url === `${FAKE_HADRON_AUTO_UPDATE_ENDPOINT}/api/v2/integrations`) { + return Promise.resolve({ + ok: true, + json() { + return Promise.resolve(integrations); + }, + } as Response); + } + } else if (url === 'https://widget.intercom.io/widget/appid123') { + // NOTE: we use 301 since intercom will redirects + // to the actual location of the widget script + return Promise.resolve({ status: 301 } as Response); + } + throw new Error(`Unexpected URL called on the fake update server: ${url}`); + }; +} + const mockUser: User = { id: 'user-123', createdAt: new Date(1649432549945), @@ -19,7 +49,10 @@ const mockUser: User = { describe('setupIntercom', function () { let backupEnv: Partial; - let fetchMock: SinonStub; + let fetchMock: SinonStub< + Parameters, + ReturnType + >; let preferences: PreferencesAccess; async function testRunSetupIntercom() { @@ -36,6 +69,7 @@ describe('setupIntercom', function () { beforeEach(async function () { backupEnv = { + HADRON_AUTO_UPDATE_ENDPOINT: process.env.HADRON_AUTO_UPDATE_ENDPOINT, HADRON_METRICS_INTERCOM_APP_ID: process.env.HADRON_METRICS_INTERCOM_APP_ID, HADRON_PRODUCT_NAME: process.env.HADRON_PRODUCT_NAME, @@ -43,15 +77,12 @@ describe('setupIntercom', function () { NODE_ENV: process.env.NODE_ENV, }; + process.env.HADRON_AUTO_UPDATE_ENDPOINT = FAKE_HADRON_AUTO_UPDATE_ENDPOINT; process.env.HADRON_PRODUCT_NAME = 'My App Name' as any; process.env.HADRON_APP_VERSION = 'v0.0.0-test.123'; process.env.NODE_ENV = 'test'; process.env.HADRON_METRICS_INTERCOM_APP_ID = 'appid123'; - fetchMock = sinon.stub(); - window.fetch = fetchMock; - // NOTE: we use 301 since intercom will redirects - // to the actual location of the widget script - fetchMock.resolves({ status: 301 } as Response); + fetchMock = sinon.stub(globalThis, 'fetch'); preferences = await createSandboxFromDefaultPreferences(); await preferences.savePreferences({ enableFeedbackPanel: true, @@ -61,16 +92,23 @@ describe('setupIntercom', function () { }); afterEach(function () { + process.env.HADRON_AUTO_UPDATE_ENDPOINT = + backupEnv.HADRON_AUTO_UPDATE_ENDPOINT; process.env.HADRON_METRICS_INTERCOM_APP_ID = backupEnv.HADRON_METRICS_INTERCOM_APP_ID; process.env.HADRON_PRODUCT_NAME = backupEnv.HADRON_PRODUCT_NAME as any; process.env.HADRON_APP_VERSION = backupEnv.HADRON_APP_VERSION as any; process.env.NODE_ENV = backupEnv.NODE_ENV; - fetchMock.reset(); + fetchMock.restore(); + resetIntercomAllowedCache(); }); describe('when it can be enabled', function () { it('calls intercomScript.load when feedback gets enabled and intercomScript.unload when feedback gets disabled', async function () { + fetchMock.callsFake( + createMockFetch({ integrations: { intercom: true } }) + ); + await preferences.savePreferences({ enableFeedbackPanel: true, }); @@ -100,6 +138,19 @@ describe('setupIntercom', function () { expect(intercomScript.load).not.to.have.been.called; expect(intercomScript.unload).to.have.been.called; }); + + it('calls intercomScript.unload when the update server disables the integration', async function () { + fetchMock.callsFake( + createMockFetch({ integrations: { intercom: false } }) + ); + + await preferences.savePreferences({ + enableFeedbackPanel: true, + }); + const { intercomScript } = await testRunSetupIntercom(); + expect(intercomScript.load).not.to.have.been.called; + expect(intercomScript.unload).to.have.been.called; + }); }); describe('when cannot be enabled', function () { diff --git a/packages/compass-intercom/src/setup-intercom.ts b/packages/compass-intercom/src/setup-intercom.ts index ddc78a213d1..7d537b4fa93 100644 --- a/packages/compass-intercom/src/setup-intercom.ts +++ b/packages/compass-intercom/src/setup-intercom.ts @@ -36,14 +36,26 @@ export async function setupIntercom( app_stage: process.env.NODE_ENV, }; - if (enableFeedbackPanel) { + async function toggleEnableFeedbackPanel(enableFeedbackPanel: boolean) { + if (enableFeedbackPanel && (await isIntercomAllowed())) { + debug('loading intercom script'); + intercomScript.load(metadata); + } else { + debug('unloading intercom script'); + intercomScript.unload(); + } + } + + const shouldLoad = enableFeedbackPanel && (await isIntercomAllowed()); + + if (shouldLoad) { // In some environment the network can be firewalled, this is a safeguard to avoid // uncaught errors when injecting the script. debug('testing intercom availability'); const intercomWidgetUrl = buildIntercomScriptUrl(metadata.app_id); - const response = await window.fetch(intercomWidgetUrl).catch((e) => { + const response = await fetch(intercomWidgetUrl).catch((e) => { debug('fetch failed', e); return null; }); @@ -56,27 +68,82 @@ export async function setupIntercom( debug('intercom is reachable, proceeding with the setup'); } else { debug( - 'not testing intercom connectivity because enableFeedbackPanel == false' + 'not testing intercom connectivity because enableFeedbackPanel == false || isAllowed == false' ); } - const toggleEnableFeedbackPanel = (enableFeedbackPanel: boolean) => { - if (enableFeedbackPanel) { - debug('loading intercom script'); - intercomScript.load(metadata); - } else { - debug('unloading intercom script'); - intercomScript.unload(); - } - }; - - toggleEnableFeedbackPanel(!!enableFeedbackPanel); + try { + await toggleEnableFeedbackPanel(shouldLoad); + } catch (error) { + debug('initial toggle failed', { + error, + }); + } preferences.onPreferenceValueChanged( 'enableFeedbackPanel', (enableFeedbackPanel) => { debug('enableFeedbackPanel changed'); - toggleEnableFeedbackPanel(enableFeedbackPanel); + void toggleEnableFeedbackPanel(enableFeedbackPanel); } ); } + +let isIntercomAllowedPromise: Promise | null = null; + +function isIntercomAllowed(): Promise { + if (!isIntercomAllowedPromise) { + isIntercomAllowedPromise = fetchIntegrations().then( + ({ intercom }) => intercom, + (error) => { + debug( + 'Failed to fetch intercom integration status, defaulting to false', + { error } + ); + return false; + } + ); + } + return isIntercomAllowedPromise; +} + +export function resetIntercomAllowedCache(): void { + isIntercomAllowedPromise = null; +} + +/** + * TODO: Move this to a shared package if we start using it to toggle other integrations. + */ +function getAutoUpdateEndpoint() { + const { HADRON_AUTO_UPDATE_ENDPOINT, HADRON_AUTO_UPDATE_ENDPOINT_OVERRIDE } = + process.env; + const result = + HADRON_AUTO_UPDATE_ENDPOINT_OVERRIDE || HADRON_AUTO_UPDATE_ENDPOINT; + if (!result) { + throw new Error( + 'Expected HADRON_AUTO_UPDATE_ENDPOINT or HADRON_AUTO_UPDATE_ENDPOINT_OVERRIDE to be set' + ); + } + return result; +} + +/** + * Fetches the integrations configuration from the update server. + * TODO: Move this to a shared package if we start using it to toggle other integrations. + */ +async function fetchIntegrations(): Promise<{ intercom: boolean }> { + const url = `${getAutoUpdateEndpoint()}/api/v2/integrations`; + debug('requesting integrations status', { url }); + const response = await fetch(url); + if (!response.ok) { + throw new Error( + `Expected an OK response, got ${response.status} '${response.statusText}'` + ); + } + const result = await response.json(); + debug('got integrations response', { result }); + if (typeof result.intercom !== 'boolean') { + throw new Error(`Expected 'intercom' to be a boolean`); + } + return result; +} diff --git a/packages/compass-logging/package.json b/packages/compass-logging/package.json index c1b5946d804..0977de1b48e 100644 --- a/packages/compass-logging/package.json +++ b/packages/compass-logging/package.json @@ -52,7 +52,7 @@ }, "dependencies": { "debug": "^4.3.4", - "hadron-app-registry": "^9.4.11", + "@mongodb-js/compass-app-registry": "^9.4.11", "hadron-ipc": "^3.5.2", "is-electron-renderer": "^2.0.1", "mongodb-log-writer": "^2.3.4", diff --git a/packages/compass-logging/src/provider.ts b/packages/compass-logging/src/provider.ts index 8e5c094ec80..c012ac0251d 100644 --- a/packages/compass-logging/src/provider.ts +++ b/packages/compass-logging/src/provider.ts @@ -4,7 +4,7 @@ import type { MongoLogId, MongoLogWriter, } from 'mongodb-log-writer/mongo-log-writer'; -import { createServiceLocator } from 'hadron-app-registry'; +import { createServiceLocator } from '@mongodb-js/compass-app-registry'; export type { Logger } from './logger'; diff --git a/packages/compass-maybe-protect-connection-string/package.json b/packages/compass-maybe-protect-connection-string/package.json index ca250d0987b..358179f2dc3 100644 --- a/packages/compass-maybe-protect-connection-string/package.json +++ b/packages/compass-maybe-protect-connection-string/package.json @@ -13,7 +13,7 @@ "email": "compass@mongodb.com" }, "homepage": "https://github.com/mongodb-js/compass", - "version": "0.38.2", + "version": "0.39.0", "repository": { "type": "git", "url": "https://github.com/mongodb-js/compass.git" @@ -50,7 +50,7 @@ "reformat": "npm run eslint . -- --fix && npm run prettier -- --write ." }, "dependencies": { - "compass-preferences-model": "^2.40.2", + "compass-preferences-model": "^2.41.0", "mongodb-connection-string-url": "^3.0.1" }, "devDependencies": { diff --git a/packages/compass-preferences-model/package.json b/packages/compass-preferences-model/package.json index 0d7977d8578..90c9e0aa3c2 100644 --- a/packages/compass-preferences-model/package.json +++ b/packages/compass-preferences-model/package.json @@ -2,7 +2,7 @@ "name": "compass-preferences-model", "description": "Compass preferences model", "author": "Lucas Hrabovsky ", - "version": "2.40.2", + "version": "2.41.0", "bugs": { "url": "https://jira.mongodb.org/projects/COMPASS/issues", "email": "compass@mongodb.com" @@ -52,9 +52,9 @@ "@mongodb-js/compass-logging": "^1.7.2", "@mongodb-js/compass-user-data": "^0.7.2", "@mongodb-js/devtools-proxy-support": "^0.4.4", - "@mongodb-js/compass-components": "^1.38.1", + "@mongodb-js/compass-components": "^1.39.0", "bson": "^6.10.3", - "hadron-app-registry": "^9.4.11", + "@mongodb-js/compass-app-registry": "^9.4.11", "hadron-ipc": "^3.5.2", "js-yaml": "^4.1.0", "lodash": "^4.17.21", diff --git a/packages/compass-preferences-model/src/react.ts b/packages/compass-preferences-model/src/react.ts index 2dc7caf8526..93bf1df8058 100644 --- a/packages/compass-preferences-model/src/react.ts +++ b/packages/compass-preferences-model/src/react.ts @@ -11,7 +11,7 @@ import { import { type AllPreferences } from './'; import type { PreferencesAccess } from './preferences'; import { ReadOnlyPreferenceAccess } from './read-only-preferences-access'; -import { createServiceLocator } from 'hadron-app-registry'; +import { createServiceLocator } from '@mongodb-js/compass-app-registry'; import { pick } from 'lodash'; const PreferencesContext = createContext(null); diff --git a/packages/compass-query-bar/package.json b/packages/compass-query-bar/package.json index e224004f4ef..826a4c29e0c 100644 --- a/packages/compass-query-bar/package.json +++ b/packages/compass-query-bar/package.json @@ -6,7 +6,7 @@ "email": "compass@mongodb.com" }, "private": true, - "version": "8.61.0", + "version": "8.62.0", "homepage": "https://github.com/mongodb-js/compass", "license": "SSPL", "bugs": { @@ -65,24 +65,24 @@ "xvfb-maybe": "^0.2.1" }, "dependencies": { - "@mongodb-js/atlas-service": "^0.45.0", - "@mongodb-js/compass-app-stores": "^7.46.0", - "@mongodb-js/compass-collection": "^4.59.0", - "@mongodb-js/compass-components": "^1.38.1", - "@mongodb-js/compass-connections": "^1.60.0", - "@mongodb-js/compass-editor": "^0.40.2", - "@mongodb-js/compass-field-store": "^9.35.0", - "@mongodb-js/compass-generative-ai": "^0.40.0", + "@mongodb-js/atlas-service": "^0.46.0", + "@mongodb-js/compass-app-stores": "^7.47.0", + "@mongodb-js/compass-collection": "^4.60.0", + "@mongodb-js/compass-components": "^1.39.0", + "@mongodb-js/compass-connections": "^1.61.0", + "@mongodb-js/compass-editor": "^0.41.0", + "@mongodb-js/compass-field-store": "^9.36.0", + "@mongodb-js/compass-generative-ai": "^0.41.0", "@mongodb-js/compass-logging": "^1.7.2", "@mongodb-js/compass-telemetry": "^1.10.0", "@mongodb-js/mongodb-constants": "^0.11.0", - "@mongodb-js/my-queries-storage": "^0.27.3", + "@mongodb-js/my-queries-storage": "^0.28.0", "bson": "^6.10.3", - "compass-preferences-model": "^2.40.2", - "hadron-app-registry": "^9.4.11", + "compass-preferences-model": "^2.41.0", + "@mongodb-js/compass-app-registry": "^9.4.11", "lodash": "^4.17.21", "mongodb": "^6.16.0", - "mongodb-instance-model": "^12.32.2", + "mongodb-instance-model": "^12.33.0", "mongodb-ns": "^2.4.2", "mongodb-query-parser": "^4.3.0", "mongodb-query-util": "^2.4.10", diff --git a/packages/compass-query-bar/src/components/hooks.tsx b/packages/compass-query-bar/src/components/hooks.tsx index 56264b86a8f..09edf6b0557 100644 --- a/packages/compass-query-bar/src/components/hooks.tsx +++ b/packages/compass-query-bar/src/components/hooks.tsx @@ -4,7 +4,7 @@ import { useSelector, useStore } from '../stores/context'; import type { ChangeFilterEvent } from '../modules/change-filter'; import { applyFilterChange } from '../stores/query-bar-reducer'; import { mapFormFieldsToQuery } from '../utils/query'; -import { createServiceLocator } from 'hadron-app-registry'; +import { createServiceLocator } from '@mongodb-js/compass-app-registry'; import type { RootState } from '../stores/query-bar-store'; import { isQueryEqual } from '../utils'; import type { BaseQuery } from '../constants/query-properties'; diff --git a/packages/compass-query-bar/src/index.tsx b/packages/compass-query-bar/src/index.tsx index f7e55a69ee9..4e171702c27 100644 --- a/packages/compass-query-bar/src/index.tsx +++ b/packages/compass-query-bar/src/index.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { registerHadronPlugin } from 'hadron-app-registry'; +import { registerCompassPlugin } from '@mongodb-js/compass-app-registry'; import { activatePlugin } from './stores/query-bar-store'; import { connectionInfoRefLocator, @@ -27,7 +27,7 @@ import { } from '@mongodb-js/my-queries-storage/provider'; import { telemetryLocator } from '@mongodb-js/compass-telemetry/provider'; -const QueryBarPlugin = registerHadronPlugin( +const QueryBarPlugin = registerCompassPlugin( { name: 'QueryBar', // Query bar is a special case where we render nothing for the purposes of diff --git a/packages/compass-query-bar/src/stores/query-bar-reducer.spec.ts b/packages/compass-query-bar/src/stores/query-bar-reducer.spec.ts index 6904ab0bf0d..e47a643701c 100644 --- a/packages/compass-query-bar/src/stores/query-bar-reducer.spec.ts +++ b/packages/compass-query-bar/src/stores/query-bar-reducer.spec.ts @@ -17,7 +17,7 @@ import { import { configureStore } from './query-bar-store'; import type { QueryBarExtraArgs, RootState } from './query-bar-store'; import Sinon from 'sinon'; -import type AppRegistry from 'hadron-app-registry'; +import type AppRegistry from '@mongodb-js/compass-app-registry'; import { mapQueryToFormFields } from '../utils/query'; import type { PreferencesAccess } from 'compass-preferences-model'; import { createSandboxFromDefaultPreferences } from 'compass-preferences-model'; diff --git a/packages/compass-query-bar/src/stores/query-bar-store.spec.ts b/packages/compass-query-bar/src/stores/query-bar-store.spec.ts index e181190bbe5..b154753d804 100644 --- a/packages/compass-query-bar/src/stores/query-bar-store.spec.ts +++ b/packages/compass-query-bar/src/stores/query-bar-store.spec.ts @@ -2,7 +2,7 @@ import sinon from 'sinon'; import { activatePlugin } from './query-bar-store'; import { createNoopLogger } from '@mongodb-js/compass-logging/provider'; import { createNoopTrack } from '@mongodb-js/compass-telemetry/provider'; -import { AppRegistry } from 'hadron-app-registry'; +import { AppRegistry } from '@mongodb-js/compass-app-registry'; import type { PreferencesAccess } from 'compass-preferences-model'; import { createSandboxFromDefaultPreferences } from 'compass-preferences-model'; import { expect } from 'chai'; diff --git a/packages/compass-query-bar/src/stores/query-bar-store.ts b/packages/compass-query-bar/src/stores/query-bar-store.ts index 52425866cc2..62f2b7e7018 100644 --- a/packages/compass-query-bar/src/stores/query-bar-store.ts +++ b/packages/compass-query-bar/src/stores/query-bar-store.ts @@ -1,4 +1,4 @@ -import type AppRegistry from 'hadron-app-registry'; +import type AppRegistry from '@mongodb-js/compass-app-registry'; import { createStore as _createStore, applyMiddleware, @@ -23,7 +23,7 @@ import { aiQueryReducer } from './ai-query-reducer'; import { getQueryAttributes } from '../utils'; import type { PreferencesAccess } from 'compass-preferences-model'; import type { CollectionTabPluginMetadata } from '@mongodb-js/compass-collection'; -import type { ActivateHelpers } from 'hadron-app-registry'; +import type { ActivateHelpers } from '@mongodb-js/compass-app-registry'; import type { MongoDBInstance } from 'mongodb-instance-model'; import { QueryBarStoreContext } from './context'; import type { Logger } from '@mongodb-js/compass-logging/provider'; diff --git a/packages/compass-saved-aggregations-queries/package.json b/packages/compass-saved-aggregations-queries/package.json index 32d6a1d020d..390081308b3 100644 --- a/packages/compass-saved-aggregations-queries/package.json +++ b/packages/compass-saved-aggregations-queries/package.json @@ -11,7 +11,7 @@ "email": "compass@mongodb.com" }, "homepage": "https://github.com/mongodb-js/compass", - "version": "1.60.0", + "version": "1.61.0", "repository": { "type": "git", "url": "https://github.com/mongodb-js/compass.git" @@ -48,19 +48,19 @@ "reformat": "npm run eslint . -- --fix && npm run prettier -- --write ." }, "dependencies": { - "@mongodb-js/compass-app-stores": "^7.46.0", - "@mongodb-js/compass-components": "^1.38.1", - "@mongodb-js/compass-connections": "^1.60.0", + "@mongodb-js/compass-app-stores": "^7.47.0", + "@mongodb-js/compass-components": "^1.39.0", + "@mongodb-js/compass-connections": "^1.61.0", "@mongodb-js/compass-logging": "^1.7.2", "@mongodb-js/compass-telemetry": "^1.10.0", - "@mongodb-js/compass-workspaces": "^0.41.0", - "@mongodb-js/connection-form": "^1.52.3", + "@mongodb-js/compass-workspaces": "^0.42.0", + "@mongodb-js/connection-form": "^1.53.0", "@mongodb-js/connection-info": "^0.15.2", - "@mongodb-js/my-queries-storage": "^0.27.3", + "@mongodb-js/my-queries-storage": "^0.28.0", "bson": "^6.10.3", - "compass-preferences-model": "^2.40.2", + "compass-preferences-model": "^2.41.0", "fuse.js": "^6.5.3", - "hadron-app-registry": "^9.4.11", + "@mongodb-js/compass-app-registry": "^9.4.11", "mongodb-ns": "^2.4.2", "react": "^17.0.2", "react-redux": "^8.1.3", diff --git a/packages/compass-saved-aggregations-queries/src/index.spec.tsx b/packages/compass-saved-aggregations-queries/src/index.spec.tsx index 82ed378a06c..eb1f7d1686d 100644 --- a/packages/compass-saved-aggregations-queries/src/index.spec.tsx +++ b/packages/compass-saved-aggregations-queries/src/index.spec.tsx @@ -2,7 +2,7 @@ import React from 'react'; import Sinon from 'sinon'; import { expect } from 'chai'; import { queries, pipelines } from '../test/fixtures'; -import { MyQueriesPlugin } from '.'; +import { WorkspaceTab } from '.'; import type { PipelineStorage, FavoriteQueryStorage, @@ -81,7 +81,7 @@ describe('AggregationsAndQueriesAndUpdatemanyList', function () { let connectionsStore: RenderWithConnectionsResult['connectionsStore']; const renderPlugin = () => { - const PluginWithMocks = MyQueriesPlugin.withMockServices({ + const PluginWithMocks = WorkspaceTab.provider.withMockServices({ instancesManager, favoriteQueryStorageAccess: { getStorage() { @@ -91,9 +91,17 @@ describe('AggregationsAndQueriesAndUpdatemanyList', function () { pipelineStorage: pipelineStorage, workspaces, }); - const result = renderWithConnections(, { - connections: [connectionOne.connectionInfo, connectionTwo.connectionInfo], - }); + const result = renderWithConnections( + + + , + { + connections: [ + connectionOne.connectionInfo, + connectionTwo.connectionInfo, + ], + } + ); connectionsStore = result.connectionsStore; }; diff --git a/packages/compass-saved-aggregations-queries/src/index.ts b/packages/compass-saved-aggregations-queries/src/index.ts index b760ec05565..1d497c130bb 100644 --- a/packages/compass-saved-aggregations-queries/src/index.ts +++ b/packages/compass-saved-aggregations-queries/src/index.ts @@ -1,10 +1,11 @@ -import { registerHadronPlugin } from 'hadron-app-registry'; +import React from 'react'; +import { registerCompassPlugin } from '@mongodb-js/compass-app-registry'; import { mongoDBInstancesManagerLocator } from '@mongodb-js/compass-app-stores/provider'; import { createLoggerLocator } from '@mongodb-js/compass-logging/provider'; import { telemetryLocator } from '@mongodb-js/compass-telemetry/provider'; import { activatePlugin } from './stores'; import AggregationsQueriesList from './components/aggregations-queries-list'; -import type { WorkspaceComponent } from '@mongodb-js/compass-workspaces'; +import type { WorkspacePlugin } from '@mongodb-js/compass-workspaces'; import { workspacesServiceLocator } from '@mongodb-js/compass-workspaces/provider'; import { pipelineStorageLocator, @@ -12,30 +13,29 @@ import { } from '@mongodb-js/my-queries-storage/provider'; import { preferencesLocator } from 'compass-preferences-model/provider'; import { connectionsLocator } from '@mongodb-js/compass-connections/provider'; +import { PluginTabTitleComponent, WorkspaceName } from './plugin-tab-title'; -const serviceLocators = { - connections: connectionsLocator, - instancesManager: mongoDBInstancesManagerLocator, - preferencesAccess: preferencesLocator, - logger: createLoggerLocator('COMPASS-MY-QUERIES-UI'), - track: telemetryLocator, - workspaces: workspacesServiceLocator, - pipelineStorage: pipelineStorageLocator, - favoriteQueryStorageAccess: favoriteQueryStorageAccessLocator, +export const WorkspaceTab: WorkspacePlugin = { + name: WorkspaceName, + provider: registerCompassPlugin( + { + name: WorkspaceName, + component: function MyQueriesProvider({ children }): any { + return React.createElement(React.Fragment, null, children); + }, + activate: activatePlugin, + }, + { + connections: connectionsLocator, + instancesManager: mongoDBInstancesManagerLocator, + preferencesAccess: preferencesLocator, + logger: createLoggerLocator('COMPASS-MY-QUERIES-UI'), + track: telemetryLocator, + workspaces: workspacesServiceLocator, + pipelineStorage: pipelineStorageLocator, + favoriteQueryStorageAccess: favoriteQueryStorageAccessLocator, + } + ), + content: AggregationsQueriesList, + header: PluginTabTitleComponent, }; - -export const MyQueriesPlugin = registerHadronPlugin( - { - name: 'MyQueries', - component: AggregationsQueriesList, - activate: activatePlugin, - }, - serviceLocators -); - -export const WorkspaceTab: WorkspaceComponent<'My Queries'> = { - name: 'My Queries' as const, - component: MyQueriesPlugin, -}; - -export default MyQueriesPlugin; diff --git a/packages/compass-saved-aggregations-queries/src/plugin-tab-title.tsx b/packages/compass-saved-aggregations-queries/src/plugin-tab-title.tsx new file mode 100644 index 00000000000..53114bee352 --- /dev/null +++ b/packages/compass-saved-aggregations-queries/src/plugin-tab-title.tsx @@ -0,0 +1,22 @@ +import React from 'react'; +import { + WorkspaceTab, + type WorkspaceTabCoreProps, +} from '@mongodb-js/compass-components'; +import type { WorkspacePluginProps } from '@mongodb-js/compass-workspaces'; + +export const WorkspaceName = 'My Queries' as const; + +type PluginTabTitleProps = WorkspaceTabCoreProps & + WorkspacePluginProps; + +export function PluginTabTitleComponent(props: PluginTabTitleProps) { + return ( + + ); +} diff --git a/packages/compass-saved-aggregations-queries/src/stores/index.ts b/packages/compass-saved-aggregations-queries/src/stores/index.ts index d03e4b7d696..0b6dbdcc6d1 100644 --- a/packages/compass-saved-aggregations-queries/src/stores/index.ts +++ b/packages/compass-saved-aggregations-queries/src/stores/index.ts @@ -1,4 +1,4 @@ -import type AppRegistry from 'hadron-app-registry'; +import type AppRegistry from '@mongodb-js/compass-app-registry'; import { createStore, applyMiddleware, combineReducers } from 'redux'; import type { AnyAction, Action } from 'redux'; import thunk from 'redux-thunk'; @@ -79,8 +79,12 @@ export type SavedQueryAggregationThunkAction< A extends Action = AnyAction > = ThunkAction; +type SavedQueryAggregationPluginProps = { + children?: React.ReactNode; +}; + export function activatePlugin( - _: Record, + _initialProps: SavedQueryAggregationPluginProps, services: MyQueriesServices ) { const store = configureStore(services); diff --git a/packages/compass-schema-validation/package.json b/packages/compass-schema-validation/package.json index 1ef00605ab1..a8e0a09e595 100644 --- a/packages/compass-schema-validation/package.json +++ b/packages/compass-schema-validation/package.json @@ -6,7 +6,7 @@ "email": "compass@mongodb.com" }, "private": true, - "version": "6.60.0", + "version": "6.61.0", "repository": { "type": "git", "url": "https://github.com/mongodb-js/compass.git" @@ -59,28 +59,28 @@ "electron-mocha": "^12.2.0", "hadron-ipc": "^3.5.2", "mocha": "^10.2.0", - "mongodb-instance-model": "^12.32.2", + "mongodb-instance-model": "^12.33.0", "nyc": "^15.1.0", "react-dom": "^17.0.2", "sinon": "^8.1.1", "typescript": "^5.0.4" }, "dependencies": { - "@mongodb-js/compass-app-stores": "^7.46.0", - "@mongodb-js/compass-collection": "^4.59.0", - "@mongodb-js/compass-components": "^1.38.1", - "@mongodb-js/compass-connections": "^1.60.0", - "@mongodb-js/compass-crud": "^13.60.0", - "@mongodb-js/compass-editor": "^0.40.2", - "@mongodb-js/compass-field-store": "^9.35.0", + "@mongodb-js/compass-app-stores": "^7.47.0", + "@mongodb-js/compass-collection": "^4.60.0", + "@mongodb-js/compass-components": "^1.39.0", + "@mongodb-js/compass-connections": "^1.61.0", + "@mongodb-js/compass-crud": "^13.61.0", + "@mongodb-js/compass-editor": "^0.41.0", + "@mongodb-js/compass-field-store": "^9.36.0", "@mongodb-js/compass-logging": "^1.7.2", - "@mongodb-js/compass-schema": "^6.61.0", + "@mongodb-js/compass-schema": "^6.62.0", "@mongodb-js/compass-telemetry": "^1.10.0", - "@mongodb-js/compass-workspaces": "^0.41.0", + "@mongodb-js/compass-workspaces": "^0.42.0", "@mongodb-js/mongodb-constants": "^0.11.0", "bson": "^6.10.3", - "compass-preferences-model": "^2.40.2", - "hadron-app-registry": "^9.4.11", + "compass-preferences-model": "^2.41.0", + "@mongodb-js/compass-app-registry": "^9.4.11", "javascript-stringify": "^2.0.1", "lodash": "^4.17.21", "mongodb": "^6.16.0", diff --git a/packages/compass-schema-validation/src/index.ts b/packages/compass-schema-validation/src/index.ts index 6dc65f41c70..17e632456e6 100644 --- a/packages/compass-schema-validation/src/index.ts +++ b/packages/compass-schema-validation/src/index.ts @@ -1,7 +1,7 @@ import React from 'react'; import { onActivated } from './stores'; import { CompassSchemaValidation } from './components/compass-schema-validation'; -import { registerHadronPlugin } from 'hadron-app-registry'; +import { registerCompassPlugin } from '@mongodb-js/compass-app-registry'; import { connectionInfoRefLocator, dataServiceLocator, @@ -15,7 +15,7 @@ import { SchemaValidationTabTitle } from './plugin-title'; import { workspacesServiceLocator } from '@mongodb-js/compass-workspaces/provider'; import type { RequiredDataServiceProps } from './modules'; -const CompassSchemaValidationHadronPlugin = registerHadronPlugin( +const CompassSchemaValidationPluginProvider = registerCompassPlugin( { name: 'CompassSchemaValidationPlugin', component: function SchemaValidationsProvider({ children }) { @@ -36,7 +36,7 @@ const CompassSchemaValidationHadronPlugin = registerHadronPlugin( ); export const CompassSchemaValidationPlugin = { name: 'Validation' as const, - provider: CompassSchemaValidationHadronPlugin, + provider: CompassSchemaValidationPluginProvider, content: CompassSchemaValidation, header: SchemaValidationTabTitle, }; diff --git a/packages/compass-schema-validation/src/modules/index.ts b/packages/compass-schema-validation/src/modules/index.ts index 59901d97389..f2ceb972f2e 100644 --- a/packages/compass-schema-validation/src/modules/index.ts +++ b/packages/compass-schema-validation/src/modules/index.ts @@ -27,7 +27,7 @@ import type { ConnectionInfoRef, DataService as OriginalDataService, } from '@mongodb-js/compass-connections/provider'; -import type AppRegistry from 'hadron-app-registry'; +import type AppRegistry from '@mongodb-js/compass-app-registry'; import type { Logger } from '@mongodb-js/compass-logging/provider'; import type { TrackFunction } from '@mongodb-js/compass-telemetry'; import { type WorkspacesService } from '@mongodb-js/compass-workspaces/provider'; diff --git a/packages/compass-schema-validation/src/stores/store.spec.ts b/packages/compass-schema-validation/src/stores/store.spec.ts index 21510c990cb..31048153ded 100644 --- a/packages/compass-schema-validation/src/stores/store.spec.ts +++ b/packages/compass-schema-validation/src/stores/store.spec.ts @@ -1,5 +1,7 @@ import { expect } from 'chai'; -import AppRegistry, { createActivateHelpers } from 'hadron-app-registry'; +import AppRegistry, { + createActivateHelpers, +} from '@mongodb-js/compass-app-registry'; import { MongoDBInstance } from 'mongodb-instance-model'; import { diff --git a/packages/compass-schema-validation/src/stores/store.ts b/packages/compass-schema-validation/src/stores/store.ts index 0bcea1a7b95..7c0240337cf 100644 --- a/packages/compass-schema-validation/src/stores/store.ts +++ b/packages/compass-schema-validation/src/stores/store.ts @@ -7,7 +7,10 @@ import { activateValidation } from '../modules/validation'; import { editModeChanged } from '../modules/edit-mode'; import semver from 'semver'; import type { CollectionTabPluginMetadata } from '@mongodb-js/compass-collection'; -import type { ActivateHelpers, AppRegistry } from 'hadron-app-registry'; +import type { + ActivateHelpers, + AppRegistry, +} from '@mongodb-js/compass-app-registry'; import type { ConnectionInfoRef } from '@mongodb-js/compass-connections/provider'; import type { MongoDBInstance } from '@mongodb-js/compass-app-stores/provider'; import type { PreferencesAccess } from 'compass-preferences-model'; diff --git a/packages/compass-schema/package.json b/packages/compass-schema/package.json index add2c9f84c5..d887e8fefc3 100644 --- a/packages/compass-schema/package.json +++ b/packages/compass-schema/package.json @@ -6,7 +6,7 @@ "email": "compass@mongodb.com" }, "private": true, - "version": "6.61.0", + "version": "6.62.0", "repository": { "type": "git", "url": "https://github.com/mongodb-js/compass.git" @@ -50,7 +50,7 @@ "devDependencies": { "@mongodb-js/eslint-config-compass": "^1.3.10", "@mongodb-js/mocha-config-compass": "^1.6.8", - "@mongodb-js/my-queries-storage": "^0.27.3", + "@mongodb-js/my-queries-storage": "^0.28.0", "@mongodb-js/prettier-config-compass": "^1.2.8", "@mongodb-js/testing-library-compass": "^1.3.2", "@mongodb-js/tsconfig-compass": "^1.2.8", @@ -71,19 +71,19 @@ "xvfb-maybe": "^0.2.1" }, "dependencies": { - "@mongodb-js/compass-collection": "^4.59.0", - "@mongodb-js/compass-components": "^1.38.1", - "@mongodb-js/compass-connections": "^1.60.0", - "@mongodb-js/compass-editor": "^0.40.2", - "@mongodb-js/compass-field-store": "^9.35.0", + "@mongodb-js/compass-collection": "^4.60.0", + "@mongodb-js/compass-components": "^1.39.0", + "@mongodb-js/compass-connections": "^1.61.0", + "@mongodb-js/compass-editor": "^0.41.0", + "@mongodb-js/compass-field-store": "^9.36.0", "@mongodb-js/compass-logging": "^1.7.2", "@mongodb-js/compass-telemetry": "^1.10.0", - "@mongodb-js/compass-query-bar": "^8.61.0", - "@mongodb-js/connection-storage": "^0.35.0", + "@mongodb-js/compass-query-bar": "^8.62.0", + "@mongodb-js/connection-storage": "^0.36.0", "bson": "^6.10.3", - "compass-preferences-model": "^2.40.2", + "compass-preferences-model": "^2.41.0", "d3": "^3.5.17", - "hadron-app-registry": "^9.4.11", + "@mongodb-js/compass-app-registry": "^9.4.11", "hadron-document": "^8.8.12", "leaflet": "^1.5.1", "leaflet-defaulticon-compatibility": "^0.1.1", diff --git a/packages/compass-schema/src/index.ts b/packages/compass-schema/src/index.ts index 8ecd87046b2..0e96a892797 100644 --- a/packages/compass-schema/src/index.ts +++ b/packages/compass-schema/src/index.ts @@ -6,7 +6,7 @@ import { } from '@mongodb-js/compass-connections/provider'; import CompassSchema from './components/compass-schema'; -import { registerHadronPlugin } from 'hadron-app-registry'; +import { registerCompassPlugin } from '@mongodb-js/compass-app-registry'; import { activateSchemaPlugin } from './stores/store'; import type { RequiredDataServiceProps } from './stores/store'; import { createLoggerLocator } from '@mongodb-js/compass-logging/provider'; @@ -16,7 +16,7 @@ import { fieldStoreServiceLocator } from '@mongodb-js/compass-field-store'; import { queryBarServiceLocator } from '@mongodb-js/compass-query-bar'; import { SchemaTabTitle } from './plugin-title'; -const CompassSchemaHadronPlugin = registerHadronPlugin( +const CompassSchemaPluginProvider = registerCompassPlugin( { name: 'CompassSchemaPlugin', component: function SchemaProvider({ children, ...props }) { @@ -45,7 +45,7 @@ const CompassSchemaHadronPlugin = registerHadronPlugin( export const CompassSchemaPlugin = { name: 'Schema' as const, - provider: CompassSchemaHadronPlugin, + provider: CompassSchemaPluginProvider, content: CompassSchema as React.FunctionComponent /* reflux store */, header: SchemaTabTitle, }; diff --git a/packages/compass-schema/src/stores/store.spec.ts b/packages/compass-schema/src/stores/store.spec.ts index c792cdf2b2f..f4da5019c79 100644 --- a/packages/compass-schema/src/stores/store.spec.ts +++ b/packages/compass-schema/src/stores/store.spec.ts @@ -1,6 +1,8 @@ import { activateSchemaPlugin } from './store'; import type { SchemaStore, SchemaPluginServices } from './store'; -import AppRegistry, { createActivateHelpers } from 'hadron-app-registry'; +import AppRegistry, { + createActivateHelpers, +} from '@mongodb-js/compass-app-registry'; import { expect } from 'chai'; import { waitFor } from '@mongodb-js/testing-library-compass'; diff --git a/packages/compass-schema/src/stores/store.ts b/packages/compass-schema/src/stores/store.ts index 21d5733ca16..069ca5e40a3 100644 --- a/packages/compass-schema/src/stores/store.ts +++ b/packages/compass-schema/src/stores/store.ts @@ -11,8 +11,8 @@ import type { ConnectionInfoRef, DataService as OriginalDataService, } from '@mongodb-js/compass-connections/provider'; -import type { ActivateHelpers } from 'hadron-app-registry'; -import type AppRegistry from 'hadron-app-registry'; +import type { ActivateHelpers } from '@mongodb-js/compass-app-registry'; +import type AppRegistry from '@mongodb-js/compass-app-registry'; import type { PreferencesAccess } from 'compass-preferences-model/provider'; import type { FieldStoreService } from '@mongodb-js/compass-field-store'; import type { QueryBarService } from '@mongodb-js/compass-query-bar'; diff --git a/packages/compass-serverstats/package.json b/packages/compass-serverstats/package.json index 583af061b3c..0d96b4d8740 100644 --- a/packages/compass-serverstats/package.json +++ b/packages/compass-serverstats/package.json @@ -2,7 +2,7 @@ "name": "@mongodb-js/compass-serverstats", "description": "Compass Real Time", "private": true, - "version": "16.59.0", + "version": "16.60.0", "main": "dist/index.js", "compass:main": "src/index.ts", "exports": { @@ -30,15 +30,15 @@ }, "license": "SSPL", "dependencies": { - "@mongodb-js/compass-app-stores": "^7.46.0", - "@mongodb-js/compass-components": "^1.38.1", - "@mongodb-js/compass-connections": "^1.60.0", + "@mongodb-js/compass-app-stores": "^7.47.0", + "@mongodb-js/compass-components": "^1.39.0", + "@mongodb-js/compass-connections": "^1.61.0", "@mongodb-js/compass-telemetry": "^1.10.0", - "@mongodb-js/compass-workspaces": "^0.41.0", + "@mongodb-js/compass-workspaces": "^0.42.0", "d3": "^3.5.17", "d3-timer": "^1.0.3", "debug": "^4.3.4", - "hadron-app-registry": "^9.4.11", + "@mongodb-js/compass-app-registry": "^9.4.11", "lodash": "^4.17.21", "mongodb-ns": "^2.4.2", "prop-types": "^15.7.2", diff --git a/packages/compass-serverstats/src/index.ts b/packages/compass-serverstats/src/index.ts index 5b10bced541..7dd017a94c4 100644 --- a/packages/compass-serverstats/src/index.ts +++ b/packages/compass-serverstats/src/index.ts @@ -1,5 +1,6 @@ +import React from 'react'; import { PerformanceComponent } from './components'; -import { registerHadronPlugin } from 'hadron-app-registry'; +import { registerCompassPlugin } from '@mongodb-js/compass-app-registry'; import { dataServiceLocator, type DataServiceLocator, @@ -9,38 +10,48 @@ import { mongoDBInstanceLocator } from '@mongodb-js/compass-app-stores/provider' import CurrentOpStore from './stores/current-op-store'; import ServerStatsStore from './stores/server-stats-graphs-store'; import TopStore from './stores/top-store'; -import type { WorkspaceComponent } from '@mongodb-js/compass-workspaces'; +import type { WorkspacePlugin } from '@mongodb-js/compass-workspaces'; +import { + WorkspaceName, + ServerStatsPluginTitleComponent, +} from './plugin-tab-title'; -const PerformancePlugin = registerHadronPlugin( - { - name: 'Performance', - component: PerformanceComponent, - activate(_initialProps: Record, { dataService, instance }) { - CurrentOpStore.onActivated(dataService); - ServerStatsStore.onActivated(dataService); - TopStore.onActivated(dataService, instance); +type PerformancePluginInitialProps = Record; - // TODO(COMPASS-7416): no stores or subscriptions are returned here, we'd - // need to refactor the stores of this package - return { - store: {}, - deactivate() { - // noop - }, - }; - }, - }, - { - dataService: dataServiceLocator as DataServiceLocator, - instance: mongoDBInstanceLocator, - } -); +const WorkspaceTab: WorkspacePlugin = { + name: WorkspaceName, + provider: registerCompassPlugin( + { + name: WorkspaceName, + component: function PerformanceProvider({ children }) { + return React.createElement(React.Fragment, null, children); + }, + activate( + _initialProps: PerformancePluginInitialProps, + { dataService, instance } + ) { + CurrentOpStore.onActivated(dataService); + ServerStatsStore.onActivated(dataService); + TopStore.onActivated(dataService, instance); -const WorkspaceTab: WorkspaceComponent<'Performance'> = { - name: 'Performance' as const, - component: PerformancePlugin, + // TODO(COMPASS-7416): no stores or subscriptions are returned here, we'd + // need to refactor the stores of this package + return { + store: {}, + deactivate() { + // noop + }, + }; + }, + }, + { + dataService: dataServiceLocator as DataServiceLocator, + instance: mongoDBInstanceLocator, + } + ), + content: PerformanceComponent, + header: ServerStatsPluginTitleComponent, }; -export default PerformancePlugin; export { WorkspaceTab }; export { default as d3 } from './d3'; diff --git a/packages/compass-serverstats/src/plugin-tab-title.tsx b/packages/compass-serverstats/src/plugin-tab-title.tsx new file mode 100644 index 00000000000..9c0742b94a9 --- /dev/null +++ b/packages/compass-serverstats/src/plugin-tab-title.tsx @@ -0,0 +1,38 @@ +import React from 'react'; +import { + useConnectionInfo, + useConnectionsListRef, + useTabConnectionTheme, +} from '@mongodb-js/compass-connections/provider'; +import { + WorkspaceTab, + type WorkspaceTabCoreProps, +} from '@mongodb-js/compass-components'; +import type { WorkspacePluginProps } from '@mongodb-js/compass-workspaces'; + +export const WorkspaceName = 'Performance' as const; + +type PluginTitleComponentProps = WorkspaceTabCoreProps & + WorkspacePluginProps; + +export function ServerStatsPluginTitleComponent( + props: PluginTitleComponentProps +) { + const { getConnectionById } = useConnectionsListRef(); + const { id: connectionId } = useConnectionInfo(); + const connectionName = getConnectionById(connectionId)?.title || ''; + + const { getThemeOf } = useTabConnectionTheme(); + + return ( + + ); +} diff --git a/packages/compass-settings/package.json b/packages/compass-settings/package.json index 7943acde773..592a9532b4d 100644 --- a/packages/compass-settings/package.json +++ b/packages/compass-settings/package.json @@ -11,7 +11,7 @@ "email": "compass@mongodb.com" }, "homepage": "https://github.com/mongodb-js/compass", - "version": "0.58.0", + "version": "0.59.0", "repository": { "type": "git", "url": "https://github.com/mongodb-js/compass.git" @@ -49,12 +49,12 @@ "reformat": "npm run eslint . -- --fix && npm run prettier -- --write ." }, "dependencies": { - "@mongodb-js/atlas-service": "^0.45.0", - "@mongodb-js/compass-components": "^1.38.1", - "@mongodb-js/compass-generative-ai": "^0.40.0", + "@mongodb-js/atlas-service": "^0.46.0", + "@mongodb-js/compass-components": "^1.39.0", + "@mongodb-js/compass-generative-ai": "^0.41.0", "@mongodb-js/compass-logging": "^1.7.2", - "compass-preferences-model": "^2.40.2", - "hadron-app-registry": "^9.4.11", + "compass-preferences-model": "^2.41.0", + "@mongodb-js/compass-app-registry": "^9.4.11", "hadron-ipc": "^3.5.2", "react": "^17.0.2", "react-redux": "^8.1.3", diff --git a/packages/compass-settings/src/index.ts b/packages/compass-settings/src/index.ts index 0b0fdf3de70..959ec343ee1 100644 --- a/packages/compass-settings/src/index.ts +++ b/packages/compass-settings/src/index.ts @@ -1,4 +1,4 @@ -import { registerHadronPlugin } from 'hadron-app-registry'; +import { registerCompassPlugin } from '@mongodb-js/compass-app-registry'; import { createLoggerLocator } from '@mongodb-js/compass-logging/provider'; import { atlasAuthServiceLocator } from '@mongodb-js/atlas-service/provider'; import { atlasAiServiceLocator } from '@mongodb-js/compass-generative-ai/provider'; @@ -8,7 +8,7 @@ import { onActivated } from './stores'; export type { SettingsTabId } from './stores/settings'; -export const CompassSettingsPlugin = registerHadronPlugin( +export const CompassSettingsPlugin = registerCompassPlugin( { name: 'CompassSettings', component: SettingsPlugin, diff --git a/packages/compass-settings/src/stores/index.ts b/packages/compass-settings/src/stores/index.ts index 1a1ca4dee3f..fffcb7f0d4f 100644 --- a/packages/compass-settings/src/stores/index.ts +++ b/packages/compass-settings/src/stores/index.ts @@ -1,5 +1,5 @@ import { ipcRenderer } from 'hadron-ipc'; -import type AppRegistry from 'hadron-app-registry'; +import type AppRegistry from '@mongodb-js/compass-app-registry'; import type { Reducer, AnyAction } from 'redux'; import { createStore, combineReducers, applyMiddleware } from 'redux'; import type { ThunkAction } from 'redux-thunk'; diff --git a/packages/compass-shell/package.json b/packages/compass-shell/package.json index f1dccb28327..645b3bb9fb5 100644 --- a/packages/compass-shell/package.json +++ b/packages/compass-shell/package.json @@ -6,7 +6,7 @@ "email": "compass@mongodb.com" }, "private": true, - "version": "3.59.0", + "version": "3.60.0", "repository": { "type": "git", "url": "https://github.com/mongodb-js/compass.git" @@ -49,20 +49,20 @@ "reformat": "npm run eslint . -- --fix && npm run prettier -- --write ." }, "dependencies": { - "@mongodb-js/compass-components": "^1.38.1", - "@mongodb-js/compass-connections": "^1.60.0", - "@mongodb-js/compass-editor": "^0.40.2", + "@mongodb-js/compass-components": "^1.39.0", + "@mongodb-js/compass-connections": "^1.61.0", + "@mongodb-js/compass-editor": "^0.41.0", "@mongodb-js/compass-logging": "^1.7.2", "@mongodb-js/compass-telemetry": "^1.10.0", "@mongodb-js/compass-user-data": "^0.7.2", "@mongodb-js/compass-utils": "^0.9.2", - "@mongodb-js/compass-workspaces": "^0.41.0", + "@mongodb-js/compass-workspaces": "^0.42.0", "@mongosh/browser-repl": "^3.12.0", "@mongosh/logging": "^3.8.0", "@mongosh/node-runtime-worker-thread": "^3.3.10", "bson": "^6.10.3", - "compass-preferences-model": "^2.40.2", - "hadron-app-registry": "^9.4.11", + "compass-preferences-model": "^2.41.0", + "@mongodb-js/compass-app-registry": "^9.4.11", "react": "^17.0.2", "react-redux": "^8.1.3", "redux": "^4.2.1", diff --git a/packages/compass-shell/src/index.ts b/packages/compass-shell/src/index.ts index 2b73e217df9..a51b82ba65c 100644 --- a/packages/compass-shell/src/index.ts +++ b/packages/compass-shell/src/index.ts @@ -1,32 +1,36 @@ +import React from 'react'; import { createLoggerLocator } from '@mongodb-js/compass-logging/provider'; import { telemetryLocator } from '@mongodb-js/compass-telemetry/provider'; import { ShellPlugin, onActivated } from './plugin'; -import { registerHadronPlugin } from 'hadron-app-registry'; +import { registerCompassPlugin } from '@mongodb-js/compass-app-registry'; import { preferencesLocator } from 'compass-preferences-model/provider'; -import { type WorkspaceComponent } from '@mongodb-js/compass-workspaces'; +import type { WorkspacePlugin } from '@mongodb-js/compass-workspaces'; import { dataServiceLocator, type DataService, connectionInfoRefLocator, type DataServiceLocator, } from '@mongodb-js/compass-connections/provider'; +import { WorkspaceName, ShellPluginTitleComponent } from './plugin-tab-title'; -export const CompassShellPlugin = registerHadronPlugin( - { - name: 'CompassShell', - component: ShellPlugin, - activate: onActivated, - }, - { - logger: createLoggerLocator('COMPASS-SHELL'), - track: telemetryLocator, - dataService: dataServiceLocator as DataServiceLocator, - connectionInfo: connectionInfoRefLocator, - preferences: preferencesLocator, - } -); - -export const WorkspaceTab: WorkspaceComponent<'Shell'> = { - name: 'Shell' as const, - component: CompassShellPlugin, +export const WorkspaceTab: WorkspacePlugin = { + name: WorkspaceName, + provider: registerCompassPlugin( + { + name: WorkspaceName, + component: function ShellProvider({ children }) { + return React.createElement(React.Fragment, null, children); + }, + activate: onActivated, + }, + { + logger: createLoggerLocator('COMPASS-SHELL'), + track: telemetryLocator, + dataService: dataServiceLocator as DataServiceLocator, + connectionInfo: connectionInfoRefLocator, + preferences: preferencesLocator, + } + ), + content: ShellPlugin, + header: ShellPluginTitleComponent, }; diff --git a/packages/compass-shell/src/plugin-tab-title.tsx b/packages/compass-shell/src/plugin-tab-title.tsx new file mode 100644 index 00000000000..4d18ddf7194 --- /dev/null +++ b/packages/compass-shell/src/plugin-tab-title.tsx @@ -0,0 +1,35 @@ +import React from 'react'; +import { + useConnectionInfo, + useConnectionsListRef, + useTabConnectionTheme, +} from '@mongodb-js/compass-connections/provider'; +import { + WorkspaceTab, + type WorkspaceTabCoreProps, +} from '@mongodb-js/compass-components'; +import type { WorkspacePluginProps } from '@mongodb-js/compass-workspaces'; + +export const WorkspaceName = 'Shell' as const; + +type PluginTitleProps = WorkspaceTabCoreProps & + WorkspacePluginProps; + +export function ShellPluginTitleComponent(tabProps: PluginTitleProps) { + const { getThemeOf } = useTabConnectionTheme(); + const { getConnectionById } = useConnectionsListRef(); + const { id: connectionId } = useConnectionInfo(); + + const connectionName = getConnectionById(connectionId)?.title || ''; + return ( + + ); +} diff --git a/packages/compass-shell/src/plugin.spec.tsx b/packages/compass-shell/src/plugin.spec.tsx index 55913229890..b54c65569c8 100644 --- a/packages/compass-shell/src/plugin.spec.tsx +++ b/packages/compass-shell/src/plugin.spec.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { expect } from 'chai'; import { EventEmitter } from 'events'; -import { CompassShellPlugin } from './index'; +import { WorkspaceTab } from './index'; import { renderWithActiveConnection, screen, @@ -9,7 +9,7 @@ import { } from '@mongodb-js/testing-library-compass'; import { RuntimeMap } from './stores/store'; -describe('CompassShellPlugin', function () { +describe('CompassShellPlugin WorkspaceTab', function () { it('returns a renderable plugin', async function () { RuntimeMap.set('test', { eventEmitter: new EventEmitter(), @@ -19,7 +19,12 @@ describe('CompassShellPlugin', function () { }, } as any); - await renderWithActiveConnection(); + const ShellContentComponent = WorkspaceTab.content; + await renderWithActiveConnection( + + + + ); await waitFor(() => { expect(screen.getByTestId('shell-section')).to.exist; diff --git a/packages/compass-shell/src/plugin.tsx b/packages/compass-shell/src/plugin.tsx index 797997d5513..0637d0017f2 100644 --- a/packages/compass-shell/src/plugin.tsx +++ b/packages/compass-shell/src/plugin.tsx @@ -16,7 +16,7 @@ import reducer, { destroyCurrentRuntime, loadHistory, } from './stores/store'; -import type { ActivateHelpers } from 'hadron-app-registry'; +import type { ActivateHelpers } from '@mongodb-js/compass-app-registry'; import { Theme, ThemeProvider } from '@mongodb-js/compass-components'; const SHELL_THEME = { theme: Theme.Dark, enabled: true }; diff --git a/packages/compass-sidebar/package.json b/packages/compass-sidebar/package.json index b616674a5dc..ac044442ee9 100644 --- a/packages/compass-sidebar/package.json +++ b/packages/compass-sidebar/package.json @@ -11,7 +11,7 @@ "email": "compass@mongodb.com" }, "homepage": "https://github.com/mongodb-js/compass", - "version": "5.60.0", + "version": "5.61.0", "repository": { "type": "git", "url": "https://github.com/mongodb-js/compass.git" @@ -48,21 +48,21 @@ "reformat": "npm run eslint . -- --fix && npm run prettier -- --write ." }, "dependencies": { - "@mongodb-js/compass-app-stores": "^7.46.0", - "@mongodb-js/compass-components": "^1.38.1", - "@mongodb-js/compass-connection-import-export": "^0.56.0", - "@mongodb-js/compass-connections": "^1.60.0", - "@mongodb-js/compass-connections-navigation": "^1.59.0", + "@mongodb-js/compass-app-stores": "^7.47.0", + "@mongodb-js/compass-components": "^1.39.0", + "@mongodb-js/compass-connection-import-export": "^0.57.0", + "@mongodb-js/compass-connections": "^1.61.0", + "@mongodb-js/compass-connections-navigation": "^1.60.0", "@mongodb-js/compass-logging": "^1.7.2", - "@mongodb-js/compass-maybe-protect-connection-string": "^0.38.2", + "@mongodb-js/compass-maybe-protect-connection-string": "^0.39.0", "@mongodb-js/compass-telemetry": "^1.10.0", - "@mongodb-js/compass-workspaces": "^0.41.0", + "@mongodb-js/compass-workspaces": "^0.42.0", "@mongodb-js/connection-info": "^0.15.2", - "compass-preferences-model": "^2.40.2", - "hadron-app-registry": "^9.4.11", + "compass-preferences-model": "^2.41.0", + "@mongodb-js/compass-app-registry": "^9.4.11", "lodash": "^4.17.21", "mongodb": "^6.16.0", - "mongodb-instance-model": "^12.32.2", + "mongodb-instance-model": "^12.33.0", "mongodb-ns": "^2.4.2", "react": "^17.0.2", "react-redux": "^8.1.3", diff --git a/packages/compass-sidebar/src/components/multiple-connections/sidebar.spec.tsx b/packages/compass-sidebar/src/components/multiple-connections/sidebar.spec.tsx index 8b054331613..86bad50b903 100644 --- a/packages/compass-sidebar/src/components/multiple-connections/sidebar.spec.tsx +++ b/packages/compass-sidebar/src/components/multiple-connections/sidebar.spec.tsx @@ -21,7 +21,7 @@ import { CompassSidebarPlugin, } from '../../index'; import type { ConnectionInfo } from '@mongodb-js/compass-connections/provider'; -import type AppRegistry from '../../../../hadron-app-registry/dist'; +import type AppRegistry from '@mongodb-js/compass-app-registry'; const savedFavoriteConnection: ConnectionInfo = { id: '12345', @@ -106,8 +106,18 @@ describe('Multiple Connections Sidebar Component', function () { null }, - { name: 'Performance', component: () => null }, + { + name: 'My Queries', + content: () => null, + header: () => null as any, + provider: (() => null) as any, + }, + { + name: 'Performance', + content: () => null, + header: () => null as any, + provider: (() => null) as any, + }, ]} > diff --git a/packages/compass-sidebar/src/index.ts b/packages/compass-sidebar/src/index.ts index dfa27cb08ab..a38fec9d09b 100644 --- a/packages/compass-sidebar/src/index.ts +++ b/packages/compass-sidebar/src/index.ts @@ -1,5 +1,8 @@ -import type { ActivateHelpers } from 'hadron-app-registry'; -import { registerHadronPlugin, type AppRegistry } from 'hadron-app-registry'; +import type { ActivateHelpers } from '@mongodb-js/compass-app-registry'; +import { + registerCompassPlugin, + type AppRegistry, +} from '@mongodb-js/compass-app-registry'; import SidebarPlugin from './plugin'; import { createSidebarStore } from './stores'; import { @@ -13,7 +16,7 @@ import type { Logger } from '@mongodb-js/compass-logging/provider'; import { createLoggerLocator } from '@mongodb-js/compass-logging/provider'; import { AtlasClusterConnectionsOnly } from './components/multiple-connections/connections-navigation'; -export const CompassSidebarPlugin = registerHadronPlugin( +export const CompassSidebarPlugin = registerCompassPlugin( { name: 'CompassSidebar', component: SidebarPlugin, diff --git a/packages/compass-sidebar/src/modules/index.ts b/packages/compass-sidebar/src/modules/index.ts index 5d529d84df9..fd9a271c869 100644 --- a/packages/compass-sidebar/src/modules/index.ts +++ b/packages/compass-sidebar/src/modules/index.ts @@ -9,7 +9,7 @@ import type { ConnectionOptionsState, } from './connection-options'; import connectionOptions from './connection-options'; -import type { AppRegistry } from 'hadron-app-registry'; +import type { AppRegistry } from '@mongodb-js/compass-app-registry'; import type { IsPerformanceTabSupportedState, SetIsPerformanceTabSupportedAction, diff --git a/packages/compass-sidebar/src/modules/instance.spec.ts b/packages/compass-sidebar/src/modules/instance.spec.ts index f48f8b16047..c1c029311f5 100644 --- a/packages/compass-sidebar/src/modules/instance.spec.ts +++ b/packages/compass-sidebar/src/modules/instance.spec.ts @@ -4,7 +4,7 @@ import { spy, stub, type SinonSpy, type SinonStub } from 'sinon'; import type { DataService } from 'mongodb-data-service'; import { setupInstance } from './instance'; import type { RootState } from '.'; -import type AppRegistry from 'hadron-app-registry'; +import type AppRegistry from '@mongodb-js/compass-app-registry'; import type { Logger } from '@mongodb-js/compass-logging'; import type { MongoDBInstance, diff --git a/packages/compass-sidebar/src/stores/store.ts b/packages/compass-sidebar/src/stores/store.ts index 7bde8fdc9ab..5fa82dbe652 100644 --- a/packages/compass-sidebar/src/stores/store.ts +++ b/packages/compass-sidebar/src/stores/store.ts @@ -2,7 +2,10 @@ import { createStore, applyMiddleware } from 'redux'; import thunk from 'redux-thunk'; import reducer from '../modules'; import { closeInstance, setupInstance } from '../modules/instance'; -import type { ActivateHelpers, AppRegistry } from 'hadron-app-registry'; +import type { + ActivateHelpers, + AppRegistry, +} from '@mongodb-js/compass-app-registry'; import type { Logger } from '@mongodb-js/compass-logging/provider'; import { type MongoDBInstancesManager, diff --git a/packages/compass-smoke-tests/package.json b/packages/compass-smoke-tests/package.json index 631366d3824..060110f7847 100644 --- a/packages/compass-smoke-tests/package.json +++ b/packages/compass-smoke-tests/package.json @@ -11,7 +11,7 @@ "email": "compass@mongodb.com" }, "homepage": "https://github.com/mongodb-js/compass", - "version": "1.1.19", + "version": "1.1.20", "repository": { "type": "git", "url": "https://github.com/mongodb-js/compass.git" @@ -35,7 +35,7 @@ "@mongodb-js/prettier-config-compass": "^1.2.8", "@mongodb-js/tsconfig-compass": "^1.2.8", "@types/node": "^20", - "compass-e2e-tests": "^1.33.0", + "compass-e2e-tests": "^1.33.1", "depcheck": "^1.4.1", "debug": "^4.3.4", "hadron-build": "^25.8.2", diff --git a/packages/compass-smoke-tests/src/installers/windows-setup.ts b/packages/compass-smoke-tests/src/installers/windows-setup.ts index 4f580d939ca..21864cb5c3e 100644 --- a/packages/compass-smoke-tests/src/installers/windows-setup.ts +++ b/packages/compass-smoke-tests/src/installers/windows-setup.ts @@ -24,6 +24,7 @@ export function installWindowsSetup({ kind, filepath, buildInfo, + sandboxPath, }: InstallablePackage): InstalledAppInfo { assert.equal(kind, 'windows_setup'); const appName = buildInfo.installerOptions.name; @@ -62,7 +63,18 @@ export function installWindowsSetup({ debug(`Running command to uninstall: ${uninstallCommand}`); cp.execSync(uninstallCommand, { stdio: 'inherit' }); // Removing the any remaining files manually - fs.rmSync(installLocation, { recursive: true, force: true }); + try { + if (fs.existsSync(installLocation)) { + debug(`Removing installer: ${installLocation}`); + fs.rmSync(installLocation, { recursive: true, force: true }); + } + } catch (error) { + console.warn( + `Failed to remove install location ${installLocation}: ${ + error instanceof Error ? error.message : error + }` + ); + } } } @@ -72,7 +84,20 @@ export function installWindowsSetup({ console.warn( "Installing globally, since we haven't discovered a way to specify an install path" ); - execute(filepath, []); + execute( + filepath, + [ + // Args are passed through to the Update.exe https://github.com/Squirrel/Squirrel.Windows/blob/51f5e2cb01add79280a53d51e8d0cfa20f8c9f9f/src/Setup/winmain.cpp#L125 + // See options in https://github.com/Squirrel/Squirrel.Windows/blob/51f5e2cb01add79280a53d51e8d0cfa20f8c9f9f/src/Update/StartupOption.cs + '--silent', + ], + { + env: { + // See https://github.com/Squirrel/Squirrel.Windows/blob/51f5e2cb01add79280a53d51e8d0cfa20f8c9f9f/src/Setup/UpdateRunner.cpp#L173C40-L173C54 + SQUIRREL_TEMP: sandboxPath, + }, + } + ); const entry = queryRegistry(); assert(entry !== null, 'Expected an entry in the registry after installing'); @@ -84,6 +109,7 @@ export function installWindowsSetup({ const appExecutablePath = path.resolve(appPath, `${appName}.exe`); // Check if the app executable exists after installing + debug('Using app executable path: %s', appExecutablePath); assert( fs.existsSync(appExecutablePath), `Expected ${appExecutablePath} to exist` diff --git a/packages/compass-telemetry/package.json b/packages/compass-telemetry/package.json index 191314f6949..452ac3dbb86 100644 --- a/packages/compass-telemetry/package.json +++ b/packages/compass-telemetry/package.json @@ -53,7 +53,7 @@ }, "dependencies": { "@mongodb-js/compass-logging": "^1.7.2", - "hadron-app-registry": "^9.4.11", + "@mongodb-js/compass-app-registry": "^9.4.11", "hadron-ipc": "^3.5.2", "react": "^17.0.2" }, diff --git a/packages/compass-telemetry/src/provider.tsx b/packages/compass-telemetry/src/provider.tsx index 5cf4b56917c..3ff409becb3 100644 --- a/packages/compass-telemetry/src/provider.tsx +++ b/packages/compass-telemetry/src/provider.tsx @@ -1,5 +1,5 @@ import React, { useRef } from 'react'; -import { createServiceLocator } from 'hadron-app-registry'; +import { createServiceLocator } from '@mongodb-js/compass-app-registry'; import { createTrack, type TelemetryServiceOptions } from './generic-track'; import { useLogger } from '@mongodb-js/compass-logging/provider'; import type { TrackFunction } from './types'; diff --git a/packages/compass-web/package.json b/packages/compass-web/package.json index e9fe6a8c6aa..f5ba72a15e4 100644 --- a/packages/compass-web/package.json +++ b/packages/compass-web/package.json @@ -14,7 +14,7 @@ "email": "compass@mongodb.com" }, "homepage": "https://github.com/mongodb-js/compass", - "version": "0.17.3", + "version": "0.17.4", "repository": { "type": "git", "url": "https://github.com/mongodb-js/compass.git" @@ -63,30 +63,30 @@ "react-dom": "^17.0.2" }, "devDependencies": { - "@mongodb-js/atlas-service": "^0.45.0", - "@mongodb-js/compass-aggregations": "^9.62.0", - "@mongodb-js/compass-app-stores": "^7.46.0", - "@mongodb-js/compass-collection": "^4.59.0", - "@mongodb-js/compass-components": "^1.38.1", - "@mongodb-js/compass-connections": "^1.60.0", - "@mongodb-js/compass-crud": "^13.60.0", - "@mongodb-js/compass-data-modeling": "^1.11.0", - "@mongodb-js/compass-databases-collections": "^1.59.0", - "@mongodb-js/compass-explain-plan": "^6.60.0", - "@mongodb-js/compass-export-to-language": "^9.36.0", - "@mongodb-js/compass-field-store": "^9.35.0", - "@mongodb-js/compass-generative-ai": "^0.40.0", - "@mongodb-js/compass-global-writes": "^1.19.0", - "@mongodb-js/compass-indexes": "^5.59.0", + "@mongodb-js/atlas-service": "^0.46.0", + "@mongodb-js/compass-aggregations": "^9.63.0", + "@mongodb-js/compass-app-stores": "^7.47.0", + "@mongodb-js/compass-collection": "^4.60.0", + "@mongodb-js/compass-components": "^1.39.0", + "@mongodb-js/compass-connections": "^1.61.0", + "@mongodb-js/compass-crud": "^13.61.0", + "@mongodb-js/compass-data-modeling": "^1.12.0", + "@mongodb-js/compass-databases-collections": "^1.60.0", + "@mongodb-js/compass-explain-plan": "^6.61.0", + "@mongodb-js/compass-export-to-language": "^9.37.0", + "@mongodb-js/compass-field-store": "^9.36.0", + "@mongodb-js/compass-generative-ai": "^0.41.0", + "@mongodb-js/compass-global-writes": "^1.20.0", + "@mongodb-js/compass-indexes": "^5.60.0", "@mongodb-js/compass-logging": "^1.7.2", - "@mongodb-js/compass-query-bar": "^8.61.0", - "@mongodb-js/compass-schema": "^6.61.0", - "@mongodb-js/compass-schema-validation": "^6.60.0", - "@mongodb-js/compass-sidebar": "^5.60.0", + "@mongodb-js/compass-query-bar": "^8.62.0", + "@mongodb-js/compass-schema": "^6.62.0", + "@mongodb-js/compass-schema-validation": "^6.61.0", + "@mongodb-js/compass-sidebar": "^5.61.0", "@mongodb-js/compass-telemetry": "^1.10.0", - "@mongodb-js/compass-welcome": "^0.58.0", - "@mongodb-js/compass-workspaces": "^0.41.0", - "@mongodb-js/connection-storage": "^0.35.0", + "@mongodb-js/compass-welcome": "^0.59.0", + "@mongodb-js/compass-workspaces": "^0.42.0", + "@mongodb-js/connection-storage": "^0.36.0", "@mongodb-js/devtools-proxy-support": "^0.4.4", "@mongodb-js/eslint-config-compass": "^1.3.10", "@mongodb-js/mocha-config-compass": "^1.6.8", @@ -105,7 +105,7 @@ "bson": "^6.2.0", "buffer": "^6.0.3", "chai": "^4.3.6", - "compass-preferences-model": "^2.40.2", + "compass-preferences-model": "^2.41.0", "crypto-browserify": "^3.12.0", "debug": "^4.3.4", "depcheck": "^1.4.1", @@ -114,7 +114,7 @@ "events": "^3.3.0", "express": "^4.21.1", "express-http-proxy": "^2.0.0", - "hadron-app-registry": "^9.4.11", + "@mongodb-js/compass-app-registry": "^9.4.11", "is-ip": "^5.0.1", "lodash": "^4.17.21", "mocha": "^10.2.0", diff --git a/packages/compass-web/src/connection-storage.tsx b/packages/compass-web/src/connection-storage.tsx index f9b4584c152..584421306cb 100644 --- a/packages/compass-web/src/connection-storage.tsx +++ b/packages/compass-web/src/connection-storage.tsx @@ -8,7 +8,7 @@ import { ConnectionStorageProvider, InMemoryConnectionStorage, } from '@mongodb-js/connection-storage/provider'; -import { createServiceProvider } from 'hadron-app-registry'; +import { createServiceProvider } from '@mongodb-js/compass-app-registry'; import type { AtlasService } from '@mongodb-js/atlas-service/provider'; import { atlasServiceLocator } from '@mongodb-js/atlas-service/provider'; import { diff --git a/packages/compass-web/src/entrypoint.tsx b/packages/compass-web/src/entrypoint.tsx index 0a8b9a7e146..4598d8ab30c 100644 --- a/packages/compass-web/src/entrypoint.tsx +++ b/packages/compass-web/src/entrypoint.tsx @@ -2,7 +2,7 @@ import React, { useEffect, useRef } from 'react'; import AppRegistry, { AppRegistryProvider, GlobalAppRegistryProvider, -} from 'hadron-app-registry'; +} from '@mongodb-js/compass-app-registry'; import type { ConnectionInfo } from '@mongodb-js/compass-connections/provider'; import { useConnectionActions } from '@mongodb-js/compass-connections/provider'; import { CompassInstanceStorePlugin } from '@mongodb-js/compass-app-stores'; diff --git a/packages/compass-welcome/package.json b/packages/compass-welcome/package.json index 5a55d9110ae..1e3384c2a67 100644 --- a/packages/compass-welcome/package.json +++ b/packages/compass-welcome/package.json @@ -11,7 +11,7 @@ "email": "compass@mongodb.com" }, "homepage": "https://github.com/mongodb-js/compass", - "version": "0.58.0", + "version": "0.59.0", "repository": { "type": "git", "url": "https://github.com/mongodb-js/compass.git" @@ -49,13 +49,13 @@ "reformat": "npm run eslint . -- --fix && npm run prettier -- --write ." }, "dependencies": { - "@mongodb-js/compass-components": "^1.38.1", - "@mongodb-js/compass-connections": "^1.60.0", + "@mongodb-js/compass-components": "^1.39.0", + "@mongodb-js/compass-connections": "^1.61.0", "@mongodb-js/compass-logging": "^1.7.2", "@mongodb-js/compass-telemetry": "^1.10.0", - "@mongodb-js/compass-workspaces": "^0.41.0", - "compass-preferences-model": "^2.40.2", - "hadron-app-registry": "^9.4.11", + "@mongodb-js/compass-workspaces": "^0.42.0", + "compass-preferences-model": "^2.41.0", + "@mongodb-js/compass-app-registry": "^9.4.11", "react": "^17.0.2", "redux": "^4.2.1", "redux-thunk": "^2.4.2" diff --git a/packages/compass-welcome/src/index.ts b/packages/compass-welcome/src/index.ts index 21822f46a58..e0928310753 100644 --- a/packages/compass-welcome/src/index.ts +++ b/packages/compass-welcome/src/index.ts @@ -1,10 +1,12 @@ -import { registerHadronPlugin } from 'hadron-app-registry'; +import React from 'react'; +import { registerCompassPlugin } from '@mongodb-js/compass-app-registry'; import { createLoggerLocator } from '@mongodb-js/compass-logging/provider'; import { workspacesServiceLocator } from '@mongodb-js/compass-workspaces/provider'; -import type { WorkspaceComponent } from '@mongodb-js/compass-workspaces'; +import type { WorkspacePlugin } from '@mongodb-js/compass-workspaces'; import { WelcomeModal, DesktopWelcomeTab, WebWelcomeTab } from './components'; import { activatePlugin } from './stores'; import { telemetryLocator } from '@mongodb-js/compass-telemetry/provider'; +import { PluginTabTitleComponent, WorkspaceName } from './plugin-tab-title'; const serviceLocators = { logger: createLoggerLocator('COMPASS-MY-QUERIES-UI'), @@ -12,28 +14,36 @@ const serviceLocators = { workspaces: workspacesServiceLocator, }; -export const DesktopWorkspaceTab: WorkspaceComponent<'Welcome'> = { - name: 'Welcome' as const, - component: registerHadronPlugin( +export const DesktopWorkspaceTab: WorkspacePlugin = { + name: WorkspaceName, + provider: registerCompassPlugin( { - name: 'Welcome', - component: DesktopWelcomeTab, + name: WorkspaceName, + component: function WelcomeProvider({ children }) { + return React.createElement(React.Fragment, null, children); + }, activate: activatePlugin, }, serviceLocators ), + content: DesktopWelcomeTab, + header: PluginTabTitleComponent, }; -export const WebWorkspaceTab: WorkspaceComponent<'Welcome'> = { - name: 'Welcome' as const, - component: registerHadronPlugin( +export const WebWorkspaceTab: WorkspacePlugin = { + name: WorkspaceName, + provider: registerCompassPlugin( { - name: 'Welcome', - component: WebWelcomeTab, + name: WorkspaceName, + component: function WelcomeProvider({ children }) { + return React.createElement(React.Fragment, null, children); + }, activate: activatePlugin, }, serviceLocators ), + content: WebWelcomeTab, + header: PluginTabTitleComponent, }; export { WelcomeModal }; diff --git a/packages/compass-welcome/src/plugin-tab-title.tsx b/packages/compass-welcome/src/plugin-tab-title.tsx new file mode 100644 index 00000000000..ce564c7159b --- /dev/null +++ b/packages/compass-welcome/src/plugin-tab-title.tsx @@ -0,0 +1,22 @@ +import React from 'react'; +import { + WorkspaceTab, + type WorkspaceTabCoreProps, +} from '@mongodb-js/compass-components'; +import type { WorkspacePluginProps } from '@mongodb-js/compass-workspaces'; + +export const WorkspaceName = 'Welcome' as const; + +type PluginTitleComponentProps = WorkspaceTabCoreProps & + WorkspacePluginProps; + +export function PluginTabTitleComponent(props: PluginTitleComponentProps) { + return ( + + ); +} diff --git a/packages/compass-welcome/src/stores/index.ts b/packages/compass-welcome/src/stores/index.ts index fa8f89a9417..0f54fc49d3b 100644 --- a/packages/compass-welcome/src/stores/index.ts +++ b/packages/compass-welcome/src/stores/index.ts @@ -1,4 +1,4 @@ -import type AppRegistry from 'hadron-app-registry'; +import type AppRegistry from '@mongodb-js/compass-app-registry'; import { createStore, applyMiddleware, combineReducers } from 'redux'; import thunk from 'redux-thunk'; import type { Logger } from '@mongodb-js/compass-logging/provider'; diff --git a/packages/compass-workspaces/package.json b/packages/compass-workspaces/package.json index ed44e0031e7..fab0c46b717 100644 --- a/packages/compass-workspaces/package.json +++ b/packages/compass-workspaces/package.json @@ -11,7 +11,7 @@ "email": "compass@mongodb.com" }, "homepage": "https://github.com/mongodb-js/compass", - "version": "0.41.0", + "version": "0.42.0", "repository": { "type": "git", "url": "https://github.com/mongodb-js/compass.git" @@ -51,13 +51,13 @@ "reformat": "npm run eslint . -- --fix && npm run prettier -- --write ." }, "dependencies": { - "@mongodb-js/compass-app-stores": "^7.46.0", - "@mongodb-js/compass-components": "^1.38.1", - "@mongodb-js/compass-connections": "^1.60.0", + "@mongodb-js/compass-app-stores": "^7.47.0", + "@mongodb-js/compass-components": "^1.39.0", + "@mongodb-js/compass-connections": "^1.61.0", "@mongodb-js/compass-logging": "^1.7.2", "bson": "^6.10.3", - "hadron-app-registry": "^9.4.11", - "compass-preferences-model": "^2.40.2", + "@mongodb-js/compass-app-registry": "^9.4.11", + "compass-preferences-model": "^2.41.0", "lodash": "^4.17.21", "mongodb-collection-model": "^5.29.2", "mongodb-database-model": "^2.29.2", diff --git a/packages/compass-workspaces/src/components/index.tsx b/packages/compass-workspaces/src/components/index.tsx index 35593bce19f..490192d6135 100644 --- a/packages/compass-workspaces/src/components/index.tsx +++ b/packages/compass-workspaces/src/components/index.tsx @@ -4,9 +4,9 @@ import type { CollectionTabInfo } from '../stores/workspaces'; import { getActiveTab, type OpenWorkspaceOptions, - type WorkspaceTab, type WorkspacesState, } from '../stores/workspaces'; +import type { WorkspaceTab } from '../types'; import Workspaces from './workspaces'; import { connect } from '../stores/context'; import { WorkspacesServiceProvider } from '../provider'; diff --git a/packages/compass-workspaces/src/components/workspace-close-handler.tsx b/packages/compass-workspaces/src/components/workspace-close-handler.tsx index 96b2cd9bcf1..e254cf94aff 100644 --- a/packages/compass-workspaces/src/components/workspace-close-handler.tsx +++ b/packages/compass-workspaces/src/components/workspace-close-handler.tsx @@ -1,5 +1,5 @@ import { useEffect, useRef } from 'react'; -import type { WorkspaceTab } from '../stores/workspaces'; +import type { WorkspaceTab } from '../types'; import { useWorkspaceTabId } from './workspace-tab-state-provider'; export type WorkspaceDestroyHandler = () => boolean; diff --git a/packages/compass-workspaces/src/components/workspace-tab-context-provider.tsx b/packages/compass-workspaces/src/components/workspace-tab-context-provider.tsx index 6a3a1d8dade..bb1dfc716f9 100644 --- a/packages/compass-workspaces/src/components/workspace-tab-context-provider.tsx +++ b/packages/compass-workspaces/src/components/workspace-tab-context-provider.tsx @@ -1,8 +1,6 @@ import React, { useCallback, useEffect, useRef } from 'react'; -import { - getLocalAppRegistryForTab, - type WorkspaceTab, -} from '../stores/workspaces'; +import { getLocalAppRegistryForTab } from '../stores/workspaces'; +import type { WorkspaceTab } from '../types'; import { NamespaceProvider } from '@mongodb-js/compass-app-stores/provider'; import { ConnectionInfoProvider } from '@mongodb-js/compass-connections/provider'; import { rafraf } from '@mongodb-js/compass-components'; @@ -11,7 +9,8 @@ import { useTabState, WorkspaceTabStateProvider, } from './workspace-tab-state-provider'; -import { AppRegistryProvider } from 'hadron-app-registry'; +import { AppRegistryProvider } from '@mongodb-js/compass-app-registry'; +import { useWorkspacePlugins } from './workspaces-provider'; function getInitialPropsForWorkspace(tab: WorkspaceTab) { switch (tab.type) { @@ -81,21 +80,42 @@ const TabCloseHandler: React.FunctionComponent = ({ children }) => { ); }; -const WorkspaceTabContextProvider: React.FunctionComponent<{ +type WorkspaceTabContextProviderProps = { tab: WorkspaceTab; - sectionType: 'tab-content' | 'tab-title'; - onNamespaceNotFound?: ( - tab: Extract, - fallbackNamespace: string | null - ) => void; children: React.JSX.Element; -}> = ({ tab, onNamespaceNotFound, sectionType: type, children }) => { +} & ( + | { + sectionType: 'tab-content'; + onNamespaceNotFound: ( + tab: Extract, + fallbackNamespace: string | null + ) => void; + } + | { + sectionType: 'tab-title'; + onNamespaceNotFound?: undefined; + } +); + +const WorkspaceTabContextProvider: React.FunctionComponent< + WorkspaceTabContextProviderProps +> = ({ tab, onNamespaceNotFound, sectionType: type, children }) => { const initialProps = getInitialPropsForWorkspace(tab); + const { getWorkspacePluginByName } = useWorkspacePlugins(); + + const { provider: WorkspaceProvider } = getWorkspacePluginByName(tab.type); if (initialProps) { children = React.cloneElement(children, initialProps); } + // The ordering of the these providers is important, + // the workspace provider needs access to the + // connection info and namespace providers. + children = ( + {children} + ); + if ('namespace' in tab) { children = ( - | WorkspaceComponent<'My Queries'> - | WorkspaceComponent<'Data Modeling'> - | WorkspaceComponent<'Shell'> - | WorkspaceComponent<'Performance'> - | WorkspaceComponent<'Databases'> - | WorkspaceComponent<'Collections'> - | WorkspaceComponent<'Collection'>; +export type AnyWorkspacePlugin = + | WorkspacePlugin<'Welcome'> + | WorkspacePlugin<'My Queries'> + | WorkspacePlugin<'Data Modeling'> + | WorkspacePlugin<'Shell'> + | WorkspacePlugin<'Performance'> + | WorkspacePlugin<'Databases'> + | WorkspacePlugin<'Collections'> + | WorkspacePlugin<'Collection'>; -const WorkspacesContext = React.createContext([]); +const WorkspacesContext = React.createContext([]); export const WorkspacesProvider: React.FunctionComponent<{ - value: AnyWorkspaceComponent[]; + value: AnyWorkspacePlugin[]; }> = ({ value, children }) => { const valueRef = useRef(value); return ( @@ -30,17 +31,17 @@ export const useWorkspacePlugins = () => { hasWorkspacePlugin: (name: T) => { return workspaces.some((ws) => ws.name === name); }, - getWorkspacePluginByName: (name?: T) => { - if (!name) { - return null; - } + getWorkspacePlugins: (): AnyWorkspacePlugin[] => { + return workspaces; + }, + getWorkspacePluginByName: (name: T) => { const plugin = workspaces.find((ws) => ws.name === name); if (!plugin) { throw new Error( `Component for workspace "${name}" is missing in context. Did you forget to set up WorkspacesProvider?` ); } - return plugin.component as unknown as WorkspaceComponent['component']; + return plugin as unknown as WorkspacePlugin; }, }); return workspacePlugins.current; diff --git a/packages/compass-workspaces/src/components/workspaces.tsx b/packages/compass-workspaces/src/components/workspaces.tsx index ad873735703..61a2e5de1e1 100644 --- a/packages/compass-workspaces/src/components/workspaces.tsx +++ b/packages/compass-workspaces/src/components/workspaces.tsx @@ -4,15 +4,14 @@ import { MongoDBLogoMark, WorkspaceTabs, css, - palette, spacing, useDarkMode, + type WorkspaceTabCoreProps, } from '@mongodb-js/compass-components'; import type { CollectionTabInfo, DatabaseTabInfo, OpenWorkspaceOptions, - WorkspaceTab, WorkspacesState, } from '../stores/workspaces'; import { @@ -29,11 +28,8 @@ import { useWorkspacePlugins } from './workspaces-provider'; import toNS from 'mongodb-ns'; import { useLogger } from '@mongodb-js/compass-logging/provider'; import { connect } from '../stores/context'; -import { useTabConnectionTheme } from '@mongodb-js/compass-connections/provider'; -import { useConnectionsListRef } from '@mongodb-js/compass-connections/provider'; import { WorkspaceTabContextProvider } from './workspace-tab-context-provider'; - -type Tooltip = [string, string][]; +import type { WorkspaceTab } from '../types'; const emptyWorkspaceStyles = css({ margin: '0 auto', @@ -86,10 +82,6 @@ type CompassWorkspacesProps = { ): void; }; -const nonExistantStyles = css({ - color: palette.gray.base, -}); - const CompassWorkspaces: React.FunctionComponent = ({ tabs, activeTab, @@ -106,159 +98,98 @@ const CompassWorkspaces: React.FunctionComponent = ({ }) => { const { log, mongoLogId } = useLogger('COMPASS-WORKSPACES'); const { getWorkspacePluginByName } = useWorkspacePlugins(); - const { getThemeOf } = useTabConnectionTheme(); - const { getConnectionById } = useConnectionsListRef(); - - const tabDescriptions = useMemo(() => { - return tabs.map((tab) => { - switch (tab.type) { - case 'Welcome': - return { - id: tab.id, - type: tab.type, - title: tab.type, - iconGlyph: 'Logo', - } as const; - case 'My Queries': - return { - id: tab.id, - type: tab.type, - title: tab.type, - iconGlyph: 'CurlyBraces', - } as const; - case 'Data Modeling': - return { - id: tab.id, - type: tab.type, - title: tab.type, - iconGlyph: 'Diagram' as const, - }; - case 'Shell': { - const connectionName = - getConnectionById(tab.connectionId)?.title || ''; - const tooltip: Tooltip = []; - if (connectionName) { - tooltip.push(['mongosh', connectionName || '']); - } - return { - id: tab.id, - connectionName, - type: tab.type, - title: connectionName - ? `mongosh: ${connectionName}` - : 'MongoDB Shell', - tooltip, - iconGlyph: 'Shell', - tabTheme: getThemeOf(tab.connectionId), - } as const; - } - case 'Databases': { - const connectionName = - getConnectionById(tab.connectionId)?.title || ''; - return { - id: tab.id, - connectionName, - type: tab.type, - title: connectionName, - tooltip: [['Connection', connectionName || '']] as Tooltip, - iconGlyph: 'Server', - tabTheme: getThemeOf(tab.connectionId), - } as const; - } - case 'Performance': { - const connectionName = - getConnectionById(tab.connectionId)?.title || ''; - return { - id: tab.id, - connectionName, - type: tab.type, - title: `Performance: ${connectionName}`, - tooltip: [['Performance', connectionName || '']] as Tooltip, - iconGlyph: 'Gauge', - tabTheme: getThemeOf(tab.connectionId), - } as const; - } - case 'Collections': { - const connectionName = - getConnectionById(tab.connectionId)?.title || ''; - const database = tab.namespace; - const namespaceId = `${tab.connectionId}.${database}`; - const { isNonExistent } = databaseInfo[namespaceId] ?? {}; - return { - id: tab.id, - connectionName, - type: tab.type, - title: database, - tooltip: [ - ['Connection', connectionName || ''], - ['Database', database], - ] as Tooltip, - iconGlyph: isNonExistent ? 'EmptyDatabase' : 'Database', - 'data-namespace': tab.namespace, - tabTheme: getThemeOf(tab.connectionId), - ...(isNonExistent && { - className: nonExistantStyles, - }), - } as const; - } - case 'Collection': { - const { database, collection, ns } = toNS(tab.namespace); - const namespaceId = `${tab.connectionId}.${ns}`; - const info = collectionInfo[namespaceId] ?? {}; - const { isTimeSeries, isReadonly, sourceName, isNonExistent } = info; - const connectionName = - getConnectionById(tab.connectionId)?.title || ''; - const collectionType = isTimeSeries - ? 'timeseries' - : isReadonly - ? 'view' - : 'collection'; - // Similar to what we have in the collection breadcrumbs. - const tooltip: Tooltip = [ - ['Connection', connectionName || ''], - ['Database', database], - ]; - if (sourceName) { - tooltip.push(['View', collection]); - tooltip.push(['Derived from', toNS(sourceName).collection]); - } else if (tab.editViewName) { - tooltip.push(['View', toNS(tab.editViewName).collection]); - tooltip.push(['Derived from', collection]); - } else { - tooltip.push(['Collection', collection]); - } - return { - id: tab.id, - connectionName, - type: tab.type, - title: collection, - tooltip, - iconGlyph: - collectionType === 'view' - ? 'Visibility' - : collectionType === 'timeseries' - ? 'TimeSeries' - : isNonExistent - ? 'EmptyFolder' - : 'Folder', - 'data-namespace': ns, - tabTheme: getThemeOf(tab.connectionId), - ...(isNonExistent && { - className: nonExistantStyles, - }), - } as const; - } - } - }); - }, [tabs, collectionInfo, databaseInfo, getThemeOf, getConnectionById]); const activeTabIndex = tabs.findIndex((tab) => tab === activeTab); - const WorkspaceComponent = getWorkspacePluginByName(activeTab?.type); const onCreateNewTab = useCallback(() => { onCreateTab(openOnEmptyWorkspace); }, [onCreateTab, openOnEmptyWorkspace]); + const workspaceTabs = useMemo(() => { + return tabs.map((tab) => { + const plugin = getWorkspacePluginByName(tab.type); + if (!plugin) { + throw new Error( + `Content component for workspace "${tab.type}" is missing in context. Did you forget to set up WorkspacesProvider?` + ); + } + const { content: WorkspaceTabContent, header: WorkspaceTabTitle } = + plugin; + + let isNonExistent: boolean | undefined; + if (tab.type === 'Collections') { + // TODO(COMPASS-9456): Move this logic and `isNonExistent` setting to the plugin. + const database = tab.namespace; + const namespaceId = `${tab.connectionId}.${database}`; + const { isNonExistent: databaseDoesNotExist } = + databaseInfo[namespaceId] ?? {}; + isNonExistent = databaseDoesNotExist; + } else if (tab.type === 'Collection') { + // TODO(COMPASS-9456): Move this logic and `isNonExistent` setting to the plugin. + const { ns } = toNS(tab.namespace); + const namespaceId = `${tab.connectionId}.${ns}`; + const { isNonExistent: collectionDoesNotExist } = + collectionInfo[namespaceId] ?? {}; + isNonExistent = collectionDoesNotExist; + } + + return { + id: tab.id, + renderTab: (workspaceTabCoreProps: WorkspaceTabCoreProps) => ( + { + log.error( + mongoLogId(1_001_000_360), + 'Workspace', + 'Rendering workspace tab header failed', + { name: tab.type, error: error.message, errorInfo } + ); + }} + > + + + + + ), + content: ( + { + log.error( + mongoLogId(1_001_000_277), + 'Workspace', + 'Rendering workspace tab content failed', + { name: tab.type, error: error.message, errorInfo } + ); + }} + > + + + + + ), + }; + }); + }, [ + getWorkspacePluginByName, + tabs, + log, + collectionInfo, + databaseInfo, + mongoLogId, + onNamespaceNotFound, + ]); + + const workspaceTabContent = workspaceTabs[activeTabIndex]?.content ?? null; + return (
= ({ onMoveTab={onMoveTab} onCreateNewTab={onCreateNewTab} onCloseTab={onCloseTab} - tabs={tabDescriptions} + tabs={workspaceTabs} selectedTabIndex={activeTabIndex} >
- {activeTab && WorkspaceComponent ? ( - { - log.error( - mongoLogId(1_001_000_277), - 'Workspace', - 'Rendering workspace tab failed', - { name: activeTab.type, error: error.message, errorInfo } - ); - }} - > - - - - + {activeTab && workspaceTabContent ? ( + workspaceTabContent ) : ( )} diff --git a/packages/compass-workspaces/src/index.spec.tsx b/packages/compass-workspaces/src/index.spec.tsx index 7ee10abb955..7bc542d8fc7 100644 --- a/packages/compass-workspaces/src/index.spec.tsx +++ b/packages/compass-workspaces/src/index.spec.tsx @@ -2,7 +2,7 @@ import React from 'react'; import { expect } from 'chai'; import WorkspacesPlugin, { WorkspacesProvider } from './index'; import Sinon from 'sinon'; -import type { AnyWorkspaceComponent } from './components/workspaces-provider'; +import type { AnyWorkspacePlugin } from './components/workspaces-provider'; import { useOpenWorkspace } from './provider'; import { renderWithConnections, @@ -12,14 +12,35 @@ import { userEvent, } from '@mongodb-js/testing-library-compass'; import { TestMongoDBInstanceManager } from '@mongodb-js/compass-app-stores/provider'; +import { WorkspaceTab } from '@mongodb-js/compass-components'; function mockWorkspace(name: string) { return { name, - component: function Component() { + provider: function Component({ + children, + props, + }: { + children?: React.ReactNode; + props?: any; + }) { + return
{children}
; + }, + content: function Component() { return <>{name}; }, - } as unknown as AnyWorkspaceComponent; + header: function Component(props: any) { + return ( + + ); + }, + } as unknown as AnyWorkspacePlugin; } const TEST_CONNECTION_INFO = { @@ -71,10 +92,33 @@ describe('WorkspacesPlugin', function () { connectFn() { return { listDatabases() { - return Promise.resolve([]); + return Promise.resolve([ + // Mock the databases and collections so we don't trigger the onNamespaceNotFound + // fallback handler which redirects collections to the databases view. + { + _id: 'db', + name: 'db', + is_non_existent: false, + collection_count: 0, + document_count: 0, + index_count: 0, + storage_size: 0, + data_size: 0, + index_size: 0, + }, + ]); }, listCollections() { - return Promise.resolve([]); + return Promise.resolve( + Array.from({ + length: 3, + }).map((_, index) => ({ + _id: `db.coll${index}`, + name: `coll${index}`, + database: 'db', + type: 'collection', + })) as any + ); }, }; }, @@ -90,16 +134,12 @@ describe('WorkspacesPlugin', function () { cleanup(); }); - const connectionName = TEST_CONNECTION_INFO.favorite.name; const tabs = [ ['My Queries', () => openFns.openMyQueriesWorkspace()], - [connectionName, () => openFns.openDatabasesWorkspace('1')], // Databases - [ - `Performance: ${connectionName}`, - () => openFns.openPerformanceWorkspace('1'), - ], + ['Databases', () => openFns.openDatabasesWorkspace('1')], + ['Performance', () => openFns.openPerformanceWorkspace('1')], ['db', () => openFns.openCollectionsWorkspace('1', 'db')], - ['coll', () => openFns.openCollectionWorkspace('1', 'db.coll')], + ['db.coll0', () => openFns.openCollectionWorkspace('1', 'db.coll0')], ] as const; for (const suite of tabs) { @@ -118,23 +158,25 @@ describe('WorkspacesPlugin', function () { expect(onTabChangeSpy).to.have.been.calledWith(null); + openFns.openCollectionWorkspace('1', 'db.coll0', { newTab: true }); openFns.openCollectionWorkspace('1', 'db.coll1', { newTab: true }); openFns.openCollectionWorkspace('1', 'db.coll2', { newTab: true }); - openFns.openCollectionWorkspace('1', 'db.coll3', { newTab: true }); - expect(screen.getByRole('tab', { name: 'coll3' })).to.have.attribute( - 'aria-selected', - 'true' - ); + await waitFor(() => { + expect(screen.getByRole('tab', { name: 'db.coll2' })).to.have.attribute( + 'aria-selected', + 'true' + ); + }); - userEvent.click(screen.getByRole('tab', { name: 'coll1' })); + userEvent.click(screen.getByRole('tab', { name: 'db.coll0' })); await waitFor(() => { - expect(screen.getByRole('tab', { name: /coll3/i })).to.have.attribute( + expect(screen.getByRole('tab', { name: 'db.coll2' })).to.have.attribute( 'aria-selected', 'false' ); - expect(screen.getByRole('tab', { name: /coll1/i })).to.have.attribute( + expect(screen.getByRole('tab', { name: 'db.coll0' })).to.have.attribute( 'aria-selected', 'true' ); diff --git a/packages/compass-workspaces/src/index.ts b/packages/compass-workspaces/src/index.ts index 92a90f7b2be..e87b816e759 100644 --- a/packages/compass-workspaces/src/index.ts +++ b/packages/compass-workspaces/src/index.ts @@ -1,9 +1,8 @@ -import type AppRegistry from 'hadron-app-registry'; -import type { ActivateHelpers } from 'hadron-app-registry'; -import { registerHadronPlugin } from 'hadron-app-registry'; +import type AppRegistry from '@mongodb-js/compass-app-registry'; +import type { ActivateHelpers } from '@mongodb-js/compass-app-registry'; +import { registerCompassPlugin } from '@mongodb-js/compass-app-registry'; import type { OpenWorkspaceOptions, - WorkspaceTab, CollectionTabInfo, } from './stores/workspaces'; import workspacesReducer, { @@ -222,7 +221,7 @@ export function activateWorkspacePlugin( }; } -const WorkspacesPlugin = registerHadronPlugin( +const WorkspacesPlugin = registerCompassPlugin( { name: 'Workspaces', component: Workspaces, @@ -238,7 +237,7 @@ const WorkspacesPlugin = registerHadronPlugin( export default WorkspacesPlugin; export { WorkspacesProvider } from './components/workspaces-provider'; -export type { OpenWorkspaceOptions, WorkspaceTab, CollectionTabInfo }; +export type { OpenWorkspaceOptions, CollectionTabInfo }; export type { WelcomeWorkspace, MyQueriesWorkspace, @@ -250,7 +249,8 @@ export type { CollectionWorkspace, AnyWorkspace, Workspace, - WorkspacePluginProps, - WorkspaceComponent, + WorkspacePlugin, + WorkspaceTab, CollectionSubtab, + WorkspacePluginProps, } from './types'; diff --git a/packages/compass-workspaces/src/provider.tsx b/packages/compass-workspaces/src/provider.tsx index edd627abb84..aa311c736c1 100644 --- a/packages/compass-workspaces/src/provider.tsx +++ b/packages/compass-workspaces/src/provider.tsx @@ -1,17 +1,13 @@ import React, { useContext, useRef } from 'react'; import { useSelector, useStore } from './stores/context'; -import type { - OpenWorkspaceOptions, - TabOptions, - WorkspaceTab, -} from './stores/workspaces'; +import type { OpenWorkspaceOptions, TabOptions } from './stores/workspaces'; import { collectionSubtabSelected, getActiveTab, openWorkspace as openWorkspaceAction, } from './stores/workspaces'; -import { createServiceLocator } from 'hadron-app-registry'; -import type { CollectionSubtab } from './types'; +import { createServiceLocator } from '@mongodb-js/compass-app-registry'; +import type { CollectionSubtab, WorkspaceTab } from './types'; import type { WorkspaceDestroyHandler } from './components/workspace-close-handler'; import { useRegisterTabDestroyHandler } from './components/workspace-close-handler'; diff --git a/packages/compass-workspaces/src/stores/workspaces.spec.ts b/packages/compass-workspaces/src/stores/workspaces.spec.ts index 86bc9c4f0aa..86105e40f28 100644 --- a/packages/compass-workspaces/src/stores/workspaces.spec.ts +++ b/packages/compass-workspaces/src/stores/workspaces.spec.ts @@ -6,7 +6,7 @@ import * as workspacesSlice from './workspaces'; import { _bulkTabsClose } from './workspaces'; import { TestMongoDBInstanceManager } from '@mongodb-js/compass-app-stores/provider'; import type { ConnectionInfo } from '../../../connection-info/dist'; -import type { WorkspaceTab } from '../stores/workspaces'; +import type { WorkspaceTab } from '../types'; import { setTabDestroyHandler } from '../components/workspace-close-handler'; import { createPluginTestHelpers } from '@mongodb-js/testing-library-compass'; diff --git a/packages/compass-workspaces/src/stores/workspaces.ts b/packages/compass-workspaces/src/stores/workspaces.ts index 214165c51ae..32e685d25ec 100644 --- a/packages/compass-workspaces/src/stores/workspaces.ts +++ b/packages/compass-workspaces/src/stores/workspaces.ts @@ -1,21 +1,10 @@ import type { Reducer, AnyAction, Action } from 'redux'; import type { ThunkAction } from 'redux-thunk'; import { ObjectId } from 'bson'; -import AppRegistry from 'hadron-app-registry'; +import AppRegistry from '@mongodb-js/compass-app-registry'; import toNS from 'mongodb-ns'; -import type { - CollectionWorkspace, - CollectionsWorkspace, - DatabasesWorkspace, - MyQueriesWorkspace, - DataModelingWorkspace, - ShellWorkspace, - ServerStatsWorkspace, - WelcomeWorkspace, - Workspace, - WorkspacesServices, - CollectionSubtab, -} from '..'; +import type { Workspace, WorkspacesServices, CollectionSubtab } from '..'; +import type { WorkspaceTab, WorkspaceTabProps } from '../types'; import { isEqual } from 'lodash'; import { cleanupTabState } from '../components/workspace-tab-state-provider'; import { @@ -83,22 +72,6 @@ function isAction
( return action.type === type; } -type WorkspaceTabProps = - | Omit - | Omit - | Omit - | Omit - | Omit - | Omit - | Omit - | (Omit & { - subTab: CollectionSubtab; - }); - -export type WorkspaceTab = { - id: string; -} & WorkspaceTabProps; - export type CollectionTabInfo = { isTimeSeries: boolean; isReadonly: boolean; diff --git a/packages/compass-workspaces/src/types.ts b/packages/compass-workspaces/src/types.ts index a744c060e61..2cbbc9b6458 100644 --- a/packages/compass-workspaces/src/types.ts +++ b/packages/compass-workspaces/src/types.ts @@ -1,3 +1,6 @@ +import type { CompassPluginComponent } from '@mongodb-js/compass-app-registry'; +import type { WorkspaceTabCoreProps } from '@mongodb-js/compass-components'; + export type CollectionSubtab = | 'Documents' | 'Aggregations' @@ -39,6 +42,8 @@ export type CollectionsWorkspace = { type: 'Collections'; connectionId: string; namespace: string; + // TODO(COMPASS-9456): Remove the `isNonExistent` field here. + isNonExistent?: boolean; }; export type CollectionWorkspace = { @@ -56,8 +61,26 @@ export type CollectionWorkspace = { initialPipelineText?: string; initialAggregation?: unknown; editViewName?: string; + // TODO(COMPASS-9456): Remove the `isNonExistent` field here. + isNonExistent?: boolean; }; +export type WorkspaceTabProps = + | WelcomeWorkspace + | MyQueriesWorkspace + | DataModelingWorkspace + | ShellWorkspace + | ServerStatsWorkspace + | DatabasesWorkspace + | CollectionsWorkspace + | (Omit & { + subTab: CollectionSubtab; + }); + +export type WorkspaceTab = { + id: string; +} & WorkspaceTabProps; + export type AnyWorkspace = | WelcomeWorkspace | MyQueriesWorkspace @@ -78,9 +101,12 @@ export type WorkspacePluginProps = Omit< 'type' | 'connectionId' >; -export type WorkspaceComponent = { +export type PluginHeaderProps = + WorkspaceTabCoreProps & WorkspacePluginProps; + +export type WorkspacePlugin = { name: T; - component: - | React.ComponentClass> - | ((props: WorkspacePluginProps) => React.ReactElement | null); + provider: CompassPluginComponent; + content: (props: WorkspacePluginProps) => React.ReactElement | null; + header: (props: PluginHeaderProps) => React.ReactElement | null; }; diff --git a/packages/compass/package.json b/packages/compass/package.json index 03921fb01b0..6b3dbb93c30 100644 --- a/packages/compass/package.json +++ b/packages/compass/package.json @@ -194,46 +194,46 @@ "devDependencies": { "@electron/rebuild": "^4.0.1", "@electron/remote": "^2.1.2", - "@mongodb-js/atlas-service": "^0.45.0", - "@mongodb-js/compass-aggregations": "^9.62.0", - "@mongodb-js/compass-app-stores": "^7.46.0", - "@mongodb-js/compass-collection": "^4.59.0", - "@mongodb-js/compass-components": "^1.38.1", - "@mongodb-js/compass-connection-import-export": "^0.56.0", - "@mongodb-js/compass-connections": "^1.60.0", - "@mongodb-js/compass-crud": "^13.60.0", - "@mongodb-js/compass-data-modeling": "^1.11.0", - "@mongodb-js/compass-databases-collections": "^1.59.0", - "@mongodb-js/compass-explain-plan": "^6.60.0", - "@mongodb-js/compass-export-to-language": "^9.36.0", - "@mongodb-js/compass-field-store": "^9.35.0", - "@mongodb-js/compass-find-in-page": "^4.39.2", - "@mongodb-js/compass-generative-ai": "^0.40.0", - "@mongodb-js/compass-global-writes": "^1.19.0", - "@mongodb-js/compass-import-export": "^7.59.0", - "@mongodb-js/compass-indexes": "^5.59.0", - "@mongodb-js/compass-intercom": "^0.24.2", + "@mongodb-js/atlas-service": "^0.46.0", + "@mongodb-js/compass-aggregations": "^9.63.0", + "@mongodb-js/compass-app-stores": "^7.47.0", + "@mongodb-js/compass-collection": "^4.60.0", + "@mongodb-js/compass-components": "^1.39.0", + "@mongodb-js/compass-connection-import-export": "^0.57.0", + "@mongodb-js/compass-connections": "^1.61.0", + "@mongodb-js/compass-crud": "^13.61.0", + "@mongodb-js/compass-data-modeling": "^1.12.0", + "@mongodb-js/compass-databases-collections": "^1.60.0", + "@mongodb-js/compass-explain-plan": "^6.61.0", + "@mongodb-js/compass-export-to-language": "^9.37.0", + "@mongodb-js/compass-field-store": "^9.36.0", + "@mongodb-js/compass-find-in-page": "^4.40.0", + "@mongodb-js/compass-generative-ai": "^0.41.0", + "@mongodb-js/compass-global-writes": "^1.20.0", + "@mongodb-js/compass-import-export": "^7.60.0", + "@mongodb-js/compass-indexes": "^5.60.0", + "@mongodb-js/compass-intercom": "^0.25.0", "@mongodb-js/compass-logging": "^1.7.2", - "@mongodb-js/compass-query-bar": "^8.61.0", - "@mongodb-js/compass-saved-aggregations-queries": "^1.60.0", - "@mongodb-js/compass-schema": "^6.61.0", - "@mongodb-js/compass-schema-validation": "^6.60.0", - "@mongodb-js/compass-serverstats": "^16.59.0", - "@mongodb-js/compass-settings": "^0.58.0", - "@mongodb-js/compass-shell": "^3.59.0", - "@mongodb-js/compass-sidebar": "^5.60.0", + "@mongodb-js/compass-query-bar": "^8.62.0", + "@mongodb-js/compass-saved-aggregations-queries": "^1.61.0", + "@mongodb-js/compass-schema": "^6.62.0", + "@mongodb-js/compass-schema-validation": "^6.61.0", + "@mongodb-js/compass-serverstats": "^16.60.0", + "@mongodb-js/compass-settings": "^0.59.0", + "@mongodb-js/compass-shell": "^3.60.0", + "@mongodb-js/compass-sidebar": "^5.61.0", "@mongodb-js/compass-telemetry": "^1.10.0", "@mongodb-js/compass-utils": "^0.9.2", - "@mongodb-js/compass-welcome": "^0.58.0", - "@mongodb-js/compass-workspaces": "^0.41.0", + "@mongodb-js/compass-welcome": "^0.59.0", + "@mongodb-js/compass-workspaces": "^0.42.0", "@mongodb-js/connection-info": "^0.15.2", - "@mongodb-js/connection-storage": "^0.35.0", + "@mongodb-js/connection-storage": "^0.36.0", "@mongodb-js/devtools-proxy-support": "^0.4.4", "@mongodb-js/eslint-config-compass": "^1.3.10", "@mongodb-js/get-os-info": "^0.4.0", "@mongodb-js/mocha-config-compass": "^1.6.8", "@mongodb-js/mongodb-downloader": "^0.3.7", - "@mongodb-js/my-queries-storage": "^0.27.3", + "@mongodb-js/my-queries-storage": "^0.28.0", "@mongodb-js/prettier-config-compass": "^1.2.8", "@mongodb-js/sbom-tools": "^0.7.2", "@mongodb-js/signing-utils": "^0.3.8", @@ -246,7 +246,7 @@ "chai": "^4.3.4", "chalk": "^4.1.2", "clean-stack": "^2.0.0", - "compass-preferences-model": "^2.40.2", + "compass-preferences-model": "^2.41.0", "cross-spawn": "^7.0.5", "debug": "^4.3.4", "depcheck": "^1.4.1", @@ -256,7 +256,7 @@ "electron-mocha": "^12.2.0", "ensure-error": "^3.0.1", "glob": "^10.2.5", - "hadron-app-registry": "^9.4.11", + "@mongodb-js/compass-app-registry": "^9.4.11", "hadron-build": "^25.8.2", "hadron-ipc": "^3.5.2", "make-fetch-happen": "^10.2.1", diff --git a/packages/compass/src/app/application.tsx b/packages/compass/src/app/application.tsx index 1c4ed5df370..54e9eeee819 100644 --- a/packages/compass/src/app/application.tsx +++ b/packages/compass/src/app/application.tsx @@ -1,7 +1,7 @@ import { ipcRenderer } from 'hadron-ipc'; import * as remote from '@electron/remote'; import { webUtils, webFrame } from 'electron'; -import { globalAppRegistry } from 'hadron-app-registry'; +import { globalAppRegistry } from '@mongodb-js/compass-app-registry'; import { defaultPreferencesInstance } from 'compass-preferences-model'; import semver from 'semver'; import { CompassElectron } from './components/entrypoint'; diff --git a/packages/compass/src/app/components/entrypoint.tsx b/packages/compass/src/app/components/entrypoint.tsx index 493580e6564..6fb4c62f6fa 100644 --- a/packages/compass/src/app/components/entrypoint.tsx +++ b/packages/compass/src/app/components/entrypoint.tsx @@ -1,5 +1,5 @@ import React, { useRef } from 'react'; -import { AppRegistryProvider } from 'hadron-app-registry'; +import { AppRegistryProvider } from '@mongodb-js/compass-app-registry'; import { defaultPreferencesInstance } from 'compass-preferences-model'; import { PreferencesProvider } from 'compass-preferences-model/provider'; import { CompassAtlasAuthService } from '@mongodb-js/atlas-service/renderer'; diff --git a/packages/compass/src/app/components/home.tsx b/packages/compass/src/app/components/home.tsx index f4ef1537823..19e11af8519 100644 --- a/packages/compass/src/app/components/home.tsx +++ b/packages/compass/src/app/components/home.tsx @@ -18,7 +18,7 @@ import type { SettingsTabId } from '@mongodb-js/compass-settings'; import { CompassSettingsPlugin } from '@mongodb-js/compass-settings'; import { WelcomeModal } from '@mongodb-js/compass-welcome'; import { type ConnectionStorage } from '@mongodb-js/connection-storage/provider'; -import { AppRegistryProvider } from 'hadron-app-registry'; +import { AppRegistryProvider } from '@mongodb-js/compass-app-registry'; import React, { useCallback, useState } from 'react'; import Workspace from './workspace'; import { getExtraConnectionData } from '../utils/telemetry'; diff --git a/packages/compass/src/app/utils/csp.ts b/packages/compass/src/app/utils/csp.ts index 7678c5a52b7..939d81991a3 100644 --- a/packages/compass/src/app/utils/csp.ts +++ b/packages/compass/src/app/utils/csp.ts @@ -89,7 +89,7 @@ export function injectCSP() { extraAllowed.push('ws://localhost:*'); // Used by proxy tests, since Chrome does not like proxying localhost // (this does not result in actual outgoing HTTP requests) - extraAllowed.push('http://compass.mongodb.com/'); + extraAllowed.push('http://proxy-test-compass.mongodb.com/'); } const cspContent = Object.entries(defaultCSP) diff --git a/packages/connection-form/package.json b/packages/connection-form/package.json index b80e84bfaac..0bcf9849bd3 100644 --- a/packages/connection-form/package.json +++ b/packages/connection-form/package.json @@ -13,7 +13,7 @@ "email": "compass@mongodb.com" }, "homepage": "https://github.com/mongodb-js/compass", - "version": "1.52.3", + "version": "1.53.0", "repository": { "type": "git", "url": "https://github.com/mongodb-js/compass.git" @@ -48,8 +48,8 @@ "reformat": "npm run eslint . -- --fix && npm run prettier -- --write ." }, "dependencies": { - "@mongodb-js/compass-components": "^1.38.1", - "@mongodb-js/compass-editor": "^0.40.2", + "@mongodb-js/compass-components": "^1.39.0", + "@mongodb-js/compass-editor": "^0.41.0", "@mongodb-js/connection-info": "^0.15.2", "@mongodb-js/shell-bson-parser": "^1.2.0", "lodash": "^4.17.21", diff --git a/packages/connection-storage/package.json b/packages/connection-storage/package.json index d3daed9babc..d9511e98d3d 100644 --- a/packages/connection-storage/package.json +++ b/packages/connection-storage/package.json @@ -13,7 +13,7 @@ "email": "compass@mongodb.com" }, "homepage": "https://github.com/mongodb-js/compass", - "version": "0.35.0", + "version": "0.36.0", "repository": { "type": "git", "url": "https://github.com/mongodb-js/compass.git" @@ -62,9 +62,9 @@ "@mongodb-js/compass-utils": "^0.9.2", "@mongodb-js/connection-info": "^0.15.2", "bson": "^6.10.3", - "compass-preferences-model": "^2.40.2", + "compass-preferences-model": "^2.41.0", "electron": "^36.4.0", - "hadron-app-registry": "^9.4.11", + "@mongodb-js/compass-app-registry": "^9.4.11", "hadron-ipc": "^3.5.2", "keytar": "^7.9.0", "lodash": "^4.17.21", diff --git a/packages/connection-storage/src/provider.ts b/packages/connection-storage/src/provider.ts index e13ca061ffa..c99edee9ba0 100644 --- a/packages/connection-storage/src/provider.ts +++ b/packages/connection-storage/src/provider.ts @@ -1,5 +1,5 @@ import { createContext, useContext } from 'react'; -import { createServiceLocator } from 'hadron-app-registry'; +import { createServiceLocator } from '@mongodb-js/compass-app-registry'; import { type ConnectionStorage, type ConnectionInfo, diff --git a/packages/databases-collections-list/package.json b/packages/databases-collections-list/package.json index 521e52ca05d..1dde9a46338 100644 --- a/packages/databases-collections-list/package.json +++ b/packages/databases-collections-list/package.json @@ -13,7 +13,7 @@ "email": "compass@mongodb.com" }, "homepage": "https://github.com/mongodb-js/compass", - "version": "1.57.0", + "version": "1.58.0", "repository": { "type": "git", "url": "https://github.com/mongodb-js/compass.git" @@ -48,12 +48,12 @@ "reformat": "npm run eslint . -- --fix && npm run prettier -- --write ." }, "dependencies": { - "@mongodb-js/compass-components": "^1.38.1", - "@mongodb-js/compass-connections": "^1.60.0", + "@mongodb-js/compass-components": "^1.39.0", + "@mongodb-js/compass-connections": "^1.61.0", "@mongodb-js/compass-telemetry": "^1.10.0", - "@mongodb-js/compass-workspaces": "^0.41.0", + "@mongodb-js/compass-workspaces": "^0.42.0", "@mongodb-js/connection-info": "^0.15.2", - "compass-preferences-model": "^2.40.2", + "compass-preferences-model": "^2.41.0", "mongodb-collection-model": "^5.29.2", "mongodb-database-model": "^2.29.2", "mongodb-ns": "^2.4.2", diff --git a/packages/databases-collections/package.json b/packages/databases-collections/package.json index a54a2110350..dfab17f64fb 100644 --- a/packages/databases-collections/package.json +++ b/packages/databases-collections/package.json @@ -2,7 +2,7 @@ "name": "@mongodb-js/compass-databases-collections", "description": "Plugin for viewing the list of, creating, and dropping databases and collections", "private": true, - "version": "1.59.0", + "version": "1.60.0", "license": "SSPL", "homepage": "https://github.com/mongodb-js/compass", "bugs": { @@ -58,21 +58,21 @@ "typescript": "^5.0.4" }, "dependencies": { - "@mongodb-js/compass-app-stores": "^7.46.0", - "@mongodb-js/compass-components": "^1.38.1", - "@mongodb-js/compass-connections": "^1.60.0", - "@mongodb-js/compass-editor": "^0.40.2", + "@mongodb-js/compass-app-stores": "^7.47.0", + "@mongodb-js/compass-components": "^1.39.0", + "@mongodb-js/compass-connections": "^1.61.0", + "@mongodb-js/compass-editor": "^0.41.0", "@mongodb-js/compass-logging": "^1.7.2", "@mongodb-js/compass-telemetry": "^1.10.0", - "@mongodb-js/compass-workspaces": "^0.41.0", - "@mongodb-js/databases-collections-list": "^1.57.0", - "@mongodb-js/my-queries-storage": "^0.27.3", - "compass-preferences-model": "^2.40.2", - "hadron-app-registry": "^9.4.11", + "@mongodb-js/compass-workspaces": "^0.42.0", + "@mongodb-js/databases-collections-list": "^1.58.0", + "@mongodb-js/my-queries-storage": "^0.28.0", + "compass-preferences-model": "^2.41.0", + "@mongodb-js/compass-app-registry": "^9.4.11", "lodash": "^4.17.21", "mongodb-collection-model": "^5.29.2", "mongodb-database-model": "^2.29.2", - "mongodb-instance-model": "^12.32.2", + "mongodb-instance-model": "^12.33.0", "mongodb-ns": "^2.4.2", "mongodb-query-parser": "^4.3.0", "prop-types": "^15.7.2", diff --git a/packages/databases-collections/src/collections-plugin-title.tsx b/packages/databases-collections/src/collections-plugin-title.tsx new file mode 100644 index 00000000000..4b4bdb6f854 --- /dev/null +++ b/packages/databases-collections/src/collections-plugin-title.tsx @@ -0,0 +1,42 @@ +import React from 'react'; +import { + useConnectionInfo, + useConnectionsListRef, + useTabConnectionTheme, +} from '@mongodb-js/compass-connections/provider'; +import { + WorkspaceTab, + type WorkspaceTabCoreProps, +} from '@mongodb-js/compass-components'; +import type { WorkspacePluginProps } from '@mongodb-js/compass-workspaces'; + +import { CollectionsWorkspaceName } from './collections-plugin'; + +type PluginTitleProps = WorkspaceTabCoreProps & + WorkspacePluginProps; + +export function CollectionsPluginTitleComponent(props: PluginTitleProps) { + const { id: connectionId } = useConnectionInfo(); + const { getConnectionById } = useConnectionsListRef(); + const { getThemeOf } = useTabConnectionTheme(); + + const connectionName = getConnectionById(connectionId)?.title || ''; + const database = props.namespace; + + return ( + + ); +} diff --git a/packages/databases-collections/src/collections-plugin.spec.tsx b/packages/databases-collections/src/collections-plugin.spec.tsx index 703516a844d..ce4eb6bc1f9 100644 --- a/packages/databases-collections/src/collections-plugin.spec.tsx +++ b/packages/databases-collections/src/collections-plugin.spec.tsx @@ -9,7 +9,7 @@ import { userEvent, } from '@mongodb-js/testing-library-compass'; import { expect } from 'chai'; -import { CollectionsPlugin } from './collections-plugin'; +import { CollectionsWorkspaceTab } from './'; import Sinon from 'sinon'; import { type PreferencesAccess, @@ -61,13 +61,17 @@ describe('Collections [Plugin]', function () { describe('with loaded collections', function () { beforeEach(async function () { - const Plugin = CollectionsPlugin.withMockServices({ + const Plugin = CollectionsWorkspaceTab.provider.withMockServices({ instance: mongodbInstance, database: mongodbInstance.databases.get('foo'), dataService, }); - const { globalAppRegistry } = render(); + const { globalAppRegistry } = render( + + + + ); appRegistry = Sinon.spy(globalAppRegistry); await waitFor(() => { diff --git a/packages/databases-collections/src/collections-plugin.tsx b/packages/databases-collections/src/collections-plugin.tsx index b0d5e172032..7e0adc48204 100644 --- a/packages/databases-collections/src/collections-plugin.tsx +++ b/packages/databases-collections/src/collections-plugin.tsx @@ -1,20 +1,24 @@ +import React from 'react'; import { databaseModelLocator, mongoDBInstanceLocator, } from '@mongodb-js/compass-app-stores/provider'; -import CollectionsList from './components/collections'; import { activatePlugin as activateCollectionsTabPlugin } from './stores/collections-store'; -import { registerHadronPlugin } from 'hadron-app-registry'; +import { registerCompassPlugin } from '@mongodb-js/compass-app-registry'; import { dataServiceLocator, type DataServiceLocator, type DataService, } from '@mongodb-js/compass-connections/provider'; -export const CollectionsPlugin = registerHadronPlugin( +export const CollectionsWorkspaceName = 'Collections' as const; + +export const CollectionsPlugin = registerCompassPlugin( { - name: 'Collections', - component: CollectionsList, + name: 'Collections' as const, + component: function CollectionsProvider({ children }) { + return React.createElement(React.Fragment, null, children); + }, activate: activateCollectionsTabPlugin, }, { diff --git a/packages/databases-collections/src/components/create-namespace-modal.spec.tsx b/packages/databases-collections/src/components/create-namespace-modal.spec.tsx index b8c94a44972..e76e31493ce 100644 --- a/packages/databases-collections/src/components/create-namespace-modal.spec.tsx +++ b/packages/databases-collections/src/components/create-namespace-modal.spec.tsx @@ -7,7 +7,7 @@ import { waitFor, userEvent, } from '@mongodb-js/testing-library-compass'; -import type AppRegistry from 'hadron-app-registry'; +import type AppRegistry from '@mongodb-js/compass-app-registry'; import { CreateNamespacePlugin } from '../..'; import { diff --git a/packages/databases-collections/src/components/rename-collection-modal/rename-collection-modal.spec.tsx b/packages/databases-collections/src/components/rename-collection-modal/rename-collection-modal.spec.tsx index 0fb0d6eb40d..67058b5e6e0 100644 --- a/packages/databases-collections/src/components/rename-collection-modal/rename-collection-modal.spec.tsx +++ b/packages/databases-collections/src/components/rename-collection-modal/rename-collection-modal.spec.tsx @@ -10,7 +10,7 @@ import { createDefaultConnectionInfo, } from '@mongodb-js/testing-library-compass'; import { RenameCollectionPlugin } from '../..'; -import type AppRegistry from 'hadron-app-registry'; +import type AppRegistry from '@mongodb-js/compass-app-registry'; describe('RenameCollectionModal [Component]', function () { const connectionId = '12345'; diff --git a/packages/databases-collections/src/databases-plugin-title.tsx b/packages/databases-collections/src/databases-plugin-title.tsx new file mode 100644 index 00000000000..062faa7049c --- /dev/null +++ b/packages/databases-collections/src/databases-plugin-title.tsx @@ -0,0 +1,35 @@ +import React from 'react'; +import { + WorkspaceTab, + type WorkspaceTabCoreProps, +} from '@mongodb-js/compass-components'; +import { + useConnectionInfo, + useConnectionsListRef, + useTabConnectionTheme, +} from '@mongodb-js/compass-connections/provider'; +import type { WorkspacePluginProps } from '@mongodb-js/compass-workspaces'; + +import { DatabasesWorkspaceName } from './databases-plugin'; + +type PluginTitleProps = WorkspaceTabCoreProps & + WorkspacePluginProps; + +export function DatabasesPluginTitleComponent(props: PluginTitleProps) { + const { id: connectionId } = useConnectionInfo(); + const { getConnectionById } = useConnectionsListRef(); + const { getThemeOf } = useTabConnectionTheme(); + + const connectionName = getConnectionById(connectionId)?.title || ''; + return ( + + ); +} diff --git a/packages/databases-collections/src/databases-plugin.spec.tsx b/packages/databases-collections/src/databases-plugin.spec.tsx index fd9c07c1c57..32fcf190833 100644 --- a/packages/databases-collections/src/databases-plugin.spec.tsx +++ b/packages/databases-collections/src/databases-plugin.spec.tsx @@ -9,7 +9,7 @@ import { userEvent, } from '@mongodb-js/testing-library-compass'; import { expect } from 'chai'; -import { DatabasesPlugin } from './databases-plugin'; +import { DatabasesWorkspaceTab } from './'; import Sinon from 'sinon'; import { createSandboxFromDefaultPreferences, @@ -49,12 +49,16 @@ describe('Databasees [Plugin]', function () { }, }; - const Plugin = DatabasesPlugin.withMockServices({ + const Plugin = DatabasesWorkspaceTab.provider.withMockServices({ instance: mongodbInstance, dataService, }); - const { globalAppRegistry } = render(); + const { globalAppRegistry } = render( + + + + ); appRegistry = Sinon.spy(globalAppRegistry); diff --git a/packages/databases-collections/src/databases-plugin.tsx b/packages/databases-collections/src/databases-plugin.tsx index 23ab01032a7..2112d878426 100644 --- a/packages/databases-collections/src/databases-plugin.tsx +++ b/packages/databases-collections/src/databases-plugin.tsx @@ -1,17 +1,21 @@ +import React from 'react'; import { mongoDBInstanceLocator } from '@mongodb-js/compass-app-stores/provider'; -import Databases from './components/databases'; import { activatePlugin as activateDatabasesTabPlugin } from './stores/databases-store'; -import { registerHadronPlugin } from 'hadron-app-registry'; +import { registerCompassPlugin } from '@mongodb-js/compass-app-registry'; import { dataServiceLocator, type DataServiceLocator, type DataService, } from '@mongodb-js/compass-connections/provider'; -export const DatabasesPlugin = registerHadronPlugin( +export const DatabasesWorkspaceName = 'Databases' as const; + +export const DatabasesPlugin = registerCompassPlugin( { - name: 'Databases', - component: Databases, + name: 'Databases' as const, + component: function DatabasesProvider({ children }) { + return React.createElement(React.Fragment, null, children); + }, activate: activateDatabasesTabPlugin, }, { diff --git a/packages/databases-collections/src/index.ts b/packages/databases-collections/src/index.ts index e45a71de468..6503cdb41e7 100644 --- a/packages/databases-collections/src/index.ts +++ b/packages/databases-collections/src/index.ts @@ -1,36 +1,51 @@ -import { registerHadronPlugin } from 'hadron-app-registry'; +import { registerCompassPlugin } from '@mongodb-js/compass-app-registry'; import { createLoggerLocator } from '@mongodb-js/compass-logging/provider'; import { telemetryLocator } from '@mongodb-js/compass-telemetry/provider'; import { connectionsLocator } from '@mongodb-js/compass-connections/provider'; import { mongoDBInstancesManagerLocator } from '@mongodb-js/compass-app-stores/provider'; -import { CollectionsPlugin } from './collections-plugin'; +import { + CollectionsPlugin, + CollectionsWorkspaceName, +} from './collections-plugin'; import { DropNamespaceComponent, activatePlugin as activateDropNamespacePlugin, } from './stores/drop-namespace'; import CreateNamespaceModal from './components/create-namespace-modal'; import { activatePlugin as activateCreateNamespacePlugin } from './stores/create-namespace'; -import { DatabasesPlugin } from './databases-plugin'; +import { DatabasesPlugin, DatabasesWorkspaceName } from './databases-plugin'; import MappedRenameCollectionModal from './components/rename-collection-modal/rename-collection-modal'; import { activateRenameCollectionPlugin } from './stores/rename-collection'; -import type { WorkspaceComponent } from '@mongodb-js/compass-workspaces'; +import type { WorkspacePlugin } from '@mongodb-js/compass-workspaces'; import { workspacesServiceLocator } from '@mongodb-js/compass-workspaces/provider'; import { favoriteQueryStorageAccessLocator, pipelineStorageLocator, } from '@mongodb-js/my-queries-storage/provider'; +import Databases from './components/databases'; +import CollectionsList from './components/collections'; +import { DatabasesPluginTitleComponent } from './databases-plugin-title'; +import { CollectionsPluginTitleComponent } from './collections-plugin-title'; -export const CollectionsWorkspaceTab: WorkspaceComponent<'Collections'> = { - name: 'Collections' as const, - component: CollectionsPlugin, +export const CollectionsWorkspaceTab: WorkspacePlugin< + typeof CollectionsWorkspaceName +> = { + name: CollectionsWorkspaceName, + provider: CollectionsPlugin, + content: CollectionsList, + header: CollectionsPluginTitleComponent, }; -export const DatabasesWorkspaceTab: WorkspaceComponent<'Databases'> = { - name: 'Databases' as const, - component: DatabasesPlugin, +export const DatabasesWorkspaceTab: WorkspacePlugin< + typeof DatabasesWorkspaceName +> = { + name: DatabasesWorkspaceName, + provider: DatabasesPlugin, + content: Databases, + header: DatabasesPluginTitleComponent, }; -export const CreateNamespacePlugin = registerHadronPlugin( +export const CreateNamespacePlugin = registerCompassPlugin( { name: 'CreateNamespace', activate: activateCreateNamespacePlugin, @@ -45,7 +60,7 @@ export const CreateNamespacePlugin = registerHadronPlugin( } ); -export const DropNamespacePlugin = registerHadronPlugin( +export const DropNamespacePlugin = registerCompassPlugin( { name: 'DropNamespace', component: DropNamespaceComponent, @@ -58,7 +73,7 @@ export const DropNamespacePlugin = registerHadronPlugin( } ); -export const RenameCollectionPlugin = registerHadronPlugin( +export const RenameCollectionPlugin = registerCompassPlugin( { name: 'RenameCollectionPlugin', component: MappedRenameCollectionModal, diff --git a/packages/databases-collections/src/modules/databases.ts b/packages/databases-collections/src/modules/databases.ts index a337684f5b4..6eb825de633 100644 --- a/packages/databases-collections/src/modules/databases.ts +++ b/packages/databases-collections/src/modules/databases.ts @@ -1,7 +1,7 @@ import type { Action, AnyAction, Reducer } from 'redux'; import type { MongoDBInstance } from '@mongodb-js/compass-app-stores/provider'; import type { ThunkAction } from 'redux-thunk'; -import type AppRegistry from 'hadron-app-registry'; +import type AppRegistry from '@mongodb-js/compass-app-registry'; function isAction( action: AnyAction, diff --git a/packages/databases-collections/src/modules/rename-collection/rename-collection.spec.ts b/packages/databases-collections/src/modules/rename-collection/rename-collection.spec.ts index ed51e4726d7..a3f0b447dc2 100644 --- a/packages/databases-collections/src/modules/rename-collection/rename-collection.spec.ts +++ b/packages/databases-collections/src/modules/rename-collection/rename-collection.spec.ts @@ -4,7 +4,9 @@ import type { RenameCollectionRootState } from './rename-collection'; import { renameCollection, renameRequestInProgress } from './rename-collection'; import type { ThunkDispatch } from 'redux-thunk'; import type { AnyAction } from 'redux'; -import AppRegistry, { createActivateHelpers } from 'hadron-app-registry'; +import AppRegistry, { + createActivateHelpers, +} from '@mongodb-js/compass-app-registry'; import type { RenameCollectionPluginServices } from '../../stores/rename-collection'; import { activateRenameCollectionPlugin } from '../../stores/rename-collection'; diff --git a/packages/databases-collections/src/stores/collections-store.ts b/packages/databases-collections/src/stores/collections-store.ts index 5a974a85a35..1a860feff09 100644 --- a/packages/databases-collections/src/stores/collections-store.ts +++ b/packages/databases-collections/src/stores/collections-store.ts @@ -2,9 +2,9 @@ import throttle from 'lodash/throttle'; import { createStore, applyMiddleware } from 'redux'; import thunk from 'redux-thunk'; import { collectionsReducer } from '../modules'; -import type AppRegistry from 'hadron-app-registry'; +import type AppRegistry from '@mongodb-js/compass-app-registry'; import type { DataService } from '@mongodb-js/compass-connections/provider'; -import type { ActivateHelpers } from 'hadron-app-registry'; +import type { ActivateHelpers } from '@mongodb-js/compass-app-registry'; import { collectionsChanged, instanceChanged } from '../modules/collections'; import type { MongoDBInstance, diff --git a/packages/databases-collections/src/stores/create-namespace.spec.tsx b/packages/databases-collections/src/stores/create-namespace.spec.tsx index 6bb58becb05..ba291808e9e 100644 --- a/packages/databases-collections/src/stores/create-namespace.spec.tsx +++ b/packages/databases-collections/src/stores/create-namespace.spec.tsx @@ -1,7 +1,7 @@ import React from 'react'; import Sinon from 'sinon'; import { CreateNamespacePlugin } from '../index'; -import type AppRegistry from 'hadron-app-registry'; +import type AppRegistry from '@mongodb-js/compass-app-registry'; import { expect } from 'chai'; import { type DataService } from '@mongodb-js/compass-connections/provider'; import { diff --git a/packages/databases-collections/src/stores/create-namespace.ts b/packages/databases-collections/src/stores/create-namespace.ts index 1adc54426fe..86074aca43e 100644 --- a/packages/databases-collections/src/stores/create-namespace.ts +++ b/packages/databases-collections/src/stores/create-namespace.ts @@ -1,4 +1,4 @@ -import type AppRegistry from 'hadron-app-registry'; +import type AppRegistry from '@mongodb-js/compass-app-registry'; import type { ConnectionsService } from '@mongodb-js/compass-connections/provider'; import {} from '@mongodb-js/compass-connections/provider'; import type { MongoDBInstance } from 'mongodb-instance-model'; @@ -15,7 +15,7 @@ import reducer, { } from '../modules/create-namespace'; import type toNS from 'mongodb-ns'; import type { workspacesServiceLocator } from '@mongodb-js/compass-workspaces/provider'; -import type { ActivateHelpers } from 'hadron-app-registry'; +import type { ActivateHelpers } from '@mongodb-js/compass-app-registry'; import { MongoDBInstancesManagerEvents, type MongoDBInstancesManager, diff --git a/packages/databases-collections/src/stores/databases-store.ts b/packages/databases-collections/src/stores/databases-store.ts index 7cca099fd12..e857a55f6fb 100644 --- a/packages/databases-collections/src/stores/databases-store.ts +++ b/packages/databases-collections/src/stores/databases-store.ts @@ -5,10 +5,10 @@ import databasesReducer, { databasesChanged, instanceChanged, } from '../modules/databases'; -import type AppRegistry from 'hadron-app-registry'; +import type AppRegistry from '@mongodb-js/compass-app-registry'; import type { MongoDBInstance } from '@mongodb-js/compass-app-stores/provider'; import type { DataService } from '@mongodb-js/compass-connections/provider'; -import type { ActivateHelpers } from 'hadron-app-registry'; +import type { ActivateHelpers } from '@mongodb-js/compass-app-registry'; type DatabasesTabServices = { globalAppRegistry: AppRegistry; @@ -16,8 +16,11 @@ type DatabasesTabServices = { dataService: DataService; }; +type DatabasesPluginInitialProps = { + children?: React.ReactNode; +}; export function activatePlugin( - _initialProps: Record, + _initialProps: DatabasesPluginInitialProps, { globalAppRegistry, instance, dataService }: DatabasesTabServices, { on, cleanup, addCleanup }: ActivateHelpers ) { diff --git a/packages/databases-collections/src/stores/drop-namespace.spec.tsx b/packages/databases-collections/src/stores/drop-namespace.spec.tsx index 0de7e4daa3d..46e4ec925de 100644 --- a/packages/databases-collections/src/stores/drop-namespace.spec.tsx +++ b/packages/databases-collections/src/stores/drop-namespace.spec.tsx @@ -1,7 +1,7 @@ import React from 'react'; import Sinon from 'sinon'; import { DropNamespacePlugin } from '../index'; -import type AppRegistry from 'hadron-app-registry'; +import type AppRegistry from '@mongodb-js/compass-app-registry'; import toNS from 'mongodb-ns'; import { expect } from 'chai'; import { diff --git a/packages/databases-collections/src/stores/drop-namespace.tsx b/packages/databases-collections/src/stores/drop-namespace.tsx index 41398b3bbd3..929c671a7de 100644 --- a/packages/databases-collections/src/stores/drop-namespace.tsx +++ b/packages/databases-collections/src/stores/drop-namespace.tsx @@ -6,9 +6,9 @@ import { ToastArea, } from '@mongodb-js/compass-components'; import type { Logger } from '@mongodb-js/compass-logging/provider'; -import type AppRegistry from 'hadron-app-registry'; +import type AppRegistry from '@mongodb-js/compass-app-registry'; import toNS from 'mongodb-ns'; -import type { ActivateHelpers } from 'hadron-app-registry'; +import type { ActivateHelpers } from '@mongodb-js/compass-app-registry'; import type { TrackFunction } from '@mongodb-js/compass-telemetry'; import type { ConnectionsService } from '@mongodb-js/compass-connections/provider'; diff --git a/packages/databases-collections/src/stores/rename-collection.ts b/packages/databases-collections/src/stores/rename-collection.ts index e4d5bc228ca..7b22d3734bf 100644 --- a/packages/databases-collections/src/stores/rename-collection.ts +++ b/packages/databases-collections/src/stores/rename-collection.ts @@ -1,6 +1,6 @@ import { legacy_createStore, applyMiddleware } from 'redux'; import thunk from 'redux-thunk'; -import type AppRegistry from 'hadron-app-registry'; +import type AppRegistry from '@mongodb-js/compass-app-registry'; import type { ConnectionsService } from '@mongodb-js/compass-connections/provider'; import reducer, { open } from '../modules/rename-collection/rename-collection'; import type { @@ -8,7 +8,7 @@ import type { PipelineStorage, } from '@mongodb-js/my-queries-storage/provider'; import { type MongoDBInstancesManager } from '@mongodb-js/compass-app-stores/provider'; -import type { ActivateHelpers } from 'hadron-app-registry'; +import type { ActivateHelpers } from '@mongodb-js/compass-app-registry'; export type RenameCollectionPluginServices = { globalAppRegistry: AppRegistry; diff --git a/packages/hadron-ipc/README.md b/packages/hadron-ipc/README.md index 0c330c7737c..425fc5fc2b1 100644 --- a/packages/hadron-ipc/README.md +++ b/packages/hadron-ipc/README.md @@ -8,7 +8,7 @@ Simplified wrapper around Electron's IPC events. process.env.DEBUG = 'hadron-*'; const ipc = require('hadron-ipc'); -const AppRegistry = require('hadron-app-registry'); +const AppRegistry = require('@mongodb-js/compass-app-registry'); const globalAppRegistry = new AppRegistry(); @@ -158,11 +158,11 @@ npm install hadron-ipc - [Electron's ipcMain][ipc-main] - [Electron's ipcRenderer][ipc-renderer] - [Hadron App][hadron-app] -- [Hadron App Registry][hadron-app-registry] +- [Compass App Registry][compass-app-registry] [npm_img]: https://img.shields.io/npm/v/hadron-ipc.svg [npm_url]: https://npmjs.org/package/hadron-ipc [ipc-renderer]: https://electronjs.org/docs/api/ipc-renderer [ipc-main]: https://electronjs.org/docs/api/ipc-mai://electronjs.org/docs/api/ipc-main -[hadron-app]: https://github.com/mongodb-js/hadron-app -[hadron-app-registry]: https://github.com/mongodb-js/hadron-app-registr://github.com/mongodb-js/hadron-app-registry +[hadron-app]: https://github.com/mongodb-js/compass/tree/main/packages/hadron-app +[compass-app-registry]: https://github.com/mongodb-js/compass/tree/main/packages/compass-app-registry diff --git a/packages/instance-model/package.json b/packages/instance-model/package.json index 581fb4881be..bf92e02b4a7 100644 --- a/packages/instance-model/package.json +++ b/packages/instance-model/package.json @@ -2,7 +2,7 @@ "name": "mongodb-instance-model", "description": "MongoDB instance model", "author": "Lucas Hrabovsky ", - "version": "12.32.2", + "version": "12.33.0", "bugs": { "url": "https://jira.mongodb.org/projects/COMPASS/issues", "email": "compass@mongodb.com" @@ -32,7 +32,7 @@ "mongodb-collection-model": "^5.29.2", "mongodb-data-service": "^22.28.2", "mongodb-database-model": "^2.29.2", - "compass-preferences-model": "^2.40.2" + "compass-preferences-model": "^2.41.0" }, "devDependencies": { "@mongodb-js/eslint-config-compass": "^1.3.10", diff --git a/packages/my-queries-storage/package.json b/packages/my-queries-storage/package.json index 63b9590376f..872bfdff88d 100644 --- a/packages/my-queries-storage/package.json +++ b/packages/my-queries-storage/package.json @@ -13,7 +13,7 @@ "email": "compass@mongodb.com" }, "homepage": "https://github.com/mongodb-js/compass", - "version": "0.27.3", + "version": "0.28.0", "repository": { "type": "git", "url": "https://github.com/mongodb-js/compass.git" @@ -71,10 +71,10 @@ "typescript": "^5.0.4" }, "dependencies": { - "@mongodb-js/compass-editor": "^0.40.2", + "@mongodb-js/compass-editor": "^0.41.0", "@mongodb-js/compass-user-data": "^0.7.2", "bson": "^6.10.3", - "hadron-app-registry": "^9.4.11", + "@mongodb-js/compass-app-registry": "^9.4.11", "react": "^17.0.2" } } diff --git a/packages/my-queries-storage/src/provider.ts b/packages/my-queries-storage/src/provider.ts index 1b83eb7ccbb..1d90f958b16 100644 --- a/packages/my-queries-storage/src/provider.ts +++ b/packages/my-queries-storage/src/provider.ts @@ -2,7 +2,7 @@ import { createContext, useContext } from 'react'; import type { QueryStorageOptions } from './compass-query-storage'; import type { PipelineStorage } from './pipeline-storage'; import type { FavoriteQueryStorage, RecentQueryStorage } from './query-storage'; -import { createServiceLocator } from 'hadron-app-registry'; +import { createServiceLocator } from '@mongodb-js/compass-app-registry'; export type { PipelineStorage, FavoriteQueryStorage, RecentQueryStorage }; diff --git a/scripts/create-workspace.js b/scripts/create-workspace.js index 70aa3d72d8f..3514be17dbe 100644 --- a/scripts/create-workspace.js +++ b/scripts/create-workspace.js @@ -296,7 +296,7 @@ async function createWorkspace({ typescript: '*', ...(isPublic && { 'gen-esm-wrapper': '*' }), ...(isPlugin && { - 'hadron-app-registry': '*', + '@mongodb-js/compass-app-registry': '*', 'xvfb-maybe': '*', }), }, @@ -388,9 +388,9 @@ module.exports = { const indexSrcPath = path.join(indexSrcDir, 'index.ts'); const indexSrcContent = isPlugin ? ` -import { registerHadronPlugin } from "hadron-app-registry"; +import { registerCompassPlugin } from '@mongodb-js/compass-app-registry'; -const Plugin = registerHadronPlugin({ +const Plugin = registerCompassPlugin({ name: 'Plugin', component: () => null, activate(initialProps, services, activateHelpers) {