diff --git a/client/src/common/drawers.js b/client/src/common/drawers.js new file mode 100644 index 000000000..987215b9f --- /dev/null +++ b/client/src/common/drawers.js @@ -0,0 +1,12 @@ + + +export const DRAWERS = { + ESTIMATE_DRAWER: 'estimate-drawer', + MANUAL_JOURNAL_DRAWER: 'journal-drawer', + INVOICE_DRAWER: 'invoice-drawer', + RECEIPT_DRAWER: 'receipt-drawer', + PAYMENT_RECEIVE_DRAWER: 'payment-receive-drawer', + ACCOUNT_DRAWER: 'account-drawer', + JOURNAL_DRAWER: 'journal-drawer', + EXPENSE_DRAWER: 'expense-drawer' +}; \ No newline at end of file diff --git a/client/src/components/Card.js b/client/src/components/Card.js index e28d3816b..4e8c3e256 100644 --- a/client/src/components/Card.js +++ b/client/src/components/Card.js @@ -1,5 +1,6 @@ import React from 'react'; +import classNames from 'classnames'; -export default function Card({ children }) { - return
{children}
; +export default function Card({ className, children }) { + return
{children}
; } diff --git a/client/src/components/Dashboard/DashboardSplitePane.js b/client/src/components/Dashboard/DashboardSplitePane.js index a6a2445e4..2ef54eb70 100644 --- a/client/src/components/Dashboard/DashboardSplitePane.js +++ b/client/src/components/Dashboard/DashboardSplitePane.js @@ -9,7 +9,7 @@ function DashboardSplitPane({ sidebarExpended, children }) { - const initialSize = 190; + const initialSize = 180; const [defaultSize, setDefaultSize] = useState( parseInt(localStorage.getItem('dashboard-size'), 10) || initialSize, @@ -27,7 +27,7 @@ function DashboardSplitPane({ { - saveInvoke(onChange, viewSlug); - throttledOnChange.current(viewSlug); + const value = viewSlug === 0 ? null : viewSlug; + saveInvoke(onChange, value); + throttledOnChange.current(value); }; // Handles click a new view. diff --git a/client/src/components/Details/index.js b/client/src/components/Details/index.js index c96252136..9c9bdacb9 100644 --- a/client/src/components/Details/index.js +++ b/client/src/components/Details/index.js @@ -1,17 +1,22 @@ import React from 'react'; import classNames from 'classnames'; -import { Col, Row } from 'components'; import 'style/components/Details.scss'; +const DIRECTION = { + VERTICAL: 'vertical', + HORIZANTAL: 'horizantal', +}; + /** * Details menu. */ -export function DetailsMenu({ children, vertical = false }) { +export function DetailsMenu({ children, direction = DIRECTION.VERTICAL }) { return (
{children} @@ -20,27 +25,15 @@ export function DetailsMenu({ children, vertical = false }) { } /** - * Detail item vertical . + * Detail item. */ -export function DetailItemVER({ label, children }) { +export function DetailItem({ label, children, name }) { return ( -
+
{label}
{children}
); } - -/** - * Detail item horizontal . - */ -export function DetailItemHOR({ label, children }) { - return ( - - - {label} - - {children} - - ); -} diff --git a/client/src/components/Dialog/DialogContent.js b/client/src/components/Dialog/DialogContent.js index 514521cd1..265182bc5 100644 --- a/client/src/components/Dialog/DialogContent.js +++ b/client/src/components/Dialog/DialogContent.js @@ -5,15 +5,10 @@ import classNames from 'classnames'; export default function DialogContent(props) { const { isLoading, children } = props; - const loadingContent = ; - - return ( -
- {isLoading ? loadingContent : children} + const loadingContent = ( +
+
); + return isLoading ? loadingContent : children; } diff --git a/client/src/components/Drawer/Drawer.js b/client/src/components/Drawer/Drawer.js index 09f7b93a5..96f7e0b5a 100644 --- a/client/src/components/Drawer/Drawer.js +++ b/client/src/components/Drawer/Drawer.js @@ -24,6 +24,7 @@ function DrawerComponent(props) { canEscapeKeyClose={true} position={Position.RIGHT} onClose={handleClose} + portalClassName={'drawer-portal'} {...props} > {children} diff --git a/client/src/components/DrawersContainer.js b/client/src/components/DrawersContainer.js index acc556105..b51d7a72b 100644 --- a/client/src/components/DrawersContainer.js +++ b/client/src/components/DrawersContainer.js @@ -13,16 +13,21 @@ import PaymentReceiveDetailDrawer from 'containers/Drawers/PaymentReceiveDetailD import PaymentMadeDetailDrawer from 'containers/Drawers/PaymentMadeDetailDrawer'; import EstimateDetailDrawer from '../containers/Drawers/EstimateDetailDrawer'; +import { DRAWERS } from 'common/drawers'; + +/** + * Drawers container of the dashboard. + */ export default function DrawersContainer() { return (
- + - - - + + + diff --git a/client/src/components/PdfPreview/index.js b/client/src/components/PdfPreview/index.js index c6279b667..f60d71e55 100644 --- a/client/src/components/PdfPreview/index.js +++ b/client/src/components/PdfPreview/index.js @@ -1,13 +1,24 @@ import React from 'react'; -import { Spinner } from '@blueprintjs/core'; +import { Spinner, Classes } from '@blueprintjs/core'; +import classNames from 'classnames'; /** * Previews the pdf document of the given object url. */ export function PdfDocumentPreview({ url, height, width, isLoading }) { - return isLoading ? ( + const content = isLoading ? ( ) : ( ); + + return ( +
+ {content} +
+ ); } diff --git a/client/src/components/index.js b/client/src/components/index.js index bcffc5cbd..b55982615 100644 --- a/client/src/components/index.js +++ b/client/src/components/index.js @@ -68,6 +68,7 @@ export * from './Dashboard/DashboardFilterButton'; export * from './Dashboard/DashboardRowsHeightButton'; export * from './UniversalSearch/UniversalSearch'; export * from './PdfPreview'; +export * from './Details'; const Hint = FieldHint; diff --git a/client/src/containers/Accounting/JournalsLanding/ManualJournalsList.js b/client/src/containers/Accounting/JournalsLanding/ManualJournalsList.js index 7cec5f733..22c2cb542 100644 --- a/client/src/containers/Accounting/JournalsLanding/ManualJournalsList.js +++ b/client/src/containers/Accounting/JournalsLanding/ManualJournalsList.js @@ -19,10 +19,12 @@ import { transformTableStateToQuery, compose } from 'utils'; function ManualJournalsTable({ // #withManualJournals journalsTableState, + journalsTableStateChanged, }) { return ( @@ -40,7 +42,8 @@ function ManualJournalsTable({ } export default compose( - withManualJournals(({ manualJournalsTableState }) => ({ + withManualJournals(({ manualJournalsTableState, manualJournalTableStateChanged }) => ({ journalsTableState: manualJournalsTableState, + journalsTableStateChanged: manualJournalTableStateChanged, })), )(ManualJournalsTable); diff --git a/client/src/containers/Accounting/JournalsLanding/ManualJournalsListProvider.js b/client/src/containers/Accounting/JournalsLanding/ManualJournalsListProvider.js index b26fbb5e8..595e9e3fb 100644 --- a/client/src/containers/Accounting/JournalsLanding/ManualJournalsListProvider.js +++ b/client/src/containers/Accounting/JournalsLanding/ManualJournalsListProvider.js @@ -1,11 +1,13 @@ import React, { createContext } from 'react'; +import { isEmpty } from 'lodash'; + import DashboardInsider from 'components/Dashboard/DashboardInsider'; import { useResourceViews, useResourceMeta, useJournals } from 'hooks/query'; -import { isTableEmptyStatus, getFieldsFromResourceMeta } from 'utils'; +import { getFieldsFromResourceMeta } from 'utils'; const ManualJournalsContext = createContext(); -function ManualJournalsListProvider({ query, ...props }) { +function ManualJournalsListProvider({ query, tableStateChanged, ...props }) { // Fetches accounts resource views and fields. const { data: journalsViews, isLoading: isViewsLoading } = useResourceViews('manual_journals'); @@ -26,11 +28,7 @@ function ManualJournalsListProvider({ query, ...props }) { // Detarmines the datatable empty status. const isEmptyStatus = - isTableEmptyStatus({ - data: manualJournals, - pagination, - filterMeta, - }) && !isManualJournalsFetching; + isEmpty(manualJournals) && !tableStateChanged && !isManualJournalsLoading; // Global state. const state = { diff --git a/client/src/containers/Accounting/JournalsLanding/utils.js b/client/src/containers/Accounting/JournalsLanding/utils.js index 851eb92d8..03fd12010 100644 --- a/client/src/containers/Accounting/JournalsLanding/utils.js +++ b/client/src/containers/Accounting/JournalsLanding/utils.js @@ -24,7 +24,7 @@ export const useManualJournalsColumns = () => { { id: 'amount', Header: intl.get('amount'), - accessor: AmountAccessor, + accessor: 'formatted_amount', className: 'amount', width: 115, }, diff --git a/client/src/containers/Accounting/JournalsLanding/withManualJournals.js b/client/src/containers/Accounting/JournalsLanding/withManualJournals.js index 551196582..d8d356ba1 100644 --- a/client/src/containers/Accounting/JournalsLanding/withManualJournals.js +++ b/client/src/containers/Accounting/JournalsLanding/withManualJournals.js @@ -1,14 +1,21 @@ import { connect } from 'react-redux'; import { - getManualJournalsTableStateFactory + getManualJournalsTableStateFactory, + manualJournalTableStateChangedFactory, } from 'store/manualJournals/manualJournals.selectors'; export default (mapState) => { const getJournalsTableQuery = getManualJournalsTableStateFactory(); + const manualJournalTableStateChanged = + manualJournalTableStateChangedFactory(); const mapStateToProps = (state, props) => { const mapped = { manualJournalsTableState: getJournalsTableQuery(state, props), + manualJournalTableStateChanged: manualJournalTableStateChanged( + state, + props, + ), }; return mapState ? mapState(mapped, state, props) : mapped; }; diff --git a/client/src/containers/Accounting/ManualJournalUniversalSearch.js b/client/src/containers/Accounting/ManualJournalUniversalSearch.js index 1ce96ddcd..4cde8bafe 100644 --- a/client/src/containers/Accounting/ManualJournalUniversalSearch.js +++ b/client/src/containers/Accounting/ManualJournalUniversalSearch.js @@ -9,12 +9,14 @@ function JournalUniversalSearchSelectComponent({ // #ownProps resourceType, resourceId, + onAction, // #withDrawerActions openDrawer, }) { if (resourceType === RESOURCES_TYPES.MANUAL_JOURNAL) { openDrawer('journal-drawer', { manualJournalId: resourceId }); + onAction && onAction(); } return null; } @@ -27,6 +29,7 @@ export const JournalUniversalSearchSelectAction = withDrawerActions( * Mappes the manual journal item to search item. */ const manualJournalsToSearch = (manualJournal) => ({ + id: manualJournal.id, text: manualJournal.journal_number, subText: manualJournal.formatted_date, label: manualJournal.formatted_amount, diff --git a/client/src/containers/Accounts/AccountUniversalSearch.js b/client/src/containers/Accounts/AccountUniversalSearch.js index 894640efb..a1af66eb3 100644 --- a/client/src/containers/Accounts/AccountUniversalSearch.js +++ b/client/src/containers/Accounts/AccountUniversalSearch.js @@ -6,12 +6,14 @@ function AccountUniversalSearchItemSelectComponent({ // #ownProps resourceType, resourceId, + onAction, // #withDrawerActions openDrawer, }) { if (resourceType === RESOURCES_TYPES.ACCOUNT) { openDrawer('account-drawer', { accountId: resourceId }); + onAction && onAction(); } return null; } @@ -26,6 +28,7 @@ export const AccountUniversalSearchItemSelect = withDrawerActions( * @returns */ const accountToSearch = (account) => ({ + id: account.id, text: `${account.name} - ${account.code}`, label: account.formatted_amount, reference: account, diff --git a/client/src/containers/Accounts/AccountsChart.js b/client/src/containers/Accounts/AccountsChart.js index 35b1dc85d..fa8680e0f 100644 --- a/client/src/containers/Accounts/AccountsChart.js +++ b/client/src/containers/Accounts/AccountsChart.js @@ -22,6 +22,7 @@ import withAccountsTableActions from './withAccountsTableActions'; function AccountsChart({ // #withAccounts accountsTableState, + accountsTableStateChanged, // #withAccountsActions setAccountsTableState, @@ -41,6 +42,7 @@ function AccountsChart({ return ( @@ -58,6 +60,9 @@ function AccountsChart({ } export default compose( - withAccounts(({ accountsTableState }) => ({ accountsTableState })), + withAccounts(({ accountsTableState, accountsTableStateChanged }) => ({ + accountsTableState, + accountsTableStateChanged, + })), withAccountsTableActions, )(AccountsChart); diff --git a/client/src/containers/Accounts/AccountsChartProvider.js b/client/src/containers/Accounts/AccountsChartProvider.js index 03353ead0..91b2e106d 100644 --- a/client/src/containers/Accounts/AccountsChartProvider.js +++ b/client/src/containers/Accounts/AccountsChartProvider.js @@ -8,7 +8,7 @@ const AccountsChartContext = createContext(); /** * Accounts chart data provider. */ -function AccountsChartProvider({ query, ...props }) { +function AccountsChartProvider({ query, tableStateChanged,...props }) { // Fetch accounts resource views and fields. const { data: resourceViews, isLoading: isViewsLoading } = useResourceViews('accounts'); diff --git a/client/src/containers/Accounts/withAccounts.js b/client/src/containers/Accounts/withAccounts.js index 0f595de4d..10ff14b73 100644 --- a/client/src/containers/Accounts/withAccounts.js +++ b/client/src/containers/Accounts/withAccounts.js @@ -1,15 +1,17 @@ import { connect } from 'react-redux'; import { getAccountsTableStateFactory, + accountsTableStateChangedFactory, } from 'store/accounts/accounts.selectors'; export default (mapState) => { const getAccountsTableState = getAccountsTableStateFactory(); + const accountsTableStateChanged = accountsTableStateChangedFactory(); const mapStateToProps = (state, props) => { const mapped = { accountsTableState: getAccountsTableState(state, props), - accountsSelectedRows: null, + accountsTableStateChanged: accountsTableStateChanged(state, props), }; return mapState ? mapState(mapped, state, props) : mapped; }; diff --git a/client/src/containers/Customers/CustomersLanding/CustomersList.js b/client/src/containers/Customers/CustomersLanding/CustomersList.js index 0e56bb645..cae241ab7 100644 --- a/client/src/containers/Customers/CustomersLanding/CustomersList.js +++ b/client/src/containers/Customers/CustomersLanding/CustomersList.js @@ -21,9 +21,10 @@ import { compose } from 'utils'; function CustomersList({ // #withCustomers customersTableState, + customersTableStateChanged, // #withCustomersActions - setCustomersTableState + setCustomersTableState, }) { // Resets the accounts table state once the page unmount. useEffect( @@ -38,7 +39,10 @@ function CustomersList({ ); return ( - + @@ -54,6 +58,9 @@ function CustomersList({ } export default compose( - withCustomers(({ customersTableState }) => ({ customersTableState })), - withCustomersActions + withCustomers(({ customersTableState, customersTableStateChanged }) => ({ + customersTableState, + customersTableStateChanged, + })), + withCustomersActions, )(CustomersList); diff --git a/client/src/containers/Customers/CustomersLanding/CustomersListProvider.js b/client/src/containers/Customers/CustomersLanding/CustomersListProvider.js index 94508abfb..cd38e45a5 100644 --- a/client/src/containers/Customers/CustomersLanding/CustomersListProvider.js +++ b/client/src/containers/Customers/CustomersLanding/CustomersListProvider.js @@ -1,13 +1,14 @@ import React, { createContext } from 'react'; +import { isEmpty } from 'lodash'; import DashboardInsider from 'components/Dashboard/DashboardInsider'; import { useResourceMeta, useResourceViews, useCustomers } from 'hooks/query'; -import { isTableEmptyStatus, getFieldsFromResourceMeta } from 'utils'; +import { getFieldsFromResourceMeta } from 'utils'; import { transformCustomersStateToQuery } from './utils'; const CustomersListContext = createContext(); -function CustomersListProvider({ tableState, ...props }) { +function CustomersListProvider({ tableState, tableStateChanged, ...props }) { // Transformes the table state to fetch query. const tableQuery = transformCustomersStateToQuery(tableState); @@ -31,13 +32,7 @@ function CustomersListProvider({ tableState, ...props }) { // Detarmines the datatable empty status. const isEmptyStatus = - isTableEmptyStatus({ - data: customers, - pagination, - filterMeta, - }) && - !isCustomersFetching && - !tableState.inactiveMode; + isEmpty(customers) && !isCustomersLoading && !tableStateChanged; const state = { customersViews, diff --git a/client/src/containers/Customers/CustomersLanding/withCustomers.js b/client/src/containers/Customers/CustomersLanding/withCustomers.js index 3e41f2e1a..2a25d4f85 100644 --- a/client/src/containers/Customers/CustomersLanding/withCustomers.js +++ b/client/src/containers/Customers/CustomersLanding/withCustomers.js @@ -1,12 +1,18 @@ import { connect } from 'react-redux'; -import { getCustomersTableStateFactory } from 'store/customers/customers.selectors'; +import { + getCustomersTableStateFactory, + customersTableStateChangedFactory, +} from 'store/customers/customers.selectors'; + export default (mapState) => { const getCustomersTableState = getCustomersTableStateFactory(); + const customersTableStateChanged = customersTableStateChangedFactory(); const mapStateToProps = (state, props) => { const mapped = { customersTableState: getCustomersTableState(state, props), + customersTableStateChanged: customersTableStateChanged(state, props), }; return mapState ? mapState(mapped, state, props) : mapped; }; diff --git a/client/src/containers/Drawers/AccountDrawer/AccountDrawerActionBar.js b/client/src/containers/Drawers/AccountDrawer/AccountDrawerActionBar.js index c8e6b4e61..37f7b6a4e 100644 --- a/client/src/containers/Drawers/AccountDrawer/AccountDrawerActionBar.js +++ b/client/src/containers/Drawers/AccountDrawer/AccountDrawerActionBar.js @@ -1,6 +1,12 @@ import React from 'react'; import Icon from 'components/Icon'; -import { Button, Classes, NavbarGroup, Intent } from '@blueprintjs/core'; +import { + Button, + Classes, + NavbarGroup, + Intent, + NavbarDivider, +} from '@blueprintjs/core'; import { FormattedMessage as T } from 'components'; import DashboardActionsBar from 'components/Dashboard/DashboardActionsBar'; @@ -11,6 +17,7 @@ import withDrawerActions from 'containers/Drawer/withDrawerActions'; import { safeCallback } from 'utils'; import { compose } from 'utils'; +import { useAccountDrawerContext } from './AccountDrawerProvider'; /** * Account drawer action bar. @@ -24,10 +31,10 @@ function AccountDrawerActionBar({ // #withDrawerActions closeDrawer, - - // #ownProps - account, }) { + // Account drawer context. + const { account } = useAccountDrawerContext(); + // Handle new child button click. const onNewChildAccount = () => { openDialog('account-form', { @@ -44,10 +51,8 @@ function AccountDrawerActionBar({ // Handle delete action account. const onDeleteAccount = () => { - if (account) { - openAlert('account-delete', { accountId: account.id }); - closeDrawer('account-drawer'); - } + openAlert('account-delete', { accountId: account.id }); + closeDrawer('account-drawer'); }; return ( @@ -65,9 +70,10 @@ function AccountDrawerActionBar({ text={} onClick={safeCallback(onNewChildAccount)} /> +