Skip to content

Commit

Permalink
components: people-browser: implement the ability to share links to f…
Browse files Browse the repository at this point in the history
…ilter configurations

Fixes #99
  • Loading branch information
tdfischer committed Oct 22, 2018
1 parent 9c87f88 commit c01f260
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 10 deletions.
21 changes: 19 additions & 2 deletions assets/js/components/PeopleIndex.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}

Expand Down Expand Up @@ -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() {
Expand Down Expand Up @@ -114,7 +131,7 @@ export class PeopleIndex extends Component {
<Tagger />
</Grid>
</Grid>
<Grid container><Grid item xs><Search filter={props.filter} /></Grid></Grid>
<Grid container><Grid item xs><Search initialFilter={this.props.initialFilter} filter={props.filter} /></Grid></Grid>
<PeopleTable />
</React.Fragment>
)
Expand Down
6 changes: 3 additions & 3 deletions assets/js/components/people-browser/BooleanFilter.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ const OperatorWidgetForField = withFieldState('property')(props => {
return (
<FormControl fullWidth>
<InputLabel>Comparison</InputLabel>
<MaterialFormSelect initialValue="is" field="op">
<MaterialFormSelect field="op">
<MenuItem value='is'>Is</MenuItem>
</MaterialFormSelect>
</FormControl>
Expand All @@ -75,7 +75,7 @@ const OperatorWidgetForField = withFieldState('property')(props => {
return (
<FormControl fullWidth>
<InputLabel>Comparison</InputLabel>
<BooleanSelect initialValue="contains" field="op"/>
<BooleanSelect field="op"/>
</FormControl>
)
}
Expand All @@ -100,7 +100,7 @@ export const BooleanFilter = props => {
<Grid item xs={3}>
<FormControl fullWidth>
<InputLabel>What</InputLabel>
<MaterialFormSelect initialValue="name" field="property">
<MaterialFormSelect field="property">
<MenuItem value="name">Name</MenuItem>
<MenuItem value="email">E-Mail</MenuItem>
<MenuItem value="geo.properties.city">City</MenuItem>
Expand Down
29 changes: 24 additions & 5 deletions assets/js/components/people-browser/Search.js
Original file line number Diff line number Diff line change
@@ -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 => (
<IconButton
<Button
color="primary"
onClick={() => {
const curFilter = props.formApi.getState().values.filter || []
props.formApi.setValues({...(props.formApi.getState().values), filter: [...curFilter, {}]})
}}>
<FontAwesomeIcon icon={['fa', 'plus-square']} />
</IconButton>
&nbsp;Add a filter
</Button>
))

const CopyButton = withFormApi(props => (
<Button
color="primary"
onClick={() => {
const curFilter = {children: props.formApi.getState().values.filter || [], op: props.formApi.getState().values.op ? 'or' : 'and'}
const encoded = btoa(JSON.stringify(curFilter))
const filterUrl = new URL(window.location)
filterUrl.searchParams.set('filter', encoded)
copy(filterUrl)
}}>
Copy link to filter
</Button>
))

export const Search = props => {
const initialFilter = (props.initialFilter || {children: [{}]}).children
const initialOp = (props.initialFilter || {op: 'and'}).op
const boolOp = initialOp == 'or'
return (
<Form initialValues={{filter: [{}]}} onChange={({values}) => props.filter.set({op: values.op ? 'or' : 'and', children: values.filter})}>
<Form initialValues={{op: boolOp, filter: (initialFilter)}} onChange={({values}) => props.filter.set({op: values.op ? 'or' : 'and', children: values.filter})}>
{({formApi}) => (
<Grid container direction="column" alignItems="stretch" spacing={8}>
<Grid item>Match All <MaterialFormSwitch field='op'/> Match Any</Grid>
Expand All @@ -33,7 +52,7 @@ export const Search = props => {
<BooleanFilter index={idx} field={'filter['+idx+']'} />
</Grid>
)}
<Grid item><AddButton /> Add a filter</Grid>
<Grid item><AddButton /> <CopyButton /></Grid>
</Grid>
)}
</Form>
Expand Down

0 comments on commit c01f260

Please sign in to comment.