fix: dashboard sidebar expanding.

This commit is contained in:
a.bouhuolia
2021-04-19 18:34:02 +02:00
parent c6aca4ecfa
commit f29c1b6cec
27 changed files with 178 additions and 230 deletions

View File

@@ -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}
/>
</Route>
))}

View File

@@ -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 (
<div className={CLASSES.DASHBOARD_PAGE}>
<Suspense fallback={''}>
<Suspense fallback={
<div class="dashboard__fallback-loading">
<Spinner size={40} value={null} />
</div>
}>
<Component />
</Suspense>
</div>
);
}
export default compose(withDashboardActions)(DashboardPage);
export default compose(
withDashboardActions,
)(DashboardPage);

View File

@@ -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 (

View File

@@ -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) => (
<div
{...column.getFooterProps({
className: 'td',
className: classNames(column.className || '', 'td'),
})}
>
{column.render('Footer')}
<div className={'cell-inner'}>
{column.render('Footer')}
</div>
</div>
))}
</div>

View File

@@ -72,20 +72,6 @@ export function ActionsMenu({
);
}
/**
* Actions cell.
*/
export function ActionsCell(props) {
return (
<Popover
position={Position.RIGHT_BOTTOM}
content={<ActionsMenu {...props} />}
>
<Button icon={<Icon icon="more-h-16" iconSize={16} />} />
</Popover>
);
}
/**
* Normal cell.
*/

View File

@@ -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) => (
<Tag minimal={true} round={true} intent={Intent.NONE}>
{ row.code }
</Tag>
);
/**
* 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,
},
],
[],
)

View File

@@ -49,20 +49,6 @@ export function ActionsMenu({
);
}
/**
* Actions cell.
*/
export function ActionsCell(props) {
return (
<Popover
content={<ActionsMenu {...props} />}
position={Position.RIGHT_BOTTOM}
>
<Button icon={<Icon icon="more-h-16" iconSize={16} />} />
</Popover>
);
}
/**
* 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],
);

View File

@@ -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);

View File

@@ -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';

View File

@@ -175,14 +175,6 @@ export function useExpensesTableColumns() {
className: 'description',
disableSortBy: true,
},
{
id: 'actions',
Header: '',
Cell: ActionsCell,
className: 'actions',
width: 50,
disableResizing: true,
},
],
[],
);

View File

@@ -1,5 +1,7 @@
import React from 'react';
import 'style/pages/InventoryAdjustments/List.scss';
import { DashboardContentTable, DashboardPageContent } from 'components';
import InventoryAdjustmentsAlerts from './InventoryAdjustmentsAlerts';

View File

@@ -179,14 +179,6 @@ export const useInventoryAdjustmentsColumns = () => {
width: 125,
className: 'created_at',
},
{
id: 'actions',
Header: '',
Cell: ActionsCell,
className: 'actions',
width: 50,
disableResizing: true,
},
],
[formatMessage],
);

View File

@@ -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,

View File

@@ -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],
);

View File

@@ -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 (
<ItemsCategoriesProvider query={{}}>
<ItemsCategoriesProvider>
<ItemsCategoryActionsBar />
<DashboardPageContent>

View File

@@ -25,7 +25,7 @@ function ItemsCategoriesProvider({ query, ...props }) {
};
return (
<DashboardInsider name={'item-category-list'}>
<DashboardInsider name={'items-categories-list'}>
<ItemsCategoriesContext.Provider value={state} {...props} />
</DashboardInsider>
);

View File

@@ -81,14 +81,7 @@ export function useItemsCategoriesTableColumns() {
accessor: 'description',
className: 'description',
width: 220,
},
{
id: 'actions',
Header: '',
Cell: TableActionsCell,
className: 'actions',
width: 50,
},
}
],
[formatMessage],
);

View File

@@ -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,
},
);
}

View File

@@ -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
};

View File

@@ -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.'
};

View File

@@ -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 businesss 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,
},
{

View File

@@ -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 }
};
}

View File

@@ -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) => {

View File

@@ -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',
};

View File

@@ -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;

View File

@@ -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) {

View File

@@ -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<ISystemUser> {
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) {