Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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 @@ -61,7 +61,7 @@ const FakerSchemaEditorContent = ({
onSchemaConfirmed,
}: {
fakerSchema: FakerSchema;
onSchemaConfirmed: (isConfirmed: boolean) => void;
onSchemaConfirmed: () => void;
}) => {
const track = useTelemetry();
const [fakerSchemaFormValues, setFakerSchemaFormValues] =
Expand All @@ -86,10 +86,6 @@ const FakerSchemaEditorContent = ({
const activeFakerFunction = fakerSchemaFormValues[activeField]?.fakerMethod;
const activeFakerArgs = fakerSchemaFormValues[activeField]?.fakerArgs;

const resetIsSchemaConfirmed = () => {
onSchemaConfirmed(false);
};

const onJsonTypeSelect = (newJsonType: MongoDBFieldType) => {
const currentMapping = fakerSchemaFormValues[activeField];
const originalLlmMapping = originalLlmMappings.current[activeField];
Expand Down Expand Up @@ -124,7 +120,6 @@ const FakerSchemaEditorContent = ({
...fakerSchemaFormValues,
[activeField]: newMapping,
});
resetIsSchemaConfirmed();
}
};

Expand Down Expand Up @@ -159,7 +154,6 @@ const FakerSchemaEditorContent = ({
...fakerSchemaFormValues,
[activeField]: newMapping,
});
resetIsSchemaConfirmed();
}
};

Expand All @@ -170,6 +164,7 @@ const FakerSchemaEditorContent = ({
activeField={activeField}
fields={fieldPaths}
onFieldSelect={setActiveField}
fakerSchema={fakerSchemaFormValues}
/>
{activeJsonType && activeFakerFunction && (
<FakerMappingSelector
Expand All @@ -185,7 +180,7 @@ const FakerSchemaEditorContent = ({
size={ButtonSize.Small}
className={confirmMappingsButtonStyles}
variant={ButtonVariant.Primary}
onClick={() => onSchemaConfirmed(true)}
onClick={onSchemaConfirmed}
>
Confirm mappings
</Button>
Expand All @@ -197,7 +192,7 @@ const FakerSchemaEditorScreen = ({
onSchemaConfirmed,
fakerSchemaGenerationState,
}: {
onSchemaConfirmed: (isConfirmed: boolean) => void;
onSchemaConfirmed: () => void;
fakerSchemaGenerationState: MockDataGeneratorState;
}) => {
return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,30 @@ describe('MockDataGeneratorModal', () => {
expect(screen.getByTestId('faker-schema-editor-loader')).to.exist;
});

it('the next button is disabled when the faker schema generation is in progress', async () => {
const mockServices = createMockServices();
mockServices.atlasAiService.getMockDataSchema = () =>
new Promise((resolve) =>
setTimeout(
() =>
resolve({
fields: [],
}),
1
)
);

await renderModal({ mockServices });

// advance to the schema editor step
userEvent.click(screen.getByText('Confirm'));
expect(screen.getByTestId('faker-schema-editor-loader')).to.exist;

expect(
screen.getByTestId('next-step-button').getAttribute('aria-disabled')
).to.equal('true');
});

it('shows the faker schema editor when the faker schema generation is completed', async () => {
await renderModal({
mockServices: mockServicesWithMockDataResponse,
Expand Down Expand Up @@ -684,95 +708,25 @@ describe('MockDataGeneratorModal', () => {
expect(screen.queryByText(/100000/)).to.not.exist;
});

it('disables the Next button when the faker schema mapping is not confirmed', async () => {
it('clicking the confirm schema mapping button advances to the document count step', async () => {
await renderModal({
mockServices: mockServicesWithMockDataResponse,
schemaAnalysis: mockSchemaAnalysis,
});

// advance to the schema editor step
userEvent.click(screen.getByText('Confirm'));
await waitFor(() => {
expect(screen.getByTestId('faker-schema-editor')).to.exist;
});

expect(
screen.getByTestId('next-step-button').getAttribute('aria-disabled')
).to.equal('true');
});

it('resets the confirm schema mapping state when the user clicks the back button then goes back to the schema editor step', async () => {
await renderModal({
mockServices: mockServicesWithMockDataResponse,
schemaAnalysis: mockSchemaAnalysis,
});

// advance to the schema editor step
userEvent.click(screen.getByText('Confirm'));
await waitFor(() => {
expect(screen.getByTestId('faker-schema-editor')).to.exist;
});
expect(
screen.getByTestId('next-step-button').getAttribute('aria-disabled')
).to.equal('true');
// click confirm mappings button
userEvent.click(screen.getByText('Confirm mappings'));
expect(
screen.getByTestId('next-step-button').getAttribute('aria-disabled')
).to.equal('false');

// click back button
userEvent.click(screen.getByText('Back'));
await waitFor(() => {
expect(screen.getByTestId('raw-schema-confirmation')).to.exist;
});

// click next button to advance to the schema editor step again
userEvent.click(screen.getByTestId('next-step-button'));
await waitFor(() => {
expect(screen.getByTestId('faker-schema-editor')).to.exist;
});
// the next button should be disabled again
expect(
screen.getByTestId('next-step-button').getAttribute('aria-disabled')
).to.equal('true');
});

it('preserves the confirm schema mapping state when the user clicks the next button then goes back to the schema editor step', async () => {
await renderModal({
mockServices: mockServicesWithMockDataResponse,
schemaAnalysis: mockSchemaAnalysis,
});

// advance to the schema editor step
userEvent.click(screen.getByText('Confirm'));
await waitFor(() => {
expect(screen.getByTestId('faker-schema-editor')).to.exist;
});
expect(
screen.getByTestId('next-step-button').getAttribute('aria-disabled')
).to.equal('true');
// click confirm mappings button
userEvent.click(screen.getByText('Confirm mappings'));
expect(
screen.getByTestId('next-step-button').getAttribute('aria-disabled')
).to.equal('false');

// click next button
userEvent.click(screen.getByTestId('next-step-button'));
await waitFor(() => {
expect(screen.queryByTestId('faker-schema-editor')).to.not.exist;
});

// click back button to go back to the schema editor step
userEvent.click(screen.getByText('Back'));
await waitFor(() => {
expect(screen.getByTestId('faker-schema-editor')).to.exist;
expect(screen.getByText('Specify Number of Documents to Generate')).to
.exist;
});
// the next button should not be disabled
expect(
screen.getByTestId('next-step-button').getAttribute('aria-disabled')
).to.equal('false');
});

it('fires a track event when the user changes the JSON field type', async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,6 @@ const MockDataGeneratorModal = ({
namespace,
fakerSchemaGenerationState,
}: Props) => {
const [isSchemaConfirmed, setIsSchemaConfirmed] =
React.useState<boolean>(false);
const [documentCount, setDocumentCount] = React.useState<number>(
DEFAULT_DOCUMENT_COUNT
);
Expand All @@ -94,7 +92,7 @@ const MockDataGeneratorModal = ({
case MockDataGeneratorStep.SCHEMA_EDITOR:
return (
<FakerSchemaEditorScreen
onSchemaConfirmed={setIsSchemaConfirmed}
onSchemaConfirmed={onNextStep}
fakerSchemaGenerationState={fakerSchemaGenerationState}
/>
);
Expand Down Expand Up @@ -123,6 +121,7 @@ const MockDataGeneratorModal = ({
fakerSchemaGenerationState,
documentCount,
setDocumentCount,
onNextStep,
]);

useEffect(() => {
Expand All @@ -133,7 +132,7 @@ const MockDataGeneratorModal = ({

const isNextButtonDisabled =
(currentStep === MockDataGeneratorStep.SCHEMA_EDITOR &&
!isSchemaConfirmed) ||
fakerSchemaGenerationState.status !== 'completed') ||
(currentStep === MockDataGeneratorStep.DOCUMENT_COUNT &&
documentCount < 1) ||
(currentStep === MockDataGeneratorStep.DOCUMENT_COUNT &&
Expand All @@ -158,14 +157,6 @@ const MockDataGeneratorModal = ({
const shouldShowNamespace =
currentStep !== MockDataGeneratorStep.GENERATE_DATA;

const handlePreviousClick = () => {
if (currentStep === MockDataGeneratorStep.SCHEMA_EDITOR) {
// reset isSchemaConfirmed state when previous step is clicked
setIsSchemaConfirmed(false);
}
onPreviousStep();
};

const onModalClose = useCallback(() => {
track('Mock Data Generator Dismissed', {
screen: currentStep,
Expand Down Expand Up @@ -203,7 +194,7 @@ const MockDataGeneratorModal = ({
</ModalBody>
<ModalFooter className={footerStyles}>
<Button
onClick={handlePreviousClick}
onClick={onPreviousStep}
disabled={currentStep === MockDataGeneratorStep.SCHEMA_CONFIRMATION}
>
Back
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ import {
palette,
useDarkMode,
Body,
Icon,
} from '@mongodb-js/compass-components';
import { UNRECOGNIZED_FAKER_METHOD } from '../../modules/collection-tab';
import type { FakerSchema } from './types';

const fieldsContainerStyles = css({
width: '40%',
Expand All @@ -30,6 +33,9 @@ const buttonStyles = css({
padding: spacing[200],
textAlign: 'left',
fontWeight: 500,
display: 'flex',
alignItems: 'center',
gap: '8px',
});

const activeStylesLight = css({
Expand Down Expand Up @@ -73,12 +79,23 @@ type SidebarProps = {
activeField: string;
onFieldSelect: (field: string) => void;
fields: Array<string>;
fakerSchema?: FakerSchema;
};

const shouldShowUnrecognizedIcon = (
field: string,
fakerSchema?: FakerSchema
): boolean => {
const mapping = fakerSchema?.[field];

return !!mapping && mapping.fakerMethod === UNRECOGNIZED_FAKER_METHOD;
};

const FieldSelector: React.FunctionComponent<SidebarProps> = ({
activeField,
fields,
onFieldSelect,
fakerSchema,
}) => {
const darkMode = useDarkMode();

Expand Down Expand Up @@ -109,6 +126,9 @@ const FieldSelector: React.FunctionComponent<SidebarProps> = ({
onClick={() => onFieldSelect(field)}
>
{field}
{shouldShowUnrecognizedIcon(field, fakerSchema) && (
<Icon glyph="ImportantWithCircle" />
)}
</button>
))}
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -708,7 +708,7 @@ function generateFakerValue(
mapping: FakerFieldMapping
): string | number | boolean | Date | null | undefined {
const method =
mapping.fakerMethod === 'unrecognized'
mapping.fakerMethod === UNRECOGNIZED_FAKER_METHOD
? getDefaultFakerMethod(mapping.mongoType)
: mapping.fakerMethod;

Expand Down
Loading