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

Add new account dropdown with search to top bar

This commit is contained in:
Aaron Lindsay 2018-11-02 21:15:33 -04:00
parent 9dd32d4d14
commit a27bf82af3
7 changed files with 230 additions and 158 deletions

View File

@ -106,8 +106,8 @@ class TransactionRow extends React.Component {
<td ref="description" onClick={this.onClick}>{this.props.transaction.Description}</td> <td ref="description" onClick={this.onClick}>{this.props.transaction.Description}</td>
<td ref="account" onClick={this.onClick}>{accountName}</td> <td ref="account" onClick={this.onClick}>{accountName}</td>
<td ref="status" onClick={this.onClick}>{status}</td> <td ref="status" onClick={this.onClick}>{status}</td>
<td ref="amount" onClick={this.onClick}>{amount}</td> <td className="amount-cell" ref="amount" onClick={this.onClick}>{amount}</td>
<td>{balance}</td> <td className="amount-cell">{balance}</td>
</tr>); </tr>);
} }
} }
@ -722,7 +722,6 @@ class AccountRegister extends React.Component {
super(); super();
this.state = { this.state = {
newTransaction: null, newTransaction: null,
height: 0
}; };
this.onEditTransaction = this.handleEditTransaction.bind(this); this.onEditTransaction = this.handleEditTransaction.bind(this);
this.onEditingCancel = this.handleEditingCancel.bind(this); this.onEditingCancel = this.handleEditingCancel.bind(this);
@ -732,20 +731,11 @@ class AccountRegister extends React.Component {
this.onUpdateTransaction = this.handleUpdateTransaction.bind(this); this.onUpdateTransaction = this.handleUpdateTransaction.bind(this);
this.onDeleteTransaction = this.handleDeleteTransaction.bind(this); this.onDeleteTransaction = this.handleDeleteTransaction.bind(this);
} }
resize() {
var div = ReactDOM.findDOMNode(this);
this.setState({height: div.parentElement.clientHeight - 64});
}
componentWillReceiveProps(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() {
this.resize();
var self = this;
$(window).resize(function() {self.resize();});
}
handleEditTransaction(transaction) { handleEditTransaction(transaction) {
this.props.onSelectTransaction(transaction.TransactionId); this.props.onSelectTransaction(transaction.TransactionId);
} }
@ -826,9 +816,8 @@ class AccountRegister extends React.Component {
)); ));
} }
var style = {height: this.state.height + "px"};
register = ( register = (
<div style={style} className="transactions-register"> <div className="transactions-register">
<Table bordered striped condensed hover> <Table bordered striped condensed hover>
<thead><tr> <thead><tr>
<th>Date</th> <th>Date</th>

View File

@ -155,23 +155,15 @@ class AccountsTab extends React.Component {
constructor() { constructor() {
super(); super();
this.state = { this.state = {
creatingNewAccount: false,
editingAccount: false, editingAccount: false,
deletingAccount: false deletingAccount: false
}; };
this.onNewAccount = this.handleNewAccount.bind(this);
this.onEditAccount = this.handleEditAccount.bind(this); this.onEditAccount = this.handleEditAccount.bind(this);
this.onDeleteAccount = this.handleDeleteAccount.bind(this); this.onDeleteAccount = this.handleDeleteAccount.bind(this);
this.onCreationCancel = this.handleCreationCancel.bind(this);
this.onEditingCancel = this.handleEditingCancel.bind(this); this.onEditingCancel = this.handleEditingCancel.bind(this);
this.onDeletionCancel = this.handleDeletionCancel.bind(this); this.onDeletionCancel = this.handleDeletionCancel.bind(this);
this.onCreateAccount = this.handleCreateAccount.bind(this);
this.onUpdateAccount = this.handleUpdateAccount.bind(this); this.onUpdateAccount = this.handleUpdateAccount.bind(this);
this.onRemoveAccount = this.handleRemoveAccount.bind(this); this.onRemoveAccount = this.handleRemoveAccount.bind(this);
this.onAccountSelected = this.handleAccountSelected.bind(this);
}
handleNewAccount() {
this.setState({creatingNewAccount: true});
} }
handleEditAccount() { handleEditAccount() {
this.setState({editingAccount: true}); this.setState({editingAccount: true});
@ -179,20 +171,12 @@ class AccountsTab extends React.Component {
handleDeleteAccount() { handleDeleteAccount() {
this.setState({deletingAccount: true}); this.setState({deletingAccount: true});
} }
handleCreationCancel() {
this.setState({creatingNewAccount: false});
}
handleEditingCancel() { handleEditingCancel() {
this.setState({editingAccount: false}); this.setState({editingAccount: false});
} }
handleDeletionCancel() { handleDeletionCancel() {
this.setState({deletingAccount: false}); this.setState({deletingAccount: false});
} }
handleCreateAccount(account) {
if (this.props.onCreateAccount != null)
this.props.onCreateAccount(account);
this.setState({creatingNewAccount: false});
}
handleUpdateAccount(account) { handleUpdateAccount(account) {
if (this.props.onUpdateAccount != null) if (this.props.onUpdateAccount != null)
this.props.onUpdateAccount(account); this.props.onUpdateAccount(account);
@ -203,10 +187,6 @@ class AccountsTab extends React.Component {
this.props.onDeleteAccount(account); this.props.onDeleteAccount(account);
this.setState({deletingAccount: false}); this.setState({deletingAccount: false});
} }
handleAccountSelected(account) {
this.props.onSelectAccount(account.AccountId);
this.props.onFetchTransactionPage(account, 20, 0);
}
render() { render() {
var disabled = (this.props.selectedAccount == -1) ? true : false; var disabled = (this.props.selectedAccount == -1) ? true : false;
@ -215,16 +195,7 @@ class AccountsTab extends React.Component {
selectedAccount = this.props.accounts[this.props.selectedAccount]; selectedAccount = this.props.accounts[this.props.selectedAccount];
return ( return (
<Grid fluid className="fullheight"><Row className="fullheight"> <div>
<Col xs={2} className="fullheight account-column">
<AddEditAccountModal
show={this.state.creatingNewAccount}
initialParentAccount={selectedAccount}
accounts={this.props.accounts}
accountChildren={this.props.accountChildren}
onCancel={this.onCreationCancel}
onSubmit={this.onCreateAccount}
security_list={this.props.security_list}/>
<AddEditAccountModal <AddEditAccountModal
show={this.state.editingAccount} show={this.state.editingAccount}
editAccount={selectedAccount} editAccount={selectedAccount}
@ -240,22 +211,14 @@ class AccountsTab extends React.Component {
accountChildren={this.props.accountChildren} accountChildren={this.props.accountChildren}
onCancel={this.onDeletionCancel} onCancel={this.onDeletionCancel}
onSubmit={this.onRemoveAccount}/> onSubmit={this.onRemoveAccount}/>
<AccountTree
accounts={this.props.accounts}
accountChildren={this.props.accountChildren}
selectedAccount={this.props.selectedAccount}
onSelect={this.onAccountSelected}/>
<ButtonGroup className="account-buttongroup"> <ButtonGroup className="account-buttongroup">
<Button onClick={this.onNewAccount} bsStyle="success">
<Glyphicon glyph='plus-sign' /></Button>
<Button onClick={this.onEditAccount} <Button onClick={this.onEditAccount}
bsStyle="primary" disabled={disabled}> bsStyle="primary" disabled={disabled}>
<Glyphicon glyph='cog' /></Button> <Glyphicon glyph='cog' /> Edit Account</Button>
<Button onClick={this.onDeleteAccount} <Button onClick={this.onDeleteAccount}
bsStyle="danger" disabled={disabled}> bsStyle="danger" disabled={disabled}>
<Glyphicon glyph='trash' /></Button> <Glyphicon glyph='trash' /> Delete Account</Button>
</ButtonGroup> </ButtonGroup>
</Col><Col xs={10} className="fullheight transactions-column">
<AccountRegister <AccountRegister
pageSize={20} pageSize={20}
selectedAccount={this.props.selectedAccount} selectedAccount={this.props.selectedAccount}
@ -278,8 +241,7 @@ class AccountsTab extends React.Component {
onImportOFX={this.props.onImportOFX} onImportOFX={this.props.onImportOFX}
onImportOFXFile={this.props.onImportOFXFile} onImportOFXFile={this.props.onImportOFXFile}
onImportGnucash={this.props.onImportGnucash} /> onImportGnucash={this.props.onImportGnucash} />
</Col> </div>
</Row></Grid>
); );
} }
} }

View File

@ -1,10 +1,23 @@
var React = require('react'); var React = require('react');
var ReactDOM = require('react-dom');
var ReactBootstrap = require('react-bootstrap'); var ReactBootstrap = require('react-bootstrap');
var Jumbotron = ReactBootstrap.Jumbotron; var Jumbotron = ReactBootstrap.Jumbotron;
var Tabs = ReactBootstrap.Tabs; var Tabs = ReactBootstrap.Tabs;
var Tab = ReactBootstrap.Tab; 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 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 TopBarContainer = require('../containers/TopBarContainer');
var NewUserModalContainer = require('../containers/NewUserModalContainer'); var NewUserModalContainer = require('../containers/NewUserModalContainer');
@ -12,28 +25,43 @@ var AccountSettingsModalContainer = require('../containers/AccountSettingsModalC
var AccountsTabContainer = require('../containers/AccountsTabContainer'); 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');
var AddEditAccountModal = require('./AddEditAccountModal');
var AccountTree = require('./AccountTree');
var utils = require('../utils');
class MoneyGoApp extends React.Component { class MoneyGoApp extends React.Component {
constructor() { constructor() {
super(); super();
this.state = { this.state = {
tab: 1,
accountFilter: "",
showNewUserModal: false, showNewUserModal: false,
showAccountSettingsModal: false showSettingsModal: false,
creatingNewAccount: false
}; };
this.onShowSettings = this.handleShowSettings.bind(this); this.onShowSettings = this.handleShowSettings.bind(this);
this.onHideSettings = this.handleHideSettings.bind(this); this.onHideSettings = this.handleHideSettings.bind(this);
this.onShowNewUser = this.handleShowNewUser.bind(this); this.onShowNewUser = this.handleShowNewUser.bind(this);
this.onHideNewUser = this.handleHideNewUser.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() { componentDidMount() {
this.props.tryResumingSession(); this.props.tryResumingSession();
this.props.fetchCurrencies(); this.props.fetchCurrencies();
} }
handleShowSettings() { handleShowSettings() {
this.setState({showAccountSettingsModal: true}); this.setState({showSettingsModal: true});
} }
handleHideSettings(user) { handleHideSettings(user) {
this.setState({showAccountSettingsModal: false}); this.setState({showSettingsModal: false});
} }
handleShowNewUser() { handleShowNewUser() {
this.setState({showNewUserModal: true}); this.setState({showNewUserModal: true});
@ -41,27 +69,117 @@ class MoneyGoApp extends React.Component {
handleHideNewUser() { handleHideNewUser() {
this.setState({showNewUserModal: false}); 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() { render() {
var mainContent; 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((<MenuItem key={accountId} onSelect={clojure}>{fullName}</MenuItem>));
}
}
} else {
accountElements.push((<MenuItem key={1} divider />));
accountElements.push((<AccountTree key={2}
accounts={this.props.accounts}
accountChildren={this.props.accountChildren}
selectedAccount={this.props.selectedAccount}
onSelectAccount={this.onAccountSelected}
onSelectKey={1} />));
}
mainContent = ( mainContent = (
<Tabs defaultActiveKey={1} id='mainNavigationTabs'> <Tab.Container id="main-ui-navigation" activeKey={this.state.tab} onSelect={this.onSelectTab}>
<Tab title="Accounts" eventKey={1} > <Row className="clearfix">
<AccountsTabContainer <Col sm={12}>
className="fullheight" /> <Nav bsStyle="tabs">
</Tab> <NavDropdown eventKey={1} title="Accounts">
<Tab title="Securities" eventKey={2} > <MenuItem onSelect={this.onNewAccount}>New Account</MenuItem>
<SecuritiesTabContainer <MenuItem divider />
className="fullheight" /> <MenuItem disabled className="account-filter-menuitem">
</Tab> <InputGroup>
<Tab title="Scheduled Transactions" eventKey={3} >Scheduled transactions go here...</Tab> <FormControl
<Tab title="Budgets" eventKey={4} >Budgets go here...</Tab> onKeyDown={function(e){if (e.key == " ") e.stopPropagation();}}
<Tab title="Reports" eventKey={5} > type="text"
<ReportsTabContainer placeholder="Search..."
className="fullheight" /> value={this.state.accountFilter}
</Tab> onChange={this.onAccountFilterChange}
</Tabs>); ref="accountFilter" />
else <InputGroup.Button>
<Button className="clear-account-filter" onClick={this.onClearAccountFilter}>
<Glyphicon glyph="remove"/>
</Button>
</InputGroup.Button>
</InputGroup>
</MenuItem>
{accountElements}
</NavDropdown>
<NavItem eventKey={2}>Securities</NavItem>
<NavItem eventKey={3}>Scheduled Transactions</NavItem>
<NavItem eventKey={4}>Budgets</NavItem>
<NavItem eventKey={5}>Reports</NavItem>
</Nav>
</Col>
<Col sm={12}>
<Tab.Content>
<Tab.Pane eventKey={1}>
<AccountsTabContainer/>
</Tab.Pane>
<Tab.Pane eventKey={2}>
<SecuritiesTabContainer/>
</Tab.Pane>
<Tab.Pane eventKey={3}>
Scheduled transactions go here...
</Tab.Pane>
<Tab.Pane eventKey={4}>
Budgets go here...
</Tab.Pane>
<Tab.Pane eventKey={5}>
<ReportsTabContainer/>
</Tab.Pane>
</Tab.Content>
</Col>
</Row>
</Tab.Container>);
} else {
mainContent = ( mainContent = (
<Jumbotron> <Jumbotron>
<center> <center>
@ -69,21 +187,30 @@ class MoneyGoApp extends React.Component {
<p><i>Go</i> manage your money.</p> <p><i>Go</i> manage your money.</p>
</center> </center>
</Jumbotron>); </Jumbotron>);
}
return ( return (
<div className="fullheight ui"> <div className="ui">
<TopBarContainer <TopBarContainer
onCreateNewUser={this.onShowNewUser} onCreateNewUser={this.onShowNewUser}
onAccountSettings={this.onShowSettings} /> onSettings={this.onShowSettings} />
{mainContent} {mainContent}
<NewUserModalContainer <NewUserModalContainer
show={this.state.showNewUserModal} show={this.state.showNewUserModal}
onSubmit={this.onHideNewUser} onSubmit={this.onHideNewUser}
onCancel={this.onHideNewUser}/> onCancel={this.onHideNewUser}/>
<AccountSettingsModalContainer <AccountSettingsModalContainer
show={this.state.showAccountSettingsModal} show={this.state.showSettingsModal}
onSubmit={this.onHideSettings} onSubmit={this.onHideSettings}
onCancel={this.onHideSettings}/> onCancel={this.onHideSettings}/>
<AddEditAccountModal
show={this.state.creatingNewAccount}
initialParentAccount={this.props.selectedAccount}
accounts={this.props.accounts}
accountChildren={this.props.accountChildren}
onCancel={this.onNewAccountCancel}
onSubmit={this.onCreateAccount}
security_list={this.props.security_list}/>
</div> </div>
); );
} }

View File

@ -76,8 +76,8 @@ class LogoutBar extends React.Component {
} }
handleOnSelect(key) { handleOnSelect(key) {
if (key == 1) { if (key == 1) {
if (this.props.onAccountSettings != null) if (this.props.onSettings != null)
this.props.onAccountSettings(); this.props.onSettings();
} else if (key == 2) { } else if (key == 2) {
this.props.onLogout(); this.props.onLogout();
} }
@ -110,7 +110,7 @@ class TopBar extends React.Component {
if (!this.props.user.isUser()) if (!this.props.user.isUser())
barContents = <LoginBar onLogin={this.props.onLogin} onCreateNewUser={this.props.onCreateNewUser} />; barContents = <LoginBar onLogin={this.props.onLogin} onCreateNewUser={this.props.onCreateNewUser} />;
else else
barContents = <LogoutBar user={this.props.user} onLogout={this.props.onLogout} onAccountSettings={this.props.onAccountSettings}/>; barContents = <LogoutBar user={this.props.user} onLogout={this.props.onLogout} onSettings={this.props.onSettings}/>;
if (this.props.error.isError()) if (this.props.error.isError())
errorAlert = errorAlert =
<Alert bsStyle="danger" onDismiss={this.props.onClearError}> <Alert bsStyle="danger" onDismiss={this.props.onClearError}>

View File

@ -23,7 +23,6 @@ function mapStateToProps(state) {
function mapDispatchToProps(dispatch) { function mapDispatchToProps(dispatch) {
return { return {
onFetchAllAccounts: function() {dispatch(AccountActions.fetchAll())}, onFetchAllAccounts: function() {dispatch(AccountActions.fetchAll())},
onCreateAccount: function(account) {dispatch(AccountActions.create(account))},
onUpdateAccount: function(account) {dispatch(AccountActions.update(account))}, onUpdateAccount: function(account) {dispatch(AccountActions.update(account))},
onDeleteAccount: function(account) {dispatch(AccountActions.remove(account))}, onDeleteAccount: function(account) {dispatch(AccountActions.remove(account))},
onSelectAccount: function(accountId) {dispatch(AccountActions.select(accountId))}, onSelectAccount: function(accountId) {dispatch(AccountActions.select(accountId))},

View File

@ -1,13 +1,19 @@
var connect = require('react-redux').connect; var connect = require('react-redux').connect;
var UserActions = require('../actions/UserActions'); var UserActions = require('../actions/UserActions');
var AccountActions = require('../actions/AccountActions');
var TransactionActions = require('../actions/TransactionActions');
var SecurityTemplateActions = require('../actions/SecurityTemplateActions'); var SecurityTemplateActions = require('../actions/SecurityTemplateActions');
var MoneyGoApp = require('../components/MoneyGoApp'); var MoneyGoApp = require('../components/MoneyGoApp');
function mapStateToProps(state) { function mapStateToProps(state) {
return { 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 { return {
tryResumingSession: function() {dispatch(UserActions.tryResumingSession())}, tryResumingSession: function() {dispatch(UserActions.tryResumingSession())},
fetchCurrencies: function() {dispatch(SecurityTemplateActions.fetchCurrencies())}, 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))},
} }
} }

View File

@ -1,22 +1,13 @@
@import url("reports.css"); @import url("reports.css");
html, body {
height: 100%;
}
div#content { div#content {
display: block; display: block;
width: 95%; width: 95%;
height: 100%;
min-width: 75em; min-width: 75em;
max-width: 100em; max-width: 100em;
margin: auto; margin: auto;
} }
/* Keep the main windows sized to the full viewable height */
.fullheight {
height: 100%;
}
.ui { .ui {
display: flex; display: flex;
flex-flow: column; flex-flow: column;
@ -34,11 +25,18 @@ div#content {
} }
/* Tabs */ /* Tabs */
.nav-tabs { .nav-tabs {
margin-bottom: 15px; 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 */ /* Style the account tree */
@ -49,6 +47,7 @@ div.accounttree-root-nochildren {
div.accounttree { div.accounttree {
position: relative; position: relative;
left: -24px; left: -24px;
white-space: nowrap;
} }
div.accounttree-nochildren { div.accounttree-nochildren {
position: relative; position: relative;
@ -67,38 +66,25 @@ div.accounttree-root div {
.accounttree-root { .accounttree-root {
display: block; display: block;
width: 100%; margin-left: 5px;
height: 100%-100px;
overflow: auto;
} }
.account-column { .accounttree-expandbutton {
padding: 15px 15px 43px 15px; padding-bottom: 6px;
border-right: 1px solid #DDD;
border-left: 1px solid #DDD;
}
.account-buttongroup {
position: absolute;
right: 15px;
bottom: 15px;
} }
.transactions-container { .transactions-container {
display: block; display: block;
width: 100%; width: 100%;
height: 100%;
} }
.transactions-register { .transactions-register {
display: block; display: block;
width: 100%; width: 100%;
height: 100%;
overflow: auto; overflow: auto;
} }
.transactions-column {
padding: 15px;
border-right: 1px solid #DDD;
}
.transactions-register-toolbar { .transactions-register-toolbar {
width: 100%; width: 100%;
height: 50px; }
td.amount-cell {
white-space: nowrap;
} }
.register-row-editing { .register-row-editing {