Source: components/userComponents/forms/AddParametersForm.js

import React from "react";
import {
  fetchMonitoredArea, updateMonitoredArea,
} from '../../restmodules/MonitoredAreaRestModule';
import { fetchDeviceList } from '../../restmodules/DeviceRestModule';
import {
  ValidateParameters
} from '../../validationModules/MonitoredAreaFormValidationModule';
import { Redirect } from 'react-router-dom';
import '../css/MonitoredAreaAnnotation.css';
import Tooltip from 'rc-tooltip';
import Slider from 'rc-slider';
import Handle from 'rc-slider/es/Handle';
import { updateMonitoredAreaParameters } from '../../restmodules/ParametersRestModule';
import { withNamespaces } from 'react-i18next';

/**
 * Form for changing parameters of a MonitoredArea.
 * @extends Component
 * @hideconstructor
 */
class AddParametersForm extends React.Component {

  /**
   * @constructs
   * @param props
   */
  constructor(props) {
    super(props);
    this.state = {
      isValid : {
        backgroundSubstractionHistory : false,
        detectorMinContourHeight : false,
        detectorMinContourWidth : false,
        counterPathSize : false,
        counterMaxDistance : false,
      },
      monitoredArea : {
        "id":"",
        "device":
          {
            "id":""
          },
        "deviceLatitude":"",
        "deviceLongitude":"",
        "name":"",
        "detectionParameters":
          {
            "id":"",
            "backgroundSubstractionHistory":"",
            "detectorMinContourWidth":"",
            "detectorMinContourHeight":"",
            "counterPathSize":"",
            "counterMaxDistance":""
          }
      },
      devices : [],
      redirectPath: false,
    };
    this.handleSubmitUpdate = this.handleSubmitUpdate.bind(this);
    this.handleParametersInputChange = this.handleParametersInputChange.bind(this);

    if (this.props.match.params.id) {
      for (let key in this.state.isValid) {
        if (this.state.isValid.hasOwnProperty(key)) {
          this.state.isValid[key] = true;
        }
      }
    }
  }

  redirectTo = (redirectPath) => {
    this.setState({
      redirectPath: redirectPath
    });
  };

  closeScreen = (event) => {
    event.preventDefault();
    this.redirectTo('/config/');
  };

  preview = (event) => {
    event.preventDefault();
    updateMonitoredAreaParameters(this.state.monitoredArea.id, this.state.monitoredArea.detectionParameters)
    .then(response => {
      this.redirectTo('/live/' + this.state.monitoredArea.device.id);
    });
  };

  /**
   *
   * @param event
   */
  handleSubmitUpdate(event) {
    event.preventDefault();
    updateMonitoredAreaParameters(this.state.monitoredArea.id, this.state.monitoredArea.detectionParameters)
    .then(response => {
      this.redirectTo('/config/');
    });
  }

  /**
   *
   * @param value
   * @param name
   */
  handleSliderChange = (value, name) => {
    let event = {
      target: {
        name: name,
        value: value
      }
    };

    this.handleParametersInputChange(event);
  };

  /**
   *
   * @param event
   */
  handleParametersInputChange(event) {
    const target = event.target;
    const value = target.value;
    const name = target.name;

    let data = this.state.monitoredArea;
    data.detectionParameters[name] = value;

    let isValid = this.state.isValid;
    let result;

    switch(name) {
      case "backgroundSubstractionHistory":
        result = ValidateParameters(value, 1, 1000);
        break;
      case "detectorMinContourHeight":
        result = ValidateParameters(value, 1,50);
        break;
      case "detectorMinContourWidth":
        result = ValidateParameters(value, 1,50);
        break;
      case "counterPathSize":
        result = ValidateParameters(value, 1,1000);
        break;
      case "counterMaxDistance":
        result = ValidateParameters(value, 1,100);
        break;
      default:
    }

    isValid[name] = result;

    this.setState({
      monitoredArea : data,
      isValid : isValid
    });
  }

  /**
   *
   */
  componentDidMount() {
    const monitoredAreaID = this.props.match.params.id;
    if (monitoredAreaID) {
      fetchMonitoredArea(monitoredAreaID)
      .then(data => this.setState({ monitoredArea: data }))
      .catch(error => this.setState({ monitoredArea: [{ name: error.toString() }] }));
    }
    fetchDeviceList().then(data => this.setState({ devices: data })).then()
    .catch(error => this.setState({ devices: [{ name: error.toString() }] }));
  }

  /**
   *
   * @returns {*}
   */
  render() {
    const { t } = this.props;
    if (this.state.redirectPath) {
      return <Redirect to={this.state.redirectPath}/>
    }

    let submitEnabled = true;
    const submitHandle = this.handleSubmitUpdate;

    for (let key in this.state.isValid) {
      if (this.state.isValid.hasOwnProperty(key) && !this.state.isValid[key]) {
        submitEnabled = false;
        break;
      }
    }

    const title = t("forms.editingParametersOf") + this.state.monitoredArea.name;

    const handle = (props) => {
      const { value, dragging, index, ...restProps } = props;
      return (
        <Tooltip
          prefixCls="rc-slider-tooltip"
          overlay={value}
          visible={dragging}
          placement="top"
          key={index}
        >
          <Handle value={value} {...restProps} />
        </Tooltip>
      );
    };

        return (
            <section className="content-header">

              <h1>
                {t("forms.setParametersOfMonitoredArea")}
                <small> {t("forms.setCameraParameters")}</small>
              </h1>

              <ol className="breadcrumb">
                <li><a href="/config"><i className="fa fa-gear"></i>{t("sidebar.adminConfiguration")}</a></li>
                <li><a href={"/config/parameters/" + this.props.match.params.id}>{t("forms.setParametersOfMonitoredArea")}</a></li>
              </ol>

              <br/>

              <div className="row">
                <div className=" col-lg-12">
                <div className="box">
                  <div className="box-header with-border">
                      <h3 className="box-title">{title}</h3>
                  </div>

                  <div className=" box-body">
                        <form role="form"
                              onSubmit={submitHandle}>

                        <div className="form-group">
                            <label>{t("forms.detectorMinContour")}</label>
                          <label className="control-label fa fa-info-circle info-icon"
                                data-toggle="tooltip"
                                title={t("forms.tooltip.detectorMinContour")}
                            />
                            <div className="row-xs-flex-center">
                                <div className="col-xs-3">
                                    <div
                                        className={this.state.isValid.detectorMinContourWidth ? "form-group" : "form-group has-error"}>
                                      <label>{t("forms.width")}</label>
                                      <label className="control-label fa fa-info-circle info-icon"
                                             data-toggle="tooltip"
                                             title={t("forms.tooltip.width")}/>
                                        <input
                                            type="number"
                                            className="form-control"
                                            name="detectorMinContourWidth"
                                            value={this.state.monitoredArea.detectionParameters.detectorMinContourWidth}
                                            onChange={this.handleParametersInputChange}
                                        />
                                    </div>
                                </div>

                                <div className="col-xs-offset-1 col-xs-6">
                                    <Slider
                                        min={1}
                                        max={50}
                                        step={1}
                                        onChange={(event, name) => this.handleSliderChange(event, "detectorMinContourWidth")}
                                        value={this.state.monitoredArea.detectionParameters.detectorMinContourWidth ? this.state.monitoredArea.detectionParameters.detectorMinContourWidth : 1}
                                        handle={handle}
                                    />
                                </div>
                            </div>

                            <div className="row-xs-flex-center">
                                <div className="col-xs-3">
                                    <div
                                        className={this.state.isValid.detectorMinContourHeight ? "form-group" : "form-group has-error"}>
                                        <label>{t("forms.height")}</label>
                                      <label className="control-label fa fa-info-circle info-icon"
                                             data-toggle="tooltip"
                                             title={t("forms.tooltip.height")}/>
                                        <input
                                            type="number"
                                            className="form-control"
                                            name="detectorMinContourHeight"
                                            value={this.state.monitoredArea.detectionParameters.detectorMinContourHeight}
                                            onChange={this.handleParametersInputChange}
                                        />
                                    </div>
                                </div>

                                <div className="col-xs-offset-1 col-xs-6">
                                    <Slider
                                        min={1}
                                        max={50}
                                        max={50}
                                        step={1}
                                        onChange={(event, name) => this.handleSliderChange(event, "detectorMinContourHeight")}
                                        value={this.state.monitoredArea.detectionParameters.detectorMinContourHeight ? this.state.monitoredArea.detectionParameters.detectorMinContourHeight : 1}
                                        handle={handle}
                                    />
                                </div>
                            </div>
                        </div>

                        <div className="pull-left">
                            <button className="btn btn-primary"
                                    onClick={(e) => this.preview(e)}
                            >{t("forms.previewOnLivestream")}
                            </button>
                        </div>

                        <div className="pull-right">
                            <button className="btn btn-outline-primary"
                                    onClick={(e) => this.closeScreen(e)}
                            >{t("forms.cancel")}
                            </button>
                            <button type="submit"
                                    className="btn btn-primary"
                                    disabled={!submitEnabled}
                            >{t("forms.update")}
                            </button>
                        </div>

                    </form>
                </div>
                </div>
                </div>
            </div>
            </section>
        )
    }
}

export default withNamespaces()(AddParametersForm);