From cf5e7e695d221d83b515fa41836028837fc3a4cf Mon Sep 17 00:00:00 2001 From: pkupczyk <piotr.kupczyk@id.ethz.ch> Date: Tue, 29 Jan 2019 18:43:57 +0100 Subject: [PATCH] Add in memory filtering of browsers: - SSDM-7560 : NEW openBIS UI - User/Groups - Navigation Tree - In Memory Filter - SSDM-7567 : NEW openBIS UI - Types - Navigation Tree - In Memory Filter --- openbis_ng_ui/src/components/Browser.jsx | 2 +- .../src/components/BrowserFilter.jsx | 22 ++++++++++++++++++- openbis_ng_ui/src/components/BrowserList.jsx | 1 + openbis_ng_ui/src/reducer/actions.js | 2 +- openbis_ng_ui/src/reducer/common/reducer.js | 17 ++++++++++++++ openbis_ng_ui/src/reducer/database/reducer.js | 10 +++++++-- openbis_ng_ui/src/reducer/initialstate.js | 6 +++++ openbis_ng_ui/src/reducer/types/reducer.js | 8 +++++-- openbis_ng_ui/src/reducer/users/reducer.js | 16 ++++++++++---- 9 files changed, 73 insertions(+), 11 deletions(-) diff --git a/openbis_ng_ui/src/components/Browser.jsx b/openbis_ng_ui/src/components/Browser.jsx index c707b5f9434..dfdf863a3ed 100644 --- a/openbis_ng_ui/src/components/Browser.jsx +++ b/openbis_ng_ui/src/components/Browser.jsx @@ -35,7 +35,7 @@ class Browser extends React.Component { selectedNodeId={this.props.selectedNodeId} onSelect={this.props.selectNode} renderNode={node => { - return (<ListItemText inset secondary={node.permId || node.id}/>) + return (<ListItemText inset secondary={node.text}/>) }} /> ) diff --git a/openbis_ng_ui/src/components/BrowserFilter.jsx b/openbis_ng_ui/src/components/BrowserFilter.jsx index 82abe17fdf7..93c7e1a02e7 100644 --- a/openbis_ng_ui/src/components/BrowserFilter.jsx +++ b/openbis_ng_ui/src/components/BrowserFilter.jsx @@ -1,8 +1,11 @@ import React from 'react' +import {connect} from 'react-redux' import {withStyles} from '@material-ui/core/styles' import InputAdornment from '@material-ui/core/InputAdornment' import TextField from '@material-ui/core/TextField' import FilterIcon from '@material-ui/icons/FilterList' +import actions from '../reducer/actions' +import {getTabState} from '../reducer/selectors' /*eslint-disable-next-line no-unused-vars*/ const styles = theme => ({ @@ -11,6 +14,21 @@ const styles = theme => ({ } }) +function mapDispatchToProps(dispatch) { + return { + setFilter: filter => { + dispatch(actions.setFilter(filter)) + } + } +} + +function mapStateToProps(state) { + let tabState = getTabState(state) + return { + filter: tabState.browser.filter + } +} + class BrowserFilter extends React.Component { render() { @@ -20,6 +38,8 @@ class BrowserFilter extends React.Component { <TextField className={classes.browserFilter} placeholder="Filter" + value={this.props.filter} + onChange={e => this.props.setFilter(e.target.value)} InputProps={{ startAdornment: ( <InputAdornment position="start"> @@ -31,4 +51,4 @@ class BrowserFilter extends React.Component { } } -export default withStyles(styles)(BrowserFilter) +export default connect(mapStateToProps, mapDispatchToProps)(withStyles(styles)(BrowserFilter)) diff --git a/openbis_ng_ui/src/components/BrowserList.jsx b/openbis_ng_ui/src/components/BrowserList.jsx index 9afd304aa81..422fba3dd83 100644 --- a/openbis_ng_ui/src/components/BrowserList.jsx +++ b/openbis_ng_ui/src/components/BrowserList.jsx @@ -55,6 +55,7 @@ class BrowserList extends React.Component { <List className={classes.noPadding}> { this.props.nodes.map(node => + (!node.filterable || node.filtered) && <div key={node.id}> <ListItem button diff --git a/openbis_ng_ui/src/reducer/actions.js b/openbis_ng_ui/src/reducer/actions.js index 9a6837a2945..c41597f6bd8 100644 --- a/openbis_ng_ui/src/reducer/actions.js +++ b/openbis_ng_ui/src/reducer/actions.js @@ -46,7 +46,7 @@ export default { }), setFilter: filter => ({ type: 'SET-FILTER', - value: filter + filter: filter }), setMode: mode => ({ type: 'SET-MODE', diff --git a/openbis_ng_ui/src/reducer/common/reducer.js b/openbis_ng_ui/src/reducer/common/reducer.js index 69cca8d92c7..3b02cced47c 100644 --- a/openbis_ng_ui/src/reducer/common/reducer.js +++ b/openbis_ng_ui/src/reducer/common/reducer.js @@ -81,12 +81,28 @@ export function browserCollapseNode(browser, action) { return newBrowser } +export function browserSetFilter(browser, action) { + let newBrowser = _.cloneDeep(browser) + newBrowser.filter = action.filter + visitNodes(newBrowser.nodes, node => { + if (action.filter === null || action.filter.trim() === '') { + node.filtered = true + } else { + node.filtered = node.text.toLowerCase().indexOf(action.filter.toLowerCase()) !== -1 + } + }) + return newBrowser +} + export function emptyTreeNode(values = {}) { return _.merge({ id: null, permId: null, type: null, + text: null, selectable: false, + filterable: false, + filtered: true, expanded: false, loading: false, loaded: false, @@ -98,6 +114,7 @@ export function entityTreeNode(entity, values = {}) { return _.merge(emptyTreeNode(), { id: entity['@type'] + '#' + entity.permId.permId, permId: entity.permId.permId, + text: entity.permId.permId, type: entity['@type'], }, values) } diff --git a/openbis_ng_ui/src/reducer/database/reducer.js b/openbis_ng_ui/src/reducer/database/reducer.js index b0eab779112..2578d2292c6 100644 --- a/openbis_ng_ui/src/reducer/database/reducer.js +++ b/openbis_ng_ui/src/reducer/database/reducer.js @@ -1,6 +1,6 @@ import initialState from '../initialstate.js' import merge from 'lodash/merge' -import {openEntities, dirtyEntities, entityTreeNode} from '../common/reducer.js' +import {openEntities, dirtyEntities, entityTreeNode, browserSetFilter} from '../common/reducer.js' function filterOf(filter, columns) { if (filter == null || filter.length === 0) { @@ -152,7 +152,8 @@ function browser(browser = initialState.database.browser, action) { switch (action.type) { case 'SET-SPACES': { return { - nodes: action.spaces.map(space => entityTreeNode(space, {selectable: true})) + filter: browser.filter, + nodes: action.spaces.map(space => entityTreeNode(space, {selectable: true, filterable: true})) } } case 'SET-PROJECTS': { @@ -160,19 +161,24 @@ function browser(browser = initialState.database.browser, action) { const projectNodes = action.projects.map(project => entityTreeNode(project, {loaded: true})) const node = merge({}, oldNode, {loading: false, loaded: true, children: projectNodes}) return { + filter: browser.filter, nodes: replaceNode(browser.nodes, node) } } + case 'SET-FILTER': + return browserSetFilter(browser, action) case 'EXPAND-NODE': { const loading = action.node.loaded === false const node = merge({}, action.node, {expanded: true, loading: loading}) return { + filter: browser.filter, nodes: replaceNode(browser.nodes, node) } } case 'COLLAPSE-NODE': { const node = merge({}, action.node, {expanded: false}) return { + filter: browser.filter, nodes: replaceNode(browser.nodes, node) } } diff --git a/openbis_ng_ui/src/reducer/initialstate.js b/openbis_ng_ui/src/reducer/initialstate.js index 51d4acf0c4d..ee3d0a84049 100644 --- a/openbis_ng_ui/src/reducer/initialstate.js +++ b/openbis_ng_ui/src/reducer/initialstate.js @@ -57,6 +57,8 @@ export default { sortDirection: 'asc' }, browser: { + loaded: false, + filter: '', nodes: [] }, openEntities: { @@ -68,6 +70,8 @@ export default { types: { browser: { + loaded: false, + filter: '', nodes: [] }, openEntities: { @@ -78,6 +82,8 @@ export default { users: { browser: { + loaded: false, + filter: '', nodes: [] }, openEntities: { diff --git a/openbis_ng_ui/src/reducer/types/reducer.js b/openbis_ng_ui/src/reducer/types/reducer.js index 236ebdfbef3..67d1f22d8ec 100644 --- a/openbis_ng_ui/src/reducer/types/reducer.js +++ b/openbis_ng_ui/src/reducer/types/reducer.js @@ -2,6 +2,7 @@ import initialState from '../initialstate.js' import { browserExpandNode, browserCollapseNode, + browserSetFilter, openEntities, dirtyEntities, sortBy, @@ -21,6 +22,8 @@ function browser(browser = initialState.types.browser, action) { switch (action.type) { case 'SET-MODE-DONE': return browserSetModeDone(browser, action) + case 'SET-FILTER': + return browserSetFilter(browser, action) case 'EXPAND-NODE': return browserExpandNode(browser, action) case 'COLLAPSE-NODE': @@ -34,6 +37,7 @@ function browserSetModeDone(browser, action) { if (action.data) { return { loaded: true, + filter: '', nodes: [ browserSetModeDoneTypeNodes('Object Types', action.data.objectTypes), browserSetModeDoneTypeNodes('Collection Types', action.data.collectionTypes), @@ -50,10 +54,10 @@ function browserSetModeDoneTypeNodes(groupId, types) { let typeNodes = [] types.forEach(type => { - typeNodes.push(entityTreeNode(type, {loaded: true, selectable: true})) + typeNodes.push(entityTreeNode(type, {loaded: true, selectable: true, filterable: true})) }) sortBy(typeNodes, 'permId') - return emptyTreeNode({id: groupId, loaded: true, children: typeNodes}) + return emptyTreeNode({id: groupId, text: groupId, loaded: true, children: typeNodes}) } \ No newline at end of file diff --git a/openbis_ng_ui/src/reducer/users/reducer.js b/openbis_ng_ui/src/reducer/users/reducer.js index 50f10b718bb..1e92590e3c1 100644 --- a/openbis_ng_ui/src/reducer/users/reducer.js +++ b/openbis_ng_ui/src/reducer/users/reducer.js @@ -2,12 +2,14 @@ import initialState from '../initialstate.js' import { browserExpandNode, browserCollapseNode, + browserSetFilter, sortBy, openEntities, dirtyEntities, emptyTreeNode, entityTreeNode } from '../common/reducer' +import _ from 'lodash' export default function users(users = initialState.users, action) { return { @@ -21,6 +23,8 @@ function browser(browser = initialState.users.browser, action) { switch (action.type) { case 'SET-MODE-DONE': return browserSetModeDone(browser, action) + case 'SET-FILTER': + return browserSetFilter(browser, action) case 'EXPAND-NODE': return browserExpandNode(browser, action) case 'COLLAPSE-NODE': @@ -34,6 +38,7 @@ function browserSetModeDone(browser, action) { if (action.data) { return { loaded: true, + filter: '', nodes: [browserSetModeDoneUserNodes(action.data.users, action.data.groups), browserSetModeDoneGroupNodes(action.data.groups)] } } else { @@ -58,18 +63,19 @@ function browserSetModeDoneUserNodes(users, groups) { let groupNodes = [] userGroups.forEach(group => { - groupNodes.push(entityTreeNode(group, {loaded: true, selectable: true})) + groupNodes.push(entityTreeNode(group, {loaded: true, selectable: true, filterable: true})) }) sortBy(groupNodes, 'permId') - userNodes.push(entityTreeNode(user, {loaded: true, selectable: true, children: groupNodes})) + userNodes.push(entityTreeNode(user, {loaded: true, selectable: true, filterable: true, children: groupNodes})) }) sortBy(userNodes, 'permId') return emptyTreeNode({ id: 'Users', + text: 'Users', loaded: true, children: userNodes }) @@ -82,20 +88,22 @@ function browserSetModeDoneGroupNodes(groups) { let userNodes = [] group.getUsers().forEach(user => { - userNodes.push(entityTreeNode(user, {loaded: true, selectable: true})) + userNodes.push(entityTreeNode(user, {loaded: true, selectable: true, filterable: true})) }) sortBy(userNodes, 'permId') - groupNodes.push(entityTreeNode(group, {loaded: true, selectable: true, children: userNodes})) + groupNodes.push(entityTreeNode(group, {loaded: true, selectable: true, filterable: true, children: userNodes})) }) sortBy(groupNodes, 'permId') return emptyTreeNode({ id: 'Groups', + text: 'Groups', loaded: true, children: groupNodes }) } + -- GitLab