Skip to content

Commit c58db3c

Browse files
authored
feat: Fix the state management for the two flows (disabled state, displaying covered queries) CLOUDP-325467 (#7036)
* fix disabled state of suggested index button when switching between tabs * maintain covered queries in btwn tabs * working version of the state management * do not render suggested index everytime initial query changes * skipping failing tests * combine coveredqueries data into an obj * fix broken tests * updated the state to hold coveredQueriesArr instead * fix error clearing, remove suggestions from start (need to fix), move query + initialQuery to redux * fixed tests and automatically generate suggestions when applicable * clear error when query is updated * default query = null for create index modal * added return for the createIndexOpened call * remove irrelevant comment * update tests, move logic to reducer for hasQueryChanges
1 parent d5cce0d commit c58db3c

File tree

10 files changed

+241
-128
lines changed

10 files changed

+241
-128
lines changed

packages/compass-indexes/src/components/create-index-form/create-index-form.tsx

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,6 @@ function CreateIndexForm({
6565
onRemoveFieldClick,
6666
onTabClick,
6767
showIndexesGuidanceVariant,
68-
query,
6968
}: CreateIndexFormProps) {
7069
const { id: connectionId } = useConnectionInfo();
7170
const rollingIndexesFeatureEnabled = !!usePreference('enableRollingIndexes');
@@ -93,9 +92,6 @@ function CreateIndexForm({
9392
showIndexesGuidanceVariant && currentTab === 'IndexFlow';
9493
const showIndexesGuidanceQueryFlow =
9594
showIndexesGuidanceVariant && currentTab === 'QueryFlow';
96-
const [inputQuery, setInputQuery] = React.useState(
97-
query ? JSON.stringify(query, null, 2) : ''
98-
);
9995

10096
const { database: dbName, collection: collectionName } = toNS(namespace);
10197

@@ -180,9 +176,6 @@ function CreateIndexForm({
180176
serverVersion={serverVersion}
181177
dbName={dbName}
182178
collectionName={collectionName}
183-
initialQuery={query}
184-
inputQuery={inputQuery}
185-
setInputQuery={setInputQuery}
186179
/>
187180
)}
188181

packages/compass-indexes/src/components/create-index-form/index-flow-section.spec.tsx

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import React from 'react';
22
import { render, screen } from '@mongodb-js/testing-library-compass';
33
import IndexFlowSection from './index-flow-section';
44
import { expect } from 'chai';
5-
import type { Field } from '../../modules/create-index';
5+
import { ActionTypes, type Field } from '../../modules/create-index';
66
import { Provider } from 'react-redux';
77
import { setupStore } from '../../../test/setup-store';
88

@@ -85,7 +85,15 @@ describe('IndexFlowSection', () => {
8585

8686
beforeEach(() => {
8787
renderComponent({ fields });
88+
8889
screen.getByTestId('index-flow-section-covered-queries-button').click();
90+
store.dispatch({
91+
type: ActionTypes.FieldsChanged,
92+
fields,
93+
});
94+
store.dispatch({
95+
type: ActionTypes.CoveredQueriesFetched,
96+
});
8997
});
9098

9199
it('renders the covered queries examples', () => {
@@ -133,7 +141,16 @@ describe('IndexFlowSection', () => {
133141

134142
beforeEach(() => {
135143
renderComponent({ fields });
144+
136145
screen.getByTestId('index-flow-section-covered-queries-button').click();
146+
147+
store.dispatch({
148+
type: ActionTypes.FieldsChanged,
149+
fields,
150+
});
151+
store.dispatch({
152+
type: ActionTypes.CoveredQueriesFetched,
153+
});
137154
});
138155

139156
it('renders the covered queries examples', () => {
@@ -179,7 +196,15 @@ describe('IndexFlowSection', () => {
179196

180197
beforeEach(() => {
181198
renderComponent({ fields });
199+
182200
screen.getByTestId('index-flow-section-covered-queries-button').click();
201+
store.dispatch({
202+
type: ActionTypes.FieldsChanged,
203+
fields,
204+
});
205+
store.dispatch({
206+
type: ActionTypes.CoveredQueriesFetched,
207+
});
183208
});
184209

185210
it('renders the covered queries examples', () => {
@@ -208,7 +233,15 @@ describe('IndexFlowSection', () => {
208233

209234
beforeEach(() => {
210235
renderComponent({ fields });
236+
211237
screen.getByTestId('index-flow-section-covered-queries-button').click();
238+
store.dispatch({
239+
type: ActionTypes.FieldsChanged,
240+
fields,
241+
});
242+
store.dispatch({
243+
type: ActionTypes.CoveredQueriesFetched,
244+
});
212245
});
213246

214247
it('renders the covered queries examples', () => {

packages/compass-indexes/src/components/create-index-form/index-flow-section.tsx

Lines changed: 38 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,18 @@ import {
1313
Tooltip,
1414
useDarkMode,
1515
} from '@mongodb-js/compass-components';
16-
import React, { useState, useCallback, useEffect } from 'react';
16+
import React, { useState, useCallback } from 'react';
1717
import {
18-
errorCleared,
1918
errorEncountered,
19+
fetchCoveredQueries,
2020
type Field,
2121
} from '../../modules/create-index';
2222
import MDBCodeViewer from './mdb-code-viewer';
2323
import { areAllFieldsFilledIn } from '../../utils/create-index-modal-validation';
2424
import { connect } from 'react-redux';
2525
import type { TrackFunction } from '@mongodb-js/compass-telemetry/provider';
2626
import { useTelemetry } from '@mongodb-js/compass-telemetry/provider';
27+
import type { RootState } from '../../modules';
2728

2829
const flexContainerStyles = css({
2930
display: 'flex',
@@ -106,13 +107,18 @@ export type IndexFlowSectionProps = {
106107
dbName: string;
107108
collectionName: string;
108109
onErrorEncountered: (error: string) => void;
109-
onErrorCleared: () => void;
110+
onCoveredQueriesFetched: () => void;
111+
coveredQueriesArr: Array<Record<string, number>> | null;
112+
hasIndexFieldChanges: boolean;
110113
};
111114

112-
const generateCoveredQueries = (
113-
coveredQueriesArr: Array<Record<string, number>>,
115+
export const generateCoveredQueries = (
116+
coveredQueriesArr: Array<Record<string, number>> | null,
114117
track: TrackFunction
115118
) => {
119+
if (!coveredQueriesArr) {
120+
return;
121+
}
116122
const rows = [];
117123
for (let i = 0; i < coveredQueriesArr.length; i++) {
118124
const currentRow = Object.assign({}, ...coveredQueriesArr.slice(0, i + 1));
@@ -135,9 +141,12 @@ const generateCoveredQueries = (
135141
return <>{rows}</>;
136142
};
137143

138-
const generateOptimalQueries = (
139-
coveredQueriesArr: Array<Record<string, number>>
144+
export const generateOptimalQueries = (
145+
coveredQueriesArr: Array<Record<string, number>> | null
140146
) => {
147+
if (!coveredQueriesArr) {
148+
return;
149+
}
141150
const numOfFields = coveredQueriesArr.length;
142151

143152
// Do not show for 1 field or less
@@ -187,18 +196,25 @@ const generateOptimalQueries = (
187196
);
188197
};
189198

199+
export const generateCoveredQueriesArr = (fields: Field[]) => {
200+
return fields.map((field, index) => {
201+
return { [field.name]: index + 1 };
202+
});
203+
};
204+
190205
const IndexFlowSection = ({
191206
createIndexFieldsComponent,
192207
fields,
193208
dbName,
194209
collectionName,
195210
onErrorEncountered,
196-
onErrorCleared,
211+
onCoveredQueriesFetched,
212+
coveredQueriesArr,
213+
hasIndexFieldChanges,
197214
}: IndexFlowSectionProps) => {
198215
const darkMode = useDarkMode();
199216
const [isCodeEquivalentToggleChecked, setIsCodeEquivalentToggleChecked] =
200217
useState(false);
201-
const [hasFieldChanges, setHasFieldChanges] = useState(false);
202218

203219
const hasUnsupportedQueryTypes = fields.some((field) => {
204220
return field.type === '2dsphere' || field.type === 'text';
@@ -208,7 +224,7 @@ const IndexFlowSection = ({
208224
const isCoveredQueriesButtonDisabled =
209225
!areAllFieldsFilledIn(fields) ||
210226
hasUnsupportedQueryTypes ||
211-
!hasFieldChanges;
227+
!hasIndexFieldChanges;
212228

213229
const indexNameTypeMap = fields.reduce<Record<string, string>>(
214230
(accumulator, currentValue) => {
@@ -220,45 +236,21 @@ const IndexFlowSection = ({
220236
{}
221237
);
222238

223-
const [coveredQueriesObj, setCoveredQueriesObj] = useState<{
224-
coveredQueries: JSX.Element;
225-
optimalQueries: string | JSX.Element;
226-
showCoveredQueries: boolean;
227-
}>({
228-
coveredQueries: <></>,
229-
optimalQueries: '',
230-
showCoveredQueries: false,
231-
});
232-
233239
const onCoveredQueriesButtonClick = useCallback(() => {
234-
const coveredQueriesArr = fields.map((field, index) => {
235-
return { [field.name]: index + 1 };
236-
});
237-
238240
track('Covered Queries Button Clicked', {
239241
context: 'Create Index Modal',
240242
});
241243

242244
try {
243-
setCoveredQueriesObj({
244-
coveredQueries: generateCoveredQueries(coveredQueriesArr, track),
245-
optimalQueries: generateOptimalQueries(coveredQueriesArr),
246-
showCoveredQueries: true,
247-
});
245+
onCoveredQueriesFetched();
248246
} catch (e) {
249247
onErrorEncountered(e instanceof Error ? e.message : String(e));
250248
}
249+
}, [onCoveredQueriesFetched, onErrorEncountered, track]);
251250

252-
setHasFieldChanges(false);
253-
}, [fields, onErrorEncountered, track]);
254-
255-
useEffect(() => {
256-
setHasFieldChanges(true);
257-
onErrorCleared();
258-
}, [fields, onErrorCleared]);
259-
260-
const { coveredQueries, optimalQueries, showCoveredQueries } =
261-
coveredQueriesObj;
251+
const coveredQueries = generateCoveredQueries(coveredQueriesArr, track);
252+
const optimalQueries = generateOptimalQueries(coveredQueriesArr);
253+
const showCoveredQueries = coveredQueriesArr !== null;
262254

263255
return (
264256
<div>
@@ -422,13 +414,17 @@ const IndexFlowSection = ({
422414
);
423415
};
424416

425-
const mapState = () => {
426-
return {};
417+
const mapState = ({ createIndex }: RootState) => {
418+
const { coveredQueriesArr, hasIndexFieldChanges } = createIndex;
419+
return {
420+
coveredQueriesArr,
421+
hasIndexFieldChanges,
422+
};
427423
};
428424

429425
const mapDispatch = {
430426
onErrorEncountered: errorEncountered,
431-
onErrorCleared: errorCleared,
427+
onCoveredQueriesFetched: fetchCoveredQueries,
432428
};
433429

434430
export default connect(mapState, mapDispatch)(IndexFlowSection);

packages/compass-indexes/src/components/create-index-form/query-flow-section.spec.tsx

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,6 @@ describe('QueryFlowSection', () => {
1818
serverVersion="5.0.0"
1919
dbName={dbName}
2020
collectionName={collectionName}
21-
initialQuery={null}
22-
inputQuery={''}
23-
setInputQuery={() => {}}
2421
/>
2522
</Provider>
2623
);

0 commit comments

Comments
 (0)