Merge pull request #455 from tomalrussell/fix/multi-edit
Fix/multi edit
This commit is contained in:
commit
c14ee75eec
app/src/frontend
@ -17,6 +17,7 @@ const AgeView = (props) => (
|
|||||||
upper={props.building.date_upper}
|
upper={props.building.date_upper}
|
||||||
lower={props.building.date_lower}
|
lower={props.building.date_lower}
|
||||||
mode={props.mode}
|
mode={props.mode}
|
||||||
|
copy={props.copy}
|
||||||
onChange={props.onChange}
|
onChange={props.onChange}
|
||||||
/>
|
/>
|
||||||
<NumericDataEntry
|
<NumericDataEntry
|
||||||
|
@ -5,9 +5,9 @@ import PropTypes from 'prop-types';
|
|||||||
|
|
||||||
import Sidebar from './sidebar';
|
import Sidebar from './sidebar';
|
||||||
import InfoBox from '../components/info-box';
|
import InfoBox from '../components/info-box';
|
||||||
import { sanitiseURL } from '../helpers';
|
import { BackIcon }from '../components/icons';
|
||||||
|
import DataEntry from './data-components/data-entry';
|
||||||
|
|
||||||
const CONFIG = [];
|
|
||||||
|
|
||||||
const MultiEdit = (props) => {
|
const MultiEdit = (props) => {
|
||||||
if (!props.user){
|
if (!props.user){
|
||||||
@ -19,8 +19,8 @@ const MultiEdit = (props) => {
|
|||||||
return (
|
return (
|
||||||
<Sidebar>
|
<Sidebar>
|
||||||
<section className='data-section'>
|
<section className='data-section'>
|
||||||
<header className={`section-header view ${cat} active`}>
|
<header className={`section-header view ${cat} background-${cat}`}>
|
||||||
<a><h3 className="h3">Like me!</h3></a>
|
<h2 className="h2">Like me!</h2>
|
||||||
</header>
|
</header>
|
||||||
<form className='buttons-container'>
|
<form className='buttons-container'>
|
||||||
<InfoBox msg='Click all the buildings that you like and think contribute to the city!' />
|
<InfoBox msg='Click all the buildings that you like and think contribute to the city!' />
|
||||||
@ -34,25 +34,47 @@ const MultiEdit = (props) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const q = parse(props.location.search);
|
const q = parse(props.location.search);
|
||||||
const data = JSON.parse(q.data as string) // TODO: verify what happens when data is string[]
|
|
||||||
const title = sectionTitleFromCat(cat);
|
let data: object;
|
||||||
|
if (cat === 'like'){
|
||||||
|
data = { like: true }
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
// TODO: verify what happens if data is string[]
|
||||||
|
data = JSON.parse(q.data as string);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error, q)
|
||||||
|
data = {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Sidebar>
|
<Sidebar>
|
||||||
<section className='data-section'>
|
<section className='data-section'>
|
||||||
<header className={`section-header view ${cat} active`}>
|
<header className={`section-header view ${cat} background-${cat}`}>
|
||||||
<a><h3 className="h3">{title}</h3></a>
|
<Link
|
||||||
|
className="icon-button back"
|
||||||
|
to={`/edit/${cat}`}>
|
||||||
|
<BackIcon />
|
||||||
|
</Link>
|
||||||
|
<h2 className="h2">Copy {cat} data</h2>
|
||||||
</header>
|
</header>
|
||||||
<Fragment>
|
<form>
|
||||||
|
<InfoBox msg='Click buildings one at a time to colour using the data below' />
|
||||||
{
|
{
|
||||||
Object.keys(data).map((key => {
|
Object.keys(data).map((key => {
|
||||||
const label = fieldTitleFromSlug(key);
|
return (
|
||||||
return <DataEntry key={key} label={label} value={data[key]}/>
|
<DataEntry
|
||||||
|
title={key}
|
||||||
|
slug={key}
|
||||||
|
disabled={true}
|
||||||
|
value={data[key]}
|
||||||
|
/>
|
||||||
|
)
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
</Fragment>
|
</form>
|
||||||
<form className='buttons-container'>
|
<form className='buttons-container'>
|
||||||
<InfoBox msg='Click buildings to colour using the data above' />
|
|
||||||
|
|
||||||
<Link to={`/view/${cat}`} className='btn btn-secondary'>Back to view</Link>
|
<Link to={`/view/${cat}`} className='btn btn-secondary'>Back to view</Link>
|
||||||
<Link to={`/edit/${cat}`} className='btn btn-secondary'>Back to edit</Link>
|
<Link to={`/edit/${cat}`} className='btn btn-secondary'>Back to edit</Link>
|
||||||
</form>
|
</form>
|
||||||
@ -67,63 +89,4 @@ MultiEdit.propTypes = {
|
|||||||
location: PropTypes.object
|
location: PropTypes.object
|
||||||
}
|
}
|
||||||
|
|
||||||
const DataEntry = (props) => {
|
|
||||||
let content;
|
|
||||||
|
|
||||||
if (props.value != null && props.value !== '') {
|
|
||||||
if (typeof(props.value) === 'boolean') {
|
|
||||||
content = (props.value)? 'Yes' : 'No'
|
|
||||||
} else if (Array.isArray(props.value)) {
|
|
||||||
if (props.value.length) {
|
|
||||||
content = <ul>{
|
|
||||||
props.value.map((item, index) => {
|
|
||||||
return <li key={index}><a href={sanitiseURL(item)}>{item}</a></li>
|
|
||||||
})
|
|
||||||
}</ul>
|
|
||||||
} else {
|
|
||||||
content = '\u00A0'
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
content = props.value
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
content = '\u00A0'
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Fragment>
|
|
||||||
<dt>{props.label}</dt>
|
|
||||||
<dd>{content}</dd>
|
|
||||||
</Fragment>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
function sectionTitleFromCat(cat) {
|
|
||||||
for (let index = 0; index < CONFIG.length; index++) {
|
|
||||||
const section = CONFIG[index];
|
|
||||||
if (section.slug === cat) {
|
|
||||||
return section.title
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return undefined
|
|
||||||
}
|
|
||||||
|
|
||||||
function fieldTitleFromSlug(slug) {
|
|
||||||
const fields = CONFIG.reduce(
|
|
||||||
(prev, section) => {
|
|
||||||
const el = prev.concat(
|
|
||||||
section.fields.filter(
|
|
||||||
(field: any) => field.slug === slug // TODO: remove any
|
|
||||||
)
|
|
||||||
)
|
|
||||||
return el
|
|
||||||
}, []
|
|
||||||
)
|
|
||||||
if (fields.length === 1 && fields[0].title) {
|
|
||||||
return fields[0].title
|
|
||||||
} else {
|
|
||||||
console.error('Expected single match, got', fields)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default MultiEdit;
|
export default MultiEdit;
|
||||||
|
@ -142,11 +142,17 @@ class MapApp extends React.Component<MapAppProps, MapAppState> {
|
|||||||
colourBuilding(building) {
|
colourBuilding(building) {
|
||||||
const cat = this.props.match.params.category;
|
const cat = this.props.match.params.category;
|
||||||
const q = parse(window.location.search);
|
const q = parse(window.location.search);
|
||||||
const data = (cat === 'like') ? { like: true } : JSON.parse(q.data as string); // TODO: verify what happens if data is string[]
|
|
||||||
if (cat === 'like') {
|
if (cat === 'like') {
|
||||||
this.likeBuilding(building.building_id)
|
this.likeBuilding(building.building_id)
|
||||||
} else {
|
} else {
|
||||||
this.updateBuilding(building.building_id, data)
|
try {
|
||||||
|
// TODO: verify what happens if data is string[]
|
||||||
|
const data = JSON.parse(q.data as string);
|
||||||
|
this.updateBuilding(building.building_id, data)
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error, q)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -245,4 +251,4 @@ class MapApp extends React.Component<MapAppProps, MapAppState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default MapApp;
|
export default MapApp;
|
||||||
|
@ -83,8 +83,11 @@ class ColouringMap extends Component<ColouringMapProps, ColouringMapState> { //
|
|||||||
this.props.selectBuilding(undefined);
|
this.props.selectBuilding(undefined);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// deselect but keep/return to expected colour theme
|
if (mode !== 'multi-edit') {
|
||||||
this.props.selectBuilding(undefined);
|
// deselect but keep/return to expected colour theme
|
||||||
|
// except if in multi-edit (never select building, only colour on click)
|
||||||
|
this.props.selectBuilding(undefined);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}.bind(this)).catch(
|
}.bind(this)).catch(
|
||||||
(err) => console.error(err)
|
(err) => console.error(err)
|
||||||
@ -106,7 +109,7 @@ class ColouringMap extends Component<ColouringMapProps, ColouringMapState> { //
|
|||||||
const layer = (this.state.theme === 'light')? 'Light 3857' : 'Night 3857';
|
const layer = (this.state.theme === 'light')? 'Light 3857' : 'Night 3857';
|
||||||
const baseUrl = `https://api2.ordnancesurvey.co.uk/mapping_api/v1/service/zxy/${tilematrixSet}/${layer}/{z}/{x}/{y}.png?key=${key}`;
|
const baseUrl = `https://api2.ordnancesurvey.co.uk/mapping_api/v1/service/zxy/${tilematrixSet}/${layer}/{z}/{x}/{y}.png?key=${key}`;
|
||||||
const attribution = 'Building attribute data is © Colouring London contributors. Maps contain OS data © Crown copyright: OS Maps baselayers and building outlines. <a href=/ordnance-survey-licence.html>OS licence</a>';
|
const attribution = 'Building attribute data is © Colouring London contributors. Maps contain OS data © Crown copyright: OS Maps baselayers and building outlines. <a href=/ordnance-survey-licence.html>OS licence</a>';
|
||||||
const baseLayer = <TileLayer
|
const baseLayer = <TileLayer
|
||||||
url={baseUrl}
|
url={baseUrl}
|
||||||
attribution={attribution}
|
attribution={attribution}
|
||||||
/>;
|
/>;
|
||||||
|
Loading…
Reference in New Issue
Block a user