Skip to content

feat(compass-collection): Add Disclaimer Screen - Mock Data Generator CLOUDP-333851 #7212

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

ncarbon
Copy link
Collaborator

@ncarbon ncarbon commented Aug 19, 2025

Description

  • Updates AIOptinModal to match the new design changes (Figma).
  • Updates openMockDataGeneratorModal to show AIOptinModal if the user hasn't opted into AI features.
  • Uses AppRegistry to emit "open-mock-data-generator-modal" after the user opts into AI features via the Optin modal.
    • Importing a method from compass-collection introduced a cyclical dependency.
Screenshot 2025-08-19 at 9 00 07 AM

Checklist

  • New tests and/or benchmarks are included
  • Documentation is changed or added
  • If this change updates the UI, screenshots/videos are added and a design review is requested
  • I have signed the MongoDB Contributor License Agreement (https://www.mongodb.com/legal/contributor-agreement)

Motivation and Context

To show an AI disclaimer screen before showing the mock data generator feature UI.

  • Bugfix
  • New feature
  • Dependency update
  • Misc

Open Questions

Dependents

Types of changes

  • Backport Needed
  • Patch (non-breaking change which fixes an issue)
  • Minor (non-breaking change which adds functionality)
  • Major (fix or feature that would cause existing functionality to change)

@ncarbon ncarbon added the no release notes Fix or feature not for release notes label Aug 19, 2025
@@ -268,6 +273,7 @@ export const optIn = (): GenAIAtlasOptInThunkAction<Promise<void>> => {
await atlasAiService.optIntoGenAIFeatures();
dispatch(atlasAiServiceOptedIn());
resolve();
localAppRegistry.emit('open-mock-data-generator-modal');
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Would appreciate some alternative suggestions.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Can you explain why do you need this event in a bit more detail?

The ensureAiFeatureAccess method is built specifically so that you can unconditionally call it for any ai feature in the app, it will await on user input and confirmation and will resolve if user opted in or will throw if not, you don't trigger features from this service, you ask this service for opt-in confirmation through it.

So the flow should be something as follows:

  • User clicks a button
  • This action triggers the ensureAiFeatureAccess call that awaits on user opting into the feature
  • If user confirmed, you open your modal
  • If user didn't, you don't need to do anything

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The ensureAiFeatureAccess method is built specifically so that you can unconditionally call it for any ai feature in the app, it will await on user input and confirmation and will resolve if user opted in

That's exactly what we want. It wasn't obvious to me that that's what ensureAiFeatureAccess does. I see a startAttempt and getAttempt pattern, is that how it works?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Okay, I see each attempt for optIn is associated with an attemptId.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Yes, internally it works by keeping track of attempt requests and associated promises and resolving when user action is taken, externally (meaning outside of the package) the interface just allows you to call the method and wait for it to resolve, you don't need to deal with attempts directly, you only need to call it and wait for it to resolve or fail. There are examples of usage in the code in other parts of the app for NLQ feature that use this method that you can take a look at

@ncarbon ncarbon marked this pull request as ready for review August 19, 2025 14:40
@Copilot Copilot AI review requested due to automatic review settings August 19, 2025 14:40
@ncarbon ncarbon requested a review from a team as a code owner August 19, 2025 14:40
@ncarbon ncarbon requested a review from jcobis August 19, 2025 14:40
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR updates the AI opt-in modal design and integrates it with the mock data generator feature. The main purpose is to show an AI disclaimer screen before allowing users to access the mock data generator, replacing the previous AI disclaimer step with a new schema confirmation step as the initial modal state.

Key changes include:

  • Updated AI opt-in modal to use MarketingModal component with new design
  • Added AppRegistry event emission after AI opt-in to trigger mock data generator modal
  • Modified mock data generator to start at schema confirmation step instead of AI disclaimer

Reviewed Changes

Copilot reviewed 17 out of 18 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
packages/compass-telemetry/src/provider.tsx Added getAssignment method to experimentation services interface
packages/compass-telemetry/src/experimentation-provider.tsx Added GetAssignmentFn type and getAssignment prop to context provider
packages/compass-generative-ai/src/store/atlas-optin-reducer.ts Added localAppRegistry to thunk actions and emit event after opt-in success
packages/compass-generative-ai/src/components/ai-optin-modal.tsx Updated modal to use MarketingModal component with new design
packages/compass-generative-ai/src/components/ai-image-banner.tsx Updated SVG banner dimensions and graphics
packages/compass-collection/src/stores/collection-tab.ts Added event listener for mock data generator modal opening
packages/compass-collection/src/modules/collection-tab.ts Changed initial mock data generator step and added modal opening logic

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

}

// Service locator for experimentation services (non-component access)
// Service locator for expexrimentation services (non-component access)
Copy link
Preview

Copilot AI Aug 19, 2025

Choose a reason for hiding this comment

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

The word 'expexrimentation' contains a spelling error. It should be 'experimentation'.

Suggested change
// Service locator for expexrimentation services (non-component access)
// Service locator for experimentation services (non-component access)

Copilot uses AI. Check for mistakes.

onClick: handleModalClose,
}}
onClose={handleModalClose}
// TODO: replace with buttonProps and add disabled state once LG-5416 is released
Copy link
Preview

Copilot AI Aug 19, 2025

Choose a reason for hiding this comment

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

This TODO comment references a specific ticket (LG-5416) but lacks context about what needs to be done when that ticket is completed. Consider adding more details about the expected changes.

Suggested change
// TODO: replace with buttonProps and add disabled state once LG-5416 is released
// TODO: Once LG-5416 is released and MarketingModal supports buttonProps,
// replace buttonText and onButtonClick with buttonProps to allow disabling the button
// when isOptInInProgress is true. This will prevent multiple opt-in attempts while
// the opt-in process is in progress.

Copilot uses AI. Check for mistakes.

Copy link
Contributor

@gagik gagik left a comment

Choose a reason for hiding this comment

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

FYI: The changes here for the opt-in model are the same as the changes that were aiming to be made for #7164

This is more up to date with the designs so I think I'll close that PR and we can use the changes one to resolve the tickets tied to them.

<ConfirmationModal
<MarketingModal
className={css({
zIndex: '99999',
Copy link

@kpamaran kpamaran Aug 19, 2025

Choose a reason for hiding this comment

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

The zIndex implies there's a visual conflict with another modal.

Slightly better: zIndex: String(otherZIndex + 10) to make that relationship clearer
Better: No two modals render at the same time

Copy link

@kpamaran kpamaran left a comment

Choose a reason for hiding this comment

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

Makes sense to me from a line-by-line POV. Will defer to another if the diffs are okay for the application architecture

@@ -9,6 +9,14 @@ type UseAssignmentHook = (
options?: typesReact.UseAssignmentOptions<types.TypeData>
) => typesReact.UseAssignmentResponse<types.TypeData>;

type GetAssignmentFn = (

Choose a reason for hiding this comment

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

nit: in the ReturnType the null is wrapped in a Promise

@@ -268,6 +273,7 @@ export const optIn = (): GenAIAtlasOptInThunkAction<Promise<void>> => {
await atlasAiService.optIntoGenAIFeatures();
dispatch(atlasAiServiceOptedIn());
resolve();
localAppRegistry.emit('open-mock-data-generator-modal');
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can you explain why do you need this event in a bit more detail?

The ensureAiFeatureAccess method is built specifically so that you can unconditionally call it for any ai feature in the app, it will await on user input and confirmation and will resolve if user opted in or will throw if not, you don't trigger features from this service, you ask this service for opt-in confirmation through it.

So the flow should be something as follows:

  • User clicks a button
  • This action triggers the ensureAiFeatureAccess call that awaits on user opting into the feature
  • If user confirmed, you open your modal
  • If user didn't, you don't need to do anything

{
atlasAiService: AtlasAiService;
preferences: PreferencesAccess;
localAppRegistry: AppRegistry;
Copy link
Collaborator

@gribnoysup gribnoysup Aug 19, 2025

Choose a reason for hiding this comment

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

The local appRegistry in the context of this plugin is not the same as in the context of compass-collections plugin. But also as I mentioned in another comment you probably don't need to use it at all

}}
onClose={handleModalClose}
// TODO: replace with buttonProps and add disabled state once LG-5416 is released
buttonText="Use AI Features"
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

You can now upgrade LG Marketing Modal to v7.0.0 so you can replace buttonText with buttonProps and disable property. (TICKET)

@@ -104,25 +81,34 @@ export const AIOptInModal: React.FunctionComponent<OptInModalProps> = ({
}, [track, onOptInModalClose]);

return (
<ConfirmationModal
<MarketingModal
className={css({
Copy link
Collaborator

@gribnoysup gribnoysup Aug 20, 2025

Choose a reason for hiding this comment

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

Don't use css in render method, this creates a new class name every time component updates and is not performant, static styles can be defined with css outside of render, dynamic should be passed through the style prop. But also this probably indicates that something is not right, we shouldn't have two modals on the screen at the same time, so can you clarify why this is happening?

Comment on lines +55 to +56
// TODO: Re-enable this test once the LG-5416 is released
it.skip('should show the opt in button enabled when project AI setting is enabled', async function () {
Copy link
Collaborator

Choose a reason for hiding this comment

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

This seems to important to just skip. If we can't disable the button, we should make sure that clicking it doesn't cause a request to opt-in and test that instead, not just skip the test

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feat no release notes Fix or feature not for release notes
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants