Work on selecting source type before adding

This commit is contained in:
Lukas Martinelli 2016-12-21 19:59:37 +01:00
parent 6c69a91f2f
commit 57ab4be42c
3 changed files with 76 additions and 55 deletions

View file

@ -113,8 +113,7 @@ export default class Toolbar extends React.Component {
<SourcesModal <SourcesModal
mapStyle={this.props.mapStyle} mapStyle={this.props.mapStyle}
onStyleChanged={this.props.onStyleChanged} onStyleChanged={this.props.onStyleChanged}
//isOpen={this.state.openSourcesModal} isOpen={this.state.openSourcesModal}
isOpen={true}
toggle={() => this.toggleSources.bind(this)} toggle={() => this.toggleSources.bind(this)}
/> />
<ToolbarAction style={{ <ToolbarAction style={{

View file

@ -1,6 +1,7 @@
import React from 'react' import React from 'react'
import Modal from './Modal' import Modal from './Modal'
import Heading from '../Heading' import Heading from '../Heading'
import Button from '../Button'
import InputBlock from '../inputs/InputBlock' import InputBlock from '../inputs/InputBlock'
import StringInput from '../inputs/StringInput' import StringInput from '../inputs/StringInput'
import SelectInput from '../inputs/SelectInput' import SelectInput from '../inputs/SelectInput'
@ -11,13 +12,13 @@ import colors from '../../config/colors'
import { margins, fontSizes } from '../../config/scales' import { margins, fontSizes } from '../../config/scales'
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'
class PublicSource extends React.Component { class PublicSource extends React.Component {
static propTypes = { static propTypes = {
id: React.PropTypes.string.isRequired, id: React.PropTypes.string.isRequired,
type: React.PropTypes.string.isRequired, type: React.PropTypes.string.isRequired,
title: React.PropTypes.string.isRequired, title: React.PropTypes.string.isRequired,
description: React.PropTypes.string.isRequired,
onSelect: React.PropTypes.func.isRequired, onSelect: React.PropTypes.func.isRequired,
} }
@ -32,34 +33,38 @@ class PublicSource extends React.Component {
fontSize: fontSizes[4], fontSize: fontSizes[4],
color: colors.lowgray, color: colors.lowgray,
}}> }}>
<div style={{ <Button style={{
backgroundColor: 'transparent',
padding: margins[2], padding: margins[2],
display: 'flex', display: 'flex',
flexDirection: 'row', flexDirection: 'row',
}}> }}>
<div> <div>
<span style={{fontWeight: 700}}>{this.props.title}</span><br/> <span style={{fontWeight: 700}}>{this.props.title}</span>
<br/>
<span style={{fontSize: fontSizes[5]}}>#{this.props.id}</span> <span style={{fontSize: fontSizes[5]}}>#{this.props.id}</span>
</div> </div>
<span style={{flexGrow: 1}} /> <span style={{flexGrow: 1}} />
<a style={{ <AddIcon />
cursor: 'pointer', </Button>
backgroundColor: colors.midgray,
color: colors.lowgray,
padding: margins[1],
borderRadius: 2,
}}>
Add
</a>
</div>
</div> </div>
} }
} }
function editorMode(source) {
if(source.type === 'geojson') return ' geojson'
if(source.type === 'vector' && source.tiles) {
return 'tilexyz'
}
return 'tilejson'
}
class SourceEditorLayout extends React.Component { class SourceEditorLayout extends React.Component {
static propTypes = { static propTypes = {
sourceId: React.PropTypes.string.isRequired, sourceId: React.PropTypes.string.isRequired,
source: React.PropTypes.object.isRequired, source: React.PropTypes.object.isRequired,
onSourceDelete: React.PropTypes.func.isRequired,
onSourceChange: React.PropTypes.func.isRequired,
} }
render() { render() {
@ -74,17 +79,14 @@ class SourceEditorLayout extends React.Component {
fontSize: fontSizes[4], fontSize: fontSizes[4],
flexDirection: 'row', flexDirection: 'row',
}}> }}>
<span style={{fontSize: fontSizes[4], lineHeight: 2}}>#{this.props.sourceId}</span> <span style={{fontWeight: 700, fontSize: fontSizes[4], lineHeight: 2}}>#{this.props.sourceId}</span>
<span style={{flexGrow: 1}} /> <span style={{flexGrow: 1}} />
<a style={{ <Button
cursor: 'pointer', onClick={this.props.onSourceDelete}
backgroundColor: colors.midgray, style={{backgroundColor: 'transparent'}}
color: colors.lowgray, >
padding: margins[1], <DeleteIcon />
borderRadius: 2, </Button>
}}>
Remove
</a>
</div> </div>
<div style={{ <div style={{
borderColor: colors.gray, borderColor: colors.gray,
@ -92,7 +94,11 @@ class SourceEditorLayout extends React.Component {
borderStyle: 'solid', borderStyle: 'solid',
padding: margins[1], padding: margins[1],
}}> }}>
<SourceTypeEditor source={this.props.source} /> <SourceTypeEditor
onChange={this.props.onSourceChange}
mode={editorMode(this.props.source)}
source={this.props.source}
/>
</div> </div>
</div> </div>
} }
@ -100,6 +106,21 @@ class SourceEditorLayout extends React.Component {
class AddSource extends React.Component { class AddSource extends React.Component {
static propTypes = { static propTypes = {
onSourceAdd: React.PropTypes.func.isRequired,
}
constructor(props) {
super(props)
this.state = {
mode: 'tilejson',
source: {}
}
}
onSourceChange(source) {
this.setState({
source: source
})
} }
render() { render() {
@ -114,21 +135,20 @@ class AddSource extends React.Component {
options={[ options={[
['geojson', 'GeoJSON'], ['geojson', 'GeoJSON'],
['tilejson', 'Vector (TileJSON URL)'], ['tilejson', 'Vector (TileJSON URL)'],
['tileurls', 'Vector (Direct URLs)'], ['tilexyz', 'Vector (XYZ URLs)'],
]} ]}
value={'geojson'} onChange={v => this.setState({mode: v})}
value={this.state.mode}
/> />
</InputBlock> </InputBlock>
<a style={{ <SourceTypeEditor
fontSize: fontSizes[4], onChange={this.onSourceChange.bind(this)}
cursor: 'pointer', mode={this.state.mode}
backgroundColor: colors.midgray, source={this.state.source}
color: colors.lowgray, />
padding: margins[1], <Button onClick={() => this.props.onSourceAdd(this.state.source)}>
borderRadius: 2,
}}>
Add Source Add Source
</a> </Button>
</div> </div>
} }
} }
@ -165,7 +185,10 @@ class SourcesModal extends React.Component {
{activeSources} {activeSources}
<Heading level={4}>Add New Source</Heading> <Heading level={4}>Add New Source</Heading>
<AddSource /> <div style={{maxWidth: 300}}>
<p style={{color: colors.lowgray, fontSize: fontSizes[5]}}>Add a new source to your style. You can only choose the source type and id at creation time!</p>
<AddSource onSourceAdd={} />
</div>
<Heading level={4}>Choose Public Source</Heading> <Heading level={4}>Choose Public Source</Heading>
<p style={{color: colors.lowgray, fontSize: fontSizes[5]}}>Add one of the publicly availble sources to your style.</p> <p style={{color: colors.lowgray, fontSize: fontSizes[5]}}>Add one of the publicly availble sources to your style.</p>

View file

@ -5,12 +5,14 @@ import StringInput from '../inputs/StringInput'
class TileJSONSourceEditor extends React.Component { class TileJSONSourceEditor extends React.Component {
static propTypes = { static propTypes = {
url: React.PropTypes.string.isRequired, url: React.PropTypes.string.isRequired,
onChange: React.PropTypes.func.isRequired,
} }
render() { render() {
return <InputBlock label={"TileJSON URL"}> return <InputBlock label={"TileJSON URL"}>
<StringInput <StringInput
value={this.props.url} value={this.props.url}
onChange={this.props.onChange}
/> />
</InputBlock> </InputBlock>
} }
@ -21,26 +23,24 @@ class TileURLSourceEditor extends React.Component {
tiles: React.PropTypes.array.isRequired, tiles: React.PropTypes.array.isRequired,
minZoom: React.PropTypes.number.isRequired, minZoom: React.PropTypes.number.isRequired,
maxZoom: React.PropTypes.number.isRequired, maxZoom: React.PropTypes.number.isRequired,
onChange: React.PropTypes.func.isRequired,
} }
renderTileUrls() { renderTileUrls() {
const prefix = ['1st', '2nd', '3rd', '4th', '5th', '6th', '7th']
return this.props.tiles.map((tileUrl, tileIndex) => { return this.props.tiles.map((tileUrl, tileIndex) => {
<InputBlock key={tileIndex} label={"Tile URL " + tileIndex}> return <InputBlock key={tileIndex} label={prefix[tileIndex] + " Tile URL"}>
<StringInput <StringInput
value={this.props.data} value={tileUrl}
/> />
</InputBlock> </InputBlock>
}) })
} }
render() { render() {
console.log(this.props.tiles)
return <div> return <div>
{this.renderTileUrls()} {this.renderTileUrls()}
<InputBlock label={"GeoJSON Data"}>
<StringInput
value={this.props.data}
/>
</InputBlock>
<InputBlock label={"Min Zoom"}> <InputBlock label={"Min Zoom"}>
<StringInput <StringInput
value={this.props.minZoom} value={this.props.minZoom}
@ -59,12 +59,14 @@ class TileURLSourceEditor extends React.Component {
class GeoJSONSourceEditor extends React.Component { class GeoJSONSourceEditor extends React.Component {
static propTypes = { static propTypes = {
data: React.PropTypes.string.isRequired, data: React.PropTypes.string.isRequired,
onChange: React.PropTypes.func.isRequired,
} }
render() { render() {
return <InputBlock label={"GeoJSON Data"}> return <InputBlock label={"GeoJSON Data"}>
<StringInput <StringInput
value={this.props.data} value={this.props.data}
onChange={this.props.onChange}
/> />
</InputBlock> </InputBlock>
} }
@ -72,22 +74,19 @@ class GeoJSONSourceEditor extends React.Component {
class SourceTypeEditor extends React.Component { class SourceTypeEditor extends React.Component {
static propTypes = { static propTypes = {
mode: React.PropTypes.string.isRequired,
source: React.PropTypes.object.isRequired, source: React.PropTypes.object.isRequired,
onChange: React.PropTypes.func.isRequired,
} }
render() { render() {
const source = this.props.source const source = this.props.source
if(source.type === "geojson") { switch(this.props.mode) {
return <GeoJSONSourceEditor data={source.data} /> case 'geojson': return <GeoJSONSourceEditor data={source.data || 'http://localhost:3000/mygeojson.json'} />
case 'tilejson': return <TileJSONSourceEditor url={source.url || 'http://localhost:3000/tiles.json'}/>
case 'tilexyz': return <TileURLSourceEditor tiles={source.tiles || ['http://localhost:3000/{x}/{y}/{z}.pbf']} minZoom={source.minZoom || 0} maxZoom={source.maxZoom || 14}/>
default: return null
} }
if(source.type === "vector") {
if(source.url) {
return <TileJSONSourceEditor url={source.url}/>
} else {
return <TileURLSourceEditor tiles={source.tiles} minZoom={source.minZoom} maxZoom={source.maxZoom}/>
}
}
return null
} }
} }