@@ -102,11 +86,9 @@ function CreateIndexActions({
}
const mapState = ({ createIndex }: RootState) => {
- const { fields, currentTab, indexSuggestions } = createIndex;
+ const { fields } = createIndex;
return {
fields,
- currentTab,
- indexSuggestions,
};
};
diff --git a/packages/compass-indexes/src/components/create-index-form/create-index-form.spec.tsx b/packages/compass-indexes/src/components/create-index-form/create-index-form.spec.tsx
index 12e495ec2ef..d47028ce6e4 100644
--- a/packages/compass-indexes/src/components/create-index-form/create-index-form.spec.tsx
+++ b/packages/compass-indexes/src/components/create-index-form/create-index-form.spec.tsx
@@ -1,73 +1,54 @@
import React from 'react';
-import { render, screen, fireEvent } from '@mongodb-js/testing-library-compass';
+import { render, screen, userEvent } from '@mongodb-js/testing-library-compass';
+import { Provider } from 'react-redux';
import { CreateIndexForm } from './create-index-form';
import type { Field } from '../../modules/create-index';
import { expect } from 'chai';
-import type { SinonSpy } from 'sinon';
-
import { setupStore } from '../../../test/setup-store';
-import sinon from 'sinon';
-import { Provider } from 'react-redux';
describe('CreateIndexForm', () => {
- let onTabClickSpy: SinonSpy;
- const store = setupStore();
-
- beforeEach(function () {
- onTabClickSpy = sinon.spy();
- });
+ const defaultProps = {
+ namespace: 'test.collection',
+ fields: [
+ { name: 'field1', type: '1' },
+ { name: 'field2', type: '-1' },
+ ] as Field[],
+ serverVersion: '5.0.0',
+ onSelectFieldNameClick: () => {},
+ onSelectFieldTypeClick: () => {},
+ onAddFieldClick: () => {},
+ onRemoveFieldClick: () => {},
+ query: null,
+ };
- const renderComponent = ({
- showIndexesGuidanceVariant,
- }: {
- showIndexesGuidanceVariant?: boolean;
- }) => {
- render(
+ const renderWithStore = (props = defaultProps) => {
+ const store = setupStore();
+ return render(
- {}}
- onSelectFieldTypeClick={() => {}}
- onAddFieldClick={() => {}}
- onRemoveFieldClick={() => {}}
- onTabClick={onTabClickSpy}
- showIndexesGuidanceVariant={showIndexesGuidanceVariant || false}
- query={null}
- />
+
);
};
it('renders the create index form', () => {
- renderComponent({});
+ renderWithStore();
expect(screen.getByTestId('create-index-form')).to.exist;
});
- describe('when showIndexesGuidanceVariant is false', () => {
- it('renders the RadioBoxGroup', () => {
- renderComponent({});
- expect(screen.queryByTestId('create-index-form-flows')).not.to.exist;
- });
+ it('renders the index fields section', () => {
+ renderWithStore();
+ expect(screen.getByText('Index fields')).to.exist;
});
- describe('when showIndexesGuidanceVariant is true', () => {
- it('renders the RadioBoxGroup', () => {
- renderComponent({ showIndexesGuidanceVariant: true });
- expect(screen.getByTestId('create-index-form-flows')).to.exist;
- });
- it('calls onTabClick when a RadioBox is selected', () => {
- renderComponent({ showIndexesGuidanceVariant: true });
- const radioBox = screen.getByLabelText('Start with a Query');
- fireEvent.click(radioBox);
- expect(onTabClickSpy).to.be.calledWith('QueryFlow');
- });
+ it('renders standard index options when accordion is expanded', () => {
+ renderWithStore();
+ expect(screen.getByTestId('create-index-modal-toggle-options')).to.exist;
+
+ // Click to expand the options accordion
+ const optionsButton = screen.getByText('Options');
+ expect(optionsButton).to.exist;
+ userEvent.click(optionsButton);
+
+ expect(screen.getByTestId('create-index-modal-options')).to.exist;
});
});
diff --git a/packages/compass-indexes/src/components/create-index-form/create-index-form.tsx b/packages/compass-indexes/src/components/create-index-form/create-index-form.tsx
index bdc9d8541e9..97a0a2c91dc 100644
--- a/packages/compass-indexes/src/components/create-index-form/create-index-form.tsx
+++ b/packages/compass-indexes/src/components/create-index-form/create-index-form.tsx
@@ -1,13 +1,6 @@
import React, { useMemo } from 'react';
-import {
- css,
- spacing,
- Accordion,
- Body,
- RadioBoxGroup,
- RadioBox,
-} from '@mongodb-js/compass-components';
-import type { Field, Tab } from '../../modules/create-index';
+import { css, spacing, Accordion, Body } from '@mongodb-js/compass-components';
+import type { Field } from '../../modules/create-index';
import { useAutocompleteFields } from '@mongodb-js/compass-field-store';
import { CreateIndexFields } from '../create-index-fields';
import { hasColumnstoreIndexesSupport } from '../../utils/columnstore-indexes';
@@ -18,9 +11,6 @@ import {
useConnectionSupports,
} from '@mongodb-js/compass-connections/provider';
import { usePreference } from 'compass-preferences-model/provider';
-import IndexFlowSection from './index-flow-section';
-import QueryFlowSection from './query-flow-section';
-import toNS from 'mongodb-ns';
import type { Document } from 'mongodb';
import { useTelemetry } from '@mongodb-js/compass-telemetry/provider';
@@ -36,21 +26,14 @@ const createIndexModalOptionStyles = css({
paddingLeft: spacing[100] + 2,
});
-const createIndexModalFlowsStyles = css({
- marginBottom: spacing[600],
-});
-
export type CreateIndexFormProps = {
namespace: string;
fields: Field[];
serverVersion: string;
- currentTab: Tab;
onSelectFieldNameClick: (idx: number, name: string) => void;
onSelectFieldTypeClick: (idx: number, fType: string) => void;
onAddFieldClick: () => void; // Plus icon.
onRemoveFieldClick: (idx: number) => void; // Minus icon.
- onTabClick: (tab: Tab) => void;
- showIndexesGuidanceVariant?: boolean;
query: Document | null;
};
@@ -58,13 +41,10 @@ function CreateIndexForm({
namespace,
fields,
serverVersion,
- currentTab,
onSelectFieldNameClick,
onSelectFieldTypeClick,
onAddFieldClick,
onRemoveFieldClick,
- onTabClick,
- showIndexesGuidanceVariant,
}: CreateIndexFormProps) {
const { id: connectionId } = useConnectionInfo();
const rollingIndexesFeatureEnabled = !!usePreference('enableRollingIndexes');
@@ -88,100 +68,33 @@ function CreateIndexForm({
});
}, [schemaFields]);
- const showIndexesGuidanceIndexFlow =
- showIndexesGuidanceVariant && currentTab === 'IndexFlow';
- const showIndexesGuidanceQueryFlow =
- showIndexesGuidanceVariant && currentTab === 'QueryFlow';
-
- const { database: dbName, collection: collectionName } = toNS(namespace);
-
return (
<>
- {!showIndexesGuidanceVariant ? (
-
- Index fields
-
- ) : (
- {
- const tabName =
- e.target.value === 'IndexFlow'
- ? 'Start with an Index'
- : 'Start with a Query';
- track(`${tabName} Tab Clicked`, {
- context: 'Create Index Modal',
- });
- onTabClick(e.target.value as Tab);
- }}
- value={currentTab}
- className={createIndexModalFlowsStyles}
- >
-
- Start with an Index
-
-
- Start with a Query
-
-
- )}
+
+ Index fields
+
{fields.length > 0 ? (
- // Variant UI
- showIndexesGuidanceVariant && showIndexesGuidanceIndexFlow ? (
- 1)}
- onSelectFieldNameClick={onSelectFieldNameClick}
- onSelectFieldTypeClick={onSelectFieldTypeClick}
- onAddFieldClick={onAddFieldClick}
- onRemoveFieldClick={onRemoveFieldClick}
- />
- }
- />
- ) : (
- // Control UI
- !showIndexesGuidanceQueryFlow && (
- 1)}
- onSelectFieldNameClick={onSelectFieldNameClick}
- onSelectFieldTypeClick={onSelectFieldTypeClick}
- onAddFieldClick={onAddFieldClick}
- onRemoveFieldClick={onRemoveFieldClick}
- />
- )
- )
+ 1)}
+ onSelectFieldNameClick={onSelectFieldNameClick}
+ onSelectFieldTypeClick={onSelectFieldTypeClick}
+ onAddFieldClick={onAddFieldClick}
+ onRemoveFieldClick={onRemoveFieldClick}
+ />
) : null}
- {showIndexesGuidanceQueryFlow && (
-
- )}
-
{
track('Options Clicked', {
context: 'Create Index Modal',
diff --git a/packages/compass-indexes/src/components/create-index-form/index-flow-section.spec.tsx b/packages/compass-indexes/src/components/create-index-form/index-flow-section.spec.tsx
deleted file mode 100644
index 4ca8ec29d71..00000000000
--- a/packages/compass-indexes/src/components/create-index-form/index-flow-section.spec.tsx
+++ /dev/null
@@ -1,262 +0,0 @@
-import React from 'react';
-import { render, screen } from '@mongodb-js/testing-library-compass';
-import IndexFlowSection from './index-flow-section';
-import { expect } from 'chai';
-import { ActionTypes, type Field } from '../../modules/create-index';
-import { Provider } from 'react-redux';
-import { setupStore } from '../../../test/setup-store';
-
-describe('IndexFlowSection', () => {
- const store = setupStore();
- const renderComponent = ({
- createIndexFieldsComponent,
- fields,
- }: {
- createIndexFieldsComponent?: JSX.Element;
- fields?: Field[];
- }) => {
- render(
-
-
-
- );
- };
-
- describe('when the fields are not filled in', () => {
- it('renders the Input Index header', () => {
- renderComponent({});
- expect(screen.getByText('Input Index')).to.be.visible;
- });
-
- it('does not render the Covered Queries header', () => {
- renderComponent({});
- expect(screen.queryByText('Covered Queries')).to.be.null;
- });
-
- it('renders the Code Equivalent toggle', () => {
- renderComponent({});
- expect(screen.getByLabelText('Toggle Code Equivalent')).to.be.visible;
- });
-
- it('renders the Show covered queries button and it\\s disabled', () => {
- renderComponent({});
- const coveredQueriesButton = screen.getByTestId(
- 'index-flow-section-covered-queries-button'
- );
-
- expect(coveredQueriesButton).to.be.visible;
- });
-
- it('does not render the covered queries examples', () => {
- renderComponent({});
- expect(
- screen.queryByTestId('index-flow-section-covered-queries-examples')
- ).not.to.exist;
- });
-
- it('does not render the optimal query examples', () => {
- renderComponent({});
- expect(
- screen.queryByTestId('index-flow-section-optimal-queries-examples')
- ).not.to.exist;
- });
-
- it('renders the provided createIndexFieldsComponent', () => {
- const mockComponent = (
- Mock Component
- );
- renderComponent({ createIndexFieldsComponent: mockComponent });
- expect(screen.getByTestId('mock-component')).to.be.visible;
- });
- });
-
- describe('when 4 index fields are filled in and user clicks on covered queries button', () => {
- const fields: Field[] = [
- { name: 'field1', type: '1 (asc)' },
- { name: 'field2', type: '-1 (desc)' },
- { name: 'field3', type: '1 (asc)' },
- { name: 'field4', type: '1 (asc)' },
- ];
-
- beforeEach(() => {
- renderComponent({ fields });
-
- screen.getByTestId('index-flow-section-covered-queries-button').click();
- store.dispatch({
- type: ActionTypes.FieldsChanged,
- fields,
- });
- store.dispatch({
- type: ActionTypes.CoveredQueriesFetched,
- });
- });
-
- it('renders the covered queries examples', () => {
- const coveredQueriesExamples = screen.getByTestId(
- 'index-flow-section-covered-queries-examples'
- );
- expect(coveredQueriesExamples).to.exist;
- expect(coveredQueriesExamples).to.contain.text(
- JSON.stringify({
- field1: 1,
- field2: 2,
- field3: 3,
- field4: 4,
- })
- );
- });
-
- it('renders the optimal query examples', () => {
- const optimalQueriesExamples = screen.getByTestId(
- 'index-flow-section-optimal-queries-examples'
- );
- expect(optimalQueriesExamples).to.exist;
- expect(optimalQueriesExamples).to.contain.text(
- `{"field1":1,"field2":2,"field4":{"$gt":3}}.sort({"field3": 1})`
- );
- });
-
- it('renders the Covered Queries Learn More link', () => {
- const link = screen.getByText('Learn about covered queries');
- expect(link).to.be.visible;
- });
-
- it('renders the ESR Learn More link', () => {
- const link = screen.getByText('Learn about ESR');
- expect(link).to.be.visible;
- });
- });
-
- describe('when 3 index fields are filled in and user clicks on covered queries button', () => {
- const fields: Field[] = [
- { name: 'field1', type: '1 (asc)' },
- { name: 'field2', type: '-1 (desc)' },
- { name: 'field3', type: '1 (asc)' },
- ];
-
- beforeEach(() => {
- renderComponent({ fields });
-
- screen.getByTestId('index-flow-section-covered-queries-button').click();
-
- store.dispatch({
- type: ActionTypes.FieldsChanged,
- fields,
- });
- store.dispatch({
- type: ActionTypes.CoveredQueriesFetched,
- });
- });
-
- it('renders the covered queries examples', () => {
- const coveredQueriesExamples = screen.getByTestId(
- 'index-flow-section-covered-queries-examples'
- );
- expect(coveredQueriesExamples).to.exist;
- expect(coveredQueriesExamples).to.contain.text(
- JSON.stringify({
- field1: 1,
- field2: 2,
- field3: 3,
- })
- );
- });
-
- it('renders the optimal query examples', () => {
- const optimalQueriesExamples = screen.getByTestId(
- 'index-flow-section-optimal-queries-examples'
- );
- expect(optimalQueriesExamples).to.exist;
- expect(optimalQueriesExamples).to.contain.text(
- `{"field1":1,"field3":{"$gt":2}}.sort({"field2": 1})`
- );
- });
-
- it('renders the Covered Queries Learn More link', () => {
- const link = screen.getByText('Learn about covered queries');
- expect(link).to.be.visible;
- });
-
- it('renders the ESR Learn More link', () => {
- const link = screen.getByText('Learn about ESR');
- expect(link).to.be.visible;
- });
- });
-
- describe('when 2 index fields are filled in and user clicks on covered queries button', () => {
- const fields: Field[] = [
- { name: 'field1', type: '1 (asc)' },
- { name: 'field2', type: '1 (asc)' },
- ];
-
- beforeEach(() => {
- renderComponent({ fields });
-
- screen.getByTestId('index-flow-section-covered-queries-button').click();
- store.dispatch({
- type: ActionTypes.FieldsChanged,
- fields,
- });
- store.dispatch({
- type: ActionTypes.CoveredQueriesFetched,
- });
- });
-
- it('renders the covered queries examples', () => {
- const coveredQueriesExamples = screen.getByTestId(
- 'index-flow-section-covered-queries-examples'
- );
- expect(coveredQueriesExamples).to.exist;
- });
-
- it('renders the optimal query examples', () => {
- const optimalQueriesExamples = screen.getByTestId(
- 'index-flow-section-optimal-queries-examples'
- );
- expect(optimalQueriesExamples).to.exist;
- expect(optimalQueriesExamples).to.contain.text(
- `{"field1":1,"field2":{"$gt":2}}`
- );
- expect(optimalQueriesExamples).to.contain.text(
- `{"field1":1}.sort({"field2":1})`
- );
- });
- });
-
- describe('when 1 index field is filled in and user clicks on covered queries button', () => {
- const fields: Field[] = [{ name: 'field1', type: '1 (asc)' }];
-
- beforeEach(() => {
- renderComponent({ fields });
-
- screen.getByTestId('index-flow-section-covered-queries-button').click();
- store.dispatch({
- type: ActionTypes.FieldsChanged,
- fields,
- });
- store.dispatch({
- type: ActionTypes.CoveredQueriesFetched,
- });
- });
-
- it('renders the covered queries examples', () => {
- expect(screen.getByTestId('index-flow-section-covered-queries-examples'))
- .to.exist;
- });
-
- it('does not render the optimal query examples', () => {
- expect(
- screen.queryByTestId('index-flow-section-optimal-queries-examples')
- ).not.to.exist;
- });
-
- it('does not render ESR Learn More link', () => {
- expect(screen.queryByText('Learn about ESR')).not.to.exist;
- });
- });
-});
diff --git a/packages/compass-indexes/src/components/create-index-form/index-flow-section.tsx b/packages/compass-indexes/src/components/create-index-form/index-flow-section.tsx
deleted file mode 100644
index c0adbd63a0e..00000000000
--- a/packages/compass-indexes/src/components/create-index-form/index-flow-section.tsx
+++ /dev/null
@@ -1,430 +0,0 @@
-import {
- Body,
- Button,
- css,
- cx,
- Label,
- Link,
- palette,
- spacing,
- Toggle,
- fontFamilies,
- InfoSprinkle,
- Tooltip,
- useDarkMode,
-} from '@mongodb-js/compass-components';
-import React, { useState, useCallback } from 'react';
-import {
- errorEncountered,
- fetchCoveredQueries,
- type Field,
-} from '../../modules/create-index';
-import MDBCodeViewer from './mdb-code-viewer';
-import { areAllFieldsFilledIn } from '../../utils/create-index-modal-validation';
-import { connect } from 'react-redux';
-import type { TrackFunction } from '@mongodb-js/compass-telemetry/provider';
-import { useTelemetry } from '@mongodb-js/compass-telemetry/provider';
-import type { RootState } from '../../modules';
-
-const flexContainerStyles = css({
- display: 'flex',
- alignItems: 'center',
-});
-
-const indexFieldsHeaderContainerStyles = css({
- justifyContent: 'space-between',
- marginBottom: spacing[200],
-});
-
-const indexFieldsCalloutStyles = css({
- border: `1px solid ${palette.gray.light2}`,
- borderRadius: '12px',
- padding: spacing[600],
- marginBottom: spacing[600],
-});
-
-const indexFieldsCalloutDarkStyles = css({
- border: `1px solid ${palette.gray.base}`,
-});
-
-const codeEquivalentToggleLabelStyles = css({
- marginRight: spacing[100],
- fontWeight: 'normal',
-});
-
-const coveredQueriesHeaderContainerStyles = css({
- marginBottom: spacing[200],
-});
-
-const coveredQueriesCalloutStyles = css({
- borderRadius: '12px',
- padding: spacing[600],
- marginBottom: spacing[600],
-});
-
-const lightModeCoveredQueriesCalloutStyles = css({
- border: `1px solid ${palette.gray.light2}`,
- background: palette.gray.light3,
-});
-
-const darkModeCoveredQueriesCalloutStyles = css({
- border: `1px solid ${palette.gray.dark2}`,
- background: palette.black,
-});
-const buttonContainerStyles = css({
- display: 'flex',
- justifyContent: 'right',
-});
-
-const coveredQueriesButtonStyles = css({
- float: 'right',
- marginTop: spacing[400],
-});
-
-const underlineStyles = css({
- textDecoration: 'underline',
-});
-
-const codeStyles = css({
- fontFamily: fontFamilies.code,
-});
-
-const coveredQueriesHeaderStyles = css({
- marginRight: spacing[200],
-});
-
-const coveredQueriesLinkStyles = css({
- marginTop: spacing[200],
-});
-
-const optimalQueriesStyles = css({
- marginTop: spacing[400],
-});
-
-export type IndexFlowSectionProps = {
- fields: Field[];
- createIndexFieldsComponent: JSX.Element | null;
- dbName: string;
- collectionName: string;
- onErrorEncountered: (error: string) => void;
- onCoveredQueriesFetched: () => void;
- coveredQueriesArr: Array> | null;
- hasIndexFieldChanges: boolean;
-};
-
-export const generateCoveredQueries = (
- coveredQueriesArr: Array> | null,
- track: TrackFunction
-) => {
- if (!coveredQueriesArr) {
- return;
- }
- const rows = [];
- for (let i = 0; i < coveredQueriesArr.length; i++) {
- const currentRow = Object.assign({}, ...coveredQueriesArr.slice(0, i + 1));
- rows.push(
- <>
- {JSON.stringify(currentRow)}
- >
- );
- }
-
- if (rows.length === 0) {
- // TODO: remove this in CLOUDP-320224
- track('Error generating covered queries', {
- context: 'Create Index Modal',
- });
- throw new Error(
- 'Error generating covered query examples. Please try again later.'
- );
- }
- return <>{rows}>;
-};
-
-export const generateOptimalQueries = (
- coveredQueriesArr: Array> | null
-) => {
- if (!coveredQueriesArr) {
- return;
- }
- const numOfFields = coveredQueriesArr.length;
-
- // Do not show for 1 field or less
- if (numOfFields < 2) {
- return '';
- }
-
- const lastField = coveredQueriesArr[numOfFields - 1];
- const lastFieldKey = Object.keys(lastField)[0];
-
- // If there are only two fields, we want to show two examples
- // i.e. {a:1, b: {$gt:2}} and {a:1}.sort({b: 1})
- if (numOfFields === 2) {
- const firstField = coveredQueriesArr[0];
- const firstFieldKey = Object.keys(firstField)[0];
-
- return (
- <>
- {`{"${firstFieldKey}":1,"${lastFieldKey}":{"$gt":2}}`}
-
- {`{"${firstFieldKey}":1}.sort({"${lastFieldKey}":1})`}
- >
- );
- }
-
- // If there are more than two fields, we want to show a longer optimal query with gt and sort
- // i.e. {a:1, b:2, d:{gt:3}}.sort({c:1})
-
- const secondToLastField = coveredQueriesArr[numOfFields - 2];
- const secondToLastFieldKey = Object.keys(secondToLastField)[0];
-
- const optimalQueries = coveredQueriesArr
- .slice(0, -2)
- .reduce>((acc, obj) => {
- const key = Object.keys(obj)[0];
- const value = obj[key];
-
- acc[key] = value;
-
- return acc;
- }, {});
-
- // Put last field in range and second to last field in sort
- optimalQueries[lastFieldKey] = { $gt: coveredQueriesArr.length - 1 };
- return (
- JSON.stringify(optimalQueries) + `.sort({"${secondToLastFieldKey}": 1})`
- );
-};
-
-export const generateCoveredQueriesArr = (fields: Field[]) => {
- return fields.map((field, index) => {
- return { [field.name]: index + 1 };
- });
-};
-
-const IndexFlowSection = ({
- createIndexFieldsComponent,
- fields,
- dbName,
- collectionName,
- onErrorEncountered,
- onCoveredQueriesFetched,
- coveredQueriesArr,
- hasIndexFieldChanges,
-}: IndexFlowSectionProps) => {
- const darkMode = useDarkMode();
- const [isCodeEquivalentToggleChecked, setIsCodeEquivalentToggleChecked] =
- useState(false);
-
- const hasUnsupportedQueryTypes = fields.some((field) => {
- return field.type === '2dsphere' || field.type === 'text';
- });
- const track = useTelemetry();
-
- const isCoveredQueriesButtonDisabled =
- !areAllFieldsFilledIn(fields) ||
- hasUnsupportedQueryTypes ||
- !hasIndexFieldChanges;
-
- const indexNameTypeMap = fields.reduce>(
- (accumulator, currentValue) => {
- if (currentValue.name && currentValue.type) {
- accumulator[currentValue.name] = currentValue.type;
- }
- return accumulator;
- },
- {}
- );
-
- const onCoveredQueriesButtonClick = useCallback(() => {
- track('Covered Queries Button Clicked', {
- context: 'Create Index Modal',
- });
-
- try {
- onCoveredQueriesFetched();
- } catch (e) {
- onErrorEncountered(e instanceof Error ? e.message : String(e));
- }
- }, [onCoveredQueriesFetched, onErrorEncountered, track]);
-
- const coveredQueries = generateCoveredQueries(coveredQueriesArr, track);
- const optimalQueries = generateOptimalQueries(coveredQueriesArr);
- const showCoveredQueries = coveredQueriesArr !== null;
-
- return (
-
-
-
- Input Index
-
-
-
- Code Equivalent
-
-
- {
- setIsCodeEquivalentToggleChecked(value);
- track('Code Equivalent Toggled', {
- context: 'Create Index Modal',
- toggled: value === true ? 'On' : 'Off',
- });
- }}
- checked={isCodeEquivalentToggleChecked}
- disabled={!areAllFieldsFilledIn(fields)}
- />
-
-
-
- {isCodeEquivalentToggleChecked ? (
-
{
- track('Input Index Copied', {
- context: 'Create Index Modal',
- });
- }}
- />
- ) : (
- createIndexFieldsComponent
- )}
-
-
-
- Show covered queries
-
- }
- align="top"
- justify="middle"
- enabled={hasUnsupportedQueryTypes}
- >
- Example queries are unavailable for 2dsphere and text
-
-
-
- {showCoveredQueries && (
- <>
-
-
- Covered Queries
-
-
-
- A covered query is a query that can be satisfied entirely using an
- index and does not have to examine any documents. If a query is
- covered, it is highly performant.
-
-
-
-
- {/* Covered Queries */}
-
-
-
- {coveredQueries}
-
-
- {
- track('Covered Queries Learn More Clicked', {
- context: 'Create Index Modal',
- });
- }}
- >
- Learn about covered queries
-
-
-
-
- {!!optimalQueries && (
-
-
- Follow the Equality, Sort, Range (ESR) Rule. This index is
- great for queries that have this pattern:
-
- {/* Optimal queries */}
-
- {optimalQueries}
-
-
- {
- track('ESR Learn More Clicked', {
- context: 'Create Index Modal',
- });
- }}
- >
- Learn about ESR
-
-
-
- )}
-
- >
- )}
-
- );
-};
-
-const mapState = ({ createIndex }: RootState) => {
- const { coveredQueriesArr, hasIndexFieldChanges } = createIndex;
- return {
- coveredQueriesArr,
- hasIndexFieldChanges,
- };
-};
-
-const mapDispatch = {
- onErrorEncountered: errorEncountered,
- onCoveredQueriesFetched: fetchCoveredQueries,
-};
-
-export default connect(mapState, mapDispatch)(IndexFlowSection);
diff --git a/packages/compass-indexes/src/components/create-index-form/mdb-code-viewer.spec.tsx b/packages/compass-indexes/src/components/create-index-form/mdb-code-viewer.spec.tsx
deleted file mode 100644
index 8c8638dbb73..00000000000
--- a/packages/compass-indexes/src/components/create-index-form/mdb-code-viewer.spec.tsx
+++ /dev/null
@@ -1,57 +0,0 @@
-import React from 'react';
-import { render, screen } from '@mongodb-js/testing-library-compass';
-import MDBCodeViewer from './mdb-code-viewer';
-import { expect } from 'chai';
-
-describe('MDBCodeViewer', () => {
- const dbName = 'testDB';
- const defaultCollectionName = 'testCollection';
- const defaultIndexNameTypeMap = {
- field1: '1 (asc)',
- field2: '-1 (desc)',
- field3: '2dsphere',
- field4: 'text',
- };
-
- const renderComponent = ({
- collectionName = defaultCollectionName,
- indexNameTypeMap = defaultIndexNameTypeMap,
- }: {
- collectionName?: string;
- indexNameTypeMap?: { [key: string]: string };
- }) => {
- render(
- {}}
- />
- );
- };
-
- it('shows the db name, collection name, and field names, and field types', () => {
- renderComponent({});
- const codeElement = screen.getByTestId('mdb-code-viewer');
- expect(codeElement).to.have.text(
- 'db.getSiblingDB("testDB").getCollection("testCollection").createIndex({ "field1": 1, "field2": -1, "field3": "2dsphere", "field4": "text"});'
- );
- });
-
- it('shows the escaped version of collection name and field name when there are quotes', () => {
- renderComponent({
- collectionName: 'collection"With"quotes',
- indexNameTypeMap: { 'field"With"quotes': '1' },
- });
- const codeElement = screen.getByTestId('mdb-code-viewer');
- expect(codeElement).to.have.text(
- 'db.getSiblingDB("testDB").getCollection("collection\\"With\\"quotes").createIndex({ "field\\"With\\"quotes": 1});'
- );
- });
-
- it('renders the link to the MongoDB documentation', () => {
- renderComponent({});
- const linkElement = screen.getByText('here');
- expect(linkElement).to.be.visible;
- });
-});
diff --git a/packages/compass-indexes/src/components/create-index-form/mdb-code-viewer.tsx b/packages/compass-indexes/src/components/create-index-form/mdb-code-viewer.tsx
deleted file mode 100644
index 8da5d083899..00000000000
--- a/packages/compass-indexes/src/components/create-index-form/mdb-code-viewer.tsx
+++ /dev/null
@@ -1,104 +0,0 @@
-import { Code, Link, css, spacing } from '@mongodb-js/compass-components';
-import { useTelemetry } from '@mongodb-js/compass-telemetry/provider';
-import React from 'react';
-
-const containerStyles = css({
- display: 'flex',
- flexDirection: 'column',
-});
-
-const programmingLanguageLinkStyles = css({
- marginLeft: 'auto',
- marginTop: spacing[100],
-});
-
-const NUMERIC_INDEX_TYPES = [-1, 1];
-
-const escapeText = (text: string) => {
- return text.replaceAll('"', '\\"');
-};
-
-const generateCode = ({
- dbName,
- collectionName,
- indexNameTypeMap,
-}: {
- dbName: string;
- collectionName: string;
- indexNameTypeMap: Record;
-}) => {
- let codeStr = `db.getSiblingDB("${dbName}").getCollection("${escapeText(
- collectionName
- )}").createIndex({\n`;
-
- Object.entries(indexNameTypeMap).forEach(([name, type], index) => {
- // Replacing everything inside the parenthesis i.e. (asc)
- let parsedType = escapeText(`${type}`.replace(/\(.*?\)/g, '')).trim();
- if (!NUMERIC_INDEX_TYPES.includes(Number(parsedType))) {
- parsedType = `"${parsedType}"`;
- }
- const parsedName = escapeText(name).trim();
-
- codeStr += ` "${parsedName}": ${parsedType}`;
-
- if (index !== Object.keys(indexNameTypeMap).length - 1) {
- codeStr += ',';
- }
-
- codeStr += '\n';
- });
-
- codeStr += `});`;
- return codeStr;
-};
-
-const MDBCodeViewer = ({
- dbName,
- collectionName,
- indexNameTypeMap,
- onCopy,
- dataTestId,
-}: {
- dbName: string;
- collectionName: string;
- indexNameTypeMap: Record;
- onCopy: () => void;
- dataTestId?: string;
-}) => {
- const track = useTelemetry();
- const GeneratedCode = generateCode({
- dbName,
- collectionName,
- indexNameTypeMap,
- });
-
- return (
-
-
- {GeneratedCode}
-
-
- View programming language driver syntax{' '}
- {
- track('View Programming Language Syntax Clicked', {
- context: 'Create Index Modal',
- });
- }}
- >
- here
-
- .
-
-
- );
-};
-
-export default MDBCodeViewer;
diff --git a/packages/compass-indexes/src/components/create-index-form/query-flow-section.spec.tsx b/packages/compass-indexes/src/components/create-index-form/query-flow-section.spec.tsx
deleted file mode 100644
index d151f7b0520..00000000000
--- a/packages/compass-indexes/src/components/create-index-form/query-flow-section.spec.tsx
+++ /dev/null
@@ -1,84 +0,0 @@
-import React from 'react';
-import { render, screen } from '@mongodb-js/testing-library-compass';
-import QueryFlowSection from './query-flow-section';
-import { expect } from 'chai';
-import { Provider } from 'react-redux';
-import { setupStore } from '../../../test/setup-store';
-import { ActionTypes } from '../../modules/create-index';
-
-describe('QueryFlowSection', () => {
- const store = setupStore();
- const dbName = 'fakeDBName';
- const collectionName = 'fakeCollectionName';
- const renderComponent = () => {
- render(
-
-
-
- );
- };
-
- describe('in the initial state', () => {
- beforeEach(() => {
- renderComponent();
- });
- it('renders the input query section with a code editor', () => {
- const codeEditor = screen.getByTestId('query-flow-section-code-editor');
- expect(codeEditor).to.be.visible;
- });
-
- it('renders the "Show suggested index" button', () => {
- const buttonElement = screen.getByText('Show suggested index');
- expect(buttonElement).to.be.visible;
- });
- it('does not render the suggested index section with formatted index code', () => {
- const codeElement = screen.queryByTestId(
- 'query-flow-section-suggested-index'
- );
- expect(codeElement).to.be.null;
- });
- });
-
- describe('when fetching for index suggestions', () => {
- beforeEach(() => {
- renderComponent();
-
- store.dispatch({
- type: ActionTypes.SuggestedIndexesRequested,
- });
- });
- it('renders a loader for the code section', () => {
- const loader = screen.getByTestId('query-flow-section-code-loader');
- expect(loader).to.be.visible;
- });
- });
-
- describe('when index suggestions is fetched', () => {
- beforeEach(() => {
- renderComponent();
-
- store.dispatch({
- type: ActionTypes.SuggestedIndexesFetched,
- sampleDocs: [],
- indexSuggestions: { a: 1, b: 2 },
- error: null,
- indexSuggestionsState: 'success',
- });
- });
-
- it('renders the suggested index section with formatted index code', () => {
- const codeElement = screen.getByTestId(
- 'query-flow-section-suggested-index'
- );
- expect(codeElement).to.be.visible;
- expect(codeElement).to.have.text(
- `db.getSiblingDB("${dbName}").getCollection("${collectionName}").createIndex({ "a": 1, "b": "2"});`
- );
- });
- });
-});
diff --git a/packages/compass-indexes/src/components/create-index-form/query-flow-section.tsx b/packages/compass-indexes/src/components/create-index-form/query-flow-section.tsx
deleted file mode 100644
index f07081d3d77..00000000000
--- a/packages/compass-indexes/src/components/create-index-form/query-flow-section.tsx
+++ /dev/null
@@ -1,298 +0,0 @@
-import {
- Button,
- palette,
- InsightsChip,
- Body,
- cx,
- useFocusRing,
- ParagraphSkeleton,
- useDarkMode,
-} from '@mongodb-js/compass-components';
-import React, { useMemo, useCallback } from 'react';
-import { css, spacing } from '@mongodb-js/compass-components';
-import {
- CodemirrorMultilineEditor,
- createQueryAutocompleter,
-} from '@mongodb-js/compass-editor';
-import MDBCodeViewer from './mdb-code-viewer';
-import type { RootState } from '../../modules';
-import { fetchIndexSuggestions } from '../../modules/create-index';
-import type {
- IndexSuggestionState,
- QueryUpdatedProps,
- SuggestedIndexFetchedProps,
-} from '../../modules/create-index';
-import { queryUpdated } from '../../modules/create-index';
-import { connect } from 'react-redux';
-import { parseFilter } from 'mongodb-query-parser';
-import { useTelemetry } from '@mongodb-js/compass-telemetry/provider';
-
-const inputQueryContainerStyles = css({
- display: 'flex',
- flexDirection: 'column',
-});
-
-const headerStyles = css({
- marginBottom: spacing[200],
-});
-
-const suggestedIndexContainerStyles = css({
- flexDirection: 'column',
- display: 'flex',
- marginBottom: spacing[600],
-});
-
-const editorActionContainerStyles = css({
- position: 'relative',
-});
-
-const suggestedIndexButtonStyles = css({
- position: 'absolute',
- right: spacing[600],
- bottom: spacing[600],
- marginBottom: spacing[400],
-});
-
-const editorContainerRadius = spacing[300];
-
-const codeEditorContainerStyles = css({
- border: `1px solid ${palette.gray.base}`,
- borderRadius: editorContainerRadius,
- marginBottom: spacing[600],
-});
-
-const codeEditorStyles = css({
- borderRadius: editorContainerRadius,
- '& .cm-editor': {
- borderRadius: editorContainerRadius,
- },
- '& .cm-content': {
- padding: spacing[600],
- paddingBottom: spacing[1400],
- },
-});
-
-const lightModeCodeEditorStyles = css({
- '& .cm-editor': {
- background: `${palette.white} !important`,
- },
-});
-
-const indexSuggestionsLoaderStyles = css({
- marginBottom: spacing[600],
- padding: spacing[600],
- borderRadius: editorContainerRadius,
-});
-
-const indexSuggestionsLoaderLightStyles = css({
- background: palette.gray.light3,
- border: `1px solid ${palette.gray.light2}`,
-});
-
-const insightStyles = css({
- display: 'flex',
- alignItems: 'center',
- gap: spacing[100],
- marginBottom: spacing[200],
- height: spacing[500],
-});
-
-const QueryFlowSection = ({
- schemaFields,
- serverVersion,
- dbName,
- collectionName,
- onSuggestedIndexButtonClick,
- indexSuggestions,
- fetchingSuggestionsState,
- initialQuery,
- query,
- hasQueryChanges,
- onQueryUpdated,
-}: {
- schemaFields: { name: string; description?: string }[];
- serverVersion: string;
- dbName: string;
- collectionName: string;
- onSuggestedIndexButtonClick: ({
- query,
- }: SuggestedIndexFetchedProps) => Promise;
- indexSuggestions: Record | null;
- fetchingSuggestionsState: IndexSuggestionState;
- initialQuery: string | null;
- query: string;
- hasQueryChanges: boolean;
- onQueryUpdated: ({ query }: QueryUpdatedProps) => void;
-}) => {
- const track = useTelemetry();
- const darkMode = useDarkMode();
-
- const [isShowSuggestionsButtonDisabled, setIsShowSuggestionsButtonDisabled] =
- React.useState(true);
-
- const completer = useMemo(
- () =>
- createQueryAutocompleter({
- fields: schemaFields,
- serverVersion,
- }),
- [schemaFields, serverVersion]
- );
-
- const focusRingProps = useFocusRing({
- outer: true,
- focusWithin: true,
- hover: true,
- radius: editorContainerRadius,
- });
-
- const generateSuggestedIndexes = useCallback(() => {
- const sanitizedInputQuery = query.trim();
-
- void onSuggestedIndexButtonClick({
- query: sanitizedInputQuery,
- });
- }, [query, onSuggestedIndexButtonClick]);
-
- const handleSuggestedIndexButtonClick = () => {
- generateSuggestedIndexes();
- track('Suggested Index Button Clicked', {
- context: 'Create Index Modal',
- });
- };
-
- const handleQueryInputChange = useCallback(
- (text: string) => {
- onQueryUpdated({ query: text });
- },
- [onQueryUpdated]
- );
-
- const isFetchingIndexSuggestions = fetchingSuggestionsState === 'fetching';
-
- useMemo(() => {
- let _isShowSuggestionsButtonDisabled = !hasQueryChanges;
- try {
- parseFilter(query);
-
- if (!query.startsWith('{') || !query.endsWith('}')) {
- _isShowSuggestionsButtonDisabled = true;
- }
- } catch {
- _isShowSuggestionsButtonDisabled = true;
- } finally {
- setIsShowSuggestionsButtonDisabled(_isShowSuggestionsButtonDisabled);
- }
- }, [hasQueryChanges, query]);
-
- return (
- <>
- {initialQuery && (
-
-
-
- We prefilled the query input below based on your recently run query
-
-
- )}
-
- Input Query
-
-
-
- handleQueryInputChange(text)}
- placeholder="Type a query: { field: 'value' }"
- completer={completer}
- className={cx(
- codeEditorStyles,
- !darkMode && lightModeCodeEditorStyles
- )}
- />
-
-
-
-
- Show suggested index
-
-
-
-
- {(isFetchingIndexSuggestions || indexSuggestions) && (
-
- Suggested Index
-
- )}
-
- {isFetchingIndexSuggestions ? (
-
- ) : (
- indexSuggestions && (
- <>
-
- {
- track('Index Suggestions Copied', {
- context: 'Create Index Modal',
- });
- }}
- />
-
- >
- )
- )}
- >
- );
-};
-
-const mapState = ({ createIndex }: RootState) => {
- const {
- indexSuggestions,
- sampleDocs,
- fetchingSuggestionsState,
- query,
- initialQuery,
- hasQueryChanges,
- } = createIndex;
- return {
- indexSuggestions,
- sampleDocs,
- fetchingSuggestionsState,
- query,
- initialQuery,
- hasQueryChanges,
- };
-};
-
-const mapDispatch = {
- onSuggestedIndexButtonClick: fetchIndexSuggestions,
- onQueryUpdated: queryUpdated,
-};
-
-export default connect(mapState, mapDispatch)(QueryFlowSection);
diff --git a/packages/compass-indexes/src/components/create-index-modal/create-index-modal-header.spec.tsx b/packages/compass-indexes/src/components/create-index-modal/create-index-modal-header.spec.tsx
deleted file mode 100644
index 35867c87797..00000000000
--- a/packages/compass-indexes/src/components/create-index-modal/create-index-modal-header.spec.tsx
+++ /dev/null
@@ -1,27 +0,0 @@
-import React from 'react';
-import { render, screen } from '@mongodb-js/testing-library-compass';
-import CreateIndexModalHeader from './create-index-modal-header';
-import { expect } from 'chai';
-
-describe('CreateIndexModalHeader', () => {
- it('renders the modal title', () => {
- render( );
- const title = screen.getByTestId('create-index-modal-header-title');
-
- expect(title.textContent).to.be.equal('Create Index');
- });
-
- it('renders the subtitle text', () => {
- render( );
- const subtitle = screen.getByTestId('create-index-modal-header-subtitle');
- expect(subtitle).to.exist;
- });
-
- it('renders the link to the Index Strategies Documentation', () => {
- render( );
- const link = screen.getByRole('link', {
- name: /Index Strategies Documentation/i,
- });
- expect(link).to.exist;
- });
-});
diff --git a/packages/compass-indexes/src/components/create-index-modal/create-index-modal-header.tsx b/packages/compass-indexes/src/components/create-index-modal/create-index-modal-header.tsx
deleted file mode 100644
index d613cc4ed8a..00000000000
--- a/packages/compass-indexes/src/components/create-index-modal/create-index-modal-header.tsx
+++ /dev/null
@@ -1,58 +0,0 @@
-import {
- H3,
- Body,
- spacing,
- css,
- palette,
- Link,
- useDarkMode,
-} from '@mongodb-js/compass-components';
-import { useTelemetry } from '@mongodb-js/compass-telemetry/provider';
-import React from 'react';
-
-const headerStyle = css({
- padding: spacing[800],
- paddingBottom: 0,
-});
-
-const subtitleLightStyle = css({
- color: palette.gray.dark1,
-});
-
-const subtitleDarkStyle = css({
- color: palette.gray.light1,
-});
-
-const CreateIndexModalHeader = () => {
- const darkMode = useDarkMode();
- const track = useTelemetry();
- return (
-
-
Create Index
-
-
- The best indexes for your application should consider a number of
- factors, such as your data model, and the queries you use most often. To
- learn more about indexing best practices, read the{' '}
- {
- track('Index Strategies Documentation Clicked', {
- context: 'Create Index Modal',
- });
- }}
- >
- Index Strategies Documentation
-
- .
-
-
- );
-};
-
-export default CreateIndexModalHeader;
diff --git a/packages/compass-indexes/src/components/create-index-modal/create-index-modal.tsx b/packages/compass-indexes/src/components/create-index-modal/create-index-modal.tsx
index 4cbf69711d1..79146b1e1f0 100644
--- a/packages/compass-indexes/src/components/create-index-modal/create-index-modal.tsx
+++ b/packages/compass-indexes/src/components/create-index-modal/create-index-modal.tsx
@@ -6,7 +6,6 @@ import {
ModalHeader,
ModalBody,
} from '@mongodb-js/compass-components';
-import type { Tab } from '../../modules/create-index';
import {
fieldAdded,
fieldRemoved,
@@ -15,7 +14,6 @@ import {
errorCleared,
createIndexFormSubmitted,
createIndexClosed,
- tabUpdated,
} from '../../modules/create-index';
import { CreateIndexForm } from '../create-index-form/create-index-form';
import CreateIndexActions from '../create-index-actions';
@@ -23,30 +21,23 @@ import type { RootState } from '../../modules';
import {
useTrackOnChange,
type TrackFunction,
- useFireExperimentViewed,
- ExperimentTestName,
useTelemetry,
} from '@mongodb-js/compass-telemetry/provider';
import { useConnectionInfoRef } from '@mongodb-js/compass-connections/provider';
-import { usePreference } from 'compass-preferences-model/provider';
-import CreateIndexModalHeader from './create-index-modal-header';
type CreateIndexModalProps = React.ComponentProps & {
isVisible: boolean;
namespace: string;
error: string | null;
- currentTab: Tab;
onErrorBannerCloseClick: () => void;
onCreateIndexClick: () => void;
onCancelCreateIndexClick: () => void;
- onTabClick: (tab: Tab) => void;
};
function CreateIndexModal({
isVisible,
namespace,
error,
- currentTab,
onErrorBannerCloseClick,
onCreateIndexClick,
onCancelCreateIndexClick,
@@ -85,38 +76,17 @@ function CreateIndexModal({
undefined
);
- // @experiment Early Journey Indexes Guidance & Awareness | Jira Epic: CLOUDP-239367
- const enableInIndexesGuidanceExp = usePreference('enableIndexesGuidanceExp');
- const showIndexesGuidanceVariant =
- usePreference('showIndexesGuidanceVariant') && enableInIndexesGuidanceExp;
-
- useFireExperimentViewed({
- testName: ExperimentTestName.earlyJourneyIndexesGuidance,
- shouldFire: enableInIndexesGuidanceExp && isVisible,
- });
-
return (
- {showIndexesGuidanceVariant ? (
-
- ) : (
-
- )}
+
-
+
-
{
- const { fields, error, isVisible, currentTab } = createIndex;
+ const { fields, error, isVisible } = createIndex;
return {
fields,
error,
isVisible,
namespace,
serverVersion,
- currentTab,
};
};
@@ -149,7 +118,6 @@ const mapDispatch = {
onRemoveFieldClick: fieldRemoved,
onSelectFieldNameClick: updateFieldName,
onSelectFieldTypeClick: fieldTypeUpdated,
- onTabClick: tabUpdated,
};
export default connect(mapState, mapDispatch)(CreateIndexModal);
diff --git a/packages/compass-indexes/src/modules/create-index.spec.ts b/packages/compass-indexes/src/modules/create-index.spec.ts
index c536aed9c91..56d7fa28175 100644
--- a/packages/compass-indexes/src/modules/create-index.spec.ts
+++ b/packages/compass-indexes/src/modules/create-index.spec.ts
@@ -219,18 +219,6 @@ describe('create-index module', function () {
expect(store.getState().createIndex.isVisible).to.equal(true);
});
-
- it('sets currentTab=IndexFlow if no query is provided', function () {
- void store.dispatch(createIndexOpened());
-
- expect(store.getState().createIndex.currentTab).to.equal('IndexFlow');
- });
-
- it('sets currentTab=QueryFlow if a query is provided', function () {
- void store.dispatch(createIndexOpened({ query }));
-
- expect(store.getState().createIndex.currentTab).to.equal('QueryFlow');
- });
});
describe('createIndexClosed', function () {
diff --git a/packages/compass-indexes/src/modules/create-index.tsx b/packages/compass-indexes/src/modules/create-index.tsx
index cc59f32acff..bb9421d34a3 100644
--- a/packages/compass-indexes/src/modules/create-index.tsx
+++ b/packages/compass-indexes/src/modules/create-index.tsx
@@ -8,9 +8,6 @@ import { Badge, Link } from '@mongodb-js/compass-components';
import { isAction } from '../utils/is-action';
import type { IndexesThunkAction, RootState } from '.';
import { createRegularIndex } from './regular-indexes';
-import * as mql from 'mongodb-mql-engines';
-import _parseShellBSON, { ParseMode } from '@mongodb-js/shell-bson-parser';
-import toNS from 'mongodb-ns';
export enum ActionTypes {
FieldAdded = 'compass-indexes/create-index/fields/field-added',
@@ -28,22 +25,11 @@ export enum ActionTypes {
CreateIndexClosed = 'compass-indexes/create-index/create-index-hidden',
CreateIndexFormSubmitted = 'compass-indexes/create-index/create-index-form-submitted',
-
- TabUpdated = 'compass-indexes/create-index/tab-updated',
-
- // Query Flow
- SuggestedIndexesRequested = 'compass-indexes/create-index/suggested-indexes-requested',
- SuggestedIndexesFetched = 'compass-indexes/create-index/suggested-indexes-fetched',
- QueryUpdatedAction = 'compass-indexes/create-index/clear-has-query-changes',
-
- // Index Flow
- CoveredQueriesFetched = 'compass-indexes/create-index/covered-queries-fetched',
}
// fields
export type Field = { name: string; type: string };
-export type Tab = 'QueryFlow' | 'IndexFlow';
const INITIAL_FIELDS_STATE = [{ name: '', type: '' }];
@@ -97,11 +83,6 @@ type CreateIndexFormSubmittedAction = {
type: ActionTypes.CreateIndexFormSubmitted;
};
-type TabUpdatedAction = {
- type: ActionTypes.TabUpdated;
- currentTab: Tab;
-};
-
export const fieldAdded = () => ({
type: ActionTypes.FieldAdded,
});
@@ -117,11 +98,6 @@ export const fieldTypeUpdated = (idx: number, fType: string) => ({
fType,
});
-export const tabUpdated = (tab: Tab) => ({
- type: ActionTypes.TabUpdated,
- currentTab: tab,
-});
-
const fieldsChanged = (fields: Field[]) => ({
type: ActionTypes.FieldsChanged,
fields: fields,
@@ -307,33 +283,6 @@ export type State = {
// index options
options: Options;
-
- // current tab that user is on (Query Flow or Index Flow)
- currentTab: Tab;
-
- // state of the index suggestions
- fetchingSuggestionsState: IndexSuggestionState;
-
- // index suggestions in a format such as {fieldName: 1}
- indexSuggestions: Record | null;
-
- // sample documents used for getting index suggestions
- sampleDocs: Array | null;
-
- // base query to be used for query flow index creation
- query: string;
-
- // the initial query that user had prefilled from the insights nudge in the documents tab
- initialQuery: string;
-
- // to determine whether there has been new query changes since user last pressed the button
- hasQueryChanges: boolean;
-
- // covered queries array for the index flow to keep track of what the user last sees after pressing the covered queries button
- coveredQueriesArr: Array> | null;
-
- // to determine whether there has been new index field changes since user last pressed the button
- hasIndexFieldChanges: boolean;
};
export const INITIAL_STATE: State = {
@@ -342,19 +291,6 @@ export const INITIAL_STATE: State = {
error: null,
fields: INITIAL_FIELDS_STATE,
options: INITIAL_OPTIONS_STATE,
- currentTab: 'IndexFlow',
-
- // Query flow
- fetchingSuggestionsState: 'initial',
- indexSuggestions: null,
- sampleDocs: null,
- query: '',
- initialQuery: '',
- hasQueryChanges: false,
-
- // Index flow
- coveredQueriesArr: null,
- hasIndexFieldChanges: false,
};
function getInitialState(): State {
@@ -368,23 +304,12 @@ function getInitialState(): State {
export const createIndexOpened = (
initialQuery?: Document
-): IndexesThunkAction<
- Promise,
- SuggestedIndexFetchedAction | CreateIndexOpenedAction
-> => {
- return async (dispatch) => {
+): IndexesThunkAction => {
+ return (dispatch) => {
dispatch({
type: ActionTypes.CreateIndexOpened,
initialQuery,
});
-
- if (initialQuery) {
- await dispatch(
- fetchIndexSuggestions({
- query: JSON.stringify(initialQuery, null, 2) || '',
- })
- );
- }
};
};
@@ -405,123 +330,6 @@ export type CreateIndexSpec = {
[key: string]: string | number;
};
-type SuggestedIndexesRequestedAction = {
- type: ActionTypes.SuggestedIndexesRequested;
-};
-
-export type SuggestedIndexFetchedAction = {
- type: ActionTypes.SuggestedIndexesFetched;
- sampleDocs: Array;
- indexSuggestions: { [key: string]: number } | null;
- error: string | null;
- indexSuggestionsState: IndexSuggestionState;
-};
-
-export type SuggestedIndexFetchedProps = {
- query: string;
-};
-
-export type CoveredQueriesFetchedAction = {
- type: ActionTypes.CoveredQueriesFetched;
-};
-
-export type QueryUpdatedProps = {
- query: string;
-};
-
-export type QueryUpdatedAction = {
- type: ActionTypes.QueryUpdatedAction;
- query: string;
-};
-
-export const fetchIndexSuggestions = ({
- query,
-}: SuggestedIndexFetchedProps): IndexesThunkAction<
- Promise,
- SuggestedIndexFetchedAction | SuggestedIndexesRequestedAction
-> => {
- return async (dispatch, getState, { dataService, track }) => {
- dispatch({
- type: ActionTypes.SuggestedIndexesRequested,
- });
-
- const namespace = getState().namespace;
- // Get sample documents from state if it's already there, otherwise fetch it
- let sampleDocuments: Array | null =
- getState().createIndex.sampleDocs || null;
- // If it's null, that means it has not been fetched before
- if (sampleDocuments === null) {
- try {
- sampleDocuments =
- (await dataService.sample(namespace, { size: 50 })) || [];
- } catch {
- // Swallow the error because mql package still will work fine with empty sampleDocuments
- sampleDocuments = [];
- }
- }
-
- const throwError = (e?: unknown) => {
- dispatch({
- type: ActionTypes.SuggestedIndexesFetched,
- sampleDocs: sampleDocuments || [],
- indexSuggestions: null,
- error:
- e instanceof Error
- ? 'Error parsing query. Please follow query structure. ' + e.message
- : 'Error parsing query. Please follow query structure.',
- indexSuggestionsState: 'error',
- });
- };
-
- // Analyze namespace and fetch suggestions
- try {
- const { database, collection } = toNS(getState().namespace);
- const analyzedNamespace = mql.analyzeNamespace(
- { database, collection },
- sampleDocuments
- );
-
- const parsedQuery = mql.parseQuery(
- _parseShellBSON(query, { mode: ParseMode.Loose }),
- analyzedNamespace
- );
- const results = await mql.suggestIndex([parsedQuery]);
- const indexSuggestions = results?.index;
-
- if (
- !indexSuggestions ||
- Object.keys(indexSuggestions as Record).length === 0
- ) {
- throwError();
- return;
- }
-
- dispatch({
- type: ActionTypes.SuggestedIndexesFetched,
- sampleDocs: sampleDocuments,
- indexSuggestions,
- error: null,
- indexSuggestionsState: 'success',
- });
- } catch (e: unknown) {
- // TODO: remove this in CLOUDP-320224
- track('Error parsing query', { context: 'Create Index Modal' });
- throwError(e);
- }
- };
-};
-
-export const fetchCoveredQueries = (): CoveredQueriesFetchedAction => ({
- type: ActionTypes.CoveredQueriesFetched,
-});
-
-export const queryUpdated = ({
- query,
-}: QueryUpdatedProps): QueryUpdatedAction => ({
- type: ActionTypes.QueryUpdatedAction,
- query,
-});
-
function isEmptyValue(value: unknown) {
if (value === '') {
return true;
@@ -553,22 +361,9 @@ export const createIndexFormSubmitted = (): IndexesThunkAction<
void,
ErrorEncounteredAction | CreateIndexFormSubmittedAction
> => {
- return (dispatch, getState, { track, preferences }) => {
- // @experiment Early Journey Indexes Guidance & Awareness | Jira Epic: CLOUDP-239367
- const currentTab = getState().createIndex.currentTab;
- const isQueryFlow = currentTab === 'QueryFlow';
- const indexSuggestions = getState().createIndex.indexSuggestions;
- const { enableIndexesGuidanceExp, showIndexesGuidanceVariant } =
- preferences.getPreferences();
-
+ return (dispatch, getState, { track }) => {
track('Create Index Button Clicked', {
context: 'Create Index Modal',
- flow:
- enableIndexesGuidanceExp && showIndexesGuidanceVariant
- ? currentTab === 'IndexFlow'
- ? 'Start with Index'
- : 'Start with Query'
- : undefined,
});
const formIndexOptions = getState().createIndex.options;
@@ -576,19 +371,12 @@ export const createIndexFormSubmitted = (): IndexesThunkAction<
let spec: Record = {};
try {
- if (isQueryFlow) {
- // Gather from suggested index
- if (indexSuggestions) {
- spec = indexSuggestions;
- }
- } else {
- // Gather from the index input fields
- spec = Object.fromEntries(
- getState().createIndex.fields.map((field) => {
- return [field.name, fieldTypeToIndexDirection(field.type)];
- })
- );
- }
+ // Gather from the index input fields
+ spec = Object.fromEntries(
+ getState().createIndex.fields.map((field) => {
+ return [field.name, fieldTypeToIndexDirection(field.type)];
+ })
+ );
} catch (e) {
dispatch(errorEncountered((e as any).message));
return;
@@ -703,7 +491,6 @@ const reducer: Reducer = (state = INITIAL_STATE, action) => {
return {
...state,
fields: [...state.fields, { name: '', type: '' }],
- hasIndexFieldChanges: true,
error: null,
};
}
@@ -714,7 +501,6 @@ const reducer: Reducer = (state = INITIAL_STATE, action) => {
return {
...state,
fields,
- hasIndexFieldChanges: true,
error: null,
};
}
@@ -729,7 +515,6 @@ const reducer: Reducer = (state = INITIAL_STATE, action) => {
return {
...state,
fields,
- hasIndexFieldChanges: true,
error: null,
};
}
@@ -738,7 +523,6 @@ const reducer: Reducer = (state = INITIAL_STATE, action) => {
return {
...state,
fields: action.fields,
- hasIndexFieldChanges: true,
error: null,
};
}
@@ -777,17 +561,9 @@ const reducer: Reducer = (state = INITIAL_STATE, action) => {
if (
isAction(action, ActionTypes.CreateIndexOpened)
) {
- const parsedInitialQuery = action.initialQuery
- ? JSON.stringify(action.initialQuery, null, 2)
- : '';
-
return {
...getInitialState(),
isVisible: true,
- // get it from the current query or initial query from insights nudge
- query: state.query || parsedInitialQuery,
- initialQuery: parsedInitialQuery,
- currentTab: action.initialQuery ? 'QueryFlow' : 'IndexFlow',
};
}
@@ -811,7 +587,6 @@ const reducer: Reducer = (state = INITIAL_STATE, action) => {
return {
...state,
isVisible: false,
- query: '',
};
}
@@ -827,67 +602,6 @@ const reducer: Reducer = (state = INITIAL_STATE, action) => {
};
}
- if (isAction(action, ActionTypes.TabUpdated)) {
- return {
- ...state,
- currentTab: action.currentTab,
- };
- }
-
- if (
- isAction(
- action,
- ActionTypes.SuggestedIndexesRequested
- )
- ) {
- return {
- ...state,
- fetchingSuggestionsState: 'fetching',
- error: null,
- indexSuggestions: null,
- };
- }
-
- if (
- isAction(
- action,
- ActionTypes.SuggestedIndexesFetched
- )
- ) {
- return {
- ...state,
- fetchingSuggestionsState: action.indexSuggestionsState,
- error: action.error,
- indexSuggestions: action.indexSuggestions,
- sampleDocs: action.sampleDocs,
- hasQueryChanges: false,
- };
- }
-
- if (
- isAction(
- action,
- ActionTypes.CoveredQueriesFetched
- )
- ) {
- return {
- ...state,
- coveredQueriesArr: state.fields.map((field, index) => {
- return { [field.name]: index + 1 };
- }),
- hasIndexFieldChanges: false,
- };
- }
-
- if (isAction(action, ActionTypes.QueryUpdatedAction)) {
- return {
- ...state,
- query: action.query,
- hasQueryChanges: true,
- error: null,
- };
- }
-
return state;
};
diff --git a/packages/compass-preferences-model/src/feature-flags.ts b/packages/compass-preferences-model/src/feature-flags.ts
index 4e8af2f53c1..b2517c6aa51 100644
--- a/packages/compass-preferences-model/src/feature-flags.ts
+++ b/packages/compass-preferences-model/src/feature-flags.ts
@@ -151,29 +151,6 @@ export const FEATURE_FLAG_DEFINITIONS = [
},
},
- /**
- * Feature flags for Early Journey Indexes Guidance & Awareness | Jira Epic: CLOUDP-239367
- * These are passed from MMS and not editable by user
- */
- {
- name: 'enableIndexesGuidanceExp',
- stage: 'development',
- atlasCloudFeatureFlagName: null,
- description: {
- short: 'Enable Indexes Guidance Experiment',
- },
- },
-
- {
- name: 'showIndexesGuidanceVariant',
- stage: 'development',
- atlasCloudFeatureFlagName: null,
- description: {
- short:
- 'Used to check if user is in the Indexes Guidance Experiment Variant',
- },
- },
-
{
name: 'enableContextMenus',
stage: 'released',
diff --git a/packages/compass-telemetry/src/growth-experiments.ts b/packages/compass-telemetry/src/growth-experiments.ts
index 92100c2da9f..96d4576bfba 100644
--- a/packages/compass-telemetry/src/growth-experiments.ts
+++ b/packages/compass-telemetry/src/growth-experiments.ts
@@ -1,5 +1,4 @@
export enum ExperimentTestName {
- earlyJourneyIndexesGuidance = 'EARLY_JOURNEY_INDEXES_GUIDANCE_20250328',
mockDataGenerator = 'MOCK_DATA_GENERATOR_20251001',
atlasSkills = 'ATLAS_SKILLS_EXPERIMENT_20251007',
}
diff --git a/packages/compass-telemetry/src/provider.tsx b/packages/compass-telemetry/src/provider.tsx
index d481433e40b..0892ea901e5 100644
--- a/packages/compass-telemetry/src/provider.tsx
+++ b/packages/compass-telemetry/src/provider.tsx
@@ -135,8 +135,8 @@ export function useTrackOnChange(
*
* @example
* useFireExperimentViewed({
- * testName: ExperimentTestName.earlyJourneyIndexesGuidance,
- * shouldFire: enableInIndexesGuidanceExp ,
+ * testName: ExperimentTestName.mockDataGenerator,
+ * shouldFire: enableMockDataGenerator,
* });
*/
export const useFireExperimentViewed = ({
diff --git a/packages/compass-telemetry/src/telemetry-events.ts b/packages/compass-telemetry/src/telemetry-events.ts
index 76d00d50183..adbea9fa94d 100644
--- a/packages/compass-telemetry/src/telemetry-events.ts
+++ b/packages/compass-telemetry/src/telemetry-events.ts
@@ -2857,21 +2857,6 @@ export type CreateIndexModalContext = 'Create Index Modal';
type CreateIndexButtonClickedEvent = CommonEvent<{
name: 'Create Index Button Clicked';
- payload: {
- flow: 'Start with Query' | 'Start with Index' | undefined;
- context: CreateIndexModalContext;
- };
-}>;
-
-type CreateIndexErrorParsingQueryEvent = CommonEvent<{
- name: 'Error parsing query';
- payload: {
- context: CreateIndexModalContext;
- };
-}>;
-
-type CreateIndexErrorGettingCoveredQueriesEvent = CommonEvent<{
- name: 'Error generating covered queries';
payload: {
context: CreateIndexModalContext;
};
@@ -2899,42 +2884,6 @@ type CreateIndexOptionsClicked = CommonEvent<{
};
}>;
-type CreateIndexCoveredQueriesButtonClicked = CommonEvent<{
- name: 'Covered Queries Button Clicked';
- payload: {
- context: CreateIndexModalContext;
- };
-}>;
-
-type CreateIndexSuggestedIndexButtonClicked = CommonEvent<{
- name: 'Suggested Index Button Clicked';
- payload: {
- context: CreateIndexModalContext;
- };
-}>;
-
-type CreateIndexIndexTabClicked = CommonEvent<{
- name: 'Start with an Index Tab Clicked';
- payload: {
- context: CreateIndexModalContext;
- };
-}>;
-
-type CreateIndexQueryTabClicked = CommonEvent<{
- name: 'Start with a Query Tab Clicked';
- payload: {
- context: CreateIndexModalContext;
- };
-}>;
-
-type CreateIndexCodeEquivalentToggled = CommonEvent<{
- name: 'Code Equivalent Toggled';
- payload: {
- context: CreateIndexModalContext;
- toggled: 'On' | 'Off';
- };
-}>;
-
type CreateIndexModalClosed = CommonEvent<{
name: 'Create Index Modal Closed';
payload: {
@@ -2949,48 +2898,6 @@ type CreateIndexModalCancelled = CommonEvent<{
};
}>;
-type CreateIndexProgrammingLanguageLinkClicked = CommonEvent<{
- name: 'View Programming Language Syntax Clicked';
- payload: {
- context: CreateIndexModalContext;
- };
-}>;
-
-type CreateIndexCoveredQueriesLearnMoreClicked = CommonEvent<{
- name: 'Covered Queries Learn More Clicked';
- payload: {
- context: CreateIndexModalContext;
- };
-}>;
-
-type CreateIndexESRLearnMoreClicked = CommonEvent<{
- name: 'ESR Learn More Clicked';
- payload: {
- context: CreateIndexModalContext;
- };
-}>;
-
-type CreateIndexInputIndexCopied = CommonEvent<{
- name: 'Input Index Copied';
- payload: {
- context: CreateIndexModalContext;
- };
-}>;
-
-type CreateIndexIndexSuggestionsCopied = CommonEvent<{
- name: 'Index Suggestions Copied';
- payload: {
- context: CreateIndexModalContext;
- };
-}>;
-
-type CreateIndexStrategiesDocumentationClicked = CommonEvent<{
- name: 'Index Strategies Documentation Clicked';
- payload: {
- context: CreateIndexModalContext;
- };
-}>;
-
/**
* This event is fired when user adds a collection in a data modeling diagram.
*
@@ -3468,23 +3375,10 @@ export type TelemetryEvent =
| TimeToFirstByteEvent
| ExperimentViewedEvent
| CreateIndexButtonClickedEvent
- | CreateIndexErrorParsingQueryEvent
- | CreateIndexErrorGettingCoveredQueriesEvent
- | CreateIndexCodeEquivalentToggled
- | CreateIndexCoveredQueriesButtonClicked
- | CreateIndexCoveredQueriesLearnMoreClicked
- | CreateIndexESRLearnMoreClicked
- | CreateIndexIndexTabClicked
| CreateIndexModalCancelled
| CreateIndexModalClosed
| CreateIndexNewFieldAdded
| CreateIndexOptionsClicked
- | CreateIndexProgrammingLanguageLinkClicked
- | CreateIndexQueryTabClicked
- | CreateIndexSuggestedIndexButtonClicked
- | CreateIndexInputIndexCopied
- | CreateIndexIndexSuggestionsCopied
- | CreateIndexStrategiesDocumentationClicked
| UUIDEncounteredEvent
| ContextMenuOpened
| ContextMenuItemClicked
diff --git a/packages/compass-web/src/entrypoint.tsx b/packages/compass-web/src/entrypoint.tsx
index e57f1447044..830c297ed22 100644
--- a/packages/compass-web/src/entrypoint.tsx
+++ b/packages/compass-web/src/entrypoint.tsx
@@ -522,23 +522,6 @@ const CompassWeb = ({
preferences: preferencesAccess.current,
});
- useEffect(() => {
- // TODO(COMPASS-9353): Provide a standard way of updating Compass' preferences from web.
- // Avoid duplicating this pattern until we address this ticket.
- const updateEarlyIndexesPreferences = async () => {
- await preferencesAccess.current.savePreferences({
- enableIndexesGuidanceExp: initialPreferences?.enableIndexesGuidanceExp,
- showIndexesGuidanceVariant:
- initialPreferences?.showIndexesGuidanceVariant,
- });
- };
- void updateEarlyIndexesPreferences();
- }, [
- initialPreferences?.enableIndexesGuidanceExp,
- initialPreferences?.showIndexesGuidanceVariant,
- preferencesAccess,
- ]);
-
return (