fix issue with number inputs not serializing correctly due to setting values as strings instead of numbers (#94)

consolidate number, string and checkbox value change functions

(cherry picked from commit 22c1590885db0534afabff74be7504ca9a0998b5)
This commit is contained in:
rjwats 2020-02-27 00:05:38 +00:00 committed by GitHub
parent a042633d8f
commit fb7053610f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 20 additions and 18 deletions

View File

@ -5,7 +5,6 @@ import { redirectingAuthorizedFetch } from '../authentication';
export interface RestControllerProps<D> extends WithSnackbarProps { export interface RestControllerProps<D> extends WithSnackbarProps {
handleValueChange: (name: keyof D) => (event: React.ChangeEvent<HTMLInputElement>) => void; handleValueChange: (name: keyof D) => (event: React.ChangeEvent<HTMLInputElement>) => void;
handleCheckboxChange: (name: keyof D) => (event: React.ChangeEvent<HTMLInputElement>, checked: boolean) => void;
handleSliderChange: (name: keyof D) => (event: React.ChangeEvent<{}>, value: number | number[]) => void; handleSliderChange: (name: keyof D) => (event: React.ChangeEvent<{}>, value: number | number[]) => void;
setData: (data: D) => void; setData: (data: D) => void;
@ -23,6 +22,17 @@ interface RestControllerState<D> {
errorMessage?: string; errorMessage?: string;
} }
const extractValue = (event: React.ChangeEvent<HTMLInputElement>) => {
switch (event.target.type) {
case "number":
return event.target.valueAsNumber;
case "checkbox":
return event.target.checked;
default:
return event.target.value
}
}
export function restController<D, P extends RestControllerProps<D>>(endpointUrl: string, RestController: React.ComponentType<P & RestControllerProps<D>>) { export function restController<D, P extends RestControllerProps<D>>(endpointUrl: string, RestController: React.ComponentType<P & RestControllerProps<D>>) {
return withSnackbar( return withSnackbar(
class extends React.Component<Omit<P, keyof RestControllerProps<D>> & WithSnackbarProps, RestControllerState<D>> { class extends React.Component<Omit<P, keyof RestControllerProps<D>> & WithSnackbarProps, RestControllerState<D>> {
@ -85,12 +95,7 @@ export function restController<D, P extends RestControllerProps<D>>(endpointUrl:
} }
handleValueChange = (name: keyof D) => (event: React.ChangeEvent<HTMLInputElement>) => { handleValueChange = (name: keyof D) => (event: React.ChangeEvent<HTMLInputElement>) => {
const data = { ...this.state.data!, [name]: event.target.value }; const data = { ...this.state.data!, [name]: extractValue(event) };
this.setState({ data });
}
handleCheckboxChange = (name: keyof D) => (event: React.ChangeEvent<HTMLInputElement>) => {
const data = { ...this.state.data!, [name]: event.target.checked };
this.setState({ data }); this.setState({ data });
} }
@ -102,7 +107,6 @@ export function restController<D, P extends RestControllerProps<D>>(endpointUrl:
render() { render() {
return <RestController return <RestController
handleValueChange={this.handleValueChange} handleValueChange={this.handleValueChange}
handleCheckboxChange={this.handleCheckboxChange}
handleSliderChange={this.handleSliderChange} handleSliderChange={this.handleSliderChange}
setData={this.setData} setData={this.setData}
saveData={this.saveData} saveData={this.saveData}

View File

@ -28,14 +28,14 @@ class NTPSettingsForm extends React.Component<NTPSettingsFormProps> {
} }
render() { render() {
const { data, handleValueChange, handleCheckboxChange, saveData, loadData } = this.props; const { data, handleValueChange, saveData, loadData } = this.props;
return ( return (
<ValidatorForm onSubmit={saveData}> <ValidatorForm onSubmit={saveData}>
<BlockFormControlLabel <BlockFormControlLabel
control={ control={
<Checkbox <Checkbox
checked={data.enabled} checked={data.enabled}
onChange={handleCheckboxChange('enabled')} onChange={handleValueChange('enabled')}
value="enabled" value="enabled"
/> />
} }

View File

@ -177,7 +177,6 @@ class ManageUsersForm extends React.Component<ManageUsersFormProps, ManageUsersF
onDoneEditing={this.doneEditingUser} onDoneEditing={this.doneEditingUser}
onCancelEditing={this.cancelEditingUser} onCancelEditing={this.cancelEditingUser}
handleValueChange={this.handleUserValueChange} handleValueChange={this.handleUserValueChange}
handleCheckboxChange={this.handleUserCheckboxChange}
uniqueUsername={this.uniqueUsername} uniqueUsername={this.uniqueUsername}
/> />
} }

View File

@ -12,7 +12,6 @@ interface UserFormProps {
user: User; user: User;
uniqueUsername: (value: any) => boolean; uniqueUsername: (value: any) => boolean;
handleValueChange: (name: keyof User) => (event: React.ChangeEvent<HTMLInputElement>) => void; handleValueChange: (name: keyof User) => (event: React.ChangeEvent<HTMLInputElement>) => void;
handleCheckboxChange: (name: keyof User) => (event: React.ChangeEvent<HTMLInputElement>, checked: boolean) => void;
onDoneEditing: () => void; onDoneEditing: () => void;
onCancelEditing: () => void; onCancelEditing: () => void;
} }
@ -30,7 +29,7 @@ class UserForm extends React.Component<UserFormProps> {
} }
render() { render() {
const { user, creating, handleValueChange, handleCheckboxChange, onDoneEditing, onCancelEditing } = this.props; const { user, creating, handleValueChange, onDoneEditing, onCancelEditing } = this.props;
return ( return (
<ValidatorForm onSubmit={onDoneEditing} ref={this.formRef}> <ValidatorForm onSubmit={onDoneEditing} ref={this.formRef}>
<Dialog onClose={onCancelEditing} aria-labelledby="user-form-dialog-title" open> <Dialog onClose={onCancelEditing} aria-labelledby="user-form-dialog-title" open>
@ -64,7 +63,7 @@ class UserForm extends React.Component<UserFormProps> {
<Checkbox <Checkbox
value="admin" value="admin"
checked={user.admin} checked={user.admin}
onChange={handleCheckboxChange('admin')} onChange={handleValueChange('admin')}
/> />
} }
label="Admin?" label="Admin?"

View File

@ -18,14 +18,14 @@ class OTASettingsForm extends React.Component<OTASettingsFormProps> {
} }
render() { render() {
const { data, handleValueChange, handleCheckboxChange, saveData, loadData } = this.props; const { data, handleValueChange, saveData, loadData } = this.props;
return ( return (
<ValidatorForm onSubmit={saveData}> <ValidatorForm onSubmit={saveData}>
<BlockFormControlLabel <BlockFormControlLabel
control={ control={
<Checkbox <Checkbox
checked={data.enabled} checked={data.enabled}
onChange={handleCheckboxChange("enabled")} onChange={handleValueChange("enabled")}
/> />
} }
label="Enable OTA Updates?" label="Enable OTA Updates?"

View File

@ -32,7 +32,7 @@ class WiFiSettingsForm extends React.Component<WiFiStatusFormProps> {
render() { render() {
const { selectedNetwork, deselectNetwork } = this.context; const { selectedNetwork, deselectNetwork } = this.context;
const { data, handleValueChange, handleCheckboxChange, saveData, loadData } = this.props; const { data, handleValueChange, saveData, loadData } = this.props;
return ( return (
<ValidatorForm onSubmit={saveData} ref="WiFiSettingsForm"> <ValidatorForm onSubmit={saveData} ref="WiFiSettingsForm">
{ {
@ -98,7 +98,7 @@ class WiFiSettingsForm extends React.Component<WiFiStatusFormProps> {
<Checkbox <Checkbox
value="static_ip_config" value="static_ip_config"
checked={data.static_ip_config} checked={data.static_ip_config}
onChange={handleCheckboxChange("static_ip_config")} onChange={handleValueChange("static_ip_config")}
/> />
} }
label="Static IP Config?" label="Static IP Config?"