UNPKG

ice-frontend-react-mobx

Version:
249 lines (214 loc) 9.13 kB
var debug = require('debug')('ice:Devices:Form'); // eslint-disable-line no-unused-vars import React from 'react'; import { inject, observer } from 'mobx-react'; import { Input, Dropdown, Dialog } from 'react-toolbox'; import Validators from '../../../common/helpers/Validators'; import Notify from '../../../common/helpers/Notify'; import FormWrapper from '../../common/FormWrapper/FormWrapper'; let styles = require('./DeviceForm.css'); const defaultState = { name: '', nameError: '', ip: '', ipError: '', port: '', portError: '', deviceInfo: '', deviceInfoError: '', feed: '', desc: '', phase: '', upstreamFailureSensor: '', breakerLimit: '' }; @inject('store') @observer export default class DeviceForm extends React.Component { constructor (props) { super(props); this.deviceStore = this.props.store.deviceStore; this.messageStore = this.props.store.messageStore; this.allFeeds = this.props.store.feedStore.all; this.wordStore = this.props.store.wordStore; this.state = defaultState; } componentWillReceiveProps (nextProps) { let newState = Object.assign({}, defaultState); if (nextProps.deviceId) { let device = this.deviceStore.getById(nextProps.deviceId); newState.device = device; newState.name = device.name; newState.ip = device.ip; newState.port = device.port; newState.deviceInfo = device.deviceInfo; newState.feed = device.feedId; newState.desc = device.description; newState.phase = (device.phase) ? device.phase : 'None'; newState.upstreamFailureSensor = device.upstreamFailureSensor; newState.breakerLimit = device.breakerLimit; } else if (nextProps.active) { newState.device = this.deviceStore.createDevice(); } this.setState(newState); } validate = (field) => { let error = ''; let value = this.state[field]; let combos; let ip = this.state.ip !== '' ? this.state.ip : false; let port = this.state.port !== '' ? this.state.port : false; let isDumb = false; try { isDumb = JSON.parse(this.state.deviceInfo).isDumb; } catch (error) { debug('No device info, using default of false', error); } if (ip && port) { combos = this.deviceStore.all.map((device) => (device.ip + ':' + device.port)); } switch (field) { case 'name': let names = this.deviceStore.all.map((device) => (device.name)); let originalName = (this.state.device) ? this.state.device.name : null; error = Validators.device.name(value, names, originalName); break; case 'ip': let originalIp = (this.state.device) ? this.state.device.ip : null; error = Validators.device.ip(value, port, combos, originalIp, isDumb); break; case 'port': let originalPort = (this.state.device) ? this.state.device.port : null; error = Validators.device.port(value, ip, combos, originalPort, isDumb); break; case 'deviceInfo': error = Validators.device.model(value); break; case 'breakerLimit': error = Validators.device.breakerLimit(value); break; } return error; } isValid = () => { var p = new Promise((resolve, reject) => { let newState = {}; ['name', 'ip', 'port', 'deviceInfo', 'breakerLimit'].forEach((field) => { newState[ field + 'Error' ] = this.validate(field); }); this.setState(newState, () => { if (this.state.nameError === '' && this.state.ipError === '' && this.state.portError === '' && this.state.deviceInfoError === '' && this.state.name !== '' && this.state.deviceInfo !== '') { resolve(); } else { reject(new Error('form not valid')); } }); }); return p; } handleChange = (field, value) => { this.setState({ [field]: value }, () => { if (field === 'deviceInfo') { this.setState({ [field + 'Error']: this.validate(field) }); } }); } handleBlur = (name) => { let error = this.validate(name); this.setState({ [name + 'Error']: error }); } save = () => { this.isValid().then(() => { let device = this.state.device || this.deviceStore.createDevice(); device.name = this.state.name; device.ip = this.state.ip; device.port = this.state.port; device.deviceInfo = this.state.deviceInfo; device.sensorStreamEnabled = device.model !== 'dumbRpdu'; device.feed = this.state.feed; device.description = this.state.desc; device.upstreamFailureSensor = this.state.upstreamFailureSensor; if (this.state.breakerLimit) { device.breakerLimit = parseInt(this.state.breakerLimit); } device.phase = (this.state.phase !== 'None') ? this.state.phase : null; device.save().then(() => { Notify.success('Device Saved'); }).catch((error) => { if (error.response && error.response.data && error.response.data.errorMessage) { Notify.error(error.response.data.errorMessage); } else { Notify.error('Error saving device'); } }); this.props.onSave(); }, () => { debug('Form is notvalid'); }); } cancel = () => { this.setState(defaultState); this.props.onCancel(); } render () { let availableDevices = this.props.store.catalogStore.all.map((device) => { return { label: device.name, value: JSON.stringify({ type: device.type, model: device.model, isDumb: device.isDumb }) }; }); let availableFeeds = this.props.store.feedStore.all.map((feed) => { return { label: feed.name, value: feed.id }; }); let availablePhases = [{value: 'NONE', name: 'None'}, {value: 'ONE', name: '1-2'}, {value: 'TWO', name: '2-3'}, {value: 'THREE', name: '3-1'}, {value: 'ALL PHASES', name: 'All'}].map((phase) => { return { label: phase.value, value: phase.name }; }); let iceBlocks = this.deviceStore.iceblocks.map((device) => { return { label: device.name, value: device.id }; }); let title = (this.props.deviceId) ? this.wordStore.translate('Edit Device') : this.wordStore.translate('Add Device'); let actions = [ { label: this.wordStore.translate('Cancel'), onClick: this.cancel }, { label: this.wordStore.translate('Save'), onClick: this.save } ]; return ( <Dialog title={title} actions={actions} active={this.props.active} onEscKeyDown={this.cancel}> <FormWrapper onSubmit={this.save}> <div className={styles.twoColumn}> <div className={styles.wideColumn}> <Input type='text' label='Name' value={this.state.name} error={this.state.nameError} onChange={this.handleChange.bind(this, 'name')} onBlur={this.handleBlur.bind(this, 'name')} /> </div> <div className={styles.narrowColumn}> <Input type='text' label='Breaker Limit' value={this.state.breakerLimit} error={this.state.breakerLimitError} onChange={this.handleChange.bind(this, 'breakerLimit')} onBlur={this.handleBlur.bind(this, 'breakerLimit')} /> </div> </div> <div className={styles.threeColumn}> <div className={styles.wideColumn}> <Dropdown label='Model' source={availableDevices} value={this.state.deviceInfo} error={this.state.deviceInfoError} onChange={this.handleChange.bind(this, 'deviceInfo')} /> </div> <div className={styles.narrowColumn}> <Dropdown label='Feed' source={availableFeeds} value={this.state.feed} onChange={this.handleChange.bind(this, 'feed')} /> </div> <div className={styles.narrowColumn}> <Dropdown label='Phase' source={availablePhases} value={this.state.phase} onChange={this.handleChange.bind(this, 'phase')} /> </div> </div> <div className={styles.twoColumn}> <div className={styles.wideColumn}> <Input type='text' label='IP' value={this.state.ip} error={this.state.ipError} onChange={this.handleChange.bind(this, 'ip')} onBlur={this.handleBlur.bind(this, 'ip')} /> </div> <div className={styles.narrowColumn}> <Input type='Number' label='Port' value={this.state.port} error={this.state.portError} onChange={this.handleChange.bind(this, 'port')} onBlur={this.handleBlur.bind(this, 'port')} /> </div> </div> <div className={styles.wideColumn}> <Dropdown auto={false} label='Upstream Sensor Failure' source={iceBlocks} value={this.state.upstreamFailureSensor} onChange={this.handleChange.bind(this, 'upstreamFailureSensor')} /> </div> <Input label='Description' value={this.state.desc} onChange={this.handleChange.bind(this, 'desc')} /> </FormWrapper> </Dialog> ); } } DeviceForm.wrappedComponent.propTypes = { deviceId: React.PropTypes.string, active: React.PropTypes.bool.isRequired, onCancel: React.PropTypes.func.isRequired, onSave: React.PropTypes.func.isRequired };