ice-frontend-react-mobx
Version:
ICE Frontend REACT+MobX
231 lines (209 loc) • 7.46 kB
JavaScript
var debug = require('debug')('ice:ZoneCard: '); // eslint-disable-line no-unused-vars
import { inject, observer } from 'mobx-react';
import React from 'react';
import { Avatar, Button, Card, CardText, CardTitle, IconButton, Tooltip } from 'react-toolbox';
import ValueWrapper from '../../common/ValueWrapper/ValueWrapper';
import PhaseData from '../../common/PhaseData/PhaseData';
import PhaseBalance from '../../charts/PhaseBalance/PhaseBalance';
import CapacityReport from '../../Reports/Capacity/Capacity';
import {CollapsingPanel} from '../../../components/Accordion';
import ClassNames from 'classnames/bind';
let styles = require('./ZoneCard.css');
var css = ClassNames.bind(styles);
const TooltipButton = Tooltip(Button);
const thresholdWarning = 0.8;
('store')
export default class ZoneCard extends React.Component {
constructor (props) {
super(props);
this.store = this.props.store;
this.wordStore = this.props.store.wordStore;
this.zone = this.props.zone;
this.state = {
active: false,
displayData: 'zoneData'
};
}
handleToggle = () => {
this.setState({active: !this.state.active});
};
handlePrint = () => {
window.print();
}
thresholdCalc = (input, limit, metrics) => {
if (!metrics) {
return 'offline';
} else if (limit - input <= 0) {
return 'critical';
} else if ((limit * thresholdWarning) - input <= 0) {
return 'warning';
} else {
return 'normal';
}
};
renderZoneIcon () {
if (this.zone.metrics.phasePowerIn.length === 3) {
let metrics = this.zone.metrics;
let [phase1, phase2, phase3] = metrics.phasePowerIn.map((phase) => (phase.instantaneousW));
return <div className={styles.phaseBalanceWrapper}><PhaseBalance phase1={phase1} phase2={phase2} phase3={phase3} /></div>;
} else {
return <Avatar icon='flash_on' className={styles.rowPowerIcon}/>;
}
}
renderZoneData () {
let metrics = this.zone.metrics;
let input = metrics.instantaneousInputPowerW / 1000;
let allocated = this.zone.allocatedPower / 1000;
let maxUtilPercentage = Math.floor(metrics.maxUtilizationProp * 100);
let peak = metrics.maxInputPowerW / 1000;
let soc = metrics.averageSocProp * 100;
return (
<div className={styles.limits}>
<div className={styles.iconWrapper}>
{this.renderZoneIcon()}
</div>
<div className={styles.row}>
<div className={styles.rowSection}>
<ValueWrapper
value={input}
label={this.wordStore.translate('input')}
size='title'
suffix='kW'
labelFirst={false} />
<ValueWrapper
value={peak}
label={this.wordStore.translate('peak')}
size='title'
suffix='kW'
labelFirst={false} />
<ValueWrapper
value={allocated}
label={this.wordStore.translate('allocated')}
size='title'
suffix='kW'
labelFirst={false} />
</div>
<div className={styles.rowSection}>
<ValueWrapper
value={maxUtilPercentage}
label={this.wordStore.translate('max utilization')}
formatNumber={false}
size='title'
suffix='%'
labelFirst={false} />
<ValueWrapper
value={soc}
suffix='%'
label={this.wordStore.translate('avg SOC')}
size='title'
labelFirst={false} />
</div>
</div>
</div>
);
}
renderRacks () {
let rackIndicators = this.zone.racks.map((rack, index) => {
var allocated = rack.allocatedPower;
var input = rack.metrics.instantaneousInputPowerW;
var metrics = rack.metrics;
let rackStyles = () => {
return css('rackIndicator', this.thresholdCalc(input, allocated, metrics));
};
return (
<TooltipButton
label={rack.redundancy}
raised
tooltip={rack.name}
tooltipDelay={500}
className={rackStyles()}
key={'rack' + index}
/>
);
});
return rackIndicators;
}
renderPhaseData () {
if (this.zone.metrics.phasePowerIn.length === 3) {
return (
<div className={styles.collapseWrapper}>
<CollapsingPanel>
<div className={styles.phaseData}>
{
this.zone.metrics.phasePowerIn.map((phase) => {
let input = phase.instantaneousW / 1000;
let peak = phase.maxW / 1000;
let limit = phase.breakerLimitW / 1000;
return (
<PhaseData phase={phase.phase} input={input} peak={peak} limit={limit} key={this.zone.id + phase.phase}>
<ValueWrapper value={input} suffix='kW' label='input' size='sm' labelFirst={false} />
<ValueWrapper value={peak} suffix='kW' label='peak' size='sm' labelFirst={false} />
<ValueWrapper value={limit} suffix='kW' label='limit' size='sm' labelFirst={false} />
</PhaseData>
);
})
}
</div>
</CollapsingPanel>
</div>
);
}
}
getSensorData = (id) => {
this.store.history.push('/reports/capacity/' + id);
};
render () {
let name = this.zone.name || 'N/A';
let rackCount = this.zone.rackIds.length || 'N/A';
let actions = [
{ label: 'Cancel', onClick: this.handleToggle },
{ label: 'Print', onClick: this.handlePrint }
];
var allocated = this.zone.allocatedPower;
var input = this.zone.metrics.instantaneousInputPowerW;
var metrics = this.zone.metrics;
let rowThreshold = () => {
return css('thresholdIndicator', this.thresholdCalc(input, allocated, metrics));
};
let statusIcon = () => {
if (this.thresholdCalc(input, allocated, metrics) === 'warning' || this.thresholdCalc(input, allocated, metrics) === 'normal') {
return 'check';
} else {
return 'priority_high';
}
};
return (
<Card raised key={this.zone.id} className={styles.zoneCard}>
<div data-qa-tag='zone-card' data-qa-id={this.zone.id}>
<div className={styles.titleWrapper}>
<Avatar icon={statusIcon()} className={rowThreshold()}/>
<CardTitle
title={name}
subtitle={ rackCount + ' racks'}
className={styles.cardTitle}>
</CardTitle>
</div>
<div className={styles.deviceToggle}>
<IconButton icon='info' onClick={this.getSensorData.bind(this, this.zone.id)}/>
</div>
<CardText>
<div>
<div className={styles.zoneData}>{this.renderZoneData()}</div>
{this.renderPhaseData()}
</div>
</CardText>
<CardText>
<h4>Racks:</h4>
<div className={styles.rackIndicatorBlock}>{this.renderRacks()}</div>
</CardText>
</div>
<CapacityReport
zone={this.zone}
actions={actions}
active={this.state.active}
onEscKeyDown={this.handleToggle}
onOverlayClick={this.handleToggle}/>
</Card>
);
}
}