diff --git a/package-lock.json b/package-lock.json index 9b2e71e0417..e805f3720c5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -51482,9 +51482,9 @@ } }, "packages/compass-user-data/node_modules/zod": { - "version": "3.25.17", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.17.tgz", - "integrity": "sha512-8hQzQ/kMOIFbwOgPrm9Sf9rtFHpFUMy4HvN0yEB0spw14aYi0uT5xG5CE2DB9cd51GWNsz+DNO7se1kztHMKnw==", + "version": "3.25.76", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/colinhacks" @@ -51567,6 +51567,7 @@ "@mongodb-js/compass-indexes": "^5.71.1", "@mongodb-js/compass-logging": "^1.7.13", "@mongodb-js/compass-query-bar": "^8.73.1", + "@mongodb-js/compass-saved-aggregations-queries": "^1.72.1", "@mongodb-js/compass-schema": "^6.73.1", "@mongodb-js/compass-schema-validation": "^6.72.1", "@mongodb-js/compass-sidebar": "^5.72.1", @@ -51578,6 +51579,7 @@ "@mongodb-js/devtools-proxy-support": "^0.5.2", "@mongodb-js/eslint-config-compass": "^1.4.8", "@mongodb-js/mocha-config-compass": "^1.7.1", + "@mongodb-js/my-queries-storage": "^0.39.1", "@mongodb-js/prettier-config-compass": "^1.2.8", "@mongodb-js/testing-library-compass": "^1.3.11", "@mongodb-js/tsconfig-compass": "^1.2.10", @@ -64128,9 +64130,9 @@ } }, "zod": { - "version": "3.25.17", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.17.tgz", - "integrity": "sha512-8hQzQ/kMOIFbwOgPrm9Sf9rtFHpFUMy4HvN0yEB0spw14aYi0uT5xG5CE2DB9cd51GWNsz+DNO7se1kztHMKnw==" + "version": "3.25.76", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==" } } }, @@ -64202,6 +64204,7 @@ "@mongodb-js/compass-indexes": "^5.71.1", "@mongodb-js/compass-logging": "^1.7.13", "@mongodb-js/compass-query-bar": "^8.73.1", + "@mongodb-js/compass-saved-aggregations-queries": "^1.72.1", "@mongodb-js/compass-schema": "^6.73.1", "@mongodb-js/compass-schema-validation": "^6.72.1", "@mongodb-js/compass-sidebar": "^5.72.1", @@ -64213,6 +64216,7 @@ "@mongodb-js/devtools-proxy-support": "^0.5.2", "@mongodb-js/eslint-config-compass": "^1.4.8", "@mongodb-js/mocha-config-compass": "^1.7.1", + "@mongodb-js/my-queries-storage": "^0.39.1", "@mongodb-js/prettier-config-compass": "^1.2.8", "@mongodb-js/testing-library-compass": "^1.3.11", "@mongodb-js/tsconfig-compass": "^1.2.10", diff --git a/packages/compass-aggregations/src/components/pipeline-toolbar/pipeline-header/index.tsx b/packages/compass-aggregations/src/components/pipeline-toolbar/pipeline-header/index.tsx index 7b0a8124ff6..edff962481a 100644 --- a/packages/compass-aggregations/src/components/pipeline-toolbar/pipeline-header/index.tsx +++ b/packages/compass-aggregations/src/components/pipeline-toolbar/pipeline-header/index.tsx @@ -8,12 +8,12 @@ import { InteractivePopover, } from '@mongodb-js/compass-components'; import { connect } from 'react-redux'; +import { usePreference } from 'compass-preferences-model/provider'; import PipelineStages from './pipeline-stages'; import PipelineActions from './pipeline-actions'; import SavedPipelines from '../../saved-pipelines/saved-pipelines'; import type { RootState } from '../../../modules'; -import { usePipelineStorage } from '@mongodb-js/my-queries-storage/provider'; const containerStyles = css({ display: 'flex', @@ -110,9 +110,7 @@ export const PipelineHeader: React.FunctionComponent = ({ isOptionsVisible, isOpenPipelineVisible, }) => { - // TODO: remove direct check for storage existing, breaks single source of - // truth rule and exposes services to UI, this breaks the rules for locators - const isSavingAggregationsEnabled = !!usePipelineStorage(); + const isSavingAggregationsEnabled = usePreference('enableMyQueries'); return (
{isOpenPipelineVisible && isSavingAggregationsEnabled && ( diff --git a/packages/compass-aggregations/src/components/pipeline-toolbar/pipeline-settings/index.tsx b/packages/compass-aggregations/src/components/pipeline-toolbar/pipeline-settings/index.tsx index fdc36150d87..5d448fef3fa 100644 --- a/packages/compass-aggregations/src/components/pipeline-toolbar/pipeline-settings/index.tsx +++ b/packages/compass-aggregations/src/components/pipeline-toolbar/pipeline-settings/index.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { connect } from 'react-redux'; -import { Button, Icon, css, spacing } from '@mongodb-js/compass-components'; +import { Button, css, Icon, spacing } from '@mongodb-js/compass-components'; import { exportToLanguage } from '../../../modules/export-to-language'; import { SaveMenu } from './pipeline-menus'; import PipelineName from './pipeline-name'; @@ -10,7 +10,8 @@ import { getIsPipelineInvalidFromBuilderState } from '../../../modules/pipeline- import { confirmNewPipeline } from '../../../modules/is-new-pipeline-confirm'; import { hiddenOnNarrowPipelineToolbarStyles } from '../pipeline-toolbar-container'; import ModifySourceBanner from '../../modify-source-banner'; -import { usePipelineStorage } from '@mongodb-js/my-queries-storage/provider'; + +import { usePreference } from 'compass-preferences-model/provider'; const containerStyles = css({ display: 'flex', @@ -47,9 +48,7 @@ export const PipelineSettings: React.FunctionComponent< onExportToLanguage, onCreateNewPipeline, }) => { - // TODO: remove direct check for storage existing, breaks single source of - // truth rule and exposes services to UI, this breaks the rules for locators - const enableSavedAggregationsQueries = !!usePipelineStorage(); + const enableSavedAggregationsQueries = usePreference('enableMyQueries'); const isPipelineNameDisplayed = !editViewName && !!enableSavedAggregationsQueries; diff --git a/packages/compass-preferences-model/src/compass-web-preferences-access.ts b/packages/compass-preferences-model/src/compass-web-preferences-access.ts index 05b9095a3db..2e265de6207 100644 --- a/packages/compass-preferences-model/src/compass-web-preferences-access.ts +++ b/packages/compass-preferences-model/src/compass-web-preferences-access.ts @@ -18,6 +18,7 @@ const editablePreferences: (keyof UserPreferences)[] = [ 'enableGenAIFeaturesAtlasOrg', 'enableGenAIFeaturesAtlasProject', 'enableDataModeling', + 'enableMyQueries', ]; export class CompassWebPreferencesAccess implements PreferencesAccess { diff --git a/packages/compass-preferences-model/src/preferences-schema.tsx b/packages/compass-preferences-model/src/preferences-schema.tsx index 0ee39436d04..328d1ba8a5e 100644 --- a/packages/compass-preferences-model/src/preferences-schema.tsx +++ b/packages/compass-preferences-model/src/preferences-schema.tsx @@ -92,6 +92,7 @@ export type UserConfigurablePreferences = PermanentFeatureFlags & enableExplainPlan: boolean; enableAtlasSearchIndexes: boolean; enableImportExport: boolean; + enableMyQueries: boolean; enableAggregationBuilderRunPipeline: boolean; enableAggregationBuilderExtraOptions: boolean; enableGenAISampleDocumentPassing: boolean; @@ -851,6 +852,18 @@ export const storedUserPreferencesProps: Required<{ type: 'boolean', }, + enableMyQueries: { + ui: true, + cli: true, + global: true, + description: { + short: + 'Enable My Queries feature to save and manage favorite queries and aggregations', + }, + validator: z.boolean().default(true), + type: 'boolean', + }, + enableAggregationBuilderRunPipeline: { ui: true, cli: true, diff --git a/packages/compass-query-bar/src/components/query-bar.tsx b/packages/compass-query-bar/src/components/query-bar.tsx index 0b067ff8be9..585d1af6bca 100644 --- a/packages/compass-query-bar/src/components/query-bar.tsx +++ b/packages/compass-query-bar/src/components/query-bar.tsx @@ -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 { @@ -202,8 +205,11 @@ export const QueryBar: React.FunctionComponent = ({ const favoriteQueryStorageAvailable = !!useFavoriteQueryStorageAccess(); const recentQueryStorageAvailable = !!useRecentQueryStorageAccess(); + const isMyQueriesEnabled = usePreference('enableMyQueries'); const enableSavedAggregationsQueries = - favoriteQueryStorageAvailable && recentQueryStorageAvailable; + favoriteQueryStorageAvailable && + recentQueryStorageAvailable && + isMyQueriesEnabled; return (
- {hasWorkspacePlugin('My Queries') && ( + {hasWorkspacePlugin('My Queries') && isMyQueriesEnabled && ( { isAtlas && !!enableGenAIFeaturesAtlasOrg, optInGenAIFeatures: isAtlas && !!optInGenAIFeatures, enableDataModeling: true, + enableMyQueries: false, }} onTrack={sandboxTelemetry.track} onDebug={sandboxLogger.debug} diff --git a/packages/compass-web/src/entrypoint.tsx b/packages/compass-web/src/entrypoint.tsx index 690d93d1833..a762d03b774 100644 --- a/packages/compass-web/src/entrypoint.tsx +++ b/packages/compass-web/src/entrypoint.tsx @@ -15,17 +15,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'; @@ -40,13 +43,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'; @@ -55,13 +53,14 @@ 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 { CompassAssistantProvider } from '@mongodb-js/compass-assistant'; import { CompassAssistantDrawerWithConnections } from './compass-assistant-drawer'; import { APP_NAMES_FOR_PROMPT } from '@mongodb-js/compass-assistant'; @@ -188,6 +187,7 @@ function CompassWorkspace({ CollectionsWorkspaceTab, CollectionWorkspace, DataModelingWorkspace, + MyQueriesWorkspace, ]} > { protected readonly userData: IUserData; + constructor( schemaValidator: TSchema, 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 + // TODO(COMPASS-9565): 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),