Skip to content

Commit

Permalink
feat: add empty state for search indexes COMPASS-7204 (#4842)
Browse files Browse the repository at this point in the history
* add empty state for search indexes

* minus the TODO comment

* fix link

* open the create modal when clicking the button

* sans only

* 💄
  • Loading branch information
lerouxb authored Sep 14, 2023
1 parent 2c9c555 commit 98c3ecf
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 13 deletions.
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
import React from 'react';
import { cleanup, render, screen, within } from '@testing-library/react';
import {
cleanup,
fireEvent,
render,
screen,
within,
} from '@testing-library/react';
import { expect } from 'chai';
import sinon from 'sinon';
import userEvent from '@testing-library/user-event';
import { spy } from 'sinon';

import { SearchIndexesTable } from './search-indexes-table';
import type { SearchIndex } from 'mongodb-data-service';
Expand All @@ -28,16 +34,22 @@ const indexes: SearchIndex[] = [
const renderIndexList = (
props: Partial<React.ComponentProps<typeof SearchIndexesTable>> = {}
) => {
const onSortTableSpy = sinon.spy();
const openCreateSpy = sinon.spy();

render(
<SearchIndexesTable
indexes={indexes}
status="READY"
isWritable={true}
readOnly={false}
onSortTable={() => {}}
onSortTable={onSortTableSpy}
openCreateModal={openCreateSpy}
{...props}
/>
);

return { onSortTableSpy, openCreateSpy };
};

describe('SearchIndexesTable Component', function () {
Expand Down Expand Up @@ -85,22 +97,26 @@ describe('SearchIndexesTable Component', function () {
});
}

it('does not render the table if there are no indexes', function () {
renderIndexList({
it('renders the zero state rather than the table if there are no indexes', function () {
const { openCreateSpy } = renderIndexList({
indexes: [],
});

expect(() => {
screen.getByTestId('search-indexes-list');
}).to.throw;

const button = screen.getByTestId('create-atlas-search-index-button');
expect(button).to.exist;

expect(openCreateSpy.callCount).to.equal(0);
fireEvent.click(button);
expect(openCreateSpy.callCount).to.equal(1);
});

for (const column of ['Name and Fields', 'Status']) {
it(`sorts table by ${column}`, function () {
const onSortTableSpy = spy();
renderIndexList({
onSortTable: onSortTableSpy,
});
const { onSortTableSpy } = renderIndexList();

const indexesList = screen.getByTestId('search-indexes-list');

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,26 @@ import { connect } from 'react-redux';
import type { SearchIndex } from 'mongodb-data-service';
import { withPreferences } from 'compass-preferences-model';

import { EmptyContent, Button, Link } from '@mongodb-js/compass-components';

import type { SearchSortColumn } from '../../modules/search-indexes';
import { SearchIndexesStatuses } from '../../modules/search-indexes';
import {
SearchIndexesStatuses,
openModalForCreation,
} from '../../modules/search-indexes';
import type { SearchIndexesStatus } from '../../modules/search-indexes';
import { sortSearchIndexes } from '../../modules/search-indexes';
import type { SortDirection, RootState } from '../../modules';

import { IndexesTable } from '../indexes-table';
import { ZeroGraphic } from './zero-graphic';

type SearchIndexesTableProps = {
indexes: SearchIndex[];
isWritable?: boolean;
readOnly?: boolean;
onSortTable: (column: SearchSortColumn, direction: SortDirection) => void;
openCreateModal: () => void;
status: SearchIndexesStatus;
};

Expand All @@ -26,9 +33,47 @@ function isReadyStatus(status: SearchIndexesStatus) {
);
}

function ZeroState({ openCreateModal }: { openCreateModal: () => void }) {
return (
<EmptyContent
icon={ZeroGraphic}
title="No search indexes yet"
subTitle="Atlas Search is an embedded full-text search in MongoDB Atlas that gives you a seamless, scalable experience for building relevance-based app features."
callToAction={
<Button
onClick={openCreateModal}
data-testid="create-atlas-search-index-button"
variant="primary"
size="small"
>
Create Atlas Search Index
</Button>
}
callToActionLink={
<span>
Not sure where to start?&nbsp;
<Link
href="https://www.mongodb.com/docs/atlas/atlas-search/"
target="_blank"
>
Visit our Docs
</Link>
</span>
}
/>
);
}

export const SearchIndexesTable: React.FunctionComponent<
SearchIndexesTableProps
> = ({ indexes, isWritable, readOnly, onSortTable, status }) => {
> = ({
indexes,
isWritable,
readOnly,
onSortTable,
openCreateModal,
status,
}) => {
if (!isReadyStatus(status)) {
// If there's an error or the search indexes are still pending or search
// indexes aren't available, then that's all handled by the toolbar and we
Expand All @@ -37,8 +82,7 @@ export const SearchIndexesTable: React.FunctionComponent<
}

if (indexes.length === 0) {
// TODO(COMPASS-7204): render the zero state
return null;
return <ZeroState openCreateModal={openCreateModal} />;
}

const canModifyIndex = isWritable && !readOnly;
Expand Down Expand Up @@ -84,6 +128,7 @@ const mapState = ({ searchIndexes, isWritable }: RootState) => ({

const mapDispatch = {
onSortTable: sortSearchIndexes,
openCreateModal: openModalForCreation,
};

export default connect(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import React, { useMemo } from 'react';

import { palette, useDarkMode } from '@mongodb-js/compass-components';

const ZeroGraphic: React.FunctionComponent = () => {
const darkMode = useDarkMode();
const strokeColor = useMemo(
() => (darkMode ? palette.white : palette.black),
[darkMode]
);
return (
<svg
width="72"
height="72"
viewBox="0 0 72 72"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M47 53C54.1797 53 60 47.1797 60 40C60 32.8203 54.1797 27 47 27C39.8203 27 34 32.8203 34 40C34 47.1797 39.8203 53 47 53Z"
fill={palette.green.base}
stroke={strokeColor}
strokeMiterlimit="10"
strokeLinecap="round"
strokeLinejoin="round"
/>
<path d="M56 49L68 61" stroke={strokeColor} />
<path
d="M4 35.9501H6.2M6.2 35.9501C9.4 35.9501 12.1 33.3553 12.1 30.0619V19.5828C12.1 14.8922 15.9 11 20.7 11M6.2 35.9501C9.4 35.9501 12.1 38.5449 12.1 41.8383V52.4172C12.1 57.1078 15.9 61 20.7 61M54.0001 35.9501H51.8001M51.8001 35.9501C48.6001 35.9501 45.9001 38.5449 45.9001 41.8383V52.4172C45.9001 57.1078 42.1001 61 37.3001 61M51.8001 35.9501C48.6001 35.9501 45.9 33.3553 45.9 30.0619V19.5828C45.9 14.8922 42.1 11 37.3 11"
stroke={strokeColor}
strokeMiterlimit="10"
/>
</svg>
);
};

export { ZeroGraphic };

0 comments on commit 98c3ecf

Please sign in to comment.