Skip to content

Commit

Permalink
Merge pull request #98 from go-spatial/dev
Browse files Browse the repository at this point in the history
Clone functionality
  • Loading branch information
justenPalmer authored Jun 4, 2020
2 parents f42fbd7 + 6528d06 commit 6254362
Show file tree
Hide file tree
Showing 15 changed files with 305 additions and 42 deletions.
2 changes: 1 addition & 1 deletion src/App.css
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ label .badge{position:relative;top:2px;}
.modal{background-color:rgba(39,50,55,0.75);}
.modal-container{position:absolute;top:0;bottom:0;left:0;right:0;}
.modal-backdrop{position:absolute;top:0;bottom:0;left:0;right:0;background-color:rgba(39,50,55,0.6);}
.modal-content{position:relative;margin:0.75em;background:#fff;z-index:1041;width:inherit;}
.modal-content{position:relative;margin:0.75em;background:#fff;z-index:1041;}

.navbar-pill{display:inline-block;border-radius:0.25rem 0.25rem 0 0;padding:0.25rem;
margin:0.5rem 0 0 0.5rem;}
Expand Down
7 changes: 7 additions & 0 deletions src/component/Field/FieldSelect.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import React from 'react'
import PropTypes from 'prop-types'

import modelLayer from '../../model/layer'

class FieldSelect extends React.Component {

handleChange = (e)=>{
Expand All @@ -21,6 +23,11 @@ class FieldSelect extends React.Component {
handle.blur && handle.blur(name)
}

handleSubmit = async ()=>{
const {layer, path, style} = this.props
await modelLayer.actions.clone({layer, path, style})
}

render (){
const {autoFocus, helper, label, name, options, placeholder, value} = this.props

Expand Down
1 change: 0 additions & 1 deletion src/component/Infotip/InfotipMessage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ class InfotipMessage extends React.Component {
}

componentWillUnmount (){
console.log('cleanup:',this.parentEl)
document.body.removeChild(this.parentEl)
}

Expand Down
34 changes: 21 additions & 13 deletions src/component/LayerAdd/index.jsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import PropTypes from 'prop-types'
import React from 'react'
import {withRouter} from 'react-router-dom'

import utilUrl from '../../utility/utilUrl'

import modelApp from '../../model/app'
import modelLayer from '../../model/layer'
import modelSource from '../../model/source'
import modelStyle from '../../model/style'

import Alert from '../Alert'
import Property from '../Property'
Expand All @@ -15,29 +17,36 @@ class LayerAdd extends React.Component {
constructor(props) {
super(props)

// check for query params
const query = new URLSearchParams(window.location.search)

this.state = {
rec:{
id:'',
source:'',
'source-layer':'',
type:''
id:query.has('source-layer')? query.get('source-layer'): '',
source:query.has('source')? query.get('source'): '',
'source-layer':query.has('source-layer')? query.get('source-layer'): '',
type:query.has('type')? query.get('type'): '',
},
error:null
}
}

handleSubmit = async (e)=>{
e.preventDefault()
const {path, style} = this.props,
const {history, path, style} = this.props,
{rec} = this.state

try{

if (style.getIn(['current','layers']).find(layer => layer.get('id') === rec.id)){
throw new Error(`LayerAdd.submit: layerId already exists`)
}
await modelApp.actions.setLoading(true)
await modelLayer.actions.add({path, rec, style})
await modelApp.actions.setLoading(false)

// route user to layer
// handle.route('layer/'+layer.id)
const route = `layers/${rec.id}`
history.push(modelStyle.helpers.getRouteFromPath({path, route}))
} catch(e){
await modelApp.actions.setLoading(false)
await modelApp.actions.setError(e)
Expand All @@ -53,8 +62,6 @@ class LayerAdd extends React.Component {

let id = parts.join('.')

// TODO: check for layer id collisions

this.setState({rec:{
...rec,
id
Expand Down Expand Up @@ -86,9 +93,9 @@ class LayerAdd extends React.Component {
{rec} = this.state

const typeOptions = modelLayer.helpers.getTypeOptions()
const sourceOptions = modelSource.helpers.getOptions({style})
const sourceLayerOptions = (this.state.source)? modelSource.helpers.getLayerOptions({style, sourceId:this.state.source}):
null
const sourceOptions = modelSource.helpers.getOptions({style}) || []
const sourceLayerOptions = rec.source? modelSource.helpers.getLayerOptions({style, sourceId:rec.source}):
[]

const handle = {
change: this.handleChange
Expand Down Expand Up @@ -165,10 +172,11 @@ class LayerAdd extends React.Component {
}

LayerAdd.propTypes = {
history: PropTypes.object,
handle: PropTypes.object,
match: PropTypes.object,
path: PropTypes.array,
style: PropTypes.object,
}

export default LayerAdd
export default withRouter(LayerAdd)
25 changes: 16 additions & 9 deletions src/component/LayerEdit/LayerEditActions.jsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
import React from 'react'
import PropTypes from 'prop-types'
import {withRouter} from 'react-router-dom'

import utilPath from '../../utility/utilPath'

import Icon from '../Icon'
import LayerEditModalRemove from './LayerEditModalRemove'

import modelLayer from '../../model/layer'
import LayerEditModalClone from './LayerEditModalClone'

class LayerEditActions extends React.Component {
constructor (props){
Expand All @@ -19,8 +17,9 @@ class LayerEditActions extends React.Component {
}

handleClone = async ()=>{
const {layer} = this.props
await modelLayer.actions.clone({layer})
this.setState({
modal: 'cloneDone'
})
}

handleModalSet = (modal)=>{
Expand All @@ -46,7 +45,7 @@ class LayerEditActions extends React.Component {
</h2>
<div className="content-body">
<div className="content-body-row">
<button disabled="disabled" onClick={()=>this.handleClone()} className="btn btn-sm btn-outline-dark btn-block">
<button onClick={()=>this.handleClone()} className="btn btn-sm btn-outline-dark btn-block">
<Icon className="mr-1" icon={'clone'}/>
Clone Layer
</button>
Expand All @@ -65,15 +64,23 @@ class LayerEditActions extends React.Component {
}

renderModal (){
const {path, style} = this.props,
const {layer, path, style} = this.props,
{modal} = this.state

switch (modal){
case 'remove':
return (
<LayerEditModalRemove
handleClose={()=>this.handleModalSet(null)}
handleDone={this.handleRemoveDone}
layer={layer}
path={path}
style={style}/>
)
case 'cloneDone':
return (
<LayerEditModalClone
handleClose={()=>this.handleModalSet(null)}
layer={layer}
path={path}
style={style}/>
)
Expand All @@ -92,4 +99,4 @@ LayerEditActions.propTypes = {
style: PropTypes.object,
}

export default withRouter(LayerEditActions)
export default LayerEditActions
126 changes: 126 additions & 0 deletions src/component/LayerEdit/LayerEditModalClone.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
import React from 'react'
import PropTypes from 'prop-types'
import Modal from '../Modal'
import {withRouter} from 'react-router-dom'

import modelApp from '../../model/app'
import modelLayer from '../../model/layer'
import modelStyle from '../../model/style'

import Property from '../Property'

class LayerEditModalClone extends React.Component {

constructor(props) {
super(props)
const {layer, style} = props

const cloneId = modelLayer.helpers.getLayerCloneId({layer, style})

this.state = {
id: cloneId,
placement: '',
}
}

handleClone = async ()=>{
const {history, layer, path, style} = this.props,
{id, placement} = this.state

try{
await modelApp.actions.setLoading(true)

const clone = await modelLayer.actions.clone({cloneId: id, layer, path, placement, style})
await modelApp.actions.setLoading(false)

// send user to newly created layer
const route = `layers/${clone.get('id')}`
history.push(modelStyle.helpers.getRouteFromPath({path, route}))

} catch(e){
await modelApp.actions.setLoading(false)
await modelApp.actions.setError(e)
}

this.setState({
modal: 'cloneDone'
})
}

handleChange = ({name, value})=>{
let state = {}
state[name] = value

this.setState(state)
}

render (){
const {handleClose} = this.props,
{id, placement} = this.state

//const stylePath = modelStyle.helpers.getRouteFromPath({path})

const handle = {
change: this.handleChange
}

const options = [
{name:'at the bottom', value:'bottom'},
{name:'after cloned layer', value:'after'},
]

return (
<Modal>
<div className="modal-header text-dark">
<h5 className="modal-title">CLONE LAYER</h5>
<button type="button" className="close" data-dismiss="modal" aria-label="Close" onClick={handleClose}>
<span aria-hidden="true">&times;</span>
</button>
</div>
<div className="modal-body text-left text-dark">

<Property
handle={handle}
info={'id for the layer clone'}
key={'id'}
label={'new layer id'}
name={'id'}
path={null}
required={true}
type={'string'}
value={id}
/>
<Property
handle={handle}
info={'placement of the cloned layer'}
key={'placement'}
label={'placement'}
name={'placement'}
options={options}
path={null}
required={true}
type={'enum'}
value={placement}
/>

</div>
<div className="modal-footer">
<button onClick={this.handleClone} className="btn btn-outline-dark">Create</button>
</div>
</Modal>
)
}

}

LayerEditModalClone.propTypes = {
handleClose: PropTypes.func.isRequired,
handleDone: PropTypes.func,
history: PropTypes.object,
layer: PropTypes.object,
path: PropTypes.array,
style: PropTypes.object,
}

export default withRouter(LayerEditModalClone)

25 changes: 21 additions & 4 deletions src/component/LayerEdit/LayerEditModalRemove.jsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,36 @@
import React from 'react'
import PropTypes from 'prop-types'
import Modal from '../Modal'
import {withRouter} from 'react-router-dom'

import modelApp from '../../model/app'
import modelLayer from '../../model/layer'
import modelStyle from '../../model/style'

class LayerEditModalRemove extends React.Component {

handleRemove = async ()=>{
const {handleDone, path} = this.props
const {history, layer, path, style} = this.props

try{
await modelApp.actions.setLoading(true)

const layerIndex = modelLayer.helpers.getIndexById({layerId: layer.get('id'), style})
if (layerIndex === -1) throw new Error(`LayerEditModalRemove.handleRemove: no layer found to clone`)

await modelStyle.actions.removeIn({
path
})
await modelApp.actions.setLoading(false)
handleDone()

// send user to prev layer
const prevIndex = layerIndex === 0? 1: layerIndex - 1
// get prev layer
const prevLayer = style.getIn(['current','layers', prevIndex])
const route = prevLayer? `layers/${prevLayer.get('id')}`: 'layers'

history.push(modelStyle.helpers.getRouteFromPath({path, route}))

} catch(e){
await modelApp.actions.setLoading(false)
await modelApp.actions.setError(e)
Expand All @@ -35,7 +49,7 @@ class LayerEditModalRemove extends React.Component {
</button>
</div>
<div className="modal-body text-left text-dark">
<p>Are you sure you want to remove this layer?</p>
<p className="mb-0">Are you sure you want to remove this layer?</p>

</div>
<div className="modal-footer">
Expand All @@ -50,8 +64,11 @@ class LayerEditModalRemove extends React.Component {
LayerEditModalRemove.propTypes = {
handleClose: PropTypes.func.isRequired,
handleDone: PropTypes.func,
history: PropTypes.object,
layer: PropTypes.object,
path: PropTypes.array,
style: PropTypes.object,
}

export default LayerEditModalRemove
export default withRouter(LayerEditModalRemove)

Loading

0 comments on commit 6254362

Please sign in to comment.