From 3a35f5dab58fe34411fb3d34d701d18440554cc8 Mon Sep 17 00:00:00 2001 From: Maciej Ziarkowski Date: Tue, 15 Oct 2019 14:37:23 +0100 Subject: [PATCH] Type, simplify, fix data containers This contains a couple fixes for minor bugs that were discovered after adding static types to the category data editing code. The other changes are mostly refactoring and styling --- app/src/frontend/building/building-view.tsx | 13 +- .../frontend/building/container-header.tsx | 12 +- app/src/frontend/building/data-container.tsx | 125 ++++++++++-------- app/src/frontend/building/sidebar.css | 9 +- app/src/frontend/map-app.tsx | 4 +- app/src/frontend/models/building.ts | 8 ++ app/src/frontend/models/user.ts | 8 ++ 7 files changed, 115 insertions(+), 64 deletions(-) create mode 100644 app/src/frontend/models/building.ts create mode 100644 app/src/frontend/models/user.ts diff --git a/app/src/frontend/building/building-view.tsx b/app/src/frontend/building/building-view.tsx index 0b7a97a2..753973b8 100644 --- a/app/src/frontend/building/building-view.tsx +++ b/app/src/frontend/building/building-view.tsx @@ -14,13 +14,24 @@ import StreetscapeContainer from './data-containers/streetscape'; import CommunityContainer from './data-containers/community'; import PlanningContainer from './data-containers/planning'; import LikeContainer from './data-containers/like'; +import { Building } from '../models/building'; + + +interface BuildingViewProps { + cat: string; + mode: 'view' | 'edit' | 'multi-edit'; + building: Building; + building_like: boolean; + user: any; + selectBuilding: (building:any) => void +} /** * Top-level container for building view/edit form * * @param props */ -const BuildingView = (props) => { +const BuildingView: React.FunctionComponent = (props) => { switch (props.cat) { case 'location': return = (props) => ( +const ContainerHeader: React.FunctionComponent = (props) => (
diff --git a/app/src/frontend/building/data-container.tsx b/app/src/frontend/building/data-container.tsx index 1547f9fc..66bcb098 100644 --- a/app/src/frontend/building/data-container.tsx +++ b/app/src/frontend/building/data-container.tsx @@ -5,6 +5,28 @@ import { Redirect } from 'react-router-dom'; import ContainerHeader from './container-header'; import ErrorBox from '../components/error-box'; import InfoBox from '../components/info-box'; +import { Building } from '../models/building'; +import { User } from '../models/user'; + +interface DataContainerProps { + title: string; + cat: string; + intro: string; + help: string; + inactive?: boolean; + + user: User; + mode: 'view' | 'edit' | 'multi-edit'; + building: Building; + building_like: boolean; +} + +interface DataContainerState { + error: string; + copying: boolean; + keys_to_copy: object; + building: Building +} /** * Shared functionality for view/edit forms @@ -15,14 +37,15 @@ import InfoBox from '../components/info-box'; * @param WrappedComponent */ const withCopyEdit = (WrappedComponent) => { - return class extends React.Component { // TODO: add proper types + return class DataContainer extends React.Component { // TODO: add proper types + static displayName = 'DataContainer'; + static propTypes = { // TODO: generate propTypes from TS title: PropTypes.string, slug: PropTypes.string, intro: PropTypes.string, help: PropTypes.string, inactive: PropTypes.bool, - building_id: PropTypes.number, children: PropTypes.node }; @@ -30,8 +53,7 @@ const withCopyEdit = (WrappedComponent) => { super(props); this.state = { - error: this.props.error || undefined, - like: this.props.like || undefined, + error: undefined, copying: false, keys_to_copy: {}, building: this.props.building @@ -62,7 +84,7 @@ const withCopyEdit = (WrappedComponent) => { * @param {string} key */ toggleCopyAttribute(key: string) { - const keys = this.state.keys_to_copy; + const keys = {...this.state.keys_to_copy}; if(this.state.keys_to_copy[key]){ delete keys[key]; } else { @@ -181,7 +203,7 @@ const withCopyEdit = (WrappedComponent) => { } render() { - if (this.state.mode === 'edit' && !this.props.user){ + if (this.props.mode === 'edit' && !this.props.user){ return } @@ -198,60 +220,17 @@ const withCopyEdit = (WrappedComponent) => { } return (
+
{ - this.props.building != undefined ? -
- { - (this.props.inactive) ? - - : null - } - { - (this.props.mode === 'edit' && !this.props.inactive) ? - - - { - this.props.slug === 'like' ? // special-case for likes - null : -
- -
- } -
- : null - } - - - : -
- { - (this.props.inactive)? - + this.props.inactive ? + @@ -265,12 +244,44 @@ const withCopyEdit = (WrappedComponent) => { onLike={this.handleLike} onUpdate={this.handleUpdate} /> - - : + : + this.props.building != undefined ? + + { + (this.props.mode === 'edit' && !this.props.inactive) ? + + + { + this.props.cat === 'like' ? // special-case for likes + null : +
+ +
+ } +
+ : null + } + + : - } - } +
); } diff --git a/app/src/frontend/building/sidebar.css b/app/src/frontend/building/sidebar.css index 53caf48e..7ce6542c 100644 --- a/app/src/frontend/building/sidebar.css +++ b/app/src/frontend/building/sidebar.css @@ -139,6 +139,11 @@ /** * Data list sections */ + + .section-body { + margin-top: 0.75em; + padding: 0 0.75em; + } .data-section .h3 { margin: 0; } @@ -162,9 +167,7 @@ padding-left: 0.75rem; padding-right: 0.75rem; } -.data-section form { - padding: 0 0.75rem; -} + .data-list a { color: #555; } diff --git a/app/src/frontend/map-app.tsx b/app/src/frontend/map-app.tsx index 5191f3fe..4dcd2b76 100644 --- a/app/src/frontend/map-app.tsx +++ b/app/src/frontend/map-app.tsx @@ -199,7 +199,7 @@ class MapApp extends React.Component { } render() { - const mode = this.props.match.params.mode || 'basic'; + const mode = this.props.match.params.mode; let category = this.state.category || 'age'; @@ -240,7 +240,7 @@ class MapApp extends React.Component {