Merge pull request from tomalrussell/fix/multi-edit

Fix/multi edit
This commit is contained in:
mz8i 2019-10-03 15:33:16 +01:00 committed by GitHub
commit c14ee75eec
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 52 additions and 79 deletions
app/src/frontend
building
data-containers
multi-edit.tsx
map-app.tsx
map

View File

@ -17,6 +17,7 @@ const AgeView = (props) => (
upper={props.building.date_upper}
lower={props.building.date_lower}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
/>
<NumericDataEntry

View File

@ -5,9 +5,9 @@ import PropTypes from 'prop-types';
import Sidebar from './sidebar';
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) => {
if (!props.user){
@ -19,8 +19,8 @@ const MultiEdit = (props) => {
return (
<Sidebar>
<section className='data-section'>
<header className={`section-header view ${cat} active`}>
<a><h3 className="h3">Like me!</h3></a>
<header className={`section-header view ${cat} background-${cat}`}>
<h2 className="h2">Like me!</h2>
</header>
<form className='buttons-container'>
<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 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 (
<Sidebar>
<section className='data-section'>
<header className={`section-header view ${cat} active`}>
<a><h3 className="h3">{title}</h3></a>
<header className={`section-header view ${cat} background-${cat}`}>
<Link
className="icon-button back"
to={`/edit/${cat}`}>
<BackIcon />
</Link>
<h2 className="h2">Copy {cat} data</h2>
</header>
<Fragment>
<form>
<InfoBox msg='Click buildings one at a time to colour using the data below' />
{
Object.keys(data).map((key => {
const label = fieldTitleFromSlug(key);
return <DataEntry key={key} label={label} value={data[key]}/>
return (
<DataEntry
title={key}
slug={key}
disabled={true}
value={data[key]}
/>
)
}))
}
</Fragment>
</form>
<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={`/edit/${cat}`} className='btn btn-secondary'>Back to edit</Link>
</form>
@ -67,63 +89,4 @@ MultiEdit.propTypes = {
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;

View File

@ -142,11 +142,17 @@ class MapApp extends React.Component<MapAppProps, MapAppState> {
colourBuilding(building) {
const cat = this.props.match.params.category;
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') {
this.likeBuilding(building.building_id)
} 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;

View File

@ -83,8 +83,11 @@ class ColouringMap extends Component<ColouringMapProps, ColouringMapState> { //
this.props.selectBuilding(undefined);
}
} else {
// deselect but keep/return to expected colour theme
this.props.selectBuilding(undefined);
if (mode !== 'multi-edit') {
// 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(
(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 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 baseLayer = <TileLayer
const baseLayer = <TileLayer
url={baseUrl}
attribution={attribution}
/>;