1
0
mirror of https://github.com/aclindsa/moneygo.git synced 2024-12-26 23:42:29 -05:00

Add AccountTree to select accounts

This commit is contained in:
Aaron Lindsay 2015-07-04 11:42:52 -04:00
parent cd24d5ecab
commit 81bdc03b10
4 changed files with 178 additions and 10 deletions

View File

@ -12,6 +12,8 @@ var Glyphicon = ReactBootstrap.Glyphicon;
var Modal = ReactBootstrap.Modal; var Modal = ReactBootstrap.Modal;
var CollapsibleMixin = ReactBootstrap.CollapsibleMixin;
var Combobox = ReactWidgets.Combobox; var Combobox = ReactWidgets.Combobox;
const recursiveAccountDisplayInfo = function(account, prefix) { const recursiveAccountDisplayInfo = function(account, prefix) {
@ -26,7 +28,7 @@ const getAccountDisplayList = function(account_list, includeRoot, rootName) {
if (includeRoot) if (includeRoot)
accounts.push({AccountId: -1, Name: rootName}); accounts.push({AccountId: -1, Name: rootName});
for (var i = 0; i < account_list.length; i++) { for (var i = 0; i < account_list.length; i++) {
if (account_list[i].ParentAccountId == -1) if (account_list[i].isRootAccount())
accounts = accounts.concat(recursiveAccountDisplayInfo(account_list[i], "")); accounts = accounts.concat(recursiveAccountDisplayInfo(account_list[i], ""));
} }
return accounts; return accounts;
@ -167,9 +169,105 @@ const NewAccountModal = React.createClass({
} }
}); });
const AccountTreeNode = React.createClass({
mixins: [CollapsibleMixin],
getCollapsibleDOMNode: function() {
return React.findDOMNode(this.refs.children);
},
getCollapsibleDimensionValue: function() {
return React.findDOMNode(this.refs.children).scrollHeight;
},
handleToggle: function(e) {
e.preventDefault();
this.setState({expanded:!this.state.expanded});
},
handleChildSelect: function(account) {
if (this.props.onSelect != null)
this.props.onSelect(account);
},
handleSelect: function() {
if (this.props.onSelect != null)
this.props.onSelect(this.props.account);
},
render: function() {
var styles = this.getCollapsibleClassSet();
var glyph = this.isExpanded() ? 'minus' : 'plus';
var active = (this.props.selectedAccount != null &&
this.props.account.AccountId == this.props.selectedAccount.AccountId);
var buttonStyle = active ? "info" : "link";
var self = this;
var children = this.props.account.Children.map(function(account) {
return (
<AccountTreeNode
account={account}
selectedAccount={self.props.selectedAccount}
onSelect={self.handleChildSelect}/>
);
});
var accounttreeClasses = "accounttree"
var expandButton = [];
if (children.length > 0)
expandButton.push((
<Button onClick={this.handleToggle}
bsSize="xsmall"
bsStyle="link"
className="accounttree-expandbutton">
<Glyphicon glyph={glyph} bsSize="xsmall"/>
</Button>
));
else
accounttreeClasses += "-nochildren";
return (
<div className={accounttreeClasses}>
{expandButton}
<Button onClick={this.handleSelect}
bsStyle={buttonStyle}
className="accounttree-name">
{this.props.account.Name}
</Button>
<div ref='children' className={classNames(styles)}>
{children}
</div>
</div>
);
}
});
const AccountTree = React.createClass({
getInitialState: function() {
return {selectedAccount: null};
},
handleSelect: function(account) {
this.setState({selectedAccount: account});
if (this.props.onSelect != null) {
this.props.onSelect(account);
}
},
render: function() {
var accounts = this.props.accounts;
var children = [];
for (var i = 0; i < accounts.length; i++) {
if (accounts[i].isRootAccount())
children.push((<AccountTreeNode
account={accounts[i]}
selectedAccount={this.state.selectedAccount}
onSelect={this.handleSelect}/>));
}
return (
<div className="accounttree-root">
{children}
</div>
);
}
});
const AccountsTab = React.createClass({ const AccountsTab = React.createClass({
getInitialState: function() { getInitialState: function() {
return { return {
selectedAccount: null,
creatingNewAccount: false creatingNewAccount: false
}; };
}, },
@ -190,16 +288,13 @@ const AccountsTab = React.createClass({
this.props.onCreateAccount(account); this.props.onCreateAccount(account);
this.setState({creatingNewAccount: false}); this.setState({creatingNewAccount: false});
}, },
handleAccountSelected: function(account) {
this.setState({selectedAccount: account});
},
render: function() { render: function() {
var accounts = this.props.accounts; var accounts = this.props.accounts;
var account_map = this.props.account_map; var account_map = this.props.account_map;
var listGroupItems = accounts.map(function(account) {
return (
<ListGroupItem>{account.Name}</ListGroupItem>
);
});
return ( return (
<Grid fluid><Row> <Grid fluid><Row>
<Col xs={2}> <Col xs={2}>
@ -210,9 +305,9 @@ const AccountsTab = React.createClass({
onCancel={this.handleCreationCancel} onCancel={this.handleCreationCancel}
onSubmit={this.handleCreateAccount} onSubmit={this.handleCreateAccount}
securities={this.props.securities}/> securities={this.props.securities}/>
<ListGroup> <AccountTree
{listGroupItems} accounts={accounts}
</ListGroup> onSelect={this.handleAccountSelected}/>
<ButtonGroup className="pull-right"> <ButtonGroup className="pull-right">
<Button onClick={this.handleNewAccount} bsStyle="success"> <Button onClick={this.handleNewAccount} bsStyle="success">
<Glyphicon glyph='plus-sign' /></Button> <Glyphicon glyph='plus-sign' /></Button>

49
static/external/classnames/index.js vendored Normal file
View File

@ -0,0 +1,49 @@
/*!
Copyright (c) 2015 Jed Watson.
Licensed under the MIT License (MIT), see
http://jedwatson.github.io/classnames
*/
(function () {
'use strict';
function classNames () {
var classes = '';
for (var i = 0; i < arguments.length; i++) {
var arg = arguments[i];
if (!arg) continue;
var argType = typeof arg;
if ('string' === argType || 'number' === argType) {
classes += ' ' + arg;
} else if (Array.isArray(arg)) {
classes += ' ' + classNames.apply(null, arg);
} else if ('object' === argType) {
for (var key in arg) {
if (arg.hasOwnProperty(key) && arg[key]) {
classes += ' ' + key;
}
}
}
}
return classes.substr(1);
}
if (typeof module !== 'undefined' && module.exports) {
module.exports = classNames;
} else if (typeof define === 'function' && typeof define.amd === 'object' && define.amd){
// AMD. Register as an anonymous module.
define(function () {
return classNames;
});
} else {
window.classNames = classNames;
}
}());

View File

@ -15,6 +15,7 @@
<script src="static/external/react-bootstrap/react-bootstrap.min.js"></script> <script src="static/external/react-bootstrap/react-bootstrap.min.js"></script>
<script src="static/external/react-widgets/react-widgets.js"></script> <script src="static/external/react-widgets/react-widgets.js"></script>
<script src="static/external/big/big.min.js"></script> <script src="static/external/big/big.min.js"></script>
<script src="static/external/classnames/index.js"></script>
<script type="text/javascript" src="static/utils.js"></script> <script type="text/javascript" src="static/utils.js"></script>
<script type="text/javascript" src="static/models.js"></script> <script type="text/javascript" src="static/models.js"></script>

View File

@ -7,3 +7,26 @@ div#content {
margin-left: auto; margin-left: auto;
margin-right: auto; margin-right: auto;
} }
div.accounttree-root-nochildren {
position: relative;
left: 24px;
}
div.accounttree {
position: relative;
left: -24px;
}
div.accounttree-nochildren {
position: relative;
left: 0px;
}
div.accounttree div {
padding-left: 24px;
}
div.accounttree-root div {
padding-left: 24px;
}
.accounttree-name {
padding: 3px;
}