From a27bf82af322111436f66ba9ae46cd10d2dd63a7 Mon Sep 17 00:00:00 2001 From: Aaron Lindsay Date: Fri, 2 Nov 2018 21:15:33 -0400 Subject: [PATCH] Add new account dropdown with search to top bar --- js/components/AccountRegister.js | 17 +-- js/components/AccountsTab.js | 132 +++++++------------ js/components/MoneyGoApp.js | 175 ++++++++++++++++++++++---- js/components/TopBar.js | 6 +- js/containers/AccountsTabContainer.js | 1 - js/containers/MoneyGoAppContainer.js | 11 +- static/css/stylesheet.css | 46 +++---- 7 files changed, 230 insertions(+), 158 deletions(-) diff --git a/js/components/AccountRegister.js b/js/components/AccountRegister.js index 0379a7a..6604b6b 100644 --- a/js/components/AccountRegister.js +++ b/js/components/AccountRegister.js @@ -106,8 +106,8 @@ class TransactionRow extends React.Component { {this.props.transaction.Description} {accountName} {status} - {amount} - {balance} + {amount} + {balance} ); } } @@ -722,7 +722,6 @@ class AccountRegister extends React.Component { super(); this.state = { newTransaction: null, - height: 0 }; this.onEditTransaction = this.handleEditTransaction.bind(this); this.onEditingCancel = this.handleEditingCancel.bind(this); @@ -732,20 +731,11 @@ class AccountRegister extends React.Component { this.onUpdateTransaction = this.handleUpdateTransaction.bind(this); this.onDeleteTransaction = this.handleDeleteTransaction.bind(this); } - resize() { - var div = ReactDOM.findDOMNode(this); - this.setState({height: div.parentElement.clientHeight - 64}); - } componentWillReceiveProps(nextProps) { if (!nextProps.transactionPage.upToDate && nextProps.selectedAccount != -1) { nextProps.onFetchTransactionPage(nextProps.accounts[nextProps.selectedAccount], nextProps.transactionPage.pageSize, nextProps.transactionPage.page); } } - componentDidMount() { - this.resize(); - var self = this; - $(window).resize(function() {self.resize();}); - } handleEditTransaction(transaction) { this.props.onSelectTransaction(transaction.TransactionId); } @@ -826,9 +816,8 @@ class AccountRegister extends React.Component { )); } - var style = {height: this.state.height + "px"}; register = ( -
+
diff --git a/js/components/AccountsTab.js b/js/components/AccountsTab.js index f508abe..c4e7ae1 100644 --- a/js/components/AccountsTab.js +++ b/js/components/AccountsTab.js @@ -155,23 +155,15 @@ class AccountsTab extends React.Component { constructor() { super(); this.state = { - creatingNewAccount: false, editingAccount: false, deletingAccount: false }; - this.onNewAccount = this.handleNewAccount.bind(this); 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}); } handleEditAccount() { this.setState({editingAccount: true}); @@ -179,20 +171,12 @@ class AccountsTab extends React.Component { handleDeleteAccount() { this.setState({deletingAccount: true}); } - handleCreationCancel() { - this.setState({creatingNewAccount: false}); - } handleEditingCancel() { this.setState({editingAccount: false}); } handleDeletionCancel() { this.setState({deletingAccount: false}); } - handleCreateAccount(account) { - if (this.props.onCreateAccount != null) - this.props.onCreateAccount(account); - this.setState({creatingNewAccount: false}); - } handleUpdateAccount(account) { if (this.props.onUpdateAccount != null) this.props.onUpdateAccount(account); @@ -203,10 +187,6 @@ class AccountsTab extends React.Component { this.props.onDeleteAccount(account); this.setState({deletingAccount: false}); } - handleAccountSelected(account) { - this.props.onSelectAccount(account.AccountId); - this.props.onFetchTransactionPage(account, 20, 0); - } render() { var disabled = (this.props.selectedAccount == -1) ? true : false; @@ -215,71 +195,53 @@ class AccountsTab extends React.Component { selectedAccount = this.props.accounts[this.props.selectedAccount]; return ( - - - - - - - - - - - - - - - +
+ + + + + + + +
); } } diff --git a/js/components/MoneyGoApp.js b/js/components/MoneyGoApp.js index b8046b2..4d546ff 100644 --- a/js/components/MoneyGoApp.js +++ b/js/components/MoneyGoApp.js @@ -1,10 +1,23 @@ var React = require('react'); +var ReactDOM = require('react-dom'); var ReactBootstrap = require('react-bootstrap'); var Jumbotron = ReactBootstrap.Jumbotron; var Tabs = ReactBootstrap.Tabs; var Tab = ReactBootstrap.Tab; +var Nav = ReactBootstrap.Nav; +var NavDropdown = ReactBootstrap.NavDropdown; +var NavItem = ReactBootstrap.NavItem; +var Col = ReactBootstrap.Col; +var Row = ReactBootstrap.Row; var Modal = ReactBootstrap.Modal; +var FormControl = ReactBootstrap.FormControl; +var InputGroup = ReactBootstrap.InputGroup; +var Button = ReactBootstrap.Button; +var Glyphicon = ReactBootstrap.Glyphicon; + +var MenuItem = ReactBootstrap.MenuItem; +var SplitButton = ReactBootstrap.SplitButton; var TopBarContainer = require('../containers/TopBarContainer'); var NewUserModalContainer = require('../containers/NewUserModalContainer'); @@ -12,28 +25,43 @@ var AccountSettingsModalContainer = require('../containers/AccountSettingsModalC var AccountsTabContainer = require('../containers/AccountsTabContainer'); var SecuritiesTabContainer = require('../containers/SecuritiesTabContainer'); var ReportsTabContainer = require('../containers/ReportsTabContainer'); +var AddEditAccountModal = require('./AddEditAccountModal'); + +var AccountTree = require('./AccountTree'); + +var utils = require('../utils'); class MoneyGoApp extends React.Component { constructor() { super(); this.state = { + tab: 1, + accountFilter: "", showNewUserModal: false, - showAccountSettingsModal: false + showSettingsModal: false, + creatingNewAccount: false }; this.onShowSettings = this.handleShowSettings.bind(this); this.onHideSettings = this.handleHideSettings.bind(this); this.onShowNewUser = this.handleShowNewUser.bind(this); this.onHideNewUser = this.handleHideNewUser.bind(this); + this.onSelectTab = this.handleSelectTab.bind(this); + this.onAccountSelected = this.handleAccountSelected.bind(this); + this.onNewAccount = this.handleNewAccount.bind(this); + this.onNewAccountCancel = this.handleNewAccountCancel.bind(this); + this.onCreateAccount = this.handleCreateAccount.bind(this); + this.onAccountFilterChange = this.handleAccountFilterChange.bind(this); + this.onClearAccountFilter = this.handleClearAccountFilter.bind(this); } componentDidMount() { this.props.tryResumingSession(); this.props.fetchCurrencies(); } handleShowSettings() { - this.setState({showAccountSettingsModal: true}); + this.setState({showSettingsModal: true}); } handleHideSettings(user) { - this.setState({showAccountSettingsModal: false}); + this.setState({showSettingsModal: false}); } handleShowNewUser() { this.setState({showNewUserModal: true}); @@ -41,27 +69,117 @@ class MoneyGoApp extends React.Component { handleHideNewUser() { this.setState({showNewUserModal: false}); } + handleSelectTab(key) { + console.log(key); + if (key != undefined) { + this.setState({tab: key}); + } + } + handleAccountSelected(account) { + this.setState({ + tab: 1, + accountFilter: ""}); + this.props.onSelectAccount(account.AccountId); + this.props.onFetchTransactionPage(account, 20, 0); + } + handleNewAccount() { + this.setState({creatingNewAccount: true}); + } + handleNewAccountCancel() { + this.setState({creatingNewAccount: false}); + } + handleCreateAccount(account) { + this.props.onCreateAccount(account); + this.setState({creatingNewAccount: false}); + } + handleAccountFilterChange() { + this.setState({accountFilter: ReactDOM.findDOMNode(this.refs.accountFilter).value}); + } + handleClearAccountFilter() { + this.setState({accountFilter: ""}); + } render() { var mainContent; - if (this.props.user.isUser()) + if (this.props.user.isUser()) { + var accountElements = []; + if (this.state.accountFilter.length > 0) { + var filterRegex = new RegExp(this.state.accountFilter, "i") + for (var accountId in this.props.accounts) { + var account = this.props.accounts[accountId]; + var fullName = utils.getAccountDisplayName(account, this.props.accounts); + if (fullName.match(filterRegex)) { + var clojure = function(self, account) { + return function() { + self.handleAccountSelected(account); + }; + }(this, account); + accountElements.push(({fullName})); + } + } + } else { + accountElements.push(()); + accountElements.push(()); + } + mainContent = ( - - - - - - - - Scheduled transactions go here... - Budgets go here... - - - - ); - else + + +
+ + + + + + + + + + + + Scheduled transactions go here... + + + Budgets go here... + + + + + + + + ); + } else { mainContent = (
@@ -69,21 +187,30 @@ class MoneyGoApp extends React.Component {

Go manage your money.

); + } return ( -
+
+ onSettings={this.onShowSettings} /> {mainContent} +
); } diff --git a/js/components/TopBar.js b/js/components/TopBar.js index 16ebf89..2e34c3e 100644 --- a/js/components/TopBar.js +++ b/js/components/TopBar.js @@ -76,8 +76,8 @@ class LogoutBar extends React.Component { } handleOnSelect(key) { if (key == 1) { - if (this.props.onAccountSettings != null) - this.props.onAccountSettings(); + if (this.props.onSettings != null) + this.props.onSettings(); } else if (key == 2) { this.props.onLogout(); } @@ -110,7 +110,7 @@ class TopBar extends React.Component { if (!this.props.user.isUser()) barContents = ; else - barContents = ; + barContents = ; if (this.props.error.isError()) errorAlert = diff --git a/js/containers/AccountsTabContainer.js b/js/containers/AccountsTabContainer.js index 9fe102e..a24fc3a 100644 --- a/js/containers/AccountsTabContainer.js +++ b/js/containers/AccountsTabContainer.js @@ -23,7 +23,6 @@ function mapStateToProps(state) { function mapDispatchToProps(dispatch) { return { onFetchAllAccounts: function() {dispatch(AccountActions.fetchAll())}, - onCreateAccount: function(account) {dispatch(AccountActions.create(account))}, onUpdateAccount: function(account) {dispatch(AccountActions.update(account))}, onDeleteAccount: function(account) {dispatch(AccountActions.remove(account))}, onSelectAccount: function(accountId) {dispatch(AccountActions.select(accountId))}, diff --git a/js/containers/MoneyGoAppContainer.js b/js/containers/MoneyGoAppContainer.js index 8a9edf8..1866434 100644 --- a/js/containers/MoneyGoAppContainer.js +++ b/js/containers/MoneyGoAppContainer.js @@ -1,13 +1,19 @@ var connect = require('react-redux').connect; var UserActions = require('../actions/UserActions'); +var AccountActions = require('../actions/AccountActions'); +var TransactionActions = require('../actions/TransactionActions'); var SecurityTemplateActions = require('../actions/SecurityTemplateActions'); var MoneyGoApp = require('../components/MoneyGoApp'); function mapStateToProps(state) { return { - user: state.user + user: state.user, + accounts: state.accounts.map, + accountChildren: state.accounts.children, + selectedAccount: state.selectedAccount, + security_list: state.securities.list, } } @@ -15,6 +21,9 @@ function mapDispatchToProps(dispatch) { return { tryResumingSession: function() {dispatch(UserActions.tryResumingSession())}, fetchCurrencies: function() {dispatch(SecurityTemplateActions.fetchCurrencies())}, + onCreateAccount: function(account) {dispatch(AccountActions.create(account))}, + onSelectAccount: function(accountId) {dispatch(AccountActions.select(accountId))}, + onFetchTransactionPage: function(account, pageSize, page) {dispatch(TransactionActions.fetchPage(account, pageSize, page))}, } } diff --git a/static/css/stylesheet.css b/static/css/stylesheet.css index e4f7a30..a192f73 100644 --- a/static/css/stylesheet.css +++ b/static/css/stylesheet.css @@ -1,22 +1,13 @@ @import url("reports.css"); -html, body { - height: 100%; -} div#content { display: block; width: 95%; - height: 100%; min-width: 75em; max-width: 100em; margin: auto; } -/* Keep the main windows sized to the full viewable height */ -.fullheight { - height: 100%; -} - .ui { display: flex; flex-flow: column; @@ -34,11 +25,18 @@ div#content { } /* Tabs */ + .nav-tabs { margin-bottom: 15px; } -#mainNavigationTabs .nav-tabs { - margin-bottom: 0px; + +.account-filter-menuitem > a { + padding: 0px 5px !important; +} + +.clear-account-filter { + height: 34px; + padding: 6px; } /* Style the account tree */ @@ -49,6 +47,7 @@ div.accounttree-root-nochildren { div.accounttree { position: relative; left: -24px; + white-space: nowrap; } div.accounttree-nochildren { position: relative; @@ -67,38 +66,25 @@ div.accounttree-root div { .accounttree-root { display: block; - width: 100%; - height: 100%-100px; - overflow: auto; + margin-left: 5px; } -.account-column { - padding: 15px 15px 43px 15px; - border-right: 1px solid #DDD; - border-left: 1px solid #DDD; -} -.account-buttongroup { - position: absolute; - right: 15px; - bottom: 15px; +.accounttree-expandbutton { + padding-bottom: 6px; } .transactions-container { display: block; width: 100%; - height: 100%; } .transactions-register { display: block; width: 100%; - height: 100%; overflow: auto; } -.transactions-column { - padding: 15px; - border-right: 1px solid #DDD; -} .transactions-register-toolbar { width: 100%; - height: 50px; +} +td.amount-cell { + white-space: nowrap; } .register-row-editing {
Date