diff --git a/src/components/item/ItemSearch.js b/src/components/item/ItemSearch.js
new file mode 100644
index 000000000..db6ac8188
--- /dev/null
+++ b/src/components/item/ItemSearch.js
@@ -0,0 +1,99 @@
+import OutlinedInput from '@material-ui/core/OutlinedInput';
+import { makeStyles } from '@material-ui/core/styles';
+import SearchIcon from '@material-ui/icons/Search';
+import PropTypes from 'prop-types';
+import React, { useState } from 'react';
+
+const useSearchStyles = makeStyles((theme) => ({
+ search: {
+ position: 'relative',
+ borderRadius: theme.shape.borderRadius,
+ marginLeft: 0,
+ width: '100%',
+ [theme.breakpoints.up('sm')]: {
+ marginLeft: theme.spacing(1),
+ width: 'auto',
+ },
+ },
+ searchIcon: {
+ padding: theme.spacing(0, 2),
+ height: '100%',
+ position: 'absolute',
+ pointerEvents: 'none',
+ display: 'flex',
+ alignItems: 'center',
+ justifyContent: 'center',
+ },
+ inputRoot: {
+ color: 'inherit',
+ },
+ inputInput: {
+ padding: theme.spacing(1, 1, 1, 0),
+ // vertical padding + font size from searchIcon
+ paddingLeft: `calc(1em + ${theme.spacing(4)}px)`,
+ transition: theme.transitions.create('width'),
+ width: '100%',
+ [theme.breakpoints.up('sm')]: {
+ width: '12ch',
+ '&:focus': {
+ width: '20ch',
+ },
+ },
+ },
+}));
+
+const ItemSearchInput = (props) => {
+ const { searchInputHandler, searchTextState } = props;
+ const classes = useSearchStyles();
+
+ return (
+
+ );
+};
+
+ItemSearchInput.propTypes = {
+ searchInputHandler: PropTypes.func,
+ searchTextState: PropTypes.string,
+};
+
+ItemSearchInput.defaultProps = {
+ searchInputHandler: () => {},
+ searchTextState: '',
+};
+
+const useItemSearch = (items) => {
+ const [searchText, setSearchText] = useState('');
+
+ const handleSearchInput = (event) => {
+ const text = event.target.value;
+ setSearchText(text.toLowerCase());
+ };
+
+ const searchResults = items.filter((it) =>
+ it.name.toLowerCase().includes(searchText),
+ );
+
+ const itemSearchInput = (
+
+ );
+ return { searchResults, itemSearchInput };
+};
+
+export { useItemSearch, ItemSearchInput };
diff --git a/src/components/main/Items.js b/src/components/main/Items.js
index fb2116fc6..e5598570c 100644
--- a/src/components/main/Items.js
+++ b/src/components/main/Items.js
@@ -1,20 +1,36 @@
-import React, { useContext } from 'react';
import { List } from 'immutable';
import PropTypes from 'prop-types';
+import React, { useContext } from 'react';
import { ITEM_LAYOUT_MODES } from '../../enums';
-import ItemsTable from './ItemsTable';
-import ItemsGrid from './ItemsGrid';
import { LayoutContext } from '../context/LayoutContext';
+import { useItemSearch } from '../item/ItemSearch';
+import ItemsGrid from './ItemsGrid';
+import ItemsTable from './ItemsTable';
const Items = ({ items, title, id }) => {
const { mode } = useContext(LayoutContext);
+ const { searchResults, itemSearchInput } = useItemSearch(items);
switch (mode) {
case ITEM_LAYOUT_MODES.GRID:
- return ;
+ return (
+
+ );
case ITEM_LAYOUT_MODES.LIST:
default:
- return ;
+ return (
+
+ );
}
};
diff --git a/src/components/main/ItemsGrid.js b/src/components/main/ItemsGrid.js
index b4cffc426..8936319fd 100644
--- a/src/components/main/ItemsGrid.js
+++ b/src/components/main/ItemsGrid.js
@@ -1,21 +1,23 @@
-import React, { Component } from 'react';
+import Grid from '@material-ui/core/Grid';
+import { withStyles } from '@material-ui/core/styles';
import { List } from 'immutable';
import PropTypes from 'prop-types';
+import React, { Component } from 'react';
import { withRouter } from 'react-router';
-import { withStyles } from '@material-ui/core/styles';
-import Typography from '@material-ui/core/Typography';
-import Grid from '@material-ui/core/Grid';
-import NewItemButton from './NewItemButton';
-import Item from './Item';
+import { ItemSearchInput } from '../item/ItemSearch';
import EmptyItem from './EmptyItem';
+import Item from './Item';
+import TableToolbar from './TableToolbar';
const styles = (theme) => ({
+ empty: { padding: '5px 20px' },
title: {
display: 'flex',
alignItems: 'center',
marginBottom: theme.spacing(1),
},
});
+
class ItemsGrid extends Component {
static propTypes = {
items: PropTypes.instanceOf(List).isRequired,
@@ -24,15 +26,25 @@ class ItemsGrid extends Component {
}).isRequired,
classes: PropTypes.shape({
title: PropTypes.string.isRequired,
+ empty: PropTypes.string.isRequired,
}).isRequired,
title: PropTypes.string.isRequired,
+ searchInput: PropTypes.instanceOf(ItemSearchInput),
+ };
+
+ static defaultProps = {
+ searchInput: null,
};
renderItems = () => {
- const { items } = this.props;
+ const { classes, items } = this.props;
if (!items || !items.size) {
- return ;
+ return (
+
+
+
+ );
}
return items.map((item) => (
@@ -43,17 +55,14 @@ class ItemsGrid extends Component {
};
render() {
- const { classes, title } = this.props;
+ const { title, searchInput } = this.props;
return (
- <>
-
- {title}
-
-
+
+
{this.renderItems()}
- >
+
);
}
}
diff --git a/src/components/main/ItemsTable.js b/src/components/main/ItemsTable.js
index 0b3810f26..34c4342d3 100644
--- a/src/components/main/ItemsTable.js
+++ b/src/components/main/ItemsTable.js
@@ -1,41 +1,42 @@
-import React, { useEffect } from 'react';
-import PropTypes from 'prop-types';
-import { List } from 'immutable';
+import { MUTATION_KEYS } from '@graasp/query-client';
+import Checkbox from '@material-ui/core/Checkbox';
+import Paper from '@material-ui/core/Paper';
import { lighten, makeStyles } from '@material-ui/core/styles';
import Table from '@material-ui/core/Table';
-import { useHistory, useParams } from 'react-router';
-import { useTranslation } from 'react-i18next';
import TableBody from '@material-ui/core/TableBody';
import TableCell from '@material-ui/core/TableCell';
import TableContainer from '@material-ui/core/TableContainer';
import TablePagination from '@material-ui/core/TablePagination';
import TableRow from '@material-ui/core/TableRow';
-import Paper from '@material-ui/core/Paper';
-import Checkbox from '@material-ui/core/Checkbox';
-import { MUTATION_KEYS } from '@graasp/query-client';
-import ItemMenu from './ItemMenu';
+import { List } from 'immutable';
+import PropTypes from 'prop-types';
+import React, { useEffect } from 'react';
+import { useTranslation } from 'react-i18next';
+import { useHistory, useParams } from 'react-router';
+import { ROWS_PER_PAGE_OPTIONS, USER_ITEM_ORDER } from '../../config/constants';
import { buildItemPath } from '../../config/paths';
-import { ORDERING, ITEM_DATA_TYPES, ITEM_TYPES } from '../../enums';
-import { getComparator, stableSort, getRowsForPage } from '../../utils/table';
-import { formatDate } from '../../utils/date';
-import EditButton from '../common/EditButton';
-import ShareButton from '../common/ShareButton';
-import DeleteButton from '../common/DeleteButton';
+import { hooks, useMutation } from '../../config/queryClient';
import {
buildItemsTableRowId,
ITEMS_TABLE_BODY,
ITEMS_TABLE_EMPTY_ROW_ID,
ITEMS_TABLE_ROW_CHECKBOX_CLASS,
} from '../../config/selectors';
-import TableToolbar from './TableToolbar';
-import TableHead from './TableHead';
-import ItemIcon from './ItemIcon';
+import { ITEM_DATA_TYPES, ITEM_TYPES, ORDERING } from '../../enums';
+import { formatDate } from '../../utils/date';
+import { getChildrenOrderFromFolderExtra } from '../../utils/item';
import { getShortcutTarget } from '../../utils/itemExtra';
-import { ROWS_PER_PAGE_OPTIONS, USER_ITEM_ORDER } from '../../config/constants';
-import DroppableTableBody from '../common/DroppableTableBody';
+import { getComparator, getRowsForPage, stableSort } from '../../utils/table';
+import DeleteButton from '../common/DeleteButton';
import DraggableTableRow from '../common/DraggableTableRow';
-import { hooks, useMutation } from '../../config/queryClient';
-import { getChildrenOrderFromFolderExtra } from '../../utils/item';
+import DroppableTableBody from '../common/DroppableTableBody';
+import EditButton from '../common/EditButton';
+import ShareButton from '../common/ShareButton';
+import { ItemSearchInput } from '../item/ItemSearch';
+import ItemIcon from './ItemIcon';
+import ItemMenu from './ItemMenu';
+import TableHead from './TableHead';
+import TableToolbar from './TableToolbar';
const { useItem } = hooks;
@@ -81,7 +82,12 @@ const computeReorderedIdList = (list, startIndex, endIndex) => {
return result.map((i) => i.id);
};
-const ItemsTable = ({ items: rows, tableTitle, id: tableId }) => {
+const ItemsTable = ({
+ items: rows,
+ tableTitle,
+ id: tableId,
+ searchInput: itemSearchInput,
+}) => {
const { itemId } = useParams();
const { data: parentItem } = useItem(itemId);
@@ -279,6 +285,7 @@ const ItemsTable = ({ items: rows, tableTitle, id: tableId }) => {
tableTitle={tableTitle}
numSelected={selected.length}
selected={selected}
+ itemSearchInput={itemSearchInput}
/>
({
root: {
@@ -28,7 +29,7 @@ const useToolbarStyles = makeStyles((theme) => ({
const TableToolbar = (props) => {
const classes = useToolbarStyles();
const { t } = useTranslation();
- const { numSelected, tableTitle, selected } = props;
+ const { numSelected, tableTitle, selected, itemSearchInput } = props;
return (
{
)}
+ {itemSearchInput}
+
{numSelected > 0 ? (