From d1ff4f72288e7aaabb81b86b7c82946b33a33e8d Mon Sep 17 00:00:00 2001 From: Jacob Samuel Lu Date: Tue, 29 Jul 2025 13:11:10 -0400 Subject: [PATCH 1/4] WIP --- .../src/experimentation-provider.tsx | 83 +++++++++++++++++++ packages/compass-telemetry/src/index.ts | 2 + 2 files changed, 85 insertions(+) create mode 100644 packages/compass-telemetry/src/experimentation-provider.tsx diff --git a/packages/compass-telemetry/src/experimentation-provider.tsx b/packages/compass-telemetry/src/experimentation-provider.tsx new file mode 100644 index 00000000000..9098874376e --- /dev/null +++ b/packages/compass-telemetry/src/experimentation-provider.tsx @@ -0,0 +1,83 @@ +import React, { createContext, useContext, useRef } from 'react'; + +interface ExperimentAssignmentData { + variant: string | null; + isInSample: boolean; +} + +interface ExperimentData { + assignmentDate: Date; + entityId: string; + entityType: string; + id: string; + tag: string; + testGroupDatabaseId: string; + testGroupId: string; + testId: string; + testName: string; +} + +interface SDKAssignment { + assignmentData: ExperimentAssignmentData; + experimentData: ExperimentData | null; +} + +interface UseAssignmentResponse { + assignment: SDKAssignment | null; + asyncStatus: 'LOADING' | 'SUCCESS' | 'ERROR'; + error?: Error; +} + +interface BasicAPICallingFunctionOptions { + timeoutMs?: number; + team?: string; +} + +type UseAssignmentHookFn = ( + experimentName: string, + trackIsInSample: boolean, + options?: BasicAPICallingFunctionOptions +) => UseAssignmentResponse; + +type AssignExperimentFn = ( + experimentName: string, + options?: BasicAPICallingFunctionOptions +) => Promise<'SUCCESS' | 'ERROR' | null>; + +interface ExperimentationProviderContextValue { + useAssignment: UseAssignmentHookFn; + assignExperiment: AssignExperimentFn; +} + +const ExperimentationContext = + createContext({ + useAssignment() { + return { + assignment: null, + asyncStatus: 'SUCCESS' as const, + }; + }, + assignExperiment() { + return Promise.resolve(null); + }, + }); + +// Provider component that accepts MMS experiment utils as props +export const ExperimentationProvider: React.FC<{ + children: React.ReactNode; + useAssignment: UseAssignmentHookFn; + assignExperiment: AssignExperimentFn; +}> = ({ children, useAssignment, assignExperiment }) => { + const contextValue = useRef({ useAssignment, assignExperiment }); + + return ( + + {children} + + ); +}; + +// Hook for components to access experiment assignment +export const useAssignment = (...args: Parameters) => { + return useContext(ExperimentationContext).useAssignment(...args); +}; diff --git a/packages/compass-telemetry/src/index.ts b/packages/compass-telemetry/src/index.ts index a2e155c8073..271a051f53d 100644 --- a/packages/compass-telemetry/src/index.ts +++ b/packages/compass-telemetry/src/index.ts @@ -5,3 +5,5 @@ export type { IdentifyTraits, ExtraConnectionData, } from './types'; + +export { ExperimentationProvider } from './experimentation-provider'; From 8a3704e88440c591f96ee10b3cee6b2023b373a4 Mon Sep 17 00:00:00 2001 From: Jacob Samuel Lu Date: Tue, 29 Jul 2025 13:30:03 -0400 Subject: [PATCH 2/4] Copilot review comment --- .../compass-telemetry/src/experimentation-provider.tsx | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/packages/compass-telemetry/src/experimentation-provider.tsx b/packages/compass-telemetry/src/experimentation-provider.tsx index 9098874376e..0a05e0ebf7e 100644 --- a/packages/compass-telemetry/src/experimentation-provider.tsx +++ b/packages/compass-telemetry/src/experimentation-provider.tsx @@ -1,4 +1,4 @@ -import React, { createContext, useContext, useRef } from 'react'; +import React, { createContext, useContext, useMemo } from 'react'; interface ExperimentAssignmentData { variant: string | null; @@ -68,10 +68,13 @@ export const ExperimentationProvider: React.FC<{ useAssignment: UseAssignmentHookFn; assignExperiment: AssignExperimentFn; }> = ({ children, useAssignment, assignExperiment }) => { - const contextValue = useRef({ useAssignment, assignExperiment }); + const contextValue = useMemo( + () => ({ useAssignment, assignExperiment }), + [useAssignment, assignExperiment] + ); return ( - + {children} ); From 34155ed4fc39c1dcfc0725e95973fac0ba3345e0 Mon Sep 17 00:00:00 2001 From: Jacob Samuel Lu Date: Tue, 29 Jul 2025 14:38:26 -0400 Subject: [PATCH 3/4] Rename provider to CompassExperimentationProvider --- packages/compass-telemetry/src/experimentation-provider.tsx | 6 +++--- packages/compass-telemetry/src/index.ts | 2 +- packages/compass-web/src/index.tsx | 2 ++ 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/packages/compass-telemetry/src/experimentation-provider.tsx b/packages/compass-telemetry/src/experimentation-provider.tsx index 0a05e0ebf7e..044cbaacabd 100644 --- a/packages/compass-telemetry/src/experimentation-provider.tsx +++ b/packages/compass-telemetry/src/experimentation-provider.tsx @@ -44,13 +44,13 @@ type AssignExperimentFn = ( options?: BasicAPICallingFunctionOptions ) => Promise<'SUCCESS' | 'ERROR' | null>; -interface ExperimentationProviderContextValue { +interface CompassExperimentationProviderContextValue { useAssignment: UseAssignmentHookFn; assignExperiment: AssignExperimentFn; } const ExperimentationContext = - createContext({ + createContext({ useAssignment() { return { assignment: null, @@ -63,7 +63,7 @@ const ExperimentationContext = }); // Provider component that accepts MMS experiment utils as props -export const ExperimentationProvider: React.FC<{ +export const CompassExperimentationProvider: React.FC<{ children: React.ReactNode; useAssignment: UseAssignmentHookFn; assignExperiment: AssignExperimentFn; diff --git a/packages/compass-telemetry/src/index.ts b/packages/compass-telemetry/src/index.ts index 271a051f53d..e7cadf9d208 100644 --- a/packages/compass-telemetry/src/index.ts +++ b/packages/compass-telemetry/src/index.ts @@ -6,4 +6,4 @@ export type { ExtraConnectionData, } from './types'; -export { ExperimentationProvider } from './experimentation-provider'; +export { CompassExperimentationProvider } from './experimentation-provider'; diff --git a/packages/compass-web/src/index.tsx b/packages/compass-web/src/index.tsx index 2c6525f50c2..e9078380492 100644 --- a/packages/compass-web/src/index.tsx +++ b/packages/compass-web/src/index.tsx @@ -4,3 +4,5 @@ export type { OpenWorkspaceOptions, WorkspaceTab, } from '@mongodb-js/compass-workspaces'; + +export { CompassExperimentationProvider } from '@mongodb-js/compass-telemetry'; From 9cfb27eb9767062f662c468aaa2eed0cb3d9d362 Mon Sep 17 00:00:00 2001 From: Nataly Carbonell Date: Wed, 30 Jul 2025 13:01:44 -0400 Subject: [PATCH 4/4] WIP --- .../mock-data-generator-modal/constants.ts | 1 + .../mock-generator-modal.tsx | 104 ++++++++++++++++++ .../mock-data-generator-modal/types.ts | 8 ++ 3 files changed, 113 insertions(+) create mode 100644 packages/compass-collection/src/components/mock-data-generator-modal/constants.ts create mode 100644 packages/compass-collection/src/components/mock-data-generator-modal/mock-generator-modal.tsx create mode 100644 packages/compass-collection/src/components/mock-data-generator-modal/types.ts diff --git a/packages/compass-collection/src/components/mock-data-generator-modal/constants.ts b/packages/compass-collection/src/components/mock-data-generator-modal/constants.ts new file mode 100644 index 00000000000..0068109918f --- /dev/null +++ b/packages/compass-collection/src/components/mock-data-generator-modal/constants.ts @@ -0,0 +1 @@ +export const DEFAULT_OUTPUT_DOCS_COUNT = 1000; diff --git a/packages/compass-collection/src/components/mock-data-generator-modal/mock-generator-modal.tsx b/packages/compass-collection/src/components/mock-data-generator-modal/mock-generator-modal.tsx new file mode 100644 index 00000000000..3d42da426f9 --- /dev/null +++ b/packages/compass-collection/src/components/mock-data-generator-modal/mock-generator-modal.tsx @@ -0,0 +1,104 @@ +import React, { useState } from 'react'; + +import { css } from '@mongodb-js/compass-components'; + +import { + Button, + Modal, + ModalHeader, + ModalBody, + ModalFooter, + ButtonVariant, +} from '@mongodb-js/compass-components'; +import { MockDataGeneratorSteps } from './types'; +import { DEFAULT_OUTPUT_DOCS_COUNT } from './constants'; + +const footerStyles = css` + flex-direction: row; + justify-content: space-between; +`; + +const rightButtonsStyles = css` + display: flex; + gap: 8px; + flex-direction: row; +`; + +interface Props { + isOpen: boolean; + setIsOpen: (isOpen: boolean) => void; +} + +const MockDataGeneratorModal = ({ isOpen, setIsOpen }: Props) => { + const [currentStep, setCurrentStep] = useState( + MockDataGeneratorSteps.AI_DISCLAIMER + ); + const [rawSchema, setRawSchema] = useState(null); + const [fakerSchema, setFakerSchema] = useState(null); + const [outputDocsCount, setOutputDocsCount] = useState( + DEFAULT_OUTPUT_DOCS_COUNT + ); + const [validationRules, setValidationRules] = useState(null); + const [sampleDoc, setSampleDoc] = useState(null); + + const resetState = () => { + setCurrentStep(MockDataGeneratorSteps.AI_DISCLAIMER); + setRawSchema(null); + setFakerSchema(null); + setOutputDocsCount(DEFAULT_OUTPUT_DOCS_COUNT); + setValidationRules(null); + setSampleDoc(null); + }; + + const onNext = () => { + if (currentStep < MockDataGeneratorSteps.GENERATE_DATA) { + setCurrentStep(currentStep + 1); + } else { + // Final step, close the modal + setIsOpen(false); + resetState(); + } + }; + + const onBack = () => { + if (currentStep > MockDataGeneratorSteps.AI_DISCLAIMER) { + setCurrentStep(currentStep - 1); + } + }; + + const onCancel = () => { + setIsOpen(false); + }; + + return ( + setIsOpen(false)} + data-testid="generate-mock-data-modal" + > + + + {currentStep === MockDataGeneratorSteps.AI_DISCLAIMER &&
} + {currentStep === MockDataGeneratorSteps.SCHEMA_CONFIRMATION && ( +
+ )} + {currentStep === MockDataGeneratorSteps.SCHEMA_EDITOR &&
} + {currentStep === MockDataGeneratorSteps.DOCUMENT_COUNT &&
} + {currentStep === MockDataGeneratorSteps.PREVIEW_DATA &&
} + {currentStep === MockDataGeneratorSteps.GENERATE_DATA &&
} +
+ + + +
+ + +
+
+
+ ); +}; + +export default MockDataGeneratorModal; diff --git a/packages/compass-collection/src/components/mock-data-generator-modal/types.ts b/packages/compass-collection/src/components/mock-data-generator-modal/types.ts new file mode 100644 index 00000000000..c1ca93a830c --- /dev/null +++ b/packages/compass-collection/src/components/mock-data-generator-modal/types.ts @@ -0,0 +1,8 @@ +export enum MockDataGeneratorSteps { + AI_DISCLAIMER = 1, + SCHEMA_CONFIRMATION = 2, + SCHEMA_EDITOR = 3, + DOCUMENT_COUNT = 4, + PREVIEW_DATA = 5, + GENERATE_DATA = 6, +}