1
0
mirror of https://github.com/aclindsa/moneygo.git synced 2024-10-31 16:00:05 -04:00

Use ES6 classes instead of React.createClass and editing prototypes

This commit is contained in:
Aaron Lindsay 2017-06-07 19:12:53 -04:00
parent 29614c38c7
commit a08131b1ba
13 changed files with 1207 additions and 1074 deletions

View File

@ -87,7 +87,7 @@ function select(report, seriesTraversal) {
// Add back in any values from the current level // Add back in any values from the current level
if (series.hasOwnProperty('Values')) if (series.hasOwnProperty('Values'))
flattenedSeries[report.topLevelAccountName] = series.Values; flattenedSeries[Report.topLevelAccountName()] = series.Values;
var flattenedReport = new Report(); var flattenedReport = new Report();

View File

@ -4,24 +4,25 @@ var Combobox = require('react-widgets').Combobox;
var getAccountDisplayList = require('../utils').getAccountDisplayList; var getAccountDisplayList = require('../utils').getAccountDisplayList;
module.exports = React.createClass({ class AccountCombobox extends React.Component {
displayName: "AccountCombobox", constructor() {
getDefaultProps: function() { super();
return { this.onAccountChange = this.handleAccountChange.bind(this);
this.defaultProps = {
includeRoot: true, includeRoot: true,
disabled: false, disabled: false,
rootName: "New Top-level Account" rootName: "New Top-level Account"
}; }
}, }
handleAccountChange: function(account) { handleAccountChange(account) {
if (this.props.onChange != null && if (this.props.onChange != null &&
account.hasOwnProperty('AccountId') && account.hasOwnProperty('AccountId') &&
(this.props.accounts.hasOwnProperty([account.AccountId]) || (this.props.accounts.hasOwnProperty([account.AccountId]) ||
account.AccountId == -1)) { account.AccountId == -1)) {
this.props.onChange(account) this.props.onChange(account)
} }
}, }
render: function() { render() {
var accounts = getAccountDisplayList(this.props.accounts, this.props.accountChildren, this.props.includeRoot, this.props.rootName); var accounts = getAccountDisplayList(this.props.accounts, this.props.accountChildren, this.props.includeRoot, this.props.rootName);
var className = ""; var className = "";
if (this.props.className) if (this.props.className)
@ -32,7 +33,7 @@ module.exports = React.createClass({
valueField='AccountId' valueField='AccountId'
textField='Name' textField='Name'
defaultValue={this.props.value} defaultValue={this.props.value}
onChange={this.handleAccountChange} onChange={this.onAccountChange}
ref="account" ref="account"
disabled={this.props.disabled} disabled={this.props.disabled}
suggest suggest
@ -40,4 +41,6 @@ module.exports = React.createClass({
className={className} /> className={className} />
); );
} }
}); }
module.exports = AccountCombobox;

View File

@ -46,8 +46,12 @@ var getAccountDisplayName = require('../utils').getAccountDisplayName;
var AccountCombobox = require('./AccountCombobox'); var AccountCombobox = require('./AccountCombobox');
const TransactionRow = React.createClass({ class TransactionRow extends React.Component {
handleClick: function(e) { constructor() {
super();
this.onClick = this.handleClick.bind(this);
}
handleClick(e) {
const refs = ["date", "number", "description", "account", "status", "amount"]; const refs = ["date", "number", "description", "account", "status", "amount"];
for (var ref in refs) { for (var ref in refs) {
if (this.refs[refs[ref]] == e.target) { if (this.refs[refs[ref]] == e.target) {
@ -55,8 +59,8 @@ const TransactionRow = React.createClass({
return; return;
} }
} }
}, }
render: function() { render() {
var date = this.props.transaction.Date; var date = this.props.transaction.Date;
var dateString = date.getFullYear() + "/" + (date.getMonth()+1) + "/" + date.getDate(); var dateString = date.getFullYear() + "/" + (date.getMonth()+1) + "/" + date.getDate();
var number = "" var number = ""
@ -97,19 +101,25 @@ const TransactionRow = React.createClass({
return ( return (
<tr> <tr>
<td ref="date" onClick={this.handleClick}>{dateString}</td> <td ref="date" onClick={this.onClick}>{dateString}</td>
<td ref="number" onClick={this.handleClick}>{number}</td> <td ref="number" onClick={this.onClick}>{number}</td>
<td ref="description" onClick={this.handleClick}>{this.props.transaction.Description}</td> <td ref="description" onClick={this.onClick}>{this.props.transaction.Description}</td>
<td ref="account" onClick={this.handleClick}>{accountName}</td> <td ref="account" onClick={this.onClick}>{accountName}</td>
<td ref="status" onClick={this.handleClick}>{status}</td> <td ref="status" onClick={this.onClick}>{status}</td>
<td ref="amount" onClick={this.handleClick}>{amount}</td> <td ref="amount" onClick={this.onClick}>{amount}</td>
<td>{balance}</td> <td>{balance}</td>
</tr>); </tr>);
} }
}); }
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 // Ensure we can edit this without screwing up other copies of it
var a; var a;
if (props.security) if (props.security)
@ -121,21 +131,23 @@ const AmountInput = React.createClass({
LastGoodAmount: a, LastGoodAmount: a,
Amount: a Amount: a
}; };
}, }
getInitialState: function() { constructor() {
return this._getInitialState(this.props); super();
}, this.onChange = this.handleChange.bind(this);
componentWillReceiveProps: function(nextProps) { this.state = this.getInitialState();
}
componentWillReceiveProps(nextProps) {
if ((!nextProps.value.eq(this.props.value) && if ((!nextProps.value.eq(this.props.value) &&
!nextProps.value.eq(this.getValue())) || !nextProps.value.eq(this.getValue())) ||
nextProps.security !== this.props.security) { nextProps.security !== this.props.security) {
this.setState(this._getInitialState(nextProps)); this.setState(this.getInitialState(nextProps));
} }
}, }
componentDidMount: function() { componentDidMount() {
ReactDOM.findDOMNode(this.refs.amount).onblur = this.onBlur; ReactDOM.findDOMNode(this.refs.amount).onblur = this.handleBlur.bind(this);
}, }
onBlur: function() { handleBlur() {
var a; var a;
if (this.props.security) if (this.props.security)
a = (new Big(this.getValue())).toFixed(this.props.security.Precision); a = (new Big(this.getValue())).toFixed(this.props.security.Precision);
@ -144,13 +156,13 @@ const AmountInput = React.createClass({
this.setState({ this.setState({
Amount: a Amount: a
}); });
}, }
onChange: function() { handleChange() {
this.setState({Amount: ReactDOM.findDOMNode(this.refs.amount).value}); this.setState({Amount: ReactDOM.findDOMNode(this.refs.amount).value});
if (this.props.onChange) if (this.props.onChange)
this.props.onChange(); this.props.onChange();
}, }
getValue: function() { getValue() {
try { try {
var value = ReactDOM.findDOMNode(this.refs.amount).value; var value = ReactDOM.findDOMNode(this.refs.amount).value;
var ret = new Big(value); var ret = new Big(value);
@ -159,8 +171,8 @@ const AmountInput = React.createClass({
} catch(err) { } catch(err) {
return new Big(this.state.LastGoodAmount); return new Big(this.state.LastGoodAmount);
} }
}, }
render: function() { render() {
var symbol = "?"; var symbol = "?";
if (this.props.security) if (this.props.security)
symbol = this.props.security.Symbol; symbol = this.props.security.Symbol;
@ -177,37 +189,54 @@ const AmountInput = React.createClass({
</FormGroup> </FormGroup>
); );
} }
}); }
const AddEditTransactionModal = React.createClass({ class AddEditTransactionModal extends React.Component {
_getInitialState: function(props) { getInitialState(props) {
// Ensure we can edit this without screwing up other copies of it // Ensure we can edit this without screwing up other copies of it
if (props)
var t = props.transaction.deepCopy(); var t = props.transaction.deepCopy();
else
var t = new Transaction();
return { return {
errorAlert: [], errorAlert: [],
transaction: t transaction: t
}; };
},
getInitialState: function() {
return this._getInitialState(this.props);
},
componentWillReceiveProps: function(nextProps) {
if (nextProps.show && !this.props.show) {
this.setState(this._getInitialState(nextProps));
} }
}, constructor() {
handleCancel: function() { 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));
}
}
handleCancel() {
if (this.props.onCancel != null) if (this.props.onCancel != null)
this.props.onCancel(); this.props.onCancel();
}, }
handleDescriptionChange: function() { handleDescriptionChange() {
this.setState({ this.setState({
transaction: react_update(this.state.transaction, { transaction: react_update(this.state.transaction, {
Description: {$set: ReactDOM.findDOMNode(this.refs.description).value} Description: {$set: ReactDOM.findDOMNode(this.refs.description).value}
}) })
}); });
}, }
handleDateChange: function(date, string) { handleDateChange(date, string) {
if (date == null) if (date == null)
return; return;
this.setState({ this.setState({
@ -215,8 +244,8 @@ const AddEditTransactionModal = React.createClass({
Date: {$set: date} Date: {$set: date}
}) })
}); });
}, }
handleAddSplit: function() { handleAddSplit() {
var split = new Split(); var split = new Split();
split.Status = SplitStatus.Entered; split.Status = SplitStatus.Entered;
this.setState({ this.setState({
@ -224,15 +253,15 @@ const AddEditTransactionModal = React.createClass({
Splits: {$push: [split]} Splits: {$push: [split]}
}) })
}); });
}, }
handleDeleteSplit: function(split) { handleDeleteSplit(split) {
this.setState({ this.setState({
transaction: react_update(this.state.transaction, { transaction: react_update(this.state.transaction, {
Splits: {$splice: [[split, 1]]} Splits: {$splice: [[split, 1]]}
}) })
}); });
}, }
handleUpdateNumber: function(split) { handleUpdateNumber(split) {
var transaction = this.state.transaction; var transaction = this.state.transaction;
transaction.Splits[split] = react_update(transaction.Splits[split], { transaction.Splits[split] = react_update(transaction.Splits[split], {
Number: {$set: ReactDOM.findDOMNode(this.refs['number-'+split]).value} Number: {$set: ReactDOM.findDOMNode(this.refs['number-'+split]).value}
@ -240,8 +269,8 @@ const AddEditTransactionModal = React.createClass({
this.setState({ this.setState({
transaction: transaction transaction: transaction
}); });
}, }
handleUpdateStatus: function(status, split) { handleUpdateStatus(status, split) {
var transaction = this.state.transaction; var transaction = this.state.transaction;
transaction.Splits[split] = react_update(transaction.Splits[split], { transaction.Splits[split] = react_update(transaction.Splits[split], {
Status: {$set: status.StatusId} Status: {$set: status.StatusId}
@ -249,8 +278,8 @@ const AddEditTransactionModal = React.createClass({
this.setState({ this.setState({
transaction: transaction transaction: transaction
}); });
}, }
handleUpdateMemo: function(split) { handleUpdateMemo(split) {
var transaction = this.state.transaction; var transaction = this.state.transaction;
transaction.Splits[split] = react_update(transaction.Splits[split], { transaction.Splits[split] = react_update(transaction.Splits[split], {
Memo: {$set: ReactDOM.findDOMNode(this.refs['memo-'+split]).value} Memo: {$set: ReactDOM.findDOMNode(this.refs['memo-'+split]).value}
@ -258,8 +287,8 @@ const AddEditTransactionModal = React.createClass({
this.setState({ this.setState({
transaction: transaction transaction: transaction
}); });
}, }
handleUpdateAccount: function(account, split) { handleUpdateAccount(account, split) {
var transaction = this.state.transaction; var transaction = this.state.transaction;
transaction.Splits[split] = react_update(transaction.Splits[split], { transaction.Splits[split] = react_update(transaction.Splits[split], {
SecurityId: {$set: -1}, SecurityId: {$set: -1},
@ -268,8 +297,8 @@ const AddEditTransactionModal = React.createClass({
this.setState({ this.setState({
transaction: transaction transaction: transaction
}); });
}, }
handleUpdateAmount: function(split) { handleUpdateAmount(split) {
var transaction = this.state.transaction; var transaction = this.state.transaction;
transaction.Splits[split] = react_update(transaction.Splits[split], { transaction.Splits[split] = react_update(transaction.Splits[split], {
Amount: {$set: new Big(this.refs['amount-'+split].getValue())} Amount: {$set: new Big(this.refs['amount-'+split].getValue())}
@ -277,8 +306,8 @@ const AddEditTransactionModal = React.createClass({
this.setState({ this.setState({
transaction: transaction transaction: transaction
}); });
}, }
handleSubmit: function() { handleSubmit() {
var errorString = "" var errorString = ""
var imbalancedSecurityList = this.state.transaction.imbalancedSplitSecurities(this.props.accounts); var imbalancedSecurityList = this.state.transaction.imbalancedSplitSecurities(this.props.accounts);
if (imbalancedSecurityList.length > 0) if (imbalancedSecurityList.length > 0)
@ -299,19 +328,19 @@ const AddEditTransactionModal = React.createClass({
if (this.props.onSubmit != null) if (this.props.onSubmit != null)
this.props.onSubmit(this.state.transaction); this.props.onSubmit(this.state.transaction);
}, }
handleDelete: function() { handleDelete() {
if (this.props.onDelete != null) if (this.props.onDelete != null)
this.props.onDelete(this.state.transaction); this.props.onDelete(this.state.transaction);
}, }
render: function() { render() {
var editing = this.props.transaction != null && this.props.transaction.isTransaction(); var editing = this.props.transaction != null && this.props.transaction.isTransaction();
var headerText = editing ? "Edit" : "Create New"; var headerText = editing ? "Edit" : "Create New";
var buttonText = editing ? "Save Changes" : "Create Transaction"; var buttonText = editing ? "Save Changes" : "Create Transaction";
var deleteButton = []; var deleteButton = [];
if (editing) { if (editing) {
deleteButton = ( deleteButton = (
<Button key={1} onClick={this.handleDelete} bsStyle="danger">Delete Transaction</Button> <Button key={1} onClick={this.onDelete} bsStyle="danger">Delete Transaction</Button>
); );
} }
@ -320,7 +349,7 @@ const AddEditTransactionModal = React.createClass({
for (i = 0; i < imbalancedSecurityList.length; i++) for (i = 0; i < imbalancedSecurityList.length; i++)
imbalancedSecurityMap[imbalancedSecurityList[i]] = i; imbalancedSecurityMap[imbalancedSecurityList[i]] = i;
splits = []; var splits = [];
for (var i = 0; i < this.state.transaction.Splits.length; i++) { for (var i = 0; i < this.state.transaction.Splits.length; i++) {
var self = this; var self = this;
var s = this.state.transaction.Splits[i]; var s = this.state.transaction.Splits[i];
@ -341,27 +370,27 @@ const AddEditTransactionModal = React.createClass({
// Define all closures for calling split-updating functions // Define all closures for calling split-updating functions
var deleteSplitFn = (function() { var deleteSplitFn = (function() {
var j = i; var j = i;
return function() {self.handleDeleteSplit(j);}; return function() {self.onDeleteSplit(j);};
})(); })();
var updateNumberFn = (function() { var updateNumberFn = (function() {
var j = i; var j = i;
return function() {self.handleUpdateNumber(j);}; return function() {self.onUpdateNumber(j);};
})(); })();
var updateStatusFn = (function() { var updateStatusFn = (function() {
var j = i; var j = i;
return function(status) {self.handleUpdateStatus(status, j);}; return function(status) {self.onUpdateStatus(status, j);};
})(); })();
var updateMemoFn = (function() { var updateMemoFn = (function() {
var j = i; var j = i;
return function() {self.handleUpdateMemo(j);}; return function() {self.onUpdateMemo(j);};
})(); })();
var updateAccountFn = (function() { var updateAccountFn = (function() {
var j = i; var j = i;
return function(account) {self.handleUpdateAccount(account, j);}; return function(account) {self.onUpdateAccount(account, j);};
})(); })();
var updateAmountFn = (function() { var updateAmountFn = (function() {
var j = i; var j = i;
return function() {self.handleUpdateAmount(j);}; return function() {self.onUpdateAmount(j);};
})(); })();
var deleteSplitButton = []; var deleteSplitButton = [];
@ -415,20 +444,20 @@ const AddEditTransactionModal = React.createClass({
} }
return ( return (
<Modal show={this.props.show} onHide={this.handleCancel} bsSize="large"> <Modal show={this.props.show} onHide={this.onCancel} bsSize="large">
<Modal.Header closeButton> <Modal.Header closeButton>
<Modal.Title>{headerText} Transaction</Modal.Title> <Modal.Title>{headerText} Transaction</Modal.Title>
</Modal.Header> </Modal.Header>
<Modal.Body> <Modal.Body>
<Form horizontal <Form horizontal
onSubmit={this.handleSubmit}> onSubmit={this.onSubmit}>
<FormGroup> <FormGroup>
<Col componentClass={ControlLabel} xs={2}>Date</Col> <Col componentClass={ControlLabel} xs={2}>Date</Col>
<Col xs={10}> <Col xs={10}>
<DateTimePicker <DateTimePicker
time={false} time={false}
defaultValue={this.state.transaction.Date} defaultValue={this.state.transaction.Date}
onChange={this.handleDateChange} /> onChange={this.onDateChange} />
</Col> </Col>
</FormGroup> </FormGroup>
<FormGroup> <FormGroup>
@ -436,7 +465,7 @@ const AddEditTransactionModal = React.createClass({
<Col xs={10}> <Col xs={10}>
<FormControl type="text" <FormControl type="text"
value={this.state.transaction.Description} value={this.state.transaction.Description}
onChange={this.handleDescriptionChange} onChange={this.onDescriptionChange}
ref="description"/> ref="description"/>
</Col> </Col>
</FormGroup> </FormGroup>
@ -451,7 +480,7 @@ const AddEditTransactionModal = React.createClass({
{splits} {splits}
<Row> <Row>
<span className="col-xs-11"></span> <span className="col-xs-11"></span>
<Col xs={1}><Button onClick={this.handleAddSplit} <Col xs={1}><Button onClick={this.onAddSplit}
bsStyle="success"> bsStyle="success">
<Glyphicon glyph='plus-sign' /></Button></Col> <Glyphicon glyph='plus-sign' /></Button></Col>
</Row> </Row>
@ -461,15 +490,15 @@ const AddEditTransactionModal = React.createClass({
</Modal.Body> </Modal.Body>
<Modal.Footer> <Modal.Footer>
<ButtonGroup> <ButtonGroup>
<Button onClick={this.handleCancel} bsStyle="warning">Cancel</Button> <Button onClick={this.onCancel} bsStyle="warning">Cancel</Button>
{deleteButton} {deleteButton}
<Button onClick={this.handleSubmit} bsStyle="success">{buttonText}</Button> <Button onClick={this.onSubmit} bsStyle="success">{buttonText}</Button>
</ButtonGroup> </ButtonGroup>
</Modal.Footer> </Modal.Footer>
</Modal> </Modal>
); );
} }
}); }
const ImportType = { const ImportType = {
OFX: 1, OFX: 1,
@ -485,8 +514,8 @@ for (var type in ImportType) {
} }
} }
const ImportTransactionsModal = React.createClass({ class ImportTransactionsModal extends React.Component {
getInitialState: function() { getInitialState() {
var startDate = new Date(); var startDate = new Date();
startDate.setMonth(startDate.getMonth() - 1); startDate.setMonth(startDate.getMonth() - 1);
return { return {
@ -496,41 +525,56 @@ const ImportTransactionsModal = React.createClass({
endDate: new Date(), endDate: new Date(),
password: "", password: "",
}; };
}, }
handleCancel: function() { 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()); this.setState(this.getInitialState());
}
}
handleCancel() {
if (this.props.onCancel != null) if (this.props.onCancel != null)
this.props.onCancel(); this.props.onCancel();
}, }
handleImportChange: function() { handleImportChange() {
this.setState({importFile: ReactDOM.findDOMNode(this.refs.importfile).value}); this.setState({importFile: ReactDOM.findDOMNode(this.refs.importfile).value});
}, }
handleTypeChange: function(type) { handleTypeChange(type) {
this.setState({importType: type.TypeId}); this.setState({importType: type.TypeId});
}, }
handlePasswordChange: function() { handlePasswordChange() {
this.setState({password: ReactDOM.findDOMNode(this.refs.password).value}); this.setState({password: ReactDOM.findDOMNode(this.refs.password).value});
}, }
handleStartDateChange: function(date, string) { handleStartDateChange(date, string) {
if (date == null) if (date == null)
return; return;
this.setState({ this.setState({
startDate: date startDate: date
}); });
}, }
handleEndDateChange: function(date, string) { handleEndDateChange(date, string) {
if (date == null) if (date == null)
return; return;
this.setState({ this.setState({
endDate: date endDate: date
}); });
}, }
handleSubmit: function() { handleSubmit() {
this.setState(this.getInitialState());
if (this.props.onSubmit != null) if (this.props.onSubmit != null)
this.props.onSubmit(this.props.account); this.props.onSubmit(this.props.account);
}, }
handleImportTransactions: function() { handleImportTransactions() {
if (this.state.importType == ImportType.OFX) { if (this.state.importType == ImportType.OFX) {
this.props.onImportOFX(this.props.account, this.state.password, this.state.startDate, this.state.endDate); this.props.onImportOFX(this.props.account, this.state.password, this.state.startDate, this.state.endDate);
} else if (this.state.importType == ImportType.OFXFile) { } else if (this.state.importType == ImportType.OFXFile) {
@ -538,8 +582,8 @@ const ImportTransactionsModal = React.createClass({
} else if (this.state.importType == ImportType.Gnucash) { } else if (this.state.importType == ImportType.Gnucash) {
this.props.onImportGnucash(ReactDOM.findDOMNode(this.refs.importfile)); this.props.onImportGnucash(ReactDOM.findDOMNode(this.refs.importfile));
} }
}, }
render: function() { render() {
var accountNameLabel = "Performing global import:" var accountNameLabel = "Performing global import:"
if (this.props.account != null && this.state.importType != ImportType.Gnucash) if (this.props.account != null && this.state.importType != ImportType.Gnucash)
accountNameLabel = "Importing to '" + getAccountDisplayName(this.props.account, this.props.accounts) + "' account:"; accountNameLabel = "Importing to '" + getAccountDisplayName(this.props.account, this.props.accounts) + "' account:";
@ -565,10 +609,10 @@ const ImportTransactionsModal = React.createClass({
var button2 = []; var button2 = [];
if (!this.props.imports.importFinished && !this.props.imports.importFailed) { 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 == ""); var importingDisabled = this.props.imports.importing || (this.state.importType != ImportType.OFX && this.state.importFile == "") || (this.state.importType == ImportType.OFX && this.state.password == "");
button1 = (<Button onClick={this.handleCancel} disabled={this.props.imports.importing} bsStyle="warning">Cancel</Button>); button1 = (<Button onClick={this.onCancel} disabled={this.props.imports.importing} bsStyle="warning">Cancel</Button>);
button2 = (<Button onClick={this.handleImportTransactions} disabled={importingDisabled} bsStyle="success">Import</Button>); button2 = (<Button onClick={this.onImportTransactions} disabled={importingDisabled} bsStyle="success">Import</Button>);
} else { } else {
button1 = (<Button onClick={this.handleSubmit} disabled={this.props.imports.importing} bsStyle="success">OK</Button>); button1 = (<Button onClick={this.onSubmit} disabled={this.props.imports.importing} bsStyle="success">OK</Button>);
} }
var inputDisabled = (this.props.imports.importing || this.props.imports.importFailed || this.props.imports.importFinished) ? true : false; 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} value={this.state.password}
placeholder="Password..." placeholder="Password..."
ref="password" ref="password"
onChange={this.handlePasswordChange} /> onChange={this.onPasswordChange} />
</Col> </Col>
</FormGroup> </FormGroup>
<FormGroup> <FormGroup>
@ -597,7 +641,7 @@ const ImportTransactionsModal = React.createClass({
<DateTimePicker <DateTimePicker
time={false} time={false}
defaultValue={this.state.startDate} defaultValue={this.state.startDate}
onChange={this.handleStartDateChange} /> onChange={this.onStartDateChange} />
</Col> </Col>
</FormGroup> </FormGroup>
<FormGroup> <FormGroup>
@ -606,7 +650,7 @@ const ImportTransactionsModal = React.createClass({
<DateTimePicker <DateTimePicker
time={false} time={false}
defaultValue={this.state.endDate} defaultValue={this.state.endDate}
onChange={this.handleEndDateChange} /> onChange={this.onEndDateChange} />
</Col> </Col>
</FormGroup> </FormGroup>
</div> </div>
@ -620,7 +664,7 @@ const ImportTransactionsModal = React.createClass({
ref="importfile" ref="importfile"
disabled={inputDisabled} disabled={inputDisabled}
value={this.state.importFile} value={this.state.importFile}
onChange={this.handleImportChange} /> onChange={this.onImportChange} />
<HelpBlock>Select a file to upload.</HelpBlock> <HelpBlock>Select a file to upload.</HelpBlock>
</Col> </Col>
</FormGroup> </FormGroup>
@ -628,12 +672,12 @@ const ImportTransactionsModal = React.createClass({
} }
return ( return (
<Modal show={this.props.show} onHide={this.handleCancel}> <Modal show={this.props.show} onHide={this.onCancel}>
<Modal.Header closeButton> <Modal.Header closeButton>
<Modal.Title>Import Transactions</Modal.Title> <Modal.Title>Import Transactions</Modal.Title>
</Modal.Header> </Modal.Header>
<Modal.Body> <Modal.Body>
<Form horizontal onSubmit={this.handleImportTransactions} <Form horizontal onSubmit={this.onImportTransactions}
encType="multipart/form-data" encType="multipart/form-data"
ref="importform"> ref="importform">
<FormGroup> <FormGroup>
@ -648,7 +692,7 @@ const ImportTransactionsModal = React.createClass({
data={ImportTypeList} data={ImportTypeList}
valueField='TypeId' valueField='TypeId'
textField='Name' textField='Name'
onSelect={this.handleTypeChange} onSelect={this.onTypeChange}
defaultValue={this.state.importType} defaultValue={this.state.importType}
disabled={disabledTypes} disabled={disabledTypes}
ref="importtype" /> ref="importtype" />
@ -668,40 +712,47 @@ const ImportTransactionsModal = React.createClass({
</Modal> </Modal>
); );
} }
}); }
module.exports = React.createClass({ class AccountRegister extends React.Component {
displayName: "AccountRegister", constructor() {
getInitialState: function() { super();
return { this.state = {
newTransaction: null, newTransaction: null,
height: 0 height: 0
}; };
}, this.onEditTransaction = this.handleEditTransaction.bind(this);
resize: function() { 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); var div = ReactDOM.findDOMNode(this);
this.setState({height: div.parentElement.clientHeight - 64}); this.setState({height: div.parentElement.clientHeight - 64});
}, }
componentWillReceiveProps: function(nextProps) { componentWillReceiveProps(nextProps) {
if (!nextProps.transactionPage.upToDate && nextProps.selectedAccount != -1) { if (!nextProps.transactionPage.upToDate && nextProps.selectedAccount != -1) {
nextProps.onFetchTransactionPage(nextProps.accounts[nextProps.selectedAccount], nextProps.transactionPage.pageSize, nextProps.transactionPage.page); nextProps.onFetchTransactionPage(nextProps.accounts[nextProps.selectedAccount], nextProps.transactionPage.pageSize, nextProps.transactionPage.page);
} }
}, }
componentDidMount: function() { componentDidMount() {
this.resize(); this.resize();
var self = this; var self = this;
$(window).resize(function() {self.resize();}); $(window).resize(function() {self.resize();});
}, }
handleEditTransaction: function(transaction) { handleEditTransaction(transaction) {
this.props.onSelectTransaction(transaction.TransactionId); this.props.onSelectTransaction(transaction.TransactionId);
}, }
handleEditingCancel: function() { handleEditingCancel() {
this.setState({ this.setState({
newTransaction: null newTransaction: null
}); });
this.props.onUnselectTransaction(); this.props.onUnselectTransaction();
}, }
handleNewTransactionClicked: function() { handleNewTransactionClicked() {
var newTransaction = new Transaction(); var newTransaction = new Transaction();
newTransaction.Date = new Date(); newTransaction.Date = new Date();
newTransaction.Splits.push(new Split()); newTransaction.Splits.push(new Split());
@ -713,14 +764,8 @@ module.exports = React.createClass({
this.setState({ this.setState({
newTransaction: newTransaction newTransaction: newTransaction
}); });
}, }
ajaxError: function(jqXHR, status, error) { handleSelectPage(eventKey) {
var e = new Error();
e.ErrorId = 5;
e.ErrorString = "Request Failed: " + status + error;
this.setState({error: e});
},
handleSelectPage: function(eventKey) {
var newpage = eventKey - 1; var newpage = eventKey - 1;
// Don't do pages that don't make sense // Don't do pages that don't make sense
if (newpage < 0) if (newpage < 0)
@ -732,17 +777,17 @@ module.exports = React.createClass({
this.props.onFetchTransactionPage(this.props.accounts[this.props.selectedAccount], this.props.pageSize, newpage); this.props.onFetchTransactionPage(this.props.accounts[this.props.selectedAccount], this.props.pageSize, newpage);
} }
} }
}, }
handleImportComplete: function() { handleImportComplete() {
this.props.onCloseImportModal(); this.props.onCloseImportModal();
this.props.onFetchAllAccounts(); this.props.onFetchAllAccounts();
this.props.onFetchTransactionPage(this.props.accounts[this.props.selectedAccount], this.props.pageSize, this.props.transactionPage.page); 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.onDeleteTransaction(transaction);
this.props.onUnselectTransaction(); this.props.onUnselectTransaction();
}, }
handleUpdateTransaction: function(transaction) { handleUpdateTransaction(transaction) {
if (transaction.TransactionId != -1) { if (transaction.TransactionId != -1) {
this.props.onUpdateTransaction(transaction); this.props.onUpdateTransaction(transaction);
} else { } else {
@ -752,10 +797,10 @@ module.exports = React.createClass({
this.setState({ this.setState({
newTransaction: null newTransaction: null
}); });
}, }
render: function() { render() {
var name = "Please select an account"; var name = "Please select an account";
register = []; var register = [];
if (this.props.selectedAccount != -1) { if (this.props.selectedAccount != -1) {
name = this.props.accounts[this.props.selectedAccount].Name; name = this.props.accounts[this.props.selectedAccount].Name;
@ -815,9 +860,9 @@ module.exports = React.createClass({
transaction={selectedTransaction} transaction={selectedTransaction}
accounts={this.props.accounts} accounts={this.props.accounts}
accountChildren={this.props.accountChildren} accountChildren={this.props.accountChildren}
onCancel={this.handleEditingCancel} onCancel={this.onEditingCancel}
onSubmit={this.handleUpdateTransaction} onSubmit={this.onUpdateTransaction}
onDelete={this.handleDeleteTransaction} onDelete={this.onDeleteTransaction}
securities={this.props.securities} /> securities={this.props.securities} />
<ImportTransactionsModal <ImportTransactionsModal
imports={this.props.imports} imports={this.props.imports}
@ -826,7 +871,7 @@ module.exports = React.createClass({
accounts={this.props.accounts} accounts={this.props.accounts}
onCancel={this.props.onCloseImportModal} onCancel={this.props.onCloseImportModal}
onHide={this.props.onCloseImportModal} onHide={this.props.onCloseImportModal}
onSubmit={this.handleImportComplete} onSubmit={this.onImportComplete}
onImportOFX={this.props.onImportOFX} onImportOFX={this.props.onImportOFX}
onImportOFXFile={this.props.onImportOFXFile} onImportOFXFile={this.props.onImportOFXFile}
onImportGnucash={this.props.onImportGnucash} /> onImportGnucash={this.props.onImportGnucash} />
@ -840,11 +885,11 @@ module.exports = React.createClass({
items={this.props.transactionPage.numPages} items={this.props.transactionPage.numPages}
maxButtons={Math.min(5, this.props.transactionPage.numPages)} maxButtons={Math.min(5, this.props.transactionPage.numPages)}
activePage={this.props.transactionPage.page + 1} activePage={this.props.transactionPage.page + 1}
onSelect={this.handleSelectPage} /> onSelect={this.onSelectPage} />
</ButtonGroup> </ButtonGroup>
<ButtonGroup> <ButtonGroup>
<Button <Button
onClick={this.handleNewTransactionClicked} onClick={this.onNewTransactionClicked}
bsStyle="success" bsStyle="success"
disabled={disabled}> disabled={disabled}>
<Glyphicon glyph='plus-sign' /> New Transaction <Glyphicon glyph='plus-sign' /> New Transaction
@ -861,4 +906,6 @@ module.exports = React.createClass({
</div> </div>
); );
} }
}); }
module.exports = AccountRegister;

View File

@ -14,27 +14,32 @@ var Col = ReactBootstrap.Col;
var User = require('../models').User; var User = require('../models').User;
module.exports = React.createClass({ class AccountSettingsModal extends React.Component {
displayName: "AccountSettingsModal", _getInitialState(props) {
_getInitialState: function(props) { return {
return {error: "", error: "",
name: props.user.Name, name: props ? props.user.Name: "",
username: props.user.Username, username: props ? props.user.Username : "",
email: props.user.Email, email: props ? props.user.Email : "",
password: models.BogusPassword, password: models.BogusPassword,
confirm_password: models.BogusPassword, confirm_password: models.BogusPassword,
passwordChanged: false, passwordChanged: false,
initial_password: models.BogusPassword}; initial_password: models.BogusPassword
}, };
getInitialState: function() { }
return this._getInitialState(this.props); constructor() {
}, super();
componentWillReceiveProps: function(nextProps) { this.state = this._getInitialState();
this.onCancel = this.handleCancel.bind(this);
this.onChange = this.handleChange.bind(this);
this.onSubmit = this.handleSubmit.bind(this);
}
componentWillReceiveProps(nextProps) {
if (nextProps.show && !this.props.show) { if (nextProps.show && !this.props.show) {
this.setState(this._getInitialState(nextProps)); this.setState(this._getInitialState(nextProps));
} }
}, }
passwordValidationState: function() { passwordValidationState() {
if (this.state.passwordChanged) { if (this.state.passwordChanged) {
if (this.state.password.length >= 10) if (this.state.password.length >= 10)
return "success"; return "success";
@ -43,20 +48,20 @@ module.exports = React.createClass({
else else
return "error"; return "error";
} }
}, }
confirmPasswordValidationState: function() { confirmPasswordValidationState() {
if (this.state.confirm_password.length > 0) { if (this.state.confirm_password.length > 0) {
if (this.state.confirm_password == this.state.password) if (this.state.confirm_password == this.state.password)
return "success"; return "success";
else else
return "error"; return "error";
} }
}, }
handleCancel: function() { handleCancel() {
if (this.props.onCancel != null) if (this.props.onCancel != null)
this.props.onCancel(); this.props.onCancel();
}, }
handleChange: function() { handleChange() {
if (ReactDOM.findDOMNode(this.refs.password).value != this.state.initial_password) if (ReactDOM.findDOMNode(this.refs.password).value != this.state.initial_password)
this.setState({passwordChanged: true}); this.setState({passwordChanged: true});
this.setState({ this.setState({
@ -66,8 +71,8 @@ module.exports = React.createClass({
password: ReactDOM.findDOMNode(this.refs.password).value, password: ReactDOM.findDOMNode(this.refs.password).value,
confirm_password: ReactDOM.findDOMNode(this.refs.confirm_password).value confirm_password: ReactDOM.findDOMNode(this.refs.confirm_password).value
}); });
}, }
handleSubmit: function(e) { handleSubmit(e) {
var u = new User(); var u = new User();
e.preventDefault(); e.preventDefault();
@ -87,22 +92,22 @@ module.exports = React.createClass({
this.props.onUpdateUser(u); this.props.onUpdateUser(u);
this.props.onSubmit(); this.props.onSubmit();
}, }
render: function() { render() {
return ( return (
<Modal show={this.props.show} onHide={this.handleCancel} bsSize="large"> <Modal show={this.props.show} onHide={this.onCancel} bsSize="large">
<Modal.Header closeButton> <Modal.Header closeButton>
<Modal.Title>Edit Account Settings</Modal.Title> <Modal.Title>Edit Account Settings</Modal.Title>
</Modal.Header> </Modal.Header>
<Modal.Body> <Modal.Body>
<span color="red">{this.state.error}</span> <span color="red">{this.state.error}</span>
<Form horizontal onSubmit={this.handleSubmit}> <Form horizontal onSubmit={this.onSubmit}>
<FormGroup> <FormGroup>
<Col componentClass={ControlLabel} xs={2}>Name</Col> <Col componentClass={ControlLabel} xs={2}>Name</Col>
<Col xs={10}> <Col xs={10}>
<FormControl type="text" <FormControl type="text"
value={this.state.name} value={this.state.name}
onChange={this.handleChange} onChange={this.onChange}
ref="name"/> ref="name"/>
</Col> </Col>
</FormGroup> </FormGroup>
@ -111,7 +116,7 @@ module.exports = React.createClass({
<Col xs={10}> <Col xs={10}>
<FormControl type="text" <FormControl type="text"
value={this.state.username} value={this.state.username}
onChange={this.handleChange} onChange={this.onChange}
ref="username"/> ref="username"/>
</Col> </Col>
</FormGroup> </FormGroup>
@ -120,7 +125,7 @@ module.exports = React.createClass({
<Col xs={10}> <Col xs={10}>
<FormControl type="email" <FormControl type="email"
value={this.state.email} value={this.state.email}
onChange={this.handleChange} onChange={this.onChange}
ref="email"/> ref="email"/>
</Col> </Col>
</FormGroup> </FormGroup>
@ -129,7 +134,7 @@ module.exports = React.createClass({
<Col xs={10}> <Col xs={10}>
<FormControl type="password" <FormControl type="password"
value={this.state.password} value={this.state.password}
onChange={this.handleChange} onChange={this.onChange}
ref="password"/> ref="password"/>
<FormControl.Feedback/> <FormControl.Feedback/>
</Col> </Col>
@ -139,7 +144,7 @@ module.exports = React.createClass({
<Col xs={10}> <Col xs={10}>
<FormControl type="password" <FormControl type="password"
value={this.state.confirm_password} value={this.state.confirm_password}
onChange={this.handleChange} onChange={this.onChange}
ref="confirm_password"/> ref="confirm_password"/>
<FormControl.Feedback/> <FormControl.Feedback/>
</Col> </Col>
@ -148,11 +153,13 @@ module.exports = React.createClass({
</Modal.Body> </Modal.Body>
<Modal.Footer> <Modal.Footer>
<ButtonGroup> <ButtonGroup>
<Button onClick={this.handleCancel} bsStyle="warning">Cancel</Button> <Button onClick={this.onCancel} bsStyle="warning">Cancel</Button>
<Button onClick={this.handleSubmit} bsStyle="success">Save Settings</Button> <Button onClick={this.onSubmit} bsStyle="success">Save Settings</Button>
</ButtonGroup> </ButtonGroup>
</Modal.Footer> </Modal.Footer>
</Modal> </Modal>
); );
} }
}); }
module.exports = AccountSettingsModal;

View File

@ -33,8 +33,8 @@ var AccountTypeList = models.AccountTypeList;
var AccountCombobox = require('./AccountCombobox'); var AccountCombobox = require('./AccountCombobox');
var AccountRegister = require('./AccountRegister'); var AccountRegister = require('./AccountRegister');
const AddEditAccountModal = React.createClass({ class AddEditAccountModal extends React.Component {
getInitialState: function() { getInitialState(props) {
var s = { var s = {
accountid: -1, accountid: -1,
security: 1, security: 1,
@ -54,36 +54,54 @@ const AddEditAccountModal = React.createClass({
ofxversion: "", ofxversion: "",
ofxnoindent: false, ofxnoindent: false,
}; };
if (this.props.editAccount != null) { if (!props) {
s.accountid = this.props.editAccount.AccountId; return s;
s.name = this.props.editAccount.Name; } else if (props.editAccount != null) {
s.security = this.props.editAccount.SecurityId; s.accountid = props.editAccount.AccountId;
s.parentaccountid = this.props.editAccount.ParentAccountId; s.name = props.editAccount.Name;
s.type = this.props.editAccount.Type; s.security = props.editAccount.SecurityId;
s.ofxurl = this.props.editAccount.OFXURL; s.parentaccountid = props.editAccount.ParentAccountId;
s.ofxorg = this.props.editAccount.OFXORG; s.type = props.editAccount.Type;
s.ofxfid = this.props.editAccount.OFXFID; s.ofxurl = props.editAccount.OFXURL;
s.ofxuser = this.props.editAccount.OFXUser; s.ofxorg = props.editAccount.OFXORG;
s.ofxbankid = this.props.editAccount.OFXBankID; s.ofxfid = props.editAccount.OFXFID;
s.ofxacctid = this.props.editAccount.OFXAcctID; s.ofxuser = props.editAccount.OFXUser;
s.ofxaccttype = this.props.editAccount.OFXAcctType; s.ofxbankid = props.editAccount.OFXBankID;
s.ofxclientuid = this.props.editAccount.OFXClientUID; s.ofxacctid = props.editAccount.OFXAcctID;
s.ofxappid = this.props.editAccount.OFXAppID; s.ofxaccttype = props.editAccount.OFXAcctType;
s.ofxappver = this.props.editAccount.OFXAppVer; s.ofxclientuid = props.editAccount.OFXClientUID;
s.ofxversion = this.props.editAccount.OFXVersion; s.ofxappid = props.editAccount.OFXAppID;
s.ofxnoindent = this.props.editAccount.OFXNoIndent; s.ofxappver = props.editAccount.OFXAppVer;
} else if (this.props.initialParentAccount != null) { s.ofxversion = props.editAccount.OFXVersion;
s.security = this.props.initialParentAccount.SecurityId; s.ofxnoindent = props.editAccount.OFXNoIndent;
s.parentaccountid = this.props.initialParentAccount.AccountId; } else if (props.initialParentAccount != null) {
s.type = this.props.initialParentAccount.Type; s.security = props.initialParentAccount.SecurityId;
s.parentaccountid = props.initialParentAccount.AccountId;
s.type = props.initialParentAccount.Type;
} }
return s; 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) if (this.props.onCancel != null)
this.props.onCancel(); this.props.onCancel();
}, }
handleChange: function() { handleChange() {
this.setState({ this.setState({
name: ReactDOM.findDOMNode(this.refs.name).value, name: ReactDOM.findDOMNode(this.refs.name).value,
ofxurl: ReactDOM.findDOMNode(this.refs.ofxurl).value, ofxurl: ReactDOM.findDOMNode(this.refs.ofxurl).value,
@ -98,27 +116,27 @@ const AddEditAccountModal = React.createClass({
ofxappver: ReactDOM.findDOMNode(this.refs.ofxappver).value, ofxappver: ReactDOM.findDOMNode(this.refs.ofxappver).value,
ofxversion: ReactDOM.findDOMNode(this.refs.ofxversion).value, ofxversion: ReactDOM.findDOMNode(this.refs.ofxversion).value,
}); });
}, }
handleNoIndentClick: function() { handleNoIndentClick() {
this.setState({ofxnoindent: !this.state.ofxnoindent}); this.setState({ofxnoindent: !this.state.ofxnoindent});
}, }
handleSecurityChange: function(security) { handleSecurityChange(security) {
if (security.hasOwnProperty('SecurityId')) if (security.hasOwnProperty('SecurityId'))
this.setState({ this.setState({
security: security.SecurityId security: security.SecurityId
}); });
}, }
handleTypeChange: function(type) { handleTypeChange(type) {
if (type.hasOwnProperty('TypeId')) if (type.hasOwnProperty('TypeId'))
this.setState({ this.setState({
type: type.TypeId type: type.TypeId
}); });
}, }
handleParentChange: function(parentAccount) { handleParentChange(parentAccount) {
this.setState({parentaccountid: parentAccount.AccountId}); this.setState({parentaccountid: parentAccount.AccountId});
}, }
handleSubmit: function() { handleSubmit() {
var a = new Account(); var a = new Account();
if (this.props.editAccount != null) if (this.props.editAccount != null)
@ -143,13 +161,8 @@ const AddEditAccountModal = React.createClass({
if (this.props.onSubmit != null) if (this.props.onSubmit != null)
this.props.onSubmit(a); this.props.onSubmit(a);
},
componentWillReceiveProps: function(nextProps) {
if (nextProps.show && !this.props.show) {
this.setState(this.getInitialState());
} }
}, render() {
render: function() {
var headerText = (this.props.editAccount != null) ? "Edit" : "Create New"; var headerText = (this.props.editAccount != null) ? "Edit" : "Create New";
var buttonText = (this.props.editAccount != null) ? "Save Changes" : "Create Account"; var buttonText = (this.props.editAccount != null) ? "Save Changes" : "Create Account";
var rootName = (this.props.editAccount != null) ? "Top-level Account" : "New Top-level Account"; var rootName = (this.props.editAccount != null) ? "Top-level Account" : "New Top-level Account";
@ -165,7 +178,7 @@ const AddEditAccountModal = React.createClass({
componentClass="select" componentClass="select"
placeholder="select" placeholder="select"
value={this.state.ofxaccttype} value={this.state.ofxaccttype}
onChange={this.handleChange} onChange={this.onChange}
ref="ofxaccttype"> ref="ofxaccttype">
<option value="CHECKING">Checking</option> <option value="CHECKING">Checking</option>
<option value="SAVINGS">Savings</option> <option value="SAVINGS">Savings</option>
@ -180,20 +193,20 @@ const AddEditAccountModal = React.createClass({
} }
var bankIdDisabled = (this.state.type != AccountType.Investment && this.state.ofxaccttype == "CC") ? true : false; var bankIdDisabled = (this.state.type != AccountType.Investment && this.state.ofxaccttype == "CC") ? true : false;
return ( return (
<Modal show={this.props.show} onHide={this.handleCancel}> <Modal show={this.props.show} onHide={this.onCancel}>
<Modal.Header closeButton> <Modal.Header closeButton>
<Modal.Title>{headerText} Account</Modal.Title> <Modal.Title>{headerText} Account</Modal.Title>
</Modal.Header> </Modal.Header>
<Modal.Body> <Modal.Body>
<Tabs defaultActiveKey={1} id="editAccountTabs"> <Tabs defaultActiveKey={1} id="editAccountTabs">
<Tab eventKey={1} title="General"> <Tab eventKey={1} title="General">
<Form horizontal onSubmit={this.handleSubmit}> <Form horizontal onSubmit={this.onSubmit}>
<FormGroup> <FormGroup>
<Col componentClass={ControlLabel} xs={2}>Name</Col> <Col componentClass={ControlLabel} xs={2}>Name</Col>
<Col xs={10}> <Col xs={10}>
<FormControl type="text" <FormControl type="text"
value={this.state.name} value={this.state.name}
onChange={this.handleChange} onChange={this.onChange}
ref="name"/> ref="name"/>
</Col> </Col>
</FormGroup> </FormGroup>
@ -205,7 +218,7 @@ const AddEditAccountModal = React.createClass({
accountChildren={this.props.accountChildren} accountChildren={this.props.accountChildren}
value={this.state.parentaccountid} value={this.state.parentaccountid}
rootName={rootName} rootName={rootName}
onChange={this.handleParentChange} onChange={this.onParentChange}
ref="parent" /> ref="parent" />
</Col> </Col>
</FormGroup> </FormGroup>
@ -218,7 +231,7 @@ const AddEditAccountModal = React.createClass({
valueField='SecurityId' valueField='SecurityId'
textField={item => typeof item === 'string' ? item : item.Name + " - " + item.Description} textField={item => typeof item === 'string' ? item : item.Name + " - " + item.Description}
defaultValue={this.state.security} defaultValue={this.state.security}
onChange={this.handleSecurityChange} onChange={this.onSecurityChange}
ref="security" /> ref="security" />
</Col> </Col>
</FormGroup> </FormGroup>
@ -231,20 +244,20 @@ const AddEditAccountModal = React.createClass({
valueField='TypeId' valueField='TypeId'
textField='Name' textField='Name'
defaultValue={this.state.type} defaultValue={this.state.type}
onChange={this.handleTypeChange} onChange={this.onTypeChange}
ref="type" /> ref="type" />
</Col> </Col>
</FormGroup> </FormGroup>
</Form> </Form>
</Tab> </Tab>
<Tab eventKey={2} title="Sync (OFX)"> <Tab eventKey={2} title="Sync (OFX)">
<Form horizontal onSubmit={this.handleSubmit}> <Form horizontal onSubmit={this.onSubmit}>
<FormGroup> <FormGroup>
<Col componentClass={ControlLabel} xs={2}>OFX URL</Col> <Col componentClass={ControlLabel} xs={2}>OFX URL</Col>
<Col xs={10}> <Col xs={10}>
<FormControl type="text" <FormControl type="text"
value={this.state.ofxurl} value={this.state.ofxurl}
onChange={this.handleChange} onChange={this.onChange}
ref="ofxurl"/> ref="ofxurl"/>
</Col> </Col>
</FormGroup> </FormGroup>
@ -253,7 +266,7 @@ const AddEditAccountModal = React.createClass({
<Col xs={10}> <Col xs={10}>
<FormControl type="text" <FormControl type="text"
value={this.state.ofxorg} value={this.state.ofxorg}
onChange={this.handleChange} onChange={this.onChange}
ref="ofxorg"/> ref="ofxorg"/>
</Col> </Col>
</FormGroup> </FormGroup>
@ -262,7 +275,7 @@ const AddEditAccountModal = React.createClass({
<Col xs={10}> <Col xs={10}>
<FormControl type="text" <FormControl type="text"
value={this.state.ofxfid} value={this.state.ofxfid}
onChange={this.handleChange} onChange={this.onChange}
ref="ofxfid"/> ref="ofxfid"/>
</Col> </Col>
</FormGroup> </FormGroup>
@ -271,7 +284,7 @@ const AddEditAccountModal = React.createClass({
<Col xs={10}> <Col xs={10}>
<FormControl type="text" <FormControl type="text"
value={this.state.ofxuser} value={this.state.ofxuser}
onChange={this.handleChange} onChange={this.onChange}
ref="ofxuser"/> ref="ofxuser"/>
</Col> </Col>
</FormGroup> </FormGroup>
@ -281,7 +294,7 @@ const AddEditAccountModal = React.createClass({
<FormControl type="text" <FormControl type="text"
disabled={bankIdDisabled} disabled={bankIdDisabled}
value={this.state.ofxbankid} value={this.state.ofxbankid}
onChange={this.handleChange} onChange={this.onChange}
ref="ofxbankid"/> ref="ofxbankid"/>
</Col> </Col>
</FormGroup> </FormGroup>
@ -290,7 +303,7 @@ const AddEditAccountModal = React.createClass({
<Col xs={10}> <Col xs={10}>
<FormControl type="text" <FormControl type="text"
value={this.state.ofxacctid} value={this.state.ofxacctid}
onChange={this.handleChange} onChange={this.onChange}
ref="ofxacctid"/> ref="ofxacctid"/>
</Col> </Col>
</FormGroup> </FormGroup>
@ -301,7 +314,7 @@ const AddEditAccountModal = React.createClass({
<Col xs={10}> <Col xs={10}>
<FormControl type="text" <FormControl type="text"
value={this.state.ofxclientuid} value={this.state.ofxclientuid}
onChange={this.handleChange} onChange={this.onChange}
ref="ofxclientuid"/> ref="ofxclientuid"/>
</Col> </Col>
</FormGroup> </FormGroup>
@ -310,7 +323,7 @@ const AddEditAccountModal = React.createClass({
<Col xs={10}> <Col xs={10}>
<FormControl type="text" <FormControl type="text"
value={this.state.ofxappid} value={this.state.ofxappid}
onChange={this.handleChange} onChange={this.onChange}
ref="ofxappid"/> ref="ofxappid"/>
</Col> </Col>
</FormGroup> </FormGroup>
@ -319,7 +332,7 @@ const AddEditAccountModal = React.createClass({
<Col xs={10}> <Col xs={10}>
<FormControl type="text" <FormControl type="text"
value={this.state.ofxappver} value={this.state.ofxappver}
onChange={this.handleChange} onChange={this.onChange}
ref="ofxappver"/> ref="ofxappver"/>
</Col> </Col>
</FormGroup> </FormGroup>
@ -328,7 +341,7 @@ const AddEditAccountModal = React.createClass({
<Col xs={10}> <Col xs={10}>
<FormControl type="text" <FormControl type="text"
value={this.state.ofxversion} value={this.state.ofxversion}
onChange={this.handleChange} onChange={this.onChange}
ref="ofxversion"/> ref="ofxversion"/>
</Col> </Col>
</FormGroup> </FormGroup>
@ -336,7 +349,7 @@ const AddEditAccountModal = React.createClass({
<Col xsOffset={2} xs={10}> <Col xsOffset={2} xs={10}>
<Checkbox <Checkbox
checked={this.state.ofxnoindent ? "checked" : ""} checked={this.state.ofxnoindent ? "checked" : ""}
onClick={this.handleNoIndentClick}> onClick={this.onNoIndentClick}>
Don't indent OFX request files Don't indent OFX request files
</Checkbox> </Checkbox>
</Col> </Col>
@ -348,40 +361,58 @@ const AddEditAccountModal = React.createClass({
</Modal.Body> </Modal.Body>
<Modal.Footer> <Modal.Footer>
<ButtonGroup className="pull-right"> <ButtonGroup className="pull-right">
<Button onClick={this.handleCancel} bsStyle="warning">Cancel</Button> <Button onClick={this.onCancel} bsStyle="warning">Cancel</Button>
<Button onClick={this.handleSubmit} bsStyle="success">{buttonText}</Button> <Button onClick={this.onSubmit} bsStyle="success">{buttonText}</Button>
</ButtonGroup> </ButtonGroup>
</Modal.Footer> </Modal.Footer>
</Modal> </Modal>
); );
} }
}); }
const DeleteAccountModal = React.createClass({ class DeleteAccountModal extends React.Component {
getInitialState: function() { getInitialState(props) {
if (this.props.initialAccount != null) if (!props)
var accountid = this.props.initialAccount.AccountId; var accountid = -1;
else if (this.props.accounts.length > 0) else if (props.initialAccount != null)
var accountid = this.props.accounts[0].AccountId; var accountid = props.initialAccount.AccountId;
else if (props.accounts.length > 0)
var accountid = props.accounts[0].AccountId;
else else
var accountid = -1; var accountid = -1;
return {error: "",
return {
error: "",
accountid: accountid, accountid: accountid,
checked: false, checked: false,
show: false}; show: false
}, };
handleCancel: function() { }
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) if (this.props.onCancel != null)
this.props.onCancel(); this.props.onCancel();
}, }
handleChange: function(account) { handleChange(account) {
this.setState({accountid: account.AccountId}); this.setState({accountid: account.AccountId});
}, }
handleCheckboxClick: function() { handleCheckboxClick() {
this.setState({checked: !this.state.checked}); this.setState({checked: !this.state.checked});
}, }
handleSubmit: function() { handleSubmit() {
if (this.props.accounts.hasOwnProperty(this.state.accountid)) { if (this.props.accounts.hasOwnProperty(this.state.accountid)) {
if (this.state.checked) { if (this.state.checked) {
if (this.props.onSubmit != null) if (this.props.onSubmit != null)
@ -392,13 +423,8 @@ const DeleteAccountModal = React.createClass({
} else { } else {
this.setState({error: "You must select an account."}); this.setState({error: "You must select an account."});
} }
},
componentWillReceiveProps: function(nextProps) {
if (nextProps.show && !this.props.show) {
this.setState(this.getInitialState());
} }
}, render() {
render: function() {
var checkbox = []; var checkbox = [];
if (this.props.accounts.hasOwnProperty(this.state.accountid)) { if (this.props.accounts.hasOwnProperty(this.state.accountid)) {
var parentAccountId = this.props.accounts[this.state.accountid].ParentAccountId; var parentAccountId = this.props.accounts[this.state.accountid].ParentAccountId;
@ -412,7 +438,7 @@ const DeleteAccountModal = React.createClass({
<Col xsOffset={2} sm={10}> <Col xsOffset={2} sm={10}>
<Checkbox <Checkbox
checked={this.state.checked ? "checked" : ""} checked={this.state.checked ? "checked" : ""}
onClick={this.handleCheckboxClick}> onClick={this.onCheckboxClick}>
{warningString} {warningString}
</Checkbox> </Checkbox>
</Col> </Col>
@ -428,14 +454,14 @@ const DeleteAccountModal = React.createClass({
return ( return (
<Modal <Modal
show={this.props.show} show={this.props.show}
onHide={this.handleCancel} onHide={this.onCancel}
ref="modal"> ref="modal">
<Modal.Header closeButton> <Modal.Header closeButton>
<Modal.Title>Delete Account</Modal.Title> <Modal.Title>Delete Account</Modal.Title>
</Modal.Header> </Modal.Header>
<Modal.Body> <Modal.Body>
{warning} {warning}
<Form horizontal onSubmit={this.handleSubmit}> <Form horizontal onSubmit={this.onSubmit}>
<FormGroup> <FormGroup>
<Col componentClass={ControlLabel} xs={2}>Delete Account</Col> <Col componentClass={ControlLabel} xs={2}>Delete Account</Col>
<Col xs={10}> <Col xs={10}>
@ -444,7 +470,7 @@ const DeleteAccountModal = React.createClass({
accounts={this.props.accounts} accounts={this.props.accounts}
accountChildren={this.props.accountChildren} accountChildren={this.props.accountChildren}
value={this.state.accountid} value={this.state.accountid}
onChange={this.handleChange}/> onChange={this.onChange}/>
</Col> </Col>
</FormGroup> </FormGroup>
{checkbox} {checkbox}
@ -452,32 +478,36 @@ const DeleteAccountModal = React.createClass({
</Modal.Body> </Modal.Body>
<Modal.Footer> <Modal.Footer>
<ButtonGroup className="pull-right"> <ButtonGroup className="pull-right">
<Button onClick={this.handleCancel} bsStyle="warning">Cancel</Button> <Button onClick={this.onCancel} bsStyle="warning">Cancel</Button>
<Button onClick={this.handleSubmit} bsStyle="success">Delete Account</Button> <Button onClick={this.onSubmit} bsStyle="success">Delete Account</Button>
</ButtonGroup> </ButtonGroup>
</Modal.Footer> </Modal.Footer>
</Modal> </Modal>
); );
} }
}); }
const AccountTreeNode = React.createClass({ class AccountTreeNode extends React.Component {
getInitialState: function() { constructor() {
return {expanded: false}; super();
}, this.state = {expanded: false};
handleToggle: function(e) { this.onToggle = this.handleToggle.bind(this);
this.onChildSelect = this.handleChildSelect.bind(this);
this.onSelect = this.handleSelect.bind(this);
}
handleToggle(e) {
e.preventDefault(); e.preventDefault();
this.setState({expanded:!this.state.expanded}); this.setState({expanded:!this.state.expanded});
}, }
handleChildSelect: function(account) { handleChildSelect(account) {
if (this.props.onSelect != null) if (this.props.onSelect != null)
this.props.onSelect(account); this.props.onSelect(account);
}, }
handleSelect: function() { handleSelect() {
if (this.props.onSelect != null) if (this.props.onSelect != null)
this.props.onSelect(this.props.account); this.props.onSelect(this.props.account);
}, }
render: function() { render() {
var glyph = this.state.expanded ? 'minus' : 'plus'; var glyph = this.state.expanded ? 'minus' : 'plus';
var active = (this.props.selectedAccount != -1 && var active = (this.props.selectedAccount != -1 &&
this.props.account.AccountId == this.props.selectedAccount); this.props.account.AccountId == this.props.selectedAccount);
@ -493,14 +523,14 @@ const AccountTreeNode = React.createClass({
selectedAccount={self.props.selectedAccount} selectedAccount={self.props.selectedAccount}
accounts={self.props.accounts} accounts={self.props.accounts}
accountChildren={self.props.accountChildren} accountChildren={self.props.accountChildren}
onSelect={self.handleChildSelect}/> onSelect={self.onChildSelect}/>
); );
}); });
var accounttreeClasses = "accounttree" var accounttreeClasses = "accounttree"
var expandButton = []; var expandButton = [];
if (children.length > 0) { if (children.length > 0) {
expandButton.push(( expandButton.push((
<Button onClick={this.handleToggle} <Button onClick={this.onToggle}
key={1} key={1}
bsSize="xsmall" bsSize="xsmall"
bsStyle="link" bsStyle="link"
@ -514,7 +544,7 @@ const AccountTreeNode = React.createClass({
return ( return (
<div className={accounttreeClasses}> <div className={accounttreeClasses}>
{expandButton} {expandButton}
<Button onClick={this.handleSelect} <Button onClick={this.onSelect}
bsStyle={buttonStyle} bsStyle={buttonStyle}
className="accounttree-name"> className="accounttree-name">
{this.props.account.Name} {this.props.account.Name}
@ -527,27 +557,29 @@ const AccountTreeNode = React.createClass({
</div> </div>
); );
} }
}); }
const AccountTree = React.createClass({ class AccountTree extends React.Component {
getInitialState: function() { constructor() {
return {height: 0}; super();
}, this.state = {height: 0};
handleSelect: function(account) { this.onSelect = this.handleSelect.bind(this);
}
handleSelect(account) {
if (this.props.onSelect != null) { if (this.props.onSelect != null) {
this.props.onSelect(account); this.props.onSelect(account);
} }
}, }
resize: function() { resize() {
var div = ReactDOM.findDOMNode(this); var div = ReactDOM.findDOMNode(this);
this.setState({height: div.parentElement.clientHeight - 73}); this.setState({height: div.parentElement.clientHeight - 73});
}, }
componentDidMount: function() { componentDidMount() {
this.resize(); this.resize();
var self = this; var self = this;
$(window).resize(function() {self.resize();}); $(window).resize(function() {self.resize();});
}, }
render: function() { render() {
var accounts = this.props.accounts; var accounts = this.props.accounts;
var children = []; var children = [];
@ -560,7 +592,7 @@ const AccountTree = React.createClass({
selectedAccount={this.props.selectedAccount} selectedAccount={this.props.selectedAccount}
accounts={this.props.accounts} accounts={this.props.accounts}
accountChildren={this.props.accountChildren} accountChildren={this.props.accountChildren}
onSelect={this.handleSelect}/>)); onSelect={this.onSelect}/>));
} }
} }
@ -572,55 +604,65 @@ const AccountTree = React.createClass({
</div> </div>
); );
} }
}); }
module.exports = React.createClass({ class AccountsTab extends React.Component {
displayName: "AccountsTab", constructor() {
getInitialState: function() { super();
return { this.state = {
creatingNewAccount: false, creatingNewAccount: false,
editingAccount: false, editingAccount: false,
deletingAccount: false deletingAccount: false
}; };
}, this.onNewAccount = this.handleNewAccount.bind(this);
handleNewAccount: function() { this.onEditAccount = this.handleEditAccount.bind(this);
this.onDeleteAccount = this.handleDeleteAccount.bind(this);
this.onCreationCancel = this.handleCreationCancel.bind(this);
this.onEditingCancel = this.handleEditingCancel.bind(this);
this.onDeletionCancel = this.handleDeletionCancel.bind(this);
this.onCreateAccount = this.handleCreateAccount.bind(this);
this.onUpdateAccount = this.handleUpdateAccount.bind(this);
this.onRemoveAccount = this.handleRemoveAccount.bind(this);
this.onAccountSelected = this.handleAccountSelected.bind(this);
}
handleNewAccount() {
this.setState({creatingNewAccount: true}); this.setState({creatingNewAccount: true});
}, }
handleEditAccount: function() { handleEditAccount() {
this.setState({editingAccount: true}); this.setState({editingAccount: true});
}, }
handleDeleteAccount: function() { handleDeleteAccount() {
this.setState({deletingAccount: true}); this.setState({deletingAccount: true});
}, }
handleCreationCancel: function() { handleCreationCancel() {
this.setState({creatingNewAccount: false}); this.setState({creatingNewAccount: false});
}, }
handleEditingCancel: function() { handleEditingCancel() {
this.setState({editingAccount: false}); this.setState({editingAccount: false});
}, }
handleDeletionCancel: function() { handleDeletionCancel() {
this.setState({deletingAccount: false}); this.setState({deletingAccount: false});
}, }
handleCreateAccount: function(account) { handleCreateAccount(account) {
if (this.props.onCreateAccount != null) if (this.props.onCreateAccount != null)
this.props.onCreateAccount(account); this.props.onCreateAccount(account);
this.setState({creatingNewAccount: false}); this.setState({creatingNewAccount: false});
}, }
handleUpdateAccount: function(account) { handleUpdateAccount(account) {
if (this.props.onUpdateAccount != null) if (this.props.onUpdateAccount != null)
this.props.onUpdateAccount(account); this.props.onUpdateAccount(account);
this.setState({editingAccount: false}); this.setState({editingAccount: false});
}, }
handleRemoveAccount: function(account) { handleRemoveAccount(account) {
if (this.props.onDeleteAccount != null) if (this.props.onDeleteAccount != null)
this.props.onDeleteAccount(account); this.props.onDeleteAccount(account);
this.setState({deletingAccount: false}); this.setState({deletingAccount: false});
}, }
handleAccountSelected: function(account) { handleAccountSelected(account) {
this.props.onSelectAccount(account.AccountId); this.props.onSelectAccount(account.AccountId);
this.props.onFetchTransactionPage(account, 20, 0); this.props.onFetchTransactionPage(account, 20, 0);
}, }
render: function() { render() {
var disabled = (this.props.selectedAccount == -1) ? true : false; var disabled = (this.props.selectedAccount == -1) ? true : false;
var selectedAccount = null; var selectedAccount = null;
@ -635,36 +677,36 @@ module.exports = React.createClass({
initialParentAccount={selectedAccount} initialParentAccount={selectedAccount}
accounts={this.props.accounts} accounts={this.props.accounts}
accountChildren={this.props.accountChildren} accountChildren={this.props.accountChildren}
onCancel={this.handleCreationCancel} onCancel={this.onCreationCancel}
onSubmit={this.handleCreateAccount} onSubmit={this.onCreateAccount}
security_list={this.props.security_list}/> security_list={this.props.security_list}/>
<AddEditAccountModal <AddEditAccountModal
show={this.state.editingAccount} show={this.state.editingAccount}
editAccount={selectedAccount} editAccount={selectedAccount}
accounts={this.props.accounts} accounts={this.props.accounts}
accountChildren={this.props.accountChildren} accountChildren={this.props.accountChildren}
onCancel={this.handleEditingCancel} onCancel={this.onEditingCancel}
onSubmit={this.handleUpdateAccount} onSubmit={this.onUpdateAccount}
security_list={this.props.security_list}/> security_list={this.props.security_list}/>
<DeleteAccountModal <DeleteAccountModal
show={this.state.deletingAccount} show={this.state.deletingAccount}
initialAccount={selectedAccount} initialAccount={selectedAccount}
accounts={this.props.accounts} accounts={this.props.accounts}
accountChildren={this.props.accountChildren} accountChildren={this.props.accountChildren}
onCancel={this.handleDeletionCancel} onCancel={this.onDeletionCancel}
onSubmit={this.handleRemoveAccount}/> onSubmit={this.onRemoveAccount}/>
<AccountTree <AccountTree
accounts={this.props.accounts} accounts={this.props.accounts}
accountChildren={this.props.accountChildren} accountChildren={this.props.accountChildren}
selectedAccount={this.props.selectedAccount} selectedAccount={this.props.selectedAccount}
onSelect={this.handleAccountSelected}/> onSelect={this.onAccountSelected}/>
<ButtonGroup className="account-buttongroup"> <ButtonGroup className="account-buttongroup">
<Button onClick={this.handleNewAccount} bsStyle="success"> <Button onClick={this.onNewAccount} bsStyle="success">
<Glyphicon glyph='plus-sign' /></Button> <Glyphicon glyph='plus-sign' /></Button>
<Button onClick={this.handleEditAccount} <Button onClick={this.onEditAccount}
bsStyle="primary" disabled={disabled}> bsStyle="primary" disabled={disabled}>
<Glyphicon glyph='cog' /></Button> <Glyphicon glyph='cog' /></Button>
<Button onClick={this.handleDeleteAccount} <Button onClick={this.onDeleteAccount}
bsStyle="danger" disabled={disabled}> bsStyle="danger" disabled={disabled}>
<Glyphicon glyph='trash' /></Button> <Glyphicon glyph='trash' /></Button>
</ButtonGroup> </ButtonGroup>
@ -694,4 +736,6 @@ module.exports = React.createClass({
</Row></Grid> </Row></Grid>
); );
} }
}); }
module.exports = AccountsTab;

View File

@ -13,36 +13,34 @@ var AccountsTabContainer = require('../containers/AccountsTabContainer');
var SecuritiesTabContainer = require('../containers/SecuritiesTabContainer'); var SecuritiesTabContainer = require('../containers/SecuritiesTabContainer');
var ReportsTabContainer = require('../containers/ReportsTabContainer'); var ReportsTabContainer = require('../containers/ReportsTabContainer');
module.exports = React.createClass({ class MoneyGoApp extends React.Component {
displayName: "MoneyGoApp", constructor() {
getInitialState: function() { super();
return { this.state = {
showNewUserModal: false, showNewUserModal: false,
showAccountSettingsModal: false showAccountSettingsModal: false
}; };
}, this.onShowSettings = this.handleShowSettings.bind(this);
componentDidMount: function() { this.onHideSettings = this.handleHideSettings.bind(this);
this.onShowNewUser = this.handleShowNewUser.bind(this);
this.onHideNewUser = this.handleHideNewUser.bind(this);
}
componentDidMount() {
this.props.tryResumingSession(); this.props.tryResumingSession();
}, }
handleAccountSettings: function() { handleShowSettings() {
this.setState({showAccountSettingsModal: true}); this.setState({showAccountSettingsModal: true});
}, }
handleSettingsSubmitted: function(user) { handleHideSettings(user) {
this.setState({showAccountSettingsModal: false}); this.setState({showAccountSettingsModal: false});
}, }
handleSettingsCanceled: function() { handleShowNewUser() {
this.setState({showAccountSettingsModal: false});
},
handleCreateNewUser: function() {
this.setState({showNewUserModal: true}); this.setState({showNewUserModal: true});
}, }
handleNewUserCreated: function() { handleHideNewUser() {
this.setState({showNewUserModal: false}); this.setState({showNewUserModal: false});
}, }
handleNewUserCanceled: function() { render() {
this.setState({showNewUserModal: false});
},
render: function() {
var mainContent; var mainContent;
if (this.props.user.isUser()) if (this.props.user.isUser())
mainContent = ( mainContent = (
@ -74,18 +72,20 @@ module.exports = React.createClass({
return ( return (
<div className="fullheight ui"> <div className="fullheight ui">
<TopBarContainer <TopBarContainer
onCreateNewUser={this.handleCreateNewUser} onCreateNewUser={this.onShowNewUser}
onAccountSettings={this.handleAccountSettings} /> onAccountSettings={this.onShowSettings} />
{mainContent} {mainContent}
<NewUserModalContainer <NewUserModalContainer
show={this.state.showNewUserModal} show={this.state.showNewUserModal}
onSubmit={this.handleNewUserCreated} onSubmit={this.onHideNewUser}
onCancel={this.handleNewUserCanceled}/> onCancel={this.onHideNewUser}/>
<AccountSettingsModalContainer <AccountSettingsModalContainer
show={this.state.showAccountSettingsModal} show={this.state.showAccountSettingsModal}
onSubmit={this.handleSettingsSubmitted} onSubmit={this.onHideSettings}
onCancel={this.handleSettingsCanceled}/> onCancel={this.onHideSettings}/>
</div> </div>
); );
} }
}); }
module.exports = MoneyGoApp;

View File

@ -14,19 +14,21 @@ var ButtonGroup = ReactBootstrap.ButtonGroup;
var models = require('../models'); var models = require('../models');
var User = models.User; var User = models.User;
module.exports = React.createClass({ class NewUserModal extends React.Component {
displayName: "NewUserModal", constructor() {
getInitialState: function() { super();
return {error: "", this.state = {
error: "",
name: "", name: "",
username: "", username: "",
email: "", email: "",
password: "", password: "",
confirm_password: "", confirm_password: "",
passwordChanged: false, passwordChanged: false,
initial_password: ""}; initial_password: ""
}, };
passwordValidationState: function() { }
passwordValidationState() {
if (this.state.passwordChanged) { if (this.state.passwordChanged) {
if (this.state.password.length >= 10) if (this.state.password.length >= 10)
return "success"; return "success";
@ -35,20 +37,20 @@ module.exports = React.createClass({
else else
return "error"; return "error";
} }
}, }
confirmPasswordValidationState: function() { confirmPasswordValidationState() {
if (this.state.confirm_password.length > 0) { if (this.state.confirm_password.length > 0) {
if (this.state.confirm_password == this.state.password) if (this.state.confirm_password == this.state.password)
return "success"; return "success";
else else
return "error"; return "error";
} }
}, }
handleCancel: function() { handleCancel() {
if (this.props.onCancel != null) if (this.props.onCancel != null)
this.props.onCancel(); this.props.onCancel();
}, }
handleChange: function() { handleChange() {
if (ReactDOM.findDOMNode(this.refs.password).value != this.state.initial_password) if (ReactDOM.findDOMNode(this.refs.password).value != this.state.initial_password)
this.setState({passwordChanged: true}); this.setState({passwordChanged: true});
this.setState({ this.setState({
@ -58,8 +60,8 @@ module.exports = React.createClass({
password: ReactDOM.findDOMNode(this.refs.password).value, password: ReactDOM.findDOMNode(this.refs.password).value,
confirm_password: ReactDOM.findDOMNode(this.refs.confirm_password).value confirm_password: ReactDOM.findDOMNode(this.refs.confirm_password).value
}); });
}, }
handleSubmit: function(e) { handleSubmit(e) {
var u = new User(); var u = new User();
var error = ""; var error = "";
e.preventDefault(); e.preventDefault();
@ -76,8 +78,8 @@ module.exports = React.createClass({
this.props.createNewUser(u); this.props.createNewUser(u);
if (this.props.onSubmit != null) if (this.props.onSubmit != null)
this.props.onSubmit(u); this.props.onSubmit(u);
}, }
render: function() { render() {
return ( return (
<Modal show={this.props.show} onHide={this.handleCancel} bsSize="large"> <Modal show={this.props.show} onHide={this.handleCancel} bsSize="large">
<Modal.Header closeButton> <Modal.Header closeButton>
@ -146,4 +148,6 @@ module.exports = React.createClass({
</Modal> </Modal>
); );
} }
}); }
module.exports = NewUserModal;

View File

@ -1,9 +1,8 @@
var d3 = require('d3'); var d3 = require('d3');
var React = require('react'); var React = require('react');
var Slice = React.createClass({ class Slice extends React.Component {
displayName: "Slice", render() {
render: function() {
if (this.props.angle > Math.PI*2 - 0.00001) { if (this.props.angle > Math.PI*2 - 0.00001) {
var slice = (<circle cx={this.props.cx} cy={this.props.cy} r={this.props.radius} var slice = (<circle cx={this.props.cx} cy={this.props.cy} r={this.props.radius}
className={this.props.className} className={this.props.className}
@ -15,7 +14,7 @@ var Slice = React.createClass({
var large_arc_flag = this.props.angle > Math.PI ? 1 : 0; var large_arc_flag = this.props.angle > Math.PI ? 1 : 0;
var rotateDegrees = this.props.startAngle * 180 / Math.PI; var rotateDegrees = this.props.startAngle * 180 / Math.PI;
slice = (<path d={"M" + center + " l " + this.props.radius + " 0 a " + this.props.radius + " " + this.props.radius + ", 0, " + large_arc_flag + ", 1, " + dx + " " + dy + " Z"} var slice = (<path d={"M" + center + " l " + this.props.radius + " 0 a " + this.props.radius + " " + this.props.radius + ", 0, " + large_arc_flag + ", 1, " + dx + " " + dy + " Z"}
className={this.props.className} className={this.props.className}
onClick={this.props.onClick} />); onClick={this.props.onClick} />);
} }
@ -26,11 +25,10 @@ var Slice = React.createClass({
</g> </g>
); );
} }
}); }
module.exports = React.createClass({ class PieChart extends React.Component {
displayName: "PieChart", sortedSeries(series) {
sortedSeries: function(series) {
// Return an array of the series names, from highest to lowest sums (in // Return an array of the series names, from highest to lowest sums (in
// absolute terms) // absolute terms)
@ -49,13 +47,13 @@ module.exports = React.createClass({
}); });
return [seriesNames, seriesValues]; return [seriesNames, seriesValues];
}, }
render: function() { render() {
height = 400; var height = 400;
width = 600; var width = 600;
legendWidth = 100; var legendWidth = 100;
xMargin = 70; var xMargin = 70;
yMargin = 70; var yMargin = 70;
height -= yMargin*2; height -= yMargin*2;
width -= xMargin*2; width -= xMargin*2;
var radius = Math.min(height, width)/2; var radius = Math.min(height, width)/2;
@ -133,4 +131,6 @@ module.exports = React.createClass({
</svg> </svg>
); );
} }
}); }
module.exports = PieChart;

View File

@ -7,27 +7,30 @@ var Panel = ReactBootstrap.Panel;
var StackedBarChart = require('../components/StackedBarChart'); var StackedBarChart = require('../components/StackedBarChart');
module.exports = React.createClass({ var models = require('../models')
displayName: "ReportsTab", var Report = models.Report;
getInitialState: function() {
return { }; class ReportsTab extends React.Component {
}, constructor() {
componentWillMount: function() { super();
this.onSelectSeries = this.handleSelectSeries.bind(this);
}
componentWillMount() {
this.props.onFetchReport("monthly_expenses"); this.props.onFetchReport("monthly_expenses");
}, }
componentWillReceiveProps: function(nextProps) { componentWillReceiveProps(nextProps) {
if (nextProps.reports['monthly_expenses'] && !nextProps.selectedReport.report) { if (nextProps.reports['monthly_expenses'] && !nextProps.selectedReport.report) {
this.props.onSelectReport(nextProps.reports['monthly_expenses'], []); this.props.onSelectReport(nextProps.reports['monthly_expenses'], []);
} }
}, }
onSelectSeries: function(series) { handleSelectSeries(series) {
if (series == this.props.selectedReport.report.topLevelAccountName) if (series == Report.topLevelAccountName())
return; return;
var seriesTraversal = this.props.selectedReport.seriesTraversal.slice(); var seriesTraversal = this.props.selectedReport.seriesTraversal.slice();
seriesTraversal.push(series); seriesTraversal.push(series);
this.props.onSelectReport(this.props.reports[this.props.selectedReport.report.ReportId], seriesTraversal); this.props.onSelectReport(this.props.reports[this.props.selectedReport.report.ReportId], seriesTraversal);
}, }
render: function() { render() {
var report = []; var report = [];
if (this.props.selectedReport.report) { if (this.props.selectedReport.report) {
var titleTracks = []; var titleTracks = [];
@ -86,4 +89,6 @@ module.exports = React.createClass({
</div> </div>
); );
} }
}); }
module.exports = ReportsTab;

View File

@ -25,11 +25,15 @@ var Security = models.Security;
var SecurityType = models.SecurityType; var SecurityType = models.SecurityType;
var SecurityTypeList = models.SecurityTypeList; var SecurityTypeList = models.SecurityTypeList;
const SecurityTemplatePanel = React.createClass({ class SecurityTemplatePanel extends React.Component {
handleSearchChange: function(){ constructor() {
super();
this.onSearchChange = this.handleSearchChange.bind(this);
}
handleSearchChange() {
this.props.onSearchTemplates(ReactDOM.findDOMNode(this.refs.search).value, 0, this.props.maxResults + 1); this.props.onSearchTemplates(ReactDOM.findDOMNode(this.refs.search).value, 0, this.props.maxResults + 1);
}, }
renderTemplateList: function() { renderTemplateList() {
var templates = this.props.securityTemplates; var templates = this.props.securityTemplates;
if (this.props.search != "") { if (this.props.search != "") {
var items = []; var items = [];
@ -70,23 +74,23 @@ const SecurityTemplatePanel = React.createClass({
</div> </div>
); );
} }
}, }
render: function() { render() {
return ( return (
<Panel collapsible header="Populate Security from Template..."> <Panel collapsible header="Populate Security from Template...">
<FormControl type="text" <FormControl type="text"
placeholder="Search..." placeholder="Search..."
value={this.props.search} value={this.props.search}
onChange={this.handleSearchChange} onChange={this.onSearchChange}
ref="search"/> ref="search"/>
{this.renderTemplateList()} {this.renderTemplateList()}
</Panel> </Panel>
); );
} }
}); }
const AddEditSecurityModal = React.createClass({ class AddEditSecurityModal extends React.Component {
getInitialState: function() { getInitialState(props) {
var s = { var s = {
securityid: -1, securityid: -1,
name: "", name: "",
@ -96,18 +100,36 @@ const AddEditSecurityModal = React.createClass({
type: 1, type: 1,
alternateid: "" alternateid: ""
}; };
if (this.props.editSecurity != null) { if (props && props.editSecurity != null) {
s.securityid = this.props.editSecurity.SecurityId; s.securityid = props.editSecurity.SecurityId;
s.name = this.props.editSecurity.Name; s.name = props.editSecurity.Name;
s.description = this.props.editSecurity.Description; s.description = props.editSecurity.Description;
s.symbol = this.props.editSecurity.Symbol; s.symbol = props.editSecurity.Symbol;
s.precision = this.props.editSecurity.Precision; s.precision = props.editSecurity.Precision;
s.type = this.props.editSecurity.Type; s.type = props.editSecurity.Type;
s.alternateid = this.props.editSecurity.AlternateId; s.alternateid = props.editSecurity.AlternateId;
} }
return s; 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({ this.setState({
name: template.Name, name: template.Name,
description: template.Description, description: template.Description,
@ -116,43 +138,43 @@ const AddEditSecurityModal = React.createClass({
type: template.Type, type: template.Type,
alternateid: template.AlternateId alternateid: template.AlternateId
}); });
}, }
handleCancel: function() { handleCancel() {
if (this.props.onCancel != null) if (this.props.onCancel != null)
this.props.onCancel(); this.props.onCancel();
}, }
handleNameChange: function() { handleNameChange() {
this.setState({ this.setState({
name: ReactDOM.findDOMNode(this.refs.name).value, name: ReactDOM.findDOMNode(this.refs.name).value,
}); });
}, }
handleDescriptionChange: function() { handleDescriptionChange() {
this.setState({ this.setState({
description: ReactDOM.findDOMNode(this.refs.description).value, description: ReactDOM.findDOMNode(this.refs.description).value,
}); });
}, }
handleSymbolChange: function() { handleSymbolChange() {
this.setState({ this.setState({
symbol: ReactDOM.findDOMNode(this.refs.symbol).value, symbol: ReactDOM.findDOMNode(this.refs.symbol).value,
}); });
}, }
handlePrecisionChange: function() { handlePrecisionChange() {
this.setState({ this.setState({
precision: +ReactDOM.findDOMNode(this.refs.precision).value, precision: +ReactDOM.findDOMNode(this.refs.precision).value,
}); });
}, }
handleTypeChange: function(type) { handleTypeChange(type) {
if (type.hasOwnProperty('TypeId')) if (type.hasOwnProperty('TypeId'))
this.setState({ this.setState({
type: type.TypeId type: type.TypeId
}); });
}, }
handleAlternateIdChange: function() { handleAlternateIdChange() {
this.setState({ this.setState({
alternateid: ReactDOM.findDOMNode(this.refs.alternateid).value, alternateid: ReactDOM.findDOMNode(this.refs.alternateid).value,
}); });
}, }
handleSubmit: function() { handleSubmit() {
var s = new Security(); var s = new Security();
if (this.props.editSecurity != null) if (this.props.editSecurity != null)
@ -166,18 +188,13 @@ const AddEditSecurityModal = React.createClass({
if (this.props.onSubmit != null) if (this.props.onSubmit != null)
this.props.onSubmit(s); this.props.onSubmit(s);
},
componentWillReceiveProps: function(nextProps) {
if (nextProps.show && !this.props.show) {
this.setState(this.getInitialState());
} }
}, render() {
render: function() {
var headerText = (this.props.editSecurity != null) ? "Edit" : "Create New"; var headerText = (this.props.editSecurity != null) ? "Edit" : "Create New";
var buttonText = (this.props.editSecurity != null) ? "Save Changes" : "Create Security"; var buttonText = (this.props.editSecurity != null) ? "Save Changes" : "Create Security";
var alternateidname = (this.state.type == SecurityType.Currency) ? "ISO 4217 Code" : "CUSIP"; var alternateidname = (this.state.type == SecurityType.Currency) ? "ISO 4217 Code" : "CUSIP";
return ( return (
<Modal show={this.props.show} onHide={this.handleCancel}> <Modal show={this.props.show} onHide={this.onCancel}>
<Modal.Header closeButton> <Modal.Header closeButton>
<Modal.Title>{headerText} Security</Modal.Title> <Modal.Title>{headerText} Security</Modal.Title>
</Modal.Header> </Modal.Header>
@ -188,13 +205,13 @@ const AddEditSecurityModal = React.createClass({
onSearchTemplates={this.props.onSearchTemplates} onSearchTemplates={this.props.onSearchTemplates}
maxResults={15} maxResults={15}
onSelectTemplate={this.onSelectTemplate} /> onSelectTemplate={this.onSelectTemplate} />
<Form horizontal onSubmit={this.handleSubmit}> <Form horizontal onSubmit={this.onSubmit}>
<FormGroup> <FormGroup>
<Col componentClass={ControlLabel} xs={3}>Name</Col> <Col componentClass={ControlLabel} xs={3}>Name</Col>
<Col xs={9}> <Col xs={9}>
<FormControl type="text" <FormControl type="text"
value={this.state.name} value={this.state.name}
onChange={this.handleNameChange} onChange={this.onNameChange}
ref="name"/> ref="name"/>
</Col> </Col>
</FormGroup> </FormGroup>
@ -203,7 +220,7 @@ const AddEditSecurityModal = React.createClass({
<Col xs={9}> <Col xs={9}>
<FormControl type="text" <FormControl type="text"
value={this.state.description} value={this.state.description}
onChange={this.handleDescriptionChange} onChange={this.onDescriptionChange}
ref="description"/> ref="description"/>
</Col> </Col>
</FormGroup> </FormGroup>
@ -212,7 +229,7 @@ const AddEditSecurityModal = React.createClass({
<Col xs={9}> <Col xs={9}>
<FormControl type="text" <FormControl type="text"
value={this.state.symbol} value={this.state.symbol}
onChange={this.handleSymbolChange} onChange={this.onSymbolChange}
ref="symbol"/> ref="symbol"/>
</Col> </Col>
</FormGroup> </FormGroup>
@ -222,7 +239,7 @@ const AddEditSecurityModal = React.createClass({
<FormControl componentClass="select" <FormControl componentClass="select"
placeholder={this.state.precision} placeholder={this.state.precision}
value={this.state.precision} value={this.state.precision}
onChange={this.handlePrecisionChange} onChange={this.onPrecisionChange}
ref="precision"> ref="precision">
<option value={0}>1</option> <option value={0}>1</option>
<option value={1}>0.1 (1/10)</option> <option value={1}>0.1 (1/10)</option>
@ -242,7 +259,7 @@ const AddEditSecurityModal = React.createClass({
valueField='TypeId' valueField='TypeId'
textField='Name' textField='Name'
value={this.state.type} value={this.state.type}
onChange={this.handleTypeChange} onChange={this.onTypeChange}
ref="type" /> ref="type" />
</Col> </Col>
</FormGroup> </FormGroup>
@ -251,7 +268,7 @@ const AddEditSecurityModal = React.createClass({
<Col xs={9}> <Col xs={9}>
<FormControl type="text" <FormControl type="text"
value={this.state.alternateid} value={this.state.alternateid}
onChange={this.handleAlternateIdChange} onChange={this.onAlternateIdChange}
ref="alternateid"/> ref="alternateid"/>
</Col> </Col>
</FormGroup> </FormGroup>
@ -259,17 +276,17 @@ const AddEditSecurityModal = React.createClass({
</Modal.Body> </Modal.Body>
<Modal.Footer> <Modal.Footer>
<ButtonGroup className="pull-right"> <ButtonGroup className="pull-right">
<Button onClick={this.handleCancel} bsStyle="warning">Cancel</Button> <Button onClick={this.onCancel} bsStyle="warning">Cancel</Button>
<Button onClick={this.handleSubmit} bsStyle="success">{buttonText}</Button> <Button onClick={this.onSubmit} bsStyle="success">{buttonText}</Button>
</ButtonGroup> </ButtonGroup>
</Modal.Footer> </Modal.Footer>
</Modal> </Modal>
); );
} }
}); }
const DeletionFailedModal = React.createClass({ class DeletionFailedModal extends React.Component {
render: function() { render() {
return ( return (
<Modal show={this.props.show} onHide={this.props.onClose}> <Modal show={this.props.show} onHide={this.props.onClose}>
<Modal.Header closeButton> <Modal.Header closeButton>
@ -286,10 +303,10 @@ const DeletionFailedModal = React.createClass({
</Modal> </Modal>
); );
} }
}); }
const SecurityList = React.createClass({ class SecurityList extends React.Component {
render: function() { render() {
var children = []; var children = [];
var self = this; var self = this;
for (var securityId in this.props.securities) { for (var securityId in this.props.securities) {
@ -314,55 +331,64 @@ const SecurityList = React.createClass({
</div> </div>
); );
} }
}); }
module.exports = React.createClass({ class SecuritiesTab extends React.Component {
displayName: "SecuritiesTab", constructor() {
getInitialState: function() { super();
return { this.state = {
creatingNewSecurity: false, creatingNewSecurity: false,
editingSecurity: false, editingSecurity: false,
deletionFailedModal: false deletionFailedModal: false
}; };
}, this.onSelectSecurity = this.handleSelectSecurity.bind(this);
componentWillReceiveProps: function(nextProps) { 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) { if (nextProps.selectedSecurity == -1 && nextProps.security_list.length > 0) {
nextProps.onSelectSecurity(nextProps.security_list[0].SecurityId); nextProps.onSelectSecurity(nextProps.security_list[0].SecurityId);
} }
}, }
handleSelectSecurity: function(security) { handleSelectSecurity(security) {
this.props.onSelectSecurity(security.SecurityId); this.props.onSelectSecurity(security.SecurityId);
}, }
handleNewSecurity: function() { handleNewSecurity() {
this.setState({creatingNewSecurity: true}); this.setState({creatingNewSecurity: true});
}, }
handleEditSecurity: function() { handleEditSecurity() {
this.setState({editingSecurity: true}); this.setState({editingSecurity: true});
}, }
handleDeleteSecurity: function() { handleDeleteSecurity() {
if (this.props.selectedSecurityAccounts.length == 0) if (this.props.selectedSecurityAccounts.length == 0)
this.props.onDeleteSecurity(this.props.securities[this.props.selectedSecurity]); this.props.onDeleteSecurity(this.props.securities[this.props.selectedSecurity]);
else else
this.setState({deletionFailedModal: true}); this.setState({deletionFailedModal: true});
}, }
handleCreationCancel: function() { handleCreationCancel() {
this.setState({creatingNewSecurity: false}); this.setState({creatingNewSecurity: false});
}, }
handleCreationSubmit: function(security) { handleCreationSubmit(security) {
this.setState({creatingNewSecurity: false}); this.setState({creatingNewSecurity: false});
this.props.onCreateSecurity(security); this.props.onCreateSecurity(security);
}, }
handleEditingCancel: function() { handleEditingCancel() {
this.setState({editingSecurity: false}); this.setState({editingSecurity: false});
}, }
handleEditingSubmit: function(security) { handleEditingSubmit(security) {
this.setState({editingSecurity: false}); this.setState({editingSecurity: false});
this.props.onUpdateSecurity(security); this.props.onUpdateSecurity(security);
}, }
closeDeletionFailedModal: function() { handleCloseDeletionFailed() {
this.setState({deletionFailedModal: false}); this.setState({deletionFailedModal: false});
}, }
render: function() { render() {
var noSecuritySelected = this.props.selectedSecurity == -1; var noSecuritySelected = this.props.selectedSecurity == -1;
var selectedSecurity = -1; var selectedSecurity = -1;
@ -373,25 +399,25 @@ module.exports = React.createClass({
<div> <div>
<AddEditSecurityModal <AddEditSecurityModal
show={this.state.creatingNewSecurity} show={this.state.creatingNewSecurity}
onCancel={this.handleCreationCancel} onCancel={this.onCreationCancel}
onSubmit={this.handleCreationSubmit} onSubmit={this.onCreationSubmit}
onSearchTemplates={this.props.onSearchTemplates} onSearchTemplates={this.props.onSearchTemplates}
securityTemplates={this.props.securityTemplates} /> securityTemplates={this.props.securityTemplates} />
<AddEditSecurityModal <AddEditSecurityModal
show={this.state.editingSecurity} show={this.state.editingSecurity}
editSecurity={selectedSecurity} editSecurity={selectedSecurity}
onCancel={this.handleEditingCancel} onCancel={this.onEditingCancel}
onSubmit={this.handleEditingSubmit} onSubmit={this.onEditingSubmit}
onSearchTemplates={this.props.onSearchTemplates} onSearchTemplates={this.props.onSearchTemplates}
securityTemplates={this.props.securityTemplates} /> securityTemplates={this.props.securityTemplates} />
<DeletionFailedModal <DeletionFailedModal
show={this.state.deletionFailedModal} show={this.state.deletionFailedModal}
deletingSecurity={selectedSecurity} deletingSecurity={selectedSecurity}
onClose={this.closeDeletionFailedModal} onClose={this.onCloseDeletionFailed}
securityAccounts={this.props.selectedSecurityAccounts} /> securityAccounts={this.props.selectedSecurityAccounts} />
<ButtonToolbar> <ButtonToolbar>
<ButtonGroup> <ButtonGroup>
<Button onClick={this.handleNewSecurity} bsStyle="success"><Glyphicon glyph='plus-sign'/> New Security</Button> <Button onClick={this.onNewSecurity} bsStyle="success"><Glyphicon glyph='plus-sign'/> New Security</Button>
</ButtonGroup> </ButtonGroup>
<ButtonGroup> <ButtonGroup>
<Combobox <Combobox
@ -399,16 +425,18 @@ module.exports = React.createClass({
valueField='SecurityId' valueField='SecurityId'
textField={item => typeof item === 'string' ? item : item.Name + " - " + item.Description} textField={item => typeof item === 'string' ? item : item.Name + " - " + item.Description}
value={selectedSecurity} value={selectedSecurity}
onChange={this.handleSelectSecurity} onChange={this.onSelectSecurity}
suggest suggest
filter='contains' filter='contains'
ref="security" /> ref="security" />
</ButtonGroup> </ButtonGroup>
<ButtonGroup> <ButtonGroup>
<Button onClick={this.handleEditSecurity} bsStyle="primary" disabled={noSecuritySelected}><Glyphicon glyph='cog'/> Edit Security</Button> <Button onClick={this.onEditSecurity} bsStyle="primary" disabled={noSecuritySelected}><Glyphicon glyph='cog'/> Edit Security</Button>
<Button onClick={this.handleDeleteSecurity} bsStyle="danger" disabled={noSecuritySelected}><Glyphicon glyph='trash'/> Delete Security</Button> <Button onClick={this.onDeleteSecurity} bsStyle="danger" disabled={noSecuritySelected}><Glyphicon glyph='trash'/> Delete Security</Button>
</ButtonGroup></ButtonToolbar> </ButtonGroup></ButtonToolbar>
</div> </div>
); );
} }
}); }
module.exports = SecuritiesTab;

View File

@ -1,9 +1,8 @@
var d3 = require('d3'); var d3 = require('d3');
var React = require('react'); var React = require('react');
module.exports = React.createClass({ class StackedBarChart extends React.Component {
displayName: "StackedBarChart", calcMinMax(series) {
calcMinMax: function(series) {
var children = []; var children = [];
for (var child in series) { for (var child in series) {
if (series.hasOwnProperty(child)) if (series.hasOwnProperty(child))
@ -28,8 +27,8 @@ module.exports = React.createClass({
} }
return [Math.min.apply(Math, negativeValues), Math.max.apply(Math, positiveValues)]; 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 // Return an array of the series names, from highest to lowest sums (in
// absolute terms) // absolute terms)
@ -48,21 +47,21 @@ module.exports = React.createClass({
}); });
return seriesNames; return seriesNames;
}, }
calcAxisMarkSeparation: function(minMax, height, ticksPerHeight) { calcAxisMarkSeparation(minMax, height, ticksPerHeight) {
var targetTicks = height / ticksPerHeight; var targetTicks = height / ticksPerHeight;
var range = minMax[1]-minMax[0]; var range = minMax[1]-minMax[0];
var rangePerTick = range/targetTicks; var rangePerTick = range/targetTicks;
var roundOrder = Math.floor(Math.log(rangePerTick) / Math.LN10); var roundOrder = Math.floor(Math.log(rangePerTick) / Math.LN10);
var roundTo = Math.pow(10, roundOrder); var roundTo = Math.pow(10, roundOrder);
return Math.ceil(rangePerTick/roundTo)*roundTo; return Math.ceil(rangePerTick/roundTo)*roundTo;
}, }
render: function() { render() {
height = 400; var height = 400;
width = 600; var width = 1000;
legendWidth = 100; var legendWidth = 100;
xMargin = 70; var xMargin = 70;
yMargin = 70; var yMargin = 70;
height -= yMargin*2; height -= yMargin*2;
width -= xMargin*2; width -= xMargin*2;
@ -189,4 +188,6 @@ module.exports = React.createClass({
</svg> </svg>
); );
} }
}); }
module.exports = StackedBarChart;

View File

@ -14,36 +14,39 @@ var ReactDOM = require('react-dom');
var User = require('../models').User; var User = require('../models').User;
const LoginBar = React.createClass({ class LoginBar extends React.Component {
getInitialState: function() { constructor() {
return {username: '', password: ''}; super();
}, this.state = {username: '', password: ''};
onUsernameChange: function(e) { this.onSubmit = this.handleSubmit.bind(this);
this.onNewUserSubmit = this.handleNewUserSubmit.bind(this);
}
onUsernameChange(e) {
this.setState({username: e.target.value}); this.setState({username: e.target.value});
}, }
onPasswordChange: function(e) { onPasswordChange(e) {
this.setState({password: e.target.value}); this.setState({password: e.target.value});
}, }
handleSubmit: function(e) { handleSubmit(e) {
var user = new User(); var user = new User();
e.preventDefault(); e.preventDefault();
user.Username = ReactDOM.findDOMNode(this.refs.username).value; user.Username = ReactDOM.findDOMNode(this.refs.username).value;
user.Password = ReactDOM.findDOMNode(this.refs.password).value; user.Password = ReactDOM.findDOMNode(this.refs.password).value;
this.props.onLogin(user); this.props.onLogin(user);
}, }
handleNewUserSubmit: function(e) { handleNewUserSubmit(e) {
e.preventDefault(); e.preventDefault();
this.props.onCreateNewUser(); this.props.onCreateNewUser();
}, }
render: function() { render() {
return ( return (
<form onSubmit={this.handleSubmit}> <form onSubmit={this.onSubmit}>
<FormGroup> <FormGroup>
<Row> <Row>
<Col xs={4}></Col> <Col xs={4}></Col>
<Col xs={2}> <Col xs={2}>
<Button bsStyle="link" <Button bsStyle="link"
onClick={this.handleNewUserSubmit}>Create New User</Button> onClick={this.onNewUserSubmit}>Create New User</Button>
</Col> </Col>
<Col xs={2}> <Col xs={2}>
<FormControl type="text" <FormControl type="text"
@ -64,18 +67,22 @@ const LoginBar = React.createClass({
</form> </form>
); );
} }
}); }
const LogoutBar = React.createClass({ class LogoutBar extends React.Component {
handleOnSelect: function(key) { constructor() {
super();
this.onSelect = this.handleOnSelect.bind(this);
}
handleOnSelect(key) {
if (key == 1) { if (key == 1) {
if (this.props.onAccountSettings != null) if (this.props.onAccountSettings != null)
this.props.onAccountSettings(); this.props.onAccountSettings();
} else if (key == 2) { } else if (key == 2) {
this.props.onLogout(); this.props.onLogout();
} }
}, }
render: function() { render() {
var signedInString = "Signed in as "+this.props.user.Name; var signedInString = "Signed in as "+this.props.user.Name;
return ( return (
<FormGroup> <FormGroup>
@ -84,7 +91,7 @@ const LogoutBar = React.createClass({
<Col xs={6}></Col> <Col xs={6}></Col>
<Col xs={4}> <Col xs={4}>
<div className="pull-right"> <div className="pull-right">
<DropdownButton id="logout-settings-dropdown" title={signedInString} onSelect={this.handleOnSelect} bsStyle="info"> <DropdownButton id="logout-settings-dropdown" title={signedInString} onSelect={this.onSelect} bsStyle="info">
<MenuItem eventKey={1}>Account Settings</MenuItem> <MenuItem eventKey={1}>Account Settings</MenuItem>
<MenuItem eventKey={2}>Logout</MenuItem> <MenuItem eventKey={2}>Logout</MenuItem>
</DropdownButton> </DropdownButton>
@ -94,11 +101,10 @@ const LogoutBar = React.createClass({
</FormGroup> </FormGroup>
); );
} }
}); }
module.exports = React.createClass({ class TopBar extends React.Component {
displayName: "TopBar", render() {
render: function() {
var barContents; var barContents;
var errorAlert; var errorAlert;
if (!this.props.user.isUser()) if (!this.props.user.isUser())
@ -120,4 +126,6 @@ module.exports = React.createClass({
</div> </div>
); );
} }
}); }
module.exports = TopBar;

View File

@ -10,15 +10,15 @@ function getJSONObj(json_input) {
return null return null
} }
function User() { class User {
constructor() {
this.UserId = -1; this.UserId = -1;
this.Name = ""; this.Name = "";
this.Username = ""; this.Username = "";
this.Password = ""; this.Password = "";
this.Email = ""; this.Email = "";
} }
toJSON() {
User.prototype.toJSON = function() {
var json_obj = {}; var json_obj = {};
json_obj.UserId = this.UserId; json_obj.UserId = this.UserId;
json_obj.Name = this.Name; json_obj.Name = this.Name;
@ -26,9 +26,8 @@ User.prototype.toJSON = function() {
json_obj.Password = this.Password; json_obj.Password = this.Password;
json_obj.Email = this.Email; json_obj.Email = this.Email;
return JSON.stringify(json_obj); return JSON.stringify(json_obj);
} }
fromJSON(json_input) {
User.prototype.fromJSON = function(json_input) {
var json_obj = getJSONObj(json_input); var json_obj = getJSONObj(json_input);
if (json_obj.hasOwnProperty("UserId")) if (json_obj.hasOwnProperty("UserId"))
@ -41,39 +40,38 @@ User.prototype.fromJSON = function(json_input) {
this.Password = json_obj.Password; this.Password = json_obj.Password;
if (json_obj.hasOwnProperty("Email")) if (json_obj.hasOwnProperty("Email"))
this.Email = json_obj.Email; this.Email = json_obj.Email;
} }
isUser() {
User.prototype.isUser = function() {
var empty_user = new User(); var empty_user = new User();
return this.UserId != empty_user.UserId || return this.UserId != empty_user.UserId ||
this.Username != empty_user.Username; this.Username != empty_user.Username;
}
} }
function Session() { class Session {
constructor() {
this.SessionId = -1; this.SessionId = -1;
this.UserId = -1; this.UserId = -1;
} }
toJSON() {
Session.prototype.toJSON = function() {
var json_obj = {}; var json_obj = {};
json_obj.SessionId = this.SessionId; json_obj.SessionId = this.SessionId;
json_obj.UserId = this.UserId; json_obj.UserId = this.UserId;
return JSON.stringify(json_obj); return JSON.stringify(json_obj);
} }
fromJSON(json_input) {
Session.prototype.fromJSON = function(json_input) {
var json_obj = getJSONObj(json_input); var json_obj = getJSONObj(json_input);
if (json_obj.hasOwnProperty("SessionId")) if (json_obj.hasOwnProperty("SessionId"))
this.SessionId = json_obj.SessionId; this.SessionId = json_obj.SessionId;
if (json_obj.hasOwnProperty("UserId")) if (json_obj.hasOwnProperty("UserId"))
this.UserId = json_obj.UserId; this.UserId = json_obj.UserId;
} }
isSession() {
Session.prototype.isSession = function() {
var empty_session = new Session(); var empty_session = new Session();
return this.SessionId != empty_session.SessionId || return this.SessionId != empty_session.SessionId ||
this.UserId != empty_session.UserId; this.UserId != empty_session.UserId;
}
} }
const SecurityType = { const SecurityType = {
@ -87,7 +85,8 @@ for (var type in SecurityType) {
} }
} }
function Security() { class Security {
constructor() {
this.SecurityId = -1; this.SecurityId = -1;
this.Name = ""; this.Name = "";
this.Description = ""; this.Description = "";
@ -95,9 +94,8 @@ function Security() {
this.Precision = -1; this.Precision = -1;
this.Type = -1; this.Type = -1;
this.AlternateId = ""; this.AlternateId = "";
} }
toJSON() {
Security.prototype.toJSON = function() {
var json_obj = {}; var json_obj = {};
json_obj.SecurityId = this.SecurityId; json_obj.SecurityId = this.SecurityId;
json_obj.Name = this.Name; json_obj.Name = this.Name;
@ -107,9 +105,8 @@ Security.prototype.toJSON = function() {
json_obj.Type = this.Type; json_obj.Type = this.Type;
json_obj.AlternateId = this.AlternateId; json_obj.AlternateId = this.AlternateId;
return JSON.stringify(json_obj); return JSON.stringify(json_obj);
} }
fromJSON(json_input) {
Security.prototype.fromJSON = function(json_input) {
var json_obj = getJSONObj(json_input); var json_obj = getJSONObj(json_input);
if (json_obj.hasOwnProperty("SecurityId")) if (json_obj.hasOwnProperty("SecurityId"))
@ -126,12 +123,12 @@ Security.prototype.fromJSON = function(json_input) {
this.Type = json_obj.Type; this.Type = json_obj.Type;
if (json_obj.hasOwnProperty("AlternateId")) if (json_obj.hasOwnProperty("AlternateId"))
this.AlternateId = json_obj.AlternateId; this.AlternateId = json_obj.AlternateId;
} }
isSecurity() {
Security.prototype.isSecurity = function() {
var empty_account = new Security(); var empty_account = new Security();
return this.SecurityId != empty_account.SecurityId || return this.SecurityId != empty_account.SecurityId ||
this.Type != empty_account.Type; this.Type != empty_account.Type;
}
} }
const AccountType = { const AccountType = {
@ -154,7 +151,8 @@ for (var type in AccountType) {
} }
} }
function Account() { class Account {
constructor() {
this.AccountId = -1; this.AccountId = -1;
this.UserId = -1; this.UserId = -1;
this.SecurityId = -1; this.SecurityId = -1;
@ -174,9 +172,8 @@ function Account() {
this.OFXAppVer = ""; this.OFXAppVer = "";
this.OFXVersion = ""; this.OFXVersion = "";
this.OFXNoIndent = false this.OFXNoIndent = false
} }
toJSON() {
Account.prototype.toJSON = function() {
var json_obj = {}; var json_obj = {};
json_obj.AccountId = this.AccountId; json_obj.AccountId = this.AccountId;
json_obj.UserId = this.UserId; json_obj.UserId = this.UserId;
@ -197,9 +194,8 @@ Account.prototype.toJSON = function() {
json_obj.OFXVersion = this.OFXVersion; json_obj.OFXVersion = this.OFXVersion;
json_obj.OFXNoIndent = this.OFXNoIndent; json_obj.OFXNoIndent = this.OFXNoIndent;
return JSON.stringify(json_obj); return JSON.stringify(json_obj);
} }
fromJSON(json_input) {
Account.prototype.fromJSON = function(json_input) {
var json_obj = getJSONObj(json_input); var json_obj = getJSONObj(json_input);
if (json_obj.hasOwnProperty("AccountId")) if (json_obj.hasOwnProperty("AccountId"))
@ -238,17 +234,16 @@ Account.prototype.fromJSON = function(json_input) {
this.OFXVersion = json_obj.OFXVersion; this.OFXVersion = json_obj.OFXVersion;
if (json_obj.hasOwnProperty("OFXNoIndent")) if (json_obj.hasOwnProperty("OFXNoIndent"))
this.OFXNoIndent = json_obj.OFXNoIndent; this.OFXNoIndent = json_obj.OFXNoIndent;
} }
isAccount() {
Account.prototype.isAccount = function() {
var empty_account = new Account(); var empty_account = new Account();
return this.AccountId != empty_account.AccountId || return this.AccountId != empty_account.AccountId ||
this.UserId != empty_account.UserId; this.UserId != empty_account.UserId;
} }
isRootAccount() {
Account.prototype.isRootAccount = function() {
var empty_account = new Account(); var empty_account = new Account();
return this.ParentAccountId == empty_account.ParentAccountId; return this.ParentAccountId == empty_account.ParentAccountId;
}
} }
const SplitStatus = { const SplitStatus = {
@ -271,7 +266,8 @@ for (var status in SplitStatus) {
} }
} }
function Split() { class Split {
constructor() {
this.SplitId = -1; this.SplitId = -1;
this.TransactionId = -1; this.TransactionId = -1;
this.AccountId = -1; this.AccountId = -1;
@ -281,9 +277,8 @@ function Split() {
this.Memo = ""; this.Memo = "";
this.Amount = new Big(0.0); this.Amount = new Big(0.0);
this.Debit = false; this.Debit = false;
} }
toJSONobj() {
Split.prototype.toJSONobj = function() {
var json_obj = {}; var json_obj = {};
json_obj.SplitId = this.SplitId; json_obj.SplitId = this.SplitId;
json_obj.TransactionId = this.TransactionId; json_obj.TransactionId = this.TransactionId;
@ -295,9 +290,8 @@ Split.prototype.toJSONobj = function() {
json_obj.Amount = this.Amount.toFixed(); json_obj.Amount = this.Amount.toFixed();
json_obj.Debit = this.Debit; json_obj.Debit = this.Debit;
return json_obj; return json_obj;
} }
fromJSONobj(json_obj) {
Split.prototype.fromJSONobj = function(json_obj) {
if (json_obj.hasOwnProperty("SplitId")) if (json_obj.hasOwnProperty("SplitId"))
this.SplitId = json_obj.SplitId; this.SplitId = json_obj.SplitId;
if (json_obj.hasOwnProperty("TransactionId")) if (json_obj.hasOwnProperty("TransactionId"))
@ -316,25 +310,25 @@ Split.prototype.fromJSONobj = function(json_obj) {
this.Amount = new Big(json_obj.Amount); this.Amount = new Big(json_obj.Amount);
if (json_obj.hasOwnProperty("Debit")) if (json_obj.hasOwnProperty("Debit"))
this.Debit = json_obj.Debit; this.Debit = json_obj.Debit;
} }
isSplit() {
Split.prototype.isSplit = function() {
var empty_split = new Split(); var empty_split = new Split();
return this.SplitId != empty_split.SplitId || return this.SplitId != empty_split.SplitId ||
this.TransactionId != empty_split.TransactionId || this.TransactionId != empty_split.TransactionId ||
this.AccountId != empty_split.AccountId || this.AccountId != empty_split.AccountId ||
this.SecurityId != empty_split.SecurityId; this.SecurityId != empty_split.SecurityId;
}
} }
function Transaction() { class Transaction {
constructor() {
this.TransactionId = -1; this.TransactionId = -1;
this.UserId = -1; this.UserId = -1;
this.Description = ""; this.Description = "";
this.Date = new Date(); this.Date = new Date();
this.Splits = []; this.Splits = [];
} }
toJSON() {
Transaction.prototype.toJSON = function() {
var json_obj = {}; var json_obj = {};
json_obj.TransactionId = this.TransactionId; json_obj.TransactionId = this.TransactionId;
json_obj.UserId = this.UserId; json_obj.UserId = this.UserId;
@ -344,9 +338,8 @@ Transaction.prototype.toJSON = function() {
for (var i = 0; i < this.Splits.length; i++) for (var i = 0; i < this.Splits.length; i++)
json_obj.Splits.push(this.Splits[i].toJSONobj()); json_obj.Splits.push(this.Splits[i].toJSONobj());
return JSON.stringify(json_obj); return JSON.stringify(json_obj);
} }
fromJSON(json_input) {
Transaction.prototype.fromJSON = function(json_input) {
var json_obj = getJSONObj(json_input); var json_obj = getJSONObj(json_input);
if (json_obj.hasOwnProperty("TransactionId")) if (json_obj.hasOwnProperty("TransactionId"))
@ -373,28 +366,25 @@ Transaction.prototype.fromJSON = function(json_input) {
this.Splits.push(s); this.Splits.push(s);
} }
} }
} }
isTransaction() {
Transaction.prototype.isTransaction = function() {
var empty_transaction = new Transaction(); var empty_transaction = new Transaction();
return this.TransactionId != empty_transaction.TransactionId || return this.TransactionId != empty_transaction.TransactionId ||
this.UserId != empty_transaction.UserId; this.UserId != empty_transaction.UserId;
} }
deepCopy() {
Transaction.prototype.deepCopy = function() {
var t = new Transaction(); var t = new Transaction();
t.fromJSON(this.toJSON()); t.fromJSON(this.toJSON());
return t; return t;
} }
imbalancedSplitSecurities(account_map) {
Transaction.prototype.imbalancedSplitSecurities = function(account_map) {
// Return a list of SecurityIDs for those securities that aren't balanced // 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 // in this transaction's splits. If a split's AccountId is invalid, that
// split is ignored, so those must be checked elsewhere // split is ignored, so those must be checked elsewhere
var splitBalances = {}; var splitBalances = {};
const emptySplit = new Split(); const emptySplit = new Split();
for (var i = 0; i < this.Splits.length; i++) { for (var i = 0; i < this.Splits.length; i++) {
split = this.Splits[i]; var split = this.Splits[i];
var securityId = -1; var securityId = -1;
if (split.AccountId != emptySplit.AccountId) { if (split.AccountId != emptySplit.AccountId) {
securityId = account_map[split.AccountId].SecurityId; securityId = account_map[split.AccountId].SecurityId;
@ -416,42 +406,41 @@ Transaction.prototype.imbalancedSplitSecurities = function(account_map) {
} }
} }
return imbalancedIDs; return imbalancedIDs;
}
} }
function Error() { class Error {
constructor() {
this.ErrorId = -1; this.ErrorId = -1;
this.ErrorString = ""; this.ErrorString = "";
} }
toJSON() {
Error.prototype.toJSON = function() {
var json_obj = {}; var json_obj = {};
json_obj.ErrorId = this.ErrorId; json_obj.ErrorId = this.ErrorId;
json_obj.ErrorString = this.ErrorString; json_obj.ErrorString = this.ErrorString;
return JSON.stringify(json_obj); return JSON.stringify(json_obj);
} }
fromJSON(json_input) {
Error.prototype.fromJSON = function(json_input) {
var json_obj = getJSONObj(json_input); var json_obj = getJSONObj(json_input);
if (json_obj.hasOwnProperty("ErrorId")) if (json_obj.hasOwnProperty("ErrorId"))
this.ErrorId = json_obj.ErrorId; this.ErrorId = json_obj.ErrorId;
if (json_obj.hasOwnProperty("ErrorString")) if (json_obj.hasOwnProperty("ErrorString"))
this.ErrorString = json_obj.ErrorString; this.ErrorString = json_obj.ErrorString;
} }
isError() {
Error.prototype.isError = function() {
var empty_error = new Error(); var empty_error = new Error();
return this.ErrorId != empty_error.ErrorId || return this.ErrorId != empty_error.ErrorId ||
this.ErrorString != empty_error.ErrorString; this.ErrorString != empty_error.ErrorString;
}
} }
class Series {
function Series() { constructor() {
this.Values = []; this.Values = [];
this.Series = {}; this.Series = {};
} }
toJSONobj() {
Series.prototype.toJSONobj = function() {
var json_obj = {}; var json_obj = {};
json_obj.Values = this.Values; json_obj.Values = this.Values;
json_obj.Series = {}; json_obj.Series = {};
@ -460,9 +449,8 @@ Series.prototype.toJSONobj = function() {
json_obj.Series[child] = this.Series[child].toJSONobj(); json_obj.Series[child] = this.Series[child].toJSONobj();
} }
return json_obj; return json_obj;
} }
fromJSONobj(json_obj) {
Series.prototype.fromJSONobj = function(json_obj) {
if (json_obj.hasOwnProperty("Values")) if (json_obj.hasOwnProperty("Values"))
this.Values = json_obj.Values; this.Values = json_obj.Values;
if (json_obj.hasOwnProperty("Series")) { if (json_obj.hasOwnProperty("Series")) {
@ -472,18 +460,16 @@ Series.prototype.fromJSONobj = function(json_obj) {
this.Series[child].fromJSONobj(json_obj.Series[child]); this.Series[child].fromJSONobj(json_obj.Series[child]);
} }
} }
} }
mapReduceChildren(mapFn, reduceFn) {
Series.prototype.mapReduceChildren = function(mapFn, reduceFn) {
var children = {} var children = {}
for (var child in this.Series) { for (var child in this.Series) {
if (this.Series.hasOwnProperty(child)) if (this.Series.hasOwnProperty(child))
children[child] = this.Series[child].mapReduce(mapFn, reduceFn); children[child] = this.Series[child].mapReduce(mapFn, reduceFn);
} }
return children; return children;
} }
mapReduce(mapFn, reduceFn) {
Series.prototype.mapReduce = function(mapFn, reduceFn) {
var childValues = []; var childValues = [];
if (mapFn) if (mapFn)
childValues.push(this.Values.map(mapFn)); childValues.push(this.Values.map(mapFn));
@ -505,9 +491,11 @@ Series.prototype.mapReduce = function(mapFn, reduceFn) {
} }
return reducedValues; return reducedValues;
}
} }
function Report() { class Report {
constructor() {
this.ReportId = ""; this.ReportId = "";
this.Title = ""; this.Title = "";
this.Subtitle = ""; this.Subtitle = "";
@ -516,11 +504,11 @@ function Report() {
this.Labels = []; this.Labels = [];
this.Series = {}; this.Series = {};
this.FlattenedSeries = {}; this.FlattenedSeries = {};
} }
static topLevelAccountName() {
Report.prototype.topLevelAccountName = "(top level)"; return "(top level)"
}
Report.prototype.toJSON = function() { toJSON() {
var json_obj = {}; var json_obj = {};
json_obj.ReportId = this.ReportId; json_obj.ReportId = this.ReportId;
json_obj.Title = this.Title; json_obj.Title = this.Title;
@ -534,9 +522,8 @@ Report.prototype.toJSON = function() {
json_obj.Series[series] = this.Series[series].toJSONobj(); json_obj.Series[series] = this.Series[series].toJSONobj();
} }
return JSON.stringify(json_obj); return JSON.stringify(json_obj);
} }
fromJSON(json_input) {
Report.prototype.fromJSON = function(json_input) {
var json_obj = getJSONObj(json_input) var json_obj = getJSONObj(json_input)
if (json_obj.hasOwnProperty("ReportId")) if (json_obj.hasOwnProperty("ReportId"))
@ -558,37 +545,36 @@ Report.prototype.fromJSON = function(json_input) {
this.Series[series].fromJSONobj(json_obj.Series[series]); this.Series[series].fromJSONobj(json_obj.Series[series]);
} }
} }
} }
mapReduceChildren(mapFn, reduceFn) {
Report.prototype.mapReduceChildren = function(mapFn, reduceFn) {
var series = {} var series = {}
for (var child in this.Series) { for (var child in this.Series) {
if (this.Series.hasOwnProperty(child)) if (this.Series.hasOwnProperty(child))
series[child] = this.Series[child].mapReduce(mapFn, reduceFn); series[child] = this.Series[child].mapReduce(mapFn, reduceFn);
} }
return series; return series;
} }
mapReduceSeries(mapFn, reduceFn) {
Report.prototype.mapReduceSeries = function(mapFn, reduceFn) {
return this.mapReduceChildren(mapFn, reduceFn); return this.mapReduceChildren(mapFn, reduceFn);
}
} }
function OFXDownload() { class OFXDownload {
constructor() {
this.OFXPassword = ""; this.OFXPassword = "";
this.StartDate = new Date(); this.StartDate = new Date();
this.EndDate = new Date(); this.EndDate = new Date();
} }
toJSON() {
OFXDownload.prototype.toJSON = function() {
var json_obj = {}; var json_obj = {};
json_obj.OFXPassword = this.OFXPassword; json_obj.OFXPassword = this.OFXPassword;
json_obj.StartDate = this.StartDate.toJSON(); json_obj.StartDate = this.StartDate.toJSON();
json_obj.EndDate = this.EndDate.toJSON(); json_obj.EndDate = this.EndDate.toJSON();
return JSON.stringify(json_obj); return JSON.stringify(json_obj);
}
} }
module.exports = models = { module.exports = models = {
// Classes // Classes
User: User, User: User,
Session: Session, Session: Session,