mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-20 06:40:31 +00:00
- feat: Highlight inactive accounts in data-table.
- feat: Separate accounts list and table order.
This commit is contained in:
@@ -95,7 +95,7 @@ function MakeJournalEntriesTable({
|
|||||||
customers,
|
customers,
|
||||||
|
|
||||||
// #withAccounts
|
// #withAccounts
|
||||||
accounts,
|
accountsList,
|
||||||
|
|
||||||
// #ownPorps
|
// #ownPorps
|
||||||
onClickRemoveRow,
|
onClickRemoveRow,
|
||||||
@@ -251,7 +251,7 @@ function MakeJournalEntriesTable({
|
|||||||
rowClassNames={rowClassNames}
|
rowClassNames={rowClassNames}
|
||||||
sticky={true}
|
sticky={true}
|
||||||
payload={{
|
payload={{
|
||||||
accounts,
|
accounts: accountsList,
|
||||||
errors: errors.entries || [],
|
errors: errors.entries || [],
|
||||||
updateData: handleUpdateData,
|
updateData: handleUpdateData,
|
||||||
removeRow: handleRemoveRow,
|
removeRow: handleRemoveRow,
|
||||||
@@ -286,8 +286,8 @@ function MakeJournalEntriesTable({
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default compose(
|
export default compose(
|
||||||
withAccounts(({ accounts }) => ({
|
withAccounts(({ accountsList }) => ({
|
||||||
accounts,
|
accountsList,
|
||||||
})),
|
})),
|
||||||
withCustomers(({ customersItems }) => ({
|
withCustomers(({ customersItems }) => ({
|
||||||
customers: customersItems,
|
customers: customersItems,
|
||||||
|
|||||||
@@ -12,11 +12,13 @@ import {
|
|||||||
} from '@blueprintjs/core';
|
} from '@blueprintjs/core';
|
||||||
import { withRouter } from 'react-router';
|
import { withRouter } from 'react-router';
|
||||||
import { FormattedMessage as T, useIntl } from 'react-intl';
|
import { FormattedMessage as T, useIntl } from 'react-intl';
|
||||||
|
import classnames from 'classnames';
|
||||||
import {
|
import {
|
||||||
Icon,
|
Icon,
|
||||||
DataTable,
|
DataTable,
|
||||||
Money,
|
Money,
|
||||||
If,
|
If,
|
||||||
|
Choose,
|
||||||
} from 'components';
|
} from 'components';
|
||||||
import { compose } from 'utils';
|
import { compose } from 'utils';
|
||||||
import { useUpdateEffect } from 'hooks';
|
import { useUpdateEffect } from 'hooks';
|
||||||
@@ -60,24 +62,54 @@ function BalanceCell({ cell }) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function AccountNameAccessor(row) {
|
function InactiveSemafro() {
|
||||||
return row.description ? (
|
return (
|
||||||
<Tooltip
|
<Tooltip
|
||||||
className={Classes.TOOLTIP_INDICATOR}
|
content={<T id='inactive' />}
|
||||||
content={row.description}
|
className={classnames(
|
||||||
position={Position.RIGHT_TOP}
|
Classes.TOOLTIP_INDICATOR,
|
||||||
hoverOpenDelay={500}
|
'bp3-popover-wrapper--inactive-semafro'
|
||||||
>
|
)}
|
||||||
{row.name}
|
position={Position.TOP}
|
||||||
|
hoverOpenDelay={250}>
|
||||||
|
<div className="inactive-semafro"></div>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
) : (
|
);
|
||||||
row.name
|
}
|
||||||
|
|
||||||
|
function AccountNameAccessor(row) {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Choose>
|
||||||
|
<Choose.When condition={!!row.description}>
|
||||||
|
<Tooltip
|
||||||
|
className={classnames(
|
||||||
|
Classes.TOOLTIP_INDICATOR,
|
||||||
|
'bp3-popover-wrapper--account-desc',
|
||||||
|
)}
|
||||||
|
content={row.description}
|
||||||
|
position={Position.RIGHT_TOP}
|
||||||
|
hoverOpenDelay={500}
|
||||||
|
>
|
||||||
|
{row.name}
|
||||||
|
</Tooltip>
|
||||||
|
</Choose.When>
|
||||||
|
|
||||||
|
<Choose.Otherwise>
|
||||||
|
{ row.name }
|
||||||
|
</Choose.Otherwise>
|
||||||
|
</Choose>
|
||||||
|
|
||||||
|
<If condition={!row.active}>
|
||||||
|
<InactiveSemafro />
|
||||||
|
</If>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function AccountsDataTable({
|
function AccountsDataTable({
|
||||||
// #withDashboardActions
|
// #withDashboardActions
|
||||||
accounts,
|
accountsTable,
|
||||||
accountsLoading,
|
accountsLoading,
|
||||||
|
|
||||||
// #withDialog.
|
// #withDialog.
|
||||||
@@ -256,7 +288,7 @@ function AccountsDataTable({
|
|||||||
<DataTable
|
<DataTable
|
||||||
noInitialFetch={true}
|
noInitialFetch={true}
|
||||||
columns={columns}
|
columns={columns}
|
||||||
data={accounts}
|
data={accountsTable}
|
||||||
onFetchData={handleDatatableFetchData}
|
onFetchData={handleDatatableFetchData}
|
||||||
manualSortBy={true}
|
manualSortBy={true}
|
||||||
selectionColumn={selectionColumn}
|
selectionColumn={selectionColumn}
|
||||||
@@ -275,8 +307,8 @@ export default compose(
|
|||||||
withDialogActions,
|
withDialogActions,
|
||||||
withDashboardActions,
|
withDashboardActions,
|
||||||
withAccountsActions,
|
withAccountsActions,
|
||||||
withAccounts(({ accountsLoading, accounts }) => ({
|
withAccounts(({ accountsLoading, accountsTable }) => ({
|
||||||
accountsLoading,
|
accountsLoading,
|
||||||
accounts,
|
accountsTable,
|
||||||
})),
|
})),
|
||||||
)(AccountsDataTable);
|
)(AccountsDataTable);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import {
|
import {
|
||||||
getAccountsItems,
|
getAccountsItems, getAccountsListFactory,
|
||||||
} from 'store/accounts/accounts.selectors';
|
} from 'store/accounts/accounts.selectors';
|
||||||
import {
|
import {
|
||||||
getResourceViews,
|
getResourceViews,
|
||||||
@@ -8,10 +8,13 @@ import {
|
|||||||
|
|
||||||
|
|
||||||
export default (mapState) => {
|
export default (mapState) => {
|
||||||
|
const getAccountsList = getAccountsListFactory();
|
||||||
|
|
||||||
const mapStateToProps = (state, props) => {
|
const mapStateToProps = (state, props) => {
|
||||||
const mapped = {
|
const mapped = {
|
||||||
accountsViews: getResourceViews(state, props, 'accounts'),
|
accountsViews: getResourceViews(state, props, 'accounts'),
|
||||||
accounts: getAccountsItems(state, props),
|
accountsTable: getAccountsItems(state, props),
|
||||||
|
accountsList: getAccountsList(state, props),
|
||||||
accountsTypes: state.accounts.accountsTypes,
|
accountsTypes: state.accounts.accountsTypes,
|
||||||
|
|
||||||
accountsTableQuery: state.accounts.tableQuery,
|
accountsTableQuery: state.accounts.tableQuery,
|
||||||
|
|||||||
@@ -20,9 +20,9 @@ export default compose(
|
|||||||
AccountFormDialogConnect,
|
AccountFormDialogConnect,
|
||||||
withAccountsActions,
|
withAccountsActions,
|
||||||
withAccountDetail,
|
withAccountDetail,
|
||||||
withAccounts(({ accountsTypes, accounts }) => ({
|
withAccounts(({ accountsTypes, accountsList }) => ({
|
||||||
accountsTypes,
|
accountsTypes,
|
||||||
accounts,
|
accounts: accountsList,
|
||||||
})),
|
})),
|
||||||
withDialogActions,
|
withDialogActions,
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ import withAccounts from 'containers/Accounts/withAccounts';
|
|||||||
function ExpenseFormHeader({
|
function ExpenseFormHeader({
|
||||||
formik: { errors, touched, setFieldValue, getFieldProps, values },
|
formik: { errors, touched, setFieldValue, getFieldProps, values },
|
||||||
currenciesList,
|
currenciesList,
|
||||||
accounts,
|
accountsList,
|
||||||
accountsTypes,
|
accountsTypes,
|
||||||
}) {
|
}) {
|
||||||
const [selectedItems, setSelectedItems] = useState({});
|
const [selectedItems, setSelectedItems] = useState({});
|
||||||
@@ -165,7 +165,7 @@ function ExpenseFormHeader({
|
|||||||
}
|
}
|
||||||
>
|
>
|
||||||
<AccountsSelectList
|
<AccountsSelectList
|
||||||
accounts={accounts}
|
accounts={accountsList}
|
||||||
onAccountSelected={onChangeAccount}
|
onAccountSelected={onChangeAccount}
|
||||||
defaultSelectText={<T id={'select_payment_account'} />}
|
defaultSelectText={<T id={'select_payment_account'} />}
|
||||||
selectedAccountId={values.payment_account_id}
|
selectedAccountId={values.payment_account_id}
|
||||||
@@ -252,8 +252,8 @@ function ExpenseFormHeader({
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default compose(
|
export default compose(
|
||||||
withAccounts(({ accounts, accountsTypes }) => ({
|
withAccounts(({ accountsList, accountsTypes }) => ({
|
||||||
accounts,
|
accountsList,
|
||||||
accountsTypes,
|
accountsTypes,
|
||||||
})),
|
})),
|
||||||
withCurrencies(({ currenciesList }) => ({
|
withCurrencies(({ currenciesList }) => ({
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ const TotalAmountCellRenderer = (chainedComponent, type) => (props) => {
|
|||||||
|
|
||||||
function ExpenseTable({
|
function ExpenseTable({
|
||||||
// #withAccounts
|
// #withAccounts
|
||||||
accounts,
|
accountsList,
|
||||||
|
|
||||||
// #ownPorps
|
// #ownPorps
|
||||||
onClickRemoveRow,
|
onClickRemoveRow,
|
||||||
@@ -228,7 +228,7 @@ function ExpenseTable({
|
|||||||
rowClassNames={rowClassNames}
|
rowClassNames={rowClassNames}
|
||||||
sticky={true}
|
sticky={true}
|
||||||
payload={{
|
payload={{
|
||||||
accounts,
|
accounts: accountsList,
|
||||||
errors: errors.categories || [],
|
errors: errors.categories || [],
|
||||||
updateData: handleUpdateData,
|
updateData: handleUpdateData,
|
||||||
removeRow: handleRemoveRow,
|
removeRow: handleRemoveRow,
|
||||||
@@ -256,7 +256,7 @@ function ExpenseTable({
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default compose(
|
export default compose(
|
||||||
withAccounts(({ accounts }) => ({
|
withAccounts(({ accountsList }) => ({
|
||||||
accounts,
|
accountsList,
|
||||||
})),
|
})),
|
||||||
)(ExpenseTable);
|
)(ExpenseTable);
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ function GeneralLedgerHeader({
|
|||||||
pageFilter,
|
pageFilter,
|
||||||
|
|
||||||
// #withAccounts
|
// #withAccounts
|
||||||
accounts,
|
accountsList,
|
||||||
|
|
||||||
// #withGeneralLedgerActions
|
// #withGeneralLedgerActions
|
||||||
refreshGeneralLedgerSheet,
|
refreshGeneralLedgerSheet,
|
||||||
@@ -83,7 +83,7 @@ function GeneralLedgerHeader({
|
|||||||
className={classNames('form-group--select-list', Classes.FILL)}
|
className={classNames('form-group--select-list', Classes.FILL)}
|
||||||
>
|
>
|
||||||
<AccountsMultiSelect
|
<AccountsMultiSelect
|
||||||
accounts={accounts}
|
accounts={accountsList}
|
||||||
onAccountSelected={onAccountSelected}
|
onAccountSelected={onAccountSelected}
|
||||||
/>
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
@@ -102,8 +102,8 @@ function GeneralLedgerHeader({
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default compose(
|
export default compose(
|
||||||
withAccounts(({ accounts }) => ({
|
withAccounts(({ accountsList }) => ({
|
||||||
accounts,
|
accountsList,
|
||||||
})),
|
})),
|
||||||
withGeneralLedger(({ generalLedgerSheetFilter, generalLedgerSheetRefresh }) => ({
|
withGeneralLedger(({ generalLedgerSheetFilter, generalLedgerSheetRefresh }) => ({
|
||||||
generalLedgerSheetFilter,
|
generalLedgerSheetFilter,
|
||||||
|
|||||||
@@ -528,4 +528,5 @@ export default {
|
|||||||
'A unique code/number for this account (limited to 10 characters)',
|
'A unique code/number for this account (limited to 10 characters)',
|
||||||
logic_expression: 'logic expression',
|
logic_expression: 'logic expression',
|
||||||
assign_to_customer: 'Assign to Customer',
|
assign_to_customer: 'Assign to Customer',
|
||||||
|
inactive: 'Inactive',
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -19,32 +19,29 @@ export const fetchAccountTypes = () => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const fetchAccountsList = ({ query } = {}) => {
|
export const fetchAccountsList = () => {
|
||||||
return (dispatch) =>
|
return (dispatch) =>
|
||||||
new Promise((resolve, reject) => {
|
new Promise((resolve, reject) => {
|
||||||
dispatch({
|
const query = { column_sort_by: 'name', sort_order: 'asc' };
|
||||||
type: t.SET_DASHBOARD_REQUEST_LOADING,
|
|
||||||
});
|
|
||||||
ApiService.get('accounts', { params: query })
|
ApiService.get('accounts', { params: query })
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
dispatch({
|
|
||||||
type: t.ACCOUNTS_PAGE_SET,
|
|
||||||
accounts: response.data.accounts,
|
|
||||||
customViewId: response.data.customViewId,
|
|
||||||
});
|
|
||||||
dispatch({
|
dispatch({
|
||||||
type: t.ACCOUNTS_ITEMS_SET,
|
type: t.ACCOUNTS_ITEMS_SET,
|
||||||
accounts: response.data.accounts,
|
accounts: response.data.accounts,
|
||||||
});
|
});
|
||||||
|
dispatch({
|
||||||
|
type: t.ACCOUNTS_LIST_SET,
|
||||||
|
payload: {
|
||||||
|
accounts: response.data.accounts,
|
||||||
|
}
|
||||||
|
})
|
||||||
dispatch({
|
dispatch({
|
||||||
type: t.SET_DASHBOARD_REQUEST_COMPLETED,
|
type: t.SET_DASHBOARD_REQUEST_COMPLETED,
|
||||||
});
|
});
|
||||||
resolve(response);
|
resolve(response);
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
dispatch({
|
|
||||||
type: t.SET_DASHBOARD_REQUEST_COMPLETED,
|
|
||||||
});
|
|
||||||
reject(error);
|
reject(error);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import { createTableQueryReducers } from 'store/queryReducers';
|
|||||||
const initialState = {
|
const initialState = {
|
||||||
items: {},
|
items: {},
|
||||||
views: {},
|
views: {},
|
||||||
|
list: [],
|
||||||
accountsTypes: [],
|
accountsTypes: [],
|
||||||
accountsById: {},
|
accountsById: {},
|
||||||
tableQuery: {
|
tableQuery: {
|
||||||
@@ -40,6 +41,11 @@ const accountsReducer = createReducer(initialState, {
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
[t.ACCOUNTS_LIST_SET]: (state, action) => {
|
||||||
|
const { accounts } = action.payload;
|
||||||
|
state.list = accounts.map(account => account.id);
|
||||||
|
},
|
||||||
|
|
||||||
[t.ACCOUNT_TYPES_LIST_SET]: (state, action) => {
|
[t.ACCOUNT_TYPES_LIST_SET]: (state, action) => {
|
||||||
state.accountsTypes = action.account_types;
|
state.accountsTypes = action.account_types;
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -6,6 +6,9 @@ const accountsDataSelector = (state) => state.accounts.items;
|
|||||||
const accountsCurrentViewSelector = (state) => state.accounts.currentViewId;
|
const accountsCurrentViewSelector = (state) => state.accounts.currentViewId;
|
||||||
const accountIdPropSelector = (state, props) => props.accountId;
|
const accountIdPropSelector = (state, props) => props.accountId;
|
||||||
|
|
||||||
|
const accountsListSelector = state => state.accounts.list;
|
||||||
|
|
||||||
|
|
||||||
export const getAccountsItems = createSelector(
|
export const getAccountsItems = createSelector(
|
||||||
accountsViewsSelector,
|
accountsViewsSelector,
|
||||||
accountsDataSelector,
|
accountsDataSelector,
|
||||||
@@ -19,6 +22,14 @@ export const getAccountsItems = createSelector(
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export const getAccountsListFactory = () => createSelector(
|
||||||
|
accountsListSelector,
|
||||||
|
accountsDataSelector,
|
||||||
|
(accounts, accountsItems) => {
|
||||||
|
return pickItemsFromIds(accountsItems, accounts);
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
export const getAccountById = createSelector(
|
export const getAccountById = createSelector(
|
||||||
accountsDataSelector,
|
accountsDataSelector,
|
||||||
accountIdPropSelector,
|
accountIdPropSelector,
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
export default {
|
export default {
|
||||||
ACCOUNT_TYPES_LIST_SET: 'ACCOUNT_TYPES_LIST_SET',
|
ACCOUNT_TYPES_LIST_SET: 'ACCOUNT_TYPES_LIST_SET',
|
||||||
ACCOUNTS_PAGE_SET: 'ACCOUNTS_PAGE_SET',
|
ACCOUNTS_PAGE_SET: 'ACCOUNTS_PAGE_SET',
|
||||||
|
ACCOUNTS_LIST_SET: 'ACCOUNTS_LIST_SET',
|
||||||
ACCOUNTS_ITEMS_SET: 'ACCOUNTS_ITEMS_SET',
|
ACCOUNTS_ITEMS_SET: 'ACCOUNTS_ITEMS_SET',
|
||||||
ACCOUNT_SET: 'ACCOUNT_SET',
|
ACCOUNT_SET: 'ACCOUNT_SET',
|
||||||
ACCOUNT_DELETE: 'ACCOUNT_DELETE',
|
ACCOUNT_DELETE: 'ACCOUNT_DELETE',
|
||||||
|
|||||||
@@ -16,10 +16,26 @@
|
|||||||
padding-bottom: 0.36rem;
|
padding-bottom: 0.36rem;
|
||||||
}
|
}
|
||||||
.account_name{
|
.account_name{
|
||||||
|
> div{
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
.bp3-tooltip-indicator{
|
.bp3-popover-wrapper--inactive-semafro{
|
||||||
cursor: default;
|
margin-left: 8px;
|
||||||
border-bottom-color: #c6c6c6;
|
margin-right: 6px;
|
||||||
|
float: right;
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
.bp3-popover-wrapper--account-desc{
|
||||||
|
border-bottom-color: #BBB;
|
||||||
|
}
|
||||||
|
.inactive-semafro{
|
||||||
|
height: 7px;
|
||||||
|
width: 7px;
|
||||||
|
background: #BBB;
|
||||||
|
display: inline-block;
|
||||||
|
border-radius: 8px;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.normal{
|
.normal{
|
||||||
|
|||||||
Reference in New Issue
Block a user