diff --git a/client/src/components/Dashboard/DashboardContentRoute.js b/client/src/components/Dashboard/DashboardContentRoute.js
index b464095d8..4951f186b 100644
--- a/client/src/components/Dashboard/DashboardContentRoute.js
+++ b/client/src/components/Dashboard/DashboardContentRoute.js
@@ -22,7 +22,8 @@ export default function DashboardContentRoute() {
pageTitle={route.pageTitle}
backLink={route.backLink}
hint={route.hint}
- sidebarShrink={route.sidebarShrink}
+ sidebarExpand={route.sidebarExpand}
+ pageType={route.pageType}
/>
))}
diff --git a/client/src/components/Dashboard/DashboardPage.js b/client/src/components/Dashboard/DashboardPage.js
index 1738cb615..215daff68 100644
--- a/client/src/components/Dashboard/DashboardPage.js
+++ b/client/src/components/Dashboard/DashboardPage.js
@@ -1,7 +1,10 @@
import React, { useEffect, Suspense } from 'react';
+import { isUndefined } from 'lodash';
import { CLASSES } from 'common/classes';
import withDashboardActions from 'containers/Dashboard/withDashboardActions';
import { compose } from 'utils';
+import { Spinner } from '@blueprintjs/core';
+
/**
* Dashboard pages wrapper.
*/
@@ -9,7 +12,7 @@ function DashboardPage({
// #ownProps
pageTitle,
backLink,
- sidebarShrink,
+ sidebarExpand = true,
Component,
name,
hint,
@@ -17,10 +20,10 @@ function DashboardPage({
// #withDashboardActions
changePageTitle,
setDashboardBackLink,
- setSidebarShrink,
- resetSidebarPreviousExpand,
changePageHint,
+ toggleSidebarExpand
}) {
+ // Hydrate the given page title.
useEffect(() => {
pageTitle && changePageTitle(pageTitle);
@@ -29,6 +32,7 @@ function DashboardPage({
};
});
+ // Hydrate the given page hint.
useEffect(() => {
hint && changePageHint(hint);
@@ -37,6 +41,7 @@ function DashboardPage({
}
}, [hint, changePageHint]);
+ // Hydrate the dashboard back link status.
useEffect(() => {
backLink && setDashboardBackLink(backLink);
@@ -45,16 +50,6 @@ function DashboardPage({
};
}, [backLink, setDashboardBackLink]);
- // Handle sidebar shrink in mount and reset to the pervious state
- // once the page unmount.
- useEffect(() => {
- sidebarShrink && setSidebarShrink();
-
- return () => {
- sidebarShrink && resetSidebarPreviousExpand();
- };
- }, [resetSidebarPreviousExpand, sidebarShrink, setSidebarShrink]);
-
useEffect(() => {
const className = `page-${name}`;
name && document.body.classList.add(className);
@@ -64,13 +59,23 @@ function DashboardPage({
};
}, [name]);
+ useEffect(() => {
+ toggleSidebarExpand(sidebarExpand);
+ }, [toggleSidebarExpand, sidebarExpand])
+
return (
-
+
+
+
+ }>
);
}
-export default compose(withDashboardActions)(DashboardPage);
+export default compose(
+ withDashboardActions,
+)(DashboardPage);
diff --git a/client/src/components/Dashboard/DashboardTopbar.js b/client/src/components/Dashboard/DashboardTopbar.js
index a597962c4..32d9b8b18 100644
--- a/client/src/components/Dashboard/DashboardTopbar.js
+++ b/client/src/components/Dashboard/DashboardTopbar.js
@@ -34,8 +34,7 @@ function DashboardTopbar({
pageHint,
// #withDashboardActions
- toggleSidebarExpend,
- recordSidebarPreviousExpand,
+ toggleSidebarExpand,
// #withDashboard
sidebarExpended,
@@ -53,8 +52,7 @@ function DashboardTopbar({
};
const handleSidebarToggleBtn = () => {
- toggleSidebarExpend();
- recordSidebarPreviousExpand();
+ toggleSidebarExpand();
};
return (
diff --git a/client/src/components/Datatable/TableFooter.js b/client/src/components/Datatable/TableFooter.js
index e682e4bd4..acb50b693 100644
--- a/client/src/components/Datatable/TableFooter.js
+++ b/client/src/components/Datatable/TableFooter.js
@@ -1,4 +1,5 @@
import React, { useContext } from 'react';
+import classNames from 'classnames';
import TableContext from './TableContext';
/**
@@ -20,10 +21,12 @@ export default function TableFooter() {
{group.headers.map((column) => (
- {column.render('Footer')}
+
+ {column.render('Footer')}
+
))}
diff --git a/client/src/containers/Accounts/components.js b/client/src/containers/Accounts/components.js
index f9d903088..28d5e541a 100644
--- a/client/src/containers/Accounts/components.js
+++ b/client/src/containers/Accounts/components.js
@@ -72,20 +72,6 @@ export function ActionsMenu({
);
}
-/**
- * Actions cell.
- */
-export function ActionsCell(props) {
- return (
- }
- >
- } />
-
- );
-}
-
/**
* Normal cell.
*/
diff --git a/client/src/containers/Accounts/utils.js b/client/src/containers/Accounts/utils.js
index 29e4ce466..510092628 100644
--- a/client/src/containers/Accounts/utils.js
+++ b/client/src/containers/Accounts/utils.js
@@ -1,8 +1,8 @@
import React from 'react';
-import { Intent } from '@blueprintjs/core';
+import { Intent, Tag } from '@blueprintjs/core';
import { If, AppToaster } from 'components';
import { formatMessage } from 'services/intl';
-import { NormalCell, BalanceCell, ActionsCell } from './components';
+import { NormalCell, BalanceCell } from './components';
/**
* Account name accessor.
@@ -40,6 +40,13 @@ export const handleDeleteErrors = (errors) => {
}
};
+
+export const AccountCodeAccessor = (row) => (
+
+ { row.code }
+
+);
+
/**
* Accounts table columns.
*/
@@ -56,7 +63,7 @@ export const useAccountsTableColumns = () => {
{
id: 'code',
Header: formatMessage({ id: 'code' }),
- accessor: 'code',
+ accessor: AccountCodeAccessor,
className: 'code',
width: 80,
},
@@ -88,14 +95,6 @@ export const useAccountsTableColumns = () => {
Cell: BalanceCell,
width: 150,
},
- {
- id: 'actions',
- Header: '',
- Cell: ActionsCell,
- className: 'actions',
- width: 50,
- skeletonWidthMin: 100,
- },
],
[],
)
diff --git a/client/src/containers/Customers/CustomersLanding/components.js b/client/src/containers/Customers/CustomersLanding/components.js
index 38b05a403..136c35d89 100644
--- a/client/src/containers/Customers/CustomersLanding/components.js
+++ b/client/src/containers/Customers/CustomersLanding/components.js
@@ -49,20 +49,6 @@ export function ActionsMenu({
);
}
-/**
- * Actions cell.
- */
-export function ActionsCell(props) {
- return (
- }
- position={Position.RIGHT_BOTTOM}
- >
- } />
-
- );
-}
-
/**
* Avatar cell.
*/
@@ -129,14 +115,6 @@ export function useCustomersTableColumns() {
className: 'receivable_balance',
width: 100,
},
- {
- id: 'actions',
- Cell: ActionsCell,
- className: 'actions',
- width: 70,
- disableResizing: true,
- disableSortBy: true,
- },
],
[formatMessage],
);
diff --git a/client/src/containers/Dashboard/withDashboardActions.js b/client/src/containers/Dashboard/withDashboardActions.js
index d55dee24a..472bbc486 100644
--- a/client/src/containers/Dashboard/withDashboardActions.js
+++ b/client/src/containers/Dashboard/withDashboardActions.js
@@ -1,5 +1,8 @@
import { connect } from 'react-redux';
import t from 'store/types';
+import {
+ toggleExpendSidebar,
+} from 'store/dashboard/dashboard.actions';
const mapActionsToProps = (dispatch) => ({
changePageTitle: (pageTitle) =>
@@ -14,10 +17,10 @@ const mapActionsToProps = (dispatch) => ({
pageSubtitle,
}),
- changePageHint: (pageHint) =>
+ changePageHint: (pageHint) =>
dispatch({
type: t.CHANGE_DASHBOARD_PAGE_HINT,
- payload: { pageHint }
+ payload: { pageHint },
}),
setTopbarEditView: (id) =>
@@ -36,32 +39,22 @@ const mapActionsToProps = (dispatch) => ({
type: t.SET_DASHBOARD_REQUEST_COMPLETED,
}),
- toggleSidebarExpend: () =>
+ /**
+ * Toggles the sidebar expend.
+ */
+ toggleSidebarExpand: (toggle) => dispatch(toggleExpendSidebar(toggle)),
+
+ changePreferencesPageTitle: (pageTitle) =>
dispatch({
- type: t.SIDEBAR_EXPEND_TOGGLE,
+ type: 'CHANGE_PREFERENCES_PAGE_TITLE',
+ pageTitle,
+ }),
+
+ setDashboardBackLink: (backLink) =>
+ dispatch({
+ type: t.SET_DASHBOARD_BACK_LINK,
+ payload: { backLink },
}),
-
- changePreferencesPageTitle: (pageTitle) => dispatch({
- type: 'CHANGE_PREFERENCES_PAGE_TITLE',
- pageTitle,
- }),
- setSidebarShrink: () => dispatch({
- type: t.SIDEBAR_SHRINK,
- }),
- setSidebarExpand: () => dispatch({
- type: t.SIDEBAR_SHRINK,
- }),
- resetSidebarPreviousExpand: () => dispatch({
- type: t.RESET_SIDEBAR_PREVIOUS_EXPAND,
- }),
- recordSidebarPreviousExpand: () => dispatch({
- type: t.RECORD_SIDEBAR_PREVIOUS_EXPAND,
- }),
-
- setDashboardBackLink: (backLink) => dispatch({
- type: t.SET_DASHBOARD_BACK_LINK,
- payload: { backLink }
- })
});
export default connect(null, mapActionsToProps);
diff --git a/client/src/containers/Expenses/ExpensesLanding/ExpenseDataTable.js b/client/src/containers/Expenses/ExpensesLanding/ExpenseDataTable.js
index c0b62ab01..365d91135 100644
--- a/client/src/containers/Expenses/ExpensesLanding/ExpenseDataTable.js
+++ b/client/src/containers/Expenses/ExpensesLanding/ExpenseDataTable.js
@@ -1,13 +1,9 @@
import React, { useCallback } from 'react';
-import classNames from 'classnames';
import { useHistory } from 'react-router-dom';
import { compose } from 'utils';
import { useExpensesListContext } from './ExpensesListProvider';
-import { Choose } from 'components';
-import { CLASSES } from 'common/classes';
-
import DataTable from 'components/DataTable';
import ExpensesEmptyStatus from './ExpensesEmptyStatus';
import TableSkeletonRows from 'components/Datatable/TableSkeletonRows';
diff --git a/client/src/containers/Expenses/ExpensesLanding/components.js b/client/src/containers/Expenses/ExpensesLanding/components.js
index ac751cb09..bb1693a43 100644
--- a/client/src/containers/Expenses/ExpensesLanding/components.js
+++ b/client/src/containers/Expenses/ExpensesLanding/components.js
@@ -175,14 +175,6 @@ export function useExpensesTableColumns() {
className: 'description',
disableSortBy: true,
},
- {
- id: 'actions',
- Header: '',
- Cell: ActionsCell,
- className: 'actions',
- width: 50,
- disableResizing: true,
- },
],
[],
);
diff --git a/client/src/containers/InventoryAdjustments/InventoryAdjustmentList.js b/client/src/containers/InventoryAdjustments/InventoryAdjustmentList.js
index 36645bd36..f6b130455 100644
--- a/client/src/containers/InventoryAdjustments/InventoryAdjustmentList.js
+++ b/client/src/containers/InventoryAdjustments/InventoryAdjustmentList.js
@@ -1,5 +1,7 @@
import React from 'react';
+import 'style/pages/InventoryAdjustments/List.scss';
+
import { DashboardContentTable, DashboardPageContent } from 'components';
import InventoryAdjustmentsAlerts from './InventoryAdjustmentsAlerts';
diff --git a/client/src/containers/InventoryAdjustments/components.js b/client/src/containers/InventoryAdjustments/components.js
index d9a975103..17aaac7a6 100644
--- a/client/src/containers/InventoryAdjustments/components.js
+++ b/client/src/containers/InventoryAdjustments/components.js
@@ -179,14 +179,6 @@ export const useInventoryAdjustmentsColumns = () => {
width: 125,
className: 'created_at',
},
- {
- id: 'actions',
- Header: '',
- Cell: ActionsCell,
- className: 'actions',
- width: 50,
- disableResizing: true,
- },
],
[formatMessage],
);
diff --git a/client/src/containers/Items/ItemsListProvider.js b/client/src/containers/Items/ItemsListProvider.js
index a2b71ae64..08947b56b 100644
--- a/client/src/containers/Items/ItemsListProvider.js
+++ b/client/src/containers/Items/ItemsListProvider.js
@@ -1,11 +1,9 @@
-import React, { useEffect, createContext } from 'react';
-import { useIntl } from 'react-intl';
+import React, { createContext } from 'react';
import { transformTableQueryToParams, isTableEmptyStatus } from 'utils';
import DashboardInsider from 'components/Dashboard/DashboardInsider';
import { useResourceViews, useResourceFields, useItems } from 'hooks/query';
-import { useDashboardPageTitle } from 'hooks/state';
const ItemsContext = createContext();
@@ -40,17 +38,6 @@ function ItemsListProvider({
data: items, pagination, filterMeta,
}) && !isItemsFetching;
- // Format message intl.
- const { formatMessage } = useIntl();
-
- // Change page title dispatcher.
- const changePageTitle = useDashboardPageTitle();
-
- // Changeas the page title once the page mount.
- useEffect(() => {
- changePageTitle(formatMessage({ id: 'items_list' }));
- }, [changePageTitle, formatMessage]);
-
const state = {
itemsViews,
itemsFields,
diff --git a/client/src/containers/Items/components.js b/client/src/containers/Items/components.js
index f338c0298..a44a50ad3 100644
--- a/client/src/containers/Items/components.js
+++ b/client/src/containers/Items/components.js
@@ -181,7 +181,6 @@ export const useItemsTableColumns = () => {
{
id: 'sell_price',
Header: formatMessage({ id: 'sell_price' }),
- // Cell: SellPriceCell,
accessor: 'sell_price_formatted',
className: 'sell-price',
width: 150,
@@ -189,7 +188,6 @@ export const useItemsTableColumns = () => {
{
id: 'cost_price',
Header: formatMessage({ id: 'cost_price' }),
- // Cell: CostPriceCell,
accessor: 'cost_price_formatted',
className: 'cost-price',
width: 150,
@@ -201,12 +199,6 @@ export const useItemsTableColumns = () => {
Cell: QuantityOnHandCell,
width: 140,
},
- {
- id: 'actions',
- Cell: ItemsActionsTableCell,
- width: 60,
- skeletonWidthMin: 100,
- },
],
[formatMessage],
);
diff --git a/client/src/containers/ItemsCategories/ItemCategoriesList.js b/client/src/containers/ItemsCategories/ItemCategoriesList.js
index 71b5ac805..d0220a575 100644
--- a/client/src/containers/ItemsCategories/ItemCategoriesList.js
+++ b/client/src/containers/ItemsCategories/ItemCategoriesList.js
@@ -1,4 +1,6 @@
import React from 'react';
+import 'style/pages/ItemsCategories/List.scss';
+
import { DashboardContentTable, DashboardPageContent } from 'components';
import ItemsCategoriesAlerts from './ItemsCategoriesAlerts';
@@ -11,7 +13,7 @@ import ItemCategoriesTable from './ItemCategoriesTable';
*/
export default function ItemCategoryList() {
return (
-
+
diff --git a/client/src/containers/ItemsCategories/ItemsCategoriesProvider.js b/client/src/containers/ItemsCategories/ItemsCategoriesProvider.js
index aeb558a4d..f6995bb9b 100644
--- a/client/src/containers/ItemsCategories/ItemsCategoriesProvider.js
+++ b/client/src/containers/ItemsCategories/ItemsCategoriesProvider.js
@@ -25,7 +25,7 @@ function ItemsCategoriesProvider({ query, ...props }) {
};
return (
-
+
);
diff --git a/client/src/containers/ItemsCategories/components.js b/client/src/containers/ItemsCategories/components.js
index b7d9a6137..d3997c198 100644
--- a/client/src/containers/ItemsCategories/components.js
+++ b/client/src/containers/ItemsCategories/components.js
@@ -81,14 +81,7 @@ export function useItemsCategoriesTableColumns() {
accessor: 'description',
className: 'description',
width: 220,
- },
- {
- id: 'actions',
- Header: '',
- Cell: TableActionsCell,
- className: 'actions',
- width: 50,
- },
+ }
],
[formatMessage],
);
diff --git a/client/src/hooks/query/contacts.js b/client/src/hooks/query/contacts.js
index 6652c5297..b56df5071 100644
--- a/client/src/hooks/query/contacts.js
+++ b/client/src/hooks/query/contacts.js
@@ -7,8 +7,29 @@ import { useQueryTenant } from '../useQueryRequest';
export function useContact(id, props) {
const apiRequest = useApiRequest();
- return useQueryTenant(['CONTACT', id], () => apiRequest.get(`contacts/${id}`), {
- select: (res) => res.data.customer,
- ...props,
- });
+ return useQueryTenant(
+ ['CONTACT', id],
+ () => apiRequest.get(`contacts/${id}`),
+ {
+ select: (res) => res.data.customer,
+ ...props,
+ },
+ );
+}
+
+/**
+ * Retrieve the auto-complete contacts.
+ */
+export function useAutoCompleteContacts(props) {
+ const apiRequest = useApiRequest();
+
+ return useQueryTenant(
+ ['CONTACTS', 'AUTO-COMPLETE'],
+ () => apiRequest.get('contacts/auto-complete'),
+ {
+ select: (res) => res.data.contacts,
+ defaultData: [],
+ ...props,
+ },
+ );
}
diff --git a/client/src/hooks/query/types.js b/client/src/hooks/query/types.js
index bfbb32c69..11cdb869d 100644
--- a/client/src/hooks/query/types.js
+++ b/client/src/hooks/query/types.js
@@ -96,8 +96,17 @@ const ORGANIZATIONS = {
const SUBSCRIPTIONS = {
SUBSCRIPTIONS: 'SUBSCRIPTIONS',
-}
+};
+const EXPENSES = {
+ EXPENSES: 'EXPENSES',
+ EXPENSE: 'EXPENSE',
+};
+
+const MANUAL_JOURNALS = {
+ MANUAL_JOURNALS: 'MANUAL_JOURNALS',
+ MANUAL_JOURNAL: 'MANUAL_JOURNAL',
+};
export default {
...ACCOUNTS,
...BILLS,
@@ -115,5 +124,7 @@ export default {
...USERS,
...SETTING,
...ORGANIZATIONS,
- ...SUBSCRIPTIONS
+ ...SUBSCRIPTIONS,
+ ...EXPENSES,
+ ...MANUAL_JOURNALS
};
diff --git a/client/src/lang/en/index.js b/client/src/lang/en/index.js
index e1e04f1a5..860014a3e 100644
--- a/client/src/lang/en/index.js
+++ b/client/src/lang/en/index.js
@@ -858,7 +858,7 @@ export default {
the_item_categories_has_been_deleted_successfully:
'The item categories has been deleted successfully .',
receivable_accounts_should_assign_with_customers:
- 'receivable accounts should assign with customers',
+ 'Receivable accounts should assign with customers.',
delivered: 'Delivered',
save_and_deliver: 'Save & Deliver',
deliver_and_new: 'Deliver and new',
@@ -1049,4 +1049,5 @@ export default {
asset_value: 'Asset value',
average: 'Average',
inventory_valuation: 'Inventory valuation',
+ payable_accounts_should_assign_with_vendors: 'Payable accounts should assign with vendors.'
};
diff --git a/client/src/routes/dashboard.js b/client/src/routes/dashboard.js
index 70816143e..52a816b2e 100644
--- a/client/src/routes/dashboard.js
+++ b/client/src/routes/dashboard.js
@@ -32,7 +32,7 @@ export default [
breadcrumb: 'Make Journal Entry',
hotkey: 'ctrl+shift+m',
pageTitle: formatMessage({ id: 'new_journal' }),
- sidebarShrink: true,
+ sidebarExpand: false,
backLink: true,
},
{
@@ -42,7 +42,7 @@ export default [
),
breadcrumb: 'Edit',
pageTitle: formatMessage({ id: 'edit_journal' }),
- sidebarShrink: true,
+ sidebarExpand: false,
backLink: true,
},
{
@@ -92,6 +92,7 @@ export default [
component: lazy(() => import('containers/Items/ItemsList')),
breadcrumb: 'Items',
hotkey: 'shift+w',
+ pageTitle: formatMessage({ id: 'items_list' }),
},
// Inventory adjustments.
@@ -115,7 +116,7 @@ export default [
hotkey: 'shift+4',
pageTitle: formatMessage({ id: 'general_ledger' }),
backLink: true,
- sidebarShrink: true,
+ sidebarExpand: false,
},
{
path: `/financial-reports/balance-sheet`,
@@ -127,7 +128,7 @@ export default [
hotkey: 'shift+1',
pageTitle: formatMessage({ id: 'balance_sheet' }),
backLink: true,
- sidebarShrink: true,
+ sidebarExpand: false,
},
{
path: `/financial-reports/trial-balance-sheet`,
@@ -141,7 +142,7 @@ export default [
hotkey: 'shift+5',
pageTitle: formatMessage({ id: 'trial_balance_sheet' }),
backLink: true,
- sidebarShrink: true,
+ sidebarExpand: false,
},
{
path: `/financial-reports/profit-loss-sheet`,
@@ -153,7 +154,7 @@ export default [
hotkey: 'shift+2',
pageTitle: formatMessage({ id: 'profit_loss_sheet' }),
backLink: true,
- sidebarShrink: true,
+ sidebarExpand: false,
},
{
path: '/financial-reports/receivable-aging-summary',
@@ -164,7 +165,7 @@ export default [
hint: "Summarize total unpaid balances of customers invoices with number of days the unpaid invoice is overdue.",
pageTitle: formatMessage({ id: 'receivable_aging_summary' }),
backLink: true,
- sidebarShrink: true,
+ sidebarExpand: false,
},
{
path: '/financial-reports/payable-aging-summary',
@@ -175,7 +176,7 @@ export default [
hint: "Summarize total unpaid balances of vendors purchase invoices with the number of days the unpaid invoice is overdue.",
pageTitle: formatMessage({ id: 'payable_aging_summary' }),
backLink: true,
- sidebarShrink: true,
+ sidebarExpand: false,
},
{
path: `/financial-reports/journal-sheet`,
@@ -186,7 +187,7 @@ export default [
hint: "The debit and credit entries of system transactions, sorted by date.",
hotkey: 'shift+3',
pageTitle: formatMessage({ id: 'journal_sheet' }),
- sidebarShrink: true,
+ sidebarExpand: false,
backLink: true,
},
{
@@ -200,7 +201,7 @@ export default [
// hotkey: '',
pageTitle: formatMessage({ id: 'purchases_by_items' }),
backLink: true,
- sidebarShrink: true,
+ sidebarExpand: false,
},
{
path: `/financial-reports/sales-by-items`,
@@ -211,7 +212,7 @@ export default [
pageTitle: formatMessage({ id: 'sales_by_items' }),
hint: 'Summarize the business’s sold items quantity, income and average income rate of each item during a specific point in time.',
backLink: true,
- sidebarShrink: true,
+ sidebarExpand: false,
},
{
path: `/financial-reports/inventory-valuation`,
@@ -224,7 +225,7 @@ export default [
hint: 'Summerize your transactions for each inventory item and how they affect quantity, valuation and weighted average.',
pageTitle: formatMessage({ id: 'inventory_valuation' }),
backLink: true,
- sidebarShrink: true,
+ sidebarExpand: false,
},
{
path: '/financial-reports',
@@ -250,7 +251,7 @@ export default [
breadcrumb: 'Expenses',
hotkey: 'ctrl+shift+x',
pageTitle: formatMessage({ id: 'new_expense' }),
- sidebarShrink: true,
+ sidebarExpand: false,
backLink: true,
},
{
@@ -260,7 +261,7 @@ export default [
),
breadcrumb: 'Edit',
pageTitle: formatMessage({ id: 'edit_expense' }),
- sidebarShrink: true,
+ sidebarExpand: false,
backLink: true,
},
{
@@ -367,7 +368,7 @@ export default [
breadcrumb: 'Edit',
pageTitle: formatMessage({ id: 'edit_estimate' }),
backLink: true,
- sidebarShrink: true,
+ sidebarExpand: false,
},
{
path: `/invoices/new?from_estimate_id=/:id`,
@@ -378,7 +379,7 @@ export default [
breadcrumb: 'New Estimate',
pageTitle: formatMessage({ id: 'new_estimate' }),
backLink: true,
- sidebarShrink: true,
+ sidebarExpand: false,
},
{
path: `/estimates/new`,
@@ -390,7 +391,7 @@ export default [
hotkey: 'ctrl+shift+e',
pageTitle: formatMessage({ id: 'new_estimate' }),
backLink: true,
- sidebarShrink: true,
+ sidebarExpand: false,
},
{
path: `/estimates`,
@@ -412,7 +413,7 @@ export default [
name: 'invoice-edit',
breadcrumb: 'Edit',
pageTitle: formatMessage({ id: 'edit_invoice' }),
- sidebarShrink: true,
+ sidebarExpand: false,
backLink: true,
},
{
@@ -424,7 +425,7 @@ export default [
breadcrumb: 'New Invoice',
hotkey: 'ctrl+shift+i',
pageTitle: formatMessage({ id: 'new_invoice' }),
- sidebarShrink: true,
+ sidebarExpand: false,
backLink: true,
},
{
@@ -447,7 +448,7 @@ export default [
breadcrumb: 'Edit',
pageTitle: formatMessage({ id: 'edit_receipt' }),
backLink: true,
- sidebarShrink: true,
+ sidebarExpand: false,
},
{
path: `/receipts/new`,
@@ -459,7 +460,7 @@ export default [
hotkey: 'ctrl+shift+r',
pageTitle: formatMessage({ id: 'new_receipt' }),
backLink: true,
- sidebarShrink: true,
+ sidebarExpand: false,
},
{
path: `/receipts`,
@@ -483,7 +484,7 @@ export default [
breadcrumb: 'Edit',
pageTitle: formatMessage({ id: 'edit_payment_receive' }),
backLink: true,
- sidebarShrink: true,
+ sidebarExpand: false,
},
{
path: `/payment-receives/new`,
@@ -496,7 +497,7 @@ export default [
breadcrumb: 'New Payment Receive',
pageTitle: formatMessage({ id: 'new_payment_receive' }),
backLink: true,
- sidebarShrink: true,
+ sidebarExpand: false,
},
{
path: `/payment-receives`,
@@ -518,7 +519,7 @@ export default [
name: 'bill-edit',
breadcrumb: 'Edit',
pageTitle: formatMessage({ id: 'edit_bill' }),
- sidebarShrink: true,
+ sidebarExpand: false,
backLink: true,
},
{
@@ -530,7 +531,7 @@ export default [
breadcrumb: 'New Bill',
hotkey: 'ctrl+shift+b',
pageTitle: formatMessage({ id: 'new_bill' }),
- sidebarShrink: true,
+ sidebarExpand: false,
backLink: true,
},
{
@@ -560,7 +561,7 @@ export default [
name: 'payment-made-edit',
breadcrumb: 'Edit',
pageTitle: formatMessage({ id: 'edit_payment_made' }),
- sidebarShrink: true,
+ sidebarExpand: false,
backLink: true,
},
{
@@ -573,7 +574,7 @@ export default [
name: 'payment-made-new',
breadcrumb: 'New Payment Made',
pageTitle: formatMessage({ id: 'new_payment_made' }),
- sidebarShrink: true,
+ sidebarExpand: false,
backLink: true,
},
{
diff --git a/client/src/store/dashboard/dashboard.actions.js b/client/src/store/dashboard/dashboard.actions.js
index 4eb52517b..9810a23ce 100644
--- a/client/src/store/dashboard/dashboard.actions.js
+++ b/client/src/store/dashboard/dashboard.actions.js
@@ -60,3 +60,13 @@ export function closeDrawer(name, payload) {
payload,
};
}
+
+/**
+ * Toggles the sidebar expend.
+ */
+export function toggleExpendSidebar(toggle) {
+ return {
+ type: t.SIDEBAR_EXPEND_TOGGLE,
+ payload: { toggle }
+ };
+}
\ No newline at end of file
diff --git a/client/src/store/dashboard/dashboard.reducer.js b/client/src/store/dashboard/dashboard.reducer.js
index b65161323..3045336cb 100644
--- a/client/src/store/dashboard/dashboard.reducer.js
+++ b/client/src/store/dashboard/dashboard.reducer.js
@@ -1,5 +1,6 @@
-import t from 'store/types';
import { createReducer } from '@reduxjs/toolkit';
+import { isUndefined } from 'lodash';
+import t from 'store/types';
import { persistReducer, purgeStoredState } from 'redux-persist';
import storage from 'redux-persist/lib/storage';
@@ -9,7 +10,6 @@ const initialState = {
pageHint: '',
preferencesPageTitle: '',
sidebarExpended: true,
- previousSidebarExpended: null,
dialogs: {},
alerts: {},
drawers: {},
@@ -22,7 +22,7 @@ const STORAGE_KEY = 'bigcapital:dashboard';
const CONFIG = {
key: STORAGE_KEY,
- whitelist: ['sidebarExpended', 'previousSidebarExpended'],
+ whitelist: [],
storage,
};
@@ -88,33 +88,11 @@ const reducerInstance = createReducer(initialState, {
state.topbarEditViewId = action.id;
},
- [t.SET_DASHBOARD_REQUEST_LOADING]: (state, action) => {
- state.requestsLoading = state.requestsLoading + 1;
- },
-
- [t.SET_DASHBOARD_REQUEST_COMPLETED]: (state, action) => {
- const requestsLoading = state.requestsLoading - 1;
- state.requestsLoading = Math.max(requestsLoading, 0);
- },
-
- [t.RECORD_SIDEBAR_PREVIOUS_EXPAND]: (state) => {
- state.previousSidebarExpended = state.sidebarExpended;
- },
-
- [t.SIDEBAR_EXPEND_TOGGLE]: (state) => {
- state.sidebarExpended = !state.sidebarExpended;
- },
-
- [t.SIDEBAR_EXPAND]: (state) => {
- state.sidebarExpended = true;
- },
-
- [t.SIDEBAR_SHRINK]: (state) => {
- state.sidebarExpended = false;
- },
-
- [t.RESET_SIDEBAR_PREVIOUS_EXPAND]: (state) => {
- state.sidebarExpended = state.previousSidebarExpended;
+ [t.SIDEBAR_EXPEND_TOGGLE]: (state, action) => {
+ const { toggle } = action.payload;
+ state.sidebarExpended = isUndefined(toggle)
+ ? !state.sidebarExpended
+ : !!toggle;
},
[t.SET_DASHBOARD_BACK_LINK]: (state, action) => {
diff --git a/client/src/store/dashboard/dashboard.types.js b/client/src/store/dashboard/dashboard.types.js
index faf6aabdc..e1ddc7425 100644
--- a/client/src/store/dashboard/dashboard.types.js
+++ b/client/src/store/dashboard/dashboard.types.js
@@ -12,12 +12,6 @@ export default {
CHANGE_PREFERENCES_PAGE_TITLE: 'CHANGE_PREFERENCES_PAGE_TITLE',
ALTER_DASHBOARD_PAGE_SUBTITLE: 'ALTER_DASHBOARD_PAGE_SUBTITLE',
SET_TOPBAR_EDIT_VIEW: 'SET_TOPBAR_EDIT_VIEW',
- SET_DASHBOARD_REQUEST_LOADING: 'SET_DASHBOARD_REQUEST_LOADING',
- SET_DASHBOARD_REQUEST_COMPLETED: 'SET_DASHBOARD_REQUEST_COMPLETED',
SIDEBAR_EXPEND_TOGGLE: 'SIDEBAR_EXPEND_TOGGLE',
- SIDEBAR_EXPAND: 'SIDEBAR_EXPAND',
- SIDEBAR_SHRINK: 'SIDEBAR_SHRINK',
- RESET_SIDEBAR_PREVIOUS_EXPAND: 'RESET_SIDEBAR_PREVIOUS_EXPAND',
- RECORD_SIDEBAR_PREVIOUS_EXPAND: 'RECORD_SIDEBAR_PREVIOUS_EXPAND',
SET_DASHBOARD_BACK_LINK: 'SET_DASHBOARD_BACK_LINK',
};
diff --git a/client/src/style/pages/Dashboard/Dashboard.scss b/client/src/style/pages/Dashboard/Dashboard.scss
index a2a47504f..f59a2942d 100644
--- a/client/src/style/pages/Dashboard/Dashboard.scss
+++ b/client/src/style/pages/Dashboard/Dashboard.scss
@@ -307,6 +307,17 @@ $dashboard-views-bar-height: 45px;
flex: 1 0 0;
}
+ &__fallback-loading{
+ display: flex;
+ flex-direction: column;
+ height: 100%;
+ background-color: #fbfbfb;
+
+ .bp3-spinner{
+ margin: auto;
+ }
+ }
+
&__page-content {
display: flex;
flex-direction: column;
diff --git a/server/src/api/controllers/Users.ts b/server/src/api/controllers/Users.ts
index ef35a71f7..8fa57a51d 100644
--- a/server/src/api/controllers/Users.ts
+++ b/server/src/api/controllers/Users.ts
@@ -223,13 +223,14 @@ export default class UsersController extends BaseController{
* @param {NextFunction} next
*/
catchServiceErrors(error: Error, req: Request, res: Response, next: NextFunction) {
+
if (error instanceof ServiceErrors) {
const errorReasons = [];
-
- if (error.errorType === 'EMAIL_ALREADY_EXISTS') {
+
+ if (error.hasType('EMAIL_ALREADY_EXISTS')) {
errorReasons.push({ type: 'EMAIL_ALREADY_EXIST', code: 100 });
}
- if (error.errorType === 'PHONE_NUMBER_ALREADY_EXIST') {
+ if (error.hasType('PHONE_NUMBER_ALREADY_EXIST')) {
errorReasons.push({ type: 'PHONE_NUMBER_ALREADY_EXIST', code: 200 });
}
if (errorReasons.length > 0) {
diff --git a/server/src/services/Users/UsersService.ts b/server/src/services/Users/UsersService.ts
index 0d3bf4eef..3803c6a69 100644
--- a/server/src/services/Users/UsersService.ts
+++ b/server/src/services/Users/UsersService.ts
@@ -2,6 +2,7 @@ import TenancyService from 'services/Tenancy/TenancyService';
import { Inject, Service } from 'typedi';
import { ServiceError, ServiceErrors } from 'exceptions';
import { ISystemUser, ISystemUserDTO } from 'interfaces';
+import { SystemUser } from 'system/models';
const ERRORS = {
CANNOT_DELETE_LAST_USER: 'CANNOT_DELETE_LAST_USER',
@@ -38,20 +39,20 @@ export default class UsersService {
): Promise {
const { systemUserRepository } = this.repositories;
- const userByEmail = await systemUserRepository.findOne({
- email: userDTO.email,
- id: userId,
- });
- const userByPhoneNumber = await systemUserRepository.findOne({
- phoneNumber: userDTO.phoneNumber,
- id: userId,
- });
+ const userByEmail = await SystemUser.query()
+ .where('email', userDTO.email)
+ .whereNot('id', userId);
+
+ const userByPhoneNumber = await SystemUser.query()
+ .where('phone_number', userDTO.phoneNumber)
+ .whereNot('id', userId);
+
const serviceErrors: ServiceError[] = [];
- if (userByEmail) {
+ if (userByEmail.length > 0) {
serviceErrors.push(new ServiceError(ERRORS.EMAIL_ALREADY_EXISTS));
}
- if (userByPhoneNumber) {
+ if (userByPhoneNumber.length > 0) {
serviceErrors.push(new ServiceError(ERRORS.PHONE_NUMBER_ALREADY_EXIST));
}
if (serviceErrors.length > 0) {