Skip to content

Commit 6a893cb

Browse files
authored
feat(compass-collection): Retrigger schema analysis after adding data to an empty collection to enable Mock Data Generator button – CLOUDP-356729 (#7533)
* WIP * WIP * WIP * Tests * Github comments * Test * Test * comment * Selector refactor * Import-finished * Comment * Empty collection refactor
1 parent 315557e commit 6a893cb

File tree

7 files changed

+645
-75
lines changed

7 files changed

+645
-75
lines changed

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

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,9 @@ describe('CollectionHeaderActions [Component]', function () {
5858
onOpenMockDataModal={sinon.stub()}
5959
hasSchemaAnalysisData={true}
6060
analyzedSchemaDepth={2}
61-
schemaAnalysisStatus="complete"
6261
schemaAnalysisError={null}
62+
isCollectionEmpty={false}
63+
hasUnsupportedStateError={false}
6364
{...props}
6465
/>
6566
</WorkspacesServiceProvider>
@@ -354,7 +355,9 @@ describe('CollectionHeaderActions [Component]', function () {
354355
isReadonly: false,
355356
hasSchemaAnalysisData: true,
356357
analyzedSchemaDepth: MAX_COLLECTION_NESTING_DEPTH + 1,
357-
schemaAnalysisStatus: 'complete',
358+
schemaAnalysisError: null,
359+
isCollectionEmpty: false,
360+
hasUnsupportedStateError: false,
358361
onOpenMockDataModal: sinon.stub(),
359362
},
360363
{},
@@ -374,11 +377,37 @@ describe('CollectionHeaderActions [Component]', function () {
374377
namespace: 'test.collection',
375378
isReadonly: false,
376379
hasSchemaAnalysisData: false,
377-
schemaAnalysisStatus: 'error',
378380
schemaAnalysisError: {
379381
errorType: 'unsupportedState',
380382
errorMessage: 'Unsupported state',
381383
},
384+
isCollectionEmpty: false,
385+
hasUnsupportedStateError: true,
386+
onOpenMockDataModal: sinon.stub(),
387+
},
388+
{},
389+
atlasConnectionInfo
390+
);
391+
392+
const button = screen.getByTestId(
393+
'collection-header-generate-mock-data-button'
394+
);
395+
expect(button).to.exist;
396+
expect(button).to.have.attribute('aria-disabled', 'true');
397+
});
398+
399+
it('should disable button when collection is empty', async function () {
400+
await renderCollectionHeaderActions(
401+
{
402+
namespace: 'test.collection',
403+
isReadonly: false,
404+
hasSchemaAnalysisData: false,
405+
schemaAnalysisError: {
406+
errorType: 'empty',
407+
errorMessage: 'No documents found in the collection to analyze.',
408+
},
409+
isCollectionEmpty: true,
410+
hasUnsupportedStateError: false,
382411
onOpenMockDataModal: sinon.stub(),
383412
},
384413
{},

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

Lines changed: 8 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,7 @@ import {
2424
useTrackOnChange,
2525
type TrackFunction,
2626
} from '@mongodb-js/compass-telemetry/provider';
27-
import {
28-
SCHEMA_ANALYSIS_STATE_ANALYZING,
29-
type SchemaAnalysisStatus,
30-
type SchemaAnalysisError,
31-
} from '../../schema-analysis-types';
27+
import { type SchemaAnalysisError } from '../../schema-analysis-types';
3228
import { MAX_COLLECTION_NESTING_DEPTH } from '../mock-data-generator-modal/utils';
3329
import {
3430
buildChartsUrl,
@@ -61,7 +57,8 @@ type CollectionHeaderActionsProps = {
6157
hasSchemaAnalysisData: boolean;
6258
schemaAnalysisError: SchemaAnalysisError | null;
6359
analyzedSchemaDepth: number;
64-
schemaAnalysisStatus: SchemaAnalysisStatus | null;
60+
isCollectionEmpty: boolean;
61+
hasUnsupportedStateError: boolean;
6562
};
6663

6764
const CollectionHeaderActions: React.FunctionComponent<
@@ -76,8 +73,9 @@ const CollectionHeaderActions: React.FunctionComponent<
7673
onOpenMockDataModal,
7774
hasSchemaAnalysisData,
7875
analyzedSchemaDepth,
79-
schemaAnalysisStatus,
8076
schemaAnalysisError,
77+
isCollectionEmpty,
78+
hasUnsupportedStateError,
8179
}: CollectionHeaderActionsProps) => {
8280
const connectionInfo = useConnectionInfo();
8381
const { id: connectionId, atlasMetadata } = connectionInfo;
@@ -117,21 +115,11 @@ const CollectionHeaderActions: React.FunctionComponent<
117115
const exceedsMaxNestingDepth =
118116
analyzedSchemaDepth > MAX_COLLECTION_NESTING_DEPTH;
119117

120-
const isCollectionEmpty =
121-
!hasSchemaAnalysisData &&
122-
schemaAnalysisStatus !== SCHEMA_ANALYSIS_STATE_ANALYZING;
123-
124-
const hasSchemaAnalysisUnsupportedStateError = Boolean(
125-
schemaAnalysisError && schemaAnalysisError.errorType === 'unsupportedState'
126-
);
127-
128118
const isView = isReadonly && sourceName && !editViewName;
129119

130120
const showViewEdit = isView && !preferencesReadWrite;
131121
const shouldDisableMockDataButton =
132-
!hasSchemaAnalysisData ||
133-
exceedsMaxNestingDepth ||
134-
hasSchemaAnalysisUnsupportedStateError;
122+
!hasSchemaAnalysisData || exceedsMaxNestingDepth;
135123

136124
const onMockDataGeneratorCtaButtonClicked = useCallback(() => {
137125
track('Mock Data Generator Opened', {
@@ -189,7 +177,7 @@ const CollectionHeaderActions: React.FunctionComponent<
189177
enabled={
190178
exceedsMaxNestingDepth ||
191179
isCollectionEmpty ||
192-
hasSchemaAnalysisUnsupportedStateError
180+
hasUnsupportedStateError
193181
}
194182
trigger={
195183
<div>
@@ -206,7 +194,7 @@ const CollectionHeaderActions: React.FunctionComponent<
206194
}
207195
>
208196
<>
209-
{hasSchemaAnalysisUnsupportedStateError ? (
197+
{hasUnsupportedStateError ? (
210198
<span className={tooltipMessageStyles}>
211199
{schemaAnalysisError?.errorMessage}
212200
</span>

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

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,16 @@ import { connect } from 'react-redux';
2323
import { openMockDataGeneratorModal } from '../../modules/collection-tab';
2424
import type { CollectionState } from '../../modules/collection-tab';
2525
import {
26-
SCHEMA_ANALYSIS_STATE_COMPLETE,
2726
SCHEMA_ANALYSIS_STATE_ERROR,
27+
SCHEMA_ANALYSIS_STATE_COMPLETE,
2828
type SchemaAnalysisStatus,
2929
type SchemaAnalysisError,
3030
} from '../../schema-analysis-types';
31+
import {
32+
selectHasSchemaAnalysisData,
33+
selectIsCollectionEmpty,
34+
selectHasUnsupportedStateError,
35+
} from '../../stores/collection-tab';
3136

3237
const collectionHeaderStyles = css({
3338
padding: spacing[400],
@@ -73,6 +78,8 @@ type CollectionHeaderProps = {
7378
analyzedSchemaDepth: number;
7479
schemaAnalysisStatus: SchemaAnalysisStatus | null;
7580
schemaAnalysisError: SchemaAnalysisError | null;
81+
isCollectionEmpty: boolean;
82+
hasUnsupportedStateError: boolean;
7683
};
7784

7885
const getInsightsForPipeline = (pipeline: any[], isAtlas: boolean) => {
@@ -110,8 +117,9 @@ const CollectionHeader: React.FunctionComponent<CollectionHeaderProps> = ({
110117
onOpenMockDataModal,
111118
hasSchemaAnalysisData,
112119
analyzedSchemaDepth,
113-
schemaAnalysisStatus,
114120
schemaAnalysisError,
121+
isCollectionEmpty,
122+
hasUnsupportedStateError,
115123
}) => {
116124
const darkMode = useDarkMode();
117125
const showInsights = usePreference('showInsights');
@@ -192,8 +200,9 @@ const CollectionHeader: React.FunctionComponent<CollectionHeaderProps> = ({
192200
onOpenMockDataModal={onOpenMockDataModal}
193201
hasSchemaAnalysisData={hasSchemaAnalysisData}
194202
analyzedSchemaDepth={analyzedSchemaDepth}
195-
schemaAnalysisStatus={schemaAnalysisStatus}
196203
schemaAnalysisError={schemaAnalysisError}
204+
isCollectionEmpty={isCollectionEmpty}
205+
hasUnsupportedStateError={hasUnsupportedStateError}
197206
/>
198207
</div>
199208
<MockDataGeneratorModal />
@@ -209,15 +218,14 @@ const mapStateToProps = (state: CollectionState) => {
209218
schemaAnalysis && schemaAnalysis.status === SCHEMA_ANALYSIS_STATE_ERROR
210219
? schemaAnalysis.error
211220
: null,
212-
hasSchemaAnalysisData:
213-
schemaAnalysis &&
214-
schemaAnalysis.status === SCHEMA_ANALYSIS_STATE_COMPLETE &&
215-
Object.keys(schemaAnalysis.processedSchema).length > 0,
221+
hasSchemaAnalysisData: selectHasSchemaAnalysisData(state),
216222
analyzedSchemaDepth:
217223
schemaAnalysis && schemaAnalysis.status === SCHEMA_ANALYSIS_STATE_COMPLETE
218224
? schemaAnalysis.schemaMetadata.maxNestingDepth
219225
: 0,
220226
schemaAnalysisStatus: schemaAnalysis?.status || null,
227+
isCollectionEmpty: selectIsCollectionEmpty(state),
228+
hasUnsupportedStateError: selectHasUnsupportedStateError(state),
221229
};
222230
};
223231

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

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,13 @@ const DEFAULT_SAMPLE_SIZE = 100;
5050

5151
const NO_DOCUMENTS_ERROR = 'No documents found in the collection to analyze.';
5252

53+
export class EmptyCollectionError extends Error {
54+
constructor() {
55+
super(NO_DOCUMENTS_ERROR);
56+
this.name = 'EmptyCollectionError';
57+
}
58+
}
59+
5360
function isAction<A extends AnyAction>(
5461
action: AnyAction,
5562
type: A['type']
@@ -68,6 +75,13 @@ function getErrorDetails(error: Error): SchemaAnalysisError {
6875
};
6976
}
7077

78+
if (error instanceof EmptyCollectionError) {
79+
return {
80+
errorType: 'empty',
81+
errorMessage: error.message,
82+
};
83+
}
84+
7185
const errorCode = (error as MongoError).code;
7286
const errorMessage = error.message || 'Unknown error';
7387
let errorType: SchemaAnalysisError['errorType'] = 'general';
@@ -756,7 +770,7 @@ export const analyzeCollectionSchema = (): CollectionThunkAction<
756770
logger.debug(NO_DOCUMENTS_ERROR);
757771
dispatch({
758772
type: CollectionActions.SchemaAnalysisFailed,
759-
error: new Error(NO_DOCUMENTS_ERROR),
773+
error: new EmptyCollectionError(),
760774
});
761775
return;
762776
}

packages/compass-collection/src/schema-analysis-types.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,12 @@ export type SchemaAnalysisStartedState = {
2222

2323
export type SchemaAnalysisError = {
2424
errorMessage: string;
25-
errorType: 'timeout' | 'highComplexity' | 'general' | 'unsupportedState';
25+
errorType:
26+
| 'timeout'
27+
| 'highComplexity'
28+
| 'general'
29+
| 'unsupportedState'
30+
| 'empty';
2631
};
2732

2833
export type SchemaAnalysisErrorState = {

0 commit comments

Comments
 (0)