mirror of
https://github.com/a-nyx/maputnik-with-pmtiles.git
synced 2024-12-28 16:51:20 +01:00
Work on selecting source type before adding
This commit is contained in:
parent
6c69a91f2f
commit
57ab4be42c
3 changed files with 76 additions and 55 deletions
|
@ -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={{
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue