<commit_before>import React, { PropTypes } from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import * as actions from '../actions/actions';
import FlatButton from 'material-ui/FlatButton';
import Paper from 'material-ui/Paper';
import Formsy from 'formsy-react';
import { FormsyText } from 'formsy-material-ui/lib';
import styles from '../assets/formStyles';
import { browserHistory } from 'react-router';
import CircularProgress from 'material-ui/CircularProgress';
import $ from 'jquery';
// import hardware from '../../config.js';

export class AddDevicePage extends React.Component {

  constructor(props) {
    super(props);

    this.errorMessages = {
      deviceIdError: 'Please provide a valid device ID',
    };

    this.state = {
      error: '',
      canSubmit: false,
      spinner: false,
    };
  }

  /**
    Called by onBlur and onChange of form to determine if submit button
    should be enabled or not
  */
  onTextChange(event) {
    if (event.target.value.length > 0) {
      this.enableButton();
    } else {
      this.disableButton();
    }
  }

  /**
    Called on after submit form to check hardware
  */
  pingDevice(device) {
    const deviceState = { isActive: true };
    /* homes id does not matter in this API call, not used */
    const apiPath = '/api/v1/homes/1/devices/ping/'.concat(device.deviceId);

    this.setState({ spinner: true });

    $.post(apiPath, deviceState, (req) => {
      const configuredDevice = {
        configured: true,
        id: device.deviceId,
        isActive: true,
      };

      if (!req.success === true) {
        this.setState({
          error: 'ADD_DEVICE',
          details: req.message,
        });
      } else {
        this.props.actions.addDevice(configuredDevice);
        // send user to setupDevice page if successful response
        browserHistory.push('/setup-device');
      }
    })
    .fail(() => {
      // set local state to display error
      this.setState({
        error: 'ADD_DEVICE',
        details: 'Failed to connect to device, try again.',
      });
    })
    .always(() => {
      this.setState({ spinner: false });
    });
  }

  /**
    Called by onTextChange to enable submit button
  */
  enableButton() {
    this.setState({ canSubmit: true });
  }

  /**
    Called by onTextChange to disable submit button
  */
  disableButton() {
    this.setState({ canSubmit: false });
  }

  render() {
    let errorMsg = '';
    let spinner = this.state.spinner ?
      <div className="loading"><CircularProgress size={2} /></div> : '';

    if (this.state.error === 'ADD_DEVICE') {
      errorMsg = <div style={styles.error}>{this.state.details}</div>;
    }

    return (
      <div>
        <div style={styles.center}>
          <h2>Add Device</h2>
          {errorMsg}
          {spinner}
          <div>
            <p>Your device should be OFF before starting this process.</p>
            <p>Enter a device ID to begin setting up a new device.</p>
          </div>
        </div>

        <Paper style={styles.paperStyle}>
          <Formsy.Form
            onValid={() => this.enableButton()}
            onInvalid={() => this.disableButton()}
            onValidSubmit={(data) => { this.pingDevice(data); this.disableButton(); }}
            onInvalidSubmit={() => this.notifyFormError()}
            autoComplete="off"
          >
            <FormsyText
              name="deviceId"
              validations="isExisty"
              validationError={this.errorMessages.deviceIdError}
              required
              style={styles.fieldStyles}
              floatingLabelText="Enter Device ID"
              onChange={(event) => this.onTextChange(event)}
              onBlur={(event) => this.onTextChange(event)}
            />
            <div style={styles.center}>
              <FlatButton
                style={styles.submitStyle}
                type="submit"
                label="Find a Device"
                disabled={!this.state.canSubmit}
              />
            </div>
          </Formsy.Form>
        </Paper>
      </div><commit_msg>(fix) update form error validation<commit_after>import React, { PropTypes } from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import * as actions from '../actions/actions';
import FlatButton from 'material-ui/FlatButton';
import Paper from 'material-ui/Paper';
import Formsy from 'formsy-react';
import { FormsyText } from 'formsy-material-ui/lib';
import styles from '../assets/formStyles';
import { browserHistory } from 'react-router';
import CircularProgress from 'material-ui/CircularProgress';
import { FormMessageDialogue } from '../components/FormMessageDialogue';
import $ from 'jquery';

export class AddDevicePage extends React.Component {

  constructor(props) {
    super(props);

    this.errorMessages = {
      deviceIdError: 'Please provide a valid device ID',
    };

    this.state = {
      error: '',
      canSubmit: true,
      spinner: false,
    };
  }

  openErrorMessage() {
    this.messageDialogue.handleOpen();
  }

  /**
    Called on after submit form to check hardware
  */
  pingDevice(device) {
    const deviceState = { isActive: true };
    /* homes id does not matter in this API call, not used */
    const apiPath = '/api/v1/homes/1/devices/ping/'.concat(device.deviceId);

    this.setState({ spinner: true });

    $.post(apiPath, deviceState, (req) => {
      const configuredDevice = {
        configured: true,
        id: device.deviceId,
        isActive: true,
      };

      if (!req.success === true) {
        this.openErrorMessage();
        this.setState({
          error: 'Unable to add the device',
          details: req.message,
        });
      } else {
        this.props.actions.addDevice(configuredDevice);
        // send user to setupDevice page if successful response
        browserHistory.push('/setup-device');
      }
    })
    .fail(() => {
      // set local state to display error
      this.setState({
        error: 'Unable to add the device',
        details: 'Failed to connect to device, please try again.',
      });
    })
    .always(() => {
      this.setState({ spinner: false });
    });
  }

  render() {
    let spinner = this.state.spinner ?
      <div className="loading"><CircularProgress size={2} /></div> : '';

    return (
      <div>
        <div style={styles.center}>
          <h2>Add Device</h2>
          {spinner}
          <div>
            <p>Your device should be OFF before starting this process.</p>
            <p>Enter a device ID to begin setting up a new device.</p>
          </div>
        </div>

        <Paper style={styles.paperStyle}>
          <Formsy.Form
            onValid={() => this.enableButton()}
            onValidSubmit={(data) => { this.pingDevice(data); this.disableButton(); }}
            onInvalidSubmit={() => this.notifyFormError()}
            autoComplete="off"
          >
            <FormsyText
              name="deviceId"
              validations="isExisty"
              validationError={this.errorMessages.deviceIdError}
              required
              style={styles.fieldStyles}
              floatingLabelText="Enter Device ID"
            />
            <div style={styles.center}>
              <FlatButton
                style={styles.submitStyle}
                type="submit"
                label="Find a Device"
                disabled={!this.state.canSubmit}
              />
            </div>
          </Formsy.Form>
          <FormMessageDialogue
            ref={(node) => { this.messageDialogue = node; }}
            title={this.state.error}
            failure
          >
            <p>{this.state.details}</p>
          </FormMessageDialogue>
        </Paper>
      </div>
{'fraction_non_alphanumeric': 0.13145780051150896, 'fraction_numerical': 0.0014066496163682865, 'mean_word_length': 2.057466770914777, 'pattern_counts': {'":': 0, '<': 55, '<?xml version=': 0, '>': 72, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '948770', 'n_tokens_mistral': 2182, 'n_tokens_neox': 2166, 'n_words': 538}