diff --git a/packages/compass-components/src/components/collapsible-field-set.tsx b/packages/compass-components/src/components/collapsible-field-set.tsx
index dc4a15d67b8..d69542bf2c7 100644
--- a/packages/compass-components/src/components/collapsible-field-set.tsx
+++ b/packages/compass-components/src/components/collapsible-field-set.tsx
@@ -16,6 +16,10 @@ const collapsibleFieldsetStyles = css({
},
});
+const checkboxStyles = css({
+ padding: `${spacing[2]}px 0`,
+});
+
export type CollapsibleFieldSetProps = {
darkMode?: boolean;
dataTestId?: string;
@@ -73,6 +77,7 @@ const UnthemedCollapsibleFieldSet = ({
checked={toggled}
id={labelId}
darkMode={darkMode}
+ className={checkboxStyles}
/>
{toggled &&
}
diff --git a/packages/compass-indexes/src/components/create-index-actions/create-index-actions.spec.jsx b/packages/compass-indexes/src/components/create-index-actions/create-index-actions.spec.jsx
new file mode 100644
index 00000000000..547e10d3f32
--- /dev/null
+++ b/packages/compass-indexes/src/components/create-index-actions/create-index-actions.spec.jsx
@@ -0,0 +1,224 @@
+import React from 'react';
+import { expect } from 'chai';
+import sinon from 'sinon';
+
+import {
+ render,
+ screen,
+ cleanup,
+ fireEvent,
+ within,
+} from '@testing-library/react';
+
+import CreateIndexActions from '../create-index-actions';
+
+describe('CreateIndexActions Component', function () {
+ let toggleIsVisibleSpy;
+ let clearErrorSpy;
+ let createIndexSpy;
+ let resetFormSpy;
+
+ beforeEach(function () {
+ toggleIsVisibleSpy = sinon.spy();
+ clearErrorSpy = sinon.spy();
+ createIndexSpy = sinon.spy();
+ resetFormSpy = sinon.spy();
+ });
+
+ afterEach(function () {
+ toggleIsVisibleSpy = null;
+ clearErrorSpy = null;
+ createIndexSpy = null;
+ resetFormSpy = null;
+
+ cleanup();
+ });
+
+ it('renders a cancel button', function () {
+ render(
+
+ );
+
+ const button = screen.getByTestId('create-index-actions-cancel-button');
+ expect(button.textContent).to.be.equal('Cancel');
+ });
+
+ context('onCancel', function () {
+ it('calls the toggleIsVisible function', function () {
+ render(
+
+ );
+
+ const button = screen.getByTestId('create-index-actions-cancel-button');
+ fireEvent.click(button);
+ expect(toggleIsVisibleSpy).to.have.been.calledWith(false);
+ });
+
+ it('calls the resetForm function', function () {
+ render(
+
+ );
+
+ const button = screen.getByTestId('create-index-actions-cancel-button');
+ fireEvent.click(button);
+ expect(resetFormSpy).to.have.been.calledOnce;
+ });
+ });
+
+ context('onConfirm', function () {
+ it('calls the createIndex function', function () {
+ render(
+
+ );
+
+ const button = screen.getByTestId(
+ 'create-index-actions-create-index-button'
+ );
+ fireEvent.click(button);
+ expect(createIndexSpy).to.have.been.calledOnce;
+ });
+ });
+
+ it('renders a create index button', function () {
+ render(
+
+ );
+
+ const button = screen.getByTestId(
+ 'create-index-actions-create-index-button'
+ );
+ expect(button.textContent).to.be.equal('Create Index');
+ });
+
+ context('with error', function () {
+ it('renders error banner', function () {
+ render(
+
+ );
+
+ const errorBanner = screen.getByTestId(
+ 'create-index-actions-error-banner-wrapper'
+ );
+ expect(errorBanner).to.contain.text('Some error happened!');
+ });
+
+ it('closes error banner', function () {
+ render(
+
+ );
+
+ const errorBanner = screen.getByTestId(
+ 'create-index-actions-error-banner-wrapper'
+ );
+ const closeIcon = within(errorBanner).getByLabelText('X Icon');
+
+ fireEvent.click(closeIcon);
+ expect(clearErrorSpy).to.have.been.calledOnce;
+ });
+
+ it('does not render in progress banner', function () {
+ render(
+
+ );
+
+ const inProgressBanner = screen.queryByTestId(
+ 'create-index-actions-in-progress-banner-wrapper'
+ );
+ expect(inProgressBanner).to.not.exist;
+ });
+ });
+
+ context('without error', function () {
+ it('does not render error banner', function () {
+ render(
+
+ );
+
+ const errorBanner = screen.queryByTestId(
+ 'create-index-actions-error-banner-wrapper'
+ );
+ expect(errorBanner).to.not.exist;
+ });
+
+ it('renders in progress banner', function () {
+ render(
+
+ );
+
+ const inProgressBanner = screen.getByTestId(
+ 'create-index-actions-in-progress-banner-wrapper'
+ );
+ expect(inProgressBanner).to.contain.text('Create in Progress');
+ });
+ });
+});
diff --git a/packages/compass-indexes/src/components/create-index-actions/create-index-actions.tsx b/packages/compass-indexes/src/components/create-index-actions/create-index-actions.tsx
new file mode 100644
index 00000000000..e257a20e889
--- /dev/null
+++ b/packages/compass-indexes/src/components/create-index-actions/create-index-actions.tsx
@@ -0,0 +1,114 @@
+import React from 'react';
+import {
+ css,
+ withTheme,
+ Banner,
+ spacing,
+ Button,
+} from '@mongodb-js/compass-components';
+
+const bannerStyles = css({
+ margin: `${spacing[3]}px 0`,
+});
+
+const createIndexButtonStyles = css({
+ marginLeft: spacing[2],
+});
+
+const modalFooterActionsStyles = css({
+ display: 'flex',
+ justifyContent: 'flex-end',
+ gap: spacing[2],
+});
+
+/**
+ * Create index actions.
+ */
+function CreateIndexActions({
+ darkMode,
+ toggleIsVisible,
+ resetForm,
+ error,
+ clearError,
+ inProgress,
+ createIndex,
+}: {
+ darkMode?: boolean;
+ toggleIsVisible: (isVisible: boolean) => void;
+ resetForm: () => void;
+ error: string | null;
+ clearError: () => void;
+ inProgress: boolean;
+ createIndex: () => void;
+}) {
+ const renderError = () => {
+ if (!error) {
+ return;
+ }
+
+ return (
+
+
+ {error}
+
+
+ );
+ };
+
+ const renderInProgress = () => {
+ if (error || !inProgress) {
+ return;
+ }
+
+ return (
+
+
+ Create in Progress
+
+
+ );
+ };
+
+ const onCancel = () => {
+ toggleIsVisible(false);
+ resetForm();
+ };
+
+ const onConfirm = () => {
+ createIndex();
+ };
+
+ return (
+ <>
+
+ {renderError()}
+ {renderInProgress()}
+
+
+
+
+
+ >
+ );
+}
+
+export default withTheme(CreateIndexActions);
diff --git a/packages/compass-indexes/src/components/create-index-actions/index.ts b/packages/compass-indexes/src/components/create-index-actions/index.ts
new file mode 100644
index 00000000000..518f0383b65
--- /dev/null
+++ b/packages/compass-indexes/src/components/create-index-actions/index.ts
@@ -0,0 +1,3 @@
+import CreateIndexActions from './create-index-actions';
+
+export default CreateIndexActions;
diff --git a/packages/compass-indexes/src/components/create-index-fields/create-index-fields.spec.tsx b/packages/compass-indexes/src/components/create-index-fields/create-index-fields.spec.tsx
index c274732048b..54130772462 100644
--- a/packages/compass-indexes/src/components/create-index-fields/create-index-fields.spec.tsx
+++ b/packages/compass-indexes/src/components/create-index-fields/create-index-fields.spec.tsx
@@ -48,6 +48,84 @@ describe('CreateIndexFields Component', function () {
const fieldTypes = screen.getByTestId('create-index-fields-type-0');
expect(fieldTypes).to.not.contain.html('columnstore');
});
+
+ it('does not render a minus button for a single field', function () {
+ render(
+
+ );
+ const minusButton = screen.queryByTestId('remove-index-field-button');
+ expect(minusButton).to.not.exist;
+ });
+
+ it('renders a minus button for more than one field', function () {
+ render(
+
+ );
+ const minusButton = screen.getAllByTestId('remove-index-field-button');
+ expect(minusButton.length).to.be.equal(2);
+ });
+
+ it('renders a plus button for a single field', function () {
+ render(
+
+ );
+ const minusButton = screen.getAllByTestId('add-index-field-button');
+ expect(minusButton.length).to.be.equal(1);
+ });
+
+ it('renders a plus button for more than one field', function () {
+ render(
+
+ );
+ const minusButton = screen.getAllByTestId('add-index-field-button');
+ expect(minusButton.length).to.be.equal(2);
+ });
});
describe('server version 6.1.0', function () {
diff --git a/packages/compass-indexes/src/components/create-index-form/columnstore-projection.tsx b/packages/compass-indexes/src/components/create-index-form/columnstore-projection.tsx
index 33652d1fba8..be412673077 100644
--- a/packages/compass-indexes/src/components/create-index-form/columnstore-projection.tsx
+++ b/packages/compass-indexes/src/components/create-index-form/columnstore-projection.tsx
@@ -28,6 +28,7 @@ const ColumnstoreProjectionCollapsibleFieldSet = ({
>
+ );
+ });
+
+ after(function () {
+ resetSpyComponentProps();
+ cleanup();
+ });
+
+ it('calls the collationStringChanged function', function () {
+ const createIndexOptions = screen.getByTestId(
+ 'create-index-modal-toggle-options'
+ );
+ fireEvent.click(createIndexOptions);
+ const editorWrapper = screen.getByTestId(
+ 'create-index-modal-use-custom-collation-editor'
+ );
+
+ const editor = within(editorWrapper).getByRole('textbox');
+
+ screen.debug(editor);
+
+ userEvent.paste(editor, '{}');
+
+ expect(collationStringChangedSpy).to.have.been.calledWith('{}');
+ });
+ });
+
context('with partial filter expression', function () {
before(function () {
spyComponentProps();
@@ -409,15 +486,89 @@ describe('CreateIndexForm Component', function () {
'create-index-modal-toggle-options'
);
fireEvent.click(createIndexOptions);
- const input = screen.getByTestId('create-index-modal-is-pfe-input');
- fireEvent.change(input, { target: { value: '{}' } });
+ const editorWrapper = screen.getByTestId(
+ 'create-index-modal-is-pfe-editor'
+ );
+
+ const editor = within(editorWrapper).getByRole('textbox');
+
+ screen.debug(editor);
+
+ userEvent.paste(editor, '{}');
+
expect(partialFilterExpressionChangedSpy).to.have.been.calledWith('{}');
});
});
- // TODO: test editors on change event.
- context.skip('with custom collation', function () {});
- context.skip('with wildcard projection', function () {});
+ context('with wildcard projection', function () {
+ before(function () {
+ spyComponentProps();
+ render(
+
+ );
+ });
+
+ after(function () {
+ resetSpyComponentProps();
+ cleanup();
+ });
+
+ it('calls the wildcardProjectionChanged function', function () {
+ const createIndexOptions = screen.getByTestId(
+ 'create-index-modal-toggle-options'
+ );
+ fireEvent.click(createIndexOptions);
+ const editorWrapper = screen.getByTestId(
+ 'create-index-modal-use-wildcard-editor'
+ );
+
+ const editor = within(editorWrapper).getByRole('textbox');
+
+ screen.debug(editor);
+
+ userEvent.paste(editor, '{}');
+
+ expect(wildcardProjectionChangedSpy).to.have.been.calledWith('{}');
+ });
+ });
});
describe('server version 6.1.0', function () {
@@ -494,6 +645,74 @@ describe('CreateIndexForm Component', function () {
});
});
- context.skip('with columnstore projection', function () {});
+ context('with columnstore projection', function () {
+ before(function () {
+ spyComponentProps();
+ render(
+
+ );
+ });
+
+ after(function () {
+ resetSpyComponentProps();
+ cleanup();
+ });
+
+ it('calls the columnstoreProjectionChanged function', function () {
+ const createIndexOptions = screen.getByTestId(
+ 'create-index-modal-toggle-options'
+ );
+ fireEvent.click(createIndexOptions);
+ const editorWrapper = screen.getByTestId(
+ 'create-index-modal-use-columnstore-editor'
+ );
+
+ const editor = within(editorWrapper).getByRole('textbox');
+
+ screen.debug(editor);
+
+ userEvent.paste(editor, '{}');
+
+ expect(columnstoreProjectionChangedSpy).to.have.been.calledWith('{}');
+ });
+ });
});
});
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 23bc22078fe..7e60f4e00ef 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
@@ -148,18 +148,18 @@ class CreateIndexForm extends Component {
this.props.partialFilterExpressionChanged
}
/>
-
+
{hasColumnstoreIndexesSupport(this.props.serverVersion) && (
- partialFilterExpressionChanged(e.target.value)}
- spellCheck={false}
+
);
diff --git a/packages/compass-indexes/src/components/create-index-form/wildcard-projection.tsx b/packages/compass-indexes/src/components/create-index-form/wildcard-projection.tsx
index 93335b3e5ed..e520f7f6efb 100644
--- a/packages/compass-indexes/src/components/create-index-form/wildcard-projection.tsx
+++ b/packages/compass-indexes/src/components/create-index-form/wildcard-projection.tsx
@@ -28,6 +28,7 @@ const WildcardProjectionCollapsibleFieldSet = ({
>
{
- if (!error) {
- return;
- }
-
- return (
-
- {error}
-
- );
- };
-
- const renderInProgress = () => {
- if (error || !inProgress) {
- return;
- }
-
- return (
-
- Create in Progress
-
- );
- };
-
- const onCancel = () => {
- toggleIsVisible(false);
- resetForm();
- };
-
- const onConfirm = () => {
- createIndex();
- };
-
return (