From ed88fb95f424edc2cc67a0ca76eea5defc013597 Mon Sep 17 00:00:00 2001 From: Sergey Petushkov Date: Wed, 15 Oct 2025 15:05:49 +0200 Subject: [PATCH 1/6] feat(data-modeling): implement data model storage that uses atlas user data --- packages/atlas-service/src/atlas-service.ts | 6 +- packages/compass-data-modeling/package.json | 4 +- .../src/services/data-model-storage-atlas.tsx | 119 ++++++++++++++++++ packages/compass-data-modeling/web.d.ts | 2 +- packages/compass-data-modeling/web.js | 2 +- packages/compass-web/sandbox/index.tsx | 3 +- .../sandbox/sandbox-atlas-sign-in.tsx | 3 + packages/compass-web/src/entrypoint.tsx | 9 +- 8 files changed, 139 insertions(+), 9 deletions(-) create mode 100644 packages/compass-data-modeling/src/services/data-model-storage-atlas.tsx diff --git a/packages/atlas-service/src/atlas-service.ts b/packages/atlas-service/src/atlas-service.ts index 183a42012cb..4ffe27627d6 100644 --- a/packages/atlas-service/src/atlas-service.ts +++ b/packages/atlas-service/src/atlas-service.ts @@ -81,7 +81,11 @@ export class AtlasService { userDataEndpoint( orgId: string, groupId: string, - type: 'favoriteQueries' | 'recentQueries' | 'favoriteAggregations', + type: + | 'favoriteQueries' + | 'recentQueries' + | 'favoriteAggregations' + | 'dataModelDescriptions', id?: string ): string { const encodedOrgId = encodeURIComponent(orgId); diff --git a/packages/compass-data-modeling/package.json b/packages/compass-data-modeling/package.json index f7d82baf23a..bdc119ac893 100644 --- a/packages/compass-data-modeling/package.json +++ b/packages/compass-data-modeling/package.json @@ -26,13 +26,13 @@ ".": "./dist/index.js", "./provider": "./dist/provider/index.js", "./renderer": "./dist/services/data-model-storage-electron.js", - "./web": "./dist/services/data-model-storage-in-memory.js" + "./web": "./dist/services/data-model-storage-atlas.js" }, "compass:exports": { ".": "./src/index.ts", "./provider": "./src/provider/index.tsx", "./renderer": "./src/services/data-model-storage-electron.tsx", - "./web": "./src/services/data-model-storage-in-memory.tsx" + "./web": "./src/services/data-model-storage-atlas.tsx" }, "types": "./dist/index.d.ts", "scripts": { diff --git a/packages/compass-data-modeling/src/services/data-model-storage-atlas.tsx b/packages/compass-data-modeling/src/services/data-model-storage-atlas.tsx new file mode 100644 index 00000000000..6db541ad5d8 --- /dev/null +++ b/packages/compass-data-modeling/src/services/data-model-storage-atlas.tsx @@ -0,0 +1,119 @@ +import { AtlasUserData } from '@mongodb-js/compass-user-data'; +import type { + DataModelStorage, + MongoDBDataModelDescription, +} from './data-model-storage'; +import { MongoDBDataModelDescriptionSchema } from './data-model-storage'; +import dataModelStorageInMemory from './data-model-storage-in-memory'; +import { + atlasServiceLocator, + type AtlasService, +} from '@mongodb-js/atlas-service/provider'; +import { createServiceProvider } from '@mongodb-js/compass-app-registry'; +import { DataModelStorageServiceProvider } from '../provider'; +import React, { useRef } from 'react'; +import { mongoLogId, useLogger } from '@mongodb-js/compass-logging/provider'; + +class DataModelStorageAtlas implements DataModelStorage { + private readonly userData: AtlasUserData< + typeof MongoDBDataModelDescriptionSchema + >; + constructor(orgId: string, projectId: string, atlasService: AtlasService) { + this.userData = new AtlasUserData( + MongoDBDataModelDescriptionSchema, + 'dataModelDescriptions', + { + orgId, + projectId, + getResourceUrl(path) { + // TODO(COMPASS-9960): this is copied from compass-web entrypoint for + // brevity, but shouldn't be defined outside of AtlasUserData, this + // logic is literally the same between all user data instances and can + // be encapsulated inside of the AtlasUserData class implementation + const [type, pathOrgId, pathProjectId, id] = + path?.split('/').filter(Boolean) || []; + + if ( + !type || + !pathOrgId || + !pathProjectId || + type !== 'dataModelDescriptions' + ) { + throw new Error( + 'DataModelStorageAtlas is used outside of Atlas Cloud context' + ); + } + + return atlasService.userDataEndpoint( + pathOrgId, + pathProjectId, + type, + id + ); + }, + authenticatedFetch: atlasService.authenticatedFetch.bind(atlasService), + } + ); + } + save(description: MongoDBDataModelDescription) { + return this.userData.write(description.id, description); + } + delete(id: MongoDBDataModelDescription['id']) { + return this.userData.delete(id); + } + async loadAll(): Promise { + try { + const res = await this.userData.readAll(); + return res.data; + } catch { + return []; + } + } + async load(id: string): Promise { + return ( + (await this.loadAll()).find((item) => { + return item.id === id; + }) ?? null + ); + } +} + +export const DataModelStorageServiceProviderAtlas = createServiceProvider( + function DataModelStorageServiceProviderAtlas({ + children, + orgId, + projectId, + }: { + children?: React.ReactNode; + orgId?: string; + projectId?: string; + }) { + const storageRef = useRef(); + const atlasService = atlasServiceLocator(); + const logger = useLogger('DATA-MODEL-STORAGE'); + + if (!storageRef.current) { + if (orgId && projectId) { + storageRef.current = new DataModelStorageAtlas( + orgId, + projectId, + atlasService + ); + } else { + logger.log.warn( + mongoLogId(1_001_000_378), + 'DataModelStorageServiceProviderAtlas', + 'Falling back to in memory storage because orgId or projectId is missing' + ); + // Fallback to in-memory if we're outside of Atlas Cloud + storageRef.current = dataModelStorageInMemory; + } + } + + return ( + + {children} + + ); + } +); diff --git a/packages/compass-data-modeling/web.d.ts b/packages/compass-data-modeling/web.d.ts index ed685938a24..67cb4172045 100644 --- a/packages/compass-data-modeling/web.d.ts +++ b/packages/compass-data-modeling/web.d.ts @@ -1 +1 @@ -export * from './dist/services/data-model-storage-in-memory.d'; +export * from './dist/services/data-model-storage-atlas.d'; diff --git a/packages/compass-data-modeling/web.js b/packages/compass-data-modeling/web.js index 904ae04d64d..cbaa64a0c8d 100644 --- a/packages/compass-data-modeling/web.js +++ b/packages/compass-data-modeling/web.js @@ -1,2 +1,2 @@ 'use strict'; -module.exports = require('./dist/services/data-model-storage-in-memory'); +module.exports = require('./dist/services/data-model-storage-atlas'); diff --git a/packages/compass-web/sandbox/index.tsx b/packages/compass-web/sandbox/index.tsx index 25e46e7e29e..cb9c6e4b0e7 100644 --- a/packages/compass-web/sandbox/index.tsx +++ b/packages/compass-web/sandbox/index.tsx @@ -38,6 +38,7 @@ const App = () => { const [currentTab, updateCurrentTab] = useWorkspaceTabRouter(); const { status, projectParams } = useAtlasProxySignIn(); const { + orgId, projectId, csrfToken, csrfTime, @@ -99,7 +100,7 @@ const App = () => { - + - + From 2e013e50c916910e801385cc0518d56ec52088b7 Mon Sep 17 00:00:00 2001 From: Sergey Petushkov Date: Wed, 15 Oct 2025 15:52:40 +0200 Subject: [PATCH 2/6] chore(components): force hide file input --- packages/compass-components/src/components/file-selector.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/compass-components/src/components/file-selector.tsx b/packages/compass-components/src/components/file-selector.tsx index 373c08e2982..b113928fe89 100644 --- a/packages/compass-components/src/components/file-selector.tsx +++ b/packages/compass-components/src/components/file-selector.tsx @@ -2,7 +2,9 @@ import React, { type InputHTMLAttributes, useRef } from 'react'; import { css } from '@leafygreen-ui/emotion'; const displayNoneStyles = css({ - display: 'none', + // make sure actual input is always hidden (mms is doing something weird + // forcing these to be visible) + display: 'none !important', }); type FileSelectorTriggerProps = { From b0749c6cdbd2b919862489785af7140be7021768 Mon Sep 17 00:00:00 2001 From: Sergey Petushkov Date: Wed, 15 Oct 2025 15:55:50 +0200 Subject: [PATCH 3/6] chore(data-modeling): fix logid --- .../src/services/data-model-storage-atlas.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/compass-data-modeling/src/services/data-model-storage-atlas.tsx b/packages/compass-data-modeling/src/services/data-model-storage-atlas.tsx index 6db541ad5d8..2fb8a431fd1 100644 --- a/packages/compass-data-modeling/src/services/data-model-storage-atlas.tsx +++ b/packages/compass-data-modeling/src/services/data-model-storage-atlas.tsx @@ -101,7 +101,7 @@ export const DataModelStorageServiceProviderAtlas = createServiceProvider( ); } else { logger.log.warn( - mongoLogId(1_001_000_378), + mongoLogId(1_001_000_379), 'DataModelStorageServiceProviderAtlas', 'Falling back to in memory storage because orgId or projectId is missing' ); From 0229c81dca2012bc62773f21bf6499032f325c4d Mon Sep 17 00:00:00 2001 From: Sergey Petushkov Date: Wed, 15 Oct 2025 16:20:11 +0200 Subject: [PATCH 4/6] chore(data-modeling): add missing dependency --- package-lock.json | 2 ++ packages/compass-data-modeling/package.json | 1 + 2 files changed, 3 insertions(+) diff --git a/package-lock.json b/package-lock.json index dfa52563cfd..c9f84a6021c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -49376,6 +49376,7 @@ "version": "1.31.0", "license": "SSPL", "dependencies": { + "@mongodb-js/atlas-service": "^0.64.0", "@mongodb-js/compass-app-registry": "^9.4.27", "@mongodb-js/compass-app-stores": "^7.66.0", "@mongodb-js/compass-components": "^1.54.2", @@ -63255,6 +63256,7 @@ "@mongodb-js/compass-data-modeling": { "version": "file:packages/compass-data-modeling", "requires": { + "@mongodb-js/atlas-service": "^0.64.0", "@mongodb-js/compass-app-registry": "^9.4.27", "@mongodb-js/compass-app-stores": "^7.66.0", "@mongodb-js/compass-components": "^1.54.2", diff --git a/packages/compass-data-modeling/package.json b/packages/compass-data-modeling/package.json index bdc119ac893..484762780a5 100644 --- a/packages/compass-data-modeling/package.json +++ b/packages/compass-data-modeling/package.json @@ -54,6 +54,7 @@ "reformat": "npm run eslint . -- --fix && npm run prettier -- --write ." }, "dependencies": { + "@mongodb-js/atlas-service": "^0.64.0", "@mongodb-js/compass-app-registry": "^9.4.27", "@mongodb-js/compass-app-stores": "^7.66.0", "@mongodb-js/compass-components": "^1.54.2", From 4996d96675b76fd2b00660ce7a1a624c980a3061 Mon Sep 17 00:00:00 2001 From: Sergey Petushkov Date: Tue, 21 Oct 2025 09:20:02 +0200 Subject: [PATCH 5/6] chore(data-modeling): rename service provider --- packages/compass-data-modeling/package.json | 4 ++-- ...ge-atlas.tsx => data-model-storage-web.tsx} | 18 ++++++++++++++---- packages/compass-data-modeling/web.d.ts | 2 +- packages/compass-data-modeling/web.js | 2 +- packages/compass-web/src/entrypoint.tsx | 6 +++--- 5 files changed, 21 insertions(+), 11 deletions(-) rename packages/compass-data-modeling/src/services/{data-model-storage-atlas.tsx => data-model-storage-web.tsx} (86%) diff --git a/packages/compass-data-modeling/package.json b/packages/compass-data-modeling/package.json index 484762780a5..a16302ce91f 100644 --- a/packages/compass-data-modeling/package.json +++ b/packages/compass-data-modeling/package.json @@ -26,13 +26,13 @@ ".": "./dist/index.js", "./provider": "./dist/provider/index.js", "./renderer": "./dist/services/data-model-storage-electron.js", - "./web": "./dist/services/data-model-storage-atlas.js" + "./web": "./dist/services/data-model-storage-web.js" }, "compass:exports": { ".": "./src/index.ts", "./provider": "./src/provider/index.tsx", "./renderer": "./src/services/data-model-storage-electron.tsx", - "./web": "./src/services/data-model-storage-atlas.tsx" + "./web": "./src/services/data-model-storage-web.tsx" }, "types": "./dist/index.d.ts", "scripts": { diff --git a/packages/compass-data-modeling/src/services/data-model-storage-atlas.tsx b/packages/compass-data-modeling/src/services/data-model-storage-web.tsx similarity index 86% rename from packages/compass-data-modeling/src/services/data-model-storage-atlas.tsx rename to packages/compass-data-modeling/src/services/data-model-storage-web.tsx index 2fb8a431fd1..04638a75868 100644 --- a/packages/compass-data-modeling/src/services/data-model-storage-atlas.tsx +++ b/packages/compass-data-modeling/src/services/data-model-storage-web.tsx @@ -78,15 +78,25 @@ class DataModelStorageAtlas implements DataModelStorage { } } -export const DataModelStorageServiceProviderAtlas = createServiceProvider( - function DataModelStorageServiceProviderAtlas({ +export const DataModelStorageServiceProviderWeb = createServiceProvider( + function DataModelStorageServiceProviderWeb({ children, orgId, projectId, }: { - children?: React.ReactNode; + /** + * Atlas organization id. Optional. If provided, data model storage will + * save the user data in Atlas Cloud, otherwise will fall back to in-memory + * storage + */ orgId?: string; + /** + * Atlas project id. Optional. If provided, data model storage will + * save the user data in Atlas Cloud, otherwise will fall back to in-memory + * storage + */ projectId?: string; + children?: React.ReactNode; }) { const storageRef = useRef(); const atlasService = atlasServiceLocator(); @@ -102,7 +112,7 @@ export const DataModelStorageServiceProviderAtlas = createServiceProvider( } else { logger.log.warn( mongoLogId(1_001_000_379), - 'DataModelStorageServiceProviderAtlas', + 'DataModelStorageServiceProviderWeb', 'Falling back to in memory storage because orgId or projectId is missing' ); // Fallback to in-memory if we're outside of Atlas Cloud diff --git a/packages/compass-data-modeling/web.d.ts b/packages/compass-data-modeling/web.d.ts index 67cb4172045..af1d4190f57 100644 --- a/packages/compass-data-modeling/web.d.ts +++ b/packages/compass-data-modeling/web.d.ts @@ -1 +1 @@ -export * from './dist/services/data-model-storage-atlas.d'; +export * from './dist/services/data-model-storage-web.d'; diff --git a/packages/compass-data-modeling/web.js b/packages/compass-data-modeling/web.js index cbaa64a0c8d..9fa8b57b899 100644 --- a/packages/compass-data-modeling/web.js +++ b/packages/compass-data-modeling/web.js @@ -1,2 +1,2 @@ 'use strict'; -module.exports = require('./dist/services/data-model-storage-atlas'); +module.exports = require('./dist/services/data-model-storage-web'); diff --git a/packages/compass-web/src/entrypoint.tsx b/packages/compass-web/src/entrypoint.tsx index f35f1cd8695..22cc48c44b4 100644 --- a/packages/compass-web/src/entrypoint.tsx +++ b/packages/compass-web/src/entrypoint.tsx @@ -63,7 +63,7 @@ import { WebWorkspaceTab as WelcomeWorkspaceTab } from '@mongodb-js/compass-welc import { WorkspaceTab as MyQueriesWorkspace } from '@mongodb-js/compass-saved-aggregations-queries'; import { useCompassWebPreferences } from './preferences'; import { DataModelingWorkspaceTab as DataModelingWorkspace } from '@mongodb-js/compass-data-modeling'; -import { DataModelStorageServiceProviderAtlas } from '@mongodb-js/compass-data-modeling/web'; +import { DataModelStorageServiceProviderWeb } from '@mongodb-js/compass-data-modeling/web'; import { createWebRecentQueryStorage, createWebFavoriteQueryStorage, @@ -507,7 +507,7 @@ const CompassWeb = ({ - @@ -579,7 +579,7 @@ const CompassWeb = ({ - + From 27fe7caae6fd5d88bba2da82450a9dbfbe11b08d Mon Sep 17 00:00:00 2001 From: Sergey Petushkov Date: Tue, 21 Oct 2025 09:31:09 +0200 Subject: [PATCH 6/6] chore(data-modeling): update package.json --- package-lock.json | 4 ++-- packages/compass-data-modeling/package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5cde6e1fc9e..c484a5a22fb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -49501,7 +49501,7 @@ "version": "1.32.0", "license": "SSPL", "dependencies": { - "@mongodb-js/atlas-service": "^0.64.0", + "@mongodb-js/atlas-service": "^0.65.0", "@mongodb-js/compass-app-registry": "^9.4.27", "@mongodb-js/compass-app-stores": "^7.67.0", "@mongodb-js/compass-components": "^1.55.0", @@ -63557,7 +63557,7 @@ "@mongodb-js/compass-data-modeling": { "version": "file:packages/compass-data-modeling", "requires": { - "@mongodb-js/atlas-service": "^0.64.0", + "@mongodb-js/atlas-service": "^0.65.0", "@mongodb-js/compass-app-registry": "^9.4.27", "@mongodb-js/compass-app-stores": "^7.67.0", "@mongodb-js/compass-components": "^1.55.0", diff --git a/packages/compass-data-modeling/package.json b/packages/compass-data-modeling/package.json index 23b2071700d..d03291c6947 100644 --- a/packages/compass-data-modeling/package.json +++ b/packages/compass-data-modeling/package.json @@ -54,7 +54,7 @@ "reformat": "npm run eslint . -- --fix && npm run prettier -- --write ." }, "dependencies": { - "@mongodb-js/atlas-service": "^0.64.0", + "@mongodb-js/atlas-service": "^0.65.0", "@mongodb-js/compass-app-registry": "^9.4.27", "@mongodb-js/compass-app-stores": "^7.67.0", "@mongodb-js/compass-components": "^1.55.0",