From d3d79fb613cd9fa18d979f3c689ee3593a066e02 Mon Sep 17 00:00:00 2001 From: Aaron Lindsay Date: Sat, 11 Feb 2017 20:39:38 -0500 Subject: [PATCH] Add Report infrastructure to UI --- js/actions/ReportActions.js | 50 +++++++++++++++++ js/components/MoneyGoApp.js | 6 ++- js/components/ReportsTab.js | 37 +++++++++++++ js/constants/ReportConstants.js | 6 +++ js/containers/ReportsTabContainer.js | 21 ++++++++ js/models.js | 80 ++++++++++++++++++++++++++++ js/reducers/MoneyGoReducer.js | 2 + js/reducers/ReportReducer.js | 18 +++++++ 8 files changed, 219 insertions(+), 1 deletion(-) create mode 100644 js/actions/ReportActions.js create mode 100644 js/components/ReportsTab.js create mode 100644 js/constants/ReportConstants.js create mode 100644 js/containers/ReportsTabContainer.js create mode 100644 js/reducers/ReportReducer.js diff --git a/js/actions/ReportActions.js b/js/actions/ReportActions.js new file mode 100644 index 0000000..d774a6b --- /dev/null +++ b/js/actions/ReportActions.js @@ -0,0 +1,50 @@ +var ReportConstants = require('../constants/ReportConstants'); + +var ErrorActions = require('./ErrorActions'); + +var models = require('../models.js'); +var Report = models.Report; +var Error = models.Error; + +function fetchReport() { + return { + type: ReportConstants.FETCH_REPORT + } +} + +function reportFetched(report) { + return { + type: ReportConstants.REPORT_FETCHED, + report: report + } +} + +function fetch(report) { + return function (dispatch) { + dispatch(fetchReport()); + + $.ajax({ + type: "GET", + dataType: "json", + url: "report/"+report+"/", + success: function(data, status, jqXHR) { + var e = new Error(); + e.fromJSON(data); + if (e.isError()) { + dispatch(ErrorActions.serverError(e)); + } else { + var r = new Report(); + r.fromJSON(data); + dispatch(reportFetched(r)); + } + }, + error: function(jqXHR, status, error) { + dispatch(ErrorActions.ajaxError(error)); + } + }); + }; +} + +module.exports = { + fetch: fetch +}; diff --git a/js/components/MoneyGoApp.js b/js/components/MoneyGoApp.js index dd72da8..62ab987 100644 --- a/js/components/MoneyGoApp.js +++ b/js/components/MoneyGoApp.js @@ -11,6 +11,7 @@ var NewUserModalContainer = require('../containers/NewUserModalContainer'); var AccountSettingsModalContainer = require('../containers/AccountSettingsModalContainer'); var AccountsTabContainer = require('../containers/AccountsTabContainer'); var SecuritiesTabContainer = require('../containers/SecuritiesTabContainer'); +var ReportsTabContainer = require('../containers/ReportsTabContainer'); module.exports = React.createClass({ displayName: "MoneyGoApp", @@ -56,7 +57,10 @@ module.exports = React.createClass({ Scheduled transactions go here... Budgets go here... - Reports go here... + + + ); else mainContent = ( diff --git a/js/components/ReportsTab.js b/js/components/ReportsTab.js new file mode 100644 index 0000000..9924db7 --- /dev/null +++ b/js/components/ReportsTab.js @@ -0,0 +1,37 @@ +var React = require('react'); +var ReactDOM = require('react-dom'); + +var ReactBootstrap = require('react-bootstrap'); +var Grid = ReactBootstrap.Grid; +var Row = ReactBootstrap.Row; +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 ListGroup = ReactBootstrap.ListGroup; +var ListGroupItem = ReactBootstrap.ListGroupItem; +var Modal = ReactBootstrap.Modal; +var Panel = ReactBootstrap.Panel; + +var Combobox = require('react-widgets').Combobox; + +module.exports = React.createClass({ + displayName: "ReportsTab", + getInitialState: function() { + return { }; + }, + componentWillMount: function() { + this.props.onFetchReport("monthly_expenses"); + }, + render: function() { + console.log(this.props.reports); + return ( +
hello
+ ); + } +}); diff --git a/js/constants/ReportConstants.js b/js/constants/ReportConstants.js new file mode 100644 index 0000000..7e8a913 --- /dev/null +++ b/js/constants/ReportConstants.js @@ -0,0 +1,6 @@ +var keyMirror = require('keymirror'); + +module.exports = keyMirror({ + FETCH_REPORT: null, + REPORT_FETCHED: null +}); diff --git a/js/containers/ReportsTabContainer.js b/js/containers/ReportsTabContainer.js new file mode 100644 index 0000000..9a917e2 --- /dev/null +++ b/js/containers/ReportsTabContainer.js @@ -0,0 +1,21 @@ +var connect = require('react-redux').connect; + +var ReportActions = require('../actions/ReportActions'); +var ReportsTab = require('../components/ReportsTab'); + +function mapStateToProps(state) { + return { + reports: state.reports + } +} + +function mapDispatchToProps(dispatch) { + return { + onFetchReport: function(reportname) {dispatch(ReportActions.fetch(reportname))} + } +} + +module.exports = connect( + mapStateToProps, + mapDispatchToProps +)(ReportsTab) diff --git a/js/models.js b/js/models.js index 404ae07..3a78419 100644 --- a/js/models.js +++ b/js/models.js @@ -396,6 +396,85 @@ Error.prototype.isError = function() { this.ErrorString != empty_error.ErrorString; } + +function Series() { + this.Values = []; + this.Children = {}; +} + +Series.prototype.toJSONobj = function() { + var json_obj = {}; + json_obj.Values = this.Values; + json_obj.Children = {}; + for (var child in this.Children) { + if (this.Children.hasOwnProperty(child)) + json_obj.Children[child] = this.Children[child].toJSONobj(); + } + return json_obj; +} + +Series.prototype.fromJSONobj = function(json_obj) { + if (json_obj.hasOwnProperty("Values")) + this.Values = json_obj.Values; + if (json_obj.hasOwnProperty("Children")) { + for (var child in json_obj.Children) { + if (json_obj.Children.hasOwnProperty(child)) + this.Children[child] = new Series(); + this.Children[child].fromJSONobj(json_obj.Children[child]); + } + } +} + +function Report() { + this.ReportId = ""; + this.Title = ""; + this.Subtitle = ""; + this.XAxisLabel = ""; + this.YAxisLabel = ""; + this.Labels = []; + this.Series = {}; +} + +Report.prototype.toJSON = function() { + var json_obj = {}; + json_obj.ReportId = this.ReportId; + json_obj.Title = this.Title; + json_obj.Subtitle = this.Subtitle; + json_obj.XAxisLabel = this.XAxisLabel; + json_obj.YAxisLabel = this.YAxisLabel; + json_obj.Labels = this.Labels; + json_obj.Series = {}; + for (var series in this.Series) { + if (this.Series.hasOwnProperty(series)) + json_obj.Series[series] = this.Series[series].toJSONobj(); + } + return JSON.stringify(json_obj); +} + +Report.prototype.fromJSON = function(json_input) { + var json_obj = getJSONObj(json_input) + + if (json_obj.hasOwnProperty("ReportId")) + this.ReportId = json_obj.ReportId; + if (json_obj.hasOwnProperty("Title")) + this.Title = json_obj.Title; + if (json_obj.hasOwnProperty("Subtitle")) + this.Subtitle = json_obj.Subtitle; + if (json_obj.hasOwnProperty("XAxisLabel")) + this.XAxisLabel = json_obj.XAxisLabel; + if (json_obj.hasOwnProperty("YAxisLabel")) + this.YAxisLabel = json_obj.YAxisLabel; + if (json_obj.hasOwnProperty("Labels")) + this.Labels = json_obj.Labels; + if (json_obj.hasOwnProperty("Series")) { + for (var series in json_obj.Series) { + if (json_obj.Series.hasOwnProperty(series)) + this.Series[series] = new Series(); + this.Series[series].fromJSONobj(json_obj.Series[series]); + } + } +} + module.exports = models = { // Classes @@ -405,6 +484,7 @@ module.exports = models = { Account: Account, Split: Split, Transaction: Transaction, + Report: Report, Error: Error, // Enums, Lists diff --git a/js/reducers/MoneyGoReducer.js b/js/reducers/MoneyGoReducer.js index 4926973..bd534bc 100644 --- a/js/reducers/MoneyGoReducer.js +++ b/js/reducers/MoneyGoReducer.js @@ -7,6 +7,7 @@ var SecurityReducer = require('./SecurityReducer'); var SecurityTemplateReducer = require('./SecurityTemplateReducer'); var SelectedAccountReducer = require('./SelectedAccountReducer'); var SelectedSecurityReducer = require('./SelectedSecurityReducer'); +var ReportReducer = require('./ReportReducer'); var ErrorReducer = require('./ErrorReducer'); module.exports = Redux.combineReducers({ @@ -17,5 +18,6 @@ module.exports = Redux.combineReducers({ securityTemplates: SecurityTemplateReducer, selectedAccount: SelectedAccountReducer, selectedSecurity: SelectedSecurityReducer, + reports: ReportReducer, error: ErrorReducer }); diff --git a/js/reducers/ReportReducer.js b/js/reducers/ReportReducer.js new file mode 100644 index 0000000..7e44be4 --- /dev/null +++ b/js/reducers/ReportReducer.js @@ -0,0 +1,18 @@ +var assign = require('object-assign'); + +var ReportConstants = require('../constants/ReportConstants'); +var UserConstants = require('../constants/UserConstants'); + +module.exports = function(state = {}, action) { + switch (action.type) { + case ReportConstants.REPORT_FETCHED: + var report = action.report; + return assign({}, state, { + [report.ReportId]: report + }); + case UserConstants.USER_LOGGEDOUT: + return {}; + default: + return state; + } +};