var React = require('react'); var ReactDOM = require('react-dom'); var ReactBootstrap = require('react-bootstrap'); var Col = ReactBootstrap.Col; var Form = ReactBootstrap.Form; var FormGroup = ReactBootstrap.FormGroup; var FormControl = ReactBootstrap.FormControl; var ControlLabel = ReactBootstrap.ControlLabel; var Button = ReactBootstrap.Button; var ButtonGroup = ReactBootstrap.ButtonGroup; var ButtonToolbar = ReactBootstrap.ButtonToolbar; var Glyphicon = ReactBootstrap.Glyphicon; var Panel = ReactBootstrap.Panel; var Modal = ReactBootstrap.Modal; var ProgressBar = ReactBootstrap.ProgressBar; var Combobox = require('react-widgets').Combobox; var CodeMirror = require('react-codemirror'); require('codemirror/mode/lua/lua'); var StackedBarChart = require('../components/StackedBarChart'); var PieChart = require('../components/PieChart'); var models = require('../models') var Report = models.Report; var Tabulation = models.Tabulation; class AddEditReportModal extends React.Component { getInitialState(props) { var s = { reportid: -1, name: "", lua: "" }; if (props && props.editReport != null) { s.reportid = props.editReport.ReportId; s.name = props.editReport.Name; s.lua = props.editReport.Lua; } return s; } constructor() { super(); this.state = this.getInitialState(); this.onCancel = this.handleCancel.bind(this); this.onNameChange = this.handleNameChange.bind(this); this.onLuaChange = this.handleLuaChange.bind(this); this.onSubmit = this.handleSubmit.bind(this); } componentWillReceiveProps(nextProps) { if (nextProps.show && !this.props.show) { this.setState(this.getInitialState(nextProps)); } } handleCancel() { if (this.props.onCancel != null) this.props.onCancel(); } handleNameChange() { this.setState({ name: ReactDOM.findDOMNode(this.refs.name).value, }); } handleLuaChange(lua) { this.setState({ lua: lua }); } handleSubmit() { var r = new Report(); if (this.props.editReport != null) r.ReportId = this.state.reportid; r.Name = this.state.name; r.Lua = this.state.lua; if (this.props.onSubmit != null) this.props.onSubmit(r); } render() { var headerText = (this.props.editReport != null) ? "Edit" : "Create New"; var buttonText = (this.props.editReport != null) ? "Save Changes" : "Create Report"; var codeMirrorOptions = { lineNumbers: true, mode: 'lua', }; return ( <Modal show={this.props.show} onHide={this.onCancel} bsSize="large"> <Modal.Header closeButton> <Modal.Title>{headerText} Report</Modal.Title> </Modal.Header> <Modal.Body> <Form horizontal onSubmit={this.onSubmit}> <FormGroup> <Col componentClass={ControlLabel} xs={3}>Name</Col> <Col xs={9}> <FormControl type="text" value={this.state.name} onChange={this.onNameChange} ref="name"/> </Col> </FormGroup> <FormGroup> <Col componentClass={ControlLabel} xs={3}>Lua Code</Col> <Col xs={9}> <CodeMirror value={this.state.lua} onChange={this.onLuaChange} options={codeMirrorOptions} /> </Col> </FormGroup> </Form> </Modal.Body> <Modal.Footer> <ButtonGroup className="pull-right"> <Button onClick={this.onCancel} bsStyle="warning">Cancel</Button> <Button onClick={this.onSubmit} bsStyle="success">{buttonText}</Button> </ButtonGroup> </Modal.Footer> </Modal> ); } } class ReportsTab extends React.Component { constructor() { super(); this.state = { initialized: false, creatingNewReport: false, editingReport: false } this.onSelectSeries = this.handleSelectSeries.bind(this); this.onSelectReport = this.handleSelectReport.bind(this); this.onNewReport = this.handleNewReport.bind(this); this.onEditReport = this.handleEditReport.bind(this); this.onDeleteReport = this.handleDeleteReport.bind(this); this.onCreationCancel = this.handleCreationCancel.bind(this); this.onCreationSubmit = this.handleCreationSubmit.bind(this); this.onEditingCancel = this.handleEditingCancel.bind(this); this.onEditingSubmit = this.handleEditingSubmit.bind(this); } componentWillMount() { this.props.onFetchAllReports(); } componentWillReceiveProps(nextProps) { var selected = nextProps.reports.selected; if (!this.state.initialized) { if (selected == -1 && nextProps.reports.list.length > 0) { nextProps.onSelectReport(nextProps.reports.list[0]); nextProps.onTabulateReport(nextProps.reports.list[0]); this.setState({initialized: true}); } } } handleSelectSeries(series) { if (series == Tabulation.topLevelSeriesName()) return; var seriesTraversal = this.props.reports.seriesTraversal.slice(); seriesTraversal.push(series); this.props.onSelectSeries(seriesTraversal); } handleSelectReport(report) { this.props.onSelectReport(report); if (!this.props.reports.tabulations.hasOwnProperty(report.ReportId)) this.props.onTabulateReport(report); } handleNewReport() { this.setState({creatingNewReport: true}); } handleEditReport() { this.setState({editingReport: true}); } handleDeleteReport() { this.props.onDeleteReport(this.props.reports.map[this.props.reports.selected]); } handleCreationCancel() { this.setState({creatingNewReport: false}); } handleCreationSubmit(report) { this.setState({creatingNewReport: false}); this.props.onCreateReport(report); } handleEditingCancel() { this.setState({editingReport: false}); } handleEditingSubmit(report) { this.setState({editingReport: false}); this.props.onUpdateReport(report); } render() { var selectedTabulation = this.props.reports.selectedTabulation; var reportPanel = []; if (selectedTabulation) { var titleTracks = []; var seriesTraversal = []; for (var i = 0; i < this.props.reports.seriesTraversal.length; i++) { var name = this.props.reports.selectedTabulation.Title; if (i > 0) name = this.props.reports.seriesTraversal[i-1]; // Make a closure for going up the food chain var self = this; var navOnClick = function() { var onSelectSeries = self.props.onSelectSeries; var mySeriesTraversal = seriesTraversal.slice(); return function() { onSelectSeries(mySeriesTraversal); }; }(); titleTracks.push(( <Button key={i*2} bsStyle="link" onClick={navOnClick}> {name} </Button> )); titleTracks.push((<span key={i*2+1}>/</span>)); seriesTraversal.push(this.props.reports.seriesTraversal[i]); } if (titleTracks.length == 0) { titleTracks.push(( <Button key={0} bsStyle="link"> {this.props.reports.selectedTabulation.Title} </Button> )); } else { var i = this.props.reports.seriesTraversal.length-1; titleTracks.push(( <Button key={i*2+2} bsStyle="link"> {this.props.reports.seriesTraversal[i]} </Button> )); } if (this.props.reports.selectedTabulation.Labels.length > 1) var report = ( <StackedBarChart report={this.props.reports.selectedTabulation} onSelectSeries={this.onSelectSeries} seriesTraversal={this.props.reports.seriesTraversal} /> ); else var report = ( <PieChart report={this.props.reports.selectedTabulation} onSelectSeries={this.onSelectSeries} seriesTraversal={this.props.reports.seriesTraversal} /> ); reportPanel = ( <Panel header={titleTracks}> {report} </Panel> ); } else if (this.props.reports.selected != -1) { reportPanel = ( <Panel header={this.props.reports.map[this.props.reports.selected].Name}> <ProgressBar active now={100} label={"Tabulating Report..."} /> </Panel> ); } var noReportSelected = this.props.reports.selected == -1; var selectedReport = -1; if (this.props.reports.map.hasOwnProperty(this.props.reports.selected)) selectedReport = this.props.reports.map[this.props.reports.selected]; return ( <div> <AddEditReportModal show={this.state.creatingNewReport} onCancel={this.onCreationCancel} onSubmit={this.onCreationSubmit} /> <AddEditReportModal show={this.state.editingReport} editReport={selectedReport} onCancel={this.onEditingCancel} onSubmit={this.onEditingSubmit} /> <ButtonToolbar> <ButtonGroup> <Button onClick={this.onNewReport} bsStyle="success"><Glyphicon glyph='plus-sign'/> New Report</Button> </ButtonGroup> <ButtonGroup> <Combobox data={this.props.reports.list} valueField='ReportId' textField={item => typeof item === 'string' ? item : item.Name} value={selectedReport} onChange={this.onSelectReport} suggest filter='contains' ref="report" /> </ButtonGroup> <ButtonGroup> <Button onClick={this.onEditReport} bsStyle="primary" disabled={noReportSelected}><Glyphicon glyph='cog'/> Edit Report</Button> <Button onClick={this.onDeleteReport} bsStyle="danger" disabled={noReportSelected}><Glyphicon glyph='trash'/> Delete Report</Button> </ButtonGroup></ButtonToolbar> {reportPanel} </div> ); } } module.exports = ReportsTab;