Skip to content

Commit 9ed5868

Browse files
committed
feat(compass-collection) Disclaimer Screen - Mock Data Generator CLOUDP-333851
1 parent 9b7ff5b commit 9ed5868

File tree

18 files changed

+633
-629
lines changed

18 files changed

+633
-629
lines changed

package-lock.json

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/compass-collection/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
"@mongodb-js/compass-app-stores": "^7.56.0",
5353
"@mongodb-js/compass-components": "^1.48.0",
5454
"@mongodb-js/compass-connections": "^1.70.0",
55+
"@mongodb-js/compass-generative-ai": "^0.50.0",
5556
"@mongodb-js/compass-logging": "^1.7.11",
5657
"@mongodb-js/compass-telemetry": "^1.13.0",
5758
"@mongodb-js/compass-workspaces": "^0.51.0",

packages/compass-collection/src/components/collection-header-actions/collection-header-actions.spec.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,17 +22,24 @@ import CollectionHeaderActions from '../collection-header-actions';
2222
describe('CollectionHeaderActions [Component]', function () {
2323
let preferences: PreferencesAccess;
2424
let mockUseAssignment: sinon.SinonStub;
25+
let mockGetAssignment: sinon.SinonStub;
2526

2627
beforeEach(async function () {
2728
preferences = await createSandboxFromDefaultPreferences();
2829
mockUseAssignment = sinon.stub();
30+
mockGetAssignment = sinon.stub();
2931
mockUseAssignment.returns({
3032
assignment: {
3133
assignmentData: {
3234
variant: 'mockDataGeneratorControl',
3335
},
3436
},
3537
});
38+
mockGetAssignment.returns({
39+
assignmentData: {
40+
variant: 'mockDataGeneratorControl',
41+
},
42+
});
3643
});
3744

3845
afterEach(function () {
@@ -48,6 +55,7 @@ describe('CollectionHeaderActions [Component]', function () {
4855
<CompassExperimentationProvider
4956
useAssignment={mockUseAssignment}
5057
assignExperiment={sinon.stub()}
58+
getAssignment={mockGetAssignment}
5159
>
5260
<WorkspacesServiceProvider
5361
value={workspaceService as WorkspacesService}

packages/compass-collection/src/components/mock-data-generator-modal/mock-data-generator-modal.spec.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ describe('MockDataGeneratorModal', () => {
2323

2424
function renderModal({
2525
isOpen = true,
26-
currentStep = MockDataGeneratorStep.AI_DISCLAIMER,
26+
currentStep = MockDataGeneratorStep.SCHEMA_CONFIRMATION,
2727
} = {}) {
2828
return render(
2929
<MockDataGeneratorModal

packages/compass-collection/src/components/mock-data-generator-modal/mock-data-generator-modal.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ const MockDataGeneratorModal = ({
7070
<ModalFooter className={footerStyles}>
7171
<Button
7272
onClick={onPreviousStep}
73-
disabled={currentStep === MockDataGeneratorStep.AI_DISCLAIMER}
73+
disabled={currentStep === MockDataGeneratorStep.SCHEMA_CONFIRMATION}
7474
>
7575
Back
7676
</Button>

packages/compass-collection/src/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import {
1818
CollectionWorkspaceTitle,
1919
CollectionPluginTitleComponent,
2020
} from './plugin-tab-title';
21+
import { atlasAiServiceLocator } from '@mongodb-js/compass-generative-ai/provider';
2122

2223
export const WorkspaceTab: WorkspacePlugin<typeof CollectionWorkspaceTitle> = {
2324
name: CollectionWorkspaceTitle,
@@ -37,6 +38,7 @@ export const WorkspaceTab: WorkspacePlugin<typeof CollectionWorkspaceTitle> = {
3738
connectionInfoRef: connectionInfoRefLocator,
3839
logger: createLoggerLocator('COMPASS-COLLECTION'),
3940
preferences: preferencesLocator,
41+
atlasAiService: atlasAiServiceLocator,
4042
}
4143
),
4244
content: CollectionTab,

packages/compass-collection/src/modules/collection-tab.ts

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import type { DataService } from '@mongodb-js/compass-connections/provider';
1010
import type { experimentationServiceLocator } from '@mongodb-js/compass-telemetry/provider';
1111
import { type Logger, mongoLogId } from '@mongodb-js/compass-logging/provider';
1212
import { type PreferencesAccess } from 'compass-preferences-model/provider';
13+
import type { AtlasAiService } from '@mongodb-js/compass-generative-ai/provider';
14+
1315
import { isInternalFieldPath } from 'hadron-document';
1416
import toNS from 'mongodb-ns';
1517
import {
@@ -22,11 +24,11 @@ import {
2224
} from '../schema-analysis-types';
2325
import { calculateSchemaDepth } from '../calculate-schema-depth';
2426
import type { Document, MongoError } from 'mongodb';
27+
import { MockDataGeneratorStep } from '../components/mock-data-generator-modal/types';
2528

2629
const DEFAULT_SAMPLE_SIZE = 100;
2730

2831
const NO_DOCUMENTS_ERROR = 'No documents found in the collection to analyze.';
29-
import { MockDataGeneratorStep } from '../components/mock-data-generator-modal/types';
3032

3133
function isAction<A extends AnyAction>(
3234
action: AnyAction,
@@ -63,6 +65,7 @@ type CollectionThunkAction<R, A extends AnyAction = AnyAction> = ThunkAction<
6365
experimentationServices: ReturnType<typeof experimentationServiceLocator>;
6466
logger: Logger;
6567
preferences: PreferencesAccess;
68+
atlasAiService: AtlasAiService;
6669
},
6770
A
6871
>;
@@ -89,6 +92,7 @@ enum CollectionActions {
8992
MockDataGeneratorModalClosed = 'compass-collection/MockDataGeneratorModalClosed',
9093
MockDataGeneratorNextButtonClicked = 'compass-collection/MockDataGeneratorNextButtonClicked',
9194
MockDataGeneratorPreviousButtonClicked = 'compass-collection/MockDataGeneratorPreviousButtonClicked',
95+
AiDisclaimerModalShown = 'compass-collection/AiDisclaimerModalShown',
9296
}
9397

9498
interface CollectionMetadataFetchedAction {
@@ -104,6 +108,10 @@ interface SchemaAnalysisStartedAction {
104108
type: CollectionActions.SchemaAnalysisStarted;
105109
}
106110

111+
interface AiDisclaimerModalShownAction {
112+
type: CollectionActions.AiDisclaimerModalShown;
113+
}
114+
107115
interface SchemaAnalysisFinishedAction {
108116
type: CollectionActions.SchemaAnalysisFinished;
109117
schema: Schema;
@@ -146,7 +154,7 @@ const reducer: Reducer<CollectionState, Action> = (
146154
},
147155
mockDataGenerator: {
148156
isModalOpen: false,
149-
currentStep: MockDataGeneratorStep.AI_DISCLAIMER,
157+
currentStep: MockDataGeneratorStep.SCHEMA_CONFIRMATION,
150158
},
151159
},
152160
action
@@ -234,7 +242,7 @@ const reducer: Reducer<CollectionState, Action> = (
234242
mockDataGenerator: {
235243
...state.mockDataGenerator,
236244
isModalOpen: true,
237-
currentStep: MockDataGeneratorStep.AI_DISCLAIMER,
245+
currentStep: MockDataGeneratorStep.SCHEMA_CONFIRMATION,
238246
},
239247
};
240248
}
@@ -359,6 +367,10 @@ export const mockDataGeneratorPreviousButtonClicked =
359367
return { type: CollectionActions.MockDataGeneratorPreviousButtonClicked };
360368
};
361369

370+
export const aIDisclaimerModalOpened = (): AiDisclaimerModalShownAction => {
371+
return { type: CollectionActions.AiDisclaimerModalShown };
372+
};
373+
362374
export const selectTab = (
363375
tabName: CollectionSubtab
364376
): CollectionThunkAction<void> => {
@@ -370,6 +382,32 @@ export const selectTab = (
370382
};
371383
};
372384

385+
export const openMockDataGeneratorModal = (): CollectionThunkAction<
386+
Promise<void>
387+
> => {
388+
return async (
389+
dispatch,
390+
_getState,
391+
{ atlasAiService, preferences, logger }
392+
) => {
393+
try {
394+
if (preferences.getPreferences().optInGenAIFeatures) {
395+
// If the user has already opted in, we can directly open the modal
396+
dispatch(mockDataGeneratorModalOpened());
397+
} else if (process.env.COMPASS_E2E_SKIP_ATLAS_SIGNIN !== 'true') {
398+
await atlasAiService.ensureAiFeatureAccess();
399+
}
400+
} catch (error) {
401+
logger.log.error(
402+
mongoLogId(1_001_000_364),
403+
'Collections',
404+
'Failed to ensure AI feature access',
405+
error
406+
);
407+
}
408+
};
409+
};
410+
373411
export const analyzeCollectionSchema = (): CollectionThunkAction<
374412
Promise<void>
375413
> => {

packages/compass-collection/src/stores/collection-tab.spec.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ describe('Collection Tab Content store', function () {
6363
.stub(collectionTabModule, 'analyzeCollectionSchema')
6464
.returns(async () => {});
6565
const dataService = {} as any;
66+
const atlasAiService = {} as any;
6667
let store: ReturnType<typeof activatePlugin>['store'];
6768
let deactivate: ReturnType<typeof activatePlugin>['deactivate'];
6869

@@ -106,6 +107,7 @@ describe('Collection Tab Content store', function () {
106107
connectionInfoRef: connectionInfoRef as any,
107108
logger,
108109
preferences,
110+
atlasAiService,
109111
},
110112
{ on() {}, cleanup() {} } as any
111113
));

packages/compass-collection/src/stores/collection-tab.ts

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import reducer, {
77
selectTab,
88
collectionMetadataFetched,
99
analyzeCollectionSchema,
10+
openMockDataGeneratorModal,
1011
} from '../modules/collection-tab';
1112
import { MockDataGeneratorStep } from '../components/mock-data-generator-modal/types';
1213

@@ -20,8 +21,12 @@ import {
2021
isAIFeatureEnabled,
2122
type PreferencesAccess,
2223
} from 'compass-preferences-model/provider';
23-
import { ExperimentTestName } from '@mongodb-js/compass-telemetry/provider';
24+
import {
25+
ExperimentTestGroup,
26+
ExperimentTestName,
27+
} from '@mongodb-js/compass-telemetry/provider';
2428
import { SCHEMA_ANALYSIS_STATE_INITIAL } from '../schema-analysis-types';
29+
import type { AtlasAiService } from '@mongodb-js/compass-generative-ai/provider';
2530

2631
export type CollectionTabOptions = {
2732
/**
@@ -48,6 +53,7 @@ export type CollectionTabServices = {
4853
connectionInfoRef: ReturnType<typeof connectionInfoRefLocator>;
4954
logger: Logger;
5055
preferences: PreferencesAccess;
56+
atlasAiService: AtlasAiService;
5157
};
5258

5359
export function activatePlugin(
@@ -67,6 +73,7 @@ export function activatePlugin(
6773
connectionInfoRef,
6874
logger,
6975
preferences,
76+
atlasAiService,
7077
} = services;
7178

7279
if (!collectionModel) {
@@ -87,7 +94,7 @@ export function activatePlugin(
8794
},
8895
mockDataGenerator: {
8996
isModalOpen: false,
90-
currentStep: MockDataGeneratorStep.AI_DISCLAIMER,
97+
currentStep: MockDataGeneratorStep.SCHEMA_CONFIRMATION,
9198
},
9299
},
93100
applyMiddleware(
@@ -98,6 +105,7 @@ export function activatePlugin(
98105
experimentationServices,
99106
logger,
100107
preferences,
108+
atlasAiService,
101109
})
102110
)
103111
);
@@ -118,6 +126,28 @@ export function activatePlugin(
118126
store.dispatch(selectTab('Schema'));
119127
});
120128

129+
on(localAppRegistry, 'open-mock-data-generator-modal', () => {
130+
void experimentationServices
131+
.getAssignment(ExperimentTestName.mockDataGenerator, {
132+
team: 'Atlas Growth',
133+
})
134+
.then((mockDataGeneratorAssignment) => {
135+
if (
136+
mockDataGeneratorAssignment?.assignmentData?.variant ===
137+
ExperimentTestGroup.mockDataGeneratorVariant
138+
) {
139+
void store.dispatch(openMockDataGeneratorModal());
140+
}
141+
})
142+
.catch((error) => {
143+
logger.debug('Mock Data Generator get experiment assignment', {
144+
experiment: ExperimentTestName.mockDataGenerator,
145+
namespace: namespace,
146+
error: error instanceof Error ? error.message : String(error),
147+
});
148+
});
149+
});
150+
121151
void collectionModel.fetchMetadata({ dataService }).then((metadata) => {
122152
store.dispatch(collectionMetadataFetched(metadata));
123153

0 commit comments

Comments
 (0)