mirror of
https://github.com/a-nyx/maputnik-with-pmtiles.git
synced 2024-12-28 17:41:16 +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 = {
|
const input = {
|
||||||
...base,
|
...base,
|
||||||
border: '1px solid rgb(36, 36, 36)',
|
border: 'none',
|
||||||
width: '47%',
|
width: '47%',
|
||||||
backgroundColor: theme.colors.gray,
|
backgroundColor: theme.colors.gray,
|
||||||
color: theme.colors.lowgray,
|
color: theme.colors.lowgray,
|
||||||
|
|
|
@ -2,13 +2,122 @@ import React from 'react'
|
||||||
import Immutable from 'immutable'
|
import Immutable from 'immutable'
|
||||||
import { PropertyGroup } from '../fields/spec'
|
import { PropertyGroup } from '../fields/spec'
|
||||||
import PureRenderMixin from 'react-addons-pure-render-mixin';
|
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 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 = {
|
static propTypes = {
|
||||||
filter: React.PropTypes.array.isRequired,
|
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) {
|
constructor(props) {
|
||||||
|
@ -16,47 +125,48 @@ export default class FilterEditor extends React.Component {
|
||||||
this.shouldComponentUpdate = PureRenderMixin.shouldComponentUpdate.bind(this);
|
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() {
|
render() {
|
||||||
const op = this.props.filter[0]
|
const filter = this.combiningFilter()
|
||||||
const filters = this.props.filter.slice(1)
|
let combiningOp = filter[0]
|
||||||
const filterElems = filters.map(f => {
|
let filters = filter.slice(1)
|
||||||
const filterOp = f[0]
|
|
||||||
const prop = f[1]
|
|
||||||
const args = f.slice(2)
|
|
||||||
|
|
||||||
const availableFilterOperators = Object.keys(GlSpec.filter_operator.values)
|
const filterEditors = filters.map((f, idx) => {
|
||||||
const filterOpOptions = availableFilterOperators.map(value => {
|
return <SingleFilterEditor
|
||||||
return <option value={value}>{value}</option>
|
key={idx}
|
||||||
|
filter={f}
|
||||||
|
onChange={this.onFilterPartChanged.bind(this, idx + 1)}
|
||||||
|
/>
|
||||||
})
|
})
|
||||||
|
|
||||||
return <div>
|
return <div style={{
|
||||||
<select
|
padding: theme.scale[2],
|
||||||
style={{...inputStyle.select, width: '15%'}}
|
paddingRight: 0,
|
||||||
value={filterOp}
|
backgroundColor: theme.colors.black
|
||||||
>
|
}}>
|
||||||
{filterOpOptions}
|
<CombiningOperatorSelect
|
||||||
</select>
|
value={combiningOp}
|
||||||
<input
|
onChange={this.onFilterPartChanged.bind(this, 0)}
|
||||||
style={{...inputStyle.input, width: '17%'}}
|
|
||||||
value={prop}
|
|
||||||
/>
|
/>
|
||||||
<input
|
{filterEditors}
|
||||||
style={{...inputStyle.input, width: '55%'}}
|
|
||||||
value={args}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
})
|
|
||||||
|
|
||||||
return <div>
|
|
||||||
<select
|
|
||||||
style={{...inputStyle.select, width: '15%'}}
|
|
||||||
value={op}
|
|
||||||
>
|
|
||||||
<option value={"all"}>all</option>
|
|
||||||
<option value={"any"}>any</option>
|
|
||||||
</select>
|
|
||||||
<br/>
|
|
||||||
{filterElems}
|
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -149,7 +149,7 @@ export class LayerEditor extends React.Component {
|
||||||
</Toolbar>
|
</Toolbar>
|
||||||
<FilterEditor
|
<FilterEditor
|
||||||
filter={this.props.layer.get('filter', Immutable.List()).toJSON()}
|
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
|
{this.props.layer.get('type') !== 'background' && <SourceEditor
|
||||||
source={this.props.layer.get('source')}
|
source={this.props.layer.get('source')}
|
||||||
|
|
Loading…
Reference in a new issue