diff --git a/packages/server/src/constants/event-tracker.ts b/packages/server/src/constants/event-tracker.ts
index bb578fcfc..3fafc76a6 100644
--- a/packages/server/src/constants/event-tracker.ts
+++ b/packages/server/src/constants/event-tracker.ts
@@ -60,6 +60,16 @@ export const BANK_TRANSACTION_CATEGORIZED = 'Bank transaction categorized';
export const BANK_TRANSACTION_UNCATEGORIZED = 'Bank transaction uncategorized';
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 ITEM_GROUP = 'Item';
export const AUTH_GROUP = 'Auth';
@@ -67,21 +77,3 @@ export const SALE_GROUP = 'Sale';
export const PAYMENT_GROUP = 'Payment';
export const BILL_GROUP = 'Bill';
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';
-
diff --git a/packages/webapp/src/components/Dashboard/DashboardTopbar/DashboardTopbar.tsx b/packages/webapp/src/components/Dashboard/DashboardTopbar/DashboardTopbar.tsx
index 549785a87..02eee52ea 100644
--- a/packages/webapp/src/components/Dashboard/DashboardTopbar/DashboardTopbar.tsx
+++ b/packages/webapp/src/components/Dashboard/DashboardTopbar/DashboardTopbar.tsx
@@ -9,7 +9,12 @@ import {
Classes,
Tooltip,
Position,
+ MenuItem,
+ Menu,
+ MenuDivider,
} from '@blueprintjs/core';
+import { Popover2 } from '@blueprintjs/popover2';
+
import { FormattedMessage as T, Icon, Hint, If } from '@/components';
import DashboardTopbarUser from '@/components/Dashboard/TopbarUser';
@@ -19,9 +24,20 @@ import DashboardBackLink from '@/components/Dashboard/DashboardBackLink';
import withUniversalSearchActions from '@/containers/UniversalSearch/withUniversalSearchActions';
import withDashboardActions from '@/containers/Dashboard/withDashboardActions';
import withDashboard from '@/containers/Dashboard/withDashboard';
+import withDialogActions from '@/containers/Dialog/withDialogActions';
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';
/**
@@ -41,6 +57,9 @@ function DashboardTopbar({
// #withGlobalSearch
openGlobalSearch,
+
+ // #withDialogActions
+ openDialog,
}) {
const history = useHistory();
@@ -112,11 +131,34 @@ function DashboardTopbar({
/>
- }
- text={}
- />
+
+
@@ -138,4 +180,5 @@ export default compose(
pageHint,
})),
withDashboardActions,
+ withDialogActions,
)(DashboardTopbar);
diff --git a/packages/webapp/src/constants/routes.ts b/packages/webapp/src/constants/routes.ts
new file mode 100644
index 000000000..f39ecfca9
--- /dev/null
+++ b/packages/webapp/src/constants/routes.ts
@@ -0,0 +1,2 @@
+export const DOCS_BIGCAPITAL_LINK = 'https://docs.bigcapital.app';
+export const COMMUNITY_BIGCAPITAL_LINK = 'https://community.bigcapital.app';
\ No newline at end of file
diff --git a/packages/webapp/src/containers/CashFlow/AccountTransactions/AccountTransactionsActionsBar.tsx b/packages/webapp/src/containers/CashFlow/AccountTransactions/AccountTransactionsActionsBar.tsx
index d8d7df5d6..c4151505d 100644
--- a/packages/webapp/src/containers/CashFlow/AccountTransactions/AccountTransactionsActionsBar.tsx
+++ b/packages/webapp/src/containers/CashFlow/AccountTransactions/AccountTransactionsActionsBar.tsx
@@ -34,21 +34,23 @@ import {
} from '@/constants/cashflowOptions';
import { useRefreshCashflowTransactions } from '@/hooks/query';
import { useAccountTransactionsContext } from './AccountTransactionsProvider';
+import { useMediaQuery } from '@/hooks/useMediaQuery';
+import { useAppShellContext } from '@/components/AppShell/AppContentShell/AppContentShellProvider';
import withDialogActions from '@/containers/Dialog/withDialogActions';
import withSettings from '@/containers/Settings/withSettings';
import withSettingsActions from '@/containers/Settings/withSettingsActions';
-
-import { compose } from '@/utils';
+import { withBankingActions } from '../withBankingActions';
+import { withBanking } from '../withBanking';
+import withAlertActions from '@/containers/Alert/withAlertActions';
import {
useUpdateBankAccount,
useExcludeUncategorizedTransactions,
useUnexcludeUncategorizedTransactions,
} 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 { compose } from '@/utils';
function AccountTransactionsActionsBar({
// #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 (
@@ -241,23 +250,27 @@ function AccountTransactionsActionsBar({
}}
/>
- }
- text={}
- />
- }
- text={}
- />
- }
- text={}
- onClick={handleImportBtnClick}
- />
-
+
+
+ }
+ text={}
+ />
+ }
+ text={}
+ />
+ }
+ text={}
+ onClick={handleImportBtnClick}
+ />
+
+
+
+
+
+
+ }
+ text={}
+ />
+ }
+ text={}
+ />
+ }
+ text={}
+ onClick={handleImportBtnClick}
+ />
+
+ }
+ >
+ }
+ minimal={true}
+ />
+
+
+
{!isEmpty(uncategorizedTransationsIdsSelected) && (
}
@@ -368,7 +415,6 @@ function AccountTransactionsActionsBar({
-
+ import('../CategorizeTransactionAside/CategorizeTransactionAside').then(
+ (module) => ({ default: module.CategorizeTransactionAside }),
+ ),
+);
+
+export function AccountTransactionsAside() {
+ return (
+
+ }>
+
+
+
+ );
+}
diff --git a/packages/webapp/src/containers/CashFlow/AccountTransactions/AccountTransactionsDetailsBar.tsx b/packages/webapp/src/containers/CashFlow/AccountTransactions/AccountTransactionsDetailsBar.tsx
index 90e10eae0..253ea3d7d 100644
--- a/packages/webapp/src/containers/CashFlow/AccountTransactions/AccountTransactionsDetailsBar.tsx
+++ b/packages/webapp/src/containers/CashFlow/AccountTransactions/AccountTransactionsDetailsBar.tsx
@@ -2,6 +2,8 @@
import React from 'react';
import intl from 'react-intl-universal';
import styled from 'styled-components';
+import { curry } from 'lodash/fp';
+import { useHistory } from 'react-router-dom';
import {
Popover,
Menu,
@@ -11,10 +13,9 @@ import {
Classes,
} from '@blueprintjs/core';
import { Icon } from '@/components';
-import { useHistory } from 'react-router-dom';
-import { curry } from 'lodash/fp';
import { useAccountTransactionsContext } from './AccountTransactionsProvider';
+import { useAppShellContext } from '@/components/AppShell/AppContentShell/AppContentShellProvider';
function AccountSwitchButton() {
const { currentAccount } = useAccountTransactionsContext();
@@ -22,7 +23,7 @@ function AccountSwitchButton() {
return (
}
+ rightIcon={}
>
{currentAccount.name}
@@ -110,12 +111,16 @@ function AccountTransactionsDetailsBarSkeleton() {
}
function AccountTransactionsDetailsContent() {
+ const { hideAside } = useAppShellContext();
+
return (
-
+
+ {/** Hide some details once the aside opens to preserve space on details bar. */}
+ {hideAside && }
-
+ {hideAside && }
);
}
diff --git a/packages/webapp/src/containers/CashFlow/AccountTransactions/AccountTransactionsList.tsx b/packages/webapp/src/containers/CashFlow/AccountTransactions/AccountTransactionsList.tsx
index 93f534093..6067860d9 100644
--- a/packages/webapp/src/containers/CashFlow/AccountTransactions/AccountTransactionsList.tsx
+++ b/packages/webapp/src/containers/CashFlow/AccountTransactions/AccountTransactionsList.tsx
@@ -1,7 +1,7 @@
// @ts-nocheck
-import React, { Suspense } from 'react';
import * as R from 'ramda';
import { Spinner } from '@blueprintjs/core';
+import { Suspense, lazy } from 'react';
import '@/style/pages/CashFlow/AccountTransactions/List.scss';
@@ -15,7 +15,7 @@ import {
import { AccountTransactionsDetailsBar } from './AccountTransactionsDetailsBar';
import { AccountTransactionsFilterTabs } from './AccountTransactionsFilterTabs';
import { AppContentShell } from '@/components/AppShell';
-import { CategorizeTransactionAside } from '../CategorizeTransactionAside/CategorizeTransactionAside';
+import { AccountTransactionsAside } from './AccountTransactionsAside';
import { AccountTransactionsLoadingBar } from './components';
import { withBanking } from '../withBanking';
@@ -56,14 +56,6 @@ function AccountTransactionsMain() {
);
}
-function AccountTransactionsAside() {
- return (
-
-
-
- );
-}
-
export default R.compose(
withBanking(
({ selectedUncategorizedTransactionId, openMatchingTransactionAside }) => ({
@@ -73,11 +65,8 @@ export default R.compose(
),
)(AccountTransactionsListRoot);
-const AccountsTransactionsAll = React.lazy(
- () => import('./AccountsTransactionsAll'),
-);
-
-const AccountsTransactionsUncategorized = React.lazy(
+const AccountsTransactionsAll = lazy(() => import('./AccountsTransactionsAll'));
+const AccountsTransactionsUncategorized = lazy(
() => import('./AllTransactionsUncategorized'),
);
diff --git a/packages/webapp/src/containers/CashFlow/CategorizeTransaction/drawers/CategorizeTransactionDrawer/CategorizeTransactionContent.tsx b/packages/webapp/src/containers/CashFlow/CategorizeTransaction/drawers/CategorizeTransactionDrawer/CategorizeTransactionContent.tsx
index 89513c6b8..4f7b2601f 100644
--- a/packages/webapp/src/containers/CashFlow/CategorizeTransaction/drawers/CategorizeTransactionDrawer/CategorizeTransactionContent.tsx
+++ b/packages/webapp/src/containers/CashFlow/CategorizeTransaction/drawers/CategorizeTransactionDrawer/CategorizeTransactionContent.tsx
@@ -1,6 +1,8 @@
// @ts-nocheck
+import { Suspense } from 'react';
import styled from 'styled-components';
import * as R from 'ramda';
+import { Spinner } from '@blueprintjs/core';
import { CategorizeTransactionBoot } from './CategorizeTransactionBoot';
import { CategorizeTransactionForm } from './CategorizeTransactionForm';
import { withBanking } from '@/containers/CashFlow/withBanking';
@@ -13,7 +15,9 @@ function CategorizeTransactionContentRoot({
uncategorizedTransactionsIds={transactionsToCategorizeIdsSelected}
>
-
+ }>
+
+
);
diff --git a/packages/webapp/src/containers/CashFlow/CategorizeTransactionAside/MatchingTransactionBoot.tsx b/packages/webapp/src/containers/CashFlow/CategorizeTransactionAside/MatchingTransactionBoot.tsx
index e6a531c93..6699ce630 100644
--- a/packages/webapp/src/containers/CashFlow/CategorizeTransactionAside/MatchingTransactionBoot.tsx
+++ b/packages/webapp/src/containers/CashFlow/CategorizeTransactionAside/MatchingTransactionBoot.tsx
@@ -2,6 +2,7 @@ import React, { createContext } from 'react';
import { defaultTo } from 'lodash';
import * as R from 'ramda';
import { useGetBankTransactionsMatches } from '@/hooks/query/bank-rules';
+import { Spinner } from '@blueprintjs/core';
interface MatchingTransactionBootValues {
isMatchingTransactionsLoading: boolean;
@@ -52,6 +53,11 @@ function MatchingTransactionBoot({
matches,
} as MatchingTransactionBootValues;
+ const isLoading = isMatchingTransactionsLoading;
+
+ if (isLoading) {
+ return ;
+ }
return ;
}
diff --git a/packages/webapp/src/hooks/useMediaQuery.ts b/packages/webapp/src/hooks/useMediaQuery.ts
new file mode 100644
index 000000000..9663f3b3f
--- /dev/null
+++ b/packages/webapp/src/hooks/useMediaQuery.ts
@@ -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();
+
+ 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;
+}
diff --git a/packages/webapp/src/static/json/icons.tsx b/packages/webapp/src/static/json/icons.tsx
index 4149a8c70..ca889ecd8 100644
--- a/packages/webapp/src/static/json/icons.tsx
+++ b/packages/webapp/src/static/json/icons.tsx
@@ -642,4 +642,10 @@ export default {
],
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',
+ }
};