From 1184ffe4dc5994455af4cdb23a50f18b1b5c98eb Mon Sep 17 00:00:00 2001 From: Maciej Ziarkowski Date: Thu, 18 Mar 2021 21:18:58 +0000 Subject: [PATCH] Add form change handler with autosave --- app/src/frontend/building/data-container.tsx | 83 ++++++++++--------- .../data-containers/category-view-props.ts | 3 + 2 files changed, 47 insertions(+), 39 deletions(-) diff --git a/app/src/frontend/building/data-container.tsx b/app/src/frontend/building/data-container.tsx index a74b5d79..e90a71a0 100644 --- a/app/src/frontend/building/data-container.tsx +++ b/app/src/frontend/building/data-container.tsx @@ -6,7 +6,7 @@ import { apiPost } from '../apiHelpers'; import ErrorBox from '../components/error-box'; import InfoBox from '../components/info-box'; import { compareObjects } from '../helpers'; -import { Building, UserVerified } from '../models/building'; +import { Building, BuildingAttributes, UserVerified } from '../models/building'; import { User } from '../models/user'; import ContainerHeader from './container-header'; @@ -72,6 +72,7 @@ const withCopyEdit: (wc: React.ComponentType) => DataContaine this.handleSubmit = this.handleSubmit.bind(this); this.handleVerify = this.handleVerify.bind(this); this.handleSaveAdd = this.handleSaveAdd.bind(this); + this.handleSaveChange = this.handleSaveChange.bind(this); this.toggleCopying = this.toggleCopying.bind(this); this.toggleCopyAttribute = this.toggleCopyAttribute.bind(this); @@ -190,14 +191,12 @@ const withCopyEdit: (wc: React.ComponentType) => DataContaine } } - async handleSubmit(event) { - event.preventDefault(); + async doSubmit(edits: Partial) { this.setState({error: undefined}); - try { const data = await apiPost( `/api/buildings/${this.props.building.building_id}.json`, - this.state.buildingEdits + edits ); if (data.error) { @@ -210,6 +209,44 @@ const withCopyEdit: (wc: React.ComponentType) => DataContaine } } + async handleSubmit(event) { + event.preventDefault(); + + this.doSubmit(this.state.buildingEdits); + } + + async handleSaveAdd(slug: string, newItem: any) { + if(this.props.building[slug] != undefined && !Array.isArray(this.props.building[slug])) { + this.setState({error: 'Unexpected error'}); + console.error(`Trying to add a new item to a field (${slug}) which is not an array`); + return; + } + + if(this.isEdited()) { + this.setState({error: 'Cannot save a new record when there are unsaved edits to existing records'}); + return; + } + + const edits = { + [slug]: [...(this.props.building[slug] ?? []), newItem] + }; + + this.doSubmit(edits); + } + + async handleSaveChange(slug: string, value: any) { + if(this.isEdited()) { + this.setState({ error: 'Cannot change this value when there are other unsaved edits. Save or discard the other edits first.'}); + return; + } + + const edits = { + [slug]: value + }; + + this.doSubmit(edits); + } + async handleVerify(slug: string, verify: boolean, x: number, y: number) { const verifyPatch = {}; if (verify) { @@ -242,40 +279,6 @@ const withCopyEdit: (wc: React.ComponentType) => DataContaine } } - async handleSaveAdd(slug: string, newItem: any) { - if(this.props.building[slug] != undefined && !Array.isArray(this.props.building[slug])) { - this.setState({error: 'Unexpected error'}); - console.error(`Trying to add a new item to a field (${slug}) which is not an array`); - return; - } - - if(this.isEdited()) { - this.setState({error: 'Cannot save a new record when there are unsaved edits to existing records'}); - return; - } - - const edits = { - [slug]: [...(this.props.building[slug] ?? []), newItem] - }; - - this.setState({error: undefined}); - - try { - const data = await apiPost( - `/api/buildings/${this.props.building.building_id}.json`, - edits - ); - - if (data.error) { - this.setState({error: data.error}); - } else { - this.props.onBuildingUpdate(this.props.building.building_id, data); - } - } catch(err) { - this.setState({error: err}); - } - } - render() { const currentBuilding = this.getEditedBuilding(); @@ -356,6 +359,7 @@ const withCopyEdit: (wc: React.ComponentType) => DataContaine onLike={undefined} onVerify={undefined} onSaveAdd={undefined} + onSaveChange={undefined} user_verified={[]} /> : @@ -408,6 +412,7 @@ const withCopyEdit: (wc: React.ComponentType) => DataContaine onLike={this.handleLike} onVerify={this.handleVerify} onSaveAdd={this.handleSaveAdd} + onSaveChange={this.handleSaveChange} user_verified={this.props.user_verified} user={this.props.user} /> diff --git a/app/src/frontend/building/data-containers/category-view-props.ts b/app/src/frontend/building/data-containers/category-view-props.ts index b1233cec..e03e2a1a 100644 --- a/app/src/frontend/building/data-containers/category-view-props.ts +++ b/app/src/frontend/building/data-containers/category-view-props.ts @@ -21,6 +21,9 @@ interface CategoryViewProps { /* Special handler for adding and immediately saving a new item of an array-like attribute */ onSaveAdd: (slug: string, newItem: any) => void; + /* Special handler for setting a value and immediately saving */ + onSaveChange: (slug: string, value: any) => void; + user_verified: any; user?: any; }