Restructure layer settings for add modal

This commit is contained in:
Lukas Martinelli 2016-12-29 14:44:46 +01:00
parent ccc39b87db
commit bf5131cadd
10 changed files with 205 additions and 120 deletions

View file

@ -164,6 +164,7 @@ export default class App extends React.Component {
const toolbar = <Toolbar
mapStyle={this.state.mapStyle}
sources={this.layerWatcher.sources}
onStyleChanged={this.onStyleChanged.bind(this)}
onStyleOpen={this.onStyleChanged.bind(this)}
onStyleDownload={this.onStyleDownload.bind(this)}

View file

@ -16,6 +16,7 @@ import HelpIcon from 'react-icons/lib/md/help-outline'
import InspectionIcon from 'react-icons/lib/md/find-in-page'
import AddIcon from 'react-icons/lib/md/add-circle-outline'
import AddModal from './modals/AddModal'
import SettingsModal from './modals/SettingsModal'
import SourcesModal from './modals/SourcesModal'
import OpenModal from './modals/OpenModal'
@ -80,6 +81,8 @@ export default class Toolbar extends React.Component {
onStyleOpen: React.PropTypes.func.isRequired,
// Current style is requested for download
onStyleDownload: React.PropTypes.func.isRequired,
// A dict of source id's and the available source layers
sources: React.PropTypes.object.isRequired,
}
constructor(props) {
@ -89,6 +92,7 @@ export default class Toolbar extends React.Component {
settings: false,
sources: false,
open: false,
add: false,
}
}
}
@ -152,6 +156,13 @@ export default class Toolbar extends React.Component {
isOpen={this.state.isOpen.sources}
onOpenToggle={this.toggleModal.bind(this, 'sources')}
/>
<AddModal
mapStyle={this.props.mapStyle}
sources={this.props.sources}
onStyleChanged={this.props.onStyleChanged}
isOpen={this.state.isOpen.add}
onOpenToggle={this.toggleModal.bind(this, 'add')}
/>
<ToolbarLink
href={"https://github.com/maputnik/editor"}
style={{

View file

@ -1,11 +1,13 @@
import React from 'react'
import JSONEditor from './JSONEditor'
import SourceEditor from './SourceEditor'
import FilterEditor from '../filter/FilterEditor'
import PropertyGroup from '../fields/PropertyGroup'
import LayerEditorGroup from './LayerEditorGroup'
import LayerSettings from './LayerSettings'
import LayerTypeBlock from './LayerTypeBlock'
import LayerIdBlock from './LayerIdBlock'
import LayerSourceBlock from './LayerSourceBlock'
import LayerSourceLayerBlock from './LayerSourceLayerBlock'
import InputBlock from '../inputs/InputBlock'
import MultiButtonInput from '../inputs/MultiButtonInput'
@ -80,7 +82,7 @@ export default class LayerEditor extends React.Component {
/** A {@property} in either the paint our layout {@group} has changed
* to a {@newValue}.
*/
onPropertyChange(group, property, newValue) {
changeProperty(group, property, newValue) {
if(group) {
this.props.onLayerChanged({
...this.props.layer,
@ -117,12 +119,16 @@ export default class LayerEditor extends React.Component {
renderGroupType(type, fields) {
switch(type) {
case 'settings': return <LayerSettings
id={this.props.layer.id}
type={this.props.layer.type}
onTypeChange={v => this.onPropertyChange(null, 'type', v)}
onIdChange={newId => this.props.onLayerIdChange(this.props.layer.id, newId)}
/>
case 'settings': return <div>
<LayerIdBlock
value={this.props.layer.id}
onChange={newId => this.props.onLayerIdChange(this.props.layer.id, newId)}
/>
<LayerTypeBlock
value={this.props.layer.type}
onChange={v => this.changeProperty(null, 'type', v)}
/>
</div>
case 'source': return <div>
{this.props.layer.filter &&
<FilterEditor
@ -131,12 +137,15 @@ export default class LayerEditor extends React.Component {
onChange={f => this.onFilterChange(f)}
/>
}
<SourceEditor
source={this.props.layer.source}
sourceLayer={this.props.layer['source-layer']}
sources={this.props.sources}
onSourceChange={console.log}
onSourceLayerChange={console.log}
<LayerSourceBlock
sourceIds={Object.keys(this.props.sources)}
value={this.props.layer.source}
onChange={v => this.changeProperty(null, 'source', v)}
/>
<LayerSourceLayerBlock
sourceLayerIds={this.props.sources[this.props.layer.source]}
value={this.props.layer['source-layer']}
onChange={v => this.changeProperty(null, 'source-layer', v)}
/>
<InputBlock label={"Inspection Mode"}>
<MultiButtonInput
@ -149,7 +158,7 @@ export default class LayerEditor extends React.Component {
case 'properties': return <PropertyGroup
layer={this.props.layer}
groupFields={fields}
onChange={this.onPropertyChange.bind(this)}
onChange={this.changeProperty.bind(this)}
/>
case 'jsoneditor': return <JSONEditor
layer={this.props.layer}

View file

@ -0,0 +1,22 @@
import React from 'react'
import InputBlock from '../inputs/InputBlock'
import StringInput from '../inputs/StringInput'
class LayerIdBlock extends React.Component {
static propTypes = {
value: React.PropTypes.string.isRequired,
onChange: React.PropTypes.func.isRequired,
}
render() {
return <InputBlock label={"Layer ID"}>
<StringInput
value={this.props.value}
onChange={this.props.onChange}
/>
</InputBlock>
}
}
export default LayerIdBlock

View file

@ -1,50 +0,0 @@
import React from 'react'
import GlSpec from 'mapbox-gl-style-spec/reference/latest.min.js'
import InputBlock from '../inputs/InputBlock'
import StringInput from '../inputs/StringInput'
import SelectInput from '../inputs/SelectInput'
import colors from '../../config/colors'
import { margins } from '../../config/scales'
class LayerSettings extends React.Component {
static propTypes = {
id: React.PropTypes.string.isRequired,
type: React.PropTypes.oneOf(Object.keys(GlSpec.layer.type.values)).isRequired,
onIdChange: React.PropTypes.func.isRequired,
onTypeChange: React.PropTypes.func.isRequired,
}
render() {
return <div style={{
padding: margins[2],
paddingRight: 0,
backgroundColor: colors.black,
}}>
<InputBlock label={"Layer ID"}>
<StringInput
value={this.props.id}
onChange={this.props.onIdChange}
/>
</InputBlock>
<InputBlock label={"Layer Type"}>
<SelectInput
options={[
['background', 'Background'],
['fill', 'Fill'],
['line', 'Line'],
['symbol', 'Symbol'],
['raster', 'Raster'],
['circle', 'Circle'],
['fill-extrusion', 'Fill Extrusion'],
]}
onChange={this.props.onTypeChange}
value={this.props.type}
/>
</InputBlock>
</div>
}
}
export default LayerSettings

View file

@ -0,0 +1,25 @@
import React from 'react'
import InputBlock from '../inputs/InputBlock'
import StringInput from '../inputs/StringInput'
import SelectInput from '../inputs/SelectInput'
class LayerSourceBlock extends React.Component {
static propTypes = {
value: React.PropTypes.string.isRequired,
onChange: React.PropTypes.func.isRequired,
sourceIds: React.PropTypes.array.isRequired,
}
render() {
return <InputBlock label={"Source"}>
<SelectInput
value={this.props.value}
onChange={this.props.onChange}
options={this.props.sourceIds.map(s => [s, s])}
/>
</InputBlock>
}
}
export default LayerSourceBlock

View file

@ -0,0 +1,25 @@
import React from 'react'
import InputBlock from '../inputs/InputBlock'
import StringInput from '../inputs/StringInput'
import SelectInput from '../inputs/SelectInput'
class LayerSourceLayer extends React.Component {
static propTypes = {
value: React.PropTypes.string.isRequired,
onChange: React.PropTypes.func.isRequired,
sourceLayerIds: React.PropTypes.array.isRequired,
}
render() {
return <InputBlock label={"Source Layer"}>
<SelectInput
value={this.props.value}
onChange={this.props.onChange}
options={this.props.sourceLayerIds.map(l => [l, l])}
/>
</InputBlock>
}
}
export default LayerSourceLayer

View file

@ -0,0 +1,31 @@
import React from 'react'
import InputBlock from '../inputs/InputBlock'
import SelectInput from '../inputs/SelectInput'
class LayerTypeBlock extends React.Component {
static propTypes = {
value: React.PropTypes.string.isRequired,
onChange: React.PropTypes.func.isRequired,
}
render() {
return <InputBlock label={"Layer Type"}>
<SelectInput
options={[
['background', 'Background'],
['fill', 'Fill'],
['line', 'Line'],
['symbol', 'Symbol'],
['raster', 'Raster'],
['circle', 'Circle'],
['fill-extrusion', 'Fill Extrusion'],
]}
onChange={this.props.onChange}
value={this.props.value}
/>
</InputBlock>
}
}
export default LayerTypeBlock

View file

@ -1,54 +0,0 @@
import React from 'react'
import PropertyGroup from '../fields/PropertyGroup'
import input from '../../config/input.js'
/** Choose tileset (source) and the source layer */
export default class SourceEditor extends React.Component {
static propTypes = {
source: React.PropTypes.string.isRequired,
sourceLayer: React.PropTypes.string.isRequired,
onSourceChange: React.PropTypes.func.isRequired,
onSourceLayerChange: React.PropTypes.func.isRequired,
/** List of available sources in the style
* https://www.mapbox.com/mapbox-gl-style-spec/#root-sources */
sources: React.PropTypes.object.isRequired,
}
render() {
const options = Object.keys(this.props.sources).map(sourceId => {
return <option key={sourceId} value={sourceId}>{sourceId}</option>
})
const layerOptions = this.props.sources[this.props.source].map(vectorLayerId => {
const id = vectorLayerId
return <option key={id} value={id}>{id}</option>
})
return <div>
<div style={input.property}>
<label style={input.label}>Source</label>
<select
style={input.select}
value={this.props.source}
onChange={(e) => this.onSourceChange(e.target.value)}
>
{options}
</select>
</div>
<div style={input.property}>
<label style={input.label}>Source Layer</label>
<select
style={input.select}
value={this.props.sourceLayer}
onChange={(e) => this.onSourceLayerChange(e.target.value)}
>
{layerOptions}
</select>
</div>
</div>
}
}

View file

@ -0,0 +1,65 @@
import React from 'react'
import InputBlock from '../inputs/InputBlock'
import StringInput from '../inputs/StringInput'
import SelectInput from '../inputs/SelectInput'
import Modal from './Modal'
import colors from '../../config/colors'
import LayerTypeBlock from '../layers/LayerTypeBlock'
import LayerIdBlock from '../layers/LayerIdBlock'
import LayerSourceBlock from '../layers/LayerSourceBlock'
import LayerSourceLayerBlock from '../layers/LayerSourceLayerBlock'
class AddModal extends React.Component {
static propTypes = {
mapStyle: React.PropTypes.object.isRequired,
onStyleChanged: React.PropTypes.func.isRequired,
isOpen: React.PropTypes.bool.isRequired,
onOpenToggle: React.PropTypes.func.isRequired,
// A dict of source id's and the available source layers
sources: React.PropTypes.object.isRequired,
}
constructor(props) {
super(props)
console.log('sources', this.props.sources)
this.state = {
type: 'fill',
id: '',
//source: Object.keys(this.props.sources)[0],
//'source-layer': this.props.sources[0][0]
}
}
render() {
return <Modal
isOpen={this.props.isOpen}
onOpenToggle={this.props.onOpenToggle}
title={'Add Layer'}
>
<LayerIdBlock
value={this.state.id}
onChange={v => this.setState({ id: v })}
/>
<LayerTypeBlock
value={this.state.type}
onChange={v => this.setState({ type: v })}
/>
<LayerSourceBlock
sourceIds={Object.keys(this.props.sources)}
value={this.state.source}
onChange={v => this.setState({ source: v })}
/>
<LayerSourceLayerBlock
sourceLayerIds={this.props.sources[this.state.source] || []}
value={this.state['source-layer']}
onChange={v => this.setState({ 'source-layer': v })}
/>
</Modal>
}
}
export default AddModal