diff --git a/client/modules/IDE/actions/sorting.js b/client/modules/IDE/actions/sorting.js index 8feb9b12..f28cf325 100644 --- a/client/modules/IDE/actions/sorting.js +++ b/client/modules/IDE/actions/sorting.js @@ -26,13 +26,14 @@ export function toggleDirectionForField(field) { }; } -export function setSearchTerm(searchTerm) { +export function setSearchTerm(scope, searchTerm) { return { type: ActionTypes.SET_SEARCH_TERM, - query: searchTerm + query: searchTerm, + scope, }; } -export function resetSearchTerm() { - return setSearchTerm(''); +export function resetSearchTerm(scope) { + return setSearchTerm(scope, ''); } diff --git a/client/modules/IDE/components/Searchbar/Collection.jsx b/client/modules/IDE/components/Searchbar/Collection.jsx new file mode 100644 index 00000000..c566ced2 --- /dev/null +++ b/client/modules/IDE/components/Searchbar/Collection.jsx @@ -0,0 +1,24 @@ +import { bindActionCreators } from 'redux'; +import { connect } from 'react-redux'; +import * as SortingActions from '../../actions/sorting'; + +import Searchbar from './Searchbar'; + +const scope = 'collection'; + +function mapStateToProps(state) { + return { + searchLabel: 'Search collections...', + searchTerm: state.search[`${scope}SearchTerm`], + }; +} + +function mapDispatchToProps(dispatch) { + const actions = { + setSearchTerm: term => SortingActions.setSearchTerm(scope, term), + resetSearchTerm: () => SortingActions.resetSearchTerm(scope), + }; + return bindActionCreators(Object.assign({}, actions), dispatch); +} + +export default connect(mapStateToProps, mapDispatchToProps)(Searchbar); diff --git a/client/modules/IDE/components/Searchbar.jsx b/client/modules/IDE/components/Searchbar/Searchbar.jsx similarity index 78% rename from client/modules/IDE/components/Searchbar.jsx rename to client/modules/IDE/components/Searchbar/Searchbar.jsx index 02de9e1b..2a926c4e 100644 --- a/client/modules/IDE/components/Searchbar.jsx +++ b/client/modules/IDE/components/Searchbar/Searchbar.jsx @@ -1,14 +1,11 @@ import PropTypes from 'prop-types'; import React from 'react'; import InlineSVG from 'react-inlinesvg'; -import { bindActionCreators } from 'redux'; -import { connect } from 'react-redux'; import { throttle } from 'lodash'; -import * as SortingActions from '../actions/sorting'; -const searchIcon = require('../../../images/magnifyingglass.svg'); +const searchIcon = require('../../../../images/magnifyingglass.svg'); -export class Searchbar extends React.Component { +class Searchbar extends React.Component { constructor(props) { super(props); this.state = { @@ -83,15 +80,4 @@ Searchbar.defaultProps = { searchLabel: 'Search sketches...', }; - -function mapStateToProps(state) { - return { - searchTerm: state.search.searchTerm - }; -} - -function mapDispatchToProps(dispatch) { - return bindActionCreators(Object.assign({}, SortingActions), dispatch); -} - -export default connect(mapStateToProps, mapDispatchToProps)(Searchbar); +export default Searchbar; diff --git a/client/modules/IDE/components/Searchbar/Sketch.jsx b/client/modules/IDE/components/Searchbar/Sketch.jsx new file mode 100644 index 00000000..bc12854e --- /dev/null +++ b/client/modules/IDE/components/Searchbar/Sketch.jsx @@ -0,0 +1,23 @@ +import { bindActionCreators } from 'redux'; +import { connect } from 'react-redux'; +import * as SortingActions from '../../actions/sorting'; + +import Searchbar from './Searchbar'; + +const scope = 'sketch'; + +function mapStateToProps(state) { + return { + searchTerm: state.search[`${scope}SearchTerm`], + }; +} + +function mapDispatchToProps(dispatch) { + const actions = { + setSearchTerm: term => SortingActions.setSearchTerm(scope, term), + resetSearchTerm: () => SortingActions.resetSearchTerm(scope), + }; + return bindActionCreators(Object.assign({}, actions), dispatch); +} + +export default connect(mapStateToProps, mapDispatchToProps)(Searchbar); diff --git a/client/modules/IDE/components/Searchbar/index.js b/client/modules/IDE/components/Searchbar/index.js new file mode 100644 index 00000000..3a063f68 --- /dev/null +++ b/client/modules/IDE/components/Searchbar/index.js @@ -0,0 +1,2 @@ +export { default as CollectionSearchbar } from './Collection.jsx'; +export { default as SketchSearchbar } from './Sketch.jsx'; diff --git a/client/modules/IDE/pages/IDEView.jsx b/client/modules/IDE/pages/IDEView.jsx index e7447eff..eb698b22 100644 --- a/client/modules/IDE/pages/IDEView.jsx +++ b/client/modules/IDE/pages/IDEView.jsx @@ -32,6 +32,7 @@ import Overlay from '../../App/components/Overlay'; import About from '../components/About'; import CollectionList from '../components/AddToCollectionList'; import Feedback from '../components/Feedback'; +import { CollectionSearchbar } from '../components/Searchbar'; class IDEView extends React.Component { constructor(props) { @@ -390,6 +391,7 @@ class IDEView extends React.Component { ariaLabel="add to collection" title="Add sketch to collection" previousPath={this.props.ide.previousPath} + actions={} > { switch (action.type) { case ActionTypes.SET_SEARCH_TERM: - return { ...state, searchTerm: action.query }; + return { ...state, [`${action.scope}SearchTerm`]: action.query }; default: return state; } diff --git a/client/modules/IDE/selectors/collections.js b/client/modules/IDE/selectors/collections.js index 3ba90241..f212103a 100644 --- a/client/modules/IDE/selectors/collections.js +++ b/client/modules/IDE/selectors/collections.js @@ -7,9 +7,28 @@ import { DIRECTION } from '../actions/sorting'; const getCollections = state => state.collections; const getField = state => state.sorting.field; const getDirection = state => state.sorting.direction; +const getSearchTerm = state => state.search.collectionSearchTerm; + +const getFilteredCollections = createSelector( + getCollections, + getSearchTerm, + (collections, search) => { + if (search) { + const searchStrings = collections.map((collection) => { + const smallCollection = { + name: collection.name + }; + return { ...collection, searchString: Object.values(smallCollection).join(' ').toLowerCase() }; + }); + return searchStrings.filter(collection => collection.searchString.includes(search.toLowerCase())); + } + return collections; + } +); + const getSortedCollections = createSelector( - getCollections, + getFilteredCollections, getField, getDirection, (collections, field, direction) => { diff --git a/client/modules/IDE/selectors/projects.js b/client/modules/IDE/selectors/projects.js index b2230826..14d65ea0 100644 --- a/client/modules/IDE/selectors/projects.js +++ b/client/modules/IDE/selectors/projects.js @@ -6,7 +6,7 @@ import { DIRECTION } from '../actions/sorting'; const getSketches = state => state.sketches; const getField = state => state.sorting.field; const getDirection = state => state.sorting.direction; -const getSearchTerm = state => state.search.searchTerm; +const getSearchTerm = state => state.search.sketchSearchTerm; const getFilteredSketches = createSelector( getSketches, diff --git a/client/modules/User/components/Collection.jsx b/client/modules/User/components/Collection.jsx index 31858181..a7efcbe6 100644 --- a/client/modules/User/components/Collection.jsx +++ b/client/modules/User/components/Collection.jsx @@ -19,7 +19,7 @@ import EditableInput from '../../IDE/components/EditableInput'; import Overlay from '../../App/components/Overlay'; import SketchList from '../../IDE/components/AddToCollectionSketchList'; import CopyableInput from '../../IDE/components/CopyableInput'; -import SketchSearchbar from '../../IDE/components/Searchbar'; +import { SketchSearchbar } from '../../IDE/components/Searchbar'; const arrowUp = require('../../../images/sort-arrow-up.svg'); const arrowDown = require('../../../images/sort-arrow-down.svg'); diff --git a/client/modules/User/pages/DashboardView.jsx b/client/modules/User/pages/DashboardView.jsx index 8a3e68a4..af9c8752 100644 --- a/client/modules/User/pages/DashboardView.jsx +++ b/client/modules/User/pages/DashboardView.jsx @@ -11,7 +11,7 @@ import AssetList from '../../IDE/components/AssetList'; import AssetSize from '../../IDE/components/AssetSize'; import CollectionList from '../../IDE/components/CollectionList'; import SketchList from '../../IDE/components/SketchList'; -import SketchSearchbar from '../../IDE/components/Searchbar'; +import { CollectionSearchbar, SketchSearchbar } from '../../IDE/components/Searchbar'; import CollectionCreate from '../components/CollectionCreate'; import DashboardTabSwitcher, { TabKey } from '../components/DashboardTabSwitcher'; @@ -77,7 +77,13 @@ class DashboardView extends React.Component { case TabKey.assets: return this.isOwner() && ; case TabKey.collections: - return this.isOwner() && Create collection; + return this.isOwner() && ( + + + + Create collection + + ); case TabKey.sketches: default: return (