Skip to content

Commit

Permalink
feat(search-indexes): add a drop down to choose a search index template
Browse files Browse the repository at this point in the history
COMPASS-7173 (#4892)

* chore: add template to both create and update modals

* chore: replace template on creating and updating

* chore: bump to the latest mongodb-constants

* chore: bump to latest mongodb-constants

* chore: fix dependencies

* chore: fix linter issues

* chore: fix peer deps

* chore: fix package-lock

* chore: fix peer deps

* chore: fix potential weird behaviour on focus and applySnippet

* chore: fix test, now codemirror content is async due to rafraf

* chore: fix style issues in dropdown

* chore: remove overflow hidden on body to avoid issues on small screens

* chore: merge with main, fix dependencies

* chore: minor fixes

* chore: forgot to remove .only for testing

* chore: bump constants package
  • Loading branch information
kmruiz authored Sep 26, 2023
1 parent 8596ab8 commit def8c21
Show file tree
Hide file tree
Showing 12 changed files with 321 additions and 129 deletions.
165 changes: 74 additions & 91 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@
"@babel/core": "7.16.0",
"@babel/parser": "7.16.0",
"@mongodb-js/monorepo-tools": "^1.1.1",
"@mongodb-js/sbom-tools": "^0.5.3",
"@mongodb-js/sbom-tools": "^0.5.2",
"@testing-library/dom": "^8.11.1",
"babel-loader": "^7.1.5",
"husky": "^8.0.3",
Expand Down
4 changes: 2 additions & 2 deletions packages/compass-aggregations/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
"@mongodb-js/compass-user-data": "^0.1.2",
"@mongodb-js/compass-utils": "^0.4.0",
"@mongodb-js/explain-plan-helper": "^1.1.2",
"@mongodb-js/mongodb-constants": "^0.8.3",
"@mongodb-js/mongodb-constants": "^0.8.4",
"@mongodb-js/mongodb-redux-common": "^2.0.11",
"bson": "^6.0.0",
"compass-preferences-model": "^2.14.0",
Expand Down Expand Up @@ -106,7 +106,7 @@
"@mongodb-js/compass-user-data": "^0.1.2",
"@mongodb-js/compass-utils": "^0.4.0",
"@mongodb-js/explain-plan-helper": "^1.1.2",
"@mongodb-js/mongodb-constants": "^0.8.3",
"@mongodb-js/mongodb-constants": "^0.8.4",
"@mongodb-js/mongodb-redux-common": "^2.0.11",
"bson": "^6.0.0",
"compass-preferences-model": "^2.14.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/compass-e2e-tests/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
"ps-list": "^8.1.0",
"puppeteer": "^15.4.0",
"resolve-mongodb-srv": "^1.1.2",
"semver": "^7.5.0",
"semver": "^7.5.4",
"ts-node": "^10.9.1",
"webdriverio": "^7.16.13",
"xvfb-maybe": "^0.2.1"
Expand Down
2 changes: 1 addition & 1 deletion packages/compass-editor/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@
"@codemirror/view": "^6.7.1",
"@lezer/highlight": "^1.1.3",
"@mongodb-js/compass-components": "^1.14.0",
"@mongodb-js/mongodb-constants": "^0.8.3",
"@mongodb-js/mongodb-constants": "^0.8.4",
"polished": "^4.2.2",
"prettier": "^2.7.1"
}
Expand Down
6 changes: 4 additions & 2 deletions packages/compass-indexes/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
"@mongodb-js/compass-editor": "^0.13.0",
"@mongodb-js/compass-logging": "^1.2.0",
"@mongodb-js/mongodb-redux-common": "^2.0.11",
"@mongodb-js/mongodb-constants": "^0.8.4",
"bson": "^6.0.0",
"compass-preferences-model": "^2.14.0",
"react": "^17.0.2"
Expand All @@ -74,6 +75,7 @@
"@testing-library/user-event": "^13.5.0",
"chai": "^4.2.0",
"depcheck": "^1.4.1",
"ejson-shell-parser": "^1.2.4",
"electron": "^26.2.2",
"enzyme": "^3.11.0",
"eslint": "^7.25.0",
Expand All @@ -93,14 +95,14 @@
"redux-thunk": "^2.4.1",
"semver": "^5.4.1",
"sinon": "^9.2.3",
"xvfb-maybe": "^0.2.1",
"ejson-shell-parser": "^1.2.4"
"xvfb-maybe": "^0.2.1"
},
"dependencies": {
"@mongodb-js/compass-components": "^1.14.0",
"@mongodb-js/compass-editor": "^0.13.0",
"@mongodb-js/compass-logging": "^1.2.0",
"@mongodb-js/mongodb-redux-common": "^2.0.11",
"@mongodb-js/mongodb-constants": "^0.8.4",
"bson": "^6.0.0",
"compass-preferences-model": "^2.14.0"
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { ATLAS_SEARCH_TEMPLATES } from '@mongodb-js/mongodb-constants';
import { expect } from 'chai';
import { SearchIndexTemplateDropdown } from './';
import sinon from 'sinon';
import type { SinonSpy } from 'sinon';

import { render, screen, cleanup } from '@testing-library/react';
import userEvent from '@testing-library/user-event';

import React from 'react';

function templateNamed(name: string) {
return ATLAS_SEARCH_TEMPLATES.find((t) => t.name === name);
}

describe('Search Index Template Dropdown', function () {
let onTemplateSpy: SinonSpy;

beforeEach(function () {
onTemplateSpy = sinon.spy();

render(
<SearchIndexTemplateDropdown
tooltip="Tooltip"
onTemplate={onTemplateSpy}
/>
);
});

afterEach(cleanup);

it('notifies upwards with onTemplate when a new template is choosen', async function () {
const dropDown = screen
.getByText('Dynamic field mappings')
.closest('button')!;

userEvent.click(dropDown);

const staticFieldMappingOption = await screen.findByText(
'Static field mappings'
);
userEvent.click(staticFieldMappingOption);

expect(onTemplateSpy).to.have.been.calledWith(
templateNamed('Static field mappings')
);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import { ATLAS_SEARCH_TEMPLATES } from '@mongodb-js/mongodb-constants';
import type { SearchTemplate } from '@mongodb-js/mongodb-constants';
import React, { useState, useCallback } from 'react';
import {
Select,
Option,
Icon,
css,
Tooltip,
} from '@mongodb-js/compass-components';

const dropdownLabelStyles = css({
display: 'flex',
pointerEvents: 'auto', // leafy green specifies none in the label, which is wrong
});

const fillParentStyles = css({
flexGrow: 1,
});

type SearchIndexTemplateDropdownLabelProps = {
label: string;
tooltip: string;
};

const SearchIndexTemplateDropdownLabel: React.FunctionComponent<
SearchIndexTemplateDropdownLabelProps
> = ({ label, tooltip }) => (
<div className={dropdownLabelStyles}>
<span className={fillParentStyles}>{label}</span>
<Tooltip
align="right"
triggerEvent="hover"
trigger={({ children, ...props }) => (
<div {...props}>
<Icon
data-testid="search-template-info-icon"
glyph="InfoWithCircle"
/>
{children}
</div>
)}
>
{tooltip}
</Tooltip>
</div>
);

type SearchIndexTemplateDropdownProps = {
tooltip: string;
onTemplate: (template: SearchTemplate) => void;
};

export const SearchIndexTemplateDropdown: React.FunctionComponent<
SearchIndexTemplateDropdownProps
> = ({ tooltip, onTemplate }) => {
const [templateValue, setTemplateValue] = useState('0');

const onChooseTemplate = useCallback(
(value: string) => {
setTemplateValue(value);
onTemplate(ATLAS_SEARCH_TEMPLATES[+value]);
},
[onTemplate]
);

return (
<Select
value={templateValue}
allowDeselect={false}
onChange={onChooseTemplate}
/* @ts-expect-error The label can be any React component, however, the type definition forces a string. */
label={
<SearchIndexTemplateDropdownLabel label="Template" tooltip={tooltip} />
}
>
{ATLAS_SEARCH_TEMPLATES.map((template, idx) => (
<Option key={idx} value={`${idx}`}>
{template.name}
</Option>
))}
</Select>
);
};
Original file line number Diff line number Diff line change
@@ -1,14 +1,25 @@
import { ATLAS_SEARCH_TEMPLATES } from '@mongodb-js/mongodb-constants';
import { expect } from 'chai';
import { BaseSearchIndexModal } from './base-search-index-modal';
import sinon from 'sinon';
import type { SinonSpy } from 'sinon';

import { render, screen, cleanup } from '@testing-library/react';
import { render, screen, cleanup, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';

import React from 'react';
import { getCodemirrorEditorValue } from '@mongodb-js/compass-editor';

function normalizedTemplateNamed(name: string) {
const snippet =
ATLAS_SEARCH_TEMPLATES.find((t) => t.name === name)?.snippet || '';
// code mirror 'changes' the template placeholders, so let's do the same
// this regexp removes `tab` markers to their default value, for example:
// ${1:default} => default
//
return snippet.replace(/\${\d+:([^}]+)}/gm, '$1');
}

describe('Create Search Index Modal', function () {
let onSubmitSpy: SinonSpy;
let onCloseSpy: SinonSpy;
Expand Down Expand Up @@ -88,4 +99,27 @@ describe('Create Search Index Modal', function () {
expect(onSubmitSpy).to.have.been.calledOnceWithExactly('default', {});
});
});

describe('templates', function () {
it('replaces the contents of the index editor when a template is selected', async function () {
const dropDown = screen
.getByText('Dynamic field mappings')
.closest('button')!;

userEvent.click(dropDown);

const staticFieldMappingOption = await screen.findByText(
'Static field mappings'
);
userEvent.click(staticFieldMappingOption);

await waitFor(() => {
const indexDef = getCodemirrorEditorValue('definition-of-search-index');

expect(indexDef).to.equal(
normalizedTemplateNamed('Static field mappings')
);
});
});
});
});
Loading

0 comments on commit def8c21

Please sign in to comment.