Skip to content

Commit

Permalink
feat: show no search results found message
Browse files Browse the repository at this point in the history
  • Loading branch information
codeofmochi committed Jul 6, 2021
1 parent a2bcbe7 commit 3cede4f
Show file tree
Hide file tree
Showing 10 changed files with 160 additions and 82 deletions.
101 changes: 101 additions & 0 deletions cypress/integration/item/search/gridItemSearch.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import { DEFAULT_ITEM_LAYOUT_MODE } from '../../../../src/config/constants';
import { buildItemPath } from '../../../../src/config/paths';
import {
buildItemCard,
ITEMS_GRID_NO_ITEM_ID,
ITEMS_GRID_NO_SEARCH_RESULT_ID,
ITEM_SEARCH_INPUT_ID,
} from '../../../../src/config/selectors';
import { ITEM_LAYOUT_MODES } from '../../../../src/enums';
import { SAMPLE_ITEMS } from '../../../fixtures/items';

describe('Search Item in Grid', () => {
const { id } = SAMPLE_ITEMS.items[0];
const child3 = SAMPLE_ITEMS.items.find((it) => it.name === 'own_item_name3');
const child4 = SAMPLE_ITEMS.items.find((it) => it.name === 'own_item_name4');

it('searches in grid successfully', () => {
cy.setUpApi(SAMPLE_ITEMS);

// visit child
cy.visit(buildItemPath(id));
if (DEFAULT_ITEM_LAYOUT_MODE !== ITEM_LAYOUT_MODES.GRID) {
cy.switchMode(ITEM_LAYOUT_MODES.GRID);
}

// should get children
cy.wait('@getChildren').then(({ response: { body } }) => {
// check item is created and displayed
for (const item of body) {
cy.get(`#${buildItemCard(item.id)}`).should('exist');
}
});

// perform search
cy.get(`#${ITEM_SEARCH_INPUT_ID}`)
.type(child3.name)
.then(() => {
// should find child3 but not child4
cy.get(`#${buildItemCard(child3.id)}`).should('exist');
cy.get(`#${buildItemCard(child4.id)}`).should('not.exist');
});

// erase search
cy.get(`#${ITEM_SEARCH_INPUT_ID}`)
.clear()
.then(() => {
// should find all children again
cy.get(`#${buildItemCard(child3.id)}`).should('exist');
cy.get(`#${buildItemCard(child4.id)}`).should('exist');
});
});

it('displays no results found correctly', () => {
cy.setUpApi(SAMPLE_ITEMS);

// visit child
cy.visit(buildItemPath(id));
if (DEFAULT_ITEM_LAYOUT_MODE !== ITEM_LAYOUT_MODES.GRID) {
cy.switchMode(ITEM_LAYOUT_MODES.GRID);
}

// should get children
cy.wait('@getChildren').then(({ response: { body } }) => {
// check item is created and displayed
for (const item of body) {
cy.get(`#${buildItemCard(item.id)}`).should('exist');
}
});

// perform search
cy.get(`#${ITEM_SEARCH_INPUT_ID}`)
.type('some-garbage-input-that-doesnt-match-anything')
.then(() => {
// should find no results found but not empty
cy.get(`#${ITEMS_GRID_NO_SEARCH_RESULT_ID}`).should('exist');
cy.get(`#${ITEMS_GRID_NO_ITEM_ID}`).should('not.exist');
});
});

it('displays item is empty correctly', () => {
cy.setUpApi({ items: [SAMPLE_ITEMS.items[0]] });

// visit child
cy.visit(buildItemPath(id));
if (DEFAULT_ITEM_LAYOUT_MODE !== ITEM_LAYOUT_MODES.GRID) {
cy.switchMode(ITEM_LAYOUT_MODES.GRID);
}

// should be empty
cy.get(`#${ITEMS_GRID_NO_ITEM_ID}`).should('exist');

// perform search, then clear
cy.get(`#${ITEM_SEARCH_INPUT_ID}`).type(
'some-garbage-input-that-doesnt-match-anything',
);
cy.get(`#${ITEM_SEARCH_INPUT_ID}`).clear();

// should still display empty message
cy.get(`#${ITEMS_GRID_NO_ITEM_ID}`).should('exist');
});
});
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { buildItemPath } from '../../../src/config/paths';
import { buildItemPath } from '../../../../src/config/paths';
import {
buildItemsTableRowId,
ITEM_SEARCH_INPUT_ID,
} from '../../../src/config/selectors';
import { SAMPLE_ITEMS } from '../../fixtures/items';
} from '../../../../src/config/selectors';
import { SAMPLE_ITEMS } from '../../../fixtures/items';

describe('Search Item in Table', () => {
const { id } = SAMPLE_ITEMS.items[0];
Expand Down
52 changes: 0 additions & 52 deletions cypress/integration/search/gridItemSearch.spec.js

This file was deleted.

28 changes: 24 additions & 4 deletions src/components/item/ItemSearch.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
import OutlinedInput from '@material-ui/core/OutlinedInput';
import { makeStyles } from '@material-ui/core/styles';
import Typography from '@material-ui/core/Typography';
import SearchIcon from '@material-ui/icons/Search';
import PropTypes from 'prop-types';
import React, { useState } from 'react';
import { ITEM_SEARCH_INPUT_ID } from '../../config/selectors';
import { useTranslation } from 'react-i18next';
import {
ITEMS_GRID_NO_SEARCH_RESULT_ID,
ITEM_SEARCH_INPUT_ID,
} from '../../config/selectors';

const useSearchStyles = makeStyles((theme) => ({
search: {
Expand Down Expand Up @@ -77,6 +82,21 @@ ItemSearchInput.defaultProps = {
searchTextState: '',
};

const NoItemSearchResult = () => {
const { t } = useTranslation();

return (
<Typography
id={ITEMS_GRID_NO_SEARCH_RESULT_ID}
variant="subtitle1"
align="center"
display="block"
>
{t('No search results found.')}
</Typography>
);
};

const useItemSearch = (items) => {
const [searchText, setSearchText] = useState('');

Expand All @@ -85,7 +105,7 @@ const useItemSearch = (items) => {
setSearchText(text.toLowerCase());
};

const searchResults = items.filter((it) =>
const results = items.filter((it) =>
it.name.toLowerCase().includes(searchText),
);

Expand All @@ -95,7 +115,7 @@ const useItemSearch = (items) => {
searchTextState={searchText}
/>
);
return { searchResults, itemSearchInput };
return { results, text: searchText, input: itemSearchInput };
};

export { useItemSearch, ItemSearchInput };
export { useItemSearch, ItemSearchInput, NoItemSearchResult };
10 changes: 5 additions & 5 deletions src/components/main/Items.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,16 @@ import ItemsTable from './ItemsTable';

const Items = ({ items, title, id }) => {
const { mode } = useContext(LayoutContext);
const { searchResults, itemSearchInput } = useItemSearch(items);
const itemSearch = useItemSearch(items);

switch (mode) {
case ITEM_LAYOUT_MODES.GRID:
return (
<ItemsGrid
id={id}
title={title}
items={searchResults}
searchInput={itemSearchInput}
items={itemSearch.results}
itemSearch={itemSearch}
/>
);
case ITEM_LAYOUT_MODES.LIST:
Expand All @@ -27,8 +27,8 @@ const Items = ({ items, title, id }) => {
<ItemsTable
id={id}
tableTitle={title}
items={searchResults}
searchInput={itemSearchInput}
items={itemSearch.results}
itemSearch={itemSearch}
/>
);
}
Expand Down
21 changes: 14 additions & 7 deletions src/components/main/ItemsGrid.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { List } from 'immutable';
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { withRouter } from 'react-router';
import { ItemSearchInput } from '../item/ItemSearch';
import { ItemSearchInput, NoItemSearchResult } from '../item/ItemSearch';
import EmptyItem from './EmptyItem';
import Item from './Item';
import TableToolbar from './TableToolbar';
Expand All @@ -29,18 +29,25 @@ class ItemsGrid extends Component {
empty: PropTypes.string.isRequired,
}).isRequired,
title: PropTypes.string.isRequired,
searchInput: PropTypes.instanceOf(ItemSearchInput),
itemSearch: PropTypes.shape({
text: PropTypes.string,
input: PropTypes.instanceOf(ItemSearchInput),
}),
};

static defaultProps = {
searchInput: null,
itemSearch: null,
};

renderItems = () => {
const { classes, items } = this.props;
const { classes, items, itemSearch } = this.props;

if (!items || !items.size) {
return (
return itemSearch && itemSearch.text ? (
<div className={classes.empty}>
<NoItemSearchResult />
</div>
) : (
<div className={classes.empty}>
<EmptyItem />
</div>
Expand All @@ -55,10 +62,10 @@ class ItemsGrid extends Component {
};

render() {
const { title, searchInput } = this.props;
const { title, itemSearch } = this.props;
return (
<div>
<TableToolbar tableTitle={title} itemSearchInput={searchInput} />
<TableToolbar tableTitle={title} itemSearchInput={itemSearch.input} />
<Grid container spacing={1}>
{this.renderItems()}
</Grid>
Expand Down
15 changes: 6 additions & 9 deletions src/components/main/ItemsTable.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,12 +82,7 @@ const computeReorderedIdList = (list, startIndex, endIndex) => {
return result.map((i) => i.id);
};

const ItemsTable = ({
items: rows,
tableTitle,
id: tableId,
searchInput: itemSearchInput,
}) => {
const ItemsTable = ({ items: rows, tableTitle, id: tableId, itemSearch }) => {
const { itemId } = useParams();
const { data: parentItem } = useItem(itemId);

Expand Down Expand Up @@ -285,7 +280,7 @@ const ItemsTable = ({
tableTitle={tableTitle}
numSelected={selected.length}
selected={selected}
itemSearchInput={itemSearchInput}
itemSearchInput={itemSearch.input}
/>
<TableContainer>
<Table
Expand Down Expand Up @@ -389,13 +384,15 @@ ItemsTable.propTypes = {
items: PropTypes.instanceOf(List),
tableTitle: PropTypes.string.isRequired,
id: PropTypes.string,
searchInput: PropTypes.instanceOf(ItemSearchInput),
itemSearch: PropTypes.shape({
input: PropTypes.instanceOf(ItemSearchInput),
}),
};

ItemsTable.defaultProps = {
id: '',
items: List(),
searchInput: null,
itemSearch: null,
};

export default ItemsTable;
1 change: 1 addition & 0 deletions src/config/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,3 +101,4 @@ export const buildItemMembershipRowDeleteButtonId = (id) =>
export const ITEM_INFORMATION_ICON_IS_OPEN_CLASS = 'itemInformationIconIsOpen';
export const ITEM_INFORMATION_BUTTON_ID = 'itemInformationButton';
export const ITEM_SEARCH_INPUT_ID = 'itemSearchInput';
export const ITEMS_GRID_NO_SEARCH_RESULT_ID = 'itemsGridNoSearchResult';
4 changes: 3 additions & 1 deletion src/langs/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@
"Profile": "Profile",
"Member ID": "Member ID",
"Size": "Size",
"Manage Access": "Manage Access"
"Manage Access": "Manage Access",
"This item is empty.": "This item is empty.",
"No search results found.": "No search results found."
}
}
4 changes: 3 additions & 1 deletion src/langs/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@
"Profile": "Profil",
"Member ID": "ID de Membre",
"Size": "Taille",
"Manage Access": "Gérer les accès"
"Manage Access": "Gérer les accès",
"This item is empty.": "Cet élément est vide.",
"No search results found.": "Aucun résultat correspondant à la recherche."
}
}

0 comments on commit 3cede4f

Please sign in to comment.