Skip to content

Commit 2c0de81

Browse files
committed
feat: building demo for saving user data project
1 parent f6efcd6 commit 2c0de81

File tree

8 files changed

+243
-94
lines changed

8 files changed

+243
-94
lines changed

packages/atlas-service/src/atlas-service.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,11 @@ export class AtlasService {
7575
// https://github.com/10gen/mms/blob/9f858bb987aac6aa80acfb86492dd74c89cbb862/client/packages/project/common/ajaxPrefilter.ts#L34-L49
7676
return this.cloudEndpoint(path);
7777
}
78+
tempEndpoint(path?: string): string {
79+
return `https://cluster-connection.cloud-dev.mongodb.com${normalizePath(
80+
path
81+
)}`;
82+
}
7883
driverProxyEndpoint(path?: string): string {
7984
return `${this.config.ccsBaseUrl}${normalizePath(path)}`;
8085
}

packages/atlas-service/src/provider.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ export const AtlasServiceProvider: React.FC<{
4848
);
4949
});
5050

51-
function useAtlasServiceContext(): AtlasService {
51+
export function useAtlasServiceContext(): AtlasService {
5252
const service = useContext(AtlasServiceContext);
5353
if (!service) {
5454
throw new Error('No AtlasService available in this context');

packages/compass-aggregations/src/modules/saved-pipeline.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@ export const savedPipelineAdd = (
7777

7878
export const getSavedPipelines =
7979
(): PipelineBuilderThunkAction<void> => (dispatch, getState) => {
80+
console.log('Get saved pipelines');
81+
// debugger;
8082
if (!getState().savedPipeline.isLoaded) {
8183
dispatch(updatePipelineList());
8284
}
@@ -93,6 +95,8 @@ export const updatePipelineList =
9395
{ pipelineStorage, logger: { debug }, globalAppRegistry }
9496
) => {
9597
const state = getState();
98+
console.log('Update pipeline list');
99+
// debugger;
96100
pipelineStorage
97101
?.loadAll()
98102
.then((pipelines: SavedPipeline[]) => {

packages/compass-user-data/src/user-data.ts

Lines changed: 24 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ const { log, mongoLogId } = createLogger('COMPASS-USER-STORAGE');
1010

1111
type SerializeContent<I> = (content: I) => string;
1212
type DeserializeContent = (content: string) => unknown;
13-
type GetResourceUrl = (path?: string) => Promise<string>;
13+
type GetResourceUrl = (path?: string) => string;
1414
type AuthenticatedFetch = (
1515
url: RequestInfo | URL,
1616
options?: RequestInit
@@ -61,6 +61,10 @@ export abstract class IUserData<T extends z.Schema> {
6161
abstract write(id: string, content: z.input<T>): Promise<boolean>;
6262
abstract delete(id: string): Promise<boolean>;
6363
abstract readAll(options?: ReadOptions): Promise<ReadAllResult<T>>;
64+
abstract readOne(
65+
id: string,
66+
options?: ReadOptions
67+
): Promise<z.output<T> | undefined>;
6468
abstract updateAttributes(
6569
id: string,
6670
data: Partial<z.input<T>>
@@ -292,8 +296,8 @@ export class AtlasUserData<T extends z.Schema> extends IUserData<T> {
292296
this.validator.parse(content);
293297

294298
const response = await this.authenticatedFetch(
295-
await this.getResourceUrl(
296-
`${this.dataType}/${this.orgId}/${this.projectId}`
299+
this.getResourceUrl(
300+
`userData/${this.dataType}/${this.orgId}/${this.projectId}`
297301
),
298302
{
299303
method: 'POST',
@@ -322,8 +326,8 @@ export class AtlasUserData<T extends z.Schema> extends IUserData<T> {
322326
'Atlas Backend',
323327
'Error writing data',
324328
{
325-
url: await this.getResourceUrl(
326-
`${this.dataType}/${this.orgId}/${this.projectId}`
329+
url: this.getResourceUrl(
330+
`userData/${this.dataType}/${this.orgId}/${this.projectId}`
327331
),
328332
error: (error as Error).message,
329333
}
@@ -335,8 +339,8 @@ export class AtlasUserData<T extends z.Schema> extends IUserData<T> {
335339
async delete(id: string): Promise<boolean> {
336340
try {
337341
const response = await this.authenticatedFetch(
338-
await this.getResourceUrl(
339-
`${this.dataType}/${this.orgId}/${this.projectId}/${id}`
342+
this.getResourceUrl(
343+
`userData/${this.dataType}/${this.orgId}/${this.projectId}/${id}`
340344
),
341345
{
342346
method: 'DELETE',
@@ -354,8 +358,8 @@ export class AtlasUserData<T extends z.Schema> extends IUserData<T> {
354358
'Atlas Backend',
355359
'Error deleting data',
356360
{
357-
url: await this.getResourceUrl(
358-
`${this.dataType}/${this.orgId}/${this.projectId}/${id}`
361+
url: this.getResourceUrl(
362+
`userData/${this.dataType}/${this.orgId}/${this.projectId}/${id}`
359363
),
360364
error: (error as Error).message,
361365
}
@@ -369,10 +373,11 @@ export class AtlasUserData<T extends z.Schema> extends IUserData<T> {
369373
data: [],
370374
errors: [],
371375
};
376+
// debugger;
372377
try {
373378
const response = await this.authenticatedFetch(
374-
await this.getResourceUrl(
375-
`${this.dataType}/${this.orgId}/${this.projectId}`
379+
this.getResourceUrl(
380+
`userData/${this.dataType}/${this.orgId}/${this.projectId}`
376381
),
377382
{
378383
method: 'GET',
@@ -411,8 +416,8 @@ export class AtlasUserData<T extends z.Schema> extends IUserData<T> {
411416
};
412417

413418
const response = await this.authenticatedFetch(
414-
await this.getResourceUrl(
415-
`${this.dataType}/${this.orgId}/${this.projectId}/${id}`
419+
this.getResourceUrl(
420+
`userData/${this.dataType}/${this.orgId}/${this.projectId}/${id}`
416421
),
417422
{
418423
method: 'PUT',
@@ -434,8 +439,8 @@ export class AtlasUserData<T extends z.Schema> extends IUserData<T> {
434439
'Atlas Backend',
435440
'Error updating data',
436441
{
437-
url: await this.getResourceUrl(
438-
`${this.dataType}/${this.orgId}/${this.projectId}/${id}`
442+
url: this.getResourceUrl(
443+
`userData/${this.dataType}/${this.orgId}/${this.projectId}/${id}`
439444
),
440445
error: (error as Error).message,
441446
}
@@ -448,8 +453,8 @@ export class AtlasUserData<T extends z.Schema> extends IUserData<T> {
448453
async readOne(id: string): Promise<z.output<T>> {
449454
try {
450455
const getResponse = await this.authenticatedFetch(
451-
await this.getResourceUrl(
452-
`${this.dataType}/${this.orgId}/${this.projectId}/${id}`
456+
this.getResourceUrl(
457+
`userData/${this.dataType}/${this.orgId}/${this.projectId}/${id}`
453458
),
454459
{
455460
method: 'GET',
@@ -469,8 +474,8 @@ export class AtlasUserData<T extends z.Schema> extends IUserData<T> {
469474
'Atlas Backend',
470475
'Error reading data',
471476
{
472-
url: await this.getResourceUrl(
473-
`${this.dataType}/${this.orgId}/${this.projectId}/${id}`
477+
url: this.getResourceUrl(
478+
`userData/${this.dataType}/${this.orgId}/${this.projectId}/${id}`
474479
),
475480
error: (error as Error).message,
476481
}

packages/compass-web/src/entrypoint.tsx

Lines changed: 126 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,10 @@ import {
4444
import { PreferencesProvider } from 'compass-preferences-model/provider';
4545
import type { AllPreferences } from 'compass-preferences-model/provider';
4646
import FieldStorePlugin from '@mongodb-js/compass-field-store';
47-
import { AtlasServiceProvider } from '@mongodb-js/atlas-service/provider';
47+
import {
48+
AtlasServiceProvider,
49+
useAtlasServiceContext,
50+
} from '@mongodb-js/atlas-service/provider';
4851
import { AtlasAiServiceProvider } from '@mongodb-js/compass-generative-ai/provider';
4952
import { LoggerProvider } from '@mongodb-js/compass-logging/provider';
5053
import { TelemetryProvider } from '@mongodb-js/compass-telemetry/provider';
@@ -55,9 +58,22 @@ import type { LogFunction, DebugFunction } from './logger';
5558
import { useCompassWebLogger } from './logger';
5659
import { type TelemetryServiceOptions } from '@mongodb-js/compass-telemetry';
5760
import { WebWorkspaceTab as WelcomeWorkspaceTab } from '@mongodb-js/compass-welcome';
61+
import { WorkspaceTab as MyQueriesWorkspace } from '@mongodb-js/compass-saved-aggregations-queries';
5862
import { useCompassWebPreferences } from './preferences';
5963
import { DataModelingWorkspaceTab as DataModelingWorkspace } from '@mongodb-js/compass-data-modeling';
6064
import { DataModelStorageServiceProviderInMemory } from '@mongodb-js/compass-data-modeling/web';
65+
import {
66+
CompassFavoriteQueryStorage,
67+
CompassPipelineStorage,
68+
CompassRecentQueryStorage,
69+
} from '@mongodb-js/my-queries-storage';
70+
import {
71+
PipelineStorageProvider,
72+
FavoriteQueryStorageProvider,
73+
RecentQueryStorageProvider,
74+
type FavoriteQueryStorageAccess,
75+
type RecentQueryStorageAccess,
76+
} from '@mongodb-js/my-queries-storage/provider';
6177

6278
export type TrackFunction = (
6379
event: string,
@@ -78,6 +94,57 @@ const WithAtlasProviders: React.FC = ({ children }) => {
7894
);
7995
};
8096

97+
const WithStorageProviders: React.FC<{ orgId: string; projectId: string }> = ({
98+
children,
99+
orgId,
100+
projectId,
101+
}) => {
102+
const atlasService = useAtlasServiceContext();
103+
console.log('atlasService', atlasService);
104+
const authenticatedFetch = atlasService.authenticatedFetch;
105+
// TODO: use non-hardcoded endpoint
106+
const getResourceUrl = atlasService.tempEndpoint;
107+
const pipelineStorage = useRef(
108+
new CompassPipelineStorage({
109+
orgId,
110+
projectId,
111+
getResourceUrl,
112+
authenticatedFetch,
113+
})
114+
);
115+
const favoriteQueryStorage = useRef<FavoriteQueryStorageAccess>({
116+
getStorage(options) {
117+
return new CompassFavoriteQueryStorage({
118+
...options,
119+
orgId,
120+
projectId,
121+
getResourceUrl,
122+
authenticatedFetch,
123+
});
124+
},
125+
});
126+
const recentQueryStorage = useRef<RecentQueryStorageAccess>({
127+
getStorage(options) {
128+
return new CompassRecentQueryStorage({
129+
...options,
130+
orgId,
131+
projectId,
132+
getResourceUrl,
133+
authenticatedFetch,
134+
});
135+
},
136+
});
137+
return (
138+
<PipelineStorageProvider value={pipelineStorage.current}>
139+
<FavoriteQueryStorageProvider value={favoriteQueryStorage.current}>
140+
<RecentQueryStorageProvider value={recentQueryStorage.current}>
141+
{children}
142+
</RecentQueryStorageProvider>
143+
</FavoriteQueryStorageProvider>
144+
</PipelineStorageProvider>
145+
);
146+
};
147+
81148
type CompassWorkspaceProps = Pick<
82149
React.ComponentProps<typeof WorkspacesPlugin>,
83150
'initialWorkspaceTabs' | 'onActiveWorkspaceTabChange'
@@ -178,6 +245,7 @@ function CompassWorkspace({
178245
CollectionsWorkspaceTab,
179246
CollectionWorkspace,
180247
DataModelingWorkspace,
248+
MyQueriesWorkspace,
181249
]}
182250
>
183251
<CollectionTabsProvider
@@ -358,63 +426,65 @@ const CompassWeb = ({
358426
<LoggerProvider value={logger}>
359427
<TelemetryProvider options={telemetryOptions.current}>
360428
<WithAtlasProviders>
361-
<DataModelStorageServiceProviderInMemory>
362-
<AtlasCloudConnectionStorageProvider
363-
orgId={orgId}
364-
projectId={projectId}
365-
>
366-
<CompassConnections
367-
appName={appName ?? 'Compass Web'}
368-
onFailToLoadConnections={onFailToLoadConnections}
369-
onExtraConnectionDataRequest={() => {
370-
return Promise.resolve([{}, null] as [
371-
Record<string, unknown>,
372-
null
373-
]);
374-
}}
375-
onAutoconnectInfoRequest={(connectionStore) => {
376-
if (autoconnectId) {
377-
return connectionStore.loadAll().then(
378-
(connections) => {
379-
return connections.find(
380-
(connectionInfo) =>
381-
connectionInfo.id === autoconnectId
382-
);
383-
},
384-
(err) => {
385-
const { log, mongoLogId } = logger;
386-
log.warn(
387-
mongoLogId(1_001_000_329),
388-
'Compass Web',
389-
'Could not load connections when trying to autoconnect',
390-
{ err: err.message }
391-
);
392-
return undefined;
393-
}
394-
);
395-
}
396-
return Promise.resolve(undefined);
397-
}}
429+
<WithStorageProviders orgId={orgId} projectId={projectId}>
430+
<DataModelStorageServiceProviderInMemory>
431+
<AtlasCloudConnectionStorageProvider
432+
orgId={orgId}
433+
projectId={projectId}
398434
>
399-
<CompassInstanceStorePlugin>
400-
<FieldStorePlugin>
401-
<WithConnectionsStore>
402-
<CompassWorkspace
403-
initialWorkspaceTabs={
404-
initialWorkspaceTabsRef.current
405-
}
406-
onActiveWorkspaceTabChange={
407-
onActiveWorkspaceTabChange
435+
<CompassConnections
436+
appName={appName ?? 'Compass Web'}
437+
onFailToLoadConnections={onFailToLoadConnections}
438+
onExtraConnectionDataRequest={() => {
439+
return Promise.resolve([{}, null] as [
440+
Record<string, unknown>,
441+
null
442+
]);
443+
}}
444+
onAutoconnectInfoRequest={(connectionStore) => {
445+
if (autoconnectId) {
446+
return connectionStore.loadAll().then(
447+
(connections) => {
448+
return connections.find(
449+
(connectionInfo) =>
450+
connectionInfo.id === autoconnectId
451+
);
452+
},
453+
(err) => {
454+
const { log, mongoLogId } = logger;
455+
log.warn(
456+
mongoLogId(1_001_000_329),
457+
'Compass Web',
458+
'Could not load connections when trying to autoconnect',
459+
{ err: err.message }
460+
);
461+
return undefined;
408462
}
409-
onOpenConnectViaModal={onOpenConnectViaModal}
410-
></CompassWorkspace>
411-
</WithConnectionsStore>
412-
</FieldStorePlugin>
413-
<CompassGenerativeAIPlugin projectId={projectId} />
414-
</CompassInstanceStorePlugin>
415-
</CompassConnections>
416-
</AtlasCloudConnectionStorageProvider>
417-
</DataModelStorageServiceProviderInMemory>
463+
);
464+
}
465+
return Promise.resolve(undefined);
466+
}}
467+
>
468+
<CompassInstanceStorePlugin>
469+
<FieldStorePlugin>
470+
<WithConnectionsStore>
471+
<CompassWorkspace
472+
initialWorkspaceTabs={
473+
initialWorkspaceTabsRef.current
474+
}
475+
onActiveWorkspaceTabChange={
476+
onActiveWorkspaceTabChange
477+
}
478+
onOpenConnectViaModal={onOpenConnectViaModal}
479+
></CompassWorkspace>
480+
</WithConnectionsStore>
481+
</FieldStorePlugin>
482+
<CompassGenerativeAIPlugin projectId={projectId} />
483+
</CompassInstanceStorePlugin>
484+
</CompassConnections>
485+
</AtlasCloudConnectionStorageProvider>
486+
</DataModelStorageServiceProviderInMemory>
487+
</WithStorageProviders>
418488
</WithAtlasProviders>
419489
</TelemetryProvider>
420490
</LoggerProvider>

packages/my-queries-storage/src/compass-pipeline-storage.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ describe('CompassPipelineStorage', function () {
2121

2222
beforeEach(async function () {
2323
tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), 'saved-pipelines-tests'));
24-
pipelineStorage = new CompassPipelineStorage(tmpDir);
24+
pipelineStorage = new CompassPipelineStorage({ basePath: tmpDir });
2525
});
2626

2727
afterEach(async function () {

0 commit comments

Comments
 (0)