@zeniai/client-epic-state 5.0.80 → 5.0.81-betaAD01

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (196) hide show
  1. package/lib/commonStateTypes/cacheOverrideFetchReducer.d.ts +17 -0
  2. package/lib/commonStateTypes/cacheOverrideFetchReducer.js +20 -0
  3. package/lib/commonStateTypes/filterPrimitives.d.ts +23 -0
  4. package/lib/commonStateTypes/filterPrimitives.js +21 -0
  5. package/lib/commonStateTypes/pusherActions.d.ts +11 -0
  6. package/lib/commonStateTypes/pusherActions.js +6 -0
  7. package/lib/coreEpics.js +1 -1
  8. package/lib/entity/account/accountSelector.d.ts +27 -1
  9. package/lib/entity/account/accountSelector.js +47 -1
  10. package/lib/entity/account/accountState.d.ts +6 -1
  11. package/lib/entity/account/accountState.js +11 -4
  12. package/lib/entity/account/subAccountSelector.d.ts +1 -1
  13. package/lib/entity/aiAccountantCustomer/aiAccountantCustomerPayload.js +1 -3
  14. package/lib/entity/aiAccountantCustomer/aiAccountantCustomerReducer.js +1 -2
  15. package/lib/entity/aiAccountantCustomer/aiAccountantCustomerSelector.d.ts +1 -1
  16. package/lib/entity/aiCfo/aiCfoPayload.d.ts +2 -0
  17. package/lib/entity/aiCfo/aiCfoReducer.d.ts +1 -1
  18. package/lib/entity/aiCfo/aiCfoReducer.js +33 -3
  19. package/lib/entity/aiCfo/aiCfoSelector.js +13 -1
  20. package/lib/entity/aiCfo/aiCfoState.d.ts +2 -0
  21. package/lib/entity/chargeCard/chargeCardReducer.d.ts +19 -2
  22. package/lib/entity/chargeCard/chargeCardReducer.js +35 -2
  23. package/lib/entity/chargeCardTransaction/chargeCardTransactionReducer.d.ts +14 -1
  24. package/lib/entity/chargeCardTransaction/chargeCardTransactionReducer.js +36 -2
  25. package/lib/entity/class/classSelector.d.ts +35 -0
  26. package/lib/entity/class/classSelector.js +50 -0
  27. package/lib/entity/sectionProjectView/sectionProjectViewReducer.d.ts +1 -1
  28. package/lib/entity/sectionProjectView/sectionProjectViewSelector.js +1 -1
  29. package/lib/entity/tenant/SessionManager.js +6 -3
  30. package/lib/entity/tenant/clearAllEpic.d.ts +2 -2
  31. package/lib/entity/tenant/clearAllEpic.js +2 -2
  32. package/lib/entity/tenant/epic/saveAPIKeyConnectionEpic.js +6 -2
  33. package/lib/entity/tenant/epic/saveOAuthConnectionEpic.js +6 -2
  34. package/lib/entity/tenant/tenantReducer.js +6 -1
  35. package/lib/entity/transaction/payloadTypes/transactionLinePayload.js +3 -1
  36. package/lib/epic.d.ts +12 -11
  37. package/lib/epic.js +13 -12
  38. package/lib/esm/commonStateTypes/cacheOverrideFetchReducer.js +16 -0
  39. package/lib/esm/commonStateTypes/filterPrimitives.js +20 -0
  40. package/lib/esm/commonStateTypes/pusherActions.js +3 -0
  41. package/lib/esm/coreEpics.js +1 -1
  42. package/lib/esm/entity/account/accountSelector.js +46 -1
  43. package/lib/esm/entity/account/accountState.js +7 -1
  44. package/lib/esm/entity/aiAccountantCustomer/aiAccountantCustomerPayload.js +1 -3
  45. package/lib/esm/entity/aiAccountantCustomer/aiAccountantCustomerReducer.js +1 -2
  46. package/lib/esm/entity/aiCfo/aiCfoReducer.js +32 -2
  47. package/lib/esm/entity/aiCfo/aiCfoSelector.js +13 -1
  48. package/lib/esm/entity/chargeCard/chargeCardReducer.js +34 -1
  49. package/lib/esm/entity/chargeCardTransaction/chargeCardTransactionReducer.js +35 -1
  50. package/lib/esm/entity/class/classSelector.js +48 -0
  51. package/lib/esm/entity/sectionProjectView/sectionProjectViewSelector.js +1 -1
  52. package/lib/esm/entity/tenant/SessionManager.js +4 -1
  53. package/lib/esm/entity/tenant/clearAllEpic.js +2 -2
  54. package/lib/esm/entity/tenant/epic/saveAPIKeyConnectionEpic.js +6 -2
  55. package/lib/esm/entity/tenant/epic/saveOAuthConnectionEpic.js +6 -2
  56. package/lib/esm/entity/tenant/tenantReducer.js +6 -1
  57. package/lib/esm/entity/transaction/payloadTypes/transactionLinePayload.js +3 -1
  58. package/lib/esm/epic.js +13 -12
  59. package/lib/esm/index.js +33 -23
  60. package/lib/esm/reducer.js +2 -2
  61. package/lib/esm/view/aiAccountantView/epics/fetchAiAccountantCustomersEpic.js +2 -5
  62. package/lib/esm/view/aiAccountantView/epics/fetchAiAccountantJobsEpic.js +2 -5
  63. package/lib/esm/view/aiAccountantView/epics/triggerAiAccountantJobEpic.js +4 -1
  64. package/lib/esm/view/aiCfoView/aiCfoViewReducer.js +11 -1
  65. package/lib/esm/view/aiCfoView/epics/updateChatSessionPinEpic.js +46 -0
  66. package/lib/esm/view/companyHealthMetricView/companyHealthMetricViewSelector.js +1 -1
  67. package/lib/esm/view/companyTaskManagerView/companyTaskManagerViewSelector.js +1 -1
  68. package/lib/esm/view/companyTaskManagerView/epics/fetchTaskManagerMetricsEpic.js +1 -1
  69. package/lib/esm/view/companyView/helpers/cockpitHelpers.js +1 -1
  70. package/lib/esm/view/companyView/selector/companyManagementViewSelector.js +1 -1
  71. package/lib/esm/view/companyView/selector/companyPortfolioViewSelector.js +1 -1
  72. package/lib/esm/view/creditAgentView/creditAgentViewReducer.js +1 -16
  73. package/lib/esm/view/expenseAutomationView/epics/missingReceipts/fetchBulkUploadBatchesEpic.js +2 -2
  74. package/lib/esm/view/expenseAutomationView/epics/missingReceipts/fetchCompletedTransactionsEpic.js +2 -1
  75. package/lib/esm/view/expenseAutomationView/epics/missingReceipts/restoreBulkUploadAutomatchingOnMountEpic.js +8 -6
  76. package/lib/esm/view/expenseAutomationView/epics/missingReceipts/searchTransactionsForManualMatchEpic.js +7 -1
  77. package/lib/esm/view/expenseAutomationView/epics/transactionCategorization/fetchTransactionCategorizationEpic.js +11 -1
  78. package/lib/esm/view/expenseAutomationView/helpers/transactionCategorizationLocalDataHelper.js +21 -1
  79. package/lib/esm/view/expenseAutomationView/reducers/missingReceiptsViewReducer.js +2 -1
  80. package/lib/esm/view/expenseAutomationView/reducers/transactionsViewReducer.js +253 -14
  81. package/lib/esm/view/expenseAutomationView/selectors/transactionCategorizationSelector.js +147 -13
  82. package/lib/esm/view/expenseAutomationView/transactionFilterHelpers.js +258 -0
  83. package/lib/esm/view/expenseAutomationView/types/completedSubTab.js +17 -0
  84. package/lib/esm/view/expenseAutomationView/types/missingReceiptsViewState.js +0 -2
  85. package/lib/esm/view/financeStatement/financeStatementSelector.js +1 -1
  86. package/lib/esm/view/recommendation/fetchEntityRecommendationsForLineUpdateEpic.js +87 -0
  87. package/lib/esm/view/recommendation/recommendationHelper.js +29 -0
  88. package/lib/esm/view/recommendation/recommendationReducer.js +26 -1
  89. package/lib/esm/view/spendManagement/chargeCards/cashbackDetail/cashbackDetailReducer.js +3 -2
  90. package/lib/esm/view/spendManagement/chargeCards/chargeCardConfig/chargeCardConfigReducer.js +3 -2
  91. package/lib/esm/view/spendManagement/chargeCards/chargeCardDetail/chargeCardDetailReducer.js +55 -18
  92. package/lib/esm/view/spendManagement/chargeCards/chargeCardDetail/fetchChargeCardDetailEpic.js +16 -2
  93. package/lib/esm/view/spendManagement/chargeCards/chargeCardDetail/fetchChargeCardDetailPageEpic.js +5 -4
  94. package/lib/esm/view/spendManagement/chargeCards/chargeCardList/chargeCardListReducer.js +26 -9
  95. package/lib/esm/view/spendManagement/chargeCards/chargeCardList/fetchChargeCardListPageEpic.js +9 -6
  96. package/lib/esm/view/spendManagement/chargeCards/chargeCardPaymentHistory/chargeCardPaymentHistoryReducer.js +3 -2
  97. package/lib/esm/view/spendManagement/chargeCards/chargeCardPaymentHistory/fetchChargeCardPaymentPageEpic.js +1 -1
  98. package/lib/esm/view/spendManagement/chargeCards/chargeCardRepaymentDetail/chargeCardRepaymentDetailReducer.js +7 -3
  99. package/lib/esm/view/spendManagement/spendManagementFilterHelpers.js +4 -2
  100. package/lib/esm/view/subscriptionView/subscriptionViewSelector.js +1 -1
  101. package/lib/esm/view/taskManager/cannedResponsesView/epics/fetchCannedResponsesEpic.js +1 -1
  102. package/lib/esm/view/taskManager/cannedResponsesView/epics/saveCannedResponseEpic.js +1 -1
  103. package/lib/esm/view/taskManager/taskDetailView/epics/unsnoozeTaskEpic.js +1 -1
  104. package/lib/esm/view/taskManager/taskListView/taskListReducer.js +1 -1
  105. package/lib/esm/view/transactionDetail/transactionDetailReducer.js +121 -6
  106. package/lib/esm/view/transactionDetail/transactionDetailSelector.js +29 -1
  107. package/lib/index.d.ts +33 -26
  108. package/lib/index.js +86 -60
  109. package/lib/reducer.d.ts +2 -2
  110. package/lib/reducer.js +2 -2
  111. package/lib/view/aiAccountantView/aiAccountantViewPayload.d.ts +2 -2
  112. package/lib/view/aiAccountantView/aiAccountantViewReducer.d.ts +1 -1
  113. package/lib/view/aiAccountantView/epics/fetchAiAccountantCustomersEpic.js +2 -5
  114. package/lib/view/aiAccountantView/epics/fetchAiAccountantJobsEpic.js +2 -5
  115. package/lib/view/aiAccountantView/epics/triggerAiAccountantJobEpic.js +4 -1
  116. package/lib/view/aiCfoView/aiCfoViewReducer.d.ts +4 -1
  117. package/lib/view/aiCfoView/aiCfoViewReducer.js +12 -2
  118. package/lib/view/aiCfoView/epics/updateChatSessionPinEpic.d.ts +8 -0
  119. package/lib/view/aiCfoView/epics/updateChatSessionPinEpic.js +50 -0
  120. package/lib/view/companyHealthMetricView/companyHealthMetricViewSelector.js +1 -1
  121. package/lib/view/companyTaskManagerView/companyTaskManagerViewSelector.d.ts +1 -1
  122. package/lib/view/companyTaskManagerView/companyTaskManagerViewSelector.js +1 -1
  123. package/lib/view/companyView/helpers/cockpitHelpers.js +1 -1
  124. package/lib/view/companyView/selector/companyManagementViewSelector.js +1 -1
  125. package/lib/view/companyView/selector/companyPortfolioViewSelector.js +1 -1
  126. package/lib/view/companyView/types/cockpitTypes.d.ts +1 -1
  127. package/lib/view/creditAgentView/creditAgentViewPayload.d.ts +0 -3
  128. package/lib/view/creditAgentView/creditAgentViewReducer.d.ts +1 -1
  129. package/lib/view/creditAgentView/creditAgentViewReducer.js +2 -17
  130. package/lib/view/creditAgentView/creditAgentViewState.d.ts +0 -5
  131. package/lib/view/expenseAutomationView/epics/missingReceipts/fetchBulkUploadBatchesEpic.js +2 -2
  132. package/lib/view/expenseAutomationView/epics/missingReceipts/fetchCompletedTransactionsEpic.js +2 -1
  133. package/lib/view/expenseAutomationView/epics/missingReceipts/restoreBulkUploadAutomatchingOnMountEpic.js +8 -6
  134. package/lib/view/expenseAutomationView/epics/missingReceipts/searchTransactionsForManualMatchEpic.js +7 -1
  135. package/lib/view/expenseAutomationView/epics/transactionCategorization/fetchTransactionCategorizationEpic.d.ts +2 -2
  136. package/lib/view/expenseAutomationView/epics/transactionCategorization/fetchTransactionCategorizationEpic.js +10 -0
  137. package/lib/view/expenseAutomationView/helpers/transactionCategorizationLocalDataHelper.d.ts +2 -1
  138. package/lib/view/expenseAutomationView/helpers/transactionCategorizationLocalDataHelper.js +23 -2
  139. package/lib/view/expenseAutomationView/payload/transactionCategorizationPayload.d.ts +21 -0
  140. package/lib/view/expenseAutomationView/reducers/missingReceiptsViewReducer.d.ts +2 -1
  141. package/lib/view/expenseAutomationView/reducers/missingReceiptsViewReducer.js +2 -1
  142. package/lib/view/expenseAutomationView/reducers/transactionsViewReducer.d.ts +28 -5
  143. package/lib/view/expenseAutomationView/reducers/transactionsViewReducer.js +253 -14
  144. package/lib/view/expenseAutomationView/selectorTypes/missingReceiptsSelectorTypes.d.ts +2 -1
  145. package/lib/view/expenseAutomationView/selectorTypes/transactionsViewSelectorTypes.d.ts +16 -0
  146. package/lib/view/expenseAutomationView/selectors/transactionCategorizationSelector.d.ts +7 -1
  147. package/lib/view/expenseAutomationView/selectors/transactionCategorizationSelector.js +150 -13
  148. package/lib/view/expenseAutomationView/transactionFilterHelpers.d.ts +66 -0
  149. package/lib/view/expenseAutomationView/transactionFilterHelpers.js +262 -0
  150. package/lib/view/expenseAutomationView/types/completedSubTab.d.ts +10 -0
  151. package/lib/view/expenseAutomationView/types/completedSubTab.js +21 -0
  152. package/lib/view/expenseAutomationView/types/missingReceiptsViewState.d.ts +1 -2
  153. package/lib/view/expenseAutomationView/types/missingReceiptsViewState.js +1 -4
  154. package/lib/view/expenseAutomationView/types/transactionsViewState.d.ts +44 -2
  155. package/lib/view/financeStatement/financeStatementSelector.js +1 -1
  156. package/lib/view/profitAndLossProjectView/profitAndLossProjectViewSelectorTypes.d.ts +1 -1
  157. package/lib/view/recommendation/fetchEntityRecommendationsForLineUpdateEpic.d.ts +9 -0
  158. package/lib/view/recommendation/fetchEntityRecommendationsForLineUpdateEpic.js +91 -0
  159. package/lib/view/recommendation/recommendationHelper.d.ts +9 -0
  160. package/lib/view/recommendation/recommendationHelper.js +31 -1
  161. package/lib/view/recommendation/recommendationReducer.d.ts +20 -1
  162. package/lib/view/recommendation/recommendationReducer.js +27 -2
  163. package/lib/view/spendManagement/billPay/billList/billListState.d.ts +1 -1
  164. package/lib/view/spendManagement/chargeCards/cashbackDetail/cashbackDetailReducer.d.ts +3 -1
  165. package/lib/view/spendManagement/chargeCards/cashbackDetail/cashbackDetailReducer.js +3 -2
  166. package/lib/view/spendManagement/chargeCards/chargeCardConfig/chargeCardConfigReducer.d.ts +3 -1
  167. package/lib/view/spendManagement/chargeCards/chargeCardConfig/chargeCardConfigReducer.js +3 -2
  168. package/lib/view/spendManagement/chargeCards/chargeCardDetail/chargeCardDetailReducer.js +55 -18
  169. package/lib/view/spendManagement/chargeCards/chargeCardDetail/fetchChargeCardDetailEpic.js +16 -2
  170. package/lib/view/spendManagement/chargeCards/chargeCardDetail/fetchChargeCardDetailPageEpic.js +5 -4
  171. package/lib/view/spendManagement/chargeCards/chargeCardList/chargeCardListReducer.d.ts +18 -3
  172. package/lib/view/spendManagement/chargeCards/chargeCardList/chargeCardListReducer.js +27 -10
  173. package/lib/view/spendManagement/chargeCards/chargeCardList/fetchChargeCardListPageEpic.js +9 -6
  174. package/lib/view/spendManagement/chargeCards/chargeCardPaymentHistory/chargeCardPaymentHistory.d.ts +1 -1
  175. package/lib/view/spendManagement/chargeCards/chargeCardPaymentHistory/chargeCardPaymentHistoryReducer.d.ts +3 -1
  176. package/lib/view/spendManagement/chargeCards/chargeCardPaymentHistory/chargeCardPaymentHistoryReducer.js +3 -2
  177. package/lib/view/spendManagement/chargeCards/chargeCardPaymentHistory/fetchChargeCardPaymentPageEpic.js +1 -1
  178. package/lib/view/spendManagement/chargeCards/chargeCardRepaymentDetail/chargeCardRepaymentDetailReducer.d.ts +3 -1
  179. package/lib/view/spendManagement/chargeCards/chargeCardRepaymentDetail/chargeCardRepaymentDetailReducer.js +7 -3
  180. package/lib/view/spendManagement/reimbursement/remiListView/remiListState.d.ts +1 -1
  181. package/lib/view/spendManagement/spendManagementFilterHelpers.d.ts +12 -3
  182. package/lib/view/spendManagement/spendManagementFilterHelpers.js +4 -2
  183. package/lib/view/subscriptionView/subscriptionViewSelector.js +1 -1
  184. package/lib/view/taskManager/taskListView/taskList.d.ts +1 -1
  185. package/lib/view/taskManager/taskListView/taskListReducer.js +1 -1
  186. package/lib/view/transactionDetail/transactionDetailReducer.d.ts +11 -1
  187. package/lib/view/transactionDetail/transactionDetailReducer.js +122 -7
  188. package/lib/view/transactionDetail/transactionDetailSelector.d.ts +2 -0
  189. package/lib/view/transactionDetail/transactionDetailSelector.js +31 -2
  190. package/lib/view/transactionDetail/transactionDetailTypes.d.ts +1 -0
  191. package/lib/view/zeniOAuthView/zeniOAuthSelector.d.ts +1 -1
  192. package/package.json +9 -4
  193. package/lib/esm/view/creditAgentView/epics/fetchCreditAgentAccessEpic.js +0 -13
  194. package/lib/tsconfig.typecheck.tsbuildinfo +0 -1
  195. package/lib/view/creditAgentView/epics/fetchCreditAgentAccessEpic.d.ts +0 -11
  196. package/lib/view/creditAgentView/epics/fetchCreditAgentAccessEpic.js +0 -17
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.hasTransactionLocalDataChanges = exports.isAnyItemWithUncategorizedExpenseAccount = exports.getSnackbarMessageForTransactionReview = exports.mergeTabSpecificLineItems = exports.getLineItemsByTransactionIdsFromLocalData = exports.getLineItemsByTransactionsIdsFromResponse = exports.checkIfAllLineItemsAreCategoryClassFilled = exports.setEntityRecommendationForLineIdInLocalData = exports.toSetAllLineItemsToCategoryClass = exports.toTransactionDetailLocalData = exports.MAX_SELECTION_LIMIT = exports.filterAutoTabLineItems = exports.removeTransactionFromTabView = exports.getPendingReviewLineIdsFromTransaction = void 0;
3
+ exports.hasTransactionLocalDataChanges = exports.isAnyItemWithUncategorizedExpenseAccount = exports.getSnackbarMessageForTransactionReview = exports.mergeTabSpecificLineItems = exports.getLineItemsByTransactionIdsFromLocalData = exports.getLineItemsByTransactionsIdsFromResponse = exports.checkIfAllLineItemsAreCategoryClassFilled = exports.setEntityRecommendationForLineIdInLocalData = exports.toSetAllLineItemsToCategoryClass = exports.toTransactionDetailLocalData = exports.shouldAutoSelectAndAdd = exports.MAX_SELECTION_LIMIT = exports.filterAutoTabLineItems = exports.removeTransactionFromTabView = exports.getPendingReviewLineIdsFromTransaction = void 0;
4
4
  const vendorTransaction_1 = require("../../../entity/transaction/stateTypes/vendorTransaction");
5
5
  const transactionDetailLocalDataHelper_1 = require("../../transactionDetail/transactionDetailLocalDataHelper");
6
6
  const transactionDetailLocalDataHelper_2 = require("../../transactionDetail/transactionDetailLocalDataHelper");
@@ -65,6 +65,23 @@ const filterAutoTabLineItems = (tabView, transactionId, updatedTransaction) => {
65
65
  };
66
66
  exports.filterAutoTabLineItems = filterAutoTabLineItems;
67
67
  exports.MAX_SELECTION_LIMIT = 5;
68
+ // Returns true when the transaction should be auto-added to the
69
+ // selectedCheckBoxTransactionIds list after a categorization-related
70
+ // state mutation: all line items are filled, the selection limit has
71
+ // not been hit, and the id isn't already in the list. Consolidates the
72
+ // triplet that was inlined at four sites (updateSelectedCustomer/Vendor,
73
+ // setAllItemsToCategoryClassInLocalDataForCategorization, and
74
+ // setEntityRecommendationForLineIdInLocalData below).
75
+ const shouldAutoSelectAndAdd = (transaction, localData, selectedCheckBoxTransactionIds, uncategorizedAccounts, isUncategorizedExpenseCategoryEnabled, isAccountingClassesEnabled) => {
76
+ if (selectedCheckBoxTransactionIds.includes(transaction.id)) {
77
+ return false;
78
+ }
79
+ if (selectedCheckBoxTransactionIds.length >= exports.MAX_SELECTION_LIMIT) {
80
+ return false;
81
+ }
82
+ return (0, exports.checkIfAllLineItemsAreCategoryClassFilled)(transaction, localData, uncategorizedAccounts, isUncategorizedExpenseCategoryEnabled, isAccountingClassesEnabled);
83
+ };
84
+ exports.shouldAutoSelectAndAdd = shouldAutoSelectAndAdd;
68
85
  const toTransactionDetailLocalData = (transaction, selectedTab, lineItemsByTransactionIds, uncategorizedIncomeExpense, isUncategorizedExpenseCategoryEnabled) => {
69
86
  const transactionLocal = {
70
87
  ...transactionsViewState_1.initialSupportedTransactionCategorization.transactionReviewLocalData,
@@ -552,10 +569,14 @@ const setEntityRecommendationForLineIdInLocalData = (draft, transaction, transac
552
569
  selectedEntity: transactionDetailLocalData.selectedEntity,
553
570
  tabSpecificLineItems: transactionDetailLocalData.tabSpecificLineItems,
554
571
  };
572
+ // Auto-uncheck if not all line items are filled (the row's
573
+ // category/class became stale after the entity update). Otherwise
574
+ // route through shouldAutoSelectAndAdd so the MAX_SELECTION_LIMIT
575
+ // gate is consistently applied across all auto-add sites.
555
576
  if (!(0, exports.checkIfAllLineItemsAreCategoryClassFilled)(transaction, newLocalData, uncategorizedAccounts, isUncategorizedExpenseCategoryEnabled, isAccountingClassesEnabled)) {
556
577
  selectedCheckBoxTransactionIds = selectedCheckBoxTransactionIds.filter((id) => id !== transaction.id);
557
578
  }
558
- else if (selectedCheckBoxTransactionIds.includes(transaction.id) === false) {
579
+ else if ((0, exports.shouldAutoSelectAndAdd)(transaction, newLocalData, selectedCheckBoxTransactionIds, uncategorizedAccounts, isUncategorizedExpenseCategoryEnabled, isAccountingClassesEnabled)) {
559
580
  selectedCheckBoxTransactionIds.push(transaction.id);
560
581
  }
561
582
  draft.selectedCheckBoxTransactionIds = selectedCheckBoxTransactionIds;
@@ -2,6 +2,7 @@ import { EntityRecommendationPayload } from '../../../commonPayloadTypes/recomme
2
2
  import { TransactionPayload } from '../../../entity/transaction/payloadTypes/transactionPayload';
3
3
  import { SupportedTransactionPayload } from '../../../entity/transaction/transactionState';
4
4
  import { ZeniAPIResponse } from '../../../responsePayload';
5
+ import { CompletedSubTab } from '../types/completedSubTab';
5
6
  export interface TransactionCategorizationQueryPayload {
6
7
  auto_categorized: boolean;
7
8
  end_date: string | null;
@@ -11,12 +12,32 @@ export interface TransactionCategorizationQueryPayload {
11
12
  sort_by: string;
12
13
  sort_order: string;
13
14
  start_date: string | null;
15
+ /**
16
+ * Required. For the Completed (`auto_categorized=true`) listing, scopes the
17
+ * returned page + `total_count` to one of the Completed sub-tabs. For the
18
+ * Review listing it is forced to `'all'` to preserve parent-tab semantics
19
+ * on the backend.
20
+ */
21
+ sub_tab: CompletedSubTab;
14
22
  }
15
23
  export interface TransactionCategorizationPayload {
16
24
  next_page_token: string | null;
17
25
  query: TransactionCategorizationQueryPayload;
18
26
  total_count: number;
19
27
  transactions: SupportedTransactionPayload[];
28
+ /**
29
+ * Count of transactions for the entire parent tab (Review or Completed),
30
+ * regardless of which sub-tab the listing was scoped to. Used solely to
31
+ * drive the parent tab badge counts on the UI; pagination, list-level
32
+ * counts, and sub-tab chips continue to consume {@link total_count}.
33
+ *
34
+ * Optional at the wire boundary so that any version-skew scenario
35
+ * (delayed BE rollout, cached SW response, hotfix without the BE change)
36
+ * deserializes cleanly. Consumers are expected to fall back to
37
+ * {@link total_count} when this is absent — see
38
+ * `fetchTransactionCategorizationEpic` for the canonical fallback.
39
+ */
40
+ parent_tab_total_count?: number;
20
41
  }
21
42
  export type TransactionCategorizationResponse = ZeniAPIResponse<TransactionCategorizationPayload>;
22
43
  export interface EntityRelatedUpdatesPayload {
@@ -6,7 +6,8 @@ import type { MonthYearPeriodId } from '../../../commonStateTypes/timePeriod';
6
6
  import { TransactionPayload } from '../../../entity/transaction/payloadTypes/transactionPayload';
7
7
  import { SupportedTransactionPayload } from '../../../entity/transaction/transactionState';
8
8
  import { ZeniAPIStatus } from '../../../responsePayload';
9
- import { type BatchDetails, type BatchListItem, type BatchStatus, type BulkUploadResultsTab, type BulkUploadSortKey, type BulkUploadState, type CompletedSubTab, type ManualSearchResult, type MissingReceiptsViewState, type MissingReceiptsViewUIState } from '../types/missingReceiptsViewState';
9
+ import { type CompletedSubTab } from '../types/completedSubTab';
10
+ import { type BatchDetails, type BatchListItem, type BatchStatus, type BulkUploadResultsTab, type BulkUploadSortKey, type BulkUploadState, type ManualSearchResult, type MissingReceiptsViewState, type MissingReceiptsViewUIState } from '../types/missingReceiptsViewState';
10
11
  export declare const getCompletedTransactionsCacheKey: (periodId: MonthYearPeriodId, sortKey: BulkUploadSortKey | undefined, sortOrder: SortOrder | undefined, subTab: CompletedSubTab) => string;
11
12
  export declare const initialBulkUploadState: BulkUploadState;
12
13
  export declare const initialState: MissingReceiptsViewState;
@@ -5,6 +5,7 @@ exports.fetchCompletedTransactions = exports.acknowledgeBulkUploadConfirmMatchCo
5
5
  exports.fetchCompletedTransactionsFailure = exports.fetchCompletedTransactionsSuccess = void 0;
6
6
  const toolkit_1 = require("@reduxjs/toolkit");
7
7
  const timePeriod_1 = require("../../../commonStateTypes/timePeriod");
8
+ const completedSubTab_1 = require("../types/completedSubTab");
8
9
  const missingReceiptsViewState_1 = require("../types/missingReceiptsViewState");
9
10
  const getCompletedTransactionsCacheKey = (periodId, sortKey, sortOrder, subTab) => {
10
11
  const sortKeyPart = sortKey ?? 'none';
@@ -19,7 +20,7 @@ exports.initialBulkUploadState = {
19
20
  batchListByPeriod: {},
20
21
  batchListFetchState: { fetchState: 'Not-Started', error: undefined },
21
22
  batchStatusById: {},
22
- completedSubTab: 'all',
23
+ completedSubTab: completedSubTab_1.DEFAULT_COMPLETED_SUB_TAB,
23
24
  completedTransactionsByPeriod: {},
24
25
  confirmMatchStatus: { fetchState: 'Not-Started', error: undefined },
25
26
  currentBatchId: undefined,
@@ -4,9 +4,9 @@ import { MonthYearPeriod, TimePeriod } from '../../../commonStateTypes/timePerio
4
4
  import { PageToken } from '../../../commonStateTypes/viewAndReport/viewAndReport';
5
5
  import { AccountBase } from '../../../entity/account/accountState';
6
6
  import { ClassBase } from '../../../entity/class/classState';
7
- import { ProjectBase } from '../../../entity/project/projectState';
8
7
  import { CustomerBase } from '../../../entity/customer/customerState';
9
8
  import { Entity } from '../../../entity/genericEntity/entity';
9
+ import { ProjectBase } from '../../../entity/project/projectState';
10
10
  import { RecommendationWithCOTByLineId, TransactionID } from '../../../entity/transaction/stateTypes/transaction';
11
11
  import { SupportedTransaction, SupportedTransactionPayload, SupportedTransactionWithCOT } from '../../../entity/transaction/transactionState';
12
12
  import { VendorBase } from '../../../entity/vendor/vendorState';
@@ -14,6 +14,7 @@ import { ZeniAPIStatus } from '../../../responsePayload';
14
14
  import { UncategorizedAccounts } from '../../accountList/accountListSelector';
15
15
  import { UpdateTransactionCategorizationResponsePayload } from '../payload/transactionCategorizationPayload';
16
16
  import { SupportedTransactionCategorization, TransactionSaveUpdates, TransactionsTab, TransactionsTabViewState, TransactionsViewState, TransactionsViewUIState } from '../types/transactionsViewState';
17
+ import { TransactionFilters } from '../transactionFilterHelpers';
17
18
  export declare const initialTransactionTabViewState: TransactionsTabViewState;
18
19
  export declare const initialState: TransactionsViewState;
19
20
  export declare const fetchTransactionCategorization: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[selectedTab: "review" | "autoCategorized", period: TimePeriod, cacheOverride?: any, keepExistingListItems?: any, searchString?: string | undefined, pageToken?: PageToken | undefined, refreshViewInBackground?: any, resetListItems?: boolean | undefined, isUncategorizedExpenseCategoryEnabled?: boolean | undefined], {
@@ -29,7 +30,10 @@ export declare const fetchTransactionCategorization: import("@reduxjs/toolkit").
29
30
  }, "expenseAutomationTransactionsView/fetchTransactionCategorization", never, never>, updateTransactionCategorizationUIState: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
30
31
  selectedTab: TransactionsTab;
31
32
  uiState: Partial<TransactionsViewUIState>;
32
- }, "expenseAutomationTransactionsView/updateTransactionCategorizationUIState">, initializeTransactionCategorizationViewLocalData: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[selectedTab: "review" | "autoCategorized", transactionIds: string[], selectedPeriod: MonthYearPeriod, keepExistingListItems: any, pageToken: PageToken, totalCount: number, lineItemsByTransactionIds: Record<string, string[]>, refreshViewInBackground?: any, isUncategorizedExpenseCategoryEnabled?: boolean | undefined], {
33
+ }, "expenseAutomationTransactionsView/updateTransactionCategorizationUIState">, updateTransactionFilters: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
34
+ filters: TransactionFilters;
35
+ selectedTab: TransactionsTab;
36
+ }, "expenseAutomationTransactionsView/updateTransactionFilters">, initializeTransactionCategorizationViewLocalData: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[selectedTab: "review" | "autoCategorized", transactionIds: string[], selectedPeriod: MonthYearPeriod, keepExistingListItems: any, pageToken: PageToken, totalCount: number, lineItemsByTransactionIds: Record<string, string[]>, refreshViewInBackground?: any, isUncategorizedExpenseCategoryEnabled?: boolean | undefined], {
33
37
  selectedTab: "review" | "autoCategorized";
34
38
  transactionIds: string[];
35
39
  selectedPeriod: MonthYearPeriod;
@@ -65,7 +69,9 @@ export declare const fetchTransactionCategorization: import("@reduxjs/toolkit").
65
69
  isUncategorizedExpenseCategoryEnabled: boolean | undefined;
66
70
  }, "expenseAutomationTransactionsView/updateTransactionCategorization", never, never>, updateCurrentSelectedTransactionCategorizationTab: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[newSelectedTab: "review" | "autoCategorized"], {
67
71
  newSelectedTab: "review" | "autoCategorized";
68
- }, "expenseAutomationTransactionsView/updateCurrentSelectedTransactionCategorizationTab", never, never>, updateTransactionCategorizationSaveStatus: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[selectedTab: "review" | "autoCategorized", fetchState: FetchState, error?: ZeniAPIStatus<Record<string, unknown>> | undefined], {
72
+ }, "expenseAutomationTransactionsView/updateCurrentSelectedTransactionCategorizationTab", never, never>, updateTransactionCategorizationCompletedSubTab: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[newSubTab: "all" | "manual" | "ai_accountant"], {
73
+ newSubTab: "all" | "manual" | "ai_accountant";
74
+ }, "expenseAutomationTransactionsView/updateTransactionCategorizationCompletedSubTab", never, never>, updateTransactionCategorizationSaveStatus: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[selectedTab: "review" | "autoCategorized", fetchState: FetchState, error?: ZeniAPIStatus<Record<string, unknown>> | undefined], {
69
75
  selectedTab: "review" | "autoCategorized";
70
76
  fetchState: FetchState;
71
77
  error: ZeniAPIStatus<Record<string, unknown>> | undefined;
@@ -120,7 +126,11 @@ export declare const fetchTransactionCategorization: import("@reduxjs/toolkit").
120
126
  selectedPeriod: MonthYearPeriod;
121
127
  selectedTab: TransactionsTab;
122
128
  totalCount: number;
123
- }, "expenseAutomationTransactionsView/updateTotalCountForTransactionCategorization">, fetchTransactionCategorizationSuccess: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
129
+ }, "expenseAutomationTransactionsView/updateTotalCountForTransactionCategorization">, updateParentTotalCountForTab: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
130
+ parentTotalCount: number;
131
+ selectedPeriod: MonthYearPeriod;
132
+ selectedTab: TransactionsTab;
133
+ }, "expenseAutomationTransactionsView/updateParentTotalCountForTab">, fetchTransactionCategorizationSuccess: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
124
134
  selectedTab: TransactionsTab;
125
135
  status: ZeniAPIStatus;
126
136
  refreshViewInBackground?: boolean;
@@ -151,7 +161,20 @@ export declare const fetchTransactionCategorization: import("@reduxjs/toolkit").
151
161
  uncategorizedAccounts: UncategorizedAccounts;
152
162
  isAccountingClassesEnabled: boolean | undefined;
153
163
  isUncategorizedExpenseCategoryEnabled: boolean | undefined;
154
- }, "expenseAutomationTransactionsView/setEntityRecommendationForLineIdsForCategorization", never, never>, updateSelectedTransactionId: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
164
+ }, "expenseAutomationTransactionsView/setEntityRecommendationForLineIdsForCategorization", never, never>, markCategoryClassRecommendationsInProgressForCategorization: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[selectedTab: "review" | "autoCategorized", transactionId: TransactionID, lineIds: string[]], {
165
+ selectedTab: "review" | "autoCategorized";
166
+ transactionId: TransactionID;
167
+ lineIds: string[];
168
+ }, "expenseAutomationTransactionsView/markCategoryClassRecommendationsInProgressForCategorization", never, never>, markCategoryClassRecommendationsCompletedForCategorization: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[selectedTab: "review" | "autoCategorized", transactionId: TransactionID, lineIds: string[]], {
169
+ selectedTab: "review" | "autoCategorized";
170
+ transactionId: TransactionID;
171
+ lineIds: string[];
172
+ }, "expenseAutomationTransactionsView/markCategoryClassRecommendationsCompletedForCategorization", never, never>, markCategoryClassRecommendationsFailureForCategorization: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[selectedTab: "review" | "autoCategorized", transactionId: TransactionID, lineIds: string[], error: ZeniAPIStatus<Record<string, unknown>>], {
173
+ selectedTab: "review" | "autoCategorized";
174
+ transactionId: TransactionID;
175
+ lineIds: string[];
176
+ error: ZeniAPIStatus<Record<string, unknown>>;
177
+ }, "expenseAutomationTransactionsView/markCategoryClassRecommendationsFailureForCategorization", never, never>, updateSelectedTransactionId: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
155
178
  lineId: ID;
156
179
  selectedTab: TransactionsTab;
157
180
  transactionId: ID;
@@ -4,13 +4,14 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  var _a;
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.uploadTransactionCategorizationReceiptSuccess = exports.updateTransactionCategorizationUploadReceiptState = exports.backgroundRefetchReviewTab = exports.syncTransactionCategorizationFromDetailSave = exports.updateSelectedTransactionId = exports.setEntityRecommendationForLineIdsForCategorization = exports.clearExpenseAutomationTransactionsView = exports.clearExpenseAutomationTransactionsViewPerTabView = exports.updateSelectedCheckboxTransactionIds = exports.fetchTransactionCategorizationView = exports.resetOtherTabsFetchState = exports.fetchTransactionCategorizationSuccess = exports.updateTotalCountForTransactionCategorization = exports.setAllItemsToCategoryClassInLocalDataForCategorization = exports.updateSelectedCustomerForTransaction = exports.updateSelectedVendorForTransaction = exports.updateStatusForTransactionNotMiscategorizedUpdateForCategorization = exports.markTransactionAsNotMiscategorized = exports.updateTransactionCategorizationSaveStatus = exports.updateCurrentSelectedTransactionCategorizationTab = exports.updateTransactionCategorization = exports.saveTransactionCategorization = exports.fetchTransactionCategorizationFailure = exports.saveTransactionCategorizationLocalData = exports.initializeTransactionCategorizationViewLocalData = exports.updateTransactionCategorizationUIState = exports.fetchTransactionCategorization = exports.initialState = exports.initialTransactionTabViewState = void 0;
7
+ exports.uploadTransactionCategorizationReceiptSuccess = exports.updateTransactionCategorizationUploadReceiptState = exports.backgroundRefetchReviewTab = exports.syncTransactionCategorizationFromDetailSave = exports.updateSelectedTransactionId = exports.markCategoryClassRecommendationsFailureForCategorization = exports.markCategoryClassRecommendationsCompletedForCategorization = exports.markCategoryClassRecommendationsInProgressForCategorization = exports.setEntityRecommendationForLineIdsForCategorization = exports.clearExpenseAutomationTransactionsView = exports.clearExpenseAutomationTransactionsViewPerTabView = exports.updateSelectedCheckboxTransactionIds = exports.fetchTransactionCategorizationView = exports.resetOtherTabsFetchState = exports.fetchTransactionCategorizationSuccess = exports.updateParentTotalCountForTab = exports.updateTotalCountForTransactionCategorization = exports.setAllItemsToCategoryClassInLocalDataForCategorization = exports.updateSelectedCustomerForTransaction = exports.updateSelectedVendorForTransaction = exports.updateStatusForTransactionNotMiscategorizedUpdateForCategorization = exports.markTransactionAsNotMiscategorized = exports.updateTransactionCategorizationSaveStatus = exports.updateTransactionCategorizationCompletedSubTab = exports.updateCurrentSelectedTransactionCategorizationTab = exports.updateTransactionCategorization = exports.saveTransactionCategorization = exports.fetchTransactionCategorizationFailure = exports.saveTransactionCategorizationLocalData = exports.initializeTransactionCategorizationViewLocalData = exports.updateTransactionFilters = exports.updateTransactionCategorizationUIState = exports.fetchTransactionCategorization = exports.initialState = exports.initialTransactionTabViewState = void 0;
8
8
  const toolkit_1 = require("@reduxjs/toolkit");
9
9
  const get_1 = __importDefault(require("lodash/get"));
10
10
  const uniq_1 = __importDefault(require("lodash/uniq"));
11
11
  const timePeriod_1 = require("../../../commonStateTypes/timePeriod");
12
12
  const vendorTransaction_1 = require("../../../entity/transaction/stateTypes/vendorTransaction");
13
13
  const transactionCategorizationLocalDataHelper_1 = require("../helpers/transactionCategorizationLocalDataHelper");
14
+ const completedSubTab_1 = require("../types/completedSubTab");
14
15
  exports.initialTransactionTabViewState = {
15
16
  saveStatus: {
16
17
  fetchState: 'Not-Started',
@@ -34,6 +35,10 @@ exports.initialTransactionTabViewState = {
34
35
  totalCount: {},
35
36
  limit: 10,
36
37
  },
38
+ filters: {
39
+ categoryCombinationOperator: 'AND',
40
+ categories: [],
41
+ },
37
42
  fetchState: 'Not-Started',
38
43
  error: undefined,
39
44
  hasValidState() {
@@ -48,12 +53,74 @@ exports.initialTransactionTabViewState = {
48
53
  selectedTransactionLineId: undefined,
49
54
  };
50
55
  exports.initialState = {
56
+ autoCategorizedSubTabCache: {},
57
+ parentTotalCountByTab: {
58
+ review: {},
59
+ autoCategorized: {},
60
+ },
51
61
  selectedTransactionCategorizationTab: 'review',
62
+ selectedTransactionCategorizationCompletedSubTab: completedSubTab_1.DEFAULT_COMPLETED_SUB_TAB,
52
63
  transactionCategorizationView: {
53
64
  review: { ...exports.initialTransactionTabViewState },
54
65
  autoCategorized: { ...exports.initialTransactionTabViewState },
55
66
  },
56
67
  };
68
+ /**
69
+ * Capture the autoCategorized tab's current paginated dataset for a sub-tab.
70
+ * The mid-flight `'In-Progress'` state is normalised to `'Completed'` because
71
+ * the in-flight request is cancelled by `switchMap` in the fetch epic when the
72
+ * sub-tab changes — restoring `'In-Progress'` later would leave the UI stuck
73
+ * showing a phantom loading state with no fetch actually running. Length-zero
74
+ * datasets degrade to `'Not-Started'` so the next visit triggers a fresh
75
+ * fetch from page 1 instead of short-circuiting on stale empty caches.
76
+ *
77
+ * Snapshot scope (deliberately narrow):
78
+ * - Captured: `pageToken`, `totalCount`, `transactionIdsBySelectedPeriod`,
79
+ * `fetchState`, `error`, `scrollPosition`. The first five are the keys the
80
+ * fetch epic's cache check reads to decide whether to short-circuit a
81
+ * sub-tab revisit; `scrollPosition` is captured per sub-tab so revisiting
82
+ * restores the user's last offset and switching to a never-visited sub-tab
83
+ * starts at the top instead of inheriting the outgoing sub-tab's offset
84
+ * (which would land the user at a meaningless row index against a
85
+ * completely different list).
86
+ * - Intentionally NOT captured (left in place on `autoCat` and inherited by
87
+ * the incoming sub-tab):
88
+ * - `uiState.searchString`, `uiState.sortKey`, `uiState.sortOrder`,
89
+ * `uiState.nodeCollapseState`, `uiState.limit` — search and sort are
90
+ * user-applied preferences that persist across sub-tabs by design (a
91
+ * search query stays active when the user toggles between Manual / AI
92
+ * Accountant).
93
+ * - `selectedCheckBoxTransactionIds` — selection state is intentionally
94
+ * cleared at the action source (the fetch epic / save flow), not
95
+ * by the snapshot path. Carrying selection across sub-tabs is safe
96
+ * because every sub-tab change goes through a fetch round-trip that
97
+ * reconciles selection against the new row IDs.
98
+ * - `transactionReviewLocalDataById`, `transactionIdsWithUnsavedData`,
99
+ * `uploadReceiptStatusById`, `saveStatus`, `refreshStatus`,
100
+ * `markAsNotMiscategorizedStatus` — these are per-row / per-flight
101
+ * caches that are write-through global state, not sub-tab-scoped.
102
+ *
103
+ * If the contract changes (e.g. selection should reset on every sub-tab
104
+ * switch), update both this comment and the snapshot return shape together.
105
+ */
106
+ function snapshotAutoCategorizedTab(autoCat) {
107
+ const transactionIdsBySelectedPeriod = {
108
+ ...autoCat.transactionIdsBySelectedPeriod,
109
+ };
110
+ const hasAnyLoadedRows = Object.values(transactionIdsBySelectedPeriod).some((ids) => ids.length > 0);
111
+ let normalisedFetchState = autoCat.fetchState;
112
+ if (normalisedFetchState === 'In-Progress') {
113
+ normalisedFetchState = hasAnyLoadedRows ? 'Completed' : 'Not-Started';
114
+ }
115
+ return {
116
+ error: autoCat.error,
117
+ fetchState: normalisedFetchState,
118
+ pageToken: autoCat.uiState.pageToken,
119
+ scrollPosition: autoCat.uiState.scrollPosition,
120
+ totalCount: { ...autoCat.uiState.totalCount },
121
+ transactionIdsBySelectedPeriod,
122
+ };
123
+ }
57
124
  const expenseAutomationTransactionsView = (0, toolkit_1.createSlice)({
58
125
  name: 'expenseAutomationTransactionsView',
59
126
  initialState: exports.initialState,
@@ -243,6 +310,12 @@ const expenseAutomationTransactionsView = (0, toolkit_1.createSlice)({
243
310
  uiState.totalCount;
244
311
  }
245
312
  },
313
+ updateTransactionFilters(draft, action) {
314
+ const { selectedTab, filters } = action.payload;
315
+ // `filters` is non-nullable per the payload type, so no runtime
316
+ // null-check is needed — dropping it removes a dead defensive branch.
317
+ draft.transactionCategorizationView[selectedTab].filters = filters;
318
+ },
246
319
  saveTransactionCategorization: {
247
320
  prepare(selectedTab, transactionIds, cotTrackingByTransactionId, isUncategorizedExpenseCategoryEnabled) {
248
321
  return {
@@ -267,6 +340,55 @@ const expenseAutomationTransactionsView = (0, toolkit_1.createSlice)({
267
340
  return { payload: { newSelectedTab } };
268
341
  },
269
342
  },
343
+ updateTransactionCategorizationCompletedSubTab: {
344
+ reducer(draft, action) {
345
+ const { newSubTab } = action.payload;
346
+ const previousSubTab = draft.selectedTransactionCategorizationCompletedSubTab;
347
+ if (previousSubTab === newSubTab) {
348
+ return;
349
+ }
350
+ const autoCat = draft.transactionCategorizationView.autoCategorized;
351
+ // Snapshot the outgoing sub-tab so a future revisit can short-circuit
352
+ // the fetch epic (mirrors the parent-tab "don't refetch what's
353
+ // already cached" behaviour). Period-scoped data is preserved as-is
354
+ // because the snapshot itself is keyed only by sub-tab; the active
355
+ // tab's per-period maps remain the source of truth while live.
356
+ draft.autoCategorizedSubTabCache[previousSubTab] =
357
+ snapshotAutoCategorizedTab(autoCat);
358
+ const cached = draft.autoCategorizedSubTabCache[newSubTab];
359
+ if (cached != null) {
360
+ autoCat.uiState.pageToken = cached.pageToken;
361
+ autoCat.uiState.totalCount = { ...cached.totalCount };
362
+ autoCat.uiState.scrollPosition = cached.scrollPosition;
363
+ autoCat.transactionIdsBySelectedPeriod = {
364
+ ...cached.transactionIdsBySelectedPeriod,
365
+ };
366
+ autoCat.fetchState = cached.fetchState;
367
+ autoCat.error = cached.error;
368
+ }
369
+ else {
370
+ // Sub-tab has never been visited — clear the active slot so the
371
+ // view-epic's `fetchState === 'Not-Started' || transactionIds.length
372
+ // === 0` cache check falls through and triggers a fresh page-1
373
+ // fetch for the new dataset. `scrollPosition` is reset to the top
374
+ // so the incoming list isn't anchored to the outgoing sub-tab's
375
+ // offset (different rows → previous offset is meaningless).
376
+ autoCat.uiState.pageToken = null;
377
+ autoCat.uiState.totalCount = {};
378
+ autoCat.uiState.scrollPosition = {
379
+ scrollTop: 0,
380
+ scrollLeft: undefined,
381
+ };
382
+ autoCat.transactionIdsBySelectedPeriod = {};
383
+ autoCat.fetchState = 'Not-Started';
384
+ autoCat.error = undefined;
385
+ }
386
+ draft.selectedTransactionCategorizationCompletedSubTab = newSubTab;
387
+ },
388
+ prepare(newSubTab) {
389
+ return { payload: { newSubTab } };
390
+ },
391
+ },
270
392
  updateTransactionCategorization: {
271
393
  reducer(draft, action) {
272
394
  const selectedTab = action.payload.selectedTab;
@@ -315,12 +437,9 @@ const expenseAutomationTransactionsView = (0, toolkit_1.createSlice)({
315
437
  const selectedCheckBoxTransactionIds = draft.transactionCategorizationView[selectedTab]
316
438
  .selectedCheckBoxTransactionIds;
317
439
  if (selectedTransaction != null &&
318
- (0, transactionCategorizationLocalDataHelper_1.checkIfAllLineItemsAreCategoryClassFilled)(selectedTransaction, newTransactionLocalData, uncategorizedAccounts, isUncategorizedExpenseCategoryEnabled, isAccountingClassesEnabled) === true && // check if all line items are filled
319
- selectedCheckBoxTransactionIds.length < transactionCategorizationLocalDataHelper_1.MAX_SELECTION_LIMIT &&
320
- selectedCheckBoxTransactionIds.includes(transactionId) === false) {
440
+ (0, transactionCategorizationLocalDataHelper_1.shouldAutoSelectAndAdd)(selectedTransaction, newTransactionLocalData, selectedCheckBoxTransactionIds, uncategorizedAccounts, isUncategorizedExpenseCategoryEnabled, isAccountingClassesEnabled)) {
321
441
  draft.transactionCategorizationView[selectedTab].selectedCheckBoxTransactionIds = [
322
- ...draft.transactionCategorizationView[selectedTab]
323
- .selectedCheckBoxTransactionIds,
442
+ ...selectedCheckBoxTransactionIds,
324
443
  transactionId,
325
444
  ];
326
445
  }
@@ -403,9 +522,26 @@ const expenseAutomationTransactionsView = (0, toolkit_1.createSlice)({
403
522
  const transactionLocalData = (0, get_1.default)(draft.transactionCategorizationView[selectedTab]
404
523
  .transactionReviewLocalDataById, transactionId.id, undefined);
405
524
  if (transactionLocalData != null) {
525
+ const newLocalData = (0, transactionCategorizationLocalDataHelper_1.setEntityRecommendationForLineIdInLocalData)(draft.transactionCategorizationView[selectedTab], transaction, transactionLocalData.transactionReviewLocalData, entity, lineIds, uncategorizedAccounts, action.payload.recommendationWithCOTByLineId, isUncategorizedExpenseCategoryEnabled, isAccountingClassesEnabled);
526
+ // Release the per-line fetch flag for every line this fetch
527
+ // covered. Done in-place on the freshly returned local data
528
+ // (the helper produces a new mutable object), before we write
529
+ // it back to the draft.
530
+ lineIds.forEach((lineId) => {
531
+ const lineItem = newLocalData.lineItemById[lineId];
532
+ if (lineItem != null) {
533
+ newLocalData.lineItemById[lineId] = {
534
+ ...lineItem,
535
+ categoryClassRecommendationsFetchState: {
536
+ fetchState: 'Completed',
537
+ error: undefined,
538
+ },
539
+ };
540
+ }
541
+ });
406
542
  draft.transactionCategorizationView[selectedTab].transactionReviewLocalDataById[transaction.id] = {
407
543
  transactionId: transaction.id,
408
- transactionReviewLocalData: (0, transactionCategorizationLocalDataHelper_1.setEntityRecommendationForLineIdInLocalData)(draft.transactionCategorizationView[selectedTab], transaction, transactionLocalData.transactionReviewLocalData, entity, lineIds, uncategorizedAccounts, action.payload.recommendationWithCOTByLineId, isUncategorizedExpenseCategoryEnabled, isAccountingClassesEnabled),
544
+ transactionReviewLocalData: newLocalData,
409
545
  };
410
546
  // Mark transaction as dirty (autofill happened)
411
547
  if (!draft.transactionCategorizationView[selectedTab].transactionIdsWithUnsavedData.includes(transaction.id)) {
@@ -418,6 +554,99 @@ const expenseAutomationTransactionsView = (0, toolkit_1.createSlice)({
418
554
  }
419
555
  },
420
556
  },
557
+ // Start arm of the line-update recommendations fetch. Flips covered
558
+ // lines to In-Progress AND removes the transaction from
559
+ // selectedCheckBoxTransactionIds — the row is unchecked + disabled
560
+ // until either the success arm (recheck if limit allows) or the
561
+ // failure arm releases the per-line flag.
562
+ markCategoryClassRecommendationsInProgressForCategorization: {
563
+ reducer(draft, action) {
564
+ const { selectedTab, transactionId, lineIds } = action.payload;
565
+ const tab = draft.transactionCategorizationView[selectedTab];
566
+ const transactionLocalData = (0, get_1.default)(tab.transactionReviewLocalDataById, transactionId.id, undefined);
567
+ if (transactionLocalData != null) {
568
+ lineIds.forEach((lineId) => {
569
+ const lineItem = transactionLocalData.transactionReviewLocalData.lineItemById[lineId];
570
+ if (lineItem != null) {
571
+ transactionLocalData.transactionReviewLocalData.lineItemById[lineId] = {
572
+ ...lineItem,
573
+ categoryClassRecommendationsFetchState: {
574
+ fetchState: 'In-Progress',
575
+ error: undefined,
576
+ },
577
+ };
578
+ }
579
+ });
580
+ }
581
+ // Uncheck on fetch start: the row's existing category/class are
582
+ // stale after a payee change, so we drop the auto-selection until
583
+ // fresh recommendations land.
584
+ if (tab.selectedCheckBoxTransactionIds.includes(transactionId.id)) {
585
+ tab.selectedCheckBoxTransactionIds =
586
+ tab.selectedCheckBoxTransactionIds.filter((id) => id !== transactionId.id);
587
+ }
588
+ },
589
+ prepare(selectedTab, transactionId, lineIds) {
590
+ return { payload: { selectedTab, transactionId, lineIds } };
591
+ },
592
+ },
593
+ // Completed arm. Used by the epic when the HTTP call succeeds but the
594
+ // server returned no per-line recommendations — we still need to
595
+ // release the In-Progress flag so the skeleton resolves. Successful
596
+ // responses with recommendations go through
597
+ // setEntityRecommendationForLineIdsForCategorization instead (which
598
+ // also flips the lines to Completed).
599
+ markCategoryClassRecommendationsCompletedForCategorization: {
600
+ reducer(draft, action) {
601
+ const { selectedTab, transactionId, lineIds } = action.payload;
602
+ const transactionLocalData = (0, get_1.default)(draft.transactionCategorizationView[selectedTab]
603
+ .transactionReviewLocalDataById, transactionId.id, undefined);
604
+ if (transactionLocalData != null) {
605
+ lineIds.forEach((lineId) => {
606
+ const lineItem = transactionLocalData.transactionReviewLocalData.lineItemById[lineId];
607
+ if (lineItem != null) {
608
+ transactionLocalData.transactionReviewLocalData.lineItemById[lineId] = {
609
+ ...lineItem,
610
+ categoryClassRecommendationsFetchState: {
611
+ fetchState: 'Completed',
612
+ error: undefined,
613
+ },
614
+ };
615
+ }
616
+ });
617
+ }
618
+ },
619
+ prepare(selectedTab, transactionId, lineIds) {
620
+ return { payload: { selectedTab, transactionId, lineIds } };
621
+ },
622
+ },
623
+ // Failure arm. Flips covered lines to Error so the skeleton resolves
624
+ // and downstream UI can react to the failure. The transaction stays
625
+ // unchecked from the start-arm action.
626
+ markCategoryClassRecommendationsFailureForCategorization: {
627
+ reducer(draft, action) {
628
+ const { selectedTab, transactionId, lineIds, error } = action.payload;
629
+ const transactionLocalData = (0, get_1.default)(draft.transactionCategorizationView[selectedTab]
630
+ .transactionReviewLocalDataById, transactionId.id, undefined);
631
+ if (transactionLocalData != null) {
632
+ lineIds.forEach((lineId) => {
633
+ const lineItem = transactionLocalData.transactionReviewLocalData.lineItemById[lineId];
634
+ if (lineItem != null) {
635
+ transactionLocalData.transactionReviewLocalData.lineItemById[lineId] = {
636
+ ...lineItem,
637
+ categoryClassRecommendationsFetchState: {
638
+ fetchState: 'Error',
639
+ error,
640
+ },
641
+ };
642
+ }
643
+ });
644
+ }
645
+ },
646
+ prepare(selectedTab, transactionId, lineIds, error) {
647
+ return { payload: { selectedTab, transactionId, lineIds, error } };
648
+ },
649
+ },
421
650
  fetchTransactionCategorizationSuccess(draft, action) {
422
651
  const { selectedTab, refreshViewInBackground } = action.payload;
423
652
  if (draft.transactionCategorizationView[selectedTab].fetchState ===
@@ -513,9 +742,7 @@ const expenseAutomationTransactionsView = (0, toolkit_1.createSlice)({
513
742
  .selectedCheckBoxTransactionIds;
514
743
  if (newTransactionLocalData.customer != null &&
515
744
  newTransactionLocalData.customer.id != null &&
516
- (0, transactionCategorizationLocalDataHelper_1.checkIfAllLineItemsAreCategoryClassFilled)(selectedTransaction, newTransactionLocalData, uncategorizedAccounts, isUncategorizedExpenseCategoryEnabled, isAccountingClassesEnabled) === true && // check if all line items are filled
517
- selectedCheckBoxTransactionIds.length < transactionCategorizationLocalDataHelper_1.MAX_SELECTION_LIMIT &&
518
- selectedCheckBoxTransactionIds.includes(transactionId) === false) {
745
+ (0, transactionCategorizationLocalDataHelper_1.shouldAutoSelectAndAdd)(selectedTransaction, newTransactionLocalData, selectedCheckBoxTransactionIds, uncategorizedAccounts, isUncategorizedExpenseCategoryEnabled, isAccountingClassesEnabled)) {
519
746
  draft.transactionCategorizationView[selectedTab].selectedCheckBoxTransactionIds = [
520
747
  ...selectedCheckBoxTransactionIds,
521
748
  transactionId,
@@ -589,9 +816,7 @@ const expenseAutomationTransactionsView = (0, toolkit_1.createSlice)({
589
816
  .selectedCheckBoxTransactionIds;
590
817
  if (newTransactionLocalData.vendor != null &&
591
818
  newTransactionLocalData.vendor.id != null &&
592
- (0, transactionCategorizationLocalDataHelper_1.checkIfAllLineItemsAreCategoryClassFilled)(selectedTransaction, newTransactionLocalData, uncategorizedAccounts, isUncategorizedExpenseCategoryEnabled, isAccountingClassesEnabled) === true && // check if all line items are filled
593
- selectedCheckBoxTransactionIds.length < transactionCategorizationLocalDataHelper_1.MAX_SELECTION_LIMIT &&
594
- selectedCheckBoxTransactionIds.includes(transactionId) === false) {
819
+ (0, transactionCategorizationLocalDataHelper_1.shouldAutoSelectAndAdd)(selectedTransaction, newTransactionLocalData, selectedCheckBoxTransactionIds, uncategorizedAccounts, isUncategorizedExpenseCategoryEnabled, isAccountingClassesEnabled)) {
595
820
  draft.transactionCategorizationView[selectedTab].selectedCheckBoxTransactionIds = [
596
821
  ...selectedCheckBoxTransactionIds,
597
822
  transactionId,
@@ -704,6 +929,10 @@ const expenseAutomationTransactionsView = (0, toolkit_1.createSlice)({
704
929
  const { selectedTab, selectedPeriod, totalCount } = action.payload;
705
930
  draft.transactionCategorizationView[selectedTab].uiState.totalCount[(0, timePeriod_1.toMonthYearPeriodId)(selectedPeriod)] = totalCount;
706
931
  },
932
+ updateParentTotalCountForTab(draft, action) {
933
+ const { selectedTab, selectedPeriod, parentTotalCount } = action.payload;
934
+ draft.parentTotalCountByTab[selectedTab][(0, timePeriod_1.toMonthYearPeriodId)(selectedPeriod)] = parentTotalCount;
935
+ },
707
936
  updateSelectedCheckboxTransactionIds(draft, action) {
708
937
  const selectedTab = action.payload.selectedTab;
709
938
  const transactionIds = action.payload.transactionIds;
@@ -714,6 +943,16 @@ const expenseAutomationTransactionsView = (0, toolkit_1.createSlice)({
714
943
  draft.transactionCategorizationView[selectedTab] = {
715
944
  ...exports.initialTransactionTabViewState,
716
945
  };
946
+ draft.parentTotalCountByTab[selectedTab] = {};
947
+ // The per-sub-tab snapshot cache lives at the slice root and is
948
+ // exclusively populated by the autoCategorized tab's sub-tab switching
949
+ // (see updateTransactionCategorizationCompletedSubTab). When that tab
950
+ // is reset, leaving stale snapshots behind would short-circuit the
951
+ // next sub-tab visit with phantom row IDs / page tokens that no longer
952
+ // correspond to anything in state — drop them in lockstep.
953
+ if (selectedTab === 'autoCategorized') {
954
+ draft.autoCategorizedSubTabCache = {};
955
+ }
717
956
  },
718
957
  clearExpenseAutomationTransactionsView(draft) {
719
958
  Object.assign(draft, exports.initialState);
@@ -810,5 +1049,5 @@ const expenseAutomationTransactionsView = (0, toolkit_1.createSlice)({
810
1049
  },
811
1050
  },
812
1051
  });
813
- _a = expenseAutomationTransactionsView.actions, exports.fetchTransactionCategorization = _a.fetchTransactionCategorization, exports.updateTransactionCategorizationUIState = _a.updateTransactionCategorizationUIState, exports.initializeTransactionCategorizationViewLocalData = _a.initializeTransactionCategorizationViewLocalData, exports.saveTransactionCategorizationLocalData = _a.saveTransactionCategorizationLocalData, exports.fetchTransactionCategorizationFailure = _a.fetchTransactionCategorizationFailure, exports.saveTransactionCategorization = _a.saveTransactionCategorization, exports.updateTransactionCategorization = _a.updateTransactionCategorization, exports.updateCurrentSelectedTransactionCategorizationTab = _a.updateCurrentSelectedTransactionCategorizationTab, exports.updateTransactionCategorizationSaveStatus = _a.updateTransactionCategorizationSaveStatus, exports.markTransactionAsNotMiscategorized = _a.markTransactionAsNotMiscategorized, exports.updateStatusForTransactionNotMiscategorizedUpdateForCategorization = _a.updateStatusForTransactionNotMiscategorizedUpdateForCategorization, exports.updateSelectedVendorForTransaction = _a.updateSelectedVendorForTransaction, exports.updateSelectedCustomerForTransaction = _a.updateSelectedCustomerForTransaction, exports.setAllItemsToCategoryClassInLocalDataForCategorization = _a.setAllItemsToCategoryClassInLocalDataForCategorization, exports.updateTotalCountForTransactionCategorization = _a.updateTotalCountForTransactionCategorization, exports.fetchTransactionCategorizationSuccess = _a.fetchTransactionCategorizationSuccess, exports.resetOtherTabsFetchState = _a.resetOtherTabsFetchState, exports.fetchTransactionCategorizationView = _a.fetchTransactionCategorizationView, exports.updateSelectedCheckboxTransactionIds = _a.updateSelectedCheckboxTransactionIds, exports.clearExpenseAutomationTransactionsViewPerTabView = _a.clearExpenseAutomationTransactionsViewPerTabView, exports.clearExpenseAutomationTransactionsView = _a.clearExpenseAutomationTransactionsView, exports.setEntityRecommendationForLineIdsForCategorization = _a.setEntityRecommendationForLineIdsForCategorization, exports.updateSelectedTransactionId = _a.updateSelectedTransactionId, exports.syncTransactionCategorizationFromDetailSave = _a.syncTransactionCategorizationFromDetailSave, exports.backgroundRefetchReviewTab = _a.backgroundRefetchReviewTab, exports.updateTransactionCategorizationUploadReceiptState = _a.updateTransactionCategorizationUploadReceiptState, exports.uploadTransactionCategorizationReceiptSuccess = _a.uploadTransactionCategorizationReceiptSuccess;
1052
+ _a = expenseAutomationTransactionsView.actions, exports.fetchTransactionCategorization = _a.fetchTransactionCategorization, exports.updateTransactionCategorizationUIState = _a.updateTransactionCategorizationUIState, exports.updateTransactionFilters = _a.updateTransactionFilters, exports.initializeTransactionCategorizationViewLocalData = _a.initializeTransactionCategorizationViewLocalData, exports.saveTransactionCategorizationLocalData = _a.saveTransactionCategorizationLocalData, exports.fetchTransactionCategorizationFailure = _a.fetchTransactionCategorizationFailure, exports.saveTransactionCategorization = _a.saveTransactionCategorization, exports.updateTransactionCategorization = _a.updateTransactionCategorization, exports.updateCurrentSelectedTransactionCategorizationTab = _a.updateCurrentSelectedTransactionCategorizationTab, exports.updateTransactionCategorizationCompletedSubTab = _a.updateTransactionCategorizationCompletedSubTab, exports.updateTransactionCategorizationSaveStatus = _a.updateTransactionCategorizationSaveStatus, exports.markTransactionAsNotMiscategorized = _a.markTransactionAsNotMiscategorized, exports.updateStatusForTransactionNotMiscategorizedUpdateForCategorization = _a.updateStatusForTransactionNotMiscategorizedUpdateForCategorization, exports.updateSelectedVendorForTransaction = _a.updateSelectedVendorForTransaction, exports.updateSelectedCustomerForTransaction = _a.updateSelectedCustomerForTransaction, exports.setAllItemsToCategoryClassInLocalDataForCategorization = _a.setAllItemsToCategoryClassInLocalDataForCategorization, exports.updateTotalCountForTransactionCategorization = _a.updateTotalCountForTransactionCategorization, exports.updateParentTotalCountForTab = _a.updateParentTotalCountForTab, exports.fetchTransactionCategorizationSuccess = _a.fetchTransactionCategorizationSuccess, exports.resetOtherTabsFetchState = _a.resetOtherTabsFetchState, exports.fetchTransactionCategorizationView = _a.fetchTransactionCategorizationView, exports.updateSelectedCheckboxTransactionIds = _a.updateSelectedCheckboxTransactionIds, exports.clearExpenseAutomationTransactionsViewPerTabView = _a.clearExpenseAutomationTransactionsViewPerTabView, exports.clearExpenseAutomationTransactionsView = _a.clearExpenseAutomationTransactionsView, exports.setEntityRecommendationForLineIdsForCategorization = _a.setEntityRecommendationForLineIdsForCategorization, exports.markCategoryClassRecommendationsInProgressForCategorization = _a.markCategoryClassRecommendationsInProgressForCategorization, exports.markCategoryClassRecommendationsCompletedForCategorization = _a.markCategoryClassRecommendationsCompletedForCategorization, exports.markCategoryClassRecommendationsFailureForCategorization = _a.markCategoryClassRecommendationsFailureForCategorization, exports.updateSelectedTransactionId = _a.updateSelectedTransactionId, exports.syncTransactionCategorizationFromDetailSave = _a.syncTransactionCategorizationFromDetailSave, exports.backgroundRefetchReviewTab = _a.backgroundRefetchReviewTab, exports.updateTransactionCategorizationUploadReceiptState = _a.updateTransactionCategorizationUploadReceiptState, exports.uploadTransactionCategorizationReceiptSuccess = _a.uploadTransactionCategorizationReceiptSuccess;
814
1053
  exports.default = expenseAutomationTransactionsView.reducer;
@@ -2,7 +2,8 @@ import { CompletionStatusType, FetchStateAndError, ID } from '../../../commonSta
2
2
  import { SortOrder } from '../../../commonStateTypes/selectorTypes/sortOrderTypes';
3
3
  import { SelectorView } from '../../../commonStateTypes/viewAndReport/viewAndReport';
4
4
  import { SupportedTransaction } from '../../../entity/transaction/transactionState';
5
- import type { BatchFileStatus, BatchListItem, BatchStatus, BulkUploadPhase, BulkUploadResultsTab, BulkUploadSortKey, CompletedSubTab, ManualSearchState, MatchSource, MissingReceiptsViewUIState } from '../types/missingReceiptsViewState';
5
+ import type { CompletedSubTab } from '../types/completedSubTab';
6
+ import type { BatchFileStatus, BatchListItem, BatchStatus, BulkUploadPhase, BulkUploadResultsTab, BulkUploadSortKey, ManualSearchState, MatchSource, MissingReceiptsViewUIState } from '../types/missingReceiptsViewState';
6
7
  export interface CompletedTransactionsSelectorData {
7
8
  fetchState: FetchStateAndError;
8
9
  nextPageToken: string | null;
@@ -7,6 +7,7 @@ import { ClassBase } from '../../../entity/class/classState';
7
7
  import { SupportedTransactionWithCOT } from '../../../entity/transaction/transactionState';
8
8
  import { UncategorizedAccounts } from '../../accountList/accountListSelector';
9
9
  import { ProjectListSelectorView } from '../../projectList/projectListSelector';
10
+ import { CompletedSubTab } from '../types/completedSubTab';
10
11
  import { TransactionReviewLocalData, TransactionsTab, TransactionsViewUIState } from '../types/transactionsViewState';
11
12
  export interface TransactionReviewLocalDataSelectorView {
12
13
  transactionId: ID;
@@ -19,12 +20,27 @@ export interface ExpenseAutomationTransactionViewSelector extends SelectorView {
19
20
  classList: ClassBase[];
20
21
  completionStatus: CompletionStatusType;
21
22
  fetchStateByTransactionTabs: Record<TransactionsTab, FetchStateAndError>;
23
+ hasInFlightCategoryClassRecommendations: boolean;
24
+ inFlightCategoryClassRecommendationsByTransactionId: Record<ID, boolean>;
22
25
  isAccountingProjectsEnabled: boolean;
23
26
  markAsNotMiscategorizedStatus: FetchStateAndError;
27
+ /**
28
+ * Parent tab badge counts, sourced from the listing response's
29
+ * `parent_tab_total_count`. Used exclusively to drive the navbar / tab
30
+ * strip badge labels — every other count consumer (pagination, in-list
31
+ * "showing X of Y", save flows) keeps reading {@link totalCountByTab}.
32
+ */
33
+ parentTabTotalCountByTab: Record<TransactionsTab, number>;
24
34
  projectList: ProjectListSelectorView;
25
35
  refreshStatus: FetchStateAndError;
26
36
  saveStatus: FetchStateAndError;
27
37
  selectedCheckBoxTransactionIds: ID[];
38
+ selectedTransactionCategorizationCompletedSubTab: CompletedSubTab;
39
+ /**
40
+ * Per-(sub-)tab counts mirroring `total_count` from the listing response.
41
+ * Powers pagination via `InfiniteLoader.itemCount`, in-list count copy,
42
+ * and the `resetTransactionCategorizationLocalData` round-trip.
43
+ */
28
44
  totalCountByTab: Record<TransactionsTab, number>;
29
45
  transactionIdsWithUnsavedData: ID[];
30
46
  transactionLocalData: TransactionReviewLocalDataSelectorView[];