trc-client-core
Version:
The core of the TRC Client
164 lines (156 loc) • 6.97 kB
JSX
import React from 'react';
import _ from 'lodash';
import {History} from 'react-router';
import moment from 'moment';
import Reflux from 'reflux';
import StoreMixin from 'reflux-immutable/StoreMixin';
import {CLASS_SIZES_CSV} from 'trc-client-core/src/constants/Endpoints';
import Grid from 'trc-client-core/src/components/Grid';
import Col from 'trc-client-core/src/components/Col';
import Icon from 'trc-client-core/src/components/Icon';
// Stampy
import UrlStore from 'bd-stampy/utils/UrlStore';
import ColumnDataTable from 'trc-client-core/src/components/ColumnDataTable';
import Column from 'bd-peanut/components/Column.jsx';
import Color from 'trc-client-core/src/components/Color';
import PrintChartView from './PrintChartView';
// Components
import COLORS from 'trc-client-core/src/constants/Color';
import Loader from 'trc-client-core/src/components/Loader';
import ModalManager from 'trc-client-core/src/Modal/ModalManager';
import TechnicalReportStore from 'trc-client-core/src/report/TechnicalReportStore';
import ReportActions from 'trc-client-core/src/report/ReportActions';
import InformationModal from 'trc-client-core/src/components/InformationModal';
import RegionSelect from 'trc-client-core/src/components/RegionSelect';
import YearSelect from 'trc-client-core/src/components/YearSelect';
import YearTypeSelect from 'trc-client-core/src/components/YearTypeSelect';
import TechnicalTrainerSelect from 'trc-client-core/src/components/TechnicalTrainerSelect';
var defaultQuery = {
regionCode: 'ALL_REGIONS',
trainerName: 'ANY_TRAINER',
year: moment().year().toString(),
year_type: 'jp_fiscal'
};
var ClassSizesReport = React.createClass({
displayName: 'ClassSizesReport',
mixins: [
StoreMixin,
History,
Reflux.listenTo(TechnicalReportStore, 'onStoreChange')
],
getStoreState() {
return {
classSizes: TechnicalReportStore.get('classSizes').toJS(),
classSizesFetching: TechnicalReportStore.get('classSizesFetching'),
classSizesAccumulative: TechnicalReportStore.get('classSizesAccumulative').toJS(),
classSizesAccumulativeFetching: TechnicalReportStore.get('classSizesAccumulativeFetching')
};
},
componentWillMount() {
this.history.replaceState(null, '/report/class_sizes', _.assign({}, this.props.location.query, defaultQuery));
},
componentDidMount() {
this.getData();
},
getData() {
ReportActions.fetchClassSizes(UrlStore.getQueryParams());
ReportActions.fetchClassSizesAccumulative(UrlStore.getQueryParams());
},
onShowLegend: function () {
ModalManager.showModal(InformationModal, {
title: 'Class Sizes & Targets Report',
children: (
<div className="Typography">
<p>Class Sizes will be based on all offerings with the following 'SO Item Stream' title:</p>
<ul>
<li><code>Protech</code></li>
<li><code>Servicetech</code></li>
<li><code>Diagnostictech</code></li>
<li><code>Mastertech</code></li>
</ul>
<p>Targets are generated as per supplied and applied to the region.</p>
<ul>
<li>Each instructor must train 100 days (8 technicians per day) per annum, therefore the annual target is 800 per instructor.</li>
<li>Per month, each instructor must train 66.666 technicians, rounded up to 67.</li>
<li>So to calculate region targets, combine each individual instructor's target.</li>
<li>Each month receives the same weight (no quiet periods).</li>
</ul>
</div>
)
});
},
render: function () {
return <div>
<h1>Class Sizes & Targets <Icon name="circleinfo" onClick={this.onShowLegend}/></h1>
{this.renderQuery()}
{this.renderCharts()}
</div>;
},
renderQuery() {
var {year, year_type, regionCode, trainerName} = this.props.location.query;
return (
<div className="hide-print">
<Grid modifier="tight">
<Col width={2}>
<YearSelect name="year" value={year} onChange={this.getData} to={2013}/>
</Col>
<Col width={2}>
<YearTypeSelect name="yearType" value={year_type} onChange={this.getData} />
</Col>
<Col width={2}>
<RegionSelect value={regionCode} onChange={this.getData} />
</Col>
<Col width={4}>
<TechnicalTrainerSelect {...this.props.location.query} value={trainerName} onChange={this.getData} />
</Col>
<Col>
</Col>
</Grid>
</div>
);
},
renderCharts(){
if(!this.state.classSizes.chartMax || !this.state.classSizesAccumulative.chartMax) {
return <Loader></Loader>;
}
return <div>
<h2>Month to Date</h2>
{this.renderChart('classSizes')}
<h2>Accumulative</h2>
{this.renderChart('classSizesAccumulative')}
</div>;
},
renderChart(storeKey) {
var data = this.state[storeKey];
var legend = ['Complete', 'Enrolled'];
var legendTable = ['Benchmark', 'Complete', 'Enrolled', 'Gap'];
var fetchingClass = this.state[storeKey + 'Fetching'] ? 'is-fetching' : '';
var {location} = this.props;
return <div className="row3">
<div className={`Chart Chart-stacked ${fetchingClass}`}>
<Column
modifier="stacked"
data={data.classSizesBenchmark}
valueSuffix="hrs"
yAxisMax={data.chartMax}
colors={['#e6e6e6']}
yAxisLabel="Attendance"
/>
<Column
modifier="stacked"
type="stacked"
data={data.classSizes}
legend={legend}
yAxisMax={data.chartMax}
displayAxis={false}
colors={[COLORS.TOYOTA.HERO, Color(COLORS.TOYOTA.HERO).lighten(0.5).hexString()]}
/>
</div>
<ColumnDataTable headers={legendTable} data={data.classSizesTable}/>
<div className="row t-right">
<PrintChartView href={(location.pathname+location.search).replace(location.pathname, CLASS_SIZES_CSV)}/>
</div>
</div>;
}
});
module.exports = ClassSizesReport;