Skip to content

Commit 692957f

Browse files
committed
improved errors and form flow
1 parent fdf0d17 commit 692957f

27 files changed

+323
-267
lines changed

package-lock.json

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
},
2323
"devDependencies": {
2424
"babel-preset-flow": "^6.23.0",
25+
"bootstrap": "^4.1.1",
2526
"gh-pages": "^1.1.0",
2627
"js-file-download": "^0.4.1",
2728
"jshint": "^2.9.5",

public/index.html

Lines changed: 24 additions & 2 deletions
Large diffs are not rendered by default.

src/App.css

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ label .badge{position:relative;top:2px;}
2626
.border-gray{border:1px solid #273237;}
2727

2828
.btn-xs{padding:0 .1rem;font-size:.8rem;}
29+
.btn-xs i{position:relative;top:-1px;left:0;}
2930
.btn.btn-primary{background-color:#00ACC1;border-color:#00A7B6;}
3031
.btn.btn-primary:hover{background-color:#00A7B6;border-color:#0094A0;}
3132
.btn.btn-primary:active{background-color:#0094A0;border-color:#0094A0;}
@@ -35,8 +36,10 @@ label .badge{position:relative;top:2px;}
3536
/* Code mirror */
3637
.CodeMirror{width:100%;height:auto;font-size:0.9em;margin-left:-4px;}
3738
.CodeMirror-linenumbers{}
38-
3939
.CodeMirror-gutters{background:transparent;border-right:1px solid transparent;}
40+
41+
.close-pos{top:0.25rem;right:0.25rem;}
42+
4043
.cm-s-default .cm-string{color: #03838F;}
4144
.cm-s-default .cm-number { color: #9C27B0; }
4245
.cm-s-default .cm-property { color: #273237; }

src/App.js

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,6 @@ import Store from './Store';
1414
export default class App extends Component {
1515

1616
render (){
17-
18-
const routeRoot = process.env.PUBLIC_URL;
19-
20-
console.log('root:',routeRoot);
21-
2217
return (
2318
<Provider store={Store}>
2419
<Router>

src/model/MstyleSource.js

Lines changed: 35 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,47 @@
11

2-
//import Store from '../Store';
3-
import Mstyle from './Mstyle';
42
import Msource from './Msource';
3+
import Mstyle from './Mstyle';
4+
55
import NameFromURL from '../utility/NameFromURL';
6+
import SourceReader from '../utility/SourceReader';
67

78
export default {
89
addFromSource:function(sourceUrl){
910
return new Promise((resolve,reject)=>{
10-
const rec = {
11-
name:NameFromURL.get(sourceUrl)
12-
};
13-
Mstyle.add(rec).then((style)=>{
14-
Mstyle.define(style);
15-
console.log('style defined:',style);
16-
// add source
17-
Msource.add({
18-
url:sourceUrl,
19-
type:'vector'
20-
}).then((source)=>{
21-
//console.log('added source:',source);
22-
const json = Msource.getJson(source.url);
23-
console.log('added source json:',json);
24-
const center = [
25-
json.getIn(['center',0]),
26-
json.getIn(['center',1])
27-
];
28-
if (json.has('center')) Mstyle.setIn(['center'],center);
29-
if (json.has('maxzoom') && json.has('minzoom')){
30-
const zoom = json.getIn(['center',2]) || (json.get('maxzoom') - json.get('minzoom'))/2;
31-
Mstyle.setIn(['zoom'],zoom);
32-
}
33-
Mstyle.save();
34-
return resolve(style);
11+
SourceReader.load(sourceUrl).then(()=>{
12+
const rec = {
13+
name:NameFromURL.get(sourceUrl)
14+
};
15+
Mstyle.add(rec).then((style)=>{
16+
Mstyle.define(style);
17+
//console.log('style defined:',style);
18+
// add source
19+
Msource.add({
20+
url:sourceUrl,
21+
type:'vector'
22+
}).then((source)=>{
23+
//console.log('added source:',source);
24+
const json = Msource.getJson(source.url);
25+
console.log('added source json:',json);
26+
const center = [
27+
json.getIn(['center',0]),
28+
json.getIn(['center',1])
29+
];
30+
if (json.has('center')) Mstyle.setIn(['center'],center);
31+
if (json.has('maxzoom') && json.has('minzoom')){
32+
const zoom = json.getIn(['center',2]) || (json.get('maxzoom') - json.get('minzoom'))/2;
33+
Mstyle.setIn(['zoom'],zoom);
34+
}
35+
Mstyle.save();
36+
return resolve(style);
37+
}).catch((e)=>{
38+
reject({message:'source not found'});
39+
});
40+
}).catch((e)=>{
41+
reject(e);
3542
});
3643
}).catch((e)=>{
37-
reject(e);
44+
reject({message:'source not found'});
3845
});
3946
});
4047
},

src/page/Pstyle.jsx

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1+
import PropTypes from 'prop-types';
12
import React from 'react';
2-
33
import {connect} from 'react-redux';
44

55
import Mstyle from '../model/Mstyle';
66

7-
import Vstyle from '../view/Vstyle';
7+
import Valert from '../view/Valert';
88
import Vmap from '../view/Vmap';
9+
import Vstyle from '../view/Vstyle';
910

1011
const mapStoreToProps = (store)=>{
1112
return {
@@ -16,11 +17,18 @@ const mapStoreToProps = (store)=>{
1617
const mapDispatchToProps = {};
1718

1819
class Pstyle extends React.Component {
20+
21+
static propTypes = {
22+
error: PropTypes.oneOfType([
23+
PropTypes.string,
24+
PropTypes.object
25+
]),
26+
match: PropTypes.object,
27+
style: PropTypes.object
28+
}
29+
1930
constructor(props) {
2031
super(props);
21-
this.state = {
22-
styleRec:undefined
23-
};
2432

2533
//styles.do();
2634
this.id = props.match.params.id;
@@ -51,18 +59,17 @@ class Pstyle extends React.Component {
5159
}
5260
}
5361

54-
componentWillReceiveProps (nextProps){
55-
const {style, error} = nextProps;
56-
57-
this.setState({styleRec:style.get('rec')});
58-
}
59-
6062
render (){
6163
const {style, match, error} = this.props;
6264

6365
return <div>
64-
<Vmap handle={this.handle} style={style.get('rec')} match={match} error={error}/>
65-
<Vstyle handle={this.handle} style={style.get('rec')} match={match} error={error}/>
66+
<Vmap handle={this.handle} style={style.get('rec')} match={match}/>
67+
<Vstyle handle={this.handle} style={style.get('rec')} match={match}/>
68+
<div className="fixed-bottom p-2">
69+
{error.has('general') &&
70+
<Valert message={error.get('general')}/>
71+
}
72+
</div>
6673
</div>
6774
}
6875
};

src/utility/SourceReader.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ export default {
1010
//if (!response.data.maps) return reject('no maps defined on source');
1111
return resolve(response.data);
1212
})
13-
.catch(function (error) {
14-
return reject(error);
13+
.catch(function (error){
14+
return reject('not found');
1515
});
1616
});
1717
}

src/view/Valert.jsx

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@ export default class Valert extends React.Component {
44
constructor(props){
55
super(props);
66
this.state = {
7-
closed:false,
7+
show:true,
88
message:null
99
}
1010
this.handle = {
1111
close:()=>{
12-
this.setState({closed:true});
12+
this.setState({show:false});
1313
}
1414
};
1515
for (const i in this.handle){
@@ -18,19 +18,20 @@ export default class Valert extends React.Component {
1818
}
1919

2020
componentWillReceiveProps(nextProps){
21-
if (nextProps.message !== this.state.message){
21+
if (!this.state.show || nextProps.message !== this.state.message){
2222
this.setState({
2323
message:nextProps.message,
24-
closed:false
24+
show:true
2525
});
2626
}
2727
}
2828

2929
render (){
3030
const {message} = this.props;
3131

32-
let className = 'alert alert-danger m-2 alert-dismissible fade';
33-
if (!this.state.closed) className += ' show';
32+
if (!message || !this.state.show) return <div/>
33+
34+
let className = 'alert alert-danger alert-dismissible fade show mb-0';
3435
return <div className={className}>
3536
{message}
3637
<button onClick={this.handle.close} type="button" className="close" aria-label="Close">

src/view/Vdropdown/index.jsx

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import React from 'react';
2+
import ReactDOM from 'react-dom';
3+
import PropTypes from 'prop-types';
4+
5+
export default class Vdropdown extends React.Component {
6+
7+
static propTypes = {
8+
elem: PropTypes.object.isRequired, // dom ref to render the dropdown around
9+
scrollElem: PropTypes.object,
10+
show: PropTypes.bool
11+
}
12+
13+
render(){
14+
const {elem, scrollElem, show} = this.props;
15+
16+
// if in bottom of window, project upwards
17+
const winRect = elem.getBoundingClientRect(); // {top, bottom, left, right}
18+
19+
// get scrollTop offset
20+
21+
const offsetTop = (scrollElem && scrollElem.offsetTop)? scrollElem.offsetTop: 0;
22+
const offsetLeft = (scrollElem && scrollElem.offsetLeft)? scrollElem.offsetLeft: 0;
23+
24+
const style = {
25+
top:(winRect.bottom+offsetTop)+'px',
26+
left:(winRect.left+offsetLeft)+'px'
27+
};
28+
const dropdownClass = 'dropdown-menu'+(show?' show':'');
29+
30+
console.log('rendered dropdown:',winRect,offsetTop,offsetLeft);
31+
32+
return ReactDOM.createPortal(
33+
<div style={style} className={dropdownClass}>
34+
{this.props.children}
35+
</div>,
36+
document.body
37+
);
38+
}
39+
};

0 commit comments

Comments
 (0)