From 322f9e08f45fe5ec19bd4d0f1a6b3a9430a1e554 Mon Sep 17 00:00:00 2001 From: Torrie Fischer Date: Sun, 21 Oct 2018 14:17:56 -0700 Subject: [PATCH 1/3] store: filter: allow getting the filter --- assets/js/store/filter.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/assets/js/store/filter.js b/assets/js/store/filter.js index 13d7f060..143160b2 100644 --- a/assets/js/store/filter.js +++ b/assets/js/store/filter.js @@ -21,6 +21,10 @@ export default class Filterable { return values.filter(value => this.matcher(value, filterConfig)) } + getFilter(state) { + return state.getIn(['filters', 'filters', this.key]) + } + bindActionCreators(dispatch) { return { set: f => dispatch(setFilter(this.key, f)) From e4f06943b3f70b3baf722ad7a033f237c414b216 Mon Sep 17 00:00:00 2001 From: Torrie Fischer Date: Sun, 21 Oct 2018 14:21:38 -0700 Subject: [PATCH 2/3] components: people-browser: implement the ability to share links to filter configurations Fixes #99 --- assets/js/components/PeopleIndex.js | 21 ++++++++++++-- .../people-browser/BooleanFilter.js | 6 ++-- assets/js/components/people-browser/Search.js | 29 +++++++++++++++---- 3 files changed, 46 insertions(+), 10 deletions(-) diff --git a/assets/js/components/PeopleIndex.js b/assets/js/components/PeopleIndex.js index f523b0ba..580c146e 100644 --- a/assets/js/components/PeopleIndex.js +++ b/assets/js/components/PeopleIndex.js @@ -21,10 +21,24 @@ const People = new Model('people') const PeopleSelector = new Selectable('people') const PeopleFilter = new Filterable('people') +function getUrlFilter(state) { + const url = new URL(state.getIn(['router', 'location', 'search'], ''), window.location) + const decoded = atob(url.searchParams.get('filter', undefined)) + try { + return JSON.parse(decoded) + } catch (_e) { + return undefined + } +} + const mapStateToProps = state => { const selection = PeopleSelector.immutableSelected(state) + const storeFilter = PeopleFilter.getFilter(state) + const urlFilter = getUrlFilter(state) return { selection, + urlFilter, + initialFilter: urlFilter ? urlFilter : storeFilter } } @@ -83,9 +97,12 @@ export class PeopleIndex extends Component { super(props) this.state = { currentState: 0, - copied: false + copied: false, } this.onCopy = this.onCopy.bind(this) + if (this.props.urlFilter) { + this.props.filter.set(this.props.urlFilter) + } } onCopy() { @@ -114,7 +131,7 @@ export class PeopleIndex extends Component { - + ) diff --git a/assets/js/components/people-browser/BooleanFilter.js b/assets/js/components/people-browser/BooleanFilter.js index b0d37f11..ab567e3c 100644 --- a/assets/js/components/people-browser/BooleanFilter.js +++ b/assets/js/components/people-browser/BooleanFilter.js @@ -53,7 +53,7 @@ const OperatorWidgetForField = withFieldState('property')(props => { return ( Comparison - + Is @@ -75,7 +75,7 @@ const OperatorWidgetForField = withFieldState('property')(props => { return ( Comparison - + ) } @@ -100,7 +100,7 @@ export const BooleanFilter = props => { What - + Name E-Mail City diff --git a/assets/js/components/people-browser/Search.js b/assets/js/components/people-browser/Search.js index 38cf910b..c5f7ece6 100644 --- a/assets/js/components/people-browser/Search.js +++ b/assets/js/components/people-browser/Search.js @@ -1,30 +1,49 @@ import React from 'react' import Grid from '@material-ui/core/Grid' -import IconButton from '@material-ui/core/IconButton' +import Button from '@material-ui/core/Button' import { Form, withFormApi } from 'informed' import faPlusSquare from '@fortawesome/fontawesome-free-solid/faPlusSquare' import { library as faLibrary } from '@fortawesome/fontawesome' import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' import MaterialFormSwitch from '../MaterialFormSwitch' +import copy from 'copy-to-clipboard' faLibrary.add(faPlusSquare) import BooleanFilter from './BooleanFilter' const AddButton = withFormApi(props => ( - { const curFilter = props.formApi.getState().values.filter || [] props.formApi.setValues({...(props.formApi.getState().values), filter: [...curFilter, {}]}) }}> - +  Add a filter + +)) + +const CopyButton = withFormApi(props => ( + )) export const Search = props => { + const initialFilter = (props.initialFilter || {children: [{}]}).children + const initialOp = (props.initialFilter || {op: 'and'}).op + const boolOp = initialOp == 'or' return ( -
props.filter.set({op: values.op ? 'or' : 'and', children: values.filter})}> + props.filter.set({op: values.op ? 'or' : 'and', children: values.filter})}> {({formApi}) => ( Match All Match Any @@ -33,7 +52,7 @@ export const Search = props => { )} - Add a filter + )}
From 07b844cfbbb7cd9d048dd67f32ecfe3cb40aac04 Mon Sep 17 00:00:00 2001 From: Torrie Fischer Date: Sun, 21 Oct 2018 14:40:52 -0700 Subject: [PATCH 3/3] components: people-browser: store filter state between pages Fixes #96 --- assets/js/components/PeopleIndex.js | 7 ++++++- assets/js/components/people-browser/Search.js | 9 ++++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/assets/js/components/PeopleIndex.js b/assets/js/components/PeopleIndex.js index 580c146e..92c138b5 100644 --- a/assets/js/components/PeopleIndex.js +++ b/assets/js/components/PeopleIndex.js @@ -100,6 +100,7 @@ export class PeopleIndex extends Component { copied: false, } this.onCopy = this.onCopy.bind(this) + this.onFilterChange = this.onFilterChange.bind(this) if (this.props.urlFilter) { this.props.filter.set(this.props.urlFilter) } @@ -110,6 +111,10 @@ export class PeopleIndex extends Component { copy(this.props.selection.join(', ')) } + onFilterChange(filter) { + this.props.filter.set(filter) + } + render() { const props = this.props return ( @@ -131,7 +136,7 @@ export class PeopleIndex extends Component {
- + ) diff --git a/assets/js/components/people-browser/Search.js b/assets/js/components/people-browser/Search.js index c5f7ece6..bc5f1c47 100644 --- a/assets/js/components/people-browser/Search.js +++ b/assets/js/components/people-browser/Search.js @@ -43,7 +43,14 @@ export const Search = props => { const initialOp = (props.initialFilter || {op: 'and'}).op const boolOp = initialOp == 'or' return ( -
props.filter.set({op: values.op ? 'or' : 'and', children: values.filter})}> + { + if (values.filter && values.filter[0]) { + props.onFilterChange({ + op: values.op ? 'or' : 'and', + children: values.filter + }) + } + }}> {({formApi}) => ( Match All Match Any