Skip to content

Commit 0626ec8

Browse files
authored
feat(compass-collection): finish contents of mock data generator confirmation screen CLOUDP-333852 (#7299)
1 parent 6b2fc4d commit 0626ec8

15 files changed

+712
-69
lines changed

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

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ describe('CollectionHeaderActions [Component]', function () {
6161
hasSchemaAnalysisData={true}
6262
analyzedSchemaDepth={2}
6363
schemaAnalysisStatus="complete"
64+
schemaAnalysisError={null}
6465
{...props}
6566
/>
6667
</PreferencesProvider>
@@ -294,5 +295,37 @@ describe('CollectionHeaderActions [Component]', function () {
294295
expect(button).to.exist;
295296
expect(button).to.have.attribute('aria-disabled', 'true');
296297
});
298+
299+
it('should show an error banner when the schema is in an unsupported state', async function () {
300+
mockUseAssignment.returns({
301+
assignment: {
302+
assignmentData: {
303+
variant: 'mockDataGeneratorVariant',
304+
},
305+
},
306+
});
307+
308+
await renderCollectionHeaderActions(
309+
{
310+
namespace: 'test.collection',
311+
isReadonly: false,
312+
hasSchemaAnalysisData: false,
313+
schemaAnalysisStatus: 'error',
314+
schemaAnalysisError: {
315+
errorType: 'unsupportedState',
316+
errorMessage: 'Unsupported state',
317+
},
318+
onOpenMockDataModal: sinon.stub(),
319+
},
320+
{},
321+
atlasConnectionInfo
322+
);
323+
324+
const button = screen.getByTestId(
325+
'collection-header-generate-mock-data-button'
326+
);
327+
expect(button).to.exist;
328+
expect(button).to.have.attribute('aria-disabled', 'true');
329+
});
297330
});
298331
});

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

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import {
2121
import {
2222
SCHEMA_ANALYSIS_STATE_ANALYZING,
2323
type SchemaAnalysisStatus,
24+
type SchemaAnalysisError,
2425
} from '../../schema-analysis-types';
2526

2627
/**
@@ -35,6 +36,14 @@ const collectionHeaderActionsStyles = css({
3536
gap: spacing[200],
3637
});
3738

39+
const tooltipMessageStyles = css({
40+
display: 'block',
41+
marginBottom: spacing[100],
42+
'&:last-child': {
43+
marginBottom: 0,
44+
},
45+
});
46+
3847
function buildChartsUrl(
3948
groupId: string,
4049
clusterName: string,
@@ -57,6 +66,7 @@ type CollectionHeaderActionsProps = {
5766
sourcePipeline?: unknown[];
5867
onOpenMockDataModal: () => void;
5968
hasSchemaAnalysisData: boolean;
69+
schemaAnalysisError: SchemaAnalysisError | null;
6070
analyzedSchemaDepth: number;
6171
schemaAnalysisStatus: SchemaAnalysisStatus | null;
6272
};
@@ -73,6 +83,7 @@ const CollectionHeaderActions: React.FunctionComponent<
7383
hasSchemaAnalysisData,
7484
analyzedSchemaDepth,
7585
schemaAnalysisStatus,
86+
schemaAnalysisError,
7687
}: CollectionHeaderActionsProps) => {
7788
const connectionInfo = useConnectionInfo();
7889
const { id: connectionId, atlasMetadata } = connectionInfo;
@@ -145,10 +156,30 @@ const CollectionHeaderActions: React.FunctionComponent<
145156
</div>
146157
}
147158
>
148-
{exceedsMaxNestingDepth &&
149-
'At this time we are unable to generate mock data for collections that have deeply nested documents'}
150-
{isCollectionEmpty &&
151-
'Please add data to your collection to generate similar mock documents'}
159+
{/* TODO(CLOUDP-333853): update disabled open-modal button
160+
tooltip to communicate if schema analysis is incomplete */}
161+
<>
162+
{exceedsMaxNestingDepth && (
163+
<span className={tooltipMessageStyles}>
164+
At this time we are unable to generate mock data for collections
165+
that have deeply nested documents.
166+
</span>
167+
)}
168+
{isCollectionEmpty && (
169+
<span className={tooltipMessageStyles}>
170+
Please add data to your collection to generate similar mock
171+
documents.
172+
</span>
173+
)}
174+
{schemaAnalysisError &&
175+
schemaAnalysisError.errorType === 'unsupportedState' && (
176+
<span className={tooltipMessageStyles}>
177+
This collection has a field with a name that contains a
178+
&quot.&quot, which mock data generation does not support at
179+
this time.
180+
</span>
181+
)}
182+
</>
152183
</Tooltip>
153184
)}
154185
{atlasMetadata && (

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@ import { openMockDataGeneratorModal } from '../../modules/collection-tab';
2424
import type { CollectionState } from '../../modules/collection-tab';
2525
import {
2626
SCHEMA_ANALYSIS_STATE_COMPLETE,
27+
SCHEMA_ANALYSIS_STATE_ERROR,
2728
type SchemaAnalysisStatus,
29+
type SchemaAnalysisError,
2830
} from '../../schema-analysis-types';
2931

3032
const collectionHeaderStyles = css({
@@ -70,6 +72,7 @@ type CollectionHeaderProps = {
7072
hasSchemaAnalysisData: boolean;
7173
analyzedSchemaDepth: number;
7274
schemaAnalysisStatus: SchemaAnalysisStatus | null;
75+
schemaAnalysisError: SchemaAnalysisError | null;
7376
};
7477

7578
const getInsightsForPipeline = (pipeline: any[], isAtlas: boolean) => {
@@ -108,6 +111,7 @@ const CollectionHeader: React.FunctionComponent<CollectionHeaderProps> = ({
108111
hasSchemaAnalysisData,
109112
analyzedSchemaDepth,
110113
schemaAnalysisStatus,
114+
schemaAnalysisError,
111115
}) => {
112116
const darkMode = useDarkMode();
113117
const showInsights = usePreference('showInsights');
@@ -188,6 +192,7 @@ const CollectionHeader: React.FunctionComponent<CollectionHeaderProps> = ({
188192
hasSchemaAnalysisData={hasSchemaAnalysisData}
189193
analyzedSchemaDepth={analyzedSchemaDepth}
190194
schemaAnalysisStatus={schemaAnalysisStatus}
195+
schemaAnalysisError={schemaAnalysisError}
191196
/>
192197
</div>
193198
<MockDataGeneratorModal />
@@ -199,6 +204,10 @@ const mapStateToProps = (state: CollectionState) => {
199204
const { schemaAnalysis } = state;
200205

201206
return {
207+
schemaAnalysisError:
208+
schemaAnalysis && schemaAnalysis.status === SCHEMA_ANALYSIS_STATE_ERROR
209+
? schemaAnalysis.error
210+
: null,
202211
hasSchemaAnalysisData:
203212
schemaAnalysis &&
204213
schemaAnalysis.status === SCHEMA_ANALYSIS_STATE_COMPLETE &&
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import React from 'react';
22

33
// TODO: More to come from CLOUDP-333853, CLOUDP-333854
4-
const FakerSchemaEditor = () => {
4+
const FakerSchemaEditorScreen = () => {
55
return (
66
<div data-testid="faker-schema-editor">
77
Schema Editor Content Placeholder
88
</div>
99
);
1010
};
1111

12-
export default FakerSchemaEditor;
12+
export default FakerSchemaEditorScreen;

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

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,12 @@ describe('MockDataGeneratorModal', () => {
2020
async function renderModal({
2121
isOpen = true,
2222
currentStep = MockDataGeneratorStep.SCHEMA_CONFIRMATION,
23+
enableGenAISampleDocumentPassing = false,
2324
mockServices = createMockServices(),
2425
connectionInfo,
2526
}: {
2627
isOpen?: boolean;
28+
enableGenAISampleDocumentPassing?: boolean;
2729
currentStep?: MockDataGeneratorStep;
2830
mockServices?: any;
2931
connectionInfo?: ConnectionInfo;
@@ -63,7 +65,12 @@ describe('MockDataGeneratorModal', () => {
6365
<Provider store={store}>
6466
<MockDataGeneratorModal />
6567
</Provider>,
66-
connectionInfo
68+
connectionInfo,
69+
{
70+
preferences: {
71+
enableGenAISampleDocumentPassing,
72+
},
73+
}
6774
);
6875
}
6976

@@ -204,6 +211,37 @@ describe('MockDataGeneratorModal', () => {
204211
).to.equal('true');
205212
});
206213

214+
it('displays the namespace', async () => {
215+
await renderModal();
216+
expect(screen.getByText('test.collection')).to.exist;
217+
});
218+
219+
it('uses the appropriate copy when Generative AI sample document passing is enabled', async () => {
220+
await renderModal({ enableGenAISampleDocumentPassing: true });
221+
expect(screen.getByText('Sample Documents Collected')).to.exist;
222+
expect(
223+
screen.getByText(
224+
'A sample of documents from your collection will be sent to an LLM for processing.'
225+
)
226+
).to.exist;
227+
// fragment from { "name": "John" }
228+
expect(screen.getByText('"John"')).to.exist;
229+
expect(screen.queryByText('"String"')).to.not.exist;
230+
});
231+
232+
it('uses the appropriate copy when Generative AI sample document passing is disabled', async () => {
233+
await renderModal();
234+
expect(screen.getByText('Document Schema Identified')).to.exist;
235+
expect(
236+
screen.queryByText(
237+
'We have identified the following schema from your documents. This schema will be sent to an LLM for processing.'
238+
)
239+
).to.exist;
240+
// fragment from { "name": "String" }
241+
expect(screen.getByText('"String"')).to.exist;
242+
expect(screen.queryByText('"John"')).to.not.exist;
243+
});
244+
207245
it('renders the faker schema editor when the confirm button is clicked', async () => {
208246
await renderModal();
209247

@@ -230,10 +268,9 @@ describe('MockDataGeneratorModal', () => {
230268
expect(screen.queryByTestId('faker-schema-editor')).to.not.exist;
231269
});
232270

233-
// todo: assert a user-friendly error is displayed (CLOUDP-333852)
271+
expect(screen.getByText('LLM Request failed. Please confirm again.')).to
272+
.exist;
234273
});
235-
236-
// todo: assert that closing then re-opening the modal after an LLM err removes the err message
237274
});
238275

239276
describe('on the generate data step', () => {

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

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { connect } from 'react-redux';
33

44
import {
55
css,
6+
Body,
67
Button,
78
ButtonVariant,
89
ModalBody,
@@ -21,8 +22,8 @@ import {
2122
generateFakerMappings,
2223
mockDataGeneratorPreviousButtonClicked,
2324
} from '../../modules/collection-tab';
24-
import { default as SchemaConfirmationScreen } from './raw-schema-confirmation';
25-
import FakerSchemaEditor from './faker-schema-editor';
25+
import RawSchemaConfirmationScreen from './raw-schema-confirmation-screen';
26+
import FakerSchemaEditorScreen from './faker-schema-editor-screen';
2627
import ScriptScreen from './script-screen';
2728

2829
const footerStyles = css`
@@ -36,13 +37,19 @@ const rightButtonsStyles = css`
3637
flex-direction: row;
3738
`;
3839

40+
const namespaceStyles = css({
41+
marginTop: spacing[200],
42+
marginBottom: spacing[400],
43+
});
44+
3945
interface Props {
4046
isOpen: boolean;
4147
onClose: () => void;
4248
currentStep: MockDataGeneratorStep;
4349
onNextStep: () => void;
4450
onConfirmSchema: () => Promise<void>;
4551
onPreviousStep: () => void;
52+
namespace: string;
4653
}
4754

4855
const MockDataGeneratorModal = ({
@@ -52,13 +59,14 @@ const MockDataGeneratorModal = ({
5259
onNextStep,
5360
onConfirmSchema,
5461
onPreviousStep,
62+
namespace,
5563
}: Props) => {
5664
const modalBodyContent = useMemo(() => {
5765
switch (currentStep) {
5866
case MockDataGeneratorStep.SCHEMA_CONFIRMATION:
59-
return <SchemaConfirmationScreen />;
67+
return <RawSchemaConfirmationScreen />;
6068
case MockDataGeneratorStep.SCHEMA_EDITOR:
61-
return <FakerSchemaEditor />;
69+
return <FakerSchemaEditorScreen />;
6270
case MockDataGeneratorStep.DOCUMENT_COUNT:
6371
return <></>; // TODO: CLOUDP-333856
6472
case MockDataGeneratorStep.PREVIEW_DATA:
@@ -78,6 +86,9 @@ const MockDataGeneratorModal = ({
7886
}
7987
};
8088

89+
const shouldShowNamespace =
90+
currentStep !== MockDataGeneratorStep.GENERATE_DATA;
91+
8192
return (
8293
<Modal
8394
size="large"
@@ -91,6 +102,9 @@ const MockDataGeneratorModal = ({
91102
>
92103
<ModalHeader title="Generate Mock Data" />
93104
<ModalBody>
105+
{shouldShowNamespace && (
106+
<Body className={namespaceStyles}>{namespace}</Body>
107+
)}
94108
<div data-testid={`generate-mock-data-step-${currentStep}`}>
95109
{modalBodyContent}
96110
</div>
@@ -120,6 +134,7 @@ const MockDataGeneratorModal = ({
120134
const mapStateToProps = (state: CollectionState) => ({
121135
isOpen: state.mockDataGenerator.isModalOpen,
122136
currentStep: state.mockDataGenerator.currentStep,
137+
namespace: state.namespace,
123138
});
124139

125140
const ConnectedMockDataGeneratorModal = connect(mapStateToProps, {

0 commit comments

Comments
 (0)