Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ const editablePreferences: (keyof UserPreferences)[] = [
'enableGenAIFeaturesAtlasOrg',
'enableGenAIFeaturesAtlasProject',
'enableDataModeling',
'enableMyQueries',
];

export class CompassWebPreferencesAccess implements PreferencesAccess {
Expand Down
11 changes: 11 additions & 0 deletions packages/compass-preferences-model/src/feature-flags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export type FeatureFlags = {
showDisabledConnections: boolean;
enableGlobalWrites: boolean;
enableDataModeling: boolean;
enableMyQueries: boolean;
enableIndexesGuidanceExp: boolean;
showIndexesGuidanceVariant: boolean;
enableContextMenus: boolean;
Expand Down Expand Up @@ -126,6 +127,16 @@ export const featureFlags: Required<{
},
},

/**
* Enable My Queries feature in Data Explorer
*/
enableMyQueries: {
stage: 'development',
description: {
short: 'Save and manage favorite queries and aggregations',
},
},
Copy link
Collaborator

@paula-stacho paula-stacho Sep 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so this part is a bit confusing, but this configuration and feature flags relate to compass, not DE. so adding it here with stage: 'development' adds it to these "feature preview" flags that we have in Compass. They are also turned off by default, which we don't want here.

Image

So instead of adding it to FeatureFlags, let's add it to the "other" section in UserConfigurablePreferences and storedUserPreferencesProps. Example you can follow is enableImportExport (make sure to use default true, you can still override that for compass-web, but the default compass setting for this feature is on).


/**
* Feature flags for Early Journey Indexes Guidance & Awareness | Jira Epic: CLOUDP-239367
* These are passed from MMS and not editable by user
Expand Down
10 changes: 8 additions & 2 deletions packages/compass-query-bar/src/components/query-bar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@ import {
createAIPlaceholderHTMLPlaceholder,
} from '@mongodb-js/compass-generative-ai';
import { connect } from '../stores/context';
import { useIsAIFeatureEnabled } from 'compass-preferences-model/provider';
import {
useIsAIFeatureEnabled,
usePreference,
} from 'compass-preferences-model/provider';
import { useTelemetry } from '@mongodb-js/compass-telemetry/provider';

import {
Expand Down Expand Up @@ -202,8 +205,11 @@ export const QueryBar: React.FunctionComponent<QueryBarProps> = ({

const favoriteQueryStorageAvailable = !!useFavoriteQueryStorageAccess();
const recentQueryStorageAvailable = !!useRecentQueryStorageAccess();
const isMyQueriesEnabled = usePreference('enableMyQueries');
const enableSavedAggregationsQueries =
favoriteQueryStorageAvailable && recentQueryStorageAvailable;
favoriteQueryStorageAvailable &&
recentQueryStorageAvailable &&
isMyQueriesEnabled;

return (
<form
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,10 @@ export function Navigation({
const { openMyQueriesWorkspace, openDataModelingWorkspace } =
useOpenWorkspace();
const isDataModelingEnabled = usePreference('enableDataModeling');
const isMyQueriesEnabled = usePreference('enableMyQueries');
return (
<div>
{hasWorkspacePlugin('My Queries') && (
{hasWorkspacePlugin('My Queries') && isMyQueriesEnabled && (
<NavigationItem
onClick={openMyQueriesWorkspace}
glyph="CurlyBraces"
Expand Down
5 changes: 3 additions & 2 deletions packages/compass-web/sandbox/index.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import React, { useCallback, useLayoutEffect, useRef } from 'react';
import ReactDOM from 'react-dom';
import {
resetGlobalCSS,
css,
Body,
css,
openToast,
resetGlobalCSS,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alphabetical 🙌 big fan.

} from '@mongodb-js/compass-components';
import type { AllPreferences } from 'compass-preferences-model';
import { CompassWeb } from '../src/index';
Expand Down Expand Up @@ -137,6 +137,7 @@ const App = () => {
isAtlas && !!enableGenAIFeaturesAtlasOrg,
optInGenAIFeatures: isAtlas && !!optInGenAIFeatures,
enableDataModeling: true,
enableMyQueries: true,
}}
onTrack={sandboxTelemetry.track}
onDebug={sandboxLogger.debug}
Expand Down
139 changes: 75 additions & 64 deletions packages/compass-web/src/entrypoint.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,20 @@ import WorkspacesPlugin, {
WorkspacesProvider,
} from '@mongodb-js/compass-workspaces';
import {
DatabasesWorkspaceTab,
CollectionsWorkspaceTab,
CreateNamespacePlugin,
DatabasesWorkspaceTab,
DropNamespacePlugin,
RenameCollectionPlugin,
} from '@mongodb-js/compass-databases-collections';
import { CompassComponentsProvider, css } from '@mongodb-js/compass-components';
import {
WorkspaceTab as CollectionWorkspace,
CollectionTabsProvider,
WorkspaceTab as CollectionWorkspace,
} from '@mongodb-js/compass-collection';
import {
CompassSidebarPlugin,
AtlasClusterConnectionsOnlyProvider,
CompassSidebarPlugin,
} from '@mongodb-js/compass-sidebar';
import CompassQueryBarPlugin from '@mongodb-js/compass-query-bar';
import { CompassDocumentsPlugin } from '@mongodb-js/compass-crud';
Expand All @@ -36,13 +39,8 @@ import { CompassGlobalWritesPlugin } from '@mongodb-js/compass-global-writes';
import { CompassGenerativeAIPlugin } from '@mongodb-js/compass-generative-ai';
import ExplainPlanCollectionTabModal from '@mongodb-js/compass-explain-plan';
import ExportToLanguageCollectionTabModal from '@mongodb-js/compass-export-to-language';
import {
CreateNamespacePlugin,
DropNamespacePlugin,
RenameCollectionPlugin,
} from '@mongodb-js/compass-databases-collections';
import { PreferencesProvider } from 'compass-preferences-model/provider';
import type { AllPreferences } from 'compass-preferences-model/provider';
import { PreferencesProvider } from 'compass-preferences-model/provider';
import FieldStorePlugin from '@mongodb-js/compass-field-store';
import { AtlasServiceProvider } from '@mongodb-js/atlas-service/provider';
import { AtlasAiServiceProvider } from '@mongodb-js/compass-generative-ai/provider';
Expand All @@ -51,13 +49,20 @@ import { TelemetryProvider } from '@mongodb-js/compass-telemetry/provider';
import CompassConnections from '@mongodb-js/compass-connections';
import { AtlasCloudConnectionStorageProvider } from './connection-storage';
import { AtlasCloudAuthServiceProvider } from './atlas-auth-service';
import type { LogFunction, DebugFunction } from './logger';
import type { DebugFunction, LogFunction } from './logger';
import { useCompassWebLogger } from './logger';
import { type TelemetryServiceOptions } from '@mongodb-js/compass-telemetry';
import { WebWorkspaceTab as WelcomeWorkspaceTab } from '@mongodb-js/compass-welcome';
import { useCompassWebPreferences } from './preferences';
import { DataModelingWorkspaceTab as DataModelingWorkspace } from '@mongodb-js/compass-data-modeling';
import { DataModelStorageServiceProviderInMemory } from '@mongodb-js/compass-data-modeling/web';
import { WorkspaceTab as MyQueriesWorkspace } from '@mongodb-js/compass-saved-aggregations-queries';
import {
FavoriteQueryStorageProvider,
RecentQueryStorageProvider,
compassFavoriteQueryStorageAccess,
compassRecentQueryStorageAccess,
} from '@mongodb-js/my-queries-storage';
import {
CompassAssistantDrawer,
CompassAssistantProvider,
Expand Down Expand Up @@ -175,61 +180,66 @@ function CompassWorkspace({
onOpenConnectViaModal,
}: CompassWorkspaceProps) {
return (
<WorkspacesProvider
value={[
WelcomeWorkspaceTab,
DatabasesWorkspaceTab,
CollectionsWorkspaceTab,
CollectionWorkspace,
DataModelingWorkspace,
]}
>
<CollectionTabsProvider
queryBar={CompassQueryBarPlugin}
tabs={[
CompassDocumentsPlugin,
CompassAggregationsPlugin,
CompassSchemaPlugin,
CompassIndexesPlugin,
CompassSchemaValidationPlugin,
CompassGlobalWritesPlugin,
]}
modals={[
ExplainPlanCollectionTabModal,
ExportToLanguageCollectionTabModal,
]}
>
<div
data-testid="compass-web-connected"
className={connectedContainerStyles}
<FavoriteQueryStorageProvider value={compassFavoriteQueryStorageAccess}>
<RecentQueryStorageProvider value={compassRecentQueryStorageAccess}>
<WorkspacesProvider
value={[
WelcomeWorkspaceTab,
DatabasesWorkspaceTab,
CollectionsWorkspaceTab,
CollectionWorkspace,
DataModelingWorkspace,
MyQueriesWorkspace,
]}
>
<WorkspacesPlugin
initialWorkspaceTabs={initialWorkspaceTabs}
openOnEmptyWorkspace={{ type: 'Welcome' }}
onActiveWorkspaceTabChange={onActiveWorkspaceTabChange}
renderSidebar={() => {
return (
<CompassSidebarPlugin
onOpenConnectViaModal={onOpenConnectViaModal}
isCompassWeb={true}
></CompassSidebarPlugin>
);
}}
renderModals={() => {
return (
<>
<CreateViewPlugin></CreateViewPlugin>
<CreateNamespacePlugin></CreateNamespacePlugin>
<DropNamespacePlugin></DropNamespacePlugin>
<RenameCollectionPlugin></RenameCollectionPlugin>
<CompassAssistantDrawer />
</>
);
}}
></WorkspacesPlugin>
</div>
</CollectionTabsProvider>
</WorkspacesProvider>
<CollectionTabsProvider
queryBar={CompassQueryBarPlugin}
tabs={[
CompassDocumentsPlugin,
CompassAggregationsPlugin,
CompassSchemaPlugin,
CompassIndexesPlugin,
CompassSchemaValidationPlugin,
CompassGlobalWritesPlugin,
]}
modals={[
ExplainPlanCollectionTabModal,
ExportToLanguageCollectionTabModal,
]}
>
<div
data-testid="compass-web-connected"
className={connectedContainerStyles}
>
<WorkspacesPlugin
initialWorkspaceTabs={initialWorkspaceTabs}
openOnEmptyWorkspace={{ type: 'Welcome' }}
onActiveWorkspaceTabChange={onActiveWorkspaceTabChange}
renderSidebar={() => {
return (
<CompassSidebarPlugin
onOpenConnectViaModal={onOpenConnectViaModal}
isCompassWeb={true}
></CompassSidebarPlugin>
);
}}
renderModals={() => {
return (
<>
<CreateViewPlugin></CreateViewPlugin>
<CreateNamespacePlugin></CreateNamespacePlugin>
<DropNamespacePlugin></DropNamespacePlugin>
<RenameCollectionPlugin></RenameCollectionPlugin>
<CompassAssistantDrawer />
</>
);
}}
></WorkspacesPlugin>
</div>
</CollectionTabsProvider>
</WorkspacesProvider>
</RecentQueryStorageProvider>
</FavoriteQueryStorageProvider>
);
}

Expand Down Expand Up @@ -280,6 +290,7 @@ const CompassWeb = ({
onDebug,
});
const preferencesAccess = useCompassWebPreferences(initialPreferences);
// TODO: My Queries feature flag will be used to conditionally provide storage providers in COMPASS-9565
const initialWorkspaceRef = useRef(initialWorkspace);
const initialWorkspaceTabsRef = useRef(
initialWorkspaceRef.current ? [initialWorkspaceRef.current] : []
Expand Down
3 changes: 2 additions & 1 deletion packages/compass-web/src/preferences.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useContext, useRef, useEffect } from 'react';
import React, { useContext, useEffect, useRef } from 'react';
import type { AllPreferences } from 'compass-preferences-model/provider';
import { CompassWebPreferencesAccess } from 'compass-preferences-model/provider';

Expand Down Expand Up @@ -47,6 +47,7 @@ export function useCompassWebPreferences(
enableGenAISampleDocumentPassingOnAtlasProject: false,
enableGenAIFeaturesAtlasOrg: false,
enablePerformanceAdvisorBanner: true,
enableMyQueries: false,
cloudFeatureRolloutAccess: {
GEN_AI_COMPASS: false,
},
Expand Down
3 changes: 2 additions & 1 deletion packages/my-queries-storage/src/compass-query-storage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ export abstract class CompassQueryStorage<TSchema extends z.Schema> {
protected readonly folder: string,
protected readonly options: QueryStorageOptions
) {
// TODO: logic for whether we're in compass web or compass desktop
// Simple implementation - use FileUserData for now
// The use-atlas-user-data branch will add proper Atlas integration
this.userData = new FileUserData(schemaValidator, folder, {
basePath: options.basepath,
serialize: (content) => EJSON.stringify(content, undefined, 2),
Expand Down
7 changes: 7 additions & 0 deletions packages/my-queries-storage/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,13 @@ export {
} from './compass-query-storage';
export type { RecentQuery, FavoriteQuery } from './query-storage-schema';

// Export providers for use in applications
export {
FavoriteQueryStorageProvider,
RecentQueryStorageProvider,
PipelineStorageProvider,
} from './provider';

Copy link
Collaborator

@paula-stacho paula-stacho Sep 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The provider being exported separately is actually intentional, this is to have a clear separation between the service and the provider (we even have a rule that restricts direct use of the service).
You can import these from @mongodb-js/my-queries-storage/provider

// These are exported to aid in testing
export const compassFavoriteQueryStorageAccess: FavoriteQueryStorageAccess = {
getStorage() {
Expand Down
Loading