diff --git a/app/src/frontend/building/data-containers/age.tsx b/app/src/frontend/building/data-containers/age.tsx index 7befa7a0..e7baa880 100644 --- a/app/src/frontend/building/data-containers/age.tsx +++ b/app/src/frontend/building/data-containers/age.tsx @@ -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 diff --git a/app/src/frontend/building/multi-edit.tsx b/app/src/frontend/building/multi-edit.tsx index a408153b..28b675f6 100644 --- a/app/src/frontend/building/multi-edit.tsx +++ b/app/src/frontend/building/multi-edit.tsx @@ -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; diff --git a/app/src/frontend/map-app.tsx b/app/src/frontend/map-app.tsx index 9f77ee99..5191f3fe 100644 --- a/app/src/frontend/map-app.tsx +++ b/app/src/frontend/map-app.tsx @@ -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; \ No newline at end of file +export default MapApp; diff --git a/app/src/frontend/map/map.tsx b/app/src/frontend/map/map.tsx index e96fd28c..84697c36 100644 --- a/app/src/frontend/map/map.tsx +++ b/app/src/frontend/map/map.tsx @@ -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} />;