mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-21 15:20:34 +00:00
Merge branch 'develop' into ui-tweaks
This commit is contained in:
@@ -60,6 +60,16 @@ export const BANK_TRANSACTION_CATEGORIZED = 'Bank transaction categorized';
|
|||||||
export const BANK_TRANSACTION_UNCATEGORIZED = 'Bank transaction uncategorized';
|
export const BANK_TRANSACTION_UNCATEGORIZED = 'Bank transaction uncategorized';
|
||||||
export const BANK_ACCOUNT_DISCONNECTED = 'Bank account disconnected';
|
export const BANK_ACCOUNT_DISCONNECTED = 'Bank account disconnected';
|
||||||
|
|
||||||
|
export const MANUAL_JOURNAL_CREATED = 'Manual journal created';
|
||||||
|
export const MANUAL_JOURNAL_EDITED = 'Manual journal edited';
|
||||||
|
export const MANUAL_JOURNAL_DELETED = 'Manual journal deleted';
|
||||||
|
export const MANUAL_JOURNAL_PUBLISHED = 'Manual journal published';
|
||||||
|
|
||||||
|
export const BANK_RULE_CREATED = 'Bank rule created';
|
||||||
|
export const BANK_RULE_EDITED = 'Bank rule edited';
|
||||||
|
export const BANK_RULE_DELETED = 'Bank rule deleted';
|
||||||
|
|
||||||
|
// # Event Groups
|
||||||
export const ACCOUNT_GROUP = 'Account';
|
export const ACCOUNT_GROUP = 'Account';
|
||||||
export const ITEM_GROUP = 'Item';
|
export const ITEM_GROUP = 'Item';
|
||||||
export const AUTH_GROUP = 'Auth';
|
export const AUTH_GROUP = 'Auth';
|
||||||
@@ -67,21 +77,3 @@ export const SALE_GROUP = 'Sale';
|
|||||||
export const PAYMENT_GROUP = 'Payment';
|
export const PAYMENT_GROUP = 'Payment';
|
||||||
export const BILL_GROUP = 'Bill';
|
export const BILL_GROUP = 'Bill';
|
||||||
export const EXPENSE_GROUP = 'Expense';
|
export const EXPENSE_GROUP = 'Expense';
|
||||||
|
|
||||||
export const MANUAL_JOURNAL_CREATED = 'Manual journal created';
|
|
||||||
export const MANUAL_JOURNAL_EDITED = 'Manual journal edited';
|
|
||||||
export const MANUAL_JOURNAL_DELETED = 'Manual journal deleted';
|
|
||||||
export const MANUAL_JOURNAL_PUBLISHED = 'Manual journal published';
|
|
||||||
|
|
||||||
export const CUSTOMER_CREATED = 'Customer created';
|
|
||||||
export const CUSTOMER_EDITED = 'Customer edited';
|
|
||||||
export const CUSTOMER_DELETED = 'Customer deleted';
|
|
||||||
|
|
||||||
export const VENDOR_CREATED = 'Vendor created';
|
|
||||||
export const VENDOR_EDITED = 'Vendor edited';
|
|
||||||
export const VENDOR_DELETED = 'Vendor deleted';
|
|
||||||
|
|
||||||
export const BANK_RULE_CREATED = 'Bank rule created';
|
|
||||||
export const BANK_RULE_EDITED = 'Bank rule edited';
|
|
||||||
export const BANK_RULE_DELETED = 'Bank rule deleted';
|
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,12 @@ import {
|
|||||||
Classes,
|
Classes,
|
||||||
Tooltip,
|
Tooltip,
|
||||||
Position,
|
Position,
|
||||||
|
MenuItem,
|
||||||
|
Menu,
|
||||||
|
MenuDivider,
|
||||||
} from '@blueprintjs/core';
|
} from '@blueprintjs/core';
|
||||||
|
import { Popover2 } from '@blueprintjs/popover2';
|
||||||
|
|
||||||
import { FormattedMessage as T, Icon, Hint, If } from '@/components';
|
import { FormattedMessage as T, Icon, Hint, If } from '@/components';
|
||||||
|
|
||||||
import DashboardTopbarUser from '@/components/Dashboard/TopbarUser';
|
import DashboardTopbarUser from '@/components/Dashboard/TopbarUser';
|
||||||
@@ -19,9 +24,20 @@ import DashboardBackLink from '@/components/Dashboard/DashboardBackLink';
|
|||||||
import withUniversalSearchActions from '@/containers/UniversalSearch/withUniversalSearchActions';
|
import withUniversalSearchActions from '@/containers/UniversalSearch/withUniversalSearchActions';
|
||||||
import withDashboardActions from '@/containers/Dashboard/withDashboardActions';
|
import withDashboardActions from '@/containers/Dashboard/withDashboardActions';
|
||||||
import withDashboard from '@/containers/Dashboard/withDashboard';
|
import withDashboard from '@/containers/Dashboard/withDashboard';
|
||||||
|
import withDialogActions from '@/containers/Dialog/withDialogActions';
|
||||||
|
|
||||||
import QuickNewDropdown from '@/containers/QuickNewDropdown/QuickNewDropdown';
|
import QuickNewDropdown from '@/containers/QuickNewDropdown/QuickNewDropdown';
|
||||||
import { DashboardHamburgerButton, DashboardQuickSearchButton } from './_components';
|
import {
|
||||||
|
DashboardHamburgerButton,
|
||||||
|
DashboardQuickSearchButton,
|
||||||
|
} from './_components';
|
||||||
|
|
||||||
|
import { DialogsName } from '@/constants/dialogs';
|
||||||
|
import {
|
||||||
|
COMMUNITY_BIGCAPITAL_LINK,
|
||||||
|
DOCS_BIGCAPITAL_LINK,
|
||||||
|
} from '@/constants/routes';
|
||||||
|
|
||||||
import { compose } from '@/utils';
|
import { compose } from '@/utils';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -41,6 +57,9 @@ function DashboardTopbar({
|
|||||||
|
|
||||||
// #withGlobalSearch
|
// #withGlobalSearch
|
||||||
openGlobalSearch,
|
openGlobalSearch,
|
||||||
|
|
||||||
|
// #withDialogActions
|
||||||
|
openDialog,
|
||||||
}) {
|
}) {
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
|
|
||||||
@@ -112,11 +131,34 @@ function DashboardTopbar({
|
|||||||
/>
|
/>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
|
||||||
<Button
|
<Popover2
|
||||||
className={Classes.MINIMAL}
|
content={
|
||||||
icon={<Icon icon={'help-24'} iconSize={20} />}
|
<Menu>
|
||||||
text={<T id={'help'} />}
|
<MenuItem
|
||||||
/>
|
text={'Documents'}
|
||||||
|
onClick={() => window.open(DOCS_BIGCAPITAL_LINK)}
|
||||||
|
labelElement={<Icon icon={'share'} iconSize={16} />}
|
||||||
|
/>
|
||||||
|
<MenuItem
|
||||||
|
text={'Community support'}
|
||||||
|
onClick={() => window.open(COMMUNITY_BIGCAPITAL_LINK)}
|
||||||
|
labelElement={<Icon icon={'share'} iconSize={16} />}
|
||||||
|
/>
|
||||||
|
<MenuItem
|
||||||
|
text={'Keyboard shortcuts'}
|
||||||
|
onClick={() => openDialog(DialogsName.KeyboardShortcutForm)}
|
||||||
|
/>
|
||||||
|
<MenuDivider />
|
||||||
|
<MenuItem text={'Share feedback'} />
|
||||||
|
</Menu>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Button
|
||||||
|
className={Classes.MINIMAL}
|
||||||
|
icon={<Icon icon={'help-24'} iconSize={20} />}
|
||||||
|
text={<T id={'help'} />}
|
||||||
|
/>
|
||||||
|
</Popover2>
|
||||||
<NavbarDivider />
|
<NavbarDivider />
|
||||||
</NavbarGroup>
|
</NavbarGroup>
|
||||||
</Navbar>
|
</Navbar>
|
||||||
@@ -138,4 +180,5 @@ export default compose(
|
|||||||
pageHint,
|
pageHint,
|
||||||
})),
|
})),
|
||||||
withDashboardActions,
|
withDashboardActions,
|
||||||
|
withDialogActions,
|
||||||
)(DashboardTopbar);
|
)(DashboardTopbar);
|
||||||
|
|||||||
2
packages/webapp/src/constants/routes.ts
Normal file
2
packages/webapp/src/constants/routes.ts
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
export const DOCS_BIGCAPITAL_LINK = 'https://docs.bigcapital.app';
|
||||||
|
export const COMMUNITY_BIGCAPITAL_LINK = 'https://community.bigcapital.app';
|
||||||
@@ -34,21 +34,23 @@ import {
|
|||||||
} from '@/constants/cashflowOptions';
|
} from '@/constants/cashflowOptions';
|
||||||
import { useRefreshCashflowTransactions } from '@/hooks/query';
|
import { useRefreshCashflowTransactions } from '@/hooks/query';
|
||||||
import { useAccountTransactionsContext } from './AccountTransactionsProvider';
|
import { useAccountTransactionsContext } from './AccountTransactionsProvider';
|
||||||
|
import { useMediaQuery } from '@/hooks/useMediaQuery';
|
||||||
|
import { useAppShellContext } from '@/components/AppShell/AppContentShell/AppContentShellProvider';
|
||||||
|
|
||||||
import withDialogActions from '@/containers/Dialog/withDialogActions';
|
import withDialogActions from '@/containers/Dialog/withDialogActions';
|
||||||
import withSettings from '@/containers/Settings/withSettings';
|
import withSettings from '@/containers/Settings/withSettings';
|
||||||
import withSettingsActions from '@/containers/Settings/withSettingsActions';
|
import withSettingsActions from '@/containers/Settings/withSettingsActions';
|
||||||
|
import { withBankingActions } from '../withBankingActions';
|
||||||
import { compose } from '@/utils';
|
import { withBanking } from '../withBanking';
|
||||||
|
import withAlertActions from '@/containers/Alert/withAlertActions';
|
||||||
import {
|
import {
|
||||||
useUpdateBankAccount,
|
useUpdateBankAccount,
|
||||||
useExcludeUncategorizedTransactions,
|
useExcludeUncategorizedTransactions,
|
||||||
useUnexcludeUncategorizedTransactions,
|
useUnexcludeUncategorizedTransactions,
|
||||||
} from '@/hooks/query/bank-rules';
|
} from '@/hooks/query/bank-rules';
|
||||||
import { withBankingActions } from '../withBankingActions';
|
|
||||||
import { withBanking } from '../withBanking';
|
|
||||||
import withAlertActions from '@/containers/Alert/withAlertActions';
|
|
||||||
import { DialogsName } from '@/constants/dialogs';
|
import { DialogsName } from '@/constants/dialogs';
|
||||||
|
import { compose } from '@/utils';
|
||||||
|
|
||||||
function AccountTransactionsActionsBar({
|
function AccountTransactionsActionsBar({
|
||||||
// #withDialogActions
|
// #withDialogActions
|
||||||
@@ -221,6 +223,13 @@ function AccountTransactionsActionsBar({
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const { hideAside } = useAppShellContext();
|
||||||
|
const isMin1350Query = useMediaQuery('(min-width: 1350px)');
|
||||||
|
|
||||||
|
// Shrink actions to dropdown if the aside is open and matched the media query,
|
||||||
|
// To avoid actions overflow in small screens.
|
||||||
|
const shrinkActions = !hideAside && !isMin1350Query;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DashboardActionsBar>
|
<DashboardActionsBar>
|
||||||
<NavbarGroup>
|
<NavbarGroup>
|
||||||
@@ -241,23 +250,27 @@ function AccountTransactionsActionsBar({
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<NavbarDivider />
|
<NavbarDivider />
|
||||||
<Button
|
|
||||||
className={Classes.MINIMAL}
|
<If condition={!shrinkActions}>
|
||||||
icon={<Icon icon="print-16" iconSize={16} />}
|
<Button
|
||||||
text={<T id={'print'} />}
|
className={Classes.MINIMAL}
|
||||||
/>
|
icon={<Icon icon="print-16" iconSize={16} />}
|
||||||
<Button
|
text={<T id={'print'} />}
|
||||||
className={Classes.MINIMAL}
|
/>
|
||||||
icon={<Icon icon="file-export-16" iconSize={16} />}
|
<Button
|
||||||
text={<T id={'export'} />}
|
className={Classes.MINIMAL}
|
||||||
/>
|
icon={<Icon icon="file-export-16" iconSize={16} />}
|
||||||
<Button
|
text={<T id={'export'} />}
|
||||||
className={Classes.MINIMAL}
|
/>
|
||||||
icon={<Icon icon="file-import-16" iconSize={16} />}
|
<Button
|
||||||
text={<T id={'import'} />}
|
className={Classes.MINIMAL}
|
||||||
onClick={handleImportBtnClick}
|
icon={<Icon icon="file-import-16" iconSize={16} />}
|
||||||
/>
|
text={<T id={'import'} />}
|
||||||
<NavbarDivider />
|
onClick={handleImportBtnClick}
|
||||||
|
/>
|
||||||
|
<NavbarDivider />
|
||||||
|
</If>
|
||||||
|
|
||||||
<DashboardRowsHeightButton
|
<DashboardRowsHeightButton
|
||||||
initialValue={cashflowTansactionsTableSize}
|
initialValue={cashflowTansactionsTableSize}
|
||||||
onChange={handleTableRowSizeChange}
|
onChange={handleTableRowSizeChange}
|
||||||
@@ -290,6 +303,40 @@ function AccountTransactionsActionsBar({
|
|||||||
</Tooltip>
|
</Tooltip>
|
||||||
</If>
|
</If>
|
||||||
|
|
||||||
|
<If condition={shrinkActions}>
|
||||||
|
<NavbarDivider />
|
||||||
|
<Popover
|
||||||
|
minimal={true}
|
||||||
|
interactionKind={PopoverInteractionKind.CLICK}
|
||||||
|
position={Position.BOTTOM_LEFT}
|
||||||
|
modifiers={{
|
||||||
|
offset: { offset: '0, 4' },
|
||||||
|
}}
|
||||||
|
content={
|
||||||
|
<Menu>
|
||||||
|
<MenuItem
|
||||||
|
icon={<Icon icon="print-16" iconSize={16} />}
|
||||||
|
text={<T id={'print'} />}
|
||||||
|
/>
|
||||||
|
<MenuItem
|
||||||
|
icon={<Icon icon="file-export-16" iconSize={16} />}
|
||||||
|
text={<T id={'export'} />}
|
||||||
|
/>
|
||||||
|
<MenuItem
|
||||||
|
icon={<Icon icon="file-import-16" iconSize={16} />}
|
||||||
|
text={<T id={'import'} />}
|
||||||
|
onClick={handleImportBtnClick}
|
||||||
|
/>
|
||||||
|
</Menu>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Button
|
||||||
|
icon={<Icon icon="more-h-16" iconSize={16} />}
|
||||||
|
minimal={true}
|
||||||
|
/>
|
||||||
|
</Popover>
|
||||||
|
</If>
|
||||||
|
|
||||||
{!isEmpty(uncategorizedTransationsIdsSelected) && (
|
{!isEmpty(uncategorizedTransationsIdsSelected) && (
|
||||||
<Button
|
<Button
|
||||||
icon={<Icon icon="disable" iconSize={16} />}
|
icon={<Icon icon="disable" iconSize={16} />}
|
||||||
@@ -368,7 +415,6 @@ function AccountTransactionsActionsBar({
|
|||||||
</If>
|
</If>
|
||||||
|
|
||||||
<MenuItem onClick={handleBankRulesClick} text={'Bank rules'} />
|
<MenuItem onClick={handleBankRulesClick} text={'Bank rules'} />
|
||||||
|
|
||||||
<MenuDivider />
|
<MenuDivider />
|
||||||
<If condition={isSyncingOwner && isFeedsActive}>
|
<If condition={isSyncingOwner && isFeedsActive}>
|
||||||
<MenuItem
|
<MenuItem
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
// @ts-nocheck
|
||||||
|
import { Suspense, lazy } from 'react';
|
||||||
|
import { Spinner } from '@blueprintjs/core';
|
||||||
|
import { AppContentShell } from '@/components/AppShell';
|
||||||
|
|
||||||
|
const CategorizeTransactionAside = lazy(() =>
|
||||||
|
import('../CategorizeTransactionAside/CategorizeTransactionAside').then(
|
||||||
|
(module) => ({ default: module.CategorizeTransactionAside }),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
export function AccountTransactionsAside() {
|
||||||
|
return (
|
||||||
|
<AppContentShell.Aside>
|
||||||
|
<Suspense fallback={<Spinner size={20} />}>
|
||||||
|
<CategorizeTransactionAside />
|
||||||
|
</Suspense>
|
||||||
|
</AppContentShell.Aside>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -2,6 +2,8 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import intl from 'react-intl-universal';
|
import intl from 'react-intl-universal';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
|
import { curry } from 'lodash/fp';
|
||||||
|
import { useHistory } from 'react-router-dom';
|
||||||
import {
|
import {
|
||||||
Popover,
|
Popover,
|
||||||
Menu,
|
Menu,
|
||||||
@@ -11,10 +13,9 @@ import {
|
|||||||
Classes,
|
Classes,
|
||||||
} from '@blueprintjs/core';
|
} from '@blueprintjs/core';
|
||||||
import { Icon } from '@/components';
|
import { Icon } from '@/components';
|
||||||
import { useHistory } from 'react-router-dom';
|
|
||||||
import { curry } from 'lodash/fp';
|
|
||||||
|
|
||||||
import { useAccountTransactionsContext } from './AccountTransactionsProvider';
|
import { useAccountTransactionsContext } from './AccountTransactionsProvider';
|
||||||
|
import { useAppShellContext } from '@/components/AppShell/AppContentShell/AppContentShellProvider';
|
||||||
|
|
||||||
function AccountSwitchButton() {
|
function AccountSwitchButton() {
|
||||||
const { currentAccount } = useAccountTransactionsContext();
|
const { currentAccount } = useAccountTransactionsContext();
|
||||||
@@ -22,7 +23,7 @@ function AccountSwitchButton() {
|
|||||||
return (
|
return (
|
||||||
<AccountSwitchButtonBase
|
<AccountSwitchButtonBase
|
||||||
minimal={true}
|
minimal={true}
|
||||||
rightIcon={<Icon icon={'arrow-drop-down'} iconSize={24} />}
|
rightIcon={<Icon icon={'caret-down-16'} iconSize={16} />}
|
||||||
>
|
>
|
||||||
<AccountSwitchText>{currentAccount.name}</AccountSwitchText>
|
<AccountSwitchText>{currentAccount.name}</AccountSwitchText>
|
||||||
</AccountSwitchButtonBase>
|
</AccountSwitchButtonBase>
|
||||||
@@ -110,12 +111,16 @@ function AccountTransactionsDetailsBarSkeleton() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function AccountTransactionsDetailsContent() {
|
function AccountTransactionsDetailsContent() {
|
||||||
|
const { hideAside } = useAppShellContext();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
<AccountSwitchItem />
|
<AccountSwitchItem />
|
||||||
<AccountNumberItem />
|
|
||||||
|
{/** Hide some details once the aside opens to preserve space on details bar. */}
|
||||||
|
{hideAside && <AccountNumberItem />}
|
||||||
<AccountBalanceItem />
|
<AccountBalanceItem />
|
||||||
<AccountBankBalanceItem />
|
{hideAside && <AccountBankBalanceItem />}
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// @ts-nocheck
|
// @ts-nocheck
|
||||||
import React, { Suspense } from 'react';
|
|
||||||
import * as R from 'ramda';
|
import * as R from 'ramda';
|
||||||
import { Spinner } from '@blueprintjs/core';
|
import { Spinner } from '@blueprintjs/core';
|
||||||
|
import { Suspense, lazy } from 'react';
|
||||||
|
|
||||||
import '@/style/pages/CashFlow/AccountTransactions/List.scss';
|
import '@/style/pages/CashFlow/AccountTransactions/List.scss';
|
||||||
|
|
||||||
@@ -15,7 +15,7 @@ import {
|
|||||||
import { AccountTransactionsDetailsBar } from './AccountTransactionsDetailsBar';
|
import { AccountTransactionsDetailsBar } from './AccountTransactionsDetailsBar';
|
||||||
import { AccountTransactionsFilterTabs } from './AccountTransactionsFilterTabs';
|
import { AccountTransactionsFilterTabs } from './AccountTransactionsFilterTabs';
|
||||||
import { AppContentShell } from '@/components/AppShell';
|
import { AppContentShell } from '@/components/AppShell';
|
||||||
import { CategorizeTransactionAside } from '../CategorizeTransactionAside/CategorizeTransactionAside';
|
import { AccountTransactionsAside } from './AccountTransactionsAside';
|
||||||
import { AccountTransactionsLoadingBar } from './components';
|
import { AccountTransactionsLoadingBar } from './components';
|
||||||
import { withBanking } from '../withBanking';
|
import { withBanking } from '../withBanking';
|
||||||
|
|
||||||
@@ -56,14 +56,6 @@ function AccountTransactionsMain() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function AccountTransactionsAside() {
|
|
||||||
return (
|
|
||||||
<AppContentShell.Aside>
|
|
||||||
<CategorizeTransactionAside />
|
|
||||||
</AppContentShell.Aside>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default R.compose(
|
export default R.compose(
|
||||||
withBanking(
|
withBanking(
|
||||||
({ selectedUncategorizedTransactionId, openMatchingTransactionAside }) => ({
|
({ selectedUncategorizedTransactionId, openMatchingTransactionAside }) => ({
|
||||||
@@ -73,11 +65,8 @@ export default R.compose(
|
|||||||
),
|
),
|
||||||
)(AccountTransactionsListRoot);
|
)(AccountTransactionsListRoot);
|
||||||
|
|
||||||
const AccountsTransactionsAll = React.lazy(
|
const AccountsTransactionsAll = lazy(() => import('./AccountsTransactionsAll'));
|
||||||
() => import('./AccountsTransactionsAll'),
|
const AccountsTransactionsUncategorized = lazy(
|
||||||
);
|
|
||||||
|
|
||||||
const AccountsTransactionsUncategorized = React.lazy(
|
|
||||||
() => import('./AllTransactionsUncategorized'),
|
() => import('./AllTransactionsUncategorized'),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
// @ts-nocheck
|
// @ts-nocheck
|
||||||
|
import { Suspense } from 'react';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
import * as R from 'ramda';
|
import * as R from 'ramda';
|
||||||
|
import { Spinner } from '@blueprintjs/core';
|
||||||
import { CategorizeTransactionBoot } from './CategorizeTransactionBoot';
|
import { CategorizeTransactionBoot } from './CategorizeTransactionBoot';
|
||||||
import { CategorizeTransactionForm } from './CategorizeTransactionForm';
|
import { CategorizeTransactionForm } from './CategorizeTransactionForm';
|
||||||
import { withBanking } from '@/containers/CashFlow/withBanking';
|
import { withBanking } from '@/containers/CashFlow/withBanking';
|
||||||
@@ -13,7 +15,9 @@ function CategorizeTransactionContentRoot({
|
|||||||
uncategorizedTransactionsIds={transactionsToCategorizeIdsSelected}
|
uncategorizedTransactionsIds={transactionsToCategorizeIdsSelected}
|
||||||
>
|
>
|
||||||
<CategorizeTransactionDrawerBody>
|
<CategorizeTransactionDrawerBody>
|
||||||
<CategorizeTransactionForm />
|
<Suspense fallback={<Spinner size={40} />}>
|
||||||
|
<CategorizeTransactionForm />
|
||||||
|
</Suspense>
|
||||||
</CategorizeTransactionDrawerBody>
|
</CategorizeTransactionDrawerBody>
|
||||||
</CategorizeTransactionBoot>
|
</CategorizeTransactionBoot>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import React, { createContext } from 'react';
|
|||||||
import { defaultTo } from 'lodash';
|
import { defaultTo } from 'lodash';
|
||||||
import * as R from 'ramda';
|
import * as R from 'ramda';
|
||||||
import { useGetBankTransactionsMatches } from '@/hooks/query/bank-rules';
|
import { useGetBankTransactionsMatches } from '@/hooks/query/bank-rules';
|
||||||
|
import { Spinner } from '@blueprintjs/core';
|
||||||
|
|
||||||
interface MatchingTransactionBootValues {
|
interface MatchingTransactionBootValues {
|
||||||
isMatchingTransactionsLoading: boolean;
|
isMatchingTransactionsLoading: boolean;
|
||||||
@@ -52,6 +53,11 @@ function MatchingTransactionBoot({
|
|||||||
matches,
|
matches,
|
||||||
} as MatchingTransactionBootValues;
|
} as MatchingTransactionBootValues;
|
||||||
|
|
||||||
|
const isLoading = isMatchingTransactionsLoading;
|
||||||
|
|
||||||
|
if (isLoading) {
|
||||||
|
return <Spinner size={40} />;
|
||||||
|
}
|
||||||
return <RuleFormBootContext.Provider value={provider} {...props} />;
|
return <RuleFormBootContext.Provider value={provider} {...props} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
63
packages/webapp/src/hooks/useMediaQuery.ts
Normal file
63
packages/webapp/src/hooks/useMediaQuery.ts
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
import { useEffect, useRef, useState } from 'react';
|
||||||
|
|
||||||
|
export interface UseMediaQueryOptions {
|
||||||
|
getInitialValueInEffect: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
type MediaQueryCallback = (event: { matches: boolean; media: string }) => void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Older versions of Safari (shipped withCatalina and before) do not support addEventListener on matchMedia
|
||||||
|
* https://stackoverflow.com/questions/56466261/matchmedia-addlistener-marked-as-deprecated-addeventlistener-equivalent
|
||||||
|
* */
|
||||||
|
function attachMediaListener(
|
||||||
|
query: MediaQueryList,
|
||||||
|
callback: MediaQueryCallback,
|
||||||
|
) {
|
||||||
|
try {
|
||||||
|
query.addEventListener('change', callback);
|
||||||
|
return () => query.removeEventListener('change', callback);
|
||||||
|
} catch (e) {
|
||||||
|
query.addListener(callback);
|
||||||
|
return () => query.removeListener(callback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getInitialValue(query: string, initialValue?: boolean) {
|
||||||
|
if (typeof initialValue === 'boolean') {
|
||||||
|
return initialValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof window !== 'undefined' && 'matchMedia' in window) {
|
||||||
|
return window.matchMedia(query).matches;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useMediaQuery(
|
||||||
|
query: string,
|
||||||
|
initialValue?: boolean,
|
||||||
|
{ getInitialValueInEffect }: UseMediaQueryOptions = {
|
||||||
|
getInitialValueInEffect: true,
|
||||||
|
},
|
||||||
|
) {
|
||||||
|
const [matches, setMatches] = useState(
|
||||||
|
getInitialValueInEffect ? initialValue : getInitialValue(query),
|
||||||
|
);
|
||||||
|
const queryRef = useRef<MediaQueryList>();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if ('matchMedia' in window) {
|
||||||
|
queryRef.current = window.matchMedia(query);
|
||||||
|
setMatches(queryRef.current.matches);
|
||||||
|
return attachMediaListener(queryRef.current, (event) =>
|
||||||
|
setMatches(event.matches),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return undefined;
|
||||||
|
}, [query]);
|
||||||
|
|
||||||
|
return matches;
|
||||||
|
}
|
||||||
@@ -642,4 +642,10 @@ export default {
|
|||||||
],
|
],
|
||||||
viewBox: '0 0 16 16',
|
viewBox: '0 0 16 16',
|
||||||
},
|
},
|
||||||
|
share: {
|
||||||
|
path: [
|
||||||
|
'M10.99 13.99h-9v-9h4.76l2-2H.99c-.55 0-1 .45-1 1v11c0 .55.45 1 1 1h11c.55 0 1-.45 1-1V7.24l-2 2v4.75zm4-14h-5c-.55 0-1 .45-1 1s.45 1 1 1h2.59L7.29 7.28a1 1 0 00-.3.71 1.003 1.003 0 001.71.71l5.29-5.29V6c0 .55.45 1 1 1s1-.45 1-1V1c0-.56-.45-1.01-1-1.01z'
|
||||||
|
],
|
||||||
|
viewBox: '0 0 16 16',
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user