Split filter editor into component per file

This commit is contained in:
Lukas Martinelli 2017-01-09 18:56:04 +01:00
parent b72f86a78d
commit 7e8813f417
5 changed files with 99 additions and 85 deletions

View file

@ -3,6 +3,7 @@ import SelectInput from '../inputs/SelectInput'
import input from '../../config/input.js' import input from '../../config/input.js'
import { margins } from '../../config/scales.js' import { margins } from '../../config/scales.js'
import { combiningFilterOps } from '../../libs/filterops.js'
class CombiningOperatorSelect extends React.Component { class CombiningOperatorSelect extends React.Component {
static propTypes = { static propTypes = {
@ -18,7 +19,7 @@ class CombiningOperatorSelect extends React.Component {
}}> }}>
<SelectInput <SelectInput
value={this.props.value} value={this.props.value}
options={['all', 'any', 'none']} options={combiningFilterOps}
onChange={this.props.onChange} onChange={this.props.onChange}
style={{ style={{
display: 'block', display: 'block',

View file

@ -4,24 +4,17 @@ import GlSpec from 'mapbox-gl-style-spec/reference/latest.js'
import input from '../../config/input.js' import input from '../../config/input.js'
import colors from '../../config/colors.js' import colors from '../../config/colors.js'
import { margins, fontSizes } from '../../config/scales.js' import { margins, fontSizes } from '../../config/scales.js'
import { combiningFilterOps } from '../../libs/filterops.js'
import OperatorSelect from './OperatorSelect'
import SingleFilterEditor from './SingleFilterEditor'
import CombiningOperatorSelect from './CombiningOperatorSelect' import CombiningOperatorSelect from './CombiningOperatorSelect'
import DocLabel from '../fields/DocLabel' import DocLabel from '../fields/DocLabel'
import Button from '../Button' import Button from '../Button'
import SelectInput from '../inputs/SelectInput'
import MultiButtonInput from '../inputs/MultiButtonInput'
import StringInput from '../inputs/StringInput'
import AutocompleteInput from '../inputs/AutocompleteInput'
import AddIcon from 'react-icons/lib/md/add-circle-outline' import AddIcon from 'react-icons/lib/md/add-circle-outline'
import DeleteIcon from 'react-icons/lib/md/delete' import DeleteIcon from 'react-icons/lib/md/delete'
const combiningFilterOps = ['all', 'any', 'none']
const setFilterOps = ['in', '!in']
const otherFilterOps = Object
.keys(GlSpec.filter_operator.values)
.filter(op => combiningFilterOps.indexOf(op) < 0)
function hasCombiningFilter(filter) { function hasCombiningFilter(filter) {
return combiningFilterOps.indexOf(filter[0]) >= 0 return combiningFilterOps.indexOf(filter[0]) >= 0
} }
@ -34,80 +27,6 @@ function hasNestedCombiningFilter(filter) {
return false return false
} }
class OperatorSelect extends React.Component {
static propTypes = {
value: React.PropTypes.string.isRequired,
onChange: React.PropTypes.func.isRequired,
}
render() {
return <SelectInput
style={{
width: '15%',
margin: margins[0]
}}
value={this.props.value}
onChange={this.props.onChange}
options={otherFilterOps.map(op => [op, op])}
/>
}
}
class SingleFilterEditor extends React.Component {
static propTypes = {
filter: React.PropTypes.array.isRequired,
onChange: React.PropTypes.func.isRequired,
properties: React.PropTypes.object,
style: React.PropTypes.object,
}
static defaultProps = {
properties: {},
}
onFilterPartChanged(filterOp, propertyName, filterArgs) {
const newFilter = [filterOp, propertyName, ...filterArgs]
this.props.onChange(newFilter)
}
render() {
const f = this.props.filter
const filterOp = f[0]
const propertyName = f[1]
const filterArgs = f.slice(2)
return <div style={{
marginTop: margins[1],
marginBottom: margins[1],
...this.props.style
}}>
<AutocompleteInput
wrapperStyle={{
width: '30%',
marginRight: margins[0]
}}
value={propertyName}
options={Object.keys(this.props.properties).map(propName => [propName, propName])}
onChange={newPropertyName => this.onFilterPartChanged(filterOp, newPropertyName, filterArgs)}
/>
<OperatorSelect
value={filterOp}
onChange={newFilterOp => this.onFilterPartChanged(newFilterOp, propertyName, filterArgs)}
/>
<StringInput
style={{
width: '50%',
marginLeft: margins[0]
}}
value={filterArgs.join(',')}
onChange={ v=> this.onFilterPartChanged(filterOp, propertyName, v.split(','))}
/>
</div>
}
}
export default class CombiningFilterEditor extends React.Component { export default class CombiningFilterEditor extends React.Component {
static propTypes = { static propTypes = {
/** Properties of the vector layer and the available fields */ /** Properties of the vector layer and the available fields */

View file

@ -0,0 +1,26 @@
import React from 'react'
import SelectInput from '../inputs/SelectInput'
import { otherFilterOps } from '../../libs/filterops.js'
import { margins, fontSizes } from '../../config/scales.js'
class OperatorSelect extends React.Component {
static propTypes = {
value: React.PropTypes.string.isRequired,
onChange: React.PropTypes.func.isRequired,
}
render() {
return <SelectInput
style={{
width: '15%',
margin: margins[0]
}}
value={this.props.value}
onChange={this.props.onChange}
options={otherFilterOps.map(op => [op, op])}
/>
}
}
export default OperatorSelect

View file

@ -0,0 +1,62 @@
import React from 'react'
import OperatorSelect from './OperatorSelect'
import { margins, fontSizes } from '../../config/scales.js'
import StringInput from '../inputs/StringInput'
import AutocompleteInput from '../inputs/AutocompleteInput'
class SingleFilterEditor extends React.Component {
static propTypes = {
filter: React.PropTypes.array.isRequired,
onChange: React.PropTypes.func.isRequired,
properties: React.PropTypes.object,
style: React.PropTypes.object,
}
static defaultProps = {
properties: {},
}
onFilterPartChanged(filterOp, propertyName, filterArgs) {
const newFilter = [filterOp, propertyName, ...filterArgs]
this.props.onChange(newFilter)
}
render() {
const f = this.props.filter
const filterOp = f[0]
const propertyName = f[1]
const filterArgs = f.slice(2)
return <div style={{
marginTop: margins[1],
marginBottom: margins[1],
...this.props.style
}}>
<AutocompleteInput
wrapperStyle={{
width: '30%',
marginRight: margins[0]
}}
value={propertyName}
options={Object.keys(this.props.properties).map(propName => [propName, propName])}
onChange={newPropertyName => this.onFilterPartChanged(filterOp, newPropertyName, filterArgs)}
/>
<OperatorSelect
value={filterOp}
onChange={newFilterOp => this.onFilterPartChanged(newFilterOp, propertyName, filterArgs)}
/>
<StringInput
style={{
width: '50%',
marginLeft: margins[0]
}}
value={filterArgs.join(',')}
onChange={ v=> this.onFilterPartChanged(filterOp, propertyName, v.split(','))}
/>
</div>
}
}
export default SingleFilterEditor

6
src/libs/filterops.js Normal file
View file

@ -0,0 +1,6 @@
import GlSpec from 'mapbox-gl-style-spec/reference/latest.js'
export const combiningFilterOps = ['all', 'any', 'none']
export const setFilterOps = ['in', '!in']
export const otherFilterOps = Object
.keys(GlSpec.filter_operator.values)
.filter(op => combiningFilterOps.indexOf(op) < 0)