From 65c5f2c55963d395ce73e252b1db83a3c6fb46ac Mon Sep 17 00:00:00 2001
From: Robert Dyer <rdyer@unl.edu>
Date: Thu, 8 Aug 2024 15:16:19 -0500
Subject: [PATCH] Filter by account when linking schedules (#3188)

* Add "S" hotkey for viewing/linking schedules.

* Default to filtering by account name when linking a schedule to a transaction.

* Work on 'all accounts' page.

* Update help modal

* add release note
---
 .../desktop-client/src/components/Modals.tsx  |  1 +
 .../src/components/accounts/Header.jsx        |  1 +
 .../modals/KeyboardShortcutModal.tsx          | 66 ++++++++++---------
 .../src/components/schedules/ScheduleLink.tsx |  4 +-
 .../SelectedTransactionsButton.jsx            | 60 +++++++++++------
 upcoming-release-notes/3188.md                |  6 ++
 6 files changed, 86 insertions(+), 52 deletions(-)
 create mode 100644 upcoming-release-notes/3188.md

diff --git a/packages/desktop-client/src/components/Modals.tsx b/packages/desktop-client/src/components/Modals.tsx
index 07711a2d2..a594d445f 100644
--- a/packages/desktop-client/src/components/Modals.tsx
+++ b/packages/desktop-client/src/components/Modals.tsx
@@ -341,6 +341,7 @@ export function Modals() {
               key={name}
               transactionIds={options?.transactionIds}
               getTransaction={options?.getTransaction}
+              accountName={options?.accountName}
             />
           );
 
diff --git a/packages/desktop-client/src/components/accounts/Header.jsx b/packages/desktop-client/src/components/accounts/Header.jsx
index 997f36298..84f74aad9 100644
--- a/packages/desktop-client/src/components/accounts/Header.jsx
+++ b/packages/desktop-client/src/components/accounts/Header.jsx
@@ -337,6 +337,7 @@ export function AccountHeader({
             </View>
           ) : (
             <SelectedTransactionsButton
+              account={account}
               getTransaction={id => transactions.find(t => t.id === id)}
               onShow={onShowTransactions}
               onDuplicate={onBatchDuplicate}
diff --git a/packages/desktop-client/src/components/modals/KeyboardShortcutModal.tsx b/packages/desktop-client/src/components/modals/KeyboardShortcutModal.tsx
index 0860c39ad..1d606abe4 100644
--- a/packages/desktop-client/src/components/modals/KeyboardShortcutModal.tsx
+++ b/packages/desktop-client/src/components/modals/KeyboardShortcutModal.tsx
@@ -206,31 +206,38 @@ export function KeyboardShortcutModal() {
                     meta={ctrl}
                   />
                   <Shortcut shortcut="B" description="Bank sync" meta={ctrl} />
-                  <GroupHeading group="Select a transaction, then" />
+                  <GroupHeading group="With transaction(s) selected" />
                   <Shortcut
-                    shortcut="J"
-                    description="Move to the next transaction down"
+                    shortcut="F"
+                    description="Filter to the selected transactions"
                   />
                   <Shortcut
-                    shortcut="K"
-                    description="Move to the next transaction up"
+                    shortcut="D"
+                    description="Delete selected transactions"
                   />
                   <Shortcut
-                    shortcut="↑"
-                    description="Move to the next transaction down and scroll"
+                    shortcut="A"
+                    description="Set account for selected transactions"
                   />
                   <Shortcut
-                    shortcut="↓"
-                    description="Move to the next transaction up and scroll"
+                    shortcut="P"
+                    description="Set payee for selected transactions"
                   />
                   <Shortcut
-                    shortcut="Space"
-                    description="Toggle selection of current transaction"
+                    shortcut="N"
+                    description="Set notes for selected transactions"
                   />
                   <Shortcut
-                    shortcut="Space"
-                    description="Toggle all transactions between current and most recently selected transaction"
-                    shift={true}
+                    shortcut="C"
+                    description="Set category for selected transactions"
+                  />
+                  <Shortcut
+                    shortcut="L"
+                    description="Toggle cleared for selected transactions"
+                  />
+                  <Shortcut
+                    shortcut="S"
+                    description="Link or view schedule for selected transactions"
                   />
                 </>
               )}
@@ -296,34 +303,31 @@ export function KeyboardShortcutModal() {
                         shortcut="F"
                         description="Filter transactions"
                       />
-                      <GroupHeading group="With transaction(s) selected" />
+                      <GroupHeading group="Select a transaction, then" />
                       <Shortcut
-                        shortcut="F"
-                        description="Filter to the selected transactions"
+                        shortcut="J"
+                        description="Move to the next transaction down"
                       />
                       <Shortcut
-                        shortcut="D"
-                        description="Delete selected transactions"
+                        shortcut="K"
+                        description="Move to the next transaction up"
                       />
                       <Shortcut
-                        shortcut="A"
-                        description="Set account for selected transactions"
+                        shortcut="↑"
+                        description="Move to the next transaction down and scroll"
                       />
                       <Shortcut
-                        shortcut="P"
-                        description="Set payee for selected transactions"
+                        shortcut="↓"
+                        description="Move to the next transaction up and scroll"
                       />
                       <Shortcut
-                        shortcut="N"
-                        description="Set notes for selected transactions"
+                        shortcut="Space"
+                        description="Toggle selection of current transaction"
                       />
                       <Shortcut
-                        shortcut="C"
-                        description="Set category for selected transactions"
-                      />
-                      <Shortcut
-                        shortcut="L"
-                        description="Toggle cleared for current transaction"
+                        shortcut="Space"
+                        description="Toggle all transactions between current and most recently selected transaction"
+                        shift={true}
                       />
                     </>
                   )}
diff --git a/packages/desktop-client/src/components/schedules/ScheduleLink.tsx b/packages/desktop-client/src/components/schedules/ScheduleLink.tsx
index 666a040c4..a5220a9f7 100644
--- a/packages/desktop-client/src/components/schedules/ScheduleLink.tsx
+++ b/packages/desktop-client/src/components/schedules/ScheduleLink.tsx
@@ -20,12 +20,14 @@ import { ROW_HEIGHT, SchedulesTable } from './SchedulesTable';
 export function ScheduleLink({
   transactionIds: ids,
   getTransaction,
+  accountName,
 }: {
   transactionIds: string[];
   getTransaction: (transactionId: string) => TransactionEntity;
+  accountName: string;
 }) {
   const dispatch = useDispatch();
-  const [filter, setFilter] = useState('');
+  const [filter, setFilter] = useState(accountName);
 
   const scheduleData = useSchedules({
     transform: useCallback((q: Query) => q.filter({ completed: false }), []),
diff --git a/packages/desktop-client/src/components/transactions/SelectedTransactionsButton.jsx b/packages/desktop-client/src/components/transactions/SelectedTransactionsButton.jsx
index 5d982ebbe..a6000bc52 100644
--- a/packages/desktop-client/src/components/transactions/SelectedTransactionsButton.jsx
+++ b/packages/desktop-client/src/components/transactions/SelectedTransactionsButton.jsx
@@ -11,6 +11,7 @@ import { Menu } from '../common/Menu';
 import { SelectedItemsButton } from '../table';
 
 export function SelectedTransactionsButton({
+  account,
   getTransaction,
   onShow,
   onDuplicate,
@@ -112,6 +113,32 @@ export function SelectedTransactionsButton({
     return areNoReconciledTransactions && areAllSplitTransactions;
   }, [selectedIds, types, getTransaction]);
 
+  function onLinkSchedule() {
+    dispatch(
+      pushModal('schedule-link', {
+        transactionIds: selectedIds,
+        getTransaction,
+        accountName: account?.name ?? '',
+      }),
+    );
+  }
+
+  function onViewSchedule() {
+    const firstId = selectedIds[0];
+    let scheduleId;
+    if (isPreviewId(firstId)) {
+      const parts = firstId.split('/');
+      scheduleId = parts[1];
+    } else {
+      const trans = getTransaction(firstId);
+      scheduleId = trans && trans.schedule;
+    }
+
+    if (scheduleId) {
+      dispatch(pushModal('schedule-edit', { id: scheduleId }));
+    }
+  }
+
   const hotKeyOptions = {
     enabled: types.trans,
     scopes: ['app'],
@@ -144,6 +171,14 @@ export function SelectedTransactionsButton({
     onEdit,
     selectedIds,
   ]);
+  useHotkeys(
+    's',
+    () => (!types.trans || linked ? onViewSchedule() : onLinkSchedule()),
+    {
+      scopes: ['app'],
+    },
+    [onLinkSchedule, onViewSchedule, linked, selectedIds],
+  );
 
   return (
     <SelectedItemsButton
@@ -151,7 +186,7 @@ export function SelectedTransactionsButton({
       items={[
         ...(!types.trans
           ? [
-              { name: 'view-schedule', text: 'View schedule' },
+              { name: 'view-schedule', text: 'View schedule', key: 'S' },
               { name: 'post-transaction', text: 'Post transaction' },
               { name: 'skip', text: 'Skip scheduled date' },
             ]
@@ -168,6 +203,7 @@ export function SelectedTransactionsButton({
                     {
                       name: 'view-schedule',
                       text: 'View schedule',
+                      key: 'S',
                       disabled: selectedIds.length > 1,
                     },
                     { name: 'unlink-schedule', text: 'Unlink schedule' },
@@ -176,6 +212,7 @@ export function SelectedTransactionsButton({
                     {
                       name: 'link-schedule',
                       text: 'Link schedule',
+                      key: 'S',
                     },
                     {
                       name: 'create-rule',
@@ -242,27 +279,10 @@ export function SelectedTransactionsButton({
             onScheduleAction(name, selectedIds);
             break;
           case 'view-schedule':
-            const firstId = selectedIds[0];
-            let scheduleId;
-            if (isPreviewId(firstId)) {
-              const parts = firstId.split('/');
-              scheduleId = parts[1];
-            } else {
-              const trans = getTransaction(firstId);
-              scheduleId = trans && trans.schedule;
-            }
-
-            if (scheduleId) {
-              dispatch(pushModal('schedule-edit', { id: scheduleId }));
-            }
+            onViewSchedule();
             break;
           case 'link-schedule':
-            dispatch(
-              pushModal('schedule-link', {
-                transactionIds: selectedIds,
-                getTransaction,
-              }),
-            );
+            onLinkSchedule();
             break;
           case 'unlink-schedule':
             onUnlink(selectedIds);
diff --git a/upcoming-release-notes/3188.md b/upcoming-release-notes/3188.md
new file mode 100644
index 000000000..6ce11140b
--- /dev/null
+++ b/upcoming-release-notes/3188.md
@@ -0,0 +1,6 @@
+---
+category: Enhancements
+authors: [psybers]
+---
+
+Filter by account when linking schedules and add shortcut "S" to link schedule.
-- 
GitLab