feat: Sidebar overlay.

This commit is contained in:
a.bouhuolia
2021-08-02 09:36:45 +02:00
parent 3eae731e42
commit 79e38d2374
26 changed files with 170 additions and 51 deletions

View File

@@ -48,7 +48,7 @@ function App({ locale }) {
<div className="App">
<Router history={history}>
<Switch>
{/* <Route path={'/auth'} component={Authentication} /> */}
<Route path={'/auth'} component={Authentication} />
<Route path={'/'}>
<PrivateRoute component={DashboardPrivatePages} />
</Route>

View File

@@ -9,7 +9,7 @@ function DashboardSplitPane({
sidebarExpended,
children
}) {
const initialSize = 210;
const initialSize = 190;
const [defaultSize, setDefaultSize] = useState(
parseInt(localStorage.getItem('dashboard-size'), 10) || initialSize,

View File

@@ -2,7 +2,6 @@ import React from 'react';
import SidebarContainer from 'components/Sidebar/SidebarContainer';
import SidebarHead from 'components/Sidebar/SidebarHead';
import SidebarMenu from 'components/Sidebar/SidebarMenu';
import SidebarOverlay from 'components/SidebarOverlay';
import 'style/containers/Dashboard/Sidebar.scss';

View File

@@ -217,7 +217,7 @@ export default [
],
},
{
text: <T id={'financial_reports'} />,
text: <T id={'Reports'} />,
children: [
{
text: <T id={'balance_sheet'} />,

View File

@@ -10,6 +10,7 @@ import {
PopoverInteractionKind,
Position,
Intent,
Switch,
} from '@blueprintjs/core';
import classNames from 'classnames';
import { FormattedMessage as T } from 'components';
@@ -36,6 +37,7 @@ function AccountsActionsBar({
// #withAccounts
accountsSelectedRows,
accountsInactiveMode,
// #withAlertActions
openAlert,
@@ -74,6 +76,12 @@ function AccountsActionsBar({
setAccountsTableState({ customViewId: customView.id || null });
};
// Handle inactive switch changing.
const handleInactiveSwitchChange = (event) => {
const checked = event.target.checked;
setAccountsTableState({ inactiveMode: checked });
};
return (
<DashboardActionsBar>
<NavbarGroup>
@@ -149,6 +157,11 @@ function AccountsActionsBar({
icon={<Icon icon="file-import-16" iconSize={16} />}
text={<T id={'import'} />}
/>
<Switch
labelElement={<T id={'inactive'} />}
defaultChecked={accountsInactiveMode}
onChange={handleInactiveSwitchChange}
/>
</NavbarGroup>
</DashboardActionsBar>
);
@@ -157,8 +170,9 @@ function AccountsActionsBar({
export default compose(
withDialogActions,
withAlertActions,
withAccounts(({ accountsSelectedRows }) => ({
withAccounts(({ accountsSelectedRows, accountsTableState }) => ({
accountsSelectedRows,
accountsInactiveMode: accountsTableState.inactiveMode,
})),
withAccountsTableActions,
)(AccountsActionsBar);

View File

@@ -12,7 +12,8 @@ import AccountsDataTable from './AccountsDataTable';
import withAccounts from 'containers/Accounts/withAccounts';
import { transformTableStateToQuery, compose } from 'utils';
import { compose } from 'utils';
import { transformAccountsStateToQuery } from './utils';
/**
* Accounts chart list.
@@ -23,7 +24,7 @@ function AccountsChart({
}) {
return (
<AccountsChartProvider
query={transformTableStateToQuery(accountsTableState)}
query={transformAccountsStateToQuery(accountsTableState)}
>
<AccountsActionsBar />

View File

@@ -3,7 +3,7 @@ import { Intent, Tag } from '@blueprintjs/core';
import { If, AppToaster } from 'components';
import intl from 'react-intl-universal';
import { NormalCell, BalanceCell } from './components';
import { isBlank, compose } from 'utils';
import { transformTableStateToQuery, isBlank } from 'utils';
/**
* Account name accessor.
@@ -100,3 +100,13 @@ export const useAccountsTableColumns = () => {
export const rowClassNames = (row) => ({
inactive: !row.original.active,
});
/**
* Transformes the table state to list query.
*/
export const transformAccountsStateToQuery = (tableState) => {
return {
...transformTableStateToQuery(tableState),
inactive_mode: tableState.inactiveMode,
}
}

View File

@@ -8,6 +8,7 @@ import {
Popover,
Position,
PopoverInteractionKind,
Switch
} from '@blueprintjs/core';
import { FormattedMessage as T } from 'components';
import intl from 'react-intl-universal';
@@ -34,15 +35,13 @@ function CustomerActionsBar({
// #withCustomersActions
setCustomersTableState,
accountsInactiveMode,
// #withAlertActions
openAlert,
}) {
// History context.
const history = useHistory();
// React intl
// Customers list context.
const { customersViews } = useCustomersListContext();
@@ -61,6 +60,11 @@ function CustomerActionsBar({
customViewId: viewId.id || null,
});
};
// Handle inactive switch changing.
const handleInactiveSwitchChange = (event) => {
const checked = event.target.checked;
setCustomersTableState({ inactiveMode: checked });
};
return (
<DashboardActionsBar>
@@ -86,7 +90,7 @@ function CustomerActionsBar({
>
<Button
className={classNames(Classes.MINIMAL, 'button--filter')}
text={`${intl.get('filters_applied')}`}
text={`${intl.get('filter')}`}
icon={<Icon icon="filter-16" iconSize={16} />}
/>
</Popover>
@@ -110,6 +114,11 @@ function CustomerActionsBar({
icon={<Icon icon="file-export-16" iconSize={16} />}
text={<T id={'export'} />}
/>
<Switch
labelElement={<T id={'inactive'} />}
defaultChecked={accountsInactiveMode}
onChange={handleInactiveSwitchChange}
/>
</NavbarGroup>
</DashboardActionsBar>
);
@@ -117,8 +126,9 @@ function CustomerActionsBar({
export default compose(
withCustomersActions,
withCustomers(({ customersSelectedRows }) => ({
withCustomers(({ customersSelectedRows, customersTableState }) => ({
customersSelectedRows,
accountsInactiveMode: customersTableState.inactiveMode,
})),
withAlertActions,
)(CustomerActionsBar);

View File

@@ -11,7 +11,7 @@ import CustomersAlerts from 'containers/Customers/CustomersAlerts';
import { CustomersListProvider } from './CustomersListProvider';
import withCustomers from './withCustomers';
import { transformTableStateToQuery, compose } from 'utils';
import { compose } from 'utils';
/**
* Customers list.
@@ -21,9 +21,7 @@ function CustomersList({
customersTableState,
}) {
return (
<CustomersListProvider
query={transformTableStateToQuery(customersTableState)}
>
<CustomersListProvider tableState={customersTableState}>
<CustomersActionsBar />
<DashboardPageContent>

View File

@@ -3,10 +3,14 @@ import React, { createContext } from 'react';
import DashboardInsider from 'components/Dashboard/DashboardInsider';
import { useResourceViews, useCustomers } from 'hooks/query';
import { isTableEmptyStatus } from 'utils';
import { transformCustomersStateToQuery } from './utils';
const CustomersListContext = createContext();
function CustomersListProvider({ query, ...props }) {
function CustomersListProvider({ tableState, ...props }) {
// Transformes the table state to fetch query.
const tableQuery = transformCustomersStateToQuery(tableState);
// Fetch customers resource views and fields.
const {
data: customersViews,
@@ -18,12 +22,12 @@ function CustomersListProvider({ query, ...props }) {
data: { customers, pagination, filterMeta },
isLoading: isCustomersLoading,
isFetching: isCustomersFetching,
} = useCustomers(query, { keepPreviousData: true });
} = useCustomers(tableQuery, { keepPreviousData: true });
// Detarmines the datatable empty status.
const isEmptyStatus = isTableEmptyStatus({
data: customers, pagination, filterMeta,
}) && !isCustomersFetching;
}) && !isCustomersFetching && !tableState.inactiveMode;
const state = {
customersViews,

View File

@@ -0,0 +1,8 @@
import { transformTableStateToQuery } from 'utils';
export const transformCustomersStateToQuery = (tableState) => {
return {
...transformTableStateToQuery(tableState),
inactive_mode: tableState.inactiveMode,
};
};

View File

@@ -10,6 +10,7 @@ import {
Button,
Classes,
Intent,
Switch,
} from '@blueprintjs/core';
import { FormattedMessage as T } from 'components';
import intl from 'react-intl-universal';
@@ -34,6 +35,7 @@ function ItemsActionsBar({
// #withItemActions
setItemsTableState,
itemsInactiveMode,
// #withAlertActions
openAlert,
@@ -42,7 +44,6 @@ function ItemsActionsBar({
const { itemsViews } = useItemsListContext();
// React intl.
// History context.
const history = useHistory();
@@ -62,6 +63,12 @@ function ItemsActionsBar({
openAlert('items-bulk-delete', { itemsIds: itemsSelectedRows });
};
// Handle inactive switch changing.
const handleInactiveSwitchChange = (event) => {
const checked = event.target.checked;
setItemsTableState({ inactiveMode: checked });
};
return (
<DashboardActionsBar>
<NavbarGroup>
@@ -112,13 +119,21 @@ function ItemsActionsBar({
icon={<Icon icon="file-export-16" iconSize={16} />}
text={<T id={'export'} />}
/>
<Switch
labelElement={<T id={'inactive'} />}
defaultChecked={itemsInactiveMode}
onChange={handleInactiveSwitchChange}
/>
</NavbarGroup>
</DashboardActionsBar>
);
}
export default compose(
withItems(({ itemsSelectedRows }) => ({ itemsSelectedRows })),
withItems(({ itemsSelectedRows, itemsTableState }) => ({
itemsSelectedRows,
itemsInactiveMode: itemsTableState.inactiveMode,
})),
withItemsActions,
withAlertActions,
)(ItemsActionsBar);

View File

@@ -12,7 +12,6 @@ import ItemsDataTable from './ItemsDataTable';
import { ItemsListProvider } from './ItemsListProvider';
import withItems from './withItems';
import { transformTableStateToQuery } from 'utils';
/**
* Items list.
@@ -22,7 +21,7 @@ function ItemsList({
itemsTableState,
}) {
return (
<ItemsListProvider query={transformTableStateToQuery(itemsTableState)}>
<ItemsListProvider tableState={itemsTableState}>
<ItemsActionsBar />
<DashboardPageContent>

View File

@@ -1,6 +1,7 @@
import React, { createContext } from 'react';
import { transformTableQueryToParams, isTableEmptyStatus } from 'utils';
import { transformItemsTableState } from './utils';
import DashboardInsider from 'components/Dashboard/DashboardInsider';
import { useResourceViews, useResourceFields, useItems } from 'hooks/query';
@@ -11,9 +12,11 @@ const ItemsContext = createContext();
* Items list provider.
*/
function ItemsListProvider({
query,
tableState,
...props
}) {
const tableQuery = transformItemsTableState(tableState);
// Fetch accounts resource views and fields.
const { data: itemsViews, isLoading: isViewsLoading } = useResourceViews(
'items',
@@ -30,13 +33,13 @@ function ItemsListProvider({
isFetching: isItemsFetching,
isLoading: isItemsLoading,
} = useItems({
...transformTableQueryToParams(query)
...transformTableQueryToParams(tableQuery)
}, { keepPreviousData: true });
// Detarmines the datatable empty status.
const isEmptyStatus = isTableEmptyStatus({
data: items, pagination, filterMeta,
}) && !isItemsFetching;
}) && !isItemsFetching && !tableState.inactiveMode;
const state = {
itemsViews,

View File

@@ -1,7 +1,10 @@
import intl from 'react-intl-universal';
import { Intent } from '@blueprintjs/core';
import { AppToaster } from 'components';
import { defaultFastFieldShouldUpdate } from 'utils';
import {
transformTableStateToQuery,
defaultFastFieldShouldUpdate,
} from 'utils';
export const transitionItemTypeKeyToLabel = (itemTypeKey) => {
const table = {
@@ -121,3 +124,10 @@ export const purchaseDescFieldShouldUpdate = (newProps, oldProps) => {
defaultFastFieldShouldUpdate(newProps, oldProps)
);
};
export function transformItemsTableState(tableState) {
return {
...transformTableStateToQuery(tableState),
inactive_mode: tableState.inactiveMode,
};
}

View File

@@ -8,6 +8,7 @@ import {
Popover,
Position,
PopoverInteractionKind,
Switch
} from '@blueprintjs/core';
import { FormattedMessage as T } from 'components';
import intl from 'react-intl-universal';
@@ -21,6 +22,7 @@ import { useVendorsListContext } from './VendorsListProvider';
import { useHistory } from 'react-router-dom';
import withVendorsActions from './withVendorsActions';
import withVendors from './withVendors';
import { compose } from 'utils';
@@ -30,6 +32,7 @@ import { compose } from 'utils';
function VendorActionsBar({
// #withVendorActions
setVendorsTableState,
vendorsInactiveMode
}) {
const history = useHistory();
@@ -46,6 +49,12 @@ function VendorActionsBar({
const handleTabChange = (customView) => {
setVendorsTableState({ customViewId: customView.id || null });
};
// Handle inactive switch changing.
const handleInactiveSwitchChange = (event) => {
const checked = event.target.checked;
setVendorsTableState({ inactiveMode: checked });
};
return (
<DashboardActionsBar>
@@ -98,6 +107,11 @@ function VendorActionsBar({
icon={<Icon icon="file-export-16" iconSize={16} />}
text={<T id={'export'} />}
/>
<Switch
labelElement={<T id={'inactive'} />}
defaultChecked={vendorsInactiveMode}
onChange={handleInactiveSwitchChange}
/>
</NavbarGroup>
</DashboardActionsBar>
);
@@ -105,4 +119,7 @@ function VendorActionsBar({
export default compose(
withVendorsActions,
withVendors(({ vendorsTableState }) => ({
vendorsInactiveMode: vendorsTableState.inactiveMode,
})),
)(VendorActionsBar);

View File

@@ -12,7 +12,7 @@ import VendorsTable from './VendorsTable';
import withVendors from './withVendors';
import { transformTableStateToQuery, compose } from 'utils';
import { compose } from 'utils';
/**
* Vendors list page.
@@ -22,7 +22,7 @@ function VendorsList({
vendorsTableState,
}) {
return (
<VendorsListProvider query={transformTableStateToQuery(vendorsTableState)}>
<VendorsListProvider tableState={vendorsTableState}>
<VendorActionsBar />
<DashboardPageContent>

View File

@@ -3,28 +3,34 @@ import React, { createContext } from 'react';
import DashboardInsider from 'components/Dashboard/DashboardInsider';
import { useResourceViews, useVendors } from 'hooks/query';
import { isTableEmptyStatus } from 'utils';
import { transformVendorsStateToQuery } from './utils';
const VendorsListContext = createContext();
function VendorsListProvider({ query, ...props }) {
function VendorsListProvider({ tableState, ...props }) {
// Transformes the vendors table state to fetch query.
const tableQuery = transformVendorsStateToQuery(tableState);
// Fetch vendors list with pagination meta.
const {
data: { vendors, pagination, filterMeta },
isLoading: isVendorsLoading,
isFetching: isVendorsFetching,
} = useVendors(query, { keepPreviousData: true });
} = useVendors(tableQuery, { keepPreviousData: true });
// Fetch customers resource views and fields.
const {
data: vendorsViews,
isLoading: isVendorsViewsLoading,
} = useResourceViews('vendors');
const { data: vendorsViews, isLoading: isVendorsViewsLoading } =
useResourceViews('vendors');
// Detarmines the datatable empty status.
const isEmptyStatus = isTableEmptyStatus({
data: vendors, pagination, filterMeta,
}) && !isVendorsLoading;
const isEmptyStatus =
isTableEmptyStatus({
data: vendors,
pagination,
filterMeta,
}) &&
!isVendorsLoading &&
!tableState.inactiveMode;
const provider = {
vendors,
@@ -35,7 +41,7 @@ function VendorsListProvider({ query, ...props }) {
isVendorsFetching,
isVendorsViewsLoading,
isEmptyStatus
isEmptyStatus,
};
return (

View File

@@ -2,13 +2,22 @@ import { useCallback } from 'react';
import intl from 'react-intl-universal';
import { Intent } from '@blueprintjs/core';
import { AppToaster } from 'components';
import { transformTableStateToQuery } from 'utils';
// Transform API errors in toasts messages.
export const transformErrors = useCallback((errors) => {
export const transformErrors = (errors) => {
if (errors.some((e) => e.type === 'VENDOR.HAS.BILLS')) {
AppToaster.show({
message: intl.get('vendor_has_bills'),
intent: Intent.DANGER,
});
}
}, []);
};
export const transformVendorsStateToQuery = (tableState) => {
return {
...transformTableStateToQuery(tableState),
inactive_mode: tableState.inactiveMode || false,
};
}

View File

@@ -1177,5 +1177,6 @@
"New service": "New service",
"New inventory item": "New inventory item",
"New purchase invoice": "New purchase invoice",
"Sales/Purchases": "Sales/Purchases"
"Sales/Purchases": "Sales/Purchases",
"Reports": "Reports"
}

View File

@@ -7,6 +7,7 @@ const initialState = {
tableState: {
pageSize: 12,
pageIndex: 0,
inactiveMode: false,
},
};

View File

@@ -9,6 +9,7 @@ const initialState = {
pageSize: 12,
pageIndex: 0,
filters: [],
inactiveMode: false,
},
selectedRows: [],
};

View File

@@ -8,6 +8,7 @@ const initialState = {
tableState: {
pageSize: 12,
pageIndex: 0,
inactiveMode: false,
},
};

View File

@@ -16,13 +16,6 @@
padding-bottom: 0.3rem;
}
.tr.inactive .td {
color: #646b82;
&.normal .#{$ns}-icon {
color: #9eaab6;
}
}
.account_name {
.bp3-popover-wrapper--inactive-semafro {
margin-left: 8px;

View File

@@ -217,6 +217,26 @@ $dashboard-views-bar-height: 45px;
margin-right: 0;
}
}
.bp3-control.bp3-switch{
margin-bottom: 0;
margin-left: 8px;
.bp3-control-indicator{
height: 16px;
min-width: 1.8em;
}
.bp3-control-indicator::before{
box-shadow: 0 0 0;
}
input ~ .bp3-control-indicator{
background: rgba(167, 182, 194, 0.55);
}
input:checked ~ .bp3-control-indicator{
background: #0069ff;
}
}
}
}

View File

@@ -15,7 +15,6 @@
}
}
.tr.inactive .td {
color: #646b82;
&.normal .bp3-icon {
color: #9eaab6;