Show UPRNs in building view

- add /building/id/uprns.json endpoint
- hide children behind details

[Closes #83]
This commit is contained in:
Tom Russell 2018-10-25 14:36:52 +01:00
parent 4934e0757b
commit 7b8b4226c9
6 changed files with 104 additions and 8 deletions

View File

@ -83,6 +83,16 @@ function getBuildingById(id) {
}); });
} }
function getBuildingUPRNsById(id) {
return db.any(
"SELECT uprn, parent_uprn FROM building_properties WHERE building_id = $1",
[id]
).catch(function(error){
console.error(error);
return undefined;
});
}
function saveBuilding(building_id, building, user_id) { function saveBuilding(building_id, building, user_id) {
// save building could fail if the revision seen by the user != the latest revision // save building could fail if the revision seen by the user != the latest revision
// - any 'intuitive' retries would need to be handled by clients of this code // - any 'intuitive' retries would need to be handled by clients of this code
@ -244,5 +254,5 @@ function compare(old_obj, new_obj, whitelist){
return [forward_patch, reverse_patch] return [forward_patch, reverse_patch]
} }
export { queryBuildingsAtPoint, queryBuildingsByReference, getBuildingById, saveBuilding, export { queryBuildingsAtPoint, queryBuildingsByReference, getBuildingById,
likeBuilding }; getBuildingUPRNsById, saveBuilding, likeBuilding };

View File

@ -51,7 +51,26 @@ class App extends React.Component {
} }
selectBuilding(building) { selectBuilding(building) {
this.setState({building: building}) // get UPRNs and update
fetch(`/building/${building.building_id}/uprns.json`, {
method: 'GET',
headers:{
'Content-Type': 'application/json'
},
credentials: 'same-origin'
}).then(
res => res.json()
).then((res) => {
if (res.error) {
console.error(res);
} else {
building.uprns = res.uprns;
this.setState({building: building});
}
}).catch((err) => {
console.error(err)
this.setState({building: building});
});
} }
render() { render() {

View File

@ -31,13 +31,19 @@ const BuildingView = (props) => {
building_id={props.building_id} building_id={props.building_id}
{...section_props}> {...section_props}>
{ {
section_props.fields.map(field_props => ( section_props.fields.map(field_props => {
return (field_props.slug === 'uprns')?
<UPRNsDataEntry
title={field_props.title}
value={props.uprns}
tooltip={field_props.tooltip} />
:
<DataEntry <DataEntry
key={field_props.slug} key={field_props.slug}
title={field_props.title} title={field_props.title}
value={props[field_props.slug]} value={props[field_props.slug]}
tooltip={field_props.tooltip} /> tooltip={field_props.tooltip} />
)) })
} }
</DataSection> </DataSection>
)) ))
@ -101,4 +107,40 @@ const DataEntry = (props) => (
</Fragment> </Fragment>
); );
const UPRNsDataEntry = (props) => {
const uprns = props.value || [];
const no_parent = uprns.filter(uprn => uprn.parent_uprn == null);
const with_parent = uprns.filter(uprn => uprn.parent_uprn != null);
return (
<Fragment>
<dt>
{ props.title }
{ props.tooltip? <Tooltip text={ props.tooltip } /> : null }
</dt>
<dd><ul className="uprn-list">
<Fragment>{
no_parent.length?
no_parent.map(uprn => (
<li>{uprn.uprn}</li>
))
: '\u00A0'
}</Fragment>
{
with_parent.length?
<details>
<summary>Children</summary>
{
with_parent.map(uprn => (
<li>{uprn.uprn} (child of {uprn.parent_uprn})</li>
))
}
</details>
: null
}
</ul></dd>
</Fragment>
)
}
export default BuildingView; export default BuildingView;

View File

@ -20,7 +20,7 @@
"disabled": true "disabled": true
}, },
{ {
"title": "UPRNs", "slug": "ref_uprn", "type": "list", "title": "UPRNs", "slug": "uprns", "type": "list",
"tooltip": "Unique Property Reference Numbers (to be filled automatically)", "tooltip": "Unique Property Reference Numbers (to be filled automatically)",
"disabled": true "disabled": true
}, },

View File

@ -258,3 +258,7 @@
.data-list .no-data { .data-list .no-data {
color: #999; color: #999;
} }
.data-list dd ul {
list-style: none;
padding-left: 0;
}

View File

@ -18,7 +18,7 @@ import App from './frontend/app';
import db from './db'; import db from './db';
import { authUser, createUser, getUserById, authAPIUser, getNewUserAPIKey } from './user'; import { authUser, createUser, getUserById, authAPIUser, getNewUserAPIKey } from './user';
import { queryBuildingsAtPoint, queryBuildingsByReference, getBuildingById, import { queryBuildingsAtPoint, queryBuildingsByReference, getBuildingById,
saveBuilding, likeBuilding } from './building'; getBuildingUPRNsById, saveBuilding, likeBuilding } from './building';
import tileserver from './tileserver'; import tileserver from './tileserver';
import { parseBuildingURL } from './parse'; import { parseBuildingURL } from './parse';
@ -76,15 +76,20 @@ function frontendRoute(req, res) {
Promise.all([ Promise.all([
req.session.user_id? getUserById(req.session.user_id) : undefined, req.session.user_id? getUserById(req.session.user_id) : undefined,
is_building? getBuildingById(building_id) : undefined is_building? getBuildingById(building_id) : undefined,
is_building? getBuildingUPRNsById(building_id) : undefined
]).then(function(values){ ]).then(function(values){
const user = values[0]; const user = values[0];
const building = values[1]; const building = values[1];
const uprns = values[2];
if (is_building && typeof(building) === "undefined"){ if (is_building && typeof(building) === "undefined"){
context.status = 404 context.status = 404
} }
data.user = user; data.user = user;
data.building = building; data.building = building;
if (data.building != null) {
data.building.uprns = uprns
}
renderHTML(context, data, req, res) renderHTML(context, data, req, res)
}).catch(error => { }).catch(error => {
console.error(error); console.error(error);
@ -218,6 +223,22 @@ function updateBuilding(req, res, user_id){
) )
} }
server.get('/building/:building_id/uprns.json', function (req, res) {
const { building_id } = req.params;
getBuildingUPRNsById(building_id).then(function(result){
if (typeof(result) === "undefined") {
res.send({error:'Database error'})
return
}
res.send({
uprns: result
});
}).catch(function(error){
console.error(error);
res.send({error:'Database error'})
})
})
// POST like building // POST like building
server.post('/building/like/:building_id', function(req, res){ server.post('/building/like/:building_id', function(req, res){
if (!req.session.user_id) { if (!req.session.user_id) {