diff --git a/js/actions/ReportActions.js b/js/actions/ReportActions.js index 725e21b..3ca75d2 100644 --- a/js/actions/ReportActions.js +++ b/js/actions/ReportActions.js @@ -87,7 +87,7 @@ function select(report, seriesTraversal) { // Add back in any values from the current level if (series.hasOwnProperty('Values')) - flattenedSeries[report.topLevelAccountName] = series.Values; + flattenedSeries[Report.topLevelAccountName()] = series.Values; var flattenedReport = new Report(); diff --git a/js/components/AccountCombobox.js b/js/components/AccountCombobox.js index d9f6d40..8f7482b 100644 --- a/js/components/AccountCombobox.js +++ b/js/components/AccountCombobox.js @@ -4,24 +4,25 @@ var Combobox = require('react-widgets').Combobox; var getAccountDisplayList = require('../utils').getAccountDisplayList; -module.exports = React.createClass({ - displayName: "AccountCombobox", - getDefaultProps: function() { - return { +class AccountCombobox extends React.Component { + constructor() { + super(); + this.onAccountChange = this.handleAccountChange.bind(this); + this.defaultProps = { includeRoot: true, disabled: false, rootName: "New Top-level Account" - }; - }, - handleAccountChange: function(account) { + } + } + handleAccountChange(account) { if (this.props.onChange != null && account.hasOwnProperty('AccountId') && (this.props.accounts.hasOwnProperty([account.AccountId]) || account.AccountId == -1)) { this.props.onChange(account) } - }, - render: function() { + } + render() { var accounts = getAccountDisplayList(this.props.accounts, this.props.accountChildren, this.props.includeRoot, this.props.rootName); var className = ""; if (this.props.className) @@ -32,7 +33,7 @@ module.exports = React.createClass({ valueField='AccountId' textField='Name' defaultValue={this.props.value} - onChange={this.handleAccountChange} + onChange={this.onAccountChange} ref="account" disabled={this.props.disabled} suggest @@ -40,4 +41,6 @@ module.exports = React.createClass({ className={className} /> ); } -}); +} + +module.exports = AccountCombobox; diff --git a/js/components/AccountRegister.js b/js/components/AccountRegister.js index d259210..5a92c66 100644 --- a/js/components/AccountRegister.js +++ b/js/components/AccountRegister.js @@ -46,8 +46,12 @@ var getAccountDisplayName = require('../utils').getAccountDisplayName; var AccountCombobox = require('./AccountCombobox'); -const TransactionRow = React.createClass({ - handleClick: function(e) { +class TransactionRow extends React.Component { + constructor() { + super(); + this.onClick = this.handleClick.bind(this); + } + handleClick(e) { const refs = ["date", "number", "description", "account", "status", "amount"]; for (var ref in refs) { if (this.refs[refs[ref]] == e.target) { @@ -55,8 +59,8 @@ const TransactionRow = React.createClass({ return; } } - }, - render: function() { + } + render() { var date = this.props.transaction.Date; var dateString = date.getFullYear() + "/" + (date.getMonth()+1) + "/" + date.getDate(); var number = "" @@ -97,19 +101,25 @@ const TransactionRow = React.createClass({ return ( - {dateString} - {number} - {this.props.transaction.Description} - {accountName} - {status} - {amount} + {dateString} + {number} + {this.props.transaction.Description} + {accountName} + {status} + {amount} {balance} ); } -}); +} + +class AmountInput extends React.Component { + getInitialState(props) { + if (!props) + return { + LastGoodAmount: "0", + Amount: "0" + } -const AmountInput = React.createClass({ - _getInitialState: function(props) { // Ensure we can edit this without screwing up other copies of it var a; if (props.security) @@ -121,21 +131,23 @@ const AmountInput = React.createClass({ LastGoodAmount: a, Amount: a }; - }, - getInitialState: function() { - return this._getInitialState(this.props); - }, - componentWillReceiveProps: function(nextProps) { + } + constructor() { + super(); + this.onChange = this.handleChange.bind(this); + this.state = this.getInitialState(); + } + componentWillReceiveProps(nextProps) { if ((!nextProps.value.eq(this.props.value) && !nextProps.value.eq(this.getValue())) || nextProps.security !== this.props.security) { - this.setState(this._getInitialState(nextProps)); + this.setState(this.getInitialState(nextProps)); } - }, - componentDidMount: function() { - ReactDOM.findDOMNode(this.refs.amount).onblur = this.onBlur; - }, - onBlur: function() { + } + componentDidMount() { + ReactDOM.findDOMNode(this.refs.amount).onblur = this.handleBlur.bind(this); + } + handleBlur() { var a; if (this.props.security) a = (new Big(this.getValue())).toFixed(this.props.security.Precision); @@ -144,13 +156,13 @@ const AmountInput = React.createClass({ this.setState({ Amount: a }); - }, - onChange: function() { + } + handleChange() { this.setState({Amount: ReactDOM.findDOMNode(this.refs.amount).value}); if (this.props.onChange) this.props.onChange(); - }, - getValue: function() { + } + getValue() { try { var value = ReactDOM.findDOMNode(this.refs.amount).value; var ret = new Big(value); @@ -159,8 +171,8 @@ const AmountInput = React.createClass({ } catch(err) { return new Big(this.state.LastGoodAmount); } - }, - render: function() { + } + render() { var symbol = "?"; if (this.props.security) symbol = this.props.security.Symbol; @@ -177,37 +189,54 @@ const AmountInput = React.createClass({ ); } -}); +} -const AddEditTransactionModal = React.createClass({ - _getInitialState: function(props) { +class AddEditTransactionModal extends React.Component { + getInitialState(props) { // Ensure we can edit this without screwing up other copies of it - var t = props.transaction.deepCopy(); + if (props) + var t = props.transaction.deepCopy(); + else + var t = new Transaction(); + return { errorAlert: [], transaction: t }; - }, - getInitialState: function() { - return this._getInitialState(this.props); - }, - componentWillReceiveProps: function(nextProps) { + } + constructor() { + super(); + this.state = this.getInitialState(); + this.onCancel = this.handleCancel.bind(this); + this.onDescriptionChange = this.handleDescriptionChange.bind(this); + this.onDateChange = this.handleDateChange.bind(this); + this.onAddSplit = this.handleAddSplit.bind(this); + this.onDeleteSplit = this.handleDeleteSplit.bind(this); + this.onUpdateNumber = this.handleUpdateNumber.bind(this); + this.onUpdateStatus = this.handleUpdateStatus.bind(this); + this.onUpdateMemo = this.handleUpdateMemo.bind(this); + this.onUpdateAccount = this.handleUpdateAccount.bind(this); + this.onUpdateAmount = this.handleUpdateAmount.bind(this); + this.onSubmit = this.handleSubmit.bind(this); + this.onDelete = this.handleDelete.bind(this); + } + componentWillReceiveProps(nextProps) { if (nextProps.show && !this.props.show) { - this.setState(this._getInitialState(nextProps)); + this.setState(this.getInitialState(nextProps)); } - }, - handleCancel: function() { + } + handleCancel() { if (this.props.onCancel != null) this.props.onCancel(); - }, - handleDescriptionChange: function() { + } + handleDescriptionChange() { this.setState({ transaction: react_update(this.state.transaction, { Description: {$set: ReactDOM.findDOMNode(this.refs.description).value} }) }); - }, - handleDateChange: function(date, string) { + } + handleDateChange(date, string) { if (date == null) return; this.setState({ @@ -215,8 +244,8 @@ const AddEditTransactionModal = React.createClass({ Date: {$set: date} }) }); - }, - handleAddSplit: function() { + } + handleAddSplit() { var split = new Split(); split.Status = SplitStatus.Entered; this.setState({ @@ -224,15 +253,15 @@ const AddEditTransactionModal = React.createClass({ Splits: {$push: [split]} }) }); - }, - handleDeleteSplit: function(split) { + } + handleDeleteSplit(split) { this.setState({ transaction: react_update(this.state.transaction, { Splits: {$splice: [[split, 1]]} }) }); - }, - handleUpdateNumber: function(split) { + } + handleUpdateNumber(split) { var transaction = this.state.transaction; transaction.Splits[split] = react_update(transaction.Splits[split], { Number: {$set: ReactDOM.findDOMNode(this.refs['number-'+split]).value} @@ -240,8 +269,8 @@ const AddEditTransactionModal = React.createClass({ this.setState({ transaction: transaction }); - }, - handleUpdateStatus: function(status, split) { + } + handleUpdateStatus(status, split) { var transaction = this.state.transaction; transaction.Splits[split] = react_update(transaction.Splits[split], { Status: {$set: status.StatusId} @@ -249,8 +278,8 @@ const AddEditTransactionModal = React.createClass({ this.setState({ transaction: transaction }); - }, - handleUpdateMemo: function(split) { + } + handleUpdateMemo(split) { var transaction = this.state.transaction; transaction.Splits[split] = react_update(transaction.Splits[split], { Memo: {$set: ReactDOM.findDOMNode(this.refs['memo-'+split]).value} @@ -258,8 +287,8 @@ const AddEditTransactionModal = React.createClass({ this.setState({ transaction: transaction }); - }, - handleUpdateAccount: function(account, split) { + } + handleUpdateAccount(account, split) { var transaction = this.state.transaction; transaction.Splits[split] = react_update(transaction.Splits[split], { SecurityId: {$set: -1}, @@ -268,8 +297,8 @@ const AddEditTransactionModal = React.createClass({ this.setState({ transaction: transaction }); - }, - handleUpdateAmount: function(split) { + } + handleUpdateAmount(split) { var transaction = this.state.transaction; transaction.Splits[split] = react_update(transaction.Splits[split], { Amount: {$set: new Big(this.refs['amount-'+split].getValue())} @@ -277,8 +306,8 @@ const AddEditTransactionModal = React.createClass({ this.setState({ transaction: transaction }); - }, - handleSubmit: function() { + } + handleSubmit() { var errorString = "" var imbalancedSecurityList = this.state.transaction.imbalancedSplitSecurities(this.props.accounts); if (imbalancedSecurityList.length > 0) @@ -299,19 +328,19 @@ const AddEditTransactionModal = React.createClass({ if (this.props.onSubmit != null) this.props.onSubmit(this.state.transaction); - }, - handleDelete: function() { + } + handleDelete() { if (this.props.onDelete != null) this.props.onDelete(this.state.transaction); - }, - render: function() { + } + render() { var editing = this.props.transaction != null && this.props.transaction.isTransaction(); var headerText = editing ? "Edit" : "Create New"; var buttonText = editing ? "Save Changes" : "Create Transaction"; var deleteButton = []; if (editing) { deleteButton = ( - + ); } @@ -320,7 +349,7 @@ const AddEditTransactionModal = React.createClass({ for (i = 0; i < imbalancedSecurityList.length; i++) imbalancedSecurityMap[imbalancedSecurityList[i]] = i; - splits = []; + var splits = []; for (var i = 0; i < this.state.transaction.Splits.length; i++) { var self = this; var s = this.state.transaction.Splits[i]; @@ -341,27 +370,27 @@ const AddEditTransactionModal = React.createClass({ // Define all closures for calling split-updating functions var deleteSplitFn = (function() { var j = i; - return function() {self.handleDeleteSplit(j);}; + return function() {self.onDeleteSplit(j);}; })(); var updateNumberFn = (function() { var j = i; - return function() {self.handleUpdateNumber(j);}; + return function() {self.onUpdateNumber(j);}; })(); var updateStatusFn = (function() { var j = i; - return function(status) {self.handleUpdateStatus(status, j);}; + return function(status) {self.onUpdateStatus(status, j);}; })(); var updateMemoFn = (function() { var j = i; - return function() {self.handleUpdateMemo(j);}; + return function() {self.onUpdateMemo(j);}; })(); var updateAccountFn = (function() { var j = i; - return function(account) {self.handleUpdateAccount(account, j);}; + return function(account) {self.onUpdateAccount(account, j);}; })(); var updateAmountFn = (function() { var j = i; - return function() {self.handleUpdateAmount(j);}; + return function() {self.onUpdateAmount(j);}; })(); var deleteSplitButton = []; @@ -415,20 +444,20 @@ const AddEditTransactionModal = React.createClass({ } return ( - + {headerText} Transaction
+ onSubmit={this.onSubmit}> Date + onChange={this.onDateChange} /> @@ -436,7 +465,7 @@ const AddEditTransactionModal = React.createClass({ @@ -451,7 +480,7 @@ const AddEditTransactionModal = React.createClass({ {splits} - @@ -461,15 +490,15 @@ const AddEditTransactionModal = React.createClass({ - + {deleteButton} - + ); } -}); +} const ImportType = { OFX: 1, @@ -485,8 +514,8 @@ for (var type in ImportType) { } } -const ImportTransactionsModal = React.createClass({ - getInitialState: function() { +class ImportTransactionsModal extends React.Component { + getInitialState() { var startDate = new Date(); startDate.setMonth(startDate.getMonth() - 1); return { @@ -496,41 +525,56 @@ const ImportTransactionsModal = React.createClass({ endDate: new Date(), password: "", }; - }, - handleCancel: function() { - this.setState(this.getInitialState()); + } + constructor() { + super(); + this.state = this.getInitialState(); + this.onCancel = this.handleCancel.bind(this); + this.onImportChange = this.handleImportChange.bind(this); + this.onTypeChange = this.handleTypeChange.bind(this); + this.onPasswordChange = this.handlePasswordChange.bind(this); + this.onStartDateChange = this.handleStartDateChange.bind(this); + this.onEndDateChange = this.handleEndDateChange.bind(this); + this.onSubmit = this.handleSubmit.bind(this); + this.onImportTransactions = this.handleImportTransactions.bind(this); + } + componentWillReceiveProps(nextProps) { + if (nextProps.show && !this.props.show) { + this.setState(this.getInitialState()); + } + } + handleCancel() { if (this.props.onCancel != null) this.props.onCancel(); - }, - handleImportChange: function() { + } + handleImportChange() { this.setState({importFile: ReactDOM.findDOMNode(this.refs.importfile).value}); - }, - handleTypeChange: function(type) { + } + handleTypeChange(type) { this.setState({importType: type.TypeId}); - }, - handlePasswordChange: function() { + } + handlePasswordChange() { this.setState({password: ReactDOM.findDOMNode(this.refs.password).value}); - }, - handleStartDateChange: function(date, string) { + } + handleStartDateChange(date, string) { if (date == null) return; this.setState({ startDate: date }); - }, - handleEndDateChange: function(date, string) { + } + handleEndDateChange(date, string) { if (date == null) return; this.setState({ endDate: date }); - }, - handleSubmit: function() { - this.setState(this.getInitialState()); + } + handleSubmit() { if (this.props.onSubmit != null) this.props.onSubmit(this.props.account); - }, - handleImportTransactions: function() { + } + handleImportTransactions() { if (this.state.importType == ImportType.OFX) { this.props.onImportOFX(this.props.account, this.state.password, this.state.startDate, this.state.endDate); } else if (this.state.importType == ImportType.OFXFile) { @@ -538,8 +582,8 @@ const ImportTransactionsModal = React.createClass({ } else if (this.state.importType == ImportType.Gnucash) { this.props.onImportGnucash(ReactDOM.findDOMNode(this.refs.importfile)); } - }, - render: function() { + } + render() { var accountNameLabel = "Performing global import:" if (this.props.account != null && this.state.importType != ImportType.Gnucash) accountNameLabel = "Importing to '" + getAccountDisplayName(this.props.account, this.props.accounts) + "' account:"; @@ -565,10 +609,10 @@ const ImportTransactionsModal = React.createClass({ var button2 = []; if (!this.props.imports.importFinished && !this.props.imports.importFailed) { var importingDisabled = this.props.imports.importing || (this.state.importType != ImportType.OFX && this.state.importFile == "") || (this.state.importType == ImportType.OFX && this.state.password == ""); - button1 = (); - button2 = (); + button1 = (); + button2 = (); } else { - button1 = (); + button1 = (); } var inputDisabled = (this.props.imports.importing || this.props.imports.importFailed || this.props.imports.importFinished) ? true : false; @@ -588,7 +632,7 @@ const ImportTransactionsModal = React.createClass({ value={this.state.password} placeholder="Password..." ref="password" - onChange={this.handlePasswordChange} /> + onChange={this.onPasswordChange} /> @@ -597,7 +641,7 @@ const ImportTransactionsModal = React.createClass({ + onChange={this.onStartDateChange} /> @@ -606,7 +650,7 @@ const ImportTransactionsModal = React.createClass({ + onChange={this.onEndDateChange} /> @@ -620,7 +664,7 @@ const ImportTransactionsModal = React.createClass({ ref="importfile" disabled={inputDisabled} value={this.state.importFile} - onChange={this.handleImportChange} /> + onChange={this.onImportChange} /> Select a file to upload. @@ -628,12 +672,12 @@ const ImportTransactionsModal = React.createClass({ } return ( - + Import Transactions - @@ -648,7 +692,7 @@ const ImportTransactionsModal = React.createClass({ data={ImportTypeList} valueField='TypeId' textField='Name' - onSelect={this.handleTypeChange} + onSelect={this.onTypeChange} defaultValue={this.state.importType} disabled={disabledTypes} ref="importtype" /> @@ -668,40 +712,47 @@ const ImportTransactionsModal = React.createClass({ ); } -}); +} -module.exports = React.createClass({ - displayName: "AccountRegister", - getInitialState: function() { - return { +class AccountRegister extends React.Component { + constructor() { + super(); + this.state = { newTransaction: null, height: 0 }; - }, - resize: function() { + this.onEditTransaction = this.handleEditTransaction.bind(this); + this.onEditingCancel = this.handleEditingCancel.bind(this); + this.onNewTransactionClicked = this.handleNewTransactionClicked.bind(this); + this.onSelectPage = this.handleSelectPage.bind(this); + this.onImportComplete = this.handleImportComplete.bind(this); + this.onUpdateTransaction = this.handleUpdateTransaction.bind(this); + this.onDeleteTransaction = this.handleDeleteTransaction.bind(this); + } + resize() { var div = ReactDOM.findDOMNode(this); this.setState({height: div.parentElement.clientHeight - 64}); - }, - componentWillReceiveProps: function(nextProps) { + } + componentWillReceiveProps(nextProps) { if (!nextProps.transactionPage.upToDate && nextProps.selectedAccount != -1) { nextProps.onFetchTransactionPage(nextProps.accounts[nextProps.selectedAccount], nextProps.transactionPage.pageSize, nextProps.transactionPage.page); } - }, - componentDidMount: function() { + } + componentDidMount() { this.resize(); var self = this; $(window).resize(function() {self.resize();}); - }, - handleEditTransaction: function(transaction) { + } + handleEditTransaction(transaction) { this.props.onSelectTransaction(transaction.TransactionId); - }, - handleEditingCancel: function() { + } + handleEditingCancel() { this.setState({ newTransaction: null }); this.props.onUnselectTransaction(); - }, - handleNewTransactionClicked: function() { + } + handleNewTransactionClicked() { var newTransaction = new Transaction(); newTransaction.Date = new Date(); newTransaction.Splits.push(new Split()); @@ -713,14 +764,8 @@ module.exports = React.createClass({ this.setState({ newTransaction: newTransaction }); - }, - ajaxError: function(jqXHR, status, error) { - var e = new Error(); - e.ErrorId = 5; - e.ErrorString = "Request Failed: " + status + error; - this.setState({error: e}); - }, - handleSelectPage: function(eventKey) { + } + handleSelectPage(eventKey) { var newpage = eventKey - 1; // Don't do pages that don't make sense if (newpage < 0) @@ -732,17 +777,17 @@ module.exports = React.createClass({ this.props.onFetchTransactionPage(this.props.accounts[this.props.selectedAccount], this.props.pageSize, newpage); } } - }, - handleImportComplete: function() { + } + handleImportComplete() { this.props.onCloseImportModal(); this.props.onFetchAllAccounts(); this.props.onFetchTransactionPage(this.props.accounts[this.props.selectedAccount], this.props.pageSize, this.props.transactionPage.page); - }, - handleDeleteTransaction: function(transaction) { + } + handleDeleteTransaction(transaction) { this.props.onDeleteTransaction(transaction); this.props.onUnselectTransaction(); - }, - handleUpdateTransaction: function(transaction) { + } + handleUpdateTransaction(transaction) { if (transaction.TransactionId != -1) { this.props.onUpdateTransaction(transaction); } else { @@ -752,10 +797,10 @@ module.exports = React.createClass({ this.setState({ newTransaction: null }); - }, - render: function() { + } + render() { var name = "Please select an account"; - register = []; + var register = []; if (this.props.selectedAccount != -1) { name = this.props.accounts[this.props.selectedAccount].Name; @@ -815,9 +860,9 @@ module.exports = React.createClass({ transaction={selectedTransaction} accounts={this.props.accounts} accountChildren={this.props.accountChildren} - onCancel={this.handleEditingCancel} - onSubmit={this.handleUpdateTransaction} - onDelete={this.handleDeleteTransaction} + onCancel={this.onEditingCancel} + onSubmit={this.onUpdateTransaction} + onDelete={this.onDeleteTransaction} securities={this.props.securities} /> @@ -840,11 +885,11 @@ module.exports = React.createClass({ items={this.props.transactionPage.numPages} maxButtons={Math.min(5, this.props.transactionPage.numPages)} activePage={this.props.transactionPage.page + 1} - onSelect={this.handleSelectPage} /> + onSelect={this.onSelectPage} /> - + + ); } -}); +} + +module.exports = AccountSettingsModal; diff --git a/js/components/AccountsTab.js b/js/components/AccountsTab.js index 1da6ed5..a2684d2 100644 --- a/js/components/AccountsTab.js +++ b/js/components/AccountsTab.js @@ -33,8 +33,8 @@ var AccountTypeList = models.AccountTypeList; var AccountCombobox = require('./AccountCombobox'); var AccountRegister = require('./AccountRegister'); -const AddEditAccountModal = React.createClass({ - getInitialState: function() { +class AddEditAccountModal extends React.Component { + getInitialState(props) { var s = { accountid: -1, security: 1, @@ -54,36 +54,54 @@ const AddEditAccountModal = React.createClass({ ofxversion: "", ofxnoindent: false, }; - if (this.props.editAccount != null) { - s.accountid = this.props.editAccount.AccountId; - s.name = this.props.editAccount.Name; - s.security = this.props.editAccount.SecurityId; - s.parentaccountid = this.props.editAccount.ParentAccountId; - s.type = this.props.editAccount.Type; - s.ofxurl = this.props.editAccount.OFXURL; - s.ofxorg = this.props.editAccount.OFXORG; - s.ofxfid = this.props.editAccount.OFXFID; - s.ofxuser = this.props.editAccount.OFXUser; - s.ofxbankid = this.props.editAccount.OFXBankID; - s.ofxacctid = this.props.editAccount.OFXAcctID; - s.ofxaccttype = this.props.editAccount.OFXAcctType; - s.ofxclientuid = this.props.editAccount.OFXClientUID; - s.ofxappid = this.props.editAccount.OFXAppID; - s.ofxappver = this.props.editAccount.OFXAppVer; - s.ofxversion = this.props.editAccount.OFXVersion; - s.ofxnoindent = this.props.editAccount.OFXNoIndent; - } else if (this.props.initialParentAccount != null) { - s.security = this.props.initialParentAccount.SecurityId; - s.parentaccountid = this.props.initialParentAccount.AccountId; - s.type = this.props.initialParentAccount.Type; + if (!props) { + return s; + } else if (props.editAccount != null) { + s.accountid = props.editAccount.AccountId; + s.name = props.editAccount.Name; + s.security = props.editAccount.SecurityId; + s.parentaccountid = props.editAccount.ParentAccountId; + s.type = props.editAccount.Type; + s.ofxurl = props.editAccount.OFXURL; + s.ofxorg = props.editAccount.OFXORG; + s.ofxfid = props.editAccount.OFXFID; + s.ofxuser = props.editAccount.OFXUser; + s.ofxbankid = props.editAccount.OFXBankID; + s.ofxacctid = props.editAccount.OFXAcctID; + s.ofxaccttype = props.editAccount.OFXAcctType; + s.ofxclientuid = props.editAccount.OFXClientUID; + s.ofxappid = props.editAccount.OFXAppID; + s.ofxappver = props.editAccount.OFXAppVer; + s.ofxversion = props.editAccount.OFXVersion; + s.ofxnoindent = props.editAccount.OFXNoIndent; + } else if (props.initialParentAccount != null) { + s.security = props.initialParentAccount.SecurityId; + s.parentaccountid = props.initialParentAccount.AccountId; + s.type = props.initialParentAccount.Type; } return s; - }, - handleCancel: function() { + } + constructor() { + super(); + this.state = this.getInitialState(); + this.onCancel = this.handleCancel.bind(this); + this.onChange = this.handleChange.bind(this); + this.onNoIndentClick = this.handleNoIndentClick.bind(this); + this.onSecurityChange = this.handleSecurityChange.bind(this); + this.onTypeChange = this.handleTypeChange.bind(this); + this.onParentChange = this.handleParentChange.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(); - }, - handleChange: function() { + } + handleChange() { this.setState({ name: ReactDOM.findDOMNode(this.refs.name).value, ofxurl: ReactDOM.findDOMNode(this.refs.ofxurl).value, @@ -98,27 +116,27 @@ const AddEditAccountModal = React.createClass({ ofxappver: ReactDOM.findDOMNode(this.refs.ofxappver).value, ofxversion: ReactDOM.findDOMNode(this.refs.ofxversion).value, }); - }, + } - handleNoIndentClick: function() { + handleNoIndentClick() { this.setState({ofxnoindent: !this.state.ofxnoindent}); - }, - handleSecurityChange: function(security) { + } + handleSecurityChange(security) { if (security.hasOwnProperty('SecurityId')) this.setState({ security: security.SecurityId }); - }, - handleTypeChange: function(type) { + } + handleTypeChange(type) { if (type.hasOwnProperty('TypeId')) this.setState({ type: type.TypeId }); - }, - handleParentChange: function(parentAccount) { + } + handleParentChange(parentAccount) { this.setState({parentaccountid: parentAccount.AccountId}); - }, - handleSubmit: function() { + } + handleSubmit() { var a = new Account(); if (this.props.editAccount != null) @@ -143,13 +161,8 @@ const AddEditAccountModal = React.createClass({ if (this.props.onSubmit != null) this.props.onSubmit(a); - }, - componentWillReceiveProps: function(nextProps) { - if (nextProps.show && !this.props.show) { - this.setState(this.getInitialState()); - } - }, - render: function() { + } + render() { var headerText = (this.props.editAccount != null) ? "Edit" : "Create New"; var buttonText = (this.props.editAccount != null) ? "Save Changes" : "Create Account"; var rootName = (this.props.editAccount != null) ? "Top-level Account" : "New Top-level Account"; @@ -165,7 +178,7 @@ const AddEditAccountModal = React.createClass({ componentClass="select" placeholder="select" value={this.state.ofxaccttype} - onChange={this.handleChange} + onChange={this.onChange} ref="ofxaccttype"> @@ -180,20 +193,20 @@ const AddEditAccountModal = React.createClass({ } var bankIdDisabled = (this.state.type != AccountType.Investment && this.state.ofxaccttype == "CC") ? true : false; return ( - + {headerText} Account - + Name @@ -205,7 +218,7 @@ const AddEditAccountModal = React.createClass({ accountChildren={this.props.accountChildren} value={this.state.parentaccountid} rootName={rootName} - onChange={this.handleParentChange} + onChange={this.onParentChange} ref="parent" /> @@ -218,7 +231,7 @@ const AddEditAccountModal = React.createClass({ valueField='SecurityId' textField={item => typeof item === 'string' ? item : item.Name + " - " + item.Description} defaultValue={this.state.security} - onChange={this.handleSecurityChange} + onChange={this.onSecurityChange} ref="security" /> @@ -231,20 +244,20 @@ const AddEditAccountModal = React.createClass({ valueField='TypeId' textField='Name' defaultValue={this.state.type} - onChange={this.handleTypeChange} + onChange={this.onTypeChange} ref="type" /> -
+ OFX URL @@ -253,7 +266,7 @@ const AddEditAccountModal = React.createClass({ @@ -262,7 +275,7 @@ const AddEditAccountModal = React.createClass({ @@ -271,7 +284,7 @@ const AddEditAccountModal = React.createClass({ @@ -281,7 +294,7 @@ const AddEditAccountModal = React.createClass({ @@ -290,7 +303,7 @@ const AddEditAccountModal = React.createClass({ @@ -301,7 +314,7 @@ const AddEditAccountModal = React.createClass({ @@ -310,7 +323,7 @@ const AddEditAccountModal = React.createClass({ @@ -319,7 +332,7 @@ const AddEditAccountModal = React.createClass({ @@ -328,7 +341,7 @@ const AddEditAccountModal = React.createClass({ @@ -336,7 +349,7 @@ const AddEditAccountModal = React.createClass({ + onClick={this.onNoIndentClick}> Don't indent OFX request files @@ -348,40 +361,58 @@ const AddEditAccountModal = React.createClass({ - - + + ); } -}); +} -const DeleteAccountModal = React.createClass({ - getInitialState: function() { - if (this.props.initialAccount != null) - var accountid = this.props.initialAccount.AccountId; - else if (this.props.accounts.length > 0) - var accountid = this.props.accounts[0].AccountId; +class DeleteAccountModal extends React.Component { + getInitialState(props) { + if (!props) + var accountid = -1; + else if (props.initialAccount != null) + var accountid = props.initialAccount.AccountId; + else if (props.accounts.length > 0) + var accountid = props.accounts[0].AccountId; else var accountid = -1; - return {error: "", + + return { + error: "", accountid: accountid, checked: false, - show: false}; - }, - handleCancel: function() { + show: false + }; + } + constructor() { + super(); + this.state = this.getInitialState(); + this.onCancel = this.handleCancel.bind(this); + this.onChange = this.handleChange.bind(this); + this.onCheckboxClick = this.handleCheckboxClick.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(); - }, - handleChange: function(account) { + } + handleChange(account) { this.setState({accountid: account.AccountId}); - }, - handleCheckboxClick: function() { + } + handleCheckboxClick() { this.setState({checked: !this.state.checked}); - }, - handleSubmit: function() { + } + handleSubmit() { if (this.props.accounts.hasOwnProperty(this.state.accountid)) { if (this.state.checked) { if (this.props.onSubmit != null) @@ -392,13 +423,8 @@ const DeleteAccountModal = React.createClass({ } else { this.setState({error: "You must select an account."}); } - }, - componentWillReceiveProps: function(nextProps) { - if (nextProps.show && !this.props.show) { - this.setState(this.getInitialState()); - } - }, - render: function() { + } + render() { var checkbox = []; if (this.props.accounts.hasOwnProperty(this.state.accountid)) { var parentAccountId = this.props.accounts[this.state.accountid].ParentAccountId; @@ -412,7 +438,7 @@ const DeleteAccountModal = React.createClass({ + onClick={this.onCheckboxClick}> {warningString} @@ -428,14 +454,14 @@ const DeleteAccountModal = React.createClass({ return ( Delete Account {warning} - + Delete Account @@ -444,7 +470,7 @@ const DeleteAccountModal = React.createClass({ accounts={this.props.accounts} accountChildren={this.props.accountChildren} value={this.state.accountid} - onChange={this.handleChange}/> + onChange={this.onChange}/> {checkbox} @@ -452,32 +478,36 @@ const DeleteAccountModal = React.createClass({ - - + + ); } -}); +} -const AccountTreeNode = React.createClass({ - getInitialState: function() { - return {expanded: false}; - }, - handleToggle: function(e) { +class AccountTreeNode extends React.Component { + constructor() { + super(); + this.state = {expanded: false}; + this.onToggle = this.handleToggle.bind(this); + this.onChildSelect = this.handleChildSelect.bind(this); + this.onSelect = this.handleSelect.bind(this); + } + handleToggle(e) { e.preventDefault(); this.setState({expanded:!this.state.expanded}); - }, - handleChildSelect: function(account) { + } + handleChildSelect(account) { if (this.props.onSelect != null) this.props.onSelect(account); - }, - handleSelect: function() { + } + handleSelect() { if (this.props.onSelect != null) this.props.onSelect(this.props.account); - }, - render: function() { + } + render() { var glyph = this.state.expanded ? 'minus' : 'plus'; var active = (this.props.selectedAccount != -1 && this.props.account.AccountId == this.props.selectedAccount); @@ -493,14 +523,14 @@ const AccountTreeNode = React.createClass({ selectedAccount={self.props.selectedAccount} accounts={self.props.accounts} accountChildren={self.props.accountChildren} - onSelect={self.handleChildSelect}/> + onSelect={self.onChildSelect}/> ); }); var accounttreeClasses = "accounttree" var expandButton = []; if (children.length > 0) { expandButton.push(( - - - @@ -694,4 +736,6 @@ module.exports = React.createClass({ ); } -}); +} + +module.exports = AccountsTab; diff --git a/js/components/MoneyGoApp.js b/js/components/MoneyGoApp.js index 62ab987..d4b4c4b 100644 --- a/js/components/MoneyGoApp.js +++ b/js/components/MoneyGoApp.js @@ -13,36 +13,34 @@ var AccountsTabContainer = require('../containers/AccountsTabContainer'); var SecuritiesTabContainer = require('../containers/SecuritiesTabContainer'); var ReportsTabContainer = require('../containers/ReportsTabContainer'); -module.exports = React.createClass({ - displayName: "MoneyGoApp", - getInitialState: function() { - return { +class MoneyGoApp extends React.Component { + constructor() { + super(); + this.state = { showNewUserModal: false, showAccountSettingsModal: false }; - }, - componentDidMount: function() { + this.onShowSettings = this.handleShowSettings.bind(this); + this.onHideSettings = this.handleHideSettings.bind(this); + this.onShowNewUser = this.handleShowNewUser.bind(this); + this.onHideNewUser = this.handleHideNewUser.bind(this); + } + componentDidMount() { this.props.tryResumingSession(); - }, - handleAccountSettings: function() { + } + handleShowSettings() { this.setState({showAccountSettingsModal: true}); - }, - handleSettingsSubmitted: function(user) { + } + handleHideSettings(user) { this.setState({showAccountSettingsModal: false}); - }, - handleSettingsCanceled: function() { - this.setState({showAccountSettingsModal: false}); - }, - handleCreateNewUser: function() { + } + handleShowNewUser() { this.setState({showNewUserModal: true}); - }, - handleNewUserCreated: function() { + } + handleHideNewUser() { this.setState({showNewUserModal: false}); - }, - handleNewUserCanceled: function() { - this.setState({showNewUserModal: false}); - }, - render: function() { + } + render() { var mainContent; if (this.props.user.isUser()) mainContent = ( @@ -74,18 +72,20 @@ module.exports = React.createClass({ return (
+ onCreateNewUser={this.onShowNewUser} + onAccountSettings={this.onShowSettings} /> {mainContent} + onSubmit={this.onHideNewUser} + onCancel={this.onHideNewUser}/> + onSubmit={this.onHideSettings} + onCancel={this.onHideSettings}/>
); } -}); +} + +module.exports = MoneyGoApp; diff --git a/js/components/NewUserModal.js b/js/components/NewUserModal.js index c89607e..62791a6 100644 --- a/js/components/NewUserModal.js +++ b/js/components/NewUserModal.js @@ -14,19 +14,21 @@ var ButtonGroup = ReactBootstrap.ButtonGroup; var models = require('../models'); var User = models.User; -module.exports = React.createClass({ - displayName: "NewUserModal", - getInitialState: function() { - return {error: "", +class NewUserModal extends React.Component { + constructor() { + super(); + this.state = { + error: "", name: "", username: "", email: "", password: "", confirm_password: "", passwordChanged: false, - initial_password: ""}; - }, - passwordValidationState: function() { + initial_password: "" + }; + } + passwordValidationState() { if (this.state.passwordChanged) { if (this.state.password.length >= 10) return "success"; @@ -35,20 +37,20 @@ module.exports = React.createClass({ else return "error"; } - }, - confirmPasswordValidationState: function() { + } + confirmPasswordValidationState() { if (this.state.confirm_password.length > 0) { if (this.state.confirm_password == this.state.password) return "success"; else return "error"; } - }, - handleCancel: function() { + } + handleCancel() { if (this.props.onCancel != null) this.props.onCancel(); - }, - handleChange: function() { + } + handleChange() { if (ReactDOM.findDOMNode(this.refs.password).value != this.state.initial_password) this.setState({passwordChanged: true}); this.setState({ @@ -58,8 +60,8 @@ module.exports = React.createClass({ password: ReactDOM.findDOMNode(this.refs.password).value, confirm_password: ReactDOM.findDOMNode(this.refs.confirm_password).value }); - }, - handleSubmit: function(e) { + } + handleSubmit(e) { var u = new User(); var error = ""; e.preventDefault(); @@ -76,8 +78,8 @@ module.exports = React.createClass({ this.props.createNewUser(u); if (this.props.onSubmit != null) this.props.onSubmit(u); - }, - render: function() { + } + render() { return ( @@ -146,4 +148,6 @@ module.exports = React.createClass({ ); } -}); +} + +module.exports = NewUserModal; diff --git a/js/components/PieChart.js b/js/components/PieChart.js index d80fac9..dbb8aa9 100644 --- a/js/components/PieChart.js +++ b/js/components/PieChart.js @@ -1,9 +1,8 @@ var d3 = require('d3'); var React = require('react'); -var Slice = React.createClass({ - displayName: "Slice", - render: function() { +class Slice extends React.Component { + render() { if (this.props.angle > Math.PI*2 - 0.00001) { var slice = ( Math.PI ? 1 : 0; var rotateDegrees = this.props.startAngle * 180 / Math.PI; - slice = (); } @@ -26,11 +25,10 @@ var Slice = React.createClass({ ); } -}); +} -module.exports = React.createClass({ - displayName: "PieChart", - sortedSeries: function(series) { +class PieChart extends React.Component { + sortedSeries(series) { // Return an array of the series names, from highest to lowest sums (in // absolute terms) @@ -49,13 +47,13 @@ module.exports = React.createClass({ }); return [seriesNames, seriesValues]; - }, - render: function() { - height = 400; - width = 600; - legendWidth = 100; - xMargin = 70; - yMargin = 70; + } + render() { + var height = 400; + var width = 600; + var legendWidth = 100; + var xMargin = 70; + var yMargin = 70; height -= yMargin*2; width -= xMargin*2; var radius = Math.min(height, width)/2; @@ -133,4 +131,6 @@ module.exports = React.createClass({ ); } -}); +} + +module.exports = PieChart; diff --git a/js/components/ReportsTab.js b/js/components/ReportsTab.js index 409321b..1e102eb 100644 --- a/js/components/ReportsTab.js +++ b/js/components/ReportsTab.js @@ -7,27 +7,30 @@ var Panel = ReactBootstrap.Panel; var StackedBarChart = require('../components/StackedBarChart'); -module.exports = React.createClass({ - displayName: "ReportsTab", - getInitialState: function() { - return { }; - }, - componentWillMount: function() { +var models = require('../models') +var Report = models.Report; + +class ReportsTab extends React.Component { + constructor() { + super(); + this.onSelectSeries = this.handleSelectSeries.bind(this); + } + componentWillMount() { this.props.onFetchReport("monthly_expenses"); - }, - componentWillReceiveProps: function(nextProps) { + } + componentWillReceiveProps(nextProps) { if (nextProps.reports['monthly_expenses'] && !nextProps.selectedReport.report) { this.props.onSelectReport(nextProps.reports['monthly_expenses'], []); } - }, - onSelectSeries: function(series) { - if (series == this.props.selectedReport.report.topLevelAccountName) + } + handleSelectSeries(series) { + if (series == Report.topLevelAccountName()) return; var seriesTraversal = this.props.selectedReport.seriesTraversal.slice(); seriesTraversal.push(series); this.props.onSelectReport(this.props.reports[this.props.selectedReport.report.ReportId], seriesTraversal); - }, - render: function() { + } + render() { var report = []; if (this.props.selectedReport.report) { var titleTracks = []; @@ -86,4 +89,6 @@ module.exports = React.createClass({ ); } -}); +} + +module.exports = ReportsTab; diff --git a/js/components/SecuritiesTab.js b/js/components/SecuritiesTab.js index a6282af..919f5f1 100644 --- a/js/components/SecuritiesTab.js +++ b/js/components/SecuritiesTab.js @@ -25,11 +25,15 @@ var Security = models.Security; var SecurityType = models.SecurityType; var SecurityTypeList = models.SecurityTypeList; -const SecurityTemplatePanel = React.createClass({ - handleSearchChange: function(){ +class SecurityTemplatePanel extends React.Component { + constructor() { + super(); + this.onSearchChange = this.handleSearchChange.bind(this); + } + handleSearchChange() { this.props.onSearchTemplates(ReactDOM.findDOMNode(this.refs.search).value, 0, this.props.maxResults + 1); - }, - renderTemplateList: function() { + } + renderTemplateList() { var templates = this.props.securityTemplates; if (this.props.search != "") { var items = []; @@ -70,23 +74,23 @@ const SecurityTemplatePanel = React.createClass({ ); } - }, - render: function() { + } + render() { return ( {this.renderTemplateList()} ); } -}); +} -const AddEditSecurityModal = React.createClass({ - getInitialState: function() { +class AddEditSecurityModal extends React.Component { + getInitialState(props) { var s = { securityid: -1, name: "", @@ -96,18 +100,36 @@ const AddEditSecurityModal = React.createClass({ type: 1, alternateid: "" }; - if (this.props.editSecurity != null) { - s.securityid = this.props.editSecurity.SecurityId; - s.name = this.props.editSecurity.Name; - s.description = this.props.editSecurity.Description; - s.symbol = this.props.editSecurity.Symbol; - s.precision = this.props.editSecurity.Precision; - s.type = this.props.editSecurity.Type; - s.alternateid = this.props.editSecurity.AlternateId; + if (props && props.editSecurity != null) { + s.securityid = props.editSecurity.SecurityId; + s.name = props.editSecurity.Name; + s.description = props.editSecurity.Description; + s.symbol = props.editSecurity.Symbol; + s.precision = props.editSecurity.Precision; + s.type = props.editSecurity.Type; + s.alternateid = props.editSecurity.AlternateId; } return s; - }, - onSelectTemplate: function(template) { + } + constructor() { + super(); + this.state = this.getInitialState(); + this.onSelectTemplate = this.handleSelectTemplate.bind(this); + this.onCancel = this.handleCancel.bind(this); + this.onNameChange = this.handleNameChange.bind(this); + this.onDescriptionChange = this.handleDescriptionChange.bind(this); + this.onSymbolChange = this.handleSymbolChange.bind(this); + this.onPrecisionChange = this.handlePrecisionChange.bind(this); + this.onTypeChange = this.handleTypeChange.bind(this); + this.onAlternateIdChange = this.handleAlternateIdChange.bind(this); + this.onSubmit = this.handleSubmit.bind(this); + } + componentWillReceiveProps(nextProps) { + if (nextProps.show && !this.props.show) { + this.setState(this.getInitialState(nextProps)); + } + } + handleSelectTemplate(template) { this.setState({ name: template.Name, description: template.Description, @@ -116,43 +138,43 @@ const AddEditSecurityModal = React.createClass({ type: template.Type, alternateid: template.AlternateId }); - }, - handleCancel: function() { + } + handleCancel() { if (this.props.onCancel != null) this.props.onCancel(); - }, - handleNameChange: function() { + } + handleNameChange() { this.setState({ name: ReactDOM.findDOMNode(this.refs.name).value, }); - }, - handleDescriptionChange: function() { + } + handleDescriptionChange() { this.setState({ description: ReactDOM.findDOMNode(this.refs.description).value, }); - }, - handleSymbolChange: function() { + } + handleSymbolChange() { this.setState({ symbol: ReactDOM.findDOMNode(this.refs.symbol).value, }); - }, - handlePrecisionChange: function() { + } + handlePrecisionChange() { this.setState({ precision: +ReactDOM.findDOMNode(this.refs.precision).value, }); - }, - handleTypeChange: function(type) { + } + handleTypeChange(type) { if (type.hasOwnProperty('TypeId')) this.setState({ type: type.TypeId }); - }, - handleAlternateIdChange: function() { + } + handleAlternateIdChange() { this.setState({ alternateid: ReactDOM.findDOMNode(this.refs.alternateid).value, }); - }, - handleSubmit: function() { + } + handleSubmit() { var s = new Security(); if (this.props.editSecurity != null) @@ -166,18 +188,13 @@ const AddEditSecurityModal = React.createClass({ if (this.props.onSubmit != null) this.props.onSubmit(s); - }, - componentWillReceiveProps: function(nextProps) { - if (nextProps.show && !this.props.show) { - this.setState(this.getInitialState()); - } - }, - render: function() { + } + render() { var headerText = (this.props.editSecurity != null) ? "Edit" : "Create New"; var buttonText = (this.props.editSecurity != null) ? "Save Changes" : "Create Security"; var alternateidname = (this.state.type == SecurityType.Currency) ? "ISO 4217 Code" : "CUSIP"; return ( - + {headerText} Security @@ -188,13 +205,13 @@ const AddEditSecurityModal = React.createClass({ onSearchTemplates={this.props.onSearchTemplates} maxResults={15} onSelectTemplate={this.onSelectTemplate} /> - + Name @@ -203,7 +220,7 @@ const AddEditSecurityModal = React.createClass({ @@ -212,7 +229,7 @@ const AddEditSecurityModal = React.createClass({ @@ -222,7 +239,7 @@ const AddEditSecurityModal = React.createClass({ @@ -242,7 +259,7 @@ const AddEditSecurityModal = React.createClass({ valueField='TypeId' textField='Name' value={this.state.type} - onChange={this.handleTypeChange} + onChange={this.onTypeChange} ref="type" /> @@ -251,7 +268,7 @@ const AddEditSecurityModal = React.createClass({ @@ -259,17 +276,17 @@ const AddEditSecurityModal = React.createClass({ - - + + ); } -}); +} -const DeletionFailedModal = React.createClass({ - render: function() { +class DeletionFailedModal extends React.Component { + render() { return ( @@ -286,10 +303,10 @@ const DeletionFailedModal = React.createClass({ ); } -}); +} -const SecurityList = React.createClass({ - render: function() { +class SecurityList extends React.Component { + render() { var children = []; var self = this; for (var securityId in this.props.securities) { @@ -314,55 +331,64 @@ const SecurityList = React.createClass({ ); } -}); +} -module.exports = React.createClass({ - displayName: "SecuritiesTab", - getInitialState: function() { - return { +class SecuritiesTab extends React.Component { + constructor() { + super(); + this.state = { creatingNewSecurity: false, editingSecurity: false, deletionFailedModal: false }; - }, - componentWillReceiveProps: function(nextProps) { + this.onSelectSecurity = this.handleSelectSecurity.bind(this); + this.onNewSecurity = this.handleNewSecurity.bind(this); + this.onEditSecurity = this.handleEditSecurity.bind(this); + this.onDeleteSecurity = this.handleDeleteSecurity.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); + this.onCloseDeletionFailed = this.handleCloseDeletionFailed.bind(this); + } + componentWillReceiveProps(nextProps) { if (nextProps.selectedSecurity == -1 && nextProps.security_list.length > 0) { nextProps.onSelectSecurity(nextProps.security_list[0].SecurityId); } - }, - handleSelectSecurity: function(security) { + } + handleSelectSecurity(security) { this.props.onSelectSecurity(security.SecurityId); - }, - handleNewSecurity: function() { + } + handleNewSecurity() { this.setState({creatingNewSecurity: true}); - }, - handleEditSecurity: function() { + } + handleEditSecurity() { this.setState({editingSecurity: true}); - }, - handleDeleteSecurity: function() { + } + handleDeleteSecurity() { if (this.props.selectedSecurityAccounts.length == 0) this.props.onDeleteSecurity(this.props.securities[this.props.selectedSecurity]); else this.setState({deletionFailedModal: true}); - }, - handleCreationCancel: function() { + } + handleCreationCancel() { this.setState({creatingNewSecurity: false}); - }, - handleCreationSubmit: function(security) { + } + handleCreationSubmit(security) { this.setState({creatingNewSecurity: false}); this.props.onCreateSecurity(security); - }, - handleEditingCancel: function() { + } + handleEditingCancel() { this.setState({editingSecurity: false}); - }, - handleEditingSubmit: function(security) { + } + handleEditingSubmit(security) { this.setState({editingSecurity: false}); this.props.onUpdateSecurity(security); - }, - closeDeletionFailedModal: function() { + } + handleCloseDeletionFailed() { this.setState({deletionFailedModal: false}); - }, - render: function() { + } + render() { var noSecuritySelected = this.props.selectedSecurity == -1; var selectedSecurity = -1; @@ -373,25 +399,25 @@ module.exports = React.createClass({
- + typeof item === 'string' ? item : item.Name + " - " + item.Description} value={selectedSecurity} - onChange={this.handleSelectSecurity} + onChange={this.onSelectSecurity} suggest filter='contains' ref="security" /> - - + +
); } -}); +} + +module.exports = SecuritiesTab; diff --git a/js/components/StackedBarChart.js b/js/components/StackedBarChart.js index 46e9553..f807ddd 100644 --- a/js/components/StackedBarChart.js +++ b/js/components/StackedBarChart.js @@ -1,9 +1,8 @@ var d3 = require('d3'); var React = require('react'); -module.exports = React.createClass({ - displayName: "StackedBarChart", - calcMinMax: function(series) { +class StackedBarChart extends React.Component { + calcMinMax(series) { var children = []; for (var child in series) { if (series.hasOwnProperty(child)) @@ -28,8 +27,8 @@ module.exports = React.createClass({ } return [Math.min.apply(Math, negativeValues), Math.max.apply(Math, positiveValues)]; - }, - sortedSeries: function(series) { + } + sortedSeries(series) { // Return an array of the series names, from highest to lowest sums (in // absolute terms) @@ -48,21 +47,21 @@ module.exports = React.createClass({ }); return seriesNames; - }, - calcAxisMarkSeparation: function(minMax, height, ticksPerHeight) { + } + calcAxisMarkSeparation(minMax, height, ticksPerHeight) { var targetTicks = height / ticksPerHeight; var range = minMax[1]-minMax[0]; var rangePerTick = range/targetTicks; var roundOrder = Math.floor(Math.log(rangePerTick) / Math.LN10); var roundTo = Math.pow(10, roundOrder); return Math.ceil(rangePerTick/roundTo)*roundTo; - }, - render: function() { - height = 400; - width = 600; - legendWidth = 100; - xMargin = 70; - yMargin = 70; + } + render() { + var height = 400; + var width = 1000; + var legendWidth = 100; + var xMargin = 70; + var yMargin = 70; height -= yMargin*2; width -= xMargin*2; @@ -189,4 +188,6 @@ module.exports = React.createClass({ ); } -}); +} + +module.exports = StackedBarChart; diff --git a/js/components/TopBar.js b/js/components/TopBar.js index 21a8664..16ebf89 100644 --- a/js/components/TopBar.js +++ b/js/components/TopBar.js @@ -14,36 +14,39 @@ var ReactDOM = require('react-dom'); var User = require('../models').User; -const LoginBar = React.createClass({ - getInitialState: function() { - return {username: '', password: ''}; - }, - onUsernameChange: function(e) { +class LoginBar extends React.Component { + constructor() { + super(); + this.state = {username: '', password: ''}; + this.onSubmit = this.handleSubmit.bind(this); + this.onNewUserSubmit = this.handleNewUserSubmit.bind(this); + } + onUsernameChange(e) { this.setState({username: e.target.value}); - }, - onPasswordChange: function(e) { + } + onPasswordChange(e) { this.setState({password: e.target.value}); - }, - handleSubmit: function(e) { + } + handleSubmit(e) { var user = new User(); e.preventDefault(); user.Username = ReactDOM.findDOMNode(this.refs.username).value; user.Password = ReactDOM.findDOMNode(this.refs.password).value; this.props.onLogin(user); - }, - handleNewUserSubmit: function(e) { + } + handleNewUserSubmit(e) { e.preventDefault(); this.props.onCreateNewUser(); - }, - render: function() { + } + render() { return ( - + + onClick={this.onNewUserSubmit}>Create New User ); } -}); +} -const LogoutBar = React.createClass({ - handleOnSelect: function(key) { +class LogoutBar extends React.Component { + constructor() { + super(); + this.onSelect = this.handleOnSelect.bind(this); + } + handleOnSelect(key) { if (key == 1) { if (this.props.onAccountSettings != null) this.props.onAccountSettings(); } else if (key == 2) { this.props.onLogout(); } - }, - render: function() { + } + render() { var signedInString = "Signed in as "+this.props.user.Name; return ( @@ -84,7 +91,7 @@ const LogoutBar = React.createClass({
- + Account Settings Logout @@ -94,11 +101,10 @@ const LogoutBar = React.createClass({ ); } -}); +} -module.exports = React.createClass({ - displayName: "TopBar", - render: function() { +class TopBar extends React.Component { + render() { var barContents; var errorAlert; if (!this.props.user.isUser()) @@ -120,4 +126,6 @@ module.exports = React.createClass({
); } -}); +} + +module.exports = TopBar; diff --git a/js/models.js b/js/models.js index caf31da..76d143f 100644 --- a/js/models.js +++ b/js/models.js @@ -10,70 +10,68 @@ function getJSONObj(json_input) { return null } -function User() { - this.UserId = -1; - this.Name = ""; - this.Username = ""; - this.Password = ""; - this.Email = ""; +class User { + constructor() { + this.UserId = -1; + this.Name = ""; + this.Username = ""; + this.Password = ""; + this.Email = ""; + } + toJSON() { + var json_obj = {}; + json_obj.UserId = this.UserId; + json_obj.Name = this.Name; + json_obj.Username = this.Username; + json_obj.Password = this.Password; + json_obj.Email = this.Email; + return JSON.stringify(json_obj); + } + fromJSON(json_input) { + var json_obj = getJSONObj(json_input); + + if (json_obj.hasOwnProperty("UserId")) + this.UserId = json_obj.UserId; + if (json_obj.hasOwnProperty("Name")) + this.Name = json_obj.Name; + if (json_obj.hasOwnProperty("Username")) + this.Username = json_obj.Username; + if (json_obj.hasOwnProperty("Password")) + this.Password = json_obj.Password; + if (json_obj.hasOwnProperty("Email")) + this.Email = json_obj.Email; + } + isUser() { + var empty_user = new User(); + return this.UserId != empty_user.UserId || + this.Username != empty_user.Username; + } } -User.prototype.toJSON = function() { - var json_obj = {}; - json_obj.UserId = this.UserId; - json_obj.Name = this.Name; - json_obj.Username = this.Username; - json_obj.Password = this.Password; - json_obj.Email = this.Email; - return JSON.stringify(json_obj); -} +class Session { + constructor() { + this.SessionId = -1; + this.UserId = -1; + } + toJSON() { + var json_obj = {}; + json_obj.SessionId = this.SessionId; + json_obj.UserId = this.UserId; + return JSON.stringify(json_obj); + } + fromJSON(json_input) { + var json_obj = getJSONObj(json_input); -User.prototype.fromJSON = function(json_input) { - var json_obj = getJSONObj(json_input); - - if (json_obj.hasOwnProperty("UserId")) - this.UserId = json_obj.UserId; - if (json_obj.hasOwnProperty("Name")) - this.Name = json_obj.Name; - if (json_obj.hasOwnProperty("Username")) - this.Username = json_obj.Username; - if (json_obj.hasOwnProperty("Password")) - this.Password = json_obj.Password; - if (json_obj.hasOwnProperty("Email")) - this.Email = json_obj.Email; -} - -User.prototype.isUser = function() { - var empty_user = new User(); - return this.UserId != empty_user.UserId || - this.Username != empty_user.Username; -} - -function Session() { - this.SessionId = -1; - this.UserId = -1; -} - -Session.prototype.toJSON = function() { - var json_obj = {}; - json_obj.SessionId = this.SessionId; - json_obj.UserId = this.UserId; - return JSON.stringify(json_obj); -} - -Session.prototype.fromJSON = function(json_input) { - var json_obj = getJSONObj(json_input); - - if (json_obj.hasOwnProperty("SessionId")) - this.SessionId = json_obj.SessionId; - if (json_obj.hasOwnProperty("UserId")) - this.UserId = json_obj.UserId; -} - -Session.prototype.isSession = function() { - var empty_session = new Session(); - return this.SessionId != empty_session.SessionId || - this.UserId != empty_session.UserId; + if (json_obj.hasOwnProperty("SessionId")) + this.SessionId = json_obj.SessionId; + if (json_obj.hasOwnProperty("UserId")) + this.UserId = json_obj.UserId; + } + isSession() { + var empty_session = new Session(); + return this.SessionId != empty_session.SessionId || + this.UserId != empty_session.UserId; + } } const SecurityType = { @@ -87,51 +85,50 @@ for (var type in SecurityType) { } } -function Security() { - this.SecurityId = -1; - this.Name = ""; - this.Description = ""; - this.Symbol = ""; - this.Precision = -1; - this.Type = -1; - this.AlternateId = ""; -} +class Security { + constructor() { + this.SecurityId = -1; + this.Name = ""; + this.Description = ""; + this.Symbol = ""; + this.Precision = -1; + this.Type = -1; + this.AlternateId = ""; + } + toJSON() { + var json_obj = {}; + json_obj.SecurityId = this.SecurityId; + json_obj.Name = this.Name; + json_obj.Description = this.Description; + json_obj.Symbol = this.Symbol; + json_obj.Precision = this.Precision; + json_obj.Type = this.Type; + json_obj.AlternateId = this.AlternateId; + return JSON.stringify(json_obj); + } + fromJSON(json_input) { + var json_obj = getJSONObj(json_input); -Security.prototype.toJSON = function() { - var json_obj = {}; - json_obj.SecurityId = this.SecurityId; - json_obj.Name = this.Name; - json_obj.Description = this.Description; - json_obj.Symbol = this.Symbol; - json_obj.Precision = this.Precision; - json_obj.Type = this.Type; - json_obj.AlternateId = this.AlternateId; - return JSON.stringify(json_obj); -} - -Security.prototype.fromJSON = function(json_input) { - var json_obj = getJSONObj(json_input); - - if (json_obj.hasOwnProperty("SecurityId")) - this.SecurityId = json_obj.SecurityId; - if (json_obj.hasOwnProperty("Name")) - this.Name = json_obj.Name; - if (json_obj.hasOwnProperty("Description")) - this.Description = json_obj.Description; - if (json_obj.hasOwnProperty("Symbol")) - this.Symbol = json_obj.Symbol; - if (json_obj.hasOwnProperty("Precision")) - this.Precision = json_obj.Precision; - if (json_obj.hasOwnProperty("Type")) - this.Type = json_obj.Type; - if (json_obj.hasOwnProperty("AlternateId")) - this.AlternateId = json_obj.AlternateId; -} - -Security.prototype.isSecurity = function() { - var empty_account = new Security(); - return this.SecurityId != empty_account.SecurityId || - this.Type != empty_account.Type; + if (json_obj.hasOwnProperty("SecurityId")) + this.SecurityId = json_obj.SecurityId; + if (json_obj.hasOwnProperty("Name")) + this.Name = json_obj.Name; + if (json_obj.hasOwnProperty("Description")) + this.Description = json_obj.Description; + if (json_obj.hasOwnProperty("Symbol")) + this.Symbol = json_obj.Symbol; + if (json_obj.hasOwnProperty("Precision")) + this.Precision = json_obj.Precision; + if (json_obj.hasOwnProperty("Type")) + this.Type = json_obj.Type; + if (json_obj.hasOwnProperty("AlternateId")) + this.AlternateId = json_obj.AlternateId; + } + isSecurity() { + var empty_account = new Security(); + return this.SecurityId != empty_account.SecurityId || + this.Type != empty_account.Type; + } } const AccountType = { @@ -154,101 +151,99 @@ for (var type in AccountType) { } } -function Account() { - this.AccountId = -1; - this.UserId = -1; - this.SecurityId = -1; - this.ParentAccountId = -1; - this.Type = -1; - this.Name = ""; +class Account { + constructor() { + this.AccountId = -1; + this.UserId = -1; + this.SecurityId = -1; + this.ParentAccountId = -1; + this.Type = -1; + this.Name = ""; - this.OFXURL = ""; - this.OFXORG = ""; - this.OFXFID = ""; - this.OFXUser = ""; - this.OFXBankID = ""; - this.OFXAcctID = ""; - this.OFXAcctType = ""; - this.OFXClientUID = ""; - this.OFXAppID = ""; - this.OFXAppVer = ""; - this.OFXVersion = ""; - this.OFXNoIndent = false -} + this.OFXURL = ""; + this.OFXORG = ""; + this.OFXFID = ""; + this.OFXUser = ""; + this.OFXBankID = ""; + this.OFXAcctID = ""; + this.OFXAcctType = ""; + this.OFXClientUID = ""; + this.OFXAppID = ""; + this.OFXAppVer = ""; + this.OFXVersion = ""; + this.OFXNoIndent = false + } + toJSON() { + var json_obj = {}; + json_obj.AccountId = this.AccountId; + json_obj.UserId = this.UserId; + json_obj.SecurityId = this.SecurityId; + json_obj.ParentAccountId = this.ParentAccountId; + json_obj.Type = this.Type; + json_obj.Name = this.Name; + json_obj.OFXURL = this.OFXURL; + json_obj.OFXORG = this.OFXORG; + json_obj.OFXFID = this.OFXFID; + json_obj.OFXUser = this.OFXUser; + json_obj.OFXBankID = this.OFXBankID; + json_obj.OFXAcctID = this.OFXAcctID; + json_obj.OFXAcctType = this.OFXAcctType; + json_obj.OFXClientUID = this.OFXClientUID; + json_obj.OFXAppID = this.OFXAppID; + json_obj.OFXAppVer = this.OFXAppVer; + json_obj.OFXVersion = this.OFXVersion; + json_obj.OFXNoIndent = this.OFXNoIndent; + return JSON.stringify(json_obj); + } + fromJSON(json_input) { + var json_obj = getJSONObj(json_input); -Account.prototype.toJSON = function() { - var json_obj = {}; - json_obj.AccountId = this.AccountId; - json_obj.UserId = this.UserId; - json_obj.SecurityId = this.SecurityId; - json_obj.ParentAccountId = this.ParentAccountId; - json_obj.Type = this.Type; - json_obj.Name = this.Name; - json_obj.OFXURL = this.OFXURL; - json_obj.OFXORG = this.OFXORG; - json_obj.OFXFID = this.OFXFID; - json_obj.OFXUser = this.OFXUser; - json_obj.OFXBankID = this.OFXBankID; - json_obj.OFXAcctID = this.OFXAcctID; - json_obj.OFXAcctType = this.OFXAcctType; - json_obj.OFXClientUID = this.OFXClientUID; - json_obj.OFXAppID = this.OFXAppID; - json_obj.OFXAppVer = this.OFXAppVer; - json_obj.OFXVersion = this.OFXVersion; - json_obj.OFXNoIndent = this.OFXNoIndent; - return JSON.stringify(json_obj); -} - -Account.prototype.fromJSON = function(json_input) { - var json_obj = getJSONObj(json_input); - - if (json_obj.hasOwnProperty("AccountId")) - this.AccountId = json_obj.AccountId; - if (json_obj.hasOwnProperty("UserId")) - this.UserId = json_obj.UserId; - if (json_obj.hasOwnProperty("SecurityId")) - this.SecurityId = json_obj.SecurityId; - if (json_obj.hasOwnProperty("ParentAccountId")) - this.ParentAccountId = json_obj.ParentAccountId; - if (json_obj.hasOwnProperty("Type")) - this.Type = json_obj.Type; - if (json_obj.hasOwnProperty("Name")) - this.Name = json_obj.Name; - if (json_obj.hasOwnProperty("OFXURL")) - this.OFXURL = json_obj.OFXURL; - if (json_obj.hasOwnProperty("OFXORG")) - this.OFXORG = json_obj.OFXORG; - if (json_obj.hasOwnProperty("OFXFID")) - this.OFXFID = json_obj.OFXFID; - if (json_obj.hasOwnProperty("OFXUser")) - this.OFXUser = json_obj.OFXUser; - if (json_obj.hasOwnProperty("OFXBankID")) - this.OFXBankID = json_obj.OFXBankID; - if (json_obj.hasOwnProperty("OFXAcctID")) - this.OFXAcctID = json_obj.OFXAcctID; - if (json_obj.hasOwnProperty("OFXAcctType")) - this.OFXAcctType = json_obj.OFXAcctType; - if (json_obj.hasOwnProperty("OFXClientUID")) - this.OFXClientUID = json_obj.OFXClientUID; - if (json_obj.hasOwnProperty("OFXAppID")) - this.OFXAppID = json_obj.OFXAppID; - if (json_obj.hasOwnProperty("OFXAppVer")) - this.OFXAppVer = json_obj.OFXAppVer; - if (json_obj.hasOwnProperty("OFXVersion")) - this.OFXVersion = json_obj.OFXVersion; - if (json_obj.hasOwnProperty("OFXNoIndent")) - this.OFXNoIndent = json_obj.OFXNoIndent; -} - -Account.prototype.isAccount = function() { - var empty_account = new Account(); - return this.AccountId != empty_account.AccountId || - this.UserId != empty_account.UserId; -} - -Account.prototype.isRootAccount = function() { - var empty_account = new Account(); - return this.ParentAccountId == empty_account.ParentAccountId; + if (json_obj.hasOwnProperty("AccountId")) + this.AccountId = json_obj.AccountId; + if (json_obj.hasOwnProperty("UserId")) + this.UserId = json_obj.UserId; + if (json_obj.hasOwnProperty("SecurityId")) + this.SecurityId = json_obj.SecurityId; + if (json_obj.hasOwnProperty("ParentAccountId")) + this.ParentAccountId = json_obj.ParentAccountId; + if (json_obj.hasOwnProperty("Type")) + this.Type = json_obj.Type; + if (json_obj.hasOwnProperty("Name")) + this.Name = json_obj.Name; + if (json_obj.hasOwnProperty("OFXURL")) + this.OFXURL = json_obj.OFXURL; + if (json_obj.hasOwnProperty("OFXORG")) + this.OFXORG = json_obj.OFXORG; + if (json_obj.hasOwnProperty("OFXFID")) + this.OFXFID = json_obj.OFXFID; + if (json_obj.hasOwnProperty("OFXUser")) + this.OFXUser = json_obj.OFXUser; + if (json_obj.hasOwnProperty("OFXBankID")) + this.OFXBankID = json_obj.OFXBankID; + if (json_obj.hasOwnProperty("OFXAcctID")) + this.OFXAcctID = json_obj.OFXAcctID; + if (json_obj.hasOwnProperty("OFXAcctType")) + this.OFXAcctType = json_obj.OFXAcctType; + if (json_obj.hasOwnProperty("OFXClientUID")) + this.OFXClientUID = json_obj.OFXClientUID; + if (json_obj.hasOwnProperty("OFXAppID")) + this.OFXAppID = json_obj.OFXAppID; + if (json_obj.hasOwnProperty("OFXAppVer")) + this.OFXAppVer = json_obj.OFXAppVer; + if (json_obj.hasOwnProperty("OFXVersion")) + this.OFXVersion = json_obj.OFXVersion; + if (json_obj.hasOwnProperty("OFXNoIndent")) + this.OFXNoIndent = json_obj.OFXNoIndent; + } + isAccount() { + var empty_account = new Account(); + return this.AccountId != empty_account.AccountId || + this.UserId != empty_account.UserId; + } + isRootAccount() { + var empty_account = new Account(); + return this.ParentAccountId == empty_account.ParentAccountId; + } } const SplitStatus = { @@ -271,324 +266,315 @@ for (var status in SplitStatus) { } } -function Split() { - this.SplitId = -1; - this.TransactionId = -1; - this.AccountId = -1; - this.SecurityId = -1; - this.Status = -1; - this.Number = ""; - this.Memo = ""; - this.Amount = new Big(0.0); - this.Debit = false; +class Split { + constructor() { + this.SplitId = -1; + this.TransactionId = -1; + this.AccountId = -1; + this.SecurityId = -1; + this.Status = -1; + this.Number = ""; + this.Memo = ""; + this.Amount = new Big(0.0); + this.Debit = false; + } + toJSONobj() { + var json_obj = {}; + json_obj.SplitId = this.SplitId; + json_obj.TransactionId = this.TransactionId; + json_obj.AccountId = this.AccountId; + json_obj.SecurityId = this.SecurityId; + json_obj.Status = this.Status; + json_obj.Number = this.Number; + json_obj.Memo = this.Memo; + json_obj.Amount = this.Amount.toFixed(); + json_obj.Debit = this.Debit; + return json_obj; + } + fromJSONobj(json_obj) { + if (json_obj.hasOwnProperty("SplitId")) + this.SplitId = json_obj.SplitId; + if (json_obj.hasOwnProperty("TransactionId")) + this.TransactionId = json_obj.TransactionId; + if (json_obj.hasOwnProperty("AccountId")) + this.AccountId = json_obj.AccountId; + if (json_obj.hasOwnProperty("SecurityId")) + this.SecurityId = json_obj.SecurityId; + if (json_obj.hasOwnProperty("Status")) + this.Status = json_obj.Status; + if (json_obj.hasOwnProperty("Number")) + this.Number = json_obj.Number; + if (json_obj.hasOwnProperty("Memo")) + this.Memo = json_obj.Memo; + if (json_obj.hasOwnProperty("Amount")) + this.Amount = new Big(json_obj.Amount); + if (json_obj.hasOwnProperty("Debit")) + this.Debit = json_obj.Debit; + } + isSplit() { + var empty_split = new Split(); + return this.SplitId != empty_split.SplitId || + this.TransactionId != empty_split.TransactionId || + this.AccountId != empty_split.AccountId || + this.SecurityId != empty_split.SecurityId; + } } -Split.prototype.toJSONobj = function() { - var json_obj = {}; - json_obj.SplitId = this.SplitId; - json_obj.TransactionId = this.TransactionId; - json_obj.AccountId = this.AccountId; - json_obj.SecurityId = this.SecurityId; - json_obj.Status = this.Status; - json_obj.Number = this.Number; - json_obj.Memo = this.Memo; - json_obj.Amount = this.Amount.toFixed(); - json_obj.Debit = this.Debit; - return json_obj; -} +class Transaction { + constructor() { + this.TransactionId = -1; + this.UserId = -1; + this.Description = ""; + this.Date = new Date(); + this.Splits = []; + } + toJSON() { + var json_obj = {}; + json_obj.TransactionId = this.TransactionId; + json_obj.UserId = this.UserId; + json_obj.Description = this.Description; + json_obj.Date = this.Date.toJSON(); + json_obj.Splits = []; + for (var i = 0; i < this.Splits.length; i++) + json_obj.Splits.push(this.Splits[i].toJSONobj()); + return JSON.stringify(json_obj); + } + fromJSON(json_input) { + var json_obj = getJSONObj(json_input); -Split.prototype.fromJSONobj = function(json_obj) { - if (json_obj.hasOwnProperty("SplitId")) - this.SplitId = json_obj.SplitId; - if (json_obj.hasOwnProperty("TransactionId")) - this.TransactionId = json_obj.TransactionId; - if (json_obj.hasOwnProperty("AccountId")) - this.AccountId = json_obj.AccountId; - if (json_obj.hasOwnProperty("SecurityId")) - this.SecurityId = json_obj.SecurityId; - if (json_obj.hasOwnProperty("Status")) - this.Status = json_obj.Status; - if (json_obj.hasOwnProperty("Number")) - this.Number = json_obj.Number; - if (json_obj.hasOwnProperty("Memo")) - this.Memo = json_obj.Memo; - if (json_obj.hasOwnProperty("Amount")) - this.Amount = new Big(json_obj.Amount); - if (json_obj.hasOwnProperty("Debit")) - this.Debit = json_obj.Debit; -} - -Split.prototype.isSplit = function() { - var empty_split = new Split(); - return this.SplitId != empty_split.SplitId || - this.TransactionId != empty_split.TransactionId || - this.AccountId != empty_split.AccountId || - this.SecurityId != empty_split.SecurityId; -} - -function Transaction() { - this.TransactionId = -1; - this.UserId = -1; - this.Description = ""; - this.Date = new Date(); - this.Splits = []; -} - -Transaction.prototype.toJSON = function() { - var json_obj = {}; - json_obj.TransactionId = this.TransactionId; - json_obj.UserId = this.UserId; - json_obj.Description = this.Description; - json_obj.Date = this.Date.toJSON(); - json_obj.Splits = []; - for (var i = 0; i < this.Splits.length; i++) - json_obj.Splits.push(this.Splits[i].toJSONobj()); - return JSON.stringify(json_obj); -} - -Transaction.prototype.fromJSON = function(json_input) { - var json_obj = getJSONObj(json_input); - - if (json_obj.hasOwnProperty("TransactionId")) - this.TransactionId = json_obj.TransactionId; - if (json_obj.hasOwnProperty("UserId")) - this.UserId = json_obj.UserId; - if (json_obj.hasOwnProperty("Description")) - this.Description = json_obj.Description; - if (json_obj.hasOwnProperty("Date")) { - this.Date = json_obj.Date - if (typeof this.Date === 'string') { - var t = Date.parse(this.Date); - if (t) - this.Date = new Date(t); - else + if (json_obj.hasOwnProperty("TransactionId")) + this.TransactionId = json_obj.TransactionId; + if (json_obj.hasOwnProperty("UserId")) + this.UserId = json_obj.UserId; + if (json_obj.hasOwnProperty("Description")) + this.Description = json_obj.Description; + if (json_obj.hasOwnProperty("Date")) { + this.Date = json_obj.Date + if (typeof this.Date === 'string') { + var t = Date.parse(this.Date); + if (t) + this.Date = new Date(t); + else + this.Date = new Date(0); + } else this.Date = new Date(0); - } else - this.Date = new Date(0); - } - if (json_obj.hasOwnProperty("Splits")) { - for (var i = 0; i < json_obj.Splits.length; i++) { - var s = new Split(); - s.fromJSONobj(json_obj.Splits[i]); - this.Splits.push(s); + } + if (json_obj.hasOwnProperty("Splits")) { + for (var i = 0; i < json_obj.Splits.length; i++) { + var s = new Split(); + s.fromJSONobj(json_obj.Splits[i]); + this.Splits.push(s); + } } } -} - -Transaction.prototype.isTransaction = function() { - var empty_transaction = new Transaction(); - return this.TransactionId != empty_transaction.TransactionId || - this.UserId != empty_transaction.UserId; -} - -Transaction.prototype.deepCopy = function() { - var t = new Transaction(); - t.fromJSON(this.toJSON()); - return t; -} - -Transaction.prototype.imbalancedSplitSecurities = function(account_map) { - // Return a list of SecurityIDs for those securities that aren't balanced - // in this transaction's splits. If a split's AccountId is invalid, that - // split is ignored, so those must be checked elsewhere - var splitBalances = {}; - const emptySplit = new Split(); - for (var i = 0; i < this.Splits.length; i++) { - split = this.Splits[i]; - var securityId = -1; - if (split.AccountId != emptySplit.AccountId) { - securityId = account_map[split.AccountId].SecurityId; - } else if (split.SecurityId != emptySplit.SecurityId) { - securityId = split.SecurityId; - } else { - continue; + isTransaction() { + var empty_transaction = new Transaction(); + return this.TransactionId != empty_transaction.TransactionId || + this.UserId != empty_transaction.UserId; + } + deepCopy() { + var t = new Transaction(); + t.fromJSON(this.toJSON()); + return t; + } + imbalancedSplitSecurities(account_map) { + // Return a list of SecurityIDs for those securities that aren't balanced + // in this transaction's splits. If a split's AccountId is invalid, that + // split is ignored, so those must be checked elsewhere + var splitBalances = {}; + const emptySplit = new Split(); + for (var i = 0; i < this.Splits.length; i++) { + var split = this.Splits[i]; + var securityId = -1; + if (split.AccountId != emptySplit.AccountId) { + securityId = account_map[split.AccountId].SecurityId; + } else if (split.SecurityId != emptySplit.SecurityId) { + securityId = split.SecurityId; + } else { + continue; + } + if (securityId in splitBalances) { + splitBalances[securityId] = split.Amount.plus(splitBalances[securityId]); + } else { + splitBalances[securityId] = split.Amount.plus(0); + } } - if (securityId in splitBalances) { - splitBalances[securityId] = split.Amount.plus(splitBalances[securityId]); - } else { - splitBalances[securityId] = split.Amount.plus(0); + var imbalancedIDs = []; + for (var id in splitBalances) { + if (!splitBalances[id].eq(0)) { + imbalancedIDs.push(id); + } + } + return imbalancedIDs; + } +} + +class Error { + constructor() { + this.ErrorId = -1; + this.ErrorString = ""; + } + toJSON() { + var json_obj = {}; + json_obj.ErrorId = this.ErrorId; + json_obj.ErrorString = this.ErrorString; + return JSON.stringify(json_obj); + } + fromJSON(json_input) { + var json_obj = getJSONObj(json_input); + + if (json_obj.hasOwnProperty("ErrorId")) + this.ErrorId = json_obj.ErrorId; + if (json_obj.hasOwnProperty("ErrorString")) + this.ErrorString = json_obj.ErrorString; + } + isError() { + var empty_error = new Error(); + return this.ErrorId != empty_error.ErrorId || + this.ErrorString != empty_error.ErrorString; + } +} + +class Series { + constructor() { + this.Values = []; + this.Series = {}; + } + toJSONobj() { + var json_obj = {}; + json_obj.Values = this.Values; + json_obj.Series = {}; + for (var child in this.Series) { + if (this.Series.hasOwnProperty(child)) + json_obj.Series[child] = this.Series[child].toJSONobj(); + } + return json_obj; + } + fromJSONobj(json_obj) { + if (json_obj.hasOwnProperty("Values")) + this.Values = json_obj.Values; + if (json_obj.hasOwnProperty("Series")) { + for (var child in json_obj.Series) { + if (json_obj.Series.hasOwnProperty(child)) + this.Series[child] = new Series(); + this.Series[child].fromJSONobj(json_obj.Series[child]); + } } } - var imbalancedIDs = []; - for (var id in splitBalances) { - if (!splitBalances[id].eq(0)) { - imbalancedIDs.push(id); + mapReduceChildren(mapFn, reduceFn) { + var children = {} + for (var child in this.Series) { + if (this.Series.hasOwnProperty(child)) + children[child] = this.Series[child].mapReduce(mapFn, reduceFn); + } + return children; + } + mapReduce(mapFn, reduceFn) { + var childValues = []; + if (mapFn) + childValues.push(this.Values.map(mapFn)); + else + childValues.push(this.Values.slice()); + + for (var child in this.Series) { + if (this.Series.hasOwnProperty(child)) + childValues.push(this.Series[child].mapReduce(mapFn, reduceFn)); + } + + var reducedValues = []; + if (reduceFn && childValues.length > 0 && childValues[0].length > 0) { + for (var j = 0; j < childValues[0].length; j++) { + reducedValues.push(childValues.reduce(function(accum, curr, i, arr) { + return reduceFn(accum, arr[i][j]); + }, 0)); + } + } + + return reducedValues; + } +} + +class Report { + constructor() { + this.ReportId = ""; + this.Title = ""; + this.Subtitle = ""; + this.XAxisLabel = ""; + this.YAxisLabel = ""; + this.Labels = []; + this.Series = {}; + this.FlattenedSeries = {}; + } + static topLevelAccountName() { + return "(top level)" + } + toJSON() { + 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); + } + fromJSON(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]); + } } } - return imbalancedIDs; -} - -function Error() { - this.ErrorId = -1; - this.ErrorString = ""; -} - -Error.prototype.toJSON = function() { - var json_obj = {}; - json_obj.ErrorId = this.ErrorId; - json_obj.ErrorString = this.ErrorString; - return JSON.stringify(json_obj); -} - -Error.prototype.fromJSON = function(json_input) { - var json_obj = getJSONObj(json_input); - - if (json_obj.hasOwnProperty("ErrorId")) - this.ErrorId = json_obj.ErrorId; - if (json_obj.hasOwnProperty("ErrorString")) - this.ErrorString = json_obj.ErrorString; -} - -Error.prototype.isError = function() { - var empty_error = new Error(); - return this.ErrorId != empty_error.ErrorId || - this.ErrorString != empty_error.ErrorString; -} - - -function Series() { - this.Values = []; - this.Series = {}; -} - -Series.prototype.toJSONobj = function() { - var json_obj = {}; - json_obj.Values = this.Values; - json_obj.Series = {}; - for (var child in this.Series) { - if (this.Series.hasOwnProperty(child)) - json_obj.Series[child] = this.Series[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("Series")) { - for (var child in json_obj.Series) { - if (json_obj.Series.hasOwnProperty(child)) - this.Series[child] = new Series(); - this.Series[child].fromJSONobj(json_obj.Series[child]); + mapReduceChildren(mapFn, reduceFn) { + var series = {} + for (var child in this.Series) { + if (this.Series.hasOwnProperty(child)) + series[child] = this.Series[child].mapReduce(mapFn, reduceFn); } + return series; + } + mapReduceSeries(mapFn, reduceFn) { + return this.mapReduceChildren(mapFn, reduceFn); } } -Series.prototype.mapReduceChildren = function(mapFn, reduceFn) { - var children = {} - for (var child in this.Series) { - if (this.Series.hasOwnProperty(child)) - children[child] = this.Series[child].mapReduce(mapFn, reduceFn); +class OFXDownload { + constructor() { + this.OFXPassword = ""; + this.StartDate = new Date(); + this.EndDate = new Date(); } - return children; -} - -Series.prototype.mapReduce = function(mapFn, reduceFn) { - var childValues = []; - if (mapFn) - childValues.push(this.Values.map(mapFn)); - else - childValues.push(this.Values.slice()); - - for (var child in this.Series) { - if (this.Series.hasOwnProperty(child)) - childValues.push(this.Series[child].mapReduce(mapFn, reduceFn)); + toJSON() { + var json_obj = {}; + json_obj.OFXPassword = this.OFXPassword; + json_obj.StartDate = this.StartDate.toJSON(); + json_obj.EndDate = this.EndDate.toJSON(); + return JSON.stringify(json_obj); } - - var reducedValues = []; - if (reduceFn && childValues.length > 0 && childValues[0].length > 0) { - for (var j = 0; j < childValues[0].length; j++) { - reducedValues.push(childValues.reduce(function(accum, curr, i, arr) { - return reduceFn(accum, arr[i][j]); - }, 0)); - } - } - - return reducedValues; -} - -function Report() { - this.ReportId = ""; - this.Title = ""; - this.Subtitle = ""; - this.XAxisLabel = ""; - this.YAxisLabel = ""; - this.Labels = []; - this.Series = {}; - this.FlattenedSeries = {}; -} - -Report.prototype.topLevelAccountName = "(top level)"; - -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]); - } - } -} - -Report.prototype.mapReduceChildren = function(mapFn, reduceFn) { - var series = {} - for (var child in this.Series) { - if (this.Series.hasOwnProperty(child)) - series[child] = this.Series[child].mapReduce(mapFn, reduceFn); - } - return series; -} - -Report.prototype.mapReduceSeries = function(mapFn, reduceFn) { - return this.mapReduceChildren(mapFn, reduceFn); -} - -function OFXDownload() { - this.OFXPassword = ""; - this.StartDate = new Date(); - this.EndDate = new Date(); -} - -OFXDownload.prototype.toJSON = function() { - var json_obj = {}; - json_obj.OFXPassword = this.OFXPassword; - json_obj.StartDate = this.StartDate.toJSON(); - json_obj.EndDate = this.EndDate.toJSON(); - return JSON.stringify(json_obj); } module.exports = models = { - // Classes User: User, Session: Session,