Add form change handler with autosave

This commit is contained in:
Maciej Ziarkowski 2021-03-18 21:18:58 +00:00
parent 4aa35b94dd
commit 1184ffe4dc
2 changed files with 47 additions and 39 deletions

View File

@ -6,7 +6,7 @@ import { apiPost } from '../apiHelpers';
import ErrorBox from '../components/error-box'; import ErrorBox from '../components/error-box';
import InfoBox from '../components/info-box'; import InfoBox from '../components/info-box';
import { compareObjects } from '../helpers'; import { compareObjects } from '../helpers';
import { Building, UserVerified } from '../models/building'; import { Building, BuildingAttributes, UserVerified } from '../models/building';
import { User } from '../models/user'; import { User } from '../models/user';
import ContainerHeader from './container-header'; import ContainerHeader from './container-header';
@ -72,6 +72,7 @@ const withCopyEdit: (wc: React.ComponentType<CategoryViewProps>) => DataContaine
this.handleSubmit = this.handleSubmit.bind(this); this.handleSubmit = this.handleSubmit.bind(this);
this.handleVerify = this.handleVerify.bind(this); this.handleVerify = this.handleVerify.bind(this);
this.handleSaveAdd = this.handleSaveAdd.bind(this); this.handleSaveAdd = this.handleSaveAdd.bind(this);
this.handleSaveChange = this.handleSaveChange.bind(this);
this.toggleCopying = this.toggleCopying.bind(this); this.toggleCopying = this.toggleCopying.bind(this);
this.toggleCopyAttribute = this.toggleCopyAttribute.bind(this); this.toggleCopyAttribute = this.toggleCopyAttribute.bind(this);
@ -190,14 +191,12 @@ const withCopyEdit: (wc: React.ComponentType<CategoryViewProps>) => DataContaine
} }
} }
async handleSubmit(event) { async doSubmit(edits: Partial<BuildingAttributes>) {
event.preventDefault();
this.setState({error: undefined}); this.setState({error: undefined});
try { try {
const data = await apiPost( const data = await apiPost(
`/api/buildings/${this.props.building.building_id}.json`, `/api/buildings/${this.props.building.building_id}.json`,
this.state.buildingEdits edits
); );
if (data.error) { if (data.error) {
@ -210,6 +209,44 @@ const withCopyEdit: (wc: React.ComponentType<CategoryViewProps>) => 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) { async handleVerify(slug: string, verify: boolean, x: number, y: number) {
const verifyPatch = {}; const verifyPatch = {};
if (verify) { if (verify) {
@ -242,40 +279,6 @@ const withCopyEdit: (wc: React.ComponentType<CategoryViewProps>) => 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() { render() {
const currentBuilding = this.getEditedBuilding(); const currentBuilding = this.getEditedBuilding();
@ -356,6 +359,7 @@ const withCopyEdit: (wc: React.ComponentType<CategoryViewProps>) => DataContaine
onLike={undefined} onLike={undefined}
onVerify={undefined} onVerify={undefined}
onSaveAdd={undefined} onSaveAdd={undefined}
onSaveChange={undefined}
user_verified={[]} user_verified={[]}
/> />
</Fragment> : </Fragment> :
@ -408,6 +412,7 @@ const withCopyEdit: (wc: React.ComponentType<CategoryViewProps>) => DataContaine
onLike={this.handleLike} onLike={this.handleLike}
onVerify={this.handleVerify} onVerify={this.handleVerify}
onSaveAdd={this.handleSaveAdd} onSaveAdd={this.handleSaveAdd}
onSaveChange={this.handleSaveChange}
user_verified={this.props.user_verified} user_verified={this.props.user_verified}
user={this.props.user} user={this.props.user}
/> />

View File

@ -21,6 +21,9 @@ interface CategoryViewProps {
/* Special handler for adding and immediately saving a new item of an array-like attribute */ /* Special handler for adding and immediately saving a new item of an array-like attribute */
onSaveAdd: (slug: string, newItem: any) => void; 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_verified: any;
user?: any; user?: any;
} }