mirror of
https://github.com/a-nyx/maputnik-with-pmtiles.git
synced 2024-12-27 08:45:28 +01:00
Split filter editor into more components
This commit is contained in:
parent
7da97ddd6e
commit
a981a39691
3 changed files with 152 additions and 42 deletions
|
@ -24,7 +24,7 @@ const property = {
|
|||
|
||||
const input = {
|
||||
...base,
|
||||
border: '1px solid rgb(36, 36, 36)',
|
||||
border: 'none',
|
||||
width: '47%',
|
||||
backgroundColor: theme.colors.gray,
|
||||
color: theme.colors.lowgray,
|
||||
|
|
|
@ -2,13 +2,122 @@ import React from 'react'
|
|||
import Immutable from 'immutable'
|
||||
import { PropertyGroup } from '../fields/spec'
|
||||
import PureRenderMixin from 'react-addons-pure-render-mixin';
|
||||
import inputStyle from '../fields/input.js'
|
||||
import GlSpec from 'mapbox-gl-style-spec/reference/latest.min.js'
|
||||
import inputStyle from '../fields/input.js'
|
||||
import theme from '../theme.js'
|
||||
|
||||
export default class FilterEditor extends React.Component {
|
||||
const combiningFilterOps = ['all', 'any', 'none']
|
||||
const otherFilterOps = Object
|
||||
.keys(GlSpec.filter_operator.values)
|
||||
.filter(op => combiningFilterOps.indexOf(op) < 0)
|
||||
|
||||
class CombiningOperatorSelect extends React.Component {
|
||||
static propTypes = {
|
||||
value: React.PropTypes.string.isRequired,
|
||||
onChange: React.PropTypes.func.isRequired,
|
||||
}
|
||||
|
||||
render() {
|
||||
const options = combiningFilterOps.map(op => {
|
||||
return <option key={op} value={op}>{op}</option>
|
||||
})
|
||||
|
||||
return <div>
|
||||
<select
|
||||
style={{
|
||||
...inputStyle.select,
|
||||
width: '20.5%',
|
||||
margin: theme.scale[0],
|
||||
}}
|
||||
value={this.props.value}
|
||||
onChange={e => this.props.onChange(e.target.value)}
|
||||
>
|
||||
{options}
|
||||
</select>
|
||||
<label style={{
|
||||
...inputStyle.label,
|
||||
width: '60%',
|
||||
marginLeft: theme.scale[0],
|
||||
}}>
|
||||
of the filters matches
|
||||
</label>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
||||
class OperatorSelect extends React.Component {
|
||||
static propTypes = {
|
||||
value: React.PropTypes.string.isRequired,
|
||||
onChange: React.PropTypes.func.isRequired,
|
||||
}
|
||||
|
||||
render() {
|
||||
const options = otherFilterOps.map(op => {
|
||||
return <option key={op} value={op}>{op}</option>
|
||||
})
|
||||
return <select
|
||||
style={{
|
||||
...inputStyle.select,
|
||||
width: '15%',
|
||||
margin: theme.scale[0]
|
||||
}}
|
||||
value={this.props.value}
|
||||
onChange={e => this.props.onChange(e.target.value)}
|
||||
>
|
||||
{options}
|
||||
</select>
|
||||
}
|
||||
}
|
||||
|
||||
class SingleFilterEditor extends React.Component {
|
||||
static propTypes = {
|
||||
filter: React.PropTypes.array.isRequired,
|
||||
onFilterChanged: React.PropTypes.func.isRequired,
|
||||
onChange: React.PropTypes.func.isRequired,
|
||||
}
|
||||
|
||||
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>
|
||||
<input
|
||||
style={{
|
||||
...inputStyle.input,
|
||||
width: '17%',
|
||||
margin: theme.scale[0]
|
||||
}}
|
||||
value={propertyName}
|
||||
onChange={newPropertyName => this.onFilterPartChanged(filterOp, newPropertyName, filterArgs)}
|
||||
/>
|
||||
<OperatorSelect
|
||||
value={filterOp}
|
||||
onChange={newFilterOp => this.onFilterPartChanged(newFilterOp, propertyName, filterArgs)}
|
||||
/>
|
||||
<input
|
||||
style={{
|
||||
...inputStyle.input,
|
||||
width: '53%',
|
||||
margin: theme.scale[0]
|
||||
}}
|
||||
value={filterArgs}
|
||||
onChange={newFilterArgs => this.onFilterPartChanged(filterOp, propertyName, newFilterArgs)}
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default class CombiningFilterEditor extends React.Component {
|
||||
static propTypes = {
|
||||
filter: React.PropTypes.array.isRequired,
|
||||
onChange: React.PropTypes.func.isRequired,
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
|
@ -16,47 +125,48 @@ export default class FilterEditor extends React.Component {
|
|||
this.shouldComponentUpdate = PureRenderMixin.shouldComponentUpdate.bind(this);
|
||||
}
|
||||
|
||||
// Convert filter to combining filter
|
||||
combiningFilter() {
|
||||
let combiningOp = this.props.filter[0]
|
||||
let filters = this.props.filter.slice(1)
|
||||
|
||||
if(combiningFilterOps.indexOf(combiningOp) < 0) {
|
||||
combiningOp = 'all'
|
||||
filters = [this.props.filter.slice(0)]
|
||||
}
|
||||
|
||||
return [combiningOp, ...filters]
|
||||
}
|
||||
|
||||
onFilterPartChanged(filterIdx, newPart) {
|
||||
const newFilter = this.combiningFilter().slice(0)
|
||||
newFilter[filterIdx] = newPart
|
||||
this.props.onChange(newFilter)
|
||||
}
|
||||
|
||||
render() {
|
||||
const op = this.props.filter[0]
|
||||
const filters = this.props.filter.slice(1)
|
||||
const filterElems = filters.map(f => {
|
||||
const filterOp = f[0]
|
||||
const prop = f[1]
|
||||
const args = f.slice(2)
|
||||
const filter = this.combiningFilter()
|
||||
let combiningOp = filter[0]
|
||||
let filters = filter.slice(1)
|
||||
|
||||
const availableFilterOperators = Object.keys(GlSpec.filter_operator.values)
|
||||
const filterOpOptions = availableFilterOperators.map(value => {
|
||||
return <option value={value}>{value}</option>
|
||||
})
|
||||
|
||||
return <div>
|
||||
<select
|
||||
style={{...inputStyle.select, width: '15%'}}
|
||||
value={filterOp}
|
||||
>
|
||||
{filterOpOptions}
|
||||
</select>
|
||||
<input
|
||||
style={{...inputStyle.input, width: '17%'}}
|
||||
value={prop}
|
||||
/>
|
||||
<input
|
||||
style={{...inputStyle.input, width: '55%'}}
|
||||
value={args}
|
||||
/>
|
||||
</div>
|
||||
const filterEditors = filters.map((f, idx) => {
|
||||
return <SingleFilterEditor
|
||||
key={idx}
|
||||
filter={f}
|
||||
onChange={this.onFilterPartChanged.bind(this, idx + 1)}
|
||||
/>
|
||||
})
|
||||
|
||||
return <div>
|
||||
<select
|
||||
style={{...inputStyle.select, width: '15%'}}
|
||||
value={op}
|
||||
>
|
||||
<option value={"all"}>all</option>
|
||||
<option value={"any"}>any</option>
|
||||
</select>
|
||||
<br/>
|
||||
{filterElems}
|
||||
return <div style={{
|
||||
padding: theme.scale[2],
|
||||
paddingRight: 0,
|
||||
backgroundColor: theme.colors.black
|
||||
}}>
|
||||
<CombiningOperatorSelect
|
||||
value={combiningOp}
|
||||
onChange={this.onFilterPartChanged.bind(this, 0)}
|
||||
/>
|
||||
{filterEditors}
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
|
|
@ -149,7 +149,7 @@ export class LayerEditor extends React.Component {
|
|||
</Toolbar>
|
||||
<FilterEditor
|
||||
filter={this.props.layer.get('filter', Immutable.List()).toJSON()}
|
||||
onFilterChanged={console.log}
|
||||
onChange={f => console.log('filter changed', f)}
|
||||
/>
|
||||
{this.props.layer.get('type') !== 'background' && <SourceEditor
|
||||
source={this.props.layer.get('source')}
|
||||
|
|
Loading…
Reference in a new issue