diff --git a/packages/desktop-client/package.tgz b/packages/desktop-client/package.tgz
new file mode 100644
index 0000000000000000000000000000000000000000..3efd4222666456b4cfd5ca87e6b977b578176aca
Binary files /dev/null and b/packages/desktop-client/package.tgz differ
diff --git a/packages/desktop-client/src/components/common/Link.tsx b/packages/desktop-client/src/components/common/Link.tsx
index ebe1f355210b4658f25079c0791503cff68a4219..fe92ea84470b4df835e5794b4d39f1d5d7ffd9f5 100644
--- a/packages/desktop-client/src/components/common/Link.tsx
+++ b/packages/desktop-client/src/components/common/Link.tsx
@@ -95,13 +95,15 @@ const ButtonLink = ({ to, style, activeStyle, ...props }: ButtonLinkProps) => {
   const match = useMatch({ path });
   return (
     <Button
-      className={String(
-        css({
-          ...style,
-          '&[data-pressed]': activeStyle,
-          ...(match ? activeStyle : {}),
-        }),
-      )}
+      className={() =>
+        String(
+          css({
+            ...style,
+            '&[data-pressed]': activeStyle,
+            ...(match ? activeStyle : {}),
+          }),
+        )
+      }
       {...props}
       variant={props.buttonVariant}
       onPress={e => {
diff --git a/packages/desktop-client/src/components/mobile/accounts/Account.jsx b/packages/desktop-client/src/components/mobile/accounts/Account.jsx
deleted file mode 100644
index 244ceb99b999c1a98daba6453bec3e98aab22d59..0000000000000000000000000000000000000000
--- a/packages/desktop-client/src/components/mobile/accounts/Account.jsx
+++ /dev/null
@@ -1,68 +0,0 @@
-import React from 'react';
-import { useSelector } from 'react-redux';
-import { useParams } from 'react-router-dom';
-
-import { useAccount } from '../../../hooks/useAccount';
-import { useFailedAccounts } from '../../../hooks/useFailedAccounts';
-import { useNavigate } from '../../../hooks/useNavigate';
-import { useSetThemeColor } from '../../../hooks/useSetThemeColor';
-import { useSyncedPref } from '../../../hooks/useSyncedPref';
-import { theme, styles } from '../../../style';
-import { Button } from '../../common/Button2';
-import { Text } from '../../common/Text';
-import { View } from '../../common/View';
-
-import { AccountTransactions } from './AccountTransactions';
-
-export function Account() {
-  const failedAccounts = useFailedAccounts();
-  const syncingAccountIds = useSelector(state => state.account.accountsSyncing);
-
-  const navigate = useNavigate();
-
-  const [_numberFormat] = useSyncedPref('numberFormat');
-  const numberFormat = _numberFormat || 'comma-dot';
-  const [hideFraction] = useSyncedPref('hideFraction');
-
-  const { id: accountId } = useParams();
-
-  useSetThemeColor(theme.mobileViewTheme);
-
-  const account = useAccount(accountId);
-
-  if (!account) {
-    return null;
-  }
-
-  if (
-    accountId === 'budgeted' ||
-    accountId === 'offbudget' ||
-    accountId === 'uncategorized'
-  ) {
-    return (
-      <View style={{ flex: 1, padding: 30 }}>
-        <Text style={(styles.text, { textAlign: 'center' })}>
-          There is no Mobile View at the moment
-        </Text>
-        <Button
-          variant="normal"
-          style={{ fontSize: 15, marginLeft: 10, marginTop: 10 }}
-          onPress={() => navigate('/accounts')}
-        >
-          Go back to Mobile Accounts
-        </Button>
-      </View>
-    );
-  }
-
-  return (
-    <AccountTransactions
-      // This key forces the whole table rerender when the number
-      // format changes
-      key={numberFormat + hideFraction}
-      account={account}
-      pending={syncingAccountIds.includes(account.id)}
-      failed={failedAccounts && failedAccounts.has(account.id)}
-    />
-  );
-}
diff --git a/packages/desktop-client/src/components/mobile/accounts/Account.tsx b/packages/desktop-client/src/components/mobile/accounts/Account.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..47c2beb9505e82c57767a7ee655748cc05a5d0a5
--- /dev/null
+++ b/packages/desktop-client/src/components/mobile/accounts/Account.tsx
@@ -0,0 +1,45 @@
+import React from 'react';
+import { useParams } from 'react-router-dom';
+
+import { useAccount } from '../../../hooks/useAccount';
+import { useSetThemeColor } from '../../../hooks/useSetThemeColor';
+import { useSyncedPref } from '../../../hooks/useSyncedPref';
+import { theme } from '../../../style';
+
+import { AccountTransactions } from './AccountTransactions';
+
+export function Account() {
+  const [_numberFormat] = useSyncedPref('numberFormat');
+  const numberFormat = _numberFormat || 'comma-dot';
+  const [hideFraction] = useSyncedPref('hideFraction');
+
+  const { id: accountId } = useParams();
+
+  useSetThemeColor(theme.mobileViewTheme);
+
+  const account = useAccount(accountId!);
+
+  return (
+    <AccountTransactions
+      // This key forces the whole table rerender when the number
+      // format changes
+      key={numberFormat + hideFraction}
+      account={account}
+      accountId={accountId}
+      accountName={account ? account.name : accountNameFromId(accountId)}
+    />
+  );
+}
+
+function accountNameFromId(id: string | undefined) {
+  switch (id) {
+    case 'budgeted':
+      return 'Budgeted Accounts';
+    case 'offbudget':
+      return 'Off Budget Accounts';
+    case 'uncategorized':
+      return 'Uncategorized';
+    default:
+      return 'All Accounts';
+  }
+}
diff --git a/packages/desktop-client/src/components/mobile/accounts/AccountTransactions.jsx b/packages/desktop-client/src/components/mobile/accounts/AccountTransactions.tsx
similarity index 63%
rename from packages/desktop-client/src/components/mobile/accounts/AccountTransactions.jsx
rename to packages/desktop-client/src/components/mobile/accounts/AccountTransactions.tsx
index 594025e357716082d3ce2b2d746825b840e91bce..eaf49332fb9239cb4625e8f2510628570d35d696 100644
--- a/packages/desktop-client/src/components/mobile/accounts/AccountTransactions.jsx
+++ b/packages/desktop-client/src/components/mobile/accounts/AccountTransactions.tsx
@@ -1,11 +1,12 @@
 import React, {
+  type CSSProperties,
   useCallback,
   useEffect,
   useMemo,
   useRef,
   useState,
 } from 'react';
-import { useDispatch } from 'react-redux';
+import { useDispatch, useSelector } from 'react-redux';
 
 import { useDebounceCallback } from 'usehooks-ts';
 
@@ -24,11 +25,17 @@ import {
   useDefaultSchedulesQueryTransform,
 } from 'loot-core/client/data-hooks/schedules';
 import * as queries from 'loot-core/client/queries';
-import { pagedQuery } from 'loot-core/client/query-helpers';
+import { type PagedQuery, pagedQuery } from 'loot-core/client/query-helpers';
 import { listen, send } from 'loot-core/platform/client/fetch';
+import { type Query } from 'loot-core/shared/query';
 import { isPreviewId } from 'loot-core/shared/transactions';
+import {
+  type AccountEntity,
+  type TransactionEntity,
+} from 'loot-core/types/models';
 
 import { useDateFormat } from '../../../hooks/useDateFormat';
+import { useFailedAccounts } from '../../../hooks/useFailedAccounts';
 import { useNavigate } from '../../../hooks/useNavigate';
 import { usePreviewTransactions } from '../../../hooks/usePreviewTransactions';
 import { styles, theme } from '../../../style';
@@ -40,40 +47,67 @@ import { MobileBackButton } from '../MobileBackButton';
 import { AddTransactionButton } from '../transactions/AddTransactionButton';
 import { TransactionListWithBalances } from '../transactions/TransactionListWithBalances';
 
-export function AccountTransactions({ account, pending, failed }) {
-  const schedulesTransform = useDefaultSchedulesQueryTransform(account.id);
+export function AccountTransactions({
+  account,
+  accountId,
+  accountName,
+}: {
+  readonly account?: AccountEntity;
+  readonly accountId?: string;
+  readonly accountName: string;
+}) {
+  const schedulesTransform = useDefaultSchedulesQueryTransform(accountId);
   return (
     <Page
       header={
         <MobilePageHeader
           title={
-            <AccountName account={account} pending={pending} failed={failed} />
+            account ? (
+              <AccountHeader account={account} />
+            ) : (
+              <NameOnlyHeader accountName={accountName} />
+            )
           }
           leftContent={<MobileBackButton />}
-          rightContent={<AddTransactionButton accountId={account.id} />}
+          rightContent={<AddTransactionButton accountId={accountId} />}
         />
       }
       padding={0}
     >
       <SchedulesProvider transform={schedulesTransform}>
-        <TransactionListWithPreviews account={account} />
+        <TransactionListWithPreviews
+          account={account}
+          accountName={accountName}
+          accountId={accountId}
+        />
       </SchedulesProvider>
     </Page>
   );
 }
 
-function AccountName({ account, pending, failed }) {
+function AccountHeader({ account }: { readonly account: AccountEntity }) {
+  const failedAccounts = useFailedAccounts();
+  const syncingAccountIds = useSelector(state => state.account.accountsSyncing);
+  const pending = useMemo(
+    () => syncingAccountIds.includes(account.id),
+    [syncingAccountIds, account.id],
+  );
+  const failed = useMemo(
+    () => failedAccounts.has(account.id),
+    [failedAccounts, account.id],
+  );
+
   const dispatch = useDispatch();
 
-  const onSave = account => {
+  const onSave = (account: AccountEntity) => {
     dispatch(updateAccount(account));
   };
 
-  const onSaveNotes = async (id, notes) => {
+  const onSaveNotes = async (id: string, notes: string) => {
     await send('notes-save', { id, note: notes });
   };
 
-  const onEditNotes = id => {
+  const onEditNotes = (id: string) => {
     dispatch(
       pushModal('notes', {
         id: `account-${id}`,
@@ -108,7 +142,7 @@ function AccountName({ account, pending, failed }) {
         flexDirection: 'row',
       }}
     >
-      {account.bankId && (
+      {account.bank && (
         <div
           style={{
             margin: 'auto',
@@ -132,7 +166,7 @@ function AccountName({ account, pending, failed }) {
             fontSize: 17,
             fontWeight: 500,
             ...styles.underlinedText,
-            ...styles.lineClamp(2),
+            ...(styles.lineClamp(2) as CSSProperties),
           }}
         >
           {`${account.closed ? 'Closed: ' : ''}${account.name}`}
@@ -142,11 +176,35 @@ function AccountName({ account, pending, failed }) {
   );
 }
 
-function TransactionListWithPreviews({ account }) {
-  const [currentQuery, setCurrentQuery] = useState();
+function NameOnlyHeader({ accountName }: { readonly accountName: string }) {
+  return (
+    <View
+      style={{
+        flexDirection: 'row',
+      }}
+    >
+      <Text style={{ ...(styles.lineClamp(2) as CSSProperties) }}>
+        {accountName}
+      </Text>
+    </View>
+  );
+}
+
+function TransactionListWithPreviews({
+  account,
+  accountId,
+  accountName,
+}: {
+  readonly account?: AccountEntity;
+  readonly accountId?: string;
+  readonly accountName: string;
+}) {
+  const [currentQuery, setCurrentQuery] = useState<Query>();
   const [isSearching, setIsSearching] = useState(false);
   const [isLoading, setIsLoading] = useState(true);
-  const [transactions, setTransactions] = useState([]);
+  const [transactions, setTransactions] = useState<
+    ReadonlyArray<TransactionEntity>
+  >([]);
   const prependTransactions = usePreviewTransactions();
   const allTransactions = useMemo(
     () =>
@@ -158,23 +216,23 @@ function TransactionListWithPreviews({ account }) {
   const dispatch = useDispatch();
   const navigate = useNavigate();
 
-  const onRefresh = async () => {
-    await dispatch(syncAndDownload(account.id));
+  const onRefresh = () => {
+    dispatch(syncAndDownload(accountId));
   };
 
   const makeRootQuery = useCallback(
-    () => queries.makeTransactionsQuery(account.id).options({ splits: 'none' }),
-    [account.id],
+    () => queries.makeTransactionsQuery(accountId).options({ splits: 'none' }),
+    [accountId],
   );
 
-  const paged = useRef(null);
+  const paged = useRef<PagedQuery>();
 
-  const updateQuery = useCallback(query => {
+  const updateQuery = useCallback((query: Query) => {
     paged.current?.unsubscribe();
     setIsLoading(true);
     paged.current = pagedQuery(
       query.options({ splits: 'none' }).select('*'),
-      data => {
+      (data: ReadonlyArray<TransactionEntity>) => {
         setTransactions(data);
         setIsLoading(false);
       },
@@ -210,9 +268,9 @@ function TransactionListWithPreviews({ account }) {
     });
 
     fetchTransactions();
-    dispatch(markAccountRead(account.id));
+    dispatch(markAccountRead(accountId));
     return () => unlisten();
-  }, [account.id, dispatch, fetchTransactions]);
+  }, [accountId, dispatch, fetchTransactions]);
 
   const updateSearchQuery = useDebounceCallback(
     useCallback(
@@ -236,11 +294,11 @@ function TransactionListWithPreviews({ account }) {
     150,
   );
 
-  const onSearch = text => {
+  const onSearch = (text: string) => {
     updateSearchQuery(text);
   };
 
-  const onOpenTransaction = transaction => {
+  const onOpenTransaction = (transaction: TransactionEntity) => {
     if (!isPreviewId(transaction.id)) {
       navigate(`/transactions/${transaction.id}`);
     } else {
@@ -266,22 +324,51 @@ function TransactionListWithPreviews({ account }) {
     paged.current?.fetchNext();
   };
 
-  const balance = queries.accountBalance(account);
-  const balanceCleared = queries.accountBalanceCleared(account);
-  const balanceUncleared = queries.accountBalanceUncleared(account);
+  const balanceQueries = useMemo(
+    () => queriesFromAccountId(accountId, account),
+    [accountId, account],
+  );
 
   return (
     <TransactionListWithBalances
       isLoading={isLoading}
       transactions={allTransactions}
-      balance={balance}
-      balanceCleared={balanceCleared}
-      balanceUncleared={balanceUncleared}
+      balance={balanceQueries.balance}
+      balanceCleared={balanceQueries.cleared}
+      balanceUncleared={balanceQueries.uncleared}
       onLoadMore={onLoadMore}
-      searchPlaceholder={`Search ${account.name}`}
+      searchPlaceholder={`Search ${accountName}`}
       onSearch={onSearch}
       onOpenTransaction={onOpenTransaction}
       onRefresh={onRefresh}
     />
   );
 }
+
+function queriesFromAccountId(
+  id: string | undefined,
+  entity: AccountEntity | undefined,
+) {
+  switch (id) {
+    case 'budgeted':
+      return {
+        balance: queries.budgetedAccountBalance(),
+      };
+    case 'offbudget':
+      return {
+        balance: queries.offbudgetAccountBalance(),
+      };
+    case 'uncategorized':
+      return {
+        balance: queries.uncategorizedBalance(),
+      };
+    default:
+      return entity
+        ? {
+            balance: queries.accountBalance(entity),
+            cleared: queries.accountBalanceCleared(entity),
+            uncleared: queries.accountBalanceUncleared(entity),
+          }
+        : { balance: queries.allAccountBalance() };
+  }
+}
diff --git a/packages/desktop-client/src/components/mobile/budget/BudgetTable.jsx b/packages/desktop-client/src/components/mobile/budget/BudgetTable.jsx
index d9b6a2da6c9c2ceea5b9a79ec8b06e1e6959370a..abd5438d356910d9c09d68c5be51bd192b0d4663 100644
--- a/packages/desktop-client/src/components/mobile/budget/BudgetTable.jsx
+++ b/packages/desktop-client/src/components/mobile/budget/BudgetTable.jsx
@@ -7,7 +7,11 @@ import memoizeOne from 'memoize-one';
 
 import { collapseModals, pushModal } from 'loot-core/client/actions';
 import { groupById, integerToCurrency } from 'loot-core/shared/util';
-import { envelopeBudget, trackingBudget } from 'loot-core/src/client/queries';
+import {
+  envelopeBudget,
+  trackingBudget,
+  uncategorizedCount,
+} from 'loot-core/src/client/queries';
 import * as monthUtils from 'loot-core/src/shared/months';
 
 import { useCategories } from '../../../hooks/useCategories';
@@ -33,6 +37,7 @@ import { makeAmountGrey, makeBalanceAmountStyle } from '../../budget/util';
 import { Button } from '../../common/Button2';
 import { Card } from '../../common/Card';
 import { Label } from '../../common/Label';
+import { Link } from '../../common/Link';
 import { Text } from '../../common/Text';
 import { View } from '../../common/View';
 import { MobilePageHeader, Page } from '../../Page';
@@ -1454,6 +1459,38 @@ function IncomeGroup({
   );
 }
 
+function UncategorizedButton() {
+  const count = useSheetValue(uncategorizedCount());
+  if (count === null || count <= 0) {
+    return null;
+  }
+
+  return (
+    <View
+      style={{
+        padding: 5,
+        paddingBottom: 2,
+      }}
+    >
+      <Link
+        variant="button"
+        type="button"
+        buttonVariant="primary"
+        to="/accounts/uncategorized"
+        style={{
+          border: 0,
+          justifyContent: 'flex-start',
+          padding: '1.25em',
+        }}
+      >
+        {count} uncategorized {count === 1 ? 'transaction' : 'transactions'}
+        <View style={{ flex: 1 }} />
+        <SvgArrowThinRight width="15" height="15" />
+      </Link>
+    </View>
+  );
+}
+
 function BudgetGroups({
   type,
   categoryGroups,
@@ -1636,6 +1673,7 @@ export function BudgetTable({
             paddingBottom: MOBILE_NAV_HEIGHT,
           }}
         >
+          <UncategorizedButton />
           <BudgetGroups
             type={type}
             categoryGroups={categoryGroups}
diff --git a/packages/desktop-client/src/components/mobile/transactions/AddTransactionButton.tsx b/packages/desktop-client/src/components/mobile/transactions/AddTransactionButton.tsx
index edaefb73e14d104b2eaffa5211be3dce185ba7f1..7b1ca2a9498499ecdc68eaefdc485a69f8905bcf 100644
--- a/packages/desktop-client/src/components/mobile/transactions/AddTransactionButton.tsx
+++ b/packages/desktop-client/src/components/mobile/transactions/AddTransactionButton.tsx
@@ -5,7 +5,7 @@ import { SvgAdd } from '../../../icons/v1';
 import { Button } from '../../common/Button2';
 
 type AddTransactionButtonProps = {
-  to: string;
+  to?: string;
   accountId?: string;
   categoryId?: string;
 };
diff --git a/packages/desktop-client/src/components/mobile/transactions/TransactionListWithBalances.jsx b/packages/desktop-client/src/components/mobile/transactions/TransactionListWithBalances.jsx
index 124ebcf0bf31989c7469036639f04f1e9f5d0abb..4a03b2c8fede379e5197b3994bdcf73226e2a6d6 100644
--- a/packages/desktop-client/src/components/mobile/transactions/TransactionListWithBalances.jsx
+++ b/packages/desktop-client/src/components/mobile/transactions/TransactionListWithBalances.jsx
@@ -74,7 +74,6 @@ export function TransactionListWithBalances({
     return newTransactions.includes(id);
   };
 
-  const unclearedAmount = useSheetValue(balanceUncleared);
   const selectedInst = useSelected('transactions', transactions);
 
   return (
@@ -91,73 +90,15 @@ export function TransactionListWithBalances({
             justifyContent: 'space-evenly',
           }}
         >
-          <View
-            style={{
-              display: !unclearedAmount ? 'none' : undefined,
-              flexBasis: '33%',
-            }}
-          >
-            <Label
-              title="Cleared"
-              style={{ textAlign: 'center', fontSize: 12 }}
+          {balanceCleared && balanceUncleared ? (
+            <BalanceWithCleared
+              balance={balance}
+              balanceCleared={balanceCleared}
+              balanceUncleared={balanceUncleared}
             />
-            <CellValue binding={balanceCleared} type="financial">
-              {props => (
-                <CellValueText
-                  {...props}
-                  style={{
-                    fontSize: 12,
-                    textAlign: 'center',
-                    fontWeight: '500',
-                  }}
-                />
-              )}
-            </CellValue>
-          </View>
-          <View style={{ flexBasis: '33%' }}>
-            <Label title="Balance" style={{ textAlign: 'center' }} />
-            <CellValue binding={balance} type="financial">
-              {props => (
-                <CellValueText
-                  {...props}
-                  style={{
-                    fontSize: 18,
-                    textAlign: 'center',
-                    fontWeight: '500',
-                    color:
-                      props.value < 0
-                        ? theme.errorText
-                        : theme.pillTextHighlighted,
-                  }}
-                  data-testid="transactions-balance"
-                />
-              )}
-            </CellValue>
-          </View>
-          <View
-            style={{
-              display: !unclearedAmount ? 'none' : undefined,
-              flexBasis: '33%',
-            }}
-          >
-            <Label
-              title="Uncleared"
-              style={{ textAlign: 'center', fontSize: 12 }}
-            />
-            <CellValue binding={balanceUncleared} type="financial">
-              {props => (
-                <CellValueText
-                  {...props}
-                  style={{
-                    fontSize: 12,
-                    textAlign: 'center',
-                    fontWeight: '500',
-                  }}
-                  data-testid="transactions-balance-uncleared"
-                />
-              )}
-            </CellValue>
-          </View>
+          ) : (
+            <Balance balance={balance} />
+          )}
         </View>
         <TransactionSearchInput
           placeholder={searchPlaceholder}
@@ -176,3 +117,81 @@ export function TransactionListWithBalances({
     </SelectedProvider>
   );
 }
+
+function BalanceWithCleared({ balanceUncleared, balanceCleared, balance }) {
+  const unclearedAmount = useSheetValue(balanceUncleared);
+
+  return (
+    <>
+      <View
+        style={{
+          display: !unclearedAmount ? 'none' : undefined,
+          flexBasis: '33%',
+        }}
+      >
+        <Label title="Cleared" style={{ textAlign: 'center', fontSize: 12 }} />
+        <CellValue binding={balanceCleared} type="financial">
+          {props => (
+            <CellValueText
+              {...props}
+              style={{
+                fontSize: 12,
+                textAlign: 'center',
+                fontWeight: '500',
+              }}
+              data-testid="transactions-balance-cleared"
+            />
+          )}
+        </CellValue>
+      </View>
+      <Balance balance={balance} />
+      <View
+        style={{
+          display: !unclearedAmount ? 'none' : undefined,
+          flexBasis: '33%',
+        }}
+      >
+        <Label
+          title="Uncleared"
+          style={{ textAlign: 'center', fontSize: 12 }}
+        />
+        <CellValue binding={balanceUncleared} type="financial">
+          {props => (
+            <CellValueText
+              {...props}
+              style={{
+                fontSize: 12,
+                textAlign: 'center',
+                fontWeight: '500',
+              }}
+              data-testid="transactions-balance-uncleared"
+            />
+          )}
+        </CellValue>
+      </View>
+    </>
+  );
+}
+
+function Balance({ balance }) {
+  return (
+    <View style={{ flexBasis: '33%' }}>
+      <Label title="Balance" style={{ textAlign: 'center' }} />
+      <CellValue binding={balance} type="financial">
+        {props => (
+          <CellValueText
+            {...props}
+            style={{
+              fontSize: 18,
+              textAlign: 'center',
+              fontWeight: '500',
+              color:
+                props.value < 0 ? theme.errorText : theme.pillTextHighlighted,
+            }}
+            data-testid="transactions-balance"
+          />
+        )}
+      </CellValue>
+    </View>
+  );
+}
diff --git a/packages/desktop-client/src/hooks/usePreviewTransactions.ts b/packages/desktop-client/src/hooks/usePreviewTransactions.ts
index 786e369c311eccc4dc19854208410a89adff3cd4..3278237e45af97cabc018b21555e9ff74ea28c34 100644
--- a/packages/desktop-client/src/hooks/usePreviewTransactions.ts
+++ b/packages/desktop-client/src/hooks/usePreviewTransactions.ts
@@ -11,7 +11,7 @@ import { type ScheduleEntity } from 'loot-core/types/models';
 import { type TransactionEntity } from '../../../loot-core/src/types/models/transaction.d';
 
 export function usePreviewTransactions(
-  collapseTransactions: (ids: string[]) => void,
+  collapseTransactions?: (ids: string[]) => void,
 ) {
   const scheduleData = useCachedSchedules();
   const [previousScheduleData, setPreviousScheduleData] =
@@ -53,7 +53,9 @@ export function usePreviewTransactions(
           })),
         }));
         setPreviewTransactions(ungroupTransactions(withDefaults));
-        collapseTransactions(withDefaults.map(t => t.id));
+        if (collapseTransactions) {
+          collapseTransactions(withDefaults.map(t => t.id));
+        }
       });
     }
 
diff --git a/packages/loot-core/src/client/query-helpers.ts b/packages/loot-core/src/client/query-helpers.ts
index 92f058b9f5e79956987e801e5a4787423d735af8..8a130d80e0e3e822fa8b5a5b8cbe1be8011062df 100644
--- a/packages/loot-core/src/client/query-helpers.ts
+++ b/packages/loot-core/src/client/query-helpers.ts
@@ -184,7 +184,7 @@ export class LiveQuery<Response = unknown> {
 }
 
 // Paging
-class PagedQuery extends LiveQuery {
+export class PagedQuery extends LiveQuery {
   done;
   onPageData;
   pageCount;
diff --git a/upcoming-release-notes/3326.md b/upcoming-release-notes/3326.md
new file mode 100644
index 0000000000000000000000000000000000000000..196c56cf2bc308681ee91f8ea6e4a7d56e2cbe23
--- /dev/null
+++ b/upcoming-release-notes/3326.md
@@ -0,0 +1,6 @@
+---
+category: Features
+authors: [tim-smart]
+---
+
+Add an uncategorized transaction button to the mobile app.