mirror of
				https://github.com/aclindsa/moneygo.git
				synced 2025-11-03 18:13:27 -05:00 
			
		
		
		
	Basic Report UI complete!
This commit is contained in:
		
							
								
								
									
										6
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								Makefile
									
									
									
									
									
								
							@@ -1,6 +1,6 @@
 | 
				
			|||||||
JS_SOURCES = $(wildcard js/*.js) $(wildcard js/*/*.js)
 | 
					JS_SOURCES = $(wildcard js/*.js) $(wildcard js/*/*.js)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
all: static/bundle.js static/react-widgets security_templates.go
 | 
					all: static/bundle.js static/react-widgets static/codemirror/codemirror.css security_templates.go
 | 
				
			||||||
 | 
					
 | 
				
			||||||
node_modules:
 | 
					node_modules:
 | 
				
			||||||
	npm install
 | 
						npm install
 | 
				
			||||||
@@ -11,6 +11,10 @@ static/bundle.js: $(JS_SOURCES) node_modules
 | 
				
			|||||||
static/react-widgets: node_modules/react-widgets/dist node_modules
 | 
					static/react-widgets: node_modules/react-widgets/dist node_modules
 | 
				
			||||||
	rsync -a node_modules/react-widgets/dist/ static/react-widgets/
 | 
						rsync -a node_modules/react-widgets/dist/ static/react-widgets/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static/codemirror/codemirror.css: node_modules/codemirror/lib/codemirror.js node_modules
 | 
				
			||||||
 | 
						mkdir -p static/codemirror
 | 
				
			||||||
 | 
						cp node_modules/codemirror/lib/codemirror.css static/codemirror/codemirror.css
 | 
				
			||||||
 | 
					
 | 
				
			||||||
security_templates.go: cusip_list.csv
 | 
					security_templates.go: cusip_list.csv
 | 
				
			||||||
	./scripts/gen_security_list.py > security_templates.go
 | 
						./scripts/gen_security_list.py > security_templates.go
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -138,9 +138,9 @@ function create(report) {
 | 
				
			|||||||
				if (e.isError()) {
 | 
									if (e.isError()) {
 | 
				
			||||||
					dispatch(ErrorActions.serverError(e));
 | 
										dispatch(ErrorActions.serverError(e));
 | 
				
			||||||
				} else {
 | 
									} else {
 | 
				
			||||||
					var a = new Report();
 | 
										var r = new Report();
 | 
				
			||||||
					a.fromJSON(data);
 | 
										r.fromJSON(data);
 | 
				
			||||||
					dispatch(reportCreated(a));
 | 
										dispatch(reportCreated(r));
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
			error: function(jqXHR, status, error) {
 | 
								error: function(jqXHR, status, error) {
 | 
				
			||||||
@@ -165,9 +165,10 @@ function update(report) {
 | 
				
			|||||||
				if (e.isError()) {
 | 
									if (e.isError()) {
 | 
				
			||||||
					dispatch(ErrorActions.serverError(e));
 | 
										dispatch(ErrorActions.serverError(e));
 | 
				
			||||||
				} else {
 | 
									} else {
 | 
				
			||||||
					var a = new Report();
 | 
										var r = new Report();
 | 
				
			||||||
					a.fromJSON(data);
 | 
										r.fromJSON(data);
 | 
				
			||||||
					dispatch(reportUpdated(a));
 | 
										dispatch(reportUpdated(r));
 | 
				
			||||||
 | 
										dispatch(tabulate(r));
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
			error: function(jqXHR, status, error) {
 | 
								error: function(jqXHR, status, error) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,9 +1,25 @@
 | 
				
			|||||||
var React = require('react');
 | 
					var React = require('react');
 | 
				
			||||||
 | 
					var ReactDOM = require('react-dom');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var ReactBootstrap = require('react-bootstrap');
 | 
					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 Button = ReactBootstrap.Button;
 | 
				
			||||||
 | 
					var ButtonGroup = ReactBootstrap.ButtonGroup;
 | 
				
			||||||
 | 
					var ButtonToolbar = ReactBootstrap.ButtonToolbar;
 | 
				
			||||||
 | 
					var Glyphicon = ReactBootstrap.Glyphicon;
 | 
				
			||||||
var Panel = ReactBootstrap.Panel;
 | 
					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 StackedBarChart = require('../components/StackedBarChart');
 | 
				
			||||||
var PieChart = require('../components/PieChart');
 | 
					var PieChart = require('../components/PieChart');
 | 
				
			||||||
@@ -12,13 +28,121 @@ var models = require('../models')
 | 
				
			|||||||
var Report = models.Report;
 | 
					var Report = models.Report;
 | 
				
			||||||
var Tabulation = models.Tabulation;
 | 
					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 {
 | 
					class ReportsTab extends React.Component {
 | 
				
			||||||
	constructor() {
 | 
						constructor() {
 | 
				
			||||||
		super();
 | 
							super();
 | 
				
			||||||
		this.state = {
 | 
							this.state = {
 | 
				
			||||||
			initialized: false
 | 
								initialized: false,
 | 
				
			||||||
 | 
								creatingNewReport: false,
 | 
				
			||||||
 | 
								editingReport: false
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		this.onSelectSeries = this.handleSelectSeries.bind(this);
 | 
							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() {
 | 
						componentWillMount() {
 | 
				
			||||||
		this.props.onFetchAllReports();
 | 
							this.props.onFetchAllReports();
 | 
				
			||||||
@@ -27,47 +151,73 @@ class ReportsTab extends React.Component {
 | 
				
			|||||||
		var selected = nextProps.reports.selected;
 | 
							var selected = nextProps.reports.selected;
 | 
				
			||||||
		if (!this.state.initialized) {
 | 
							if (!this.state.initialized) {
 | 
				
			||||||
			if (selected == -1 &&
 | 
								if (selected == -1 &&
 | 
				
			||||||
					nextProps.reports.list.length > 0)
 | 
										nextProps.reports.list.length > 0) {
 | 
				
			||||||
				nextProps.onSelectReport(nextProps.reports.map[nextProps.reports.list[0]]);
 | 
									nextProps.onSelectReport(nextProps.reports.map[nextProps.reports.list[0]]);
 | 
				
			||||||
			this.setState({initialized: true});
 | 
					 | 
				
			||||||
		} else if (selected != -1 && !nextProps.reports.tabulations.hasOwnProperty(selected)) {
 | 
					 | 
				
			||||||
				nextProps.onTabulateReport(nextProps.reports.map[nextProps.reports.list[0]]);
 | 
									nextProps.onTabulateReport(nextProps.reports.map[nextProps.reports.list[0]]);
 | 
				
			||||||
		} else if (selected != -1 && nextProps.reports.selectedTabulation == null) {
 | 
									this.setState({initialized: true});
 | 
				
			||||||
			nextProps.onSelectSeries(nextProps.reports.tabulations[nextProps.reports.list[0]]);
 | 
								}
 | 
				
			||||||
 | 
							} else if (selected != -1 &&
 | 
				
			||||||
 | 
									nextProps.reports.tabulations.hasOwnProperty(selected) &&
 | 
				
			||||||
 | 
									nextProps.reports.selectedTabulation == null) {
 | 
				
			||||||
 | 
								nextProps.onSelectSeries(nextProps.reports.tabulations[selected]);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	handleSelectSeries(series) {
 | 
						handleSelectSeries(series) {
 | 
				
			||||||
		if (series == Tabulation.topLevelSeriesName())
 | 
							if (series == Tabulation.topLevelSeriesName())
 | 
				
			||||||
			return;
 | 
								return;
 | 
				
			||||||
		var seriesTraversal = this.props.selectedTabulation.seriesTraversal.slice();
 | 
							var seriesTraversal = this.props.reports.seriesTraversal.slice();
 | 
				
			||||||
		seriesTraversal.push(series);
 | 
							seriesTraversal.push(series);
 | 
				
			||||||
		var selectedTabulation = this.props.reports.tabulations[this.props.reports.selected];
 | 
							var selectedTabulation = this.props.reports.tabulations[this.props.reports.selected];
 | 
				
			||||||
		this.props.onSelectSeries(selectedTabulation, seriesTraversal);
 | 
							this.props.onSelectSeries(selectedTabulation, 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() {
 | 
						render() {
 | 
				
			||||||
		var selectedTabulation = this.props.reports.selectedTabulation;
 | 
							var selectedTabulation = this.props.reports.selectedTabulation;
 | 
				
			||||||
		if (!selectedTabulation) {
 | 
							var reportPanel = [];
 | 
				
			||||||
			return (
 | 
							if (selectedTabulation) {
 | 
				
			||||||
				<div></div>
 | 
					 | 
				
			||||||
			);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			var titleTracks = [];
 | 
								var titleTracks = [];
 | 
				
			||||||
			var seriesTraversal = [];
 | 
								var seriesTraversal = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		for (var i = 0; i < this.props.selectedTabulation.seriesTraversal.length; i++) {
 | 
								for (var i = 0; i < this.props.reports.seriesTraversal.length; i++) {
 | 
				
			||||||
			var name = this.props.selectedTabulation.tabulation.Title;
 | 
									var name = this.props.reports.selectedTabulation.Title;
 | 
				
			||||||
				if (i > 0)
 | 
									if (i > 0)
 | 
				
			||||||
				name = this.props.selectedTabulation.seriesTraversal[i-1];
 | 
										name = this.props.reports.seriesTraversal[i-1];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				// Make a closure for going up the food chain
 | 
									// Make a closure for going up the food chain
 | 
				
			||||||
				var self = this;
 | 
									var self = this;
 | 
				
			||||||
				var navOnClick = function() {
 | 
									var navOnClick = function() {
 | 
				
			||||||
				var onSelectTabulation = self.props.onSelectTabulation;
 | 
										var onSelectSeries = self.props.onSelectSeries;
 | 
				
			||||||
				var report = self.props.reports[self.props.selectedTabulation.tabulation.ReportId];
 | 
										var tabulation = self.props.reports.tabulations[self.props.reports.selected];
 | 
				
			||||||
					var mySeriesTraversal = seriesTraversal.slice();
 | 
										var mySeriesTraversal = seriesTraversal.slice();
 | 
				
			||||||
					return function() {
 | 
										return function() {
 | 
				
			||||||
					onSelectTabulation(report, mySeriesTraversal);
 | 
											onSelectSeries(tabulation, mySeriesTraversal);
 | 
				
			||||||
					};
 | 
										};
 | 
				
			||||||
				}();
 | 
									}();
 | 
				
			||||||
				titleTracks.push((
 | 
									titleTracks.push((
 | 
				
			||||||
@@ -77,31 +227,89 @@ class ReportsTab extends React.Component {
 | 
				
			|||||||
					</Button>
 | 
										</Button>
 | 
				
			||||||
				));
 | 
									));
 | 
				
			||||||
				titleTracks.push((<span key={i*2+1}>/</span>));
 | 
									titleTracks.push((<span key={i*2+1}>/</span>));
 | 
				
			||||||
			seriesTraversal.push(this.props.selectedTabulation.seriesTraversal[i]);
 | 
									seriesTraversal.push(this.props.reports.seriesTraversal[i]);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			if (titleTracks.length == 0) {
 | 
								if (titleTracks.length == 0) {
 | 
				
			||||||
				titleTracks.push((
 | 
									titleTracks.push((
 | 
				
			||||||
					<Button key={0} bsStyle="link">
 | 
										<Button key={0} bsStyle="link">
 | 
				
			||||||
					{this.props.selectedTabulation.tabulation.Title}
 | 
											{this.props.reports.selectedTabulation.Title}
 | 
				
			||||||
					</Button>
 | 
										</Button>
 | 
				
			||||||
				));
 | 
									));
 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
			var i = this.props.selectedTabulation.seriesTraversal.length-1;
 | 
									var i = this.props.reports.seriesTraversal.length-1;
 | 
				
			||||||
				titleTracks.push((
 | 
									titleTracks.push((
 | 
				
			||||||
					<Button key={i*2+2} bsStyle="link">
 | 
										<Button key={i*2+2} bsStyle="link">
 | 
				
			||||||
				{this.props.selectedTabulation.seriesTraversal[i]}
 | 
										{this.props.reports.seriesTraversal[i]}
 | 
				
			||||||
					</Button>
 | 
										</Button>
 | 
				
			||||||
				));
 | 
									));
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		return (
 | 
								if (this.props.reports.selectedTabulation.Labels.length > 1)
 | 
				
			||||||
			<Panel header={titleTracks}>
 | 
									var report = (
 | 
				
			||||||
				<PieChart
 | 
										<StackedBarChart
 | 
				
			||||||
					report={this.props.selectedTabulation.tabulation}
 | 
											report={this.props.reports.selectedTabulation}
 | 
				
			||||||
						onSelectSeries={this.onSelectSeries}
 | 
											onSelectSeries={this.onSelectSeries}
 | 
				
			||||||
					seriesTraversal={this.props.selectedTabulation.seriesTraversal} />
 | 
											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>
 | 
									</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.report_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>
 | 
				
			||||||
 | 
							);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -135,12 +135,12 @@ class StackedBarChart extends React.Component {
 | 
				
			|||||||
				if (value == 0)
 | 
									if (value == 0)
 | 
				
			||||||
					continue;
 | 
										continue;
 | 
				
			||||||
				if (value > 0) {
 | 
									if (value > 0) {
 | 
				
			||||||
					rectHeight = y(value) - y(0);
 | 
										var rectHeight = y(value) - y(0);
 | 
				
			||||||
					positiveSum[j] += rectHeight;
 | 
										positiveSum[j] += rectHeight;
 | 
				
			||||||
					rectY = height - y(0) - positiveSum[j];
 | 
										var rectY = height - y(0) - positiveSum[j];
 | 
				
			||||||
				} else {
 | 
									} else {
 | 
				
			||||||
					rectHeight = y(0) - y(value);
 | 
										var rectHeight = y(0) - y(value);
 | 
				
			||||||
					rectY = height - y(0) + negativeSum[j];
 | 
										var rectY = height - y(0) + negativeSum[j];
 | 
				
			||||||
					negativeSum[j] += rectHeight;
 | 
										negativeSum[j] += rectHeight;
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,8 +4,14 @@ var ReportActions = require('../actions/ReportActions');
 | 
				
			|||||||
var ReportsTab = require('../components/ReportsTab');
 | 
					var ReportsTab = require('../components/ReportsTab');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function mapStateToProps(state) {
 | 
					function mapStateToProps(state) {
 | 
				
			||||||
 | 
						var report_list = [];
 | 
				
			||||||
 | 
						for (var reportId in state.reports.map) {
 | 
				
			||||||
 | 
							if (state.reports.map.hasOwnProperty(reportId))
 | 
				
			||||||
 | 
								report_list.push(state.reports.map[reportId]);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	return {
 | 
						return {
 | 
				
			||||||
		reports: state.reports
 | 
							reports: state.reports,
 | 
				
			||||||
 | 
							report_list: report_list
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										32
									
								
								js/models.js
									
									
									
									
									
								
							
							
						
						
									
										32
									
								
								js/models.js
									
									
									
									
									
								
							@@ -435,6 +435,35 @@ class Error {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Report {
 | 
				
			||||||
 | 
						constructor() {
 | 
				
			||||||
 | 
							this.ReportId = -1;
 | 
				
			||||||
 | 
							this.UserId = -1;
 | 
				
			||||||
 | 
							this.Name = "";
 | 
				
			||||||
 | 
							this.Lua = "";
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						toJSON() {
 | 
				
			||||||
 | 
							var json_obj = {};
 | 
				
			||||||
 | 
							json_obj.ReportId = this.ReportId;
 | 
				
			||||||
 | 
							json_obj.UserId = this.UserId;
 | 
				
			||||||
 | 
							json_obj.Name = this.Name;
 | 
				
			||||||
 | 
							json_obj.Lua = this.Lua;
 | 
				
			||||||
 | 
							return JSON.stringify(json_obj);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						fromJSON(json_input) {
 | 
				
			||||||
 | 
							var json_obj = getJSONObj(json_input)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (json_obj.hasOwnProperty("ReportId"))
 | 
				
			||||||
 | 
								this.ReportId = json_obj.ReportId;
 | 
				
			||||||
 | 
							if (json_obj.hasOwnProperty("UserId"))
 | 
				
			||||||
 | 
								this.UserId = json_obj.UserId;
 | 
				
			||||||
 | 
							if (json_obj.hasOwnProperty("Name"))
 | 
				
			||||||
 | 
								this.Name = json_obj.Name;
 | 
				
			||||||
 | 
							if (json_obj.hasOwnProperty("Lua"))
 | 
				
			||||||
 | 
								this.Lua = json_obj.Lua;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Series {
 | 
					class Series {
 | 
				
			||||||
	constructor() {
 | 
						constructor() {
 | 
				
			||||||
		this.Values = [];
 | 
							this.Values = [];
 | 
				
			||||||
@@ -496,7 +525,7 @@ class Series {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
class Tabulation {
 | 
					class Tabulation {
 | 
				
			||||||
	constructor() {
 | 
						constructor() {
 | 
				
			||||||
		this.ReportId = "";
 | 
							this.ReportId = -1;
 | 
				
			||||||
		this.Title = "";
 | 
							this.Title = "";
 | 
				
			||||||
		this.Subtitle = "";
 | 
							this.Subtitle = "";
 | 
				
			||||||
		this.Units = "";
 | 
							this.Units = "";
 | 
				
			||||||
@@ -578,6 +607,7 @@ module.exports = {
 | 
				
			|||||||
	Account: Account,
 | 
						Account: Account,
 | 
				
			||||||
	Split: Split,
 | 
						Split: Split,
 | 
				
			||||||
	Transaction: Transaction,
 | 
						Transaction: Transaction,
 | 
				
			||||||
 | 
						Report: Report,
 | 
				
			||||||
	Tabulation: Tabulation,
 | 
						Tabulation: Tabulation,
 | 
				
			||||||
	OFXDownload: OFXDownload,
 | 
						OFXDownload: OFXDownload,
 | 
				
			||||||
	Error: Error,
 | 
						Error: Error,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -63,16 +63,19 @@ module.exports = function(state = initialState, action) {
 | 
				
			|||||||
				selectedTabulation: null,
 | 
									selectedTabulation: null,
 | 
				
			||||||
				seriesTraversal: []
 | 
									seriesTraversal: []
 | 
				
			||||||
			});
 | 
								});
 | 
				
			||||||
		case ReportConstants.TABULATION_FETCHED:
 | 
							case ReportConstants.REPORT_TABULATED:
 | 
				
			||||||
			var tabulation = action.tabulation;
 | 
								var tabulation = action.tabulation;
 | 
				
			||||||
			return assign({}, state, {
 | 
								var tabulations = assign({}, state.tabulations, {
 | 
				
			||||||
				[tabulation.ReportId]: tabulation
 | 
									[tabulation.ReportId]: tabulation
 | 
				
			||||||
			});
 | 
								});
 | 
				
			||||||
 | 
								return assign({}, state, {
 | 
				
			||||||
 | 
									tabulations: tabulations
 | 
				
			||||||
 | 
								});
 | 
				
			||||||
		case ReportConstants.SERIES_SELECTED:
 | 
							case ReportConstants.SERIES_SELECTED:
 | 
				
			||||||
			return {
 | 
								return assign({}, state, {
 | 
				
			||||||
				selectedTabulation: action.tabulation,
 | 
									selectedTabulation: action.tabulation,
 | 
				
			||||||
				seriesTraversal: action.seriesTraversal
 | 
									seriesTraversal: action.seriesTraversal
 | 
				
			||||||
			};
 | 
								});
 | 
				
			||||||
		case UserConstants.USER_LOGGEDOUT:
 | 
							case UserConstants.USER_LOGGEDOUT:
 | 
				
			||||||
			return initialState;
 | 
								return initialState;
 | 
				
			||||||
		default:
 | 
							default:
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -19,6 +19,7 @@
 | 
				
			|||||||
    "react-dom": "^15.3.2",
 | 
					    "react-dom": "^15.3.2",
 | 
				
			||||||
    "react-redux": "^5.0.5",
 | 
					    "react-redux": "^5.0.5",
 | 
				
			||||||
    "react-widgets": "^3.4.4",
 | 
					    "react-widgets": "^3.4.4",
 | 
				
			||||||
 | 
					    "react-codemirror": "^1.0.0",
 | 
				
			||||||
    "redux": "^3.6.0",
 | 
					    "redux": "^3.6.0",
 | 
				
			||||||
    "redux-thunk": "^2.1.0"
 | 
					    "redux-thunk": "^2.1.0"
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -203,6 +203,8 @@ func ReportTabulationHandler(w http.ResponseWriter, r *http.Request, user *User,
 | 
				
			|||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tabulation.ReportId = reportid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	err = tabulation.Write(w)
 | 
						err = tabulation.Write(w)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		WriteError(w, 999 /*Internal Error*/)
 | 
							WriteError(w, 999 /*Internal Error*/)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,6 +5,7 @@
 | 
				
			|||||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
 | 
					<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
 | 
				
			||||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css">
 | 
					<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css">
 | 
				
			||||||
<link rel="stylesheet" href="static/react-widgets/css/react-widgets.css">
 | 
					<link rel="stylesheet" href="static/react-widgets/css/react-widgets.css">
 | 
				
			||||||
 | 
					<link rel="stylesheet" href="static/codemirror/codemirror.css">
 | 
				
			||||||
<link rel="stylesheet" href="static/css/stylesheet.css">
 | 
					<link rel="stylesheet" href="static/css/stylesheet.css">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.js"></script>
 | 
					<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.js"></script>
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user