Merge pull request #1200 from colouring-cities/interface/ui-tweaks

Interface/UI tweaks
This commit is contained in:
Mike Simpson 2023-06-29 15:43:07 +01:00 committed by GitHub
commit f855c8d3f2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 1655 additions and 1622 deletions

View File

@ -59,6 +59,10 @@ export const buildingAttributesConfig = valueType<DataFieldConfig>()({ /* eslint
edit: true,
verify: true,
},
location_name_link: {
edit: true,
verify: true,
},
location_number: {
edit: true,
verify: true,
@ -103,6 +107,10 @@ export const buildingAttributesConfig = valueType<DataFieldConfig>()({ /* eslint
edit: true,
verify: true
},
location_alternative_footprint_links: {
edit: true,
verify: true
},
date_year: {
edit: true,
verify: true,
@ -482,6 +490,10 @@ export const buildingAttributesConfig = valueType<DataFieldConfig>()({ /* eslint
edit: true,
verify: true
},
developer_links: {
edit: true,
verify: true
},
developer_source_type: {
edit: true,
verify: true
@ -494,6 +506,10 @@ export const buildingAttributesConfig = valueType<DataFieldConfig>()({ /* eslint
edit: true,
verify: true
},
landowner_links: {
edit: true,
verify: true
},
landowner_source_type: {
edit: true,
verify: true
@ -506,6 +522,10 @@ export const buildingAttributesConfig = valueType<DataFieldConfig>()({ /* eslint
edit: true,
verify: true
},
designers_links: {
edit: true,
verify: true
},
designers_source_type: {
edit: true,
verify: true
@ -530,6 +550,10 @@ export const buildingAttributesConfig = valueType<DataFieldConfig>()({ /* eslint
edit: true,
verify: true
},
builder_links: {
edit: true,
verify: true
},
builder_source_type: {
edit: true,
verify: true
@ -685,6 +709,38 @@ export const buildingAttributesConfig = valueType<DataFieldConfig>()({ /* eslint
age_retrofit_date_source_links : {
edit: true,
verify: true
},
age_historical_raster_map_links : {
edit: true,
verify: true
},
age_historical_vectorised_footprint_links : {
edit: true,
verify: true
},
energy_solar : {
edit: true,
verify: true
},
energy_solar_source_type : {
edit: true,
verify: true
},
energy_solar_source_links : {
edit: true,
verify: true
},
energy_green_roof : {
edit: true,
verify: true
},
energy_green_roof_source_type : {
edit: true,
verify: true
},
energy_green_roof_source_links : {
edit: true,
verify: true
}
});

View File

@ -69,83 +69,89 @@ export const MultiDataEntry: React.FC<MultiDataEntryProps> = ({
copy={copyable ? props.copy : undefined}
/>
<div id={`${props.slug}-wrapper`}>
{
values.length === 0 && !isEditing &&
<div className="input-group">
<input className="form-control no-entries" type="text" value="No entries" disabled={true} />
</div>
}
<ul className="data-entry-list">
{
values.length === 0 && !isEditing &&
isEditing && isDisabled && values.length === 0 &&
<div className="input-group">
<input className="form-control no-entries" type="text" value="No entries" disabled={true} />
<input className="form-control no-entries" type="text" value="Please add a link below" disabled={true} />
</div>
}
<ul className="data-entry-list">
{
values.map((val, i) => (
<li className="input-group" key={i /* i as key prevents input component recreation on edit */}>
<DataEntryInput
slug={props.slug}
name={`${slugWithModifier}-${i}`}
id={`${slugWithModifier}-${i}`}
value={val}
disabled={!editableEntries || isDisabled}
onChange={(_key, val) => edit(i, val)}
{
values.map((val, i) => (
<li className="input-group" key={i /* i as key prevents input component recreation on edit */}>
<DataEntryInput
slug={props.slug}
name={`${slugWithModifier}-${i}`}
id={`${slugWithModifier}-${i}`}
value={val}
disabled={!editableEntries || isDisabled}
onChange={(_key, val) => edit(i, val)}
maxLength={props.maxLength}
isUrl={props.isUrl}
valueTransform={props.valueTransform}
maxLength={props.maxLength}
isUrl={props.isUrl}
valueTransform={props.valueTransform}
autofill={props.autofill}
showAllOptionsOnEmpty={props.showAllOptionsOnEmpty}
/>
{
!isDisabled &&
<div className="input-group-append">
<button type="button" onClick={() => remove(i)}
title="Remove"
data-index={i} className="btn btn-outline-dark data-entry-list-button"><CloseIcon /></button>
</div>
}
</li>
))
}
{
!isDisabled &&
<li className="input-group">
<DataEntryInput
slug={props.slug}
name={slugWithModifier}
id={slugWithModifier}
value={newValue}
disabled={props.disabled}
required={props.required && values.length < 1}
onChange={(_key, val) => setNewValue(val)}
onConfirm={(_key, val) => addNew(val)}
autofill={props.autofill}
showAllOptionsOnEmpty={props.showAllOptionsOnEmpty}
/>
{
!isDisabled &&
<div className="input-group-append">
<button type="button" onClick={() => remove(i)}
title="Remove"
data-index={i} className="btn btn-outline-dark data-entry-list-button"><CloseIcon /></button>
</div>
}
</li>
))
}
{
!isDisabled &&
<li className="input-group">
<DataEntryInput
slug={props.slug}
name={slugWithModifier}
id={slugWithModifier}
value={newValue}
disabled={props.disabled}
required={props.required && values.length < 1}
onChange={(_key, val) => setNewValue(val)}
onConfirm={(_key, val) => addNew(val)}
maxLength={props.maxLength}
placeholder={props.placeholder}
isUrl={props.isUrl}
valueTransform={props.valueTransform}
confirmOnEnter={confirmOnEnter}
maxLength={props.maxLength}
placeholder={props.placeholder}
isUrl={props.isUrl}
valueTransform={props.valueTransform}
confirmOnEnter={confirmOnEnter}
autofill={props.autofill}
showAllOptionsOnEmpty={props.showAllOptionsOnEmpty}
confirmOnAutofillSelect={true}
/>
{
newValue != undefined &&
<>
<div className="input-group-append">
<button type="button"
className="btn btn-primary data-entry-list-button"
title="Confirm new value"
onClick={() => addNew()}
><SaveIcon /></button>
</div>
<div className="input-group-append">
<button type="button" onClick={() => clearNew()}
title="Clear new value"
className="btn btn-warning data-entry-list-button"><CloseIcon /></button>
</div>
</>
}
</li>
autofill={props.autofill}
showAllOptionsOnEmpty={props.showAllOptionsOnEmpty}
confirmOnAutofillSelect={true}
/>
{
newValue != undefined &&
<>
<div className="input-group-append">
<button type="button"
className="btn btn-primary data-entry-list-button"
title="Confirm new value"
onClick={() => addNew()}
><SaveIcon /></button>
</div>
<div className="input-group-append">
<button type="button" onClick={() => clearNew()}
title="Clear new value"
className="btn btn-warning data-entry-list-button"><CloseIcon /></button>
</div>
</>
}
</li>
}
</ul>
</div>

View File

@ -12,11 +12,20 @@ interface PatternDataEntryProps extends BaseDataEntryProps {
*/
pattern: string;
maxLength?: number;
valueTransform?: (val: string) => string;
}
export const PatternDataEntry: React.FC<PatternDataEntryProps> = props => {
const handleChange = (value: string) => {
props.onChange?.(props.slug, value);
props.onChange?.(props.slug, transformValue(value));
};
const transformValue = (value: string) => {
const transform = props.valueTransform || (x => x);
const transformedValue = value === '' ?
null :
transform(value);
return transformedValue;
};
return (

View File

@ -54,383 +54,6 @@ const AgeView: React.FunctionComponent<CategoryViewProps> = (props) => {
}
}
if (props.building.date_source == "Expert knowledge of building" ||
props.building.date_source == "Expert estimate from image" ||
props.building.date_source == null
){
return (
<Fragment>
<DataEntryGroup name="Building age">
<YearDataEntry
year={props.building.date_year}
upper={props.building.date_upper}
lower={props.building.date_lower}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
allow_verify={props.user !== undefined && props.building.date_year !== null && !props.edited}
onVerify={props.onVerify}
user_verified={props.user_verified.hasOwnProperty("date_year")}
user_verified_as={props.user_verified.date_year}
verified_count={props.building.verified.date_year}
allow_verify_upper={props.user !== undefined && props.building.date_upper !== null && !props.edited}
onVerify_upper={props.onVerify}
user_verified_upper={props.user_verified.hasOwnProperty("date_upper")}
user_verified_as_upper={props.user_verified.date_upper}
verified_count_upper={props.building.verified.date_upper}
allow_verify_lower={props.user !== undefined && props.building.date_lower !== null && !props.edited}
onVerify_lower={props.onVerify}
user_verified_lower={props.user_verified.hasOwnProperty("date_lower")}
user_verified_as_lower={props.user_verified.date_lower}
verified_count_lower={props.building.verified.date_lower}
/>
<NumericDataEntry
title={dataFields.facade_year.title}
slug="facade_year"
value={props.building.facade_year}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
step={1}
min={1}
max={currentYear}
tooltip={dataFields.facade_year.tooltip}
/>
<Verification
slug="facade_year"
allow_verify={props.user !== undefined && props.building.facade_year !== null && !props.edited}
onVerify={props.onVerify}
user_verified={props.user_verified.hasOwnProperty("facade_year")}
user_verified_as={props.user_verified.facade_year}
verified_count={props.building.verified.facade_year}
/>
<SelectDataEntry
title={dataFields.date_source.title}
slug="date_source"
value={props.building.date_source}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
tooltip={dataFields.date_source.tooltip}
placeholder={dataFields.date_source.example}
options={dataFields.date_source.items}
/>
{(props.building.date_source == dataFields.date_source.items[0] ||
props.building.date_source == dataFields.date_source.items[1] ||
props.building.date_source == null) ? <></> :
<>
<MultiDataEntry
title={dataFields.date_link.title}
slug="date_link"
value={props.building.date_link}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
tooltip={dataFields.date_link.tooltip}
placeholder="https://..."
editableEntries={true}
isUrl={true}
/>
</>
}
</DataEntryGroup>
<DataEntryGroup name="Cladding, extensions and retrofits">
<NumericDataEntry
slug='age_cladding_date'
title={dataFields.age_cladding_date.title}
value={props.building.age_cladding_date}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
step={1}
min={1}
max={currentYear}
tooltip={dataFields.extension_year.tooltip}
/>
<Verification
slug="age_cladding_date"
allow_verify={props.user !== undefined && props.building.age_cladding_date !== null && !props.edited}
onVerify={props.onVerify}
user_verified={props.user_verified.hasOwnProperty("age_cladding_date")}
user_verified_as={props.user_verified.age_cladding_date}
verified_count={props.building.verified.age_cladding_date}
/>
<SelectDataEntry
title={dataFields.age_cladding_date_source_type.title}
slug="age_cladding_date_source_type"
value={props.building.age_cladding_date_source_type}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
tooltip={dataFields.age_cladding_date_source_type.tooltip}
options={dataFields.age_cladding_date_source_type.items}
placeholder={dataFields.age_cladding_date_source_type.example}
/>
{(props.building.age_cladding_date_source_type == dataFields.age_cladding_date_source_type.items[0] ||
props.building.age_cladding_date_source_type == dataFields.age_cladding_date_source_type.items[1] ||
props.building.age_cladding_date_source_type == null) ? <></> :
<>
<MultiDataEntry
title={dataFields.age_cladding_date_source_links.title}
slug="age_cladding_date_source_links"
value={props.building.age_cladding_date_source_links}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
tooltip={dataFields.age_cladding_date_source_links.tooltip}
placeholder="https://..."
editableEntries={true}
isUrl={true}
/>
</>
}
<hr/>
<NumericDataEntry
slug='age_extension_date'
title={dataFields.age_extension_date.title}
value={props.building.age_extension_date}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
step={1}
min={1}
max={currentYear}
tooltip={dataFields.extension_year.tooltip}
/>
<Verification
slug="age_extension_date"
allow_verify={props.user !== undefined && props.building.age_extension_date !== null && !props.edited}
onVerify={props.onVerify}
user_verified={props.user_verified.hasOwnProperty("age_extension_date")}
user_verified_as={props.user_verified.age_extension_date}
verified_count={props.building.verified.age_extension_date}
/>
<SelectDataEntry
title={dataFields.age_extension_date_source_type.title}
slug="age_extension_date_source_type"
value={props.building.age_extension_date_source_type}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
tooltip={dataFields.age_extension_date_source_type.tooltip}
options={dataFields.age_extension_date_source_type.items}
placeholder={dataFields.age_extension_date_source_type.example}
/>
{(props.building.age_extension_date_source_type == dataFields.age_extension_date_source_type.items[0] ||
props.building.age_extension_date_source_type == dataFields.age_extension_date_source_type.items[1] ||
props.building.age_extension_date_source_type == null) ? <></> :
<>
<MultiDataEntry
title={dataFields.age_extension_date_source_links.title}
slug="age_extension_date_source_links"
value={props.building.age_extension_date_source_links}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
tooltip={dataFields.age_extension_date_source_links.tooltip}
placeholder="https://..."
editableEntries={true}
isUrl={true}
/>
</>
}
<hr/>
<NumericDataEntry
slug='age_retrofit_date'
title={dataFields.age_retrofit_date.title}
value={props.building.age_retrofit_date}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
step={1}
min={1}
max={currentYear}
tooltip={dataFields.extension_year.tooltip}
/>
<Verification
slug="age_retrofit_date"
allow_verify={props.user !== undefined && props.building.age_retrofit_date !== null && !props.edited}
onVerify={props.onVerify}
user_verified={props.user_verified.hasOwnProperty("age_retrofit_date")}
user_verified_as={props.user_verified.age_retrofit_date}
verified_count={props.building.verified.age_retrofit_date}
/>
<SelectDataEntry
title={dataFields.age_retrofit_date_source_type.title}
slug="age_retrofit_date_source_type"
value={props.building.age_retrofit_date_source_type}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
tooltip={dataFields.age_retrofit_date_source_type.tooltip}
options={dataFields.age_retrofit_date_source_type.items}
placeholder={dataFields.age_retrofit_date_source_type.example}
/>
{(props.building.age_retrofit_date_source_type == dataFields.age_retrofit_date_source_type.items[0] ||
props.building.age_retrofit_date_source_type == dataFields.age_retrofit_date_source_type.items[1] ||
props.building.age_retrofit_date_source_type == null) ? <></> :
<>
<MultiDataEntry
title={dataFields.age_retrofit_date_source_links.title}
slug="age_retrofit_date_source_links"
value={props.building.age_retrofit_date_source_links}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
tooltip={dataFields.age_retrofit_date_source_links.tooltip}
placeholder="https://..."
editableEntries={true}
isUrl={true}
/>
</>
}
</DataEntryGroup>
<DataEntryGroup name="Lifespan and site history">
<button className={`map-switcher-inline ${props.mapColourScale == "survival_status" ? "enabled-state" : "disabled-state"} btn btn-outline btn-outline-dark ${darkLightTheme}`} onClick={switchToSurvivalMapStyle}>
{(props.mapColourScale == "is_domestic")? 'Click here to hide historical maps':'Click here to show historical maps'}
</button>
<DataEntryGroup name="Constructions and demolitions on this site" showCount={false}>
<DynamicsBuildingPane>
<label>Current building (age data <Link to={ageLinkUrl}>editable here</Link>)</label>
<FieldRow>
<div>
<NumericDataEntry
slug=''
title={dataFields.demolished_buildings.items.year_constructed.title}
value={currentBuildingConstructionYear}
disabled={true}
mode='view'
/>
</div>
<div>
<NumericDataEntry
slug=''
title={dataFields.demolished_buildings.items.year_demolished.title}
value={undefined}
placeholder='---'
disabled={true}
mode='view'
/>
</div>
<div style={{flex: '0 1 27%'}}>
<DataEntry
slug=''
title='Lifespan to date'
value={ (thisYear - currentBuildingConstructionYear) + ''}
disabled={true}
mode='view'
/>
</div>
</FieldRow>
</DynamicsBuildingPane>
{
currentBuildingConstructionYear == undefined ?
<InfoBox>To add historical records, fill in the <Link to={ageLinkUrl}>Age</Link> data first.</InfoBox> :
<>
<LogicalDataEntry
slug='dynamics_has_demolished_buildings'
title={dataFields.dynamics_has_demolished_buildings.title}
value={building.dynamics_has_demolished_buildings}
disallowFalse={(building.demolished_buildings?.length ?? 0) > 0}
disallowNull={(building.demolished_buildings?.length ?? 0) > 0}
onChange={props.onSaveChange}
mode={props.mode}
copy={props.copy}
/>
{
building.dynamics_has_demolished_buildings &&
<>
<DynamicsDataEntry
/*
Will clear the edits and new record data upon navigating to another building.
Should get a better way to do this, plus a way to actually keep unsaved edits.
*/
key={building.building_id}
value={building.demolished_buildings}
editableEntries={true}
slug='demolished_buildings'
title={dataFields.demolished_buildings.title}
mode={props.mode}
onChange={props.onChange}
onSaveAdd={props.onSaveAdd}
hasEdits={props.edited}
maxYear={currentBuildingConstructionYear}
minYear={50}
/>
{
props.mode === 'view' &&
<InfoBox>Switch to edit mode to add/edit past building records</InfoBox>
}
</>
}
</>
}
</DataEntryGroup>
<InfoBox type='warning'>
This section is under development in collaboration with the historic environment sector.
Please let us know your suggestions on the <a href="https://discuss.colouring.london/t/dynamics-category-discussion/107">discussion forum</a>! (external link - save your edits first)
</InfoBox>
</DataEntryGroup>
<DataEntryGroup name="Survival and loss tracked using historical maps" collapsed={true} >
<div className={`alert alert-dark`} role="alert" style={{ fontSize: 13, backgroundColor: "#f6f8f9" }}>
<i>
Can you help us create a map that shows how many buildings in London have survived since the 1890s?
Choose a colour to indicate whether the building has survived.
</i>
</div>
<button className={`map-switcher-inline ${props.mapColourScale == "survival_status" ? "enabled-state" : "disabled-state"} btn btn-outline btn-outline-dark ${darkLightTheme}`} onClick={switchToSurvivalMapStyle}>
{(props.mapColourScale == "is_domestic")? 'Click here to hide historical maps':'Click here to show historical maps'}
</button>
<SelectDataEntry
title={dataFields.survival_status.title}
slug="survival_status"
value={props.building.survival_status}
tooltip={dataFields.survival_status.tooltip}
options={SurvivalStatusOptions}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
/>
<SelectDataEntry
title={dataFields.survival_source.title}
slug="survival_source"
value={props.building.survival_source}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
tooltip={dataFields.survival_source.tooltip}
placeholder={dataFields.survival_source.example}
options={dataFields.survival_source.items}
/>
{(props.building.survival_source == dataFields.survival_source_links[0] ||
props.building.survival_source == dataFields.survival_source_links[1] ||
props.building.survival_source == null) ? <></> :
<><MultiDataEntry
title={dataFields.survival_source_links.title}
slug="survival_source_links"
value={props.building.survival_source_links}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
tooltip={dataFields.survival_source_links.tooltip}
placeholder="https://..."
editableEntries={true}
isUrl={true}
/>
</>
}
</DataEntryGroup>
</Fragment>
);
};
return (
<Fragment>
<DataEntryGroup name="Building age">
@ -509,6 +132,13 @@ const AgeView: React.FunctionComponent<CategoryViewProps> = (props) => {
/>
</>
}
<DataEntry
title="Year of completion (best estimate)"
slug=""
value=""
mode='view'
tooltip='Coming Soon'
/>
</DataEntryGroup>
<DataEntryGroup name="Cladding, extensions and retrofits">
<NumericDataEntry
@ -751,7 +381,7 @@ const AgeView: React.FunctionComponent<CategoryViewProps> = (props) => {
Please let us know your suggestions on the <a href="https://discuss.colouring.london/t/dynamics-category-discussion/107">discussion forum</a>! (external link - save your edits first)
</InfoBox>
</DataEntryGroup>
<DataEntryGroup name="Survival and loss tracked using historical maps" collapsed={true} >
<DataEntryGroup name="Survival tracking" collapsed={true} >
<div className={`alert alert-dark`} role="alert" style={{ fontSize: 13, backgroundColor: "#f6f8f9" }}>
<i>
Can you help us create a map that shows how many buildings in London have survived since the 1890s?
@ -800,6 +430,40 @@ const AgeView: React.FunctionComponent<CategoryViewProps> = (props) => {
</>
}
</DataEntryGroup>
<DataEntryGroup name="Historical map data options" collapsed={true} >
<InfoBox type='warning'>
This section is under development
</InfoBox>
<div className={`alert alert-dark`} role="alert" style={{ fontSize: 13, backgroundColor: "#f6f8f9" }}>
<i>
This section provides links to open digitised historical maps/mapping data that we are using in the Colouring Cities platform.
</i>
</div>
<MultiDataEntry
title={dataFields.age_historical_raster_map_links.title}
slug="age_historical_raster_map_links"
value={props.building.age_historical_raster_map_links}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
tooltip={dataFields.age_historical_raster_map_links.tooltip}
placeholder="https://..."
editableEntries={true}
isUrl={true}
/>
<MultiDataEntry
title={dataFields.age_historical_vectorised_footprint_links.title}
slug="age_historical_vectorised_footprint_links"
value={props.building.age_historical_vectorised_footprint_links}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
tooltip={dataFields.age_historical_vectorised_footprint_links.tooltip}
placeholder="https://..."
editableEntries={true}
isUrl={true}
/>
</DataEntryGroup>
</Fragment>
);
};

View File

@ -1,4 +1,4 @@
import React from 'react';
import React, { Fragment } from 'react';
import '../../map/map-button.css';
import withCopyEdit from '../data-container';
@ -15,6 +15,7 @@ import SelectDataEntry from '../data-components/select-data-entry';
import Verification from '../data-components/verification';
import { MultiDataEntry } from '../data-components/multi-data-entry/multi-data-entry';
import { useDisplayPreferences } from '../../displayPreferences-context';
import DataEntry from '../data-components/data-entry';
/**
* Community view/edit section
@ -38,192 +39,199 @@ const CommunityView: React.FunctionComponent<CategoryViewProps> = (props) => {
}
const { darkLightTheme } = useDisplayPreferences();
const worthKeepingReasonsNonEmpty = Object.values(props.building.community_type_worth_keeping_reasons ?? {}).some(x => x);
return <>
<DataEntryGroup name="Community views on building types">
<div className={`alert alert-dark`} role="alert" style={{ fontSize: 13, backgroundColor: "#f6f8f9" }}>
<i>
Note: We are currently only collecting data on non-residential buildings.
</i>
</div>
<div className='community-opinion-pane'>
{(props.building.is_domestic === "no" || props.building.is_domestic === "mixed domestic/non-domestic") ?
<>
<UserOpinionEntry
slug='community_like'
title={buildingUserFields.community_like.title}
return (
<Fragment>
<DataEntryGroup name="Community views on how well buildings work">
<div className={`alert alert-dark`} role="alert" style={{ fontSize: 13, backgroundColor: "#f6f8f9" }}>
<i>
Note: We are currently only collecting data on non-residential buildings.
</i>
</div>
<div className='community-opinion-pane'>
{(props.building.is_domestic === "no" || props.building.is_domestic === "mixed domestic/non-domestic") ?
<>
<UserOpinionEntry
slug='community_like'
title={buildingUserFields.community_like.title}
userValue={props.building.community_like}
userValue={props.building.community_like}
onChange={props.onSaveChange}
mode={props.mode}
copy={props.copy}
/>
</>
:
<></>
}
<LogicalDataEntryYesOnlyWithExplanation
slug='community_type_worth_keeping'
title={buildingUserFields.community_type_worth_keeping.title}
value={props.building.community_type_worth_keeping}
disallowFalse={worthKeepingReasonsNonEmpty}
disallowNull={worthKeepingReasonsNonEmpty}
onChange={props.onSaveChange}
mode={props.mode}
/>
{(props.mapColourScale == "typology_likes") ?
<button className={`map-switcher-inline enabled-state btn btn-outline btn-outline-dark ${darkLightTheme}`} onClick={switchToLocalSignificanceMapStyle}>
{'Click here to change map to buildings of local interest.'}
</button>
:
<button className={`map-switcher-inline disabled-state btn btn-outline btn-outline-dark ${darkLightTheme}`} onClick={switchToTypologyMapStyle}>
{"Click to return to liked typologies mapped."}
</button>
}
{
props.building.community_type_worth_keeping === true &&
<MultiSelectDataEntry
slug='community_type_worth_keeping_reasons'
title={buildingUserFields.community_type_worth_keeping_reasons.title}
value={props.building.community_type_worth_keeping_reasons}
disabled={!props.building.community_type_worth_keeping}
onChange={props.onSaveChange}
options={
Object.entries(buildingUserFields.community_type_worth_keeping_reasons.fields)
.map(([key, definition]) => ({
key,
label: definition.title
}))
}
mode={props.mode}
/>
}
<hr />
<UserOpinionEntry
slug='community_local_significance'
title={buildingUserFields.community_local_significance.title}
userValue={props.building.community_local_significance}
onChange={props.onSaveChange}
mode={props.mode}
copy={props.copy}
/>
</>
:
<></>
}
<LogicalDataEntryYesOnlyWithExplanation
slug='community_type_worth_keeping'
title={buildingUserFields.community_type_worth_keeping.title}
{(props.mapColourScale == "community_local_significance_total") ?
<button className={`map-switcher-inline enabled-state btn btn-outline btn-outline-dark ${darkLightTheme}`} onClick={switchToTypologyMapStyle}>
{'Click to return to liked typologies mapped.'}
</button>
:
<button className={`map-switcher-inline disabled-state btn btn-outline btn-outline-dark ${darkLightTheme}`} onClick={switchToLocalSignificanceMapStyle}>
{"Click here to change map to buildings of local interest."}
</button>
}
<hr />
<UserOpinionEntry
slug='community_expected_planning_application'
title={buildingUserFields.community_expected_planning_application.title}
value={props.building.community_type_worth_keeping}
disallowFalse={worthKeepingReasonsNonEmpty}
disallowNull={worthKeepingReasonsNonEmpty}
userValue={props.building.community_expected_planning_application}
onChange={props.onSaveChange}
mode={props.mode}
/>
{(props.mapColourScale == "typology_likes") ?
<button className={`map-switcher-inline enabled-state btn btn-outline btn-outline-dark ${darkLightTheme}`} onClick={switchToLocalSignificanceMapStyle}>
{'Click here to change map to buildings of local interest.'}
</button>
:
<button className={`map-switcher-inline disabled-state btn btn-outline btn-outline-dark ${darkLightTheme}`} onClick={switchToTypologyMapStyle}>
{"Click to return to liked typologies mapped."}
</button>
}
{
props.building.community_type_worth_keeping === true &&
<MultiSelectDataEntry
slug='community_type_worth_keeping_reasons'
title={buildingUserFields.community_type_worth_keeping_reasons.title}
value={props.building.community_type_worth_keeping_reasons}
disabled={!props.building.community_type_worth_keeping}
onChange={props.onSaveChange}
options={
Object.entries(buildingUserFields.community_type_worth_keeping_reasons.fields)
.map(([key, definition]) => ({
key,
label: definition.title
}))
}
mode={props.mode}
copy={props.copy}
/>
}
<hr />
<UserOpinionEntry
slug='community_local_significance'
title={buildingUserFields.community_local_significance.title}
userValue={props.building.community_local_significance}
onChange={props.onSaveChange}
<div className={`alert alert-dark`} role="alert" style={{ fontSize: 13, backgroundColor: "#f6f8f9" }}>
<i>
For more information on current planning applications, refer to the Planning Controls category.
</i>
</div>
{(props.mapColourScale == "community_expected_planning_application_total") ?
<button className={`map-switcher-inline enabled-state btn btn-outline btn-outline-dark ${darkLightTheme}`} onClick={switchToTypologyMapStyle}>
{'Click to return to liked typologies mapped.'}
</button>
:
<button className={`map-switcher-inline disabled-state btn btn-outline btn-outline-dark ${darkLightTheme}`} onClick={switchToExpectedApplicationMapStyle}>
{"Click here to change map to planning applications expected by community."}
</button>
}
</div>
</DataEntryGroup>
<DataEntryGroup name="Buildings in community use">
<div className={`alert alert-dark`} role="alert" style={{ fontSize: 13, backgroundColor: "#f6f8f9" }}>
<i>
Here we are collecting information on the location of buildings used for community activities so we can track loss of/additions to community space over time.
</i>
</div>
<LogicalDataEntry
slug='community_activities_current'
title={dataFields.community_activities_current.title}
tooltip={dataFields.community_activities_current.tooltip}
value={props.building.community_activities_current}
copy={props.copy}
onChange={props.onChange}
mode={props.mode}
/>
<LogicalDataEntry
slug='community_activities'
title={dataFields.community_activities.title}
tooltip={dataFields.community_activities.tooltip}
value={props.building.community_activities}
copy={props.copy}
onChange={props.onChange}
mode={props.mode}
/>
<LogicalDataEntry
slug='community_activities_always'
title={dataFields.community_activities_always.title}
tooltip={dataFields.community_activities_always.tooltip}
value={props.building.community_activities_always}
copy={props.copy}
onChange={props.onChange}
mode={props.mode}
/>
<SelectDataEntry
slug='community_public_ownership'
title={dataFields.community_public_ownership.title}
value={props.building.community_public_ownership}
options={dataFields.community_public_ownership.items}
onChange={props.onChange}
mode={props.mode}
copy={props.copy}
/>
{(props.mapColourScale == "community_local_significance_total") ?
<Verification
slug="community_public_ownership"
allow_verify={props.user !== undefined && props.building.community_public_ownership !== null && !props.edited}
onVerify={props.onVerify}
user_verified={props.user_verified.hasOwnProperty("community_public_ownership")}
user_verified_as={props.user_verified.community_public_ownership}
verified_count={props.building.verified.community_public_ownership}
/>
<MultiDataEntry
slug='community_public_ownership_sources'
title={dataFields.community_public_ownership_sources.title}
isUrl={true}
placeholder={'https://...'}
editableEntries={true}
value={props.building.community_public_ownership_sources}
onChange={props.onChange}
mode={props.mode}
copy={props.copy}
/>
<Verification
slug="community_public_ownership_sources"
allow_verify={props.user !== undefined && props.building.community_public_ownership_sources !== null && !props.edited}
onVerify={props.onVerify}
user_verified={props.user_verified.hasOwnProperty("community_public_ownership_sources")}
user_verified_as={props.user_verified.community_public_ownership_sources}
verified_count={props.building.verified.community_public_ownership_sources}
/>
{(props.mapColourScale == "community_in_public_ownership") ?
<button className={`map-switcher-inline enabled-state btn btn-outline btn-outline-dark ${darkLightTheme}`} onClick={switchToTypologyMapStyle}>
{'Click to return to liked typologies mapped.'}
</button>
:
<button className={`map-switcher-inline disabled-state btn btn-outline btn-outline-dark ${darkLightTheme}`} onClick={switchToLocalSignificanceMapStyle}>
{"Click here to change map to buildings of local interest."}
<button className={`map-switcher-inline disabled-state btn btn-outline btn-outline-dark ${darkLightTheme}`} onClick={switchToPublicOwnershipMapStyle}>
{"Click here to see ownership type mapped."}
</button>
}
<hr />
<UserOpinionEntry
slug='community_expected_planning_application'
title={buildingUserFields.community_expected_planning_application.title}
userValue={props.building.community_expected_planning_application}
onChange={props.onSaveChange}
mode={props.mode}
copy={props.copy}
/>
{(props.mapColourScale == "community_expected_planning_application_total") ?
<button className={`map-switcher-inline enabled-state btn btn-outline btn-outline-dark ${darkLightTheme}`} onClick={switchToTypologyMapStyle}>
{'Click to return to liked typologies mapped.'}
</button>
:
<button className={`map-switcher-inline disabled-state btn btn-outline btn-outline-dark ${darkLightTheme}`} onClick={switchToExpectedApplicationMapStyle}>
{"Click here to change map to planning applications expected by community."}
</button>
}
</div>
</DataEntryGroup>
<DataEntryGroup name="Building use for community activities">
<div className={`alert alert-dark`} role="alert" style={{ fontSize: 13, backgroundColor: "#f6f8f9" }}>
<i>
Here we are collecting information on the location of buildings used for community activities so we can track loss of/additions to community space over time.
</i>
</div>
<LogicalDataEntry
slug='community_activities_current'
title={dataFields.community_activities_current.title}
tooltip={dataFields.community_activities_current.tooltip}
value={props.building.community_activities_current}
copy={props.copy}
onChange={props.onChange}
mode={props.mode}
/>
<LogicalDataEntry
slug='community_activities'
title={dataFields.community_activities.title}
tooltip={dataFields.community_activities.tooltip}
value={props.building.community_activities}
copy={props.copy}
onChange={props.onChange}
mode={props.mode}
/>
<LogicalDataEntry
slug='community_activities_always'
title={dataFields.community_activities_always.title}
tooltip={dataFields.community_activities_always.tooltip}
value={props.building.community_activities_always}
copy={props.copy}
onChange={props.onChange}
mode={props.mode}
/>
<SelectDataEntry
slug='community_public_ownership'
title={dataFields.community_public_ownership.title}
value={props.building.community_public_ownership}
options={dataFields.community_public_ownership.items}
onChange={props.onChange}
mode={props.mode}
copy={props.copy}
/>
<Verification
slug="community_public_ownership"
allow_verify={props.user !== undefined && props.building.community_public_ownership !== null && !props.edited}
onVerify={props.onVerify}
user_verified={props.user_verified.hasOwnProperty("community_public_ownership")}
user_verified_as={props.user_verified.community_public_ownership}
verified_count={props.building.verified.community_public_ownership}
/>
<MultiDataEntry
slug='community_public_ownership_sources'
title={dataFields.community_public_ownership_sources.title}
isUrl={true}
placeholder={'https://...'}
editableEntries={true}
value={props.building.community_public_ownership_sources}
onChange={props.onChange}
mode={props.mode}
copy={props.copy}
/>
<Verification
slug="community_public_ownership_sources"
allow_verify={props.user !== undefined && props.building.community_public_ownership_sources !== null && !props.edited}
onVerify={props.onVerify}
user_verified={props.user_verified.hasOwnProperty("community_public_ownership_sources")}
user_verified_as={props.user_verified.community_public_ownership_sources}
verified_count={props.building.verified.community_public_ownership_sources}
/>
{(props.mapColourScale == "community_in_public_ownership") ?
<button className={`map-switcher-inline enabled-state btn btn-outline btn-outline-dark ${darkLightTheme}`} onClick={switchToTypologyMapStyle}>
{'Click to return to liked typologies mapped.'}
</button>
:
<button className={`map-switcher-inline disabled-state btn btn-outline btn-outline-dark ${darkLightTheme}`} onClick={switchToPublicOwnershipMapStyle}>
{"Click here to see ownership type mapped."}
</button>
}
</DataEntryGroup>
</>
</DataEntryGroup>
</Fragment>
);
};
const CommunityContainer = withCopyEdit(CommunityView);

View File

@ -11,6 +11,7 @@ import InfoBox from '../../components/info-box';
import { CategoryViewProps } from './category-view-props';
import { DataEntryGroup } from '../data-components/data-entry-group';
import { MultiDataEntry } from '../data-components/multi-data-entry/multi-data-entry';
import { LogicalDataEntry } from '../data-components/logical-data-entry/logical-data-entry';
const EnergyCategoryOptions = ["A", "B", "C", "D", "E", "F", "G"];
const BreeamRatingOptions = [
@ -25,9 +26,20 @@ const BreeamRatingOptions = [
* Sustainability view/edit section
*/
const SustainabilityView: React.FunctionComponent<CategoryViewProps> = (props) => {
const currentYear = new Date().getFullYear();
return (
<Fragment>
<DataEntryGroup name="Energy rating data">
<DataEntryGroup name="Environmental quality rating">
<DataEntry
title="Official environmental quality rating"
slug=""
value=""
mode='view'
/>
</DataEntryGroup>
<DataEntryGroup name="Energy rating">
<SelectDataEntry
title={dataFields.sust_breeam_rating.title}
slug="sust_breeam_rating"
@ -46,7 +58,6 @@ const SustainabilityView: React.FunctionComponent<CategoryViewProps> = (props) =
user_verified_as={props.user_verified.sust_breeam_rating}
verified_count={props.building.verified.sust_breeam_rating}
/>
<SelectDataEntry
title={dataFields.sust_dec.title}
slug="sust_dec"
@ -65,7 +76,6 @@ const SustainabilityView: React.FunctionComponent<CategoryViewProps> = (props) =
user_verified_as={props.user_verified.sust_dec}
verified_count={props.building.verified.sust_dec}
/>
<SelectDataEntry
title={dataFields.sust_aggregate_estimate_epc.title}
slug="sust_aggregate_estimate_epc"
@ -78,91 +88,160 @@ const SustainabilityView: React.FunctionComponent<CategoryViewProps> = (props) =
onChange={props.onChange}
/>
</DataEntryGroup>
<DataEntryGroup name="Retrofit Data">
<DataEntryGroup name="Retrofit history">
<NumericDataEntry
title={dataFields.sust_retrofit_date.title}
slug="sust_retrofit_date"
value={props.building.sust_retrofit_date}
tooltip={dataFields.sust_retrofit_date.tooltip}
step={1}
min={1086}
max={new Date().getFullYear()}
slug='age_retrofit_date'
title={dataFields.age_retrofit_date.title}
value={props.building.age_retrofit_date}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
/>
step={1}
min={1}
max={currentYear}
tooltip={dataFields.extension_year.tooltip}
/>
<Verification
slug="sust_retrofit_date"
allow_verify={props.user !== undefined && props.building.sust_retrofit_date !== null && !props.edited}
slug="age_retrofit_date"
allow_verify={props.user !== undefined && props.building.age_retrofit_date !== null && !props.edited}
onVerify={props.onVerify}
user_verified={props.user_verified.hasOwnProperty("sust_retrofit_date")}
user_verified_as={props.user_verified.sust_retrofit_date}
verified_count={props.building.verified.sust_retrofit_date}
user_verified={props.user_verified.hasOwnProperty("age_retrofit_date")}
user_verified_as={props.user_verified.age_retrofit_date}
verified_count={props.building.verified.age_retrofit_date}
/>
<SelectDataEntry
title={dataFields.sust_retrofit_source_type.title}
slug="sust_retrofit_source_type"
value={props.building.sust_retrofit_source_type}
title={dataFields.age_retrofit_date_source_type.title}
slug="age_retrofit_date_source_type"
value={props.building.age_retrofit_date_source_type}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
tooltip={dataFields.sust_retrofit_source_type.tooltip}
options={dataFields.sust_retrofit_source_type.items}
placeholder={dataFields.sust_retrofit_source_type.example}
tooltip={dataFields.age_retrofit_date_source_type.tooltip}
options={dataFields.age_retrofit_date_source_type.items}
placeholder={dataFields.age_retrofit_date_source_type.example}
/>
{(props.building.sust_retrofit_source_type == dataFields.sust_retrofit_source_type.items[0] ||
props.building.sust_retrofit_source_type == dataFields.sust_retrofit_source_type.items[1] ||
props.building.sust_retrofit_source_type == null) ? <></> :
{(props.building.age_retrofit_date_source_type == dataFields.age_retrofit_date_source_type.items[0] ||
props.building.age_retrofit_date_source_type == dataFields.age_retrofit_date_source_type.items[1] ||
props.building.age_retrofit_date_source_type == null) ? <></> :
<>
<MultiDataEntry
title={dataFields.sust_retrofit_source_links.title}
slug="sust_retrofit_source_links"
value={props.building.sust_retrofit_source_links}
title={dataFields.age_retrofit_date_source_links.title}
slug="age_retrofit_date_source_links"
value={props.building.age_retrofit_date_source_links}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
tooltip={dataFields.sust_retrofit_source_links.tooltip}
tooltip={dataFields.age_retrofit_date_source_links.tooltip}
placeholder="https://..."
editableEntries={true}
isUrl={true}
/>
</>
}
{/* <hr/>
<DataEntry
title="Date of Significant Retrofits"
slug=""
value=""
mode='view'
</DataEntryGroup>
<DataEntryGroup name="Solar panels">
<LogicalDataEntry
title={dataFields.energy_solar.title}
slug="energy_solar"
value={props.building.energy_solar}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
tooltip={dataFields.energy_solar.tooltip}
/>
<Verification
slug="date_link"
allow_verify={props.user !== undefined && props.building.date_link !== null && !props.edited}
slug="energy_solar"
allow_verify={props.user !== undefined && props.building.energy_solar !== null && !props.edited}
onVerify={props.onVerify}
user_verified={props.user_verified.hasOwnProperty("date_link")}
user_verified_as={props.user_verified.date_link}
verified_count={props.building.verified.date_link}
user_verified={props.user_verified.hasOwnProperty("energy_solar")}
user_verified_as={props.user_verified.energy_solar}
verified_count={props.building.verified.energy_solar}
/>
<DataEntry
title="Source"
slug=""
value=""
mode='view'
/> */}
{props.building.energy_solar == null ? <></> :
<>
<SelectDataEntry
title={dataFields.energy_solar_source_type.title}
slug="energy_solar_source_type"
value={props.building.energy_solar_source_type}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
tooltip={dataFields.energy_solar_source_type.tooltip}
options={dataFields.energy_solar_source_type.items}
placeholder={dataFields.energy_solar_source_type.example}
/>
{(props.building.energy_solar_source_type == dataFields.energy_solar_source_type.items[0] ||
props.building.energy_solar_source_type == dataFields.energy_solar_source_type.items[1] ||
props.building.energy_solar_source_type == null) ? <></> :
<>
<MultiDataEntry
title={dataFields.energy_solar_source_links.title}
slug="energy_solar_source_links"
value={props.building.energy_solar_source_links}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
tooltip={dataFields.energy_solar_source_links.tooltip}
placeholder="https://..."
editableEntries={true}
isUrl={true}
/>
</>
}
</>
}
</DataEntryGroup>
<DataEntryGroup name="Other sustainability features">
<DataEntry
title="Does the building have Solar Panels?"
slug=""
value=""
mode='view'
/>
<DataEntry
title="Does the building have Green Walls / Green Roof"
slug=""
value=""
mode='view'
<DataEntryGroup name="Green walls/roof">
<LogicalDataEntry
title={dataFields.energy_green_roof.title}
slug="energy_green_roof"
value={props.building.energy_green_roof}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
tooltip={dataFields.energy_green_roof.tooltip}
/>
<Verification
slug="energy_green_roof"
allow_verify={props.user !== undefined && props.building.energy_green_roof !== null && !props.edited}
onVerify={props.onVerify}
user_verified={props.user_verified.hasOwnProperty("energy_green_roof")}
user_verified_as={props.user_verified.energy_green_roof}
verified_count={props.building.verified.energy_green_roof}
/>
{props.building.energy_green_roof == null ? <></> :
<>
<SelectDataEntry
title={dataFields.energy_green_roof_source_type.title}
slug="energy_green_roof_source_type"
value={props.building.energy_green_roof_source_type}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
tooltip={dataFields.energy_green_roof_source_type.tooltip}
options={dataFields.energy_green_roof_source_type.items}
placeholder={dataFields.energy_green_roof_source_type.example}
/>
{(props.building.energy_green_roof_source_type == dataFields.energy_green_roof_source_type.items[0] ||
props.building.energy_green_roof_source_type == dataFields.energy_green_roof_source_type.items[1] ||
props.building.energy_green_roof_source_type == null) ? <></> :
<>
<MultiDataEntry
title={dataFields.energy_green_roof_source_links.title}
slug="energy_green_roof_source_links"
value={props.building.energy_green_roof_source_links}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
tooltip={dataFields.energy_green_roof_source_links.tooltip}
placeholder="https://..."
editableEntries={true}
isUrl={true}
/>
</>
}
</>
}
</DataEntryGroup>
</Fragment>
);

View File

@ -32,14 +32,14 @@ const UseView: React.FunctionComponent<CategoryViewProps> = (props) => {
const { darkLightTheme } = useDisplayPreferences();
return (
<Fragment>
<DataEntryGroup name="Residential/non-residential land use data (general)">
<DataEntryGroup name="General Land Use">
<div className={`alert alert-dark`} role="alert" style={{ fontSize: 13, backgroundColor: "#f6f8f9" }}>
<i>
The vast majority of properties are residential (93% in the UK), so we have set 'residential' as the default value. Can you help us identify non-residential and mixed use buildings (and verify residential buildings too)?
</i>
</div>
<button className={`map-switcher-inline ${props.mapColourScale == "is_domestic" ? "enabled-state" : "disabled-state"} btn btn-outline btn-outline-dark ${darkLightTheme}`} onClick={switchToIsDomesticMapStyle}>
{(props.mapColourScale == "is_domestic")? 'Showing domestic, non-domestic and mixed-use buildings (click to hide)' : 'Click to see domestic, non-domestic and mixed-use buildings on the map.'}
{(props.mapColourScale == "is_domestic")? 'Showing residential, non-residential and mixed-use buildings (click to hide)' : 'Click to see residential, non-residential and mixed-use buildings on the map.'}
</button>
<SelectDataEntry
title={dataFields.is_domestic.title}
@ -87,7 +87,7 @@ const UseView: React.FunctionComponent<CategoryViewProps> = (props) => {
</>
}
</DataEntryGroup>
<DataEntryGroup name="Specific land use data">
<DataEntryGroup name="Specific land use(s)">
<MultiDataEntry
title={dataFields.current_landuse_group.title}
slug="current_landuse_group"

View File

@ -12,12 +12,14 @@ import SelectDataEntry from '../data-components/select-data-entry';
import { MultiDataEntry } from '../data-components/multi-data-entry/multi-data-entry';
const locationNumberPattern = "[1-9]\\d*[a-z]?(-([1-9]\\d*))?"; ///[1-9]\d*[a-z]?(-([1-9]\d*))?/;
const postcodeCharacterPattern = "^[A-Z]{1,2}[0-9]{1,2}[A-Z]?(\\s*[0-9][A-Z]{1,2})?$";
const osmIdentifierPattern = "[0-9]{1,9}";
const LocationView: React.FunctionComponent<CategoryViewProps> = (props) => {
const osm_url = "https://www.openstreetmap.org/way/"+props.building.ref_osm_id;
const osm_url = "www.openstreetmap.org/way/"+props.building.ref_osm_id;
return (
<Fragment>
<DataEntryGroup name="Address data">
<DataEntryGroup name="Addresses">
<DataEntry
title={dataFields.location_name.title}
slug="location_name"
@ -26,8 +28,9 @@ const LocationView: React.FunctionComponent<CategoryViewProps> = (props) => {
copy={props.copy}
onChange={props.onChange}
tooltip={dataFields.location_name.tooltip}
placeholder="https://..."
isUrl={true}
placeholder=""
isUrl={false}
disabled={true}
/>
<Verification
slug="location_name"
@ -44,6 +47,23 @@ const LocationView: React.FunctionComponent<CategoryViewProps> = (props) => {
mode='view'
tooltip="Not yet activated.<br><br>For security reasons, we do not allow the use of free text boxes and are currently looking into alternative ways to collect this data."
/>
<DataEntry
title={dataFields.location_name_link.title}
slug="location_name_link"
value={props.building.location_name_link}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
tooltip={dataFields.location_name_link.tooltip}
placeholder={dataFields.location_name_link.example}
isUrl={true}
/>
{
(props.building.location_name_link == null) ? <></> :
<div className={`alert alert-dark`} role="alert" style={{ fontSize: 14, backgroundColor: "#f6f8f9" }}>
<i className="source-url">Source: <a href={props.building.location_name_link} target={"_blank"}>{props.building.location_name_link}</a></i>
</div>
}
<hr/>
<PatternDataEntry
title={dataFields.location_number.title}
@ -54,6 +74,7 @@ const LocationView: React.FunctionComponent<CategoryViewProps> = (props) => {
copy={props.copy}
onChange={props.onChange}
tooltip={dataFields.location_number.tooltip}
maxLength={5}
/>
<Verification
slug="location_number"
@ -71,6 +92,7 @@ const LocationView: React.FunctionComponent<CategoryViewProps> = (props) => {
copy={props.copy}
onChange={props.onChange}
maxLength={30}
disabled={true}
/>
<Verification
slug="location_street"
@ -88,6 +110,7 @@ const LocationView: React.FunctionComponent<CategoryViewProps> = (props) => {
copy={props.copy}
onChange={props.onChange}
maxLength={30}
disabled={true}
/>
<Verification
slug="location_line_two"
@ -104,6 +127,7 @@ const LocationView: React.FunctionComponent<CategoryViewProps> = (props) => {
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
disabled={true}
/>
<Verification
slug="location_town"
@ -113,15 +137,17 @@ const LocationView: React.FunctionComponent<CategoryViewProps> = (props) => {
user_verified_as={props.user_verified.location_town}
verified_count={props.building.verified.location_town}
/>
<DataEntry
<PatternDataEntry
title={dataFields.location_postcode.title}
slug="location_postcode"
value={props.building.location_postcode}
pattern={postcodeCharacterPattern}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
maxLength={8}
valueTransform={x=>x.toUpperCase()}
tooltip={dataFields.location_postcode.tooltip}
/>
<Verification
slug="location_postcode"
@ -161,7 +187,7 @@ const LocationView: React.FunctionComponent<CategoryViewProps> = (props) => {
</>
}
</DataEntryGroup>
<DataEntryGroup name="Property/footprint IDs and coordinate data">
<DataEntryGroup name="Property/footprint IDs and coordinates">
<DataEntry
title={dataFields.ref_toid.title}
slug="ref_toid"
@ -172,13 +198,27 @@ const LocationView: React.FunctionComponent<CategoryViewProps> = (props) => {
onChange={props.onChange}
disabled={true}
/>
{
(props.building.ref_toid == null) ? <></> :
<div className={`alert alert-dark`} role="alert" style={{ fontSize: 14, backgroundColor: "#f6f8f9" }}>
<i className="source-url">Source: <a href="https://www.ordnancesurvey.co.uk/products/os-open-toid" target={"_blank"}>{"www.ordnancesurvey.co.uk/products/os-open-toid"}</a></i>
</div>
}
<hr/>
<UPRNsDataEntry
title={dataFields.uprns.title}
slug="ref_uprns"
value={props.building.uprns}
tooltip={dataFields.uprns.tooltip}
/>
<DataEntry
{
(props.building.uprns == null) ? <></> :
<div className={`alert alert-dark`} role="alert" style={{ fontSize: 14, backgroundColor: "#f6f8f9" }}>
<i className="source-url">Source: <a href="https://beta.ordnancesurvey.co.uk/products/os-open-uprn" target={"_blank"}>{"beta.ordnancesurvey.co.uk/products/os-open-uprn"}</a></i>
</div>
}
<hr/>
<PatternDataEntry
title={dataFields.ref_osm_id.title}
slug="ref_osm_id"
value={props.building.ref_osm_id}
@ -187,13 +227,8 @@ const LocationView: React.FunctionComponent<CategoryViewProps> = (props) => {
tooltip={dataFields.ref_osm_id.tooltip}
maxLength={20}
onChange={props.onChange}
pattern={osmIdentifierPattern}
/>
{
(props.building.ref_osm_id == null) ? <></> :
<div className={`alert alert-dark`} role="alert" style={{ fontSize: 14, backgroundColor: "#f6f8f9" }}>
<i className="source-url">Source: <a href={osm_url} target={"_blank"}>{osm_url}</a></i>
</div>
}
<Verification
slug="ref_osm_id"
allow_verify={props.user !== undefined && props.building.ref_osm_id !== null && !props.edited}
@ -202,6 +237,12 @@ const LocationView: React.FunctionComponent<CategoryViewProps> = (props) => {
user_verified_as={props.user_verified.ref_osm_id}
verified_count={props.building.verified.ref_osm_id}
/>
{
(props.building.ref_osm_id == null) ? <></> :
<div className={`alert alert-dark`} role="alert" style={{ fontSize: 14, backgroundColor: "#f6f8f9" }}>
<i className="source-url">Source: <a href={"https://"+osm_url} target={"_blank"}>{osm_url}</a></i>
</div>
}
<hr/>
<NumericDataEntry
title={dataFields.location_latitude.title}
@ -274,6 +315,19 @@ const LocationView: React.FunctionComponent<CategoryViewProps> = (props) => {
/>
</>
}
<hr/>
<MultiDataEntry
title={dataFields.location_alternative_footprint_links.title}
slug="location_alternative_footprint_links"
value={props.building.location_alternative_footprint_links}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
tooltip={dataFields.location_alternative_footprint_links.tooltip}
placeholder="https://..."
editableEntries={true}
isUrl={true}
/>
</DataEntryGroup>
</Fragment>
);

View File

@ -19,6 +19,8 @@ import { CategoryViewProps } from './category-view-props';
import { Category } from '../../config/categories-config';
import { useDisplayPreferences } from '../../displayPreferences-context';
import { processParam } from '../../../api/parameters';
import { MultiDataEntry } from '../data-components/multi-data-entry/multi-data-entry';
import YearDataEntry from '../data-components/year-data-entry';
const currentTimestamp = new Date().valueOf();
const milisecondsInYear = 1000 * 60 * 60 * 24 * 365;
@ -65,8 +67,8 @@ const PlanningView: React.FunctionComponent<CategoryViewProps> = (props) => {
const communityLinkUrl = `/${props.mode}/${Category.Community}/${props.building.building_id}`;
return (
<Fragment>
<DataEntryGroup name="Planning application information" collapsed={true} >
<DataEntryGroup name="Current/active applications (official data)">
<DataEntryGroup name="Current planning applications" collapsed={true} >
<DataEntryGroup name="Official data">
<InfoBox>
This section provides data on active applications. We define these as applications with any activity in the last year.
<br />
@ -85,49 +87,85 @@ const PlanningView: React.FunctionComponent<CategoryViewProps> = (props) => {
: <></>
}
</DataEntryGroup>
<DataEntryGroup name="Past applications (official data)" collapsed={true} >
<InfoBox>
This section provides data on past applications where available from the GLA, including those with no decision in over a year
</InfoBox>
{props.building.planning_data ?
<PlanningDataOfficialDataEntry
shownData={props.building.planning_data.filter(item => isArchived(item))}
messageOnMissingData={
props.building.planning_data.length > 0 ?
"Only current application data is currently available for this site"
:
"No live planning data are currently available for this building from the Planning London Datahub."
}
/>
: <></>
}
</DataEntryGroup>
<DataEntryGroup name="Possible future applications (crowdsourced data)" collapsed={true} >
<InfoBox type='info'>Click and colour buildings here if you think they may be subject to a future planning application involving demolition. To add your opinion on how well this building works, please also visit the <Link to={communityLinkUrl}>Community</Link> section.</InfoBox>
{
props.mapColourScale != "community_expected_planning_application_total" ?
<button className={`map-switcher-inline disabled-state btn btn-outline btn-outline-dark ${darkLightTheme}`} onClick={switchToExpectedApplicationMapStyle}>
{'Click here to view possible locations of future applications'}
</button>
:
<button className={`map-switcher-inline enabled-state btn btn-outline btn-outline-dark ${darkLightTheme}`} onClick={switchToAllPlanningApplicationsMapStyle}>
{'Click to see planning applications'}
</button>
}
<UserOpinionEntry
slug='community_expected_planning_application'
title={buildingUserFields.community_expected_planning_application.title}
userValue={props.building.community_expected_planning_application}
onChange={props.onSaveChange}
mode={props.mode}
copy={props.copy}
<DataEntryGroup name="Year of completion" collapsed={true} >
<DataEntry
title="Was the building completed?"
slug=""
value=""
mode='view'
tooltip='Coming Soon'
/>
<InfoBox type='warning'>
Further improvements to this feature are currently being made.
<DataEntry
title="Year of completion"
slug=""
value=""
mode='view'
tooltip='Coming Soon'
/>
</DataEntryGroup>
<DataEntryGroup name="Incomplete/missing data" collapsed={true} >
<DataEntry
title="Is information on a planning application relating to this building missing?"
slug=""
value=""
mode='view'
tooltip='Coming Soon'
/>
<DataEntry
title="Link (to correct data)"
slug=""
value=""
mode='view'
tooltip='Coming Soon'
/>
<InfoBox>
If you feel there are incorrect or missing data relating to this building please contact:
planningdata@London.gov.uk
</InfoBox>
</DataEntryGroup>
</DataEntryGroup>
<DataEntryGroup name="Past applications" collapsed={true} >
<InfoBox>
This section provides data on past applications where available from the GLA, including those with no decision in over a year
</InfoBox>
{props.building.planning_data ?
<PlanningDataOfficialDataEntry
shownData={props.building.planning_data.filter(item => isArchived(item))}
messageOnMissingData={
props.building.planning_data.length > 0 ?
"Only current application data is currently available for this site"
:
"No live planning data are currently available for this building from the Planning London Datahub."
}
/>
: <></>
}
</DataEntryGroup>
<DataEntryGroup name="Possible future applications" collapsed={true} >
<InfoBox type='info'>Click and colour buildings here if you think they may be subject to a future planning application involving demolition. To add your opinion on how well this building works, please also visit the <Link to={communityLinkUrl}>Community</Link> section.</InfoBox>
{
props.mapColourScale != "community_expected_planning_application_total" ?
<button className={`map-switcher-inline disabled-state btn btn-outline btn-outline-dark ${darkLightTheme}`} onClick={switchToExpectedApplicationMapStyle}>
{'Click here to view possible locations of future applications'}
</button>
:
<button className={`map-switcher-inline enabled-state btn btn-outline btn-outline-dark ${darkLightTheme}`} onClick={switchToAllPlanningApplicationsMapStyle}>
{'Click to see planning applications'}
</button>
}
<UserOpinionEntry
slug='community_expected_planning_application'
title={buildingUserFields.community_expected_planning_application.title}
userValue={props.building.community_expected_planning_application}
onChange={props.onSaveChange}
mode={props.mode}
copy={props.copy}
/>
<InfoBox type='warning'>
Further improvements to this feature are currently being made.
</InfoBox>
</DataEntryGroup>
<DataEntryGroup name="Planning zones" collapsed={true} >
<InfoBox>
To view planning zone data for London click the buttons below. You may need to <u>zoom out</u>.
@ -358,6 +396,24 @@ const PlanningView: React.FunctionComponent<CategoryViewProps> = (props) => {
user_verified_as={props.user_verified.planning_in_conservation_area_url}
verified_count={props.building.verified.planning_in_conservation_area_url}
/>
<DataEntry
title={dataFields.planning_in_apa_url.title}
slug="planning_in_apa_url"
value={props.building.planning_in_apa_url}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
isUrl={true}
placeholder="Please add relevant link here"
/>
<Verification
slug="planning_in_apa_url"
allow_verify={props.user !== undefined && props.building.planning_in_apa_url !== null && !props.edited}
onVerify={props.onVerify}
user_verified={props.user_verified.hasOwnProperty("planning_in_apa_url")}
user_verified_as={props.user_verified.planning_in_apa_url}
verified_count={props.building.verified.planning_in_apa_url}
/>
{/*
<DataEntry
title={dataFields.planning_conservation_area_name.title}
@ -394,140 +450,61 @@ const PlanningView: React.FunctionComponent<CategoryViewProps> = (props) => {
user_verified_as={props.user_verified.planning_historic_area_assessment_url}
verified_count={props.building.verified.planning_historic_area_assessment_url}
/>
</DataEntryGroup>
<DataEntryGroup name="Land ownership" collapsed={true} >
<InfoBox>
This section is designed to provide information on land parcels and their ownership type. Can you help us collect this information?
</InfoBox>
<SelectDataEntry
slug='community_public_ownership'
title={dataFields.community_public_ownership.title}
value={props.building.community_public_ownership}
options={dataFields.community_public_ownership.items}
onChange={props.onChange}
mode={props.mode}
copy={props.copy}
/>
<Verification
slug="community_public_ownership"
allow_verify={props.user !== undefined && props.building.community_public_ownership !== null && !props.edited}
onVerify={props.onVerify}
user_verified={props.user_verified.hasOwnProperty("community_public_ownership")}
user_verified_as={props.user_verified.community_public_ownership}
verified_count={props.building.verified.community_public_ownership}
/>
<DataEntry
title={dataFields.planning_in_apa_url.title}
slug="planning_in_apa_url"
value={props.building.planning_in_apa_url}
title="Source Type"
slug=""
value=""
mode='view'
tooltip='Coming Soon'
/>
<MultiDataEntry
slug='community_public_ownership_sources'
title={dataFields.community_public_ownership_sources.title}
isUrl={true}
placeholder={'https://...'}
editableEntries={true}
value={props.building.community_public_ownership_sources}
onChange={props.onChange}
mode={props.mode}
copy={props.copy}
/>
<hr/>
<DataEntry
title={dataFields.size_parcel_geometry.title}
slug="size_parcel_geometry"
value={props.building.size_parcel_geometry}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
tooltip={dataFields.size_parcel_geometry.tooltip}
placeholder="https://..."
isUrl={true}
placeholder="Please add relevant link here"
/>
<Verification
slug="planning_in_apa_url"
allow_verify={props.user !== undefined && props.building.planning_in_apa_url !== null && !props.edited}
onVerify={props.onVerify}
user_verified={props.user_verified.hasOwnProperty("planning_in_apa_url")}
user_verified_as={props.user_verified.planning_in_apa_url}
verified_count={props.building.verified.planning_in_apa_url}
/>
</DataEntryGroup>
<DataEntryGroup name="Forthcoming data (sections to be activated)" collapsed={true} >
<DataEntryGroup name="Active application info (crowdsourced)" collapsed={true} >
{/* will be titled "Other active application info (crowdsourced data)" once active" */}
<InfoBox type='warning'>
This category is not yet activated - Until this section is activated please report inaccuracies or problems on the <a href=" https://github.com/colouring-cities/colouring-london/discussions/categories/planning-section-comments">Discussion Forum</a>.
</InfoBox>
{/* that is placeholder display, will be replaced by actual code */}
<div className="data-title">
<div className="data-title-text">
<ul>
<li>Year of completion if known</li>
<li>If you know of a planning application that has been recently submitted for this site, and is not listed in the blue box above, please enter its planning application ID below:</li>
<li>If any of the active planning applications are not mapped onto the correct site, please tick here</li>
</ul>
</div>
</div>
{
/*
<NumericDataEntry
title={dataFields.planning_crowdsourced_site_completion_year.title}
slug="planning_crowdsourced_site_completion_year"
value={props.building.planning_crowdsourced_site_completion_year}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
disabled={true}
/>
<Verification
slug="planning_crowdsourced_site_completion_year"
allow_verify={false}
onVerify={props.onVerify}
user_verified={props.user_verified.hasOwnProperty("planning_crowdsourced_site_completion_year")}
user_verified_as={props.user_verified.planning_crowdsourced_site_completion_year}
verified_count={props.building.verified.planning_crowdsourced_site_completion_year}
/>
<DataEntry
title={dataFields.planning_crowdsourced_planning_id.title}
slug="planning_crowdsourced_planning_id"
value={props.building.planning_crowdsourced_planning_id}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
disabled={true}
/>
<Verification
slug="planning_crowdsourced_planning_id"
allow_verify={false && props.user !== undefined && props.building.planning_crowdsourced_planning_id !== null && !props.edited}
onVerify={props.onVerify}
user_verified={props.user_verified.hasOwnProperty("planning_crowdsourced_planning_id")}
user_verified_as={props.user_verified.planning_crowdsourced_planning_id}
verified_count={props.building.verified.planning_crowdsourced_planning_id}
/>
<LogicalDataEntry
slug='community_expected_planning_application_is_inaccurate'
title={"If any of the active planning applications are not mapped onto the correct site, please tick here"}
value={null}
onChange={props.onSaveChange}
mode={props.mode}
copy={props.copy}
disabled={true}
/>
on enabling switch it to UserOpinionEntry, remove value and restore userValue
*/
}
</DataEntryGroup>
<DataEntryGroup name="Land ownership type" collapsed={true} >
<InfoBox type='warning'>
This category is not yet activated.
</InfoBox>
<InfoBox>
This section is designed to provide information on land parcels and their ownership type. Can you help us to crowdsource this information?
</InfoBox>
<button className={`map-switcher-inline ${parcel}-state btn btn-outline btn-outline-dark ${darkLightTheme}`} onClick={parcelSwitchOnClick}>
{(parcel === 'enabled')? 'Click to hide sample of parcel data (in City)' : 'Click to see sample of parcel data (in City) mapped'}
</button>
<div className="data-title">
<div className="data-title-text">
<ul>
<li>What type of owner owns this land parcel?</li>
</ul>
</div>
</div>
{/*
<SelectDataEntry
slug='community_public_ownership'
title={"What type of owner owns this land parcel? "}
value={props.building.community_public_ownership}
options={[
'Government-owned',
'Charity-owned',
'Community-owned/cooperative',
'Owned by other non-profit body',
'Not in public/community ownership',
]}
onChange={props.onChange}
mode={props.mode}
copy={props.copy}
/>
<Verification
slug="community_public_ownership"
allow_verify={props.user !== undefined && props.building.community_public_ownership !== null && !props.edited}
onVerify={props.onVerify}
user_verified={props.user_verified.hasOwnProperty("community_public_ownership")}
user_verified_as={props.user_verified.community_public_ownership}
verified_count={props.building.verified.community_public_ownership}
/>
*/
}
</DataEntryGroup>
/>
<button className={`map-switcher-inline ${parcel}-state btn btn-outline btn-outline-dark ${darkLightTheme}`} onClick={parcelSwitchOnClick}>
{(parcel === 'enabled')? 'Click to hide sample land parcel data' : 'Click to show sample land parcel data'}
</button>
</DataEntryGroup>
</Fragment>
)};

View File

@ -15,441 +15,469 @@ import { MultiDataEntry } from '../data-components/multi-data-entry/multi-data-e
/**
* Size view/edit section
*/
const SizeView: React.FunctionComponent<CategoryViewProps> = (props) => (
<Fragment>
<DataEntryGroup name="Number of floors/storeys">
<NumericDataEntry
title={dataFields.size_storeys_core.title}
slug="size_storeys_core"
value={props.building.size_storeys_core}
mode={props.mode}
copy={props.copy}
tooltip={dataFields.size_storeys_core.tooltip}
onChange={props.onChange}
step={1}
min={0}
/>
<Verification
slug="size_storeys_core"
allow_verify={props.user !== undefined && props.building.size_storeys_core !== null}
onVerify={props.onVerify}
user_verified={props.user_verified.hasOwnProperty("size_storeys_core")}
user_verified_as={props.user_verified.size_storeys_core}
verified_count={props.building.verified.size_storeys_core}
/>
<NumericDataEntry
title={dataFields.size_storeys_attic.title}
slug="size_storeys_attic"
value={props.building.size_storeys_attic}
mode={props.mode}
copy={props.copy}
tooltip={dataFields.size_storeys_attic.tooltip}
onChange={props.onChange}
step={1}
min={0}
/>
<Verification
slug="size_storeys_attic"
allow_verify={props.user !== undefined && props.building.size_storeys_attic !== null}
onVerify={props.onVerify}
user_verified={props.user_verified.hasOwnProperty("size_storeys_attic")}
user_verified_as={props.user_verified.size_storeys_attic}
verified_count={props.building.verified.size_storeys_attic}
/>
<NumericDataEntry
title={dataFields.size_storeys_basement.title}
slug="size_storeys_basement"
value={props.building.size_storeys_basement}
mode={props.mode}
copy={props.copy}
tooltip={dataFields.size_storeys_basement.tooltip}
onChange={props.onChange}
step={1}
min={0}
/>
<Verification
slug="size_storeys_basement"
allow_verify={props.user !== undefined && props.building.size_storeys_basement !== null}
onVerify={props.onVerify}
user_verified={props.user_verified.hasOwnProperty("size_storeys_basement")}
user_verified_as={props.user_verified.size_storeys_basement}
verified_count={props.building.verified.size_storeys_basement}
/>
<SelectDataEntry
title={dataFields.size_storeys_source_type.title}
slug="size_storeys_source_type"
value={props.building.size_storeys_source_type}
options={dataFields.size_storeys_source_type.items}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
tooltip={dataFields.size_storeys_source_type.tooltip}
/>
{(props.building.size_storeys_source_type == commonSourceTypes[0] ||
props.building.size_storeys_source_type == commonSourceTypes[1] ||
props.building.size_storeys_source_type == null) ? <></> :
<><MultiDataEntry
title={dataFields.size_storeys_source_links.title}
slug="size_storeys_source_links"
value={props.building.size_storeys_source_links}
const SizeView: React.FunctionComponent<CategoryViewProps> = (props) => {
// Calculate the total number of floors
let total_floors = 0;
if (props.building.size_storeys_attic != null) {
total_floors += props.building.size_storeys_attic;
}
if (props.building.size_storeys_core != null) {
total_floors += props.building.size_storeys_core;
}
if (props.building.size_storeys_basement != null) {
total_floors += props.building.size_storeys_basement;
}
return (
<Fragment>
<DataEntryGroup name="Number of floors/storeys">
<NumericDataEntry
title={dataFields.size_storeys_core.title}
slug="size_storeys_core"
value={props.building.size_storeys_core}
mode={props.mode}
copy={props.copy}
tooltip={dataFields.size_storeys_core.tooltip}
onChange={props.onChange}
step={1}
min={0}
/>
<Verification
slug="size_storeys_core"
allow_verify={props.user !== undefined && props.building.size_storeys_core !== null}
onVerify={props.onVerify}
user_verified={props.user_verified.hasOwnProperty("size_storeys_core")}
user_verified_as={props.user_verified.size_storeys_core}
verified_count={props.building.verified.size_storeys_core}
/>
<NumericDataEntry
title={dataFields.size_storeys_attic.title}
slug="size_storeys_attic"
value={props.building.size_storeys_attic}
mode={props.mode}
copy={props.copy}
tooltip={dataFields.size_storeys_attic.tooltip}
onChange={props.onChange}
step={1}
min={0}
/>
<Verification
slug="size_storeys_attic"
allow_verify={props.user !== undefined && props.building.size_storeys_attic !== null}
onVerify={props.onVerify}
user_verified={props.user_verified.hasOwnProperty("size_storeys_attic")}
user_verified_as={props.user_verified.size_storeys_attic}
verified_count={props.building.verified.size_storeys_attic}
/>
<NumericDataEntry
title={dataFields.size_storeys_basement.title}
slug="size_storeys_basement"
value={props.building.size_storeys_basement}
mode={props.mode}
copy={props.copy}
tooltip={dataFields.size_storeys_basement.tooltip}
onChange={props.onChange}
step={1}
min={0}
/>
<Verification
slug="size_storeys_basement"
allow_verify={props.user !== undefined && props.building.size_storeys_basement !== null}
onVerify={props.onVerify}
user_verified={props.user_verified.hasOwnProperty("size_storeys_basement")}
user_verified_as={props.user_verified.size_storeys_basement}
verified_count={props.building.verified.size_storeys_basement}
/>
<NumericDataEntry
title="Total number of floors"
slug="size_total_floors"
value={total_floors}
mode={props.mode}
copy={props.copy}
tooltip="Total number of floors, calculated from other values."
onChange={props.onChange}
step={1}
min={0}
disabled={true}
/>
<SelectDataEntry
title={dataFields.size_storeys_source_type.title}
slug="size_storeys_source_type"
value={props.building.size_storeys_source_type}
options={dataFields.size_storeys_source_type.items}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
tooltip={dataFields.size_storeys_source_links.tooltip}
placeholder="https://..."
editableEntries={true}
isUrl={true}
/>
</>
}
</DataEntryGroup>
<DataEntryGroup name="Building height data">
<NumericDataEntry
title={dataFields.size_height_apex.title}
slug="size_height_apex"
value={props.building.size_height_apex}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
step={0.1}
min={0}
tooltip={dataFields.size_storeys_source_type.tooltip}
/>
<Verification
slug="size_height_apex"
allow_verify={props.user !== undefined && props.building.size_height_apex !== null}
onVerify={props.onVerify}
user_verified={props.user_verified.hasOwnProperty("size_height_apex")}
user_verified_as={props.user_verified.size_height_apex}
verified_count={props.building.verified.size_height_apex}
/>
<SelectDataEntry
title={dataFields.size_height_apex_source_type.title}
slug="size_height_apex_source_type"
value={props.building.size_height_apex_source_type}
options={dataFields.size_height_apex_source_type.items}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
tooltip={dataFields.size_height_apex_source_type.tooltip}
/>
{(props.building.size_height_apex_source_type == commonSourceTypes[0] ||
props.building.size_height_apex_source_type == commonSourceTypes[1] ||
props.building.size_height_apex_source_type == null) ? <></> :
<><MultiDataEntry
title={dataFields.size_height_apex_source_links.title}
slug="size_height_apex_source_links"
value={props.building.size_height_apex_source_links}
{(props.building.size_storeys_source_type == commonSourceTypes[0] ||
props.building.size_storeys_source_type == commonSourceTypes[1] ||
props.building.size_storeys_source_type == null) ? <></> :
<><MultiDataEntry
title={dataFields.size_storeys_source_links.title}
slug="size_storeys_source_links"
value={props.building.size_storeys_source_links}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
tooltip={dataFields.size_storeys_source_links.tooltip}
placeholder="https://..."
editableEntries={true}
isUrl={true}
/>
</>
}
</DataEntryGroup>
<DataEntryGroup name="Height">
<NumericDataEntry
title={dataFields.size_height_apex.title}
slug="size_height_apex"
value={props.building.size_height_apex}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
tooltip={dataFields.size_height_apex_source_links.tooltip}
placeholder="https://..."
editableEntries={true}
isUrl={true}
step={0.1}
min={0}
/>
</>
}
<hr/>
<NumericDataEntry
title={dataFields.size_height_eaves.title}
slug="size_height_eaves"
value={props.building.size_height_eaves}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
step={0.1}
min={0}
/>
<Verification
slug="size_height_eaves"
allow_verify={props.user !== undefined && props.building.size_height_eaves !== null}
onVerify={props.onVerify}
user_verified={props.user_verified.hasOwnProperty("size_height_eaves")}
user_verified_as={props.user_verified.size_height_eaves}
verified_count={props.building.verified.size_height_eaves}
/>
<SelectDataEntry
title={dataFields.size_height_eaves_source_type.title}
slug="size_height_eaves_source_type"
value={props.building.size_height_eaves_source_type}
options={dataFields.size_height_eaves_source_type.items}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
tooltip={dataFields.size_height_eaves_source_type.tooltip}
/>
{(props.building.size_height_eaves_source_type == commonSourceTypes[0] ||
props.building.size_height_eaves_source_type == commonSourceTypes[1] ||
props.building.size_height_eaves_source_type == null) ? <></> :
<><MultiDataEntry
title={dataFields.size_height_eaves_source_links.title}
slug="size_height_eaves_source_links"
value={props.building.size_height_eaves_source_links}
<Verification
slug="size_height_apex"
allow_verify={props.user !== undefined && props.building.size_height_apex !== null}
onVerify={props.onVerify}
user_verified={props.user_verified.hasOwnProperty("size_height_apex")}
user_verified_as={props.user_verified.size_height_apex}
verified_count={props.building.verified.size_height_apex}
/>
<SelectDataEntry
title={dataFields.size_height_apex_source_type.title}
slug="size_height_apex_source_type"
value={props.building.size_height_apex_source_type}
options={dataFields.size_height_apex_source_type.items}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
tooltip={dataFields.size_height_eaves_source_links.tooltip}
placeholder="https://..."
editableEntries={true}
isUrl={true}
/>
</>
}
</DataEntryGroup>
<DataEntryGroup name="Floor area data">
<NumericDataEntry
title={dataFields.size_floor_area_ground.title}
slug="size_floor_area_ground"
value={props.building.size_floor_area_ground}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
step={0.1}
min={0}
tooltip={dataFields.size_height_apex_source_type.tooltip}
/>
<Verification
slug="size_floor_area_ground"
allow_verify={props.user !== undefined && props.building.size_floor_area_ground !== null}
onVerify={props.onVerify}
user_verified={props.user_verified.hasOwnProperty("size_floor_area_ground")}
user_verified_as={props.user_verified.size_floor_area_ground}
verified_count={props.building.verified.size_floor_area_ground}
/>
<NumericDataEntry
title={dataFields.size_floor_area_total.title}
slug="size_floor_area_total"
value={props.building.size_floor_area_total}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
step={0.1}
min={0}
/>
<Verification
slug="size_floor_area_total"
allow_verify={props.user !== undefined && props.building.size_floor_area_total !== null}
onVerify={props.onVerify}
user_verified={props.user_verified.hasOwnProperty("size_floor_area_total")}
user_verified_as={props.user_verified.size_floor_area_total}
verified_count={props.building.verified.size_floor_area_total}
/>
<SelectDataEntry
title={dataFields.size_floor_area_source_type.title}
slug="size_floor_area_source_type"
value={props.building.size_floor_area_source_type}
options={dataFields.size_floor_area_source_type.items}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
tooltip={dataFields.size_floor_area_source_type.tooltip}
/>
{(props.building.size_floor_area_source_type == commonSourceTypes[0] ||
props.building.size_floor_area_source_type == commonSourceTypes[1] ||
props.building.size_floor_area_source_type == null) ? <></> :
<><MultiDataEntry
title={dataFields.size_floor_area_source_links.title}
slug="size_floor_area_source_links"
value={props.building.size_floor_area_source_links}
{(props.building.size_height_apex_source_type == commonSourceTypes[0] ||
props.building.size_height_apex_source_type == commonSourceTypes[1] ||
props.building.size_height_apex_source_type == null) ? <></> :
<><MultiDataEntry
title={dataFields.size_height_apex_source_links.title}
slug="size_height_apex_source_links"
value={props.building.size_height_apex_source_links}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
tooltip={dataFields.size_height_apex_source_links.tooltip}
placeholder="https://..."
editableEntries={true}
isUrl={true}
/>
</>
}
<hr/>
<NumericDataEntry
title={dataFields.size_height_eaves.title}
slug="size_height_eaves"
value={props.building.size_height_eaves}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
tooltip={dataFields.size_floor_area_source_links.tooltip}
placeholder="https://..."
editableEntries={true}
isUrl={true}
step={0.1}
min={0}
/>
</>
}
</DataEntryGroup>
<DataEntryGroup name="Plot size data">
<NumericDataEntry
title={dataFields.size_width_frontage.title}
slug="size_width_frontage"
value={props.building.size_width_frontage}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
step={0.1}
min={0}
/>
<Verification
slug="size_width_frontage"
allow_verify={props.user !== undefined && props.building.size_width_frontage !== null}
onVerify={props.onVerify}
user_verified={props.user_verified.hasOwnProperty("size_width_frontage")}
user_verified_as={props.user_verified.size_width_frontage}
verified_count={props.building.verified.size_width_frontage}
/>
<SelectDataEntry
title={dataFields.size_width_frontage_source_type.title}
slug="size_width_frontage_source_type"
value={props.building.size_width_frontage_source_type}
options={dataFields.size_width_frontage_source_type.items}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
tooltip={dataFields.size_width_frontage_source_type.tooltip}
/>
{(props.building.size_width_frontage_source_type == commonSourceTypes[0] ||
props.building.size_width_frontage_source_type == commonSourceTypes[1] ||
props.building.size_width_frontage_source_type == null) ? <></> :
<><MultiDataEntry
title={dataFields.size_width_frontage_source_links.title}
slug="size_width_frontage_source_links"
value={props.building.size_width_frontage_source_links}
<Verification
slug="size_height_eaves"
allow_verify={props.user !== undefined && props.building.size_height_eaves !== null}
onVerify={props.onVerify}
user_verified={props.user_verified.hasOwnProperty("size_height_eaves")}
user_verified_as={props.user_verified.size_height_eaves}
verified_count={props.building.verified.size_height_eaves}
/>
<SelectDataEntry
title={dataFields.size_height_eaves_source_type.title}
slug="size_height_eaves_source_type"
value={props.building.size_height_eaves_source_type}
options={dataFields.size_height_eaves_source_type.items}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
tooltip={dataFields.size_width_frontage_source_links.tooltip}
placeholder="https://..."
editableEntries={true}
isUrl={true}
/>
</>
}
<hr/>
<NumericDataEntry
title={dataFields.size_plot_area_total.title}
slug="size_plot_area_total"
tooltip={dataFields.size_plot_area_total.tooltip}
value={props.building.size_plot_area_total}
mode={props.mode}
onChange={props.onChange}
step={0.1}
min={0}
/>
<Verification
slug="size_plot_area_total"
allow_verify={props.user !== undefined && props.building.size_plot_area_total !== null}
onVerify={props.onVerify}
user_verified={props.user_verified.hasOwnProperty("size_plot_area_total")}
user_verified_as={props.user_verified.size_plot_area_total}
verified_count={props.building.verified.size_plot_area_total}
tooltip={dataFields.size_height_eaves_source_type.tooltip}
/>
<SelectDataEntry
title={dataFields.size_plot_area_total_source_type.title}
slug="size_plot_area_total_source_type"
value={props.building.size_plot_area_total_source_type}
options={dataFields.size_plot_area_total_source_type.items}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
tooltip={dataFields.size_plot_area_total_source_type.tooltip}
/>
{(props.building.size_plot_area_total_source_type == commonSourceTypes[0] ||
props.building.size_plot_area_total_source_type == commonSourceTypes[1] ||
props.building.size_far_ratio_source_type == null) ? <></> :
<><MultiDataEntry
title={dataFields.size_plot_area_total_source_links.title}
slug="size_plot_area_total_source_links"
value={props.building.size_plot_area_total_source_links}
{(props.building.size_height_eaves_source_type == commonSourceTypes[0] ||
props.building.size_height_eaves_source_type == commonSourceTypes[1] ||
props.building.size_height_eaves_source_type == null) ? <></> :
<><MultiDataEntry
title={dataFields.size_height_eaves_source_links.title}
slug="size_height_eaves_source_links"
value={props.building.size_height_eaves_source_links}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
tooltip={dataFields.size_height_eaves_source_links.tooltip}
placeholder="https://..."
editableEntries={true}
isUrl={true}
/>
</>
}
</DataEntryGroup>
<DataEntryGroup name="Floor area">
<NumericDataEntry
title={dataFields.size_floor_area_ground.title}
slug="size_floor_area_ground"
value={props.building.size_floor_area_ground}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
tooltip={dataFields.size_plot_area_total_source_links.tooltip}
placeholder="https://..."
editableEntries={true}
isUrl={true}
step={0.1}
min={0}
/>
</>
}
<hr/>
<NumericDataEntry
title={dataFields.size_far_ratio.title}
value={props.building.size_far_ratio}
slug="size_far_ratio"
tooltip={dataFields.size_far_ratio.tooltip}
//placeholder={dataFields.size_far_ratio.example}
mode={props.mode}
onChange={props.onChange}
step={1}
min={0}
/>
<Verification
slug="size_far_ratio"
allow_verify={props.user !== undefined && props.building.size_far_ratio !== null}
onVerify={props.onVerify}
user_verified={props.user_verified.hasOwnProperty("size_far_ratio")}
user_verified_as={props.user_verified.size_far_ratio}
verified_count={props.building.verified.size_far_ratio}
/>
<SelectDataEntry
title={dataFields.size_far_ratio_source_type.title}
slug="size_far_ratio_source_type"
value={props.building.size_far_ratio_source_type}
options={dataFields.size_far_ratio_source_type.items}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
tooltip={dataFields.size_far_ratio_source_type.tooltip}
/>
{(props.building.size_far_ratio_source_type == commonSourceTypes[0] ||
props.building.size_far_ratio_source_type == commonSourceTypes[1] ||
props.building.size_far_ratio_source_type == null) ? <></> :
<><MultiDataEntry
title={dataFields.size_far_ratio_source_links.title}
slug="size_far_ratio_source_links"
value={props.building.size_far_ratio_source_links}
<Verification
slug="size_floor_area_ground"
allow_verify={props.user !== undefined && props.building.size_floor_area_ground !== null}
onVerify={props.onVerify}
user_verified={props.user_verified.hasOwnProperty("size_floor_area_ground")}
user_verified_as={props.user_verified.size_floor_area_ground}
verified_count={props.building.verified.size_floor_area_ground}
/>
<NumericDataEntry
title={dataFields.size_floor_area_total.title}
slug="size_floor_area_total"
value={props.building.size_floor_area_total}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
tooltip={dataFields.size_far_ratio_source_links.tooltip}
placeholder="https://..."
editableEntries={true}
isUrl={true}
step={0.1}
min={0}
/>
</>
}
<hr/>
<DataEntry
title={dataFields.size_parcel_geometry.title}
slug="size_parcel_geometry"
value={props.building.size_parcel_geometry}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
tooltip={dataFields.size_parcel_geometry.tooltip}
placeholder="https://..."
isUrl={true}
/>
<Verification
slug="size_parcel_geometry"
allow_verify={props.user !== undefined && props.building.size_parcel_geometry !== null}
onVerify={props.onVerify}
user_verified={props.user_verified.hasOwnProperty("size_parcel_geometry")}
user_verified_as={props.user_verified.size_parcel_geometry}
verified_count={props.building.verified.size_parcel_geometry}
/>
<SelectDataEntry
title={dataFields.size_parcel_geometry_source_type.title}
slug="size_parcel_geometry_source_type"
value={props.building.size_parcel_geometry_source_type}
options={dataFields.size_parcel_geometry_source_type.items}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
tooltip={dataFields.size_parcel_geometry_source_type.tooltip}
/>
{(props.building.size_parcel_geometry_source_type == commonSourceTypes[0] ||
props.building.size_parcel_geometry_source_type == commonSourceTypes[1] ||
props.building.size_parcel_geometry_source_type == null) ? <></> :
<><MultiDataEntry
title={dataFields.size_parcel_geometry_source_links.title}
slug="size_parcel_geometry_source_links"
value={props.building.size_parcel_geometry_source_links}
<Verification
slug="size_floor_area_total"
allow_verify={props.user !== undefined && props.building.size_floor_area_total !== null}
onVerify={props.onVerify}
user_verified={props.user_verified.hasOwnProperty("size_floor_area_total")}
user_verified_as={props.user_verified.size_floor_area_total}
verified_count={props.building.verified.size_floor_area_total}
/>
<SelectDataEntry
title={dataFields.size_floor_area_source_type.title}
slug="size_floor_area_source_type"
value={props.building.size_floor_area_source_type}
options={dataFields.size_floor_area_source_type.items}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
tooltip={dataFields.size_parcel_geometry_source_links.tooltip}
tooltip={dataFields.size_floor_area_source_type.tooltip}
/>
{(props.building.size_floor_area_source_type == commonSourceTypes[0] ||
props.building.size_floor_area_source_type == commonSourceTypes[1] ||
props.building.size_floor_area_source_type == null) ? <></> :
<><MultiDataEntry
title={dataFields.size_floor_area_source_links.title}
slug="size_floor_area_source_links"
value={props.building.size_floor_area_source_links}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
tooltip={dataFields.size_floor_area_source_links.tooltip}
placeholder="https://..."
editableEntries={true}
isUrl={true}
/>
</>
}
</DataEntryGroup>
<DataEntryGroup name="Plot size">
<NumericDataEntry
title={dataFields.size_width_frontage.title}
slug="size_width_frontage"
value={props.building.size_width_frontage}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
step={0.1}
min={0}
/>
<Verification
slug="size_width_frontage"
allow_verify={props.user !== undefined && props.building.size_width_frontage !== null}
onVerify={props.onVerify}
user_verified={props.user_verified.hasOwnProperty("size_width_frontage")}
user_verified_as={props.user_verified.size_width_frontage}
verified_count={props.building.verified.size_width_frontage}
/>
<SelectDataEntry
title={dataFields.size_width_frontage_source_type.title}
slug="size_width_frontage_source_type"
value={props.building.size_width_frontage_source_type}
options={dataFields.size_width_frontage_source_type.items}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
tooltip={dataFields.size_width_frontage_source_type.tooltip}
/>
{(props.building.size_width_frontage_source_type == commonSourceTypes[0] ||
props.building.size_width_frontage_source_type == commonSourceTypes[1] ||
props.building.size_width_frontage_source_type == null) ? <></> :
<><MultiDataEntry
title={dataFields.size_width_frontage_source_links.title}
slug="size_width_frontage_source_links"
value={props.building.size_width_frontage_source_links}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
tooltip={dataFields.size_width_frontage_source_links.tooltip}
placeholder="https://..."
editableEntries={true}
isUrl={true}
/>
</>
}
<hr/>
<NumericDataEntry
title={dataFields.size_plot_area_total.title}
slug="size_plot_area_total"
tooltip={dataFields.size_plot_area_total.tooltip}
value={props.building.size_plot_area_total}
mode={props.mode}
onChange={props.onChange}
step={0.1}
min={0}
/>
<Verification
slug="size_plot_area_total"
allow_verify={props.user !== undefined && props.building.size_plot_area_total !== null}
onVerify={props.onVerify}
user_verified={props.user_verified.hasOwnProperty("size_plot_area_total")}
user_verified_as={props.user_verified.size_plot_area_total}
verified_count={props.building.verified.size_plot_area_total}
/>
<SelectDataEntry
title={dataFields.size_plot_area_total_source_type.title}
slug="size_plot_area_total_source_type"
value={props.building.size_plot_area_total_source_type}
options={dataFields.size_plot_area_total_source_type.items}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
tooltip={dataFields.size_plot_area_total_source_type.tooltip}
/>
{(props.building.size_plot_area_total_source_type == commonSourceTypes[0] ||
props.building.size_plot_area_total_source_type == commonSourceTypes[1] ||
props.building.size_far_ratio_source_type == null) ? <></> :
<><MultiDataEntry
title={dataFields.size_plot_area_total_source_links.title}
slug="size_plot_area_total_source_links"
value={props.building.size_plot_area_total_source_links}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
tooltip={dataFields.size_plot_area_total_source_links.tooltip}
placeholder="https://..."
editableEntries={true}
isUrl={true}
/>
</>
}
<hr/>
<NumericDataEntry
title={dataFields.size_far_ratio.title}
value={props.building.size_far_ratio}
slug="size_far_ratio"
tooltip={dataFields.size_far_ratio.tooltip}
//placeholder={dataFields.size_far_ratio.example}
mode={props.mode}
onChange={props.onChange}
step={1}
min={0}
/>
<Verification
slug="size_far_ratio"
allow_verify={props.user !== undefined && props.building.size_far_ratio !== null}
onVerify={props.onVerify}
user_verified={props.user_verified.hasOwnProperty("size_far_ratio")}
user_verified_as={props.user_verified.size_far_ratio}
verified_count={props.building.verified.size_far_ratio}
/>
<SelectDataEntry
title={dataFields.size_far_ratio_source_type.title}
slug="size_far_ratio_source_type"
value={props.building.size_far_ratio_source_type}
options={dataFields.size_far_ratio_source_type.items}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
tooltip={dataFields.size_far_ratio_source_type.tooltip}
/>
{(props.building.size_far_ratio_source_type == commonSourceTypes[0] ||
props.building.size_far_ratio_source_type == commonSourceTypes[1] ||
props.building.size_far_ratio_source_type == null) ? <></> :
<><MultiDataEntry
title={dataFields.size_far_ratio_source_links.title}
slug="size_far_ratio_source_links"
value={props.building.size_far_ratio_source_links}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
tooltip={dataFields.size_far_ratio_source_links.tooltip}
placeholder="https://..."
editableEntries={true}
isUrl={true}
/>
</>
}
<hr/>
<DataEntry
title={dataFields.size_parcel_geometry.title}
slug="size_parcel_geometry"
value={props.building.size_parcel_geometry}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
tooltip={dataFields.size_parcel_geometry.tooltip}
placeholder="https://..."
editableEntries={true}
isUrl={true}
/>
</>
}
</DataEntryGroup>
</Fragment>
);
<Verification
slug="size_parcel_geometry"
allow_verify={props.user !== undefined && props.building.size_parcel_geometry !== null}
onVerify={props.onVerify}
user_verified={props.user_verified.hasOwnProperty("size_parcel_geometry")}
user_verified_as={props.user_verified.size_parcel_geometry}
verified_count={props.building.verified.size_parcel_geometry}
/>
<SelectDataEntry
title={dataFields.size_parcel_geometry_source_type.title}
slug="size_parcel_geometry_source_type"
value={props.building.size_parcel_geometry_source_type}
options={dataFields.size_parcel_geometry_source_type.items}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
tooltip={dataFields.size_parcel_geometry_source_type.tooltip}
/>
{(props.building.size_parcel_geometry_source_type == commonSourceTypes[0] ||
props.building.size_parcel_geometry_source_type == commonSourceTypes[1] ||
props.building.size_parcel_geometry_source_type == null) ? <></> :
<><MultiDataEntry
title={dataFields.size_parcel_geometry_source_links.title}
slug="size_parcel_geometry_source_links"
value={props.building.size_parcel_geometry_source_links}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
tooltip={dataFields.size_parcel_geometry_source_links.tooltip}
placeholder="https://..."
editableEntries={true}
isUrl={true}
/>
</>
}
</DataEntryGroup>
</Fragment>
)
};
const SizeContainer = withCopyEdit(SizeView);
export default SizeContainer;

View File

@ -1,28 +1,25 @@
import React, { Fragment } from 'react';
import InfoBox from '../../components/info-box';
import { commonSourceTypes, dataFields } from '../../config/data-fields-config';
import DataEntry from '../data-components/data-entry';
import NumericDataEntry from '../data-components/numeric-data-entry';
import withCopyEdit from '../data-container';
import { CategoryViewProps } from './category-view-props';
import { DataEntryGroup } from '../data-components/data-entry-group';
import { MultiDataEntry } from '../data-components/multi-data-entry/multi-data-entry';
import SelectDataEntry from '../data-components/select-data-entry';
import Verification from '../data-components/verification';
import { LogicalDataEntry } from '../data-components/logical-data-entry/logical-data-entry';
/**
* Streetscape view/edit section
* Street Context view/edit section
*/
const StreetscapeView: React.FunctionComponent<CategoryViewProps> = (props) => (
const StreetContextView: React.FunctionComponent<CategoryViewProps> = (props) => (
<Fragment>
<DataEntryGroup name="Does the building have a garden?">
<SelectDataEntry
<DataEntryGroup name="Green Space">
<LogicalDataEntry
title={dataFields.context_front_garden.title}
slug="context_front_garden"
value={props.building.context_front_garden}
options={dataFields.context_front_garden.items}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
@ -36,7 +33,7 @@ const StreetscapeView: React.FunctionComponent<CategoryViewProps> = (props) => (
user_verified_as={props.user_verified.context_front_garden}
verified_count={props.building.verified.context_front_garden}
/>
<SelectDataEntry
<LogicalDataEntry
title={dataFields.context_back_garden.title}
slug="context_back_garden"
value={props.building.context_back_garden}
@ -44,8 +41,6 @@ const StreetscapeView: React.FunctionComponent<CategoryViewProps> = (props) => (
copy={props.copy}
onChange={props.onChange}
tooltip={dataFields.context_back_garden.tooltip}
//placeholder={dataFields.context_back_garden.example}
options={dataFields.context_back_garden.items}
/>
<Verification
slug="context_back_garden"
@ -55,7 +50,7 @@ const StreetscapeView: React.FunctionComponent<CategoryViewProps> = (props) => (
user_verified_as={props.user_verified.context_back_garden}
verified_count={props.building.verified.context_back_garden}
/>
<SelectDataEntry
<LogicalDataEntry
title={dataFields.context_flats_garden.title}
slug="context_flats_garden"
value={props.building.context_flats_garden}
@ -63,8 +58,6 @@ const StreetscapeView: React.FunctionComponent<CategoryViewProps> = (props) => (
copy={props.copy}
onChange={props.onChange}
tooltip={dataFields.context_flats_garden.tooltip}
//placeholder={dataFields.context_flats_garden.example}
options={dataFields.context_flats_garden.items}
/>
<Verification
slug="context_flats_garden"
@ -74,7 +67,6 @@ const StreetscapeView: React.FunctionComponent<CategoryViewProps> = (props) => (
user_verified_as={props.user_verified.context_flats_garden}
verified_count={props.building.verified.context_flats_garden}
/>
<hr/>
<SelectDataEntry
title={dataFields.context_garden_source_type.title}
slug="context_garden_source_type"
@ -104,8 +96,110 @@ const StreetscapeView: React.FunctionComponent<CategoryViewProps> = (props) => (
/>
</>
}
<hr/>
<NumericDataEntry
title={dataFields.context_green_space_distance.title}
value={props.building.context_green_space_distance}
slug="context_green_space_distance"
tooltip={dataFields.context_green_space_distance.tooltip}
//placeholder={dataFields.context_green_space_distance.example}
mode={props.mode}
onChange={props.onChange}
step={1}
min={0}
/>
<Verification
slug="context_green_space_distance"
allow_verify={props.user !== undefined && props.building.context_green_space_distance !== null}
onVerify={props.onVerify}
user_verified={props.user_verified.hasOwnProperty("context_green_space_distance")}
user_verified_as={props.user_verified.context_green_space_distance}
verified_count={props.building.verified.context_green_space_distance}
/>
<SelectDataEntry
title={dataFields.context_green_space_distance_source_type.title}
slug="context_green_space_distance_source_type"
value={props.building.context_green_space_distance_source_type}
options={dataFields.context_green_space_distance_source_type.items}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
tooltip={dataFields.context_green_space_distance_source_type.tooltip}
/>
{(props.building.context_green_space_distance_source_type == commonSourceTypes[0] ||
props.building.context_green_space_distance_source_type == commonSourceTypes[1] ||
props.building.context_green_space_distance_source_type == null) ? <></> :
<><MultiDataEntry
title={dataFields.context_green_space_distance_source_links.title}
slug="context_green_space_distance_source_links"
value={props.building.context_green_space_distance_source_links}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
tooltip={dataFields.context_green_space_distance_source_links.tooltip}
placeholder="https://..."
editableEntries={true}
isUrl={true}
/>
</>
}
<hr/>
<NumericDataEntry
title={dataFields.context_tree_distance.title}
value={props.building.context_tree_distance}
slug="context_tree_distance"
tooltip={dataFields.context_tree_distance.tooltip}
//placeholder={dataFields.context_tree_distance.example}
mode={props.mode}
onChange={props.onChange}
step={1}
min={0}
/>
<Verification
slug="context_tree_distance"
allow_verify={props.user !== undefined && props.building.context_tree_distance !== null}
onVerify={props.onVerify}
user_verified={props.user_verified.hasOwnProperty("context_tree_distance")}
user_verified_as={props.user_verified.context_tree_distance}
verified_count={props.building.verified.context_tree_distance}
/>
<SelectDataEntry
title={dataFields.context_tree_distance_source_type.title}
slug="context_tree_distance_source_type"
value={props.building.context_tree_distance_source_type}
options={dataFields.context_tree_distance_source_type.items}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
tooltip={dataFields.context_tree_distance_source_type.tooltip}
/>
{(props.building.context_tree_distance_source_type == commonSourceTypes[0] ||
props.building.context_tree_distance_source_type == commonSourceTypes[1] ||
props.building.context_tree_distance_source_type == null) ? <></> :
<><MultiDataEntry
title={dataFields.context_tree_distance_source_links.title}
slug="context_tree_distance_source_links"
value={props.building.context_tree_distance_source_links}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
tooltip={dataFields.context_tree_distance_source_links.tooltip}
placeholder="https://..."
editableEntries={true}
isUrl={true}
/>
</>
}
</DataEntryGroup>
<DataEntryGroup name="Street/pavement properties">
<DataEntryGroup name="Street/pavement">
<DataEntry
title="Walkability Index"
slug=""
value=""
mode='view'
tooltip='Under development'
/>
<hr/>
<NumericDataEntry
title={dataFields.context_street_width.title}
value={props.building.context_street_width}
@ -247,103 +341,17 @@ const StreetscapeView: React.FunctionComponent<CategoryViewProps> = (props) => (
</>
}
</DataEntryGroup>
<DataEntryGroup name="Access to green space">
<NumericDataEntry
title={dataFields.context_green_space_distance.title}
value={props.building.context_green_space_distance}
slug="context_green_space_distance"
tooltip={dataFields.context_green_space_distance.tooltip}
//placeholder={dataFields.context_green_space_distance.example}
mode={props.mode}
onChange={props.onChange}
step={1}
min={0}
<DataEntryGroup name="Number of entrances facing street">
<DataEntry
title="Number of entrances facing street"
slug=""
value=""
mode='view'
tooltip='Under development'
/>
<Verification
slug="context_green_space_distance"
allow_verify={props.user !== undefined && props.building.context_green_space_distance !== null}
onVerify={props.onVerify}
user_verified={props.user_verified.hasOwnProperty("context_green_space_distance")}
user_verified_as={props.user_verified.context_green_space_distance}
verified_count={props.building.verified.context_green_space_distance}
/>
<SelectDataEntry
title={dataFields.context_green_space_distance_source_type.title}
slug="context_green_space_distance_source_type"
value={props.building.context_green_space_distance_source_type}
options={dataFields.context_green_space_distance_source_type.items}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
tooltip={dataFields.context_green_space_distance_source_type.tooltip}
/>
{(props.building.context_green_space_distance_source_type == commonSourceTypes[0] ||
props.building.context_green_space_distance_source_type == commonSourceTypes[1] ||
props.building.context_green_space_distance_source_type == null) ? <></> :
<><MultiDataEntry
title={dataFields.context_green_space_distance_source_links.title}
slug="context_green_space_distance_source_links"
value={props.building.context_green_space_distance_source_links}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
tooltip={dataFields.context_green_space_distance_source_links.tooltip}
placeholder="https://..."
editableEntries={true}
isUrl={true}
/>
</>
}
<hr/>
<NumericDataEntry
title={dataFields.context_tree_distance.title}
value={props.building.context_tree_distance}
slug="context_tree_distance"
tooltip={dataFields.context_tree_distance.tooltip}
//placeholder={dataFields.context_tree_distance.example}
mode={props.mode}
onChange={props.onChange}
step={1}
min={0}
/>
<Verification
slug="context_tree_distance"
allow_verify={props.user !== undefined && props.building.context_tree_distance !== null}
onVerify={props.onVerify}
user_verified={props.user_verified.hasOwnProperty("context_tree_distance")}
user_verified_as={props.user_verified.context_tree_distance}
verified_count={props.building.verified.context_tree_distance}
/>
<SelectDataEntry
title={dataFields.context_tree_distance_source_type.title}
slug="context_tree_distance_source_type"
value={props.building.context_tree_distance_source_type}
options={dataFields.context_tree_distance_source_type.items}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
tooltip={dataFields.context_tree_distance_source_type.tooltip}
/>
{(props.building.context_tree_distance_source_type == commonSourceTypes[0] ||
props.building.context_tree_distance_source_type == commonSourceTypes[1] ||
props.building.context_tree_distance_source_type == null) ? <></> :
<><MultiDataEntry
title={dataFields.context_tree_distance_source_links.title}
slug="context_tree_distance_source_links"
value={props.building.context_tree_distance_source_links}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
tooltip={dataFields.context_tree_distance_source_links.tooltip}
placeholder="https://..."
editableEntries={true}
isUrl={true}
/>
</>
}
</DataEntryGroup>
</Fragment>
);
const StreetscapeContainer = withCopyEdit(StreetscapeView);
const StreetContextContainer = withCopyEdit(StreetContextView);
export default StreetscapeContainer;
export default StreetContextContainer;

View File

@ -4,9 +4,9 @@ import { commonSourceTypes, dataFields } from '../../config/data-fields-config';
import SelectDataEntry from '../data-components/select-data-entry';
import NumericDataEntry from '../data-components/numeric-data-entry';
import Verification from '../data-components/verification';
import { MultiDataEntry } from '../data-components/multi-data-entry/multi-data-entry';
import { LogicalDataEntry, LogicalDataEntryYesOnly } from '../data-components/logical-data-entry/logical-data-entry';
import { DataEntryGroup } from '../data-components/data-entry-group';
import { MultiDataEntry } from '../data-components/multi-data-entry/multi-data-entry';
import withCopyEdit from '../data-container';
@ -21,57 +21,7 @@ const TeamView: React.FunctionComponent<CategoryViewProps> = (props) => {
const currentBuildingConstructionYear = building.date_year || undefined;
return (
<form>
<DataEntryGroup name="Data relating to original building or extension?">
<NumericDataEntry
slug='date_year'
title={dataFields.date_year.title}
value={currentBuildingConstructionYear}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
step={1}
min={1}
max={currentYear}
tooltip={dataFields.extension_year.tooltip}
/>
<Verification
slug="date_year"
allow_verify={props.user !== undefined && props.building.date_year !== null && !props.edited}
onVerify={props.onVerify}
user_verified={props.user_verified.hasOwnProperty("date_year")}
user_verified_as={props.user_verified.date_year}
verified_count={props.building.verified.date_year}
/>
<SelectDataEntry
title={dataFields.date_source.title}
slug="date_source"
value={props.building.date_source}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
tooltip={dataFields.date_source.tooltip}
options={dataFields.date_source.items}
placeholder={dataFields.date_source.example}
/>
{(props.building.date_source == dataFields.date_source.items[0] ||
props.building.date_source == dataFields.date_source.items[1] ||
props.building.date_source == null) ? <></> :
<>
<MultiDataEntry
title={dataFields.date_link.title}
slug="date_link"
value={props.building.date_link}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
tooltip={dataFields.date_link.tooltip}
placeholder="https://..."
editableEntries={true}
isUrl={true}
/>
</>
}
<hr/>
<DataEntryGroup name="General info">
<LogicalDataEntry
title={dataFields.has_extension.title}
slug="has_extension"
@ -81,7 +31,7 @@ const TeamView: React.FunctionComponent<CategoryViewProps> = (props) => {
onChange={props.onChange}
tooltip={dataFields.has_extension.tooltip}
/>
{props.building.has_extension ? (
{props.building.has_extension!=null && !props.building.has_extension ? (
<>
<NumericDataEntry
slug='extension_year'
@ -135,7 +85,7 @@ const TeamView: React.FunctionComponent<CategoryViewProps> = (props) => {
</>
) : (null)}
</DataEntryGroup>
<DataEntryGroup name="Land ownership data">
<DataEntryGroup name="Land ownership">
<MultiDataEntry
title={dataFields.landowner.title}
slug="landowner"
@ -146,6 +96,7 @@ const TeamView: React.FunctionComponent<CategoryViewProps> = (props) => {
tooltip={dataFields.landowner.tooltip}
placeholder=""
editableEntries={true}
disabled={true}
/>
<Verification
slug="landowner"
@ -155,6 +106,18 @@ const TeamView: React.FunctionComponent<CategoryViewProps> = (props) => {
user_verified_as={props.user_verified.landowner}
verified_count={props.building.verified.landowner}
/>
<MultiDataEntry
title={dataFields.landowner_links.title}
slug="landowner_links"
value={props.building.landowner_links}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
tooltip={dataFields.landowner_links.tooltip}
placeholder="https://..."
editableEntries={true}
isUrl={true}
/>
<SelectDataEntry
title={dataFields.landowner_source_type.title}
slug="landowner_source_type"
@ -185,7 +148,7 @@ const TeamView: React.FunctionComponent<CategoryViewProps> = (props) => {
</>
}
</DataEntryGroup>
<DataEntryGroup name="Developer data">
<DataEntryGroup name="Developer">
<SelectDataEntry
slug='developer_type'
title={dataFields.developer_type.title}
@ -213,6 +176,7 @@ const TeamView: React.FunctionComponent<CategoryViewProps> = (props) => {
tooltip={dataFields.developer_name.tooltip}
placeholder=""
editableEntries={true}
disabled={true}
/>
<Verification
slug="developer_name"
@ -222,6 +186,18 @@ const TeamView: React.FunctionComponent<CategoryViewProps> = (props) => {
user_verified_as={props.user_verified.developer_name}
verified_count={props.building.verified.developer_name}
/>
<MultiDataEntry
title={dataFields.developer_links.title}
slug="developer_links"
value={props.building.developer_links}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
tooltip={dataFields.developer_links.tooltip}
placeholder="https://..."
editableEntries={true}
isUrl={true}
/>
<SelectDataEntry
title={dataFields.developer_source_type.title}
slug="developer_source_type"
@ -252,7 +228,7 @@ const TeamView: React.FunctionComponent<CategoryViewProps> = (props) => {
</>
}
</DataEntryGroup>
<DataEntryGroup name="Designer data">
<DataEntryGroup name="Designer">
<MultiDataEntry
title={dataFields.designers.title}
slug="designers"
@ -263,6 +239,7 @@ const TeamView: React.FunctionComponent<CategoryViewProps> = (props) => {
tooltip={dataFields.designers.tooltip}
placeholder=""
editableEntries={true}
disabled={true}
/>
<Verification
slug="designers"
@ -272,7 +249,18 @@ const TeamView: React.FunctionComponent<CategoryViewProps> = (props) => {
user_verified_as={props.user_verified.designers}
verified_count={props.building.verified.designers}
/>
<MultiDataEntry
title={dataFields.designers_links.title}
slug="designers_links"
value={props.building.designers_links}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
tooltip={dataFields.designers_links.tooltip}
placeholder="https://..."
editableEntries={true}
isUrl={true}
/>
<SelectDataEntry
slug='lead_designer_type'
title={dataFields.lead_designer_type.title}
@ -319,98 +307,113 @@ const TeamView: React.FunctionComponent<CategoryViewProps> = (props) => {
/>
</>
}
<hr/>
<LogicalDataEntryYesOnly
slug='designer_awards'
title={dataFields.designer_awards.title}
tooltip={dataFields.designer_awards.tooltip}
value={props.building.designer_awards}
copy={props.copy}
onChange={props.onChange}
mode={props.mode}
/>
<Verification
slug="designer_awards"
allow_verify={props.user !== undefined && props.building.designer_awards !== null && !props.edited}
onVerify={props.onVerify}
user_verified={props.user_verified.hasOwnProperty("designer_awards")}
user_verified_as={props.user_verified.designer_awards}
verified_count={props.building.verified.designer_awards}
/>
{props.building.designer_awards ? (
<>
</DataEntryGroup>
<DataEntryGroup name="Builder">
<MultiDataEntry
title={dataFields.awards_source_link.title}
slug="awards_source_link"
value={props.building.awards_source_link}
title={dataFields.builder.title}
slug="builder"
value={props.building.builder}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
tooltip={dataFields.awards_source_link.tooltip}
tooltip={dataFields.builder.tooltip}
placeholder=""
editableEntries={true}
disabled={true}
/>
<Verification
slug="builder"
allow_verify={props.user !== undefined && props.building.builder !== null && !props.edited}
onVerify={props.onVerify}
user_verified={props.user_verified.hasOwnProperty("builder")}
user_verified_as={props.user_verified.builder}
verified_count={props.building.verified.builder}
/>
<MultiDataEntry
title={dataFields.builder_links.title}
slug="builder_links"
value={props.building.builder_links}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
tooltip={dataFields.builder_links.tooltip}
placeholder="https://..."
editableEntries={true}
isUrl={true}
/>
<SelectDataEntry
title={dataFields.builder_source_type.title}
slug="builder_source_type"
value={props.building.builder_source_type}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
tooltip={dataFields.builder_source_type.tooltip}
options={dataFields.builder_source_type.items}
placeholder={dataFields.builder_source_type.example}
/>
<Verification
slug="awards_source_link"
allow_verify={props.user !== undefined && props.building.awards_source_link !== null && !props.edited}
onVerify={props.onVerify}
user_verified={props.user_verified.hasOwnProperty("awards_source_link")}
user_verified_as={props.user_verified.awards_source_link}
verified_count={props.building.verified.awards_source_link}
/>
</>
) : (null)
}
{(props.building.builder_source_type == commonSourceTypes[0] ||
props.building.builder_source_type == commonSourceTypes[1] ||
props.building.builder_source_type == null) ? <></> :
<>
<MultiDataEntry
title={dataFields.builder_source_link.title}
slug="builder_source_link"
value={props.building.builder_source_link}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
placeholder="https://..."
editableEntries={true}
isUrl={true}
/>
</>
}
</DataEntryGroup>
<DataEntryGroup name="Builder data">
<MultiDataEntry
title={dataFields.builder.title}
slug="builder"
value={props.building.builder}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
placeholder=""
editableEntries={true}
/>
<Verification
slug="builder"
allow_verify={props.user !== undefined && props.building.builder !== null && !props.edited}
onVerify={props.onVerify}
user_verified={props.user_verified.hasOwnProperty("builder")}
user_verified_as={props.user_verified.builder}
verified_count={props.building.verified.builder}
/>
<SelectDataEntry
title={dataFields.builder_source_type.title}
slug="builder_source_type"
value={props.building.builder_source_type}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
tooltip={dataFields.builder_source_type.tooltip}
options={dataFields.builder_source_type.items}
placeholder={dataFields.builder_source_type.example}
/>
{(props.building.builder_source_type == commonSourceTypes[0] ||
props.building.builder_source_type == commonSourceTypes[1] ||
props.building.builder_source_type == null) ? <></> :
<>
<DataEntryGroup name="Awards">
<LogicalDataEntryYesOnly
slug='designer_awards'
title={dataFields.designer_awards.title}
tooltip={dataFields.designer_awards.tooltip}
value={props.building.designer_awards}
copy={props.copy}
onChange={props.onChange}
mode={props.mode}
/>
<Verification
slug="designer_awards"
allow_verify={props.user !== undefined && props.building.designer_awards !== null && !props.edited}
onVerify={props.onVerify}
user_verified={props.user_verified.hasOwnProperty("designer_awards")}
user_verified_as={props.user_verified.designer_awards}
verified_count={props.building.verified.designer_awards}
/>
{props.building.designer_awards ? (
<>
<MultiDataEntry
title={dataFields.builder_source_link.title}
slug="builder_source_link"
value={props.building.builder_source_link}
title={dataFields.awards_source_link.title}
slug="awards_source_link"
value={props.building.awards_source_link}
mode={props.mode}
copy={props.copy}
onChange={props.onChange}
tooltip={dataFields.awards_source_link.tooltip}
placeholder="https://..."
editableEntries={true}
isUrl={true}
/>
</>
}
</DataEntryGroup>
/>
<Verification
slug="awards_source_link"
allow_verify={props.user !== undefined && props.building.awards_source_link !== null && !props.edited}
onVerify={props.onVerify}
user_verified={props.user_verified.hasOwnProperty("awards_source_link")}
user_verified_as={props.user_verified.awards_source_link}
verified_count={props.building.verified.awards_source_link}
/>
</>
) : (null)
}
</DataEntryGroup>
</form>
);
};

View File

@ -184,3 +184,16 @@
padding-top: 0px;
padding-bottom: 5px;
}
dd {
margin-bottom: 15px;
}
.uprn-list {
margin-top: 10px;
margin-bottom: 0px;
}
.uprn-list li {
margin-bottom: 10px;
}

View File

@ -338,11 +338,11 @@ export const categoryMapsConfig: {[key in Category]: CategoryMapDefinition[]} =
{
mapStyle: 'is_domestic',
legend: {
title: 'Domestic building',
title: 'Residential building',
elements: [
{ color: '#f7ec25', text: 'Domestic' },
{ color: '#f7ec25', text: 'Residential' },
{ color: '#fc9b2a', text: 'Mixed' },
{ color: '#ff2121', text: 'Non-domestic' },
{ color: '#ff2121', text: 'Non-residential' },
]
}
}

View File

@ -7,7 +7,7 @@ import ResilienceContainer from '../building/data-containers/resilience';
import LocationContainer from '../building/data-containers/location';
import PlanningContainer from '../building/data-containers/planning';
import SizeContainer from '../building/data-containers/size';
import StreetscapeContainer from '../building/data-containers/street-context';
import StreetContextContainer from '../building/data-containers/street-context';
import SustainabilityContainer from '../building/data-containers/energy-performance';
import TeamContainer from '../building/data-containers/team';
import TypeContainer from '../building/data-containers/typology';
@ -22,7 +22,7 @@ export const categoryUiConfig: {[key in Category]: DataContainerType} = {
[Category.Age]: AgeContainer,
[Category.Size]: SizeContainer,
[Category.Construction]: ConstructionContainer,
[Category.StreetContext]: StreetscapeContainer,
[Category.StreetContext]: StreetContextContainer,
[Category.Team]: TeamContainer,
[Category.Planning]: PlanningContainer,
[Category.EnergyPerformance]: SustainabilityContainer,

View File

@ -6,13 +6,14 @@ let ccconfig: CCConfig = require('../../cc-config.json')
* Common list of Source Types, used in multiple menus
*/
export const commonSourceTypes = [
"Assessed by eye",
"Assessed using expert knowledge of building or building type",
"Assessed using streetview photographs or satellite imagery",
"Assessed by eye/personal knowledge of the building",
"Assessed using professional knowledge of building or building type",
"Assessed using streetview photographs, satellite imagery or maps",
"Assessed by specialist emergency group",
"Current government record/database",
"Live streamed from a government source",
"Current government record/dataset",
"Independently managed public database",
"Open database",
"Other independently managed public database",
"Commercial database",
"Inferred computationally using existing open attribute data",
];
@ -144,8 +145,14 @@ export const buildingUserFields = {
export const dataFields = { /* eslint-disable @typescript-eslint/camelcase */
location_name: {
category: Category.Location,
title: "Building name (non-domestic)",
tooltip: "Link to a website with the name of the building.<br/><br/>(For security reasons, we currently only collect the names of non-residential buildings).",
title: "Building name (non-residential)",
tooltip: "The name of the building.<br/><br/>(For security reasons, we currently only collect the names of non-residential buildings).",
example: "Broadcasting House",
},
location_name_link: {
category: Category.Location,
title: "Building name link",
tooltip: "Link to a website with the name of the building.",
example: "https://en.wikipedia.org/wiki/Palace_of_Westminster",
},
location_number: {
@ -156,7 +163,7 @@ export const dataFields = { /* eslint-disable @typescript-eslint/camelcase */
},
location_street: {
category: Category.Location,
title: "Street",
title: "Street name",
example: "Gower Street",
//tooltip: ,
},
@ -176,7 +183,7 @@ export const dataFields = { /* eslint-disable @typescript-eslint/camelcase */
category: Category.Location,
title: "Area code/"+ccconfig.postcode,
example: "W1W 6TR",
//tooltip: ,
tooltip: "Correctly formatted UK postcode, i.e. NW1 2FB",
},
location_address_source: {
category: Category.Location,
@ -194,9 +201,15 @@ export const dataFields = { /* eslint-disable @typescript-eslint/camelcase */
ref_toid: {
category: Category.Location,
title: "Building footprint ID",
tooltip: "Ordnance Survey Topography Layer ID (TOID) [<a href='https://www.ordnancesurvey.co.uk/business-government/products/open-toid'>link</a>]",
tooltip: "Ordnance Survey Topography Layer ID (TOID)",
example: "",
},
location_alternative_footprint_links: {
category: Category.Location,
title: "Alternative open building footprint links",
tooltip: "Links to alternative building footprint datasets (include the direct link to the footprint of this building where possible).",
example: ["", "", ""],
},
/**
* UPRNs is not part of the buildings table, but the string fields
@ -205,7 +218,7 @@ export const dataFields = { /* eslint-disable @typescript-eslint/camelcase */
uprns: {
category: Category.Location,
title: "Unique Property Reference Number(s) (UPRN)",
tooltip: "Unique Property Reference Numbers (to be filled automatically) [<a href='https://beta.ordnancesurvey.co.uk/products/os-open-uprn'>LINK</a>]",
tooltip: "Unique Property Reference Number(s) (UPRN) (derived automatically)",
example: [{ uprn: "", parent_uprn: "" }, { uprn: "", parent_uprn: "" }],
},
@ -218,11 +231,10 @@ export const dataFields = { /* eslint-disable @typescript-eslint/camelcase */
],
},
ref_osm_id: {
category: Category.Location,
title: "OpenStreetMap ID",
tooltip: "OpenStreetMap feature ID",
tooltip: "OpenStreetMap building ('way') ID - Numerical string of up to 9 characters",
example: "",
},
location_latitude: {
@ -267,15 +279,16 @@ export const dataFields = { /* eslint-disable @typescript-eslint/camelcase */
title: "Source type",
tooltip: "Source for the current land use",
example: "",
items: [
"Expert/personal knowledge of building",
"Online streetview image",
"Open planning authority dataset",
"Open property tax dataset",
"Open housing dataset",
"Open address dataset",
"Other"
],
items: commonSourceTypes
// items: [
// "Expert/personal knowledge of building",
// "Online streetview image",
// "Open planning authority dataset",
// "Open property tax dataset",
// "Open housing dataset",
// "Open address dataset",
// "Other"
// ],
},
current_landuse_source_detail: {
category: Category.LandUse,
@ -342,7 +355,7 @@ export const dataFields = { /* eslint-disable @typescript-eslint/camelcase */
},
facade_year: {
category: Category.Age,
title: "Date of front of building",
title: "Date of front of building (best estimate)",
tooltip: "Best estimate",
example: 1900,
},
@ -416,7 +429,7 @@ export const dataFields = { /* eslint-disable @typescript-eslint/camelcase */
category: Category.Size,
title: "Height to apex (m)",
example: 100.5,
tooltip: "i.e. the highest part of the roof.",
tooltip: "i.e. the highest part of the roof (in meters).",
},
size_height_apex_source_type: {
category: Category.Team,
@ -435,7 +448,7 @@ export const dataFields = { /* eslint-disable @typescript-eslint/camelcase */
category: Category.Size,
title: "Height to eaves (m)",
example: 20.33,
tooltip: "i.e. to where the top of the wall meets the roof",
tooltip: "i.e. to where the top of the wall meets the roof (in meters)",
},
size_height_eaves_source_type: {
category: Category.Team,
@ -479,7 +492,7 @@ export const dataFields = { /* eslint-disable @typescript-eslint/camelcase */
category: Category.Size,
title: "Frontage width (m)",
example: 12.2,
//tooltip: ,
tooltip: "Size of the frontage of the building (in meters)",
},
size_width_frontage_source_type: {
category: Category.Team,
@ -583,19 +596,19 @@ export const dataFields = { /* eslint-disable @typescript-eslint/camelcase */
sust_breeam_rating: {
category: Category.EnergyPerformance,
title: "Official environmental quality rating",
title: "Residential energy rating",
tooltip: ccconfig.energy_rating,
example: "",
},
sust_dec: {
category: Category.EnergyPerformance,
title: "Non-domestic Building Energy Rating",
title: "Non-residential Building Energy Rating",
tooltip: "Display Energy Certificate (DEC) Any public building should have (and display) a DEC. Showing how the energy use for that building compares to other buildings with same use",
example: "G",
},
sust_aggregate_estimate_epc: {
category: Category.EnergyPerformance,
title: "Domestic Building Energy Rating",
title: "Residential Building Energy Rating",
tooltip: "Energy Performance Certificate (EPC) Any premises sold or rented is required to have an EPC to show how energy efficient it is. Only buildings rate grade E or higher may be rented",
example: "",
},
@ -716,7 +729,7 @@ export const dataFields = { /* eslint-disable @typescript-eslint/camelcase */
},
planning_list_grade: {
category: Category.Planning,
title: "What is its rating?",
title: "What is its protection rating?",
example: "II",
//tooltip: ,
},
@ -740,19 +753,19 @@ export const dataFields = { /* eslint-disable @typescript-eslint/camelcase */
},
planning_in_apa_url: {
category: Category.Planning,
title: "Is it in an area if archaeological priority?",
title: "Is the building in an area of archaeological priority?",
example: "",
//tooltip: ,
},
planning_local_list_url: {
category: Category.Planning,
title: "Is it a locally listed heritage asset?",
title: "Is the building a locally listed heritage asset?",
example: "",
//tooltip: ,
},
planning_historic_area_assessment_url: {
category: Category.Planning,
title: "Does it have any other kind of historic area assessment?",
title: "Does it have any other type of designation?",
example: "",
//tooltip: ,
},
@ -764,8 +777,8 @@ export const dataFields = { /* eslint-disable @typescript-eslint/camelcase */
},
is_domestic: {
category: Category.Team,
title: "Is the building a home/domestic building?",
tooltip: "Note: Homes used as offices for working from home should be classified as domestic.",
title: "Is the building a home/residential building?",
tooltip: "Note: Homes used as offices for working from home should be classified as residential.",
example: "mixed domestic/non-domestic",
items: [
"Yes",
@ -776,14 +789,14 @@ export const dataFields = { /* eslint-disable @typescript-eslint/camelcase */
is_domestic_source: {
category: Category.Team,
title: "Source type",
tooltip: "Source of domestic/non-domestic data",
tooltip: "Source of residential/non-residential data",
example: "",
items: commonSourceTypes
},
is_domestic_links: {
category: Category.Team,
title: "Source links",
tooltip: "URL(s) for domestic/non-domestic data source(s)",
tooltip: "URL(s) for residential/non-residential data source(s)",
example: ["", "", ""],
},
likes_total: {
@ -811,19 +824,19 @@ export const dataFields = { /* eslint-disable @typescript-eslint/camelcase */
community_activities_current: {
category: Category.Community,
title: "Are activities open to the community currently taking place in the building?",
title: "Is this building currently used for community activities?",
tooltip: "E.g. youth club, place of worship, GP surgery, pub",
example: true
},
community_activities: {
category: Category.Community,
title: "Has this ever been used for community activities in the past?",
title: "If not been used for community activities in the past?",
tooltip: "E.g. youth club, place of worship, GP surgery, pub",
example: true
},
community_activities_always: {
category: Category.Community,
title: "Has the building always been used for community activities?",
title: "If in community use now, has it always been used for community activities?",
tooltip: "E.g. youth club, place of worship, GP surgery, pub",
example: true
},
@ -837,11 +850,15 @@ export const dataFields = { /* eslint-disable @typescript-eslint/camelcase */
title: "Is the building in public/community ownership?",
example: "Privately owned (non-corporate)",
items: [
'Government-owned',
'Charity-owned',
'Community-owned/cooperative',
'Owned by other non-profit body',
'Not in public/community ownership'
"Public/State body",
"Public body with Private company",
"Charity",
"Community group/Cooperative",
"Other non-profit body",
"Privately owned company",
"Privately owned offshore company",
"Private individual",
"Other",
]
},
community_public_ownership_sources: {
@ -892,8 +909,8 @@ export const dataFields = { /* eslint-disable @typescript-eslint/camelcase */
},
has_extension: {
category: Category.Team,
title: "Was a later extension added?",
tooltip: "",
title: "Does this information relate to the original main building?",
tooltip: "If the data in this section relates to the original main building, select \"yes\". If the data relates to a later extension/ redevelopment, select \"no\".",
example: false
},
extension_year: {
@ -934,7 +951,13 @@ export const dataFields = { /* eslint-disable @typescript-eslint/camelcase */
developer_name: {
category: Category.Team,
title: "Who were the developer(s)?",
tooltip: "Free text. First name, space, then Last name",
tooltip: "Name(s) of the building's developers.<br/><br/>Free-text entry disabled for security reasons.",
example: ["", "", ""],
},
developer_links: {
category: Category.Team,
title: "Developer link(s)",
tooltip: "Link(s) to webpage(s) explaining who developed the building.",
example: ["", "", ""],
},
developer_source_type: {
@ -953,7 +976,13 @@ export const dataFields = { /* eslint-disable @typescript-eslint/camelcase */
landowner: {
category: Category.Team,
title: "Landowner(s) at time of construction",
tooltip: "Free text. First name, space, then Last name",
tooltip: "Land owner when the building was constructed.<br/><br/>Free-text entry disabled for security reasons.<br/><br/>For info on current land ownership, see 'Planning Controls'.",
example: ["", "", ""],
},
landowner_links: {
category: Category.Team,
title: "Landowner link(s)",
tooltip: "Link(s) to webpage(s) explaining who owned the land when when the building was built.",
example: ["", "", ""],
},
landowner_source_type: {
@ -972,7 +1001,13 @@ export const dataFields = { /* eslint-disable @typescript-eslint/camelcase */
designers: {
category: Category.Team,
title: "Who were the main designer(s)?",
tooltip: "Free text. First name, space, then Last name",
tooltip: "Free-text entry disabled for security reasons.",
example: ["", "", ""],
},
designers_links: {
category: Category.Team,
title: "Designer link(s)",
tooltip: "Link(s) to webpage(s) explaining who designed the building.",
example: ["", "", ""],
},
designers_source_type: {
@ -1003,19 +1038,26 @@ export const dataFields = { /* eslint-disable @typescript-eslint/camelcase */
},
designer_awards: {
category: Category.Team,
title: "Did the design team win any awards for this building?",
title: "Has the building won any awards?",
tooltip: "",
example: false
},
awards_source_link: {
category: Category.Team,
title: "Source link(s) for designer award(s)",
tooltip: "URL for source for designer award(s)",
title: "Source link(s) for building award(s)",
tooltip: "URL for source for building award(s)",
example: ["", "", ""],
},
builder: {
category: Category.Team,
title: "Name of builder/construction team",
title: "Name of builder/construction team.",
tooltip: "Free-text entry disabled for security reasons.",
example: ["", "", ""],
},
builder_links: {
category: Category.Team,
title: "Builder link(s)",
tooltip: "Link(s) to webpage(s) explaining who built the building.",
example: ["", "", ""],
},
builder_source_type: {
@ -1098,31 +1140,19 @@ export const dataFields = { /* eslint-disable @typescript-eslint/camelcase */
category: Category.StreetContext,
title: "Does the building have a front garden?",
tooltip: "Is the front garden mainly green/planted?",
example: "",
items: [
"Yes",
"No"
]
example: true,
},
context_back_garden: {
category: Category.StreetContext,
title: "Does the building have a back garden?",
tooltip: "Is the back garden mainly green/planted?",
example: "",
items: [
"Yes",
"No"
]
example: true
},
context_flats_garden: {
category: Category.StreetContext,
title: "Is the building flats with a dedicated green space?",
title: "Are flats with a dedicated green space?",
tooltip: "If the building is a block of flats, does it have a dedicated garden area/green space?",
example: "",
items: [
"Yes",
"No"
]
example: true
},
context_garden_source_type: {
category: Category.StreetContext,
@ -1139,8 +1169,8 @@ export const dataFields = { /* eslint-disable @typescript-eslint/camelcase */
},
context_street_width: {
category: Category.Team,
title: "Street width (m)",
tooltip: "Width of the street in metres.",
title: "Average street width (m)",
tooltip: "Average width of the street in metres.",
example: 10
},
context_street_width_source_type: {
@ -1158,8 +1188,8 @@ export const dataFields = { /* eslint-disable @typescript-eslint/camelcase */
},
context_pavement_width: {
category: Category.Team,
title: "Pavement width (m)",
tooltip: "Width of the pavement in metres.",
title: "Average pavement width (m)",
tooltip: "Average width of the pavement in metres.",
example: 10
},
context_pavement_width_source_type: {
@ -1178,7 +1208,7 @@ export const dataFields = { /* eslint-disable @typescript-eslint/camelcase */
context_green_space_distance: {
category: Category.Team,
title: "Distance to nearest green space (m)",
tooltip: "Approximate distance from the front door of the building to the nearest public green space.",
tooltip: "Approximate distance from the front door of the building to the nearest public green space (in meters).",
example: 10
},
context_green_space_distance_source_type: {
@ -1197,7 +1227,7 @@ export const dataFields = { /* eslint-disable @typescript-eslint/camelcase */
context_tree_distance: {
category: Category.Team,
title: "Distance to nearest tree (m)",
tooltip: "Approximate distance from the front door of the building to the nearest tree.",
tooltip: "Approximate distance from the front door of the building to the nearest tree in meters.",
example: 10
},
context_tree_distance_source_type: {
@ -1234,7 +1264,7 @@ export const dataFields = { /* eslint-disable @typescript-eslint/camelcase */
},
age_cladding_date: {
category: Category.Age,
title: "Cladding date",
title: "Cladding date (best estimate)",
tooltip: "Width of the street in metres.",
example: 1970
},
@ -1253,7 +1283,7 @@ export const dataFields = { /* eslint-disable @typescript-eslint/camelcase */
},
age_extension_date: {
category: Category.Age,
title: "Date of significant extensions",
title: "Date of significant extensions (best estimate)",
tooltip: "Width of the street in metres.",
example: 1970
},
@ -1272,7 +1302,7 @@ export const dataFields = { /* eslint-disable @typescript-eslint/camelcase */
},
age_retrofit_date: {
category: Category.Age,
title: "Date of significant retrofits",
title: "Date of last significant retrofit (best estimate)",
tooltip: "Width of the street in metres.",
example: 1970
},
@ -1289,6 +1319,57 @@ export const dataFields = { /* eslint-disable @typescript-eslint/camelcase */
tooltip: "Source link(s) for street width data",
example: ["", "", ""],
},
age_historical_raster_map_links: {
category: Category.Age,
title: "Historical maps links",
tooltip: "Links to rasterised historical maps",
example: ["", "", ""],
},
age_historical_vectorised_footprint_links: {
category: Category.Age,
title: "Extracted vectorised historical footprints links",
tooltip: "Extracted vectorised historical footprints links",
example: ["", "", ""],
},
energy_solar: {
category: Category.EnergyPerformance,
title: "Does the building have solar panels?",
tooltip: "Are there any kinds of solar panels on the roof of the building?",
example: true
},
energy_solar_source_type: {
category: Category.EnergyPerformance,
title: "Source type",
tooltip: "Source type for street width data",
example: "",
items: commonSourceTypes
},
energy_solar_source_links: {
category: Category.EnergyPerformance,
title: "Source link(s)",
tooltip: "Source link(s) for street width data",
example: ["", "", ""],
},
energy_green_roof: {
category: Category.EnergyPerformance,
title: "Does the building have green walls/green roof?",
tooltip: "Are there any green walls, or a green roof, on the building?",
example: true
},
energy_green_roof_source_type: {
category: Category.EnergyPerformance,
title: "Source type",
tooltip: "Source type for street width data",
example: "",
items: commonSourceTypes
},
energy_green_roof_source_links: {
category: Category.EnergyPerformance,
title: "Source link(s)",
tooltip: "Source link(s) for street width data",
example: ["", "", ""],
},
};
export const allFieldsConfig = { ...dataFields, ...buildingUserFields };

View File

@ -57,7 +57,8 @@ function getCurrentMenuLinks(username: string): MenuLink[][] {
},
{
to: "https://github.com/colouring-cities/manual/wiki",
text: "Open Manual - Wiki",
text: "Colouring Cities Open Manual/Wiki",
disabled: false,
external: true
},
{
@ -65,12 +66,6 @@ function getCurrentMenuLinks(username: string): MenuLink[][] {
text: "Open code",
external: true
},
{
to: "https://github.com/colouring-cities/manual/wiki",
text: "Colouring Cities Open Manual/Wiki",
disabled: false,
external: true
},
{
to: "/showcase.html",
text: "Case Study Showcase",
@ -79,12 +74,17 @@ function getCurrentMenuLinks(username: string): MenuLink[][] {
],
[
{
to: "https://pages.colouring.london",
text: "About",
to: "https://github.com/colouring-cities/manual/wiki/A.-What-is-the-CCRP%3F",
text: "About the Colouring Cities Research Programme",
external: true
},
{
to: "https://pages.colouring.london/buildingcategories",
to: "https://github.com/colouring-cities/manual/wiki/A2.-How-to%3F-Guides",
text: "How to Use",
external: true
},
{
to: "https://github.com/colouring-cities/manual/wiki/I.--DATA",
text: "Data Categories",
external: true
},
@ -94,15 +94,10 @@ function getCurrentMenuLinks(username: string): MenuLink[][] {
external: true
},
{
to: "https://pages.colouring.london/data-ethics",
text: "Data Ethics",
to: "https://github.com/colouring-cities/manual/wiki/C.-Ethical-framework-and-ethics-policies",
text: "Ethical Framework",
external: true
},
{
to: "https://pages.colouring.london/colouring-cities",
text: "Colouring Cities Research Programme",
external: true
},
}
],
[
{
@ -110,32 +105,45 @@ function getCurrentMenuLinks(username: string): MenuLink[][] {
text: "Top Contributors"
},
{
to: "https://discuss.colouring.london",
to: config.githubURL+"/discussions",
text: "Discussion Forum",
external: true
},
{
to: "https://discuss.colouring.london/c/blog/9",
text: "Blog",
external: true
},
// {
// to: "https://discuss.colouring.london/c/blog/9",
// text: "Blog",
// external: true
// },
],
[
{
to: "/privacy-policy.html",
text: "Privacy Policy"
to: "https://github.com/colouring-cities/manual/wiki/C1.-Protocols,-codes-of-conduct-&-data-sharing-agreements#ccrp-contributor-privacy-statement",
text: "Privacy Policy",
external: true
},
{
to: "/contributor-agreement.html",
text: "Contributor Agreement"
to: "https://github.com/colouring-cities/manual/wiki/C1.-Protocols,-codes-of-conduct-&-data-sharing-agreements#ccrp-contributor--data-user-data-accuracy--ethical-use-agreement",
text: "Contributor Agreement",
external: true
},
{
to: "/code-of-conduct.html",
text: "Code of Conduct"
},
{
to: "/data-accuracy.html",
text: "Data Accuracy Agreement"
to: "https://github.com/colouring-cities/manual/wiki/C1.-Protocols,-codes-of-conduct-&-data-sharing-agreements#ccrp-contributor--data-user-data-accuracy--ethical-use-agreement",
text: "Data Accuracy and Use Agreement",
external: true
},
{
to: "https://github.com/colouring-cities/manual/wiki/C1.-Protocols,-codes-of-conduct-&-data-sharing-agreements#ccrp-equality-diversity-and-inclusion-policy",
text: "Equality, Diversity and Inclusion",
external: true
},
{
to: "https://github.com/colouring-cities/manual/wiki/C1.-Protocols,-codes-of-conduct-&-data-sharing-agreements#ccrp-protocols-for-international-academic-partners",
text: "CCRP Academic Partner Protocols",
external: true
},
{
to: "/ordnance-survey-uprn.html",
@ -183,7 +191,7 @@ const InternalNavLink: React.FC<{to: string; onClick: () => void}> = ({ to, onCl
);
const ExternalNavLink: React.FC<{to: string}> = ({ to, children }) => (
<a className="nav-link" href={to}>
<a className="nav-link" href={to} target="_blank">
{children}
</a>
);

View File

@ -4,6 +4,7 @@ COPY (SELECT
ref_osm_id,
revision_id,
location_name,
location_name_link,
location_number,
location_street,
location_line_two,
@ -13,6 +14,7 @@ COPY (SELECT
location_address_links,
location_latitude,
location_longitude,
location_alternative_footprint_links
current_landuse_group,
current_landuse_order,
building_attachment_form,

View File

@ -0,0 +1,15 @@
ALTER TABLE buildings DROP COLUMN IF EXISTS location_name_link;
ALTER TABLE buildings DROP COLUMN IF EXISTS location_alternative_footprint_links;
ALTER TABLE buildings DROP COLUMN IF EXISTS age_historical_raster_map_links;
ALTER TABLE buildings DROP COLUMN IF EXISTS age_historical_vectorised_footprint_links;
ALTER TABLE buildings DROP COLUMN IF EXISTS landowner_links;
ALTER TABLE buildings DROP COLUMN IF EXISTS designers_links;
ALTER TABLE buildings DROP COLUMN IF EXISTS builder_links;
ALTER TABLE buildings DROP COLUMN IF EXISTS developer_links;
ALTER TABLE buildings DROP COLUMN IF EXISTS energy_solar;
ALTER TABLE buildings DROP COLUMN IF EXISTS energy_solar_source_type;
ALTER TABLE buildings DROP COLUMN IF EXISTS energy_solar_source_links;
ALTER TABLE buildings DROP COLUMN IF EXISTS energy_green_roof;
ALTER TABLE buildings DROP COLUMN IF EXISTS energy_green_roof_source_type;
ALTER TABLE buildings DROP COLUMN IF EXISTS energy_green_roof_source_links;

View File

@ -0,0 +1,15 @@
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS location_name_link text;
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS location_alternative_footprint_links text[];
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS age_historical_raster_map_links text[];
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS age_historical_vectorised_footprint_links text[];
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS landowner_links text[];
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS designers_links text[];
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS builder_links text[];
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS developer_links text[];
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS energy_solar boolean;
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS energy_solar_source_type text;
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS energy_solar_source_links text[];
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS energy_green_roof boolean;
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS energy_green_roof_source_type text;
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS energy_green_roof_source_links text[];

View File

@ -0,0 +1,7 @@
ALTER TABLE buildings DROP COLUMN IF EXISTS context_front_garden;
ALTER TABLE buildings DROP COLUMN IF EXISTS context_back_garden;
ALTER TABLE buildings DROP COLUMN IF EXISTS context_flats_garden;
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS context_front_garden boolean;
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS context_back_garden boolean;
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS context_flats_garden boolean;