@zeniai/client-epic-state 5.1.18-betaDI11 → 5.1.18-betaDI12
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.
- package/README.md +3 -1
- package/lib/commonStateTypes/viewAndReport/agingReportStateTypes.d.ts +1 -1
- package/lib/entity/accountRecon/accountReconPayload.d.ts +22 -0
- package/lib/entity/accountRecon/accountReconPayload.js +26 -1
- package/lib/entity/accountRecon/accountReconReducer.d.ts +5 -2
- package/lib/entity/accountRecon/accountReconReducer.js +36 -2
- package/lib/entity/accountRecon/accountReconSelector.d.ts +6 -1
- package/lib/entity/accountRecon/accountReconSelector.js +5 -0
- package/lib/entity/accountRecon/accountReconState.d.ts +22 -0
- package/lib/entity/monthEndCloseChecks/monthEndCloseChecksPayload.d.ts +8 -0
- package/lib/entity/monthEndCloseChecks/monthEndCloseChecksPayload.js +10 -0
- package/lib/entity/monthEndCloseChecks/monthEndCloseChecksState.d.ts +8 -0
- package/lib/entity/task/taskReducer.js +3 -0
- package/lib/entity/task/taskState.d.ts +1 -1
- package/lib/entity/transaction/payloadTypes/transactionPayload.d.ts +1 -0
- package/lib/entity/transaction/payloadTypes/transactionPayload.js +5 -0
- package/lib/entity/transaction/stateTypes/transaction.d.ts +1 -0
- package/lib/epic.d.ts +7 -2
- package/lib/epic.js +7 -2
- package/lib/esm/entity/accountRecon/accountReconPayload.js +26 -1
- package/lib/esm/entity/accountRecon/accountReconReducer.js +35 -1
- package/lib/esm/entity/accountRecon/accountReconSelector.js +5 -0
- package/lib/esm/entity/monthEndCloseChecks/monthEndCloseChecksPayload.js +10 -0
- package/lib/esm/entity/task/taskReducer.js +3 -0
- package/lib/esm/entity/transaction/payloadTypes/transactionPayload.js +5 -0
- package/lib/esm/epic.js +7 -2
- package/lib/esm/index.js +9 -9
- package/lib/esm/view/aiCfoView/aiCfoViewReducer.js +29 -3
- package/lib/esm/view/aiCfoView/aiCfoViewSelector.js +11 -0
- package/lib/esm/view/aiCfoView/epics/createSessionAndSubmitEpic.js +2 -2
- package/lib/esm/view/aiCfoView/epics/fetchSkillsEpic.js +34 -0
- package/lib/esm/view/aiCfoView/epics/submitQuestionEpic.js +7 -1
- package/lib/esm/view/expenseAutomationView/epics/accountRecon/parseStatementEpic.js +34 -0
- package/lib/esm/view/expenseAutomationView/epics/accountRecon/reparseStatementEpic.js +31 -0
- package/lib/esm/view/expenseAutomationView/epics/accountRecon/updateStatementInfoEpic.js +57 -0
- package/lib/esm/view/expenseAutomationView/epics/fluxAnalysis/fetchFluxAnalysisViewEpic.js +1 -0
- package/lib/esm/view/expenseAutomationView/epics/transactionCategorization/fetchTransactionCategorizationEpic.js +49 -11
- package/lib/esm/view/expenseAutomationView/epics/transactionCategorization/fetchTransactionCategorizationViewEpic.js +30 -3
- package/lib/esm/view/expenseAutomationView/payload/reconciliationPayload.js +153 -0
- package/lib/esm/view/expenseAutomationView/reducers/fluxAnalysisViewReducer.js +6 -1
- package/lib/esm/view/expenseAutomationView/reducers/reconciliationViewReducer.js +188 -9
- package/lib/esm/view/expenseAutomationView/reducers/transactionsViewReducer.js +37 -17
- package/lib/esm/view/expenseAutomationView/selectors/fluxAnalysisViewSelector.js +2 -1
- package/lib/esm/view/expenseAutomationView/selectors/reconciliationViewSelector.js +27 -0
- package/lib/esm/view/expenseAutomationView/types/reconciliationViewState.js +29 -0
- package/lib/esm/view/onboardingView/cockpitView/epic/initializeOnboardingCustomerViewUpdateDataEpic.js +4 -16
- package/lib/esm/view/onboardingView/cockpitView/onboardingCockpitViewPayload.js +2 -2
- package/lib/esm/view/opExByVendor/opExByVendorReducer.js +28 -5
- package/lib/esm/view/opExByVendor/opExByVendorSelector.js +1 -0
- package/lib/esm/view/opExByVendor/refreshOpExByVendorReportEpic.js +21 -0
- package/lib/esm/view/referralView/epics/sendReferralInviteEpic.js +9 -1
- package/lib/esm/view/referralView/referralReducer.js +3 -2
- package/lib/esm/view/spendManagement/commonSetup/setupViewReducer.js +5 -1
- package/lib/esm/view/taskManager/taskDetailView/epics/saveTaskDetailEpic.js +2 -2
- package/lib/esm/view/taskManager/taskDetailView/epics/sendCommentMentionNotificationEpic.js +2 -2
- package/lib/esm/view/taskManager/taskDetailView/taskDetailSelector.js +1 -1
- package/lib/esm/view/taskManager/taskListView/taskListReducer.js +3 -1
- package/lib/esm/view/transactionDetail/epics/saveTransactionDetailEpic.js +3 -1
- package/lib/esm/view/transactionDetail/epics/saveTransactionHelper.js +11 -2
- package/lib/esm/view/transactionDetail/epics/updateTransactionDetailEpic.js +34 -5
- package/lib/esm/view/transactionDetail/transactionDetailLocalDataHelper.js +17 -0
- package/lib/index.d.ts +14 -14
- package/lib/index.js +57 -37
- package/lib/view/aiCfoView/aiCfoViewPayload.d.ts +14 -0
- package/lib/view/aiCfoView/aiCfoViewReducer.d.ts +8 -4
- package/lib/view/aiCfoView/aiCfoViewReducer.js +30 -4
- package/lib/view/aiCfoView/aiCfoViewSelector.d.ts +2 -1
- package/lib/view/aiCfoView/aiCfoViewSelector.js +12 -0
- package/lib/view/aiCfoView/aiCfoViewState.d.ts +15 -0
- package/lib/view/aiCfoView/epics/createSessionAndSubmitEpic.js +2 -2
- package/lib/view/aiCfoView/epics/fetchSkillsEpic.d.ts +8 -0
- package/lib/view/aiCfoView/epics/fetchSkillsEpic.js +38 -0
- package/lib/view/aiCfoView/epics/submitQuestionEpic.js +7 -1
- package/lib/view/expenseAutomationView/epics/accountRecon/parseStatementEpic.d.ts +6 -0
- package/lib/view/expenseAutomationView/epics/accountRecon/parseStatementEpic.js +38 -0
- package/lib/view/expenseAutomationView/epics/accountRecon/reparseStatementEpic.d.ts +26 -0
- package/lib/view/expenseAutomationView/epics/accountRecon/reparseStatementEpic.js +35 -0
- package/lib/view/expenseAutomationView/epics/accountRecon/updateStatementInfoEpic.d.ts +27 -0
- package/lib/view/expenseAutomationView/epics/accountRecon/updateStatementInfoEpic.js +61 -0
- package/lib/view/expenseAutomationView/epics/fluxAnalysis/fetchFluxAnalysisViewEpic.js +1 -0
- package/lib/view/expenseAutomationView/epics/transactionCategorization/fetchTransactionCategorizationEpic.js +47 -9
- package/lib/view/expenseAutomationView/epics/transactionCategorization/fetchTransactionCategorizationViewEpic.js +30 -3
- package/lib/view/expenseAutomationView/payload/fluxAnalysisPayload.d.ts +8 -0
- package/lib/view/expenseAutomationView/payload/reconciliationPayload.d.ts +176 -10
- package/lib/view/expenseAutomationView/payload/reconciliationPayload.js +159 -0
- package/lib/view/expenseAutomationView/payload/transactionCategorizationPayload.d.ts +7 -0
- package/lib/view/expenseAutomationView/reducers/fluxAnalysisViewReducer.d.ts +2 -1
- package/lib/view/expenseAutomationView/reducers/fluxAnalysisViewReducer.js +6 -1
- package/lib/view/expenseAutomationView/reducers/reconciliationViewReducer.d.ts +53 -3
- package/lib/view/expenseAutomationView/reducers/reconciliationViewReducer.js +190 -10
- package/lib/view/expenseAutomationView/reducers/transactionsViewReducer.js +37 -17
- package/lib/view/expenseAutomationView/selectorTypes/reconciliationViewSelectorTypes.d.ts +7 -1
- package/lib/view/expenseAutomationView/selectors/fluxAnalysisViewSelector.js +2 -1
- package/lib/view/expenseAutomationView/selectors/reconciliationViewSelector.d.ts +2 -0
- package/lib/view/expenseAutomationView/selectors/reconciliationViewSelector.js +29 -1
- package/lib/view/expenseAutomationView/types/fluxAnalysisViewState.d.ts +2 -0
- package/lib/view/expenseAutomationView/types/reconciliationViewState.d.ts +175 -0
- package/lib/view/expenseAutomationView/types/reconciliationViewState.js +30 -0
- package/lib/view/onboardingView/cockpitView/epic/initializeOnboardingCustomerViewUpdateDataEpic.js +3 -15
- package/lib/view/onboardingView/cockpitView/onboardingCockpitViewPayload.js +2 -2
- package/lib/view/opExByVendor/opExByVendorReducer.d.ts +6 -1
- package/lib/view/opExByVendor/opExByVendorReducer.js +29 -6
- package/lib/view/opExByVendor/opExByVendorSelector.d.ts +1 -0
- package/lib/view/opExByVendor/opExByVendorSelector.js +1 -0
- package/lib/view/opExByVendor/opExByVendorState.d.ts +1 -0
- package/lib/view/opExByVendor/refreshOpExByVendorReportEpic.d.ts +17 -0
- package/lib/view/opExByVendor/refreshOpExByVendorReportEpic.js +25 -0
- package/lib/view/referralView/epics/sendReferralInviteEpic.js +9 -1
- package/lib/view/referralView/referralReducer.d.ts +1 -0
- package/lib/view/referralView/referralReducer.js +4 -3
- package/lib/view/spendManagement/commonSetup/setupViewReducer.js +5 -1
- package/lib/view/taskManager/taskDetailView/epics/saveTaskDetailEpic.js +2 -2
- package/lib/view/taskManager/taskDetailView/epics/sendCommentMentionNotificationEpic.d.ts +1 -1
- package/lib/view/taskManager/taskDetailView/epics/sendCommentMentionNotificationEpic.js +1 -1
- package/lib/view/taskManager/taskDetailView/taskDetail.d.ts +1 -1
- package/lib/view/taskManager/taskDetailView/taskDetailSelector.js +1 -1
- package/lib/view/taskManager/taskListView/taskListReducer.js +3 -1
- package/lib/view/transactionDetail/epics/saveTransactionDetailEpic.js +3 -1
- package/lib/view/transactionDetail/epics/saveTransactionHelper.d.ts +1 -1
- package/lib/view/transactionDetail/epics/saveTransactionHelper.js +11 -2
- package/lib/view/transactionDetail/epics/updateTransactionDetailEpic.d.ts +8 -0
- package/lib/view/transactionDetail/epics/updateTransactionDetailEpic.js +36 -6
- package/lib/view/transactionDetail/transactionDetailLocalDataHelper.js +17 -0
- package/lib/view/transactionDetail/transactionDetailState.d.ts +1 -0
- package/lib/view/transactionDetail/transactionDetailTypes.d.ts +1 -0
- package/lib/view/vendorFiling1099/vendorFiling1099List/vendorFiling1099ListState.d.ts +1 -1
- package/package.json +5 -2
package/lib/esm/index.js
CHANGED
|
@@ -173,10 +173,10 @@ import { MAX_SELECTION_LIMIT, checkIfAllLineItemsAreCategoryClassFilled, getLine
|
|
|
173
173
|
import { clearExpenseAutomationFluxAnalysisView, fetchFluxAnalysisView, reviewFluxAnalysisView, updateFluxAnalysisViewPageMetaData, updateFluxAnalysisViewUIState, updateOperatingExpensesIdsForReview, updateSelectedSectionIdsForReview, } from './view/expenseAutomationView/reducers/fluxAnalysisViewReducer';
|
|
174
174
|
import { clearJeScheduleLocalData as clearExpenseAutomationJEScheduleLocalData, clearExpenseAutomationJESchedulesView, fetchJeSchedulesPage as fetchExpenseAutomationJESchedulesPage, ignoreRecommendedJeSchedule as ignoreExpenseAutomationJESchedule, initializeAccountSettingsView as initializeJeAccountSettingsView, initializeJeScheduleLocalData, removeJeScheduleTransactionKey, retryJeSchedule as retryExpenseAutomationJESchedule, saveAccountSettings as saveJeAccountSettings, saveAccountSettingsLocalData as saveJeAccountSettingsLocalData, updateJESchedulesUIState as updateExpenseAutomationJESchedulesUIState, updateJeScheduleLocalDataById, updateJeScheduleTransactionKeys, } from './view/expenseAutomationView/reducers/jeSchedulesViewReducer';
|
|
175
175
|
import { acknowledgeBulkUploadConfirmMatchComplete, bulkUploadAutomatchingTimedOut, bulkUploadReceipts, bulkUploadReceiptsFailure, bulkUploadReceiptsSuccess, clearBulkUpload, clearBulkUploadBatchDetailsForScopeChange, clearManualSearchResults, clearMissingReceiptsTabNavigation, confirmBulkUploadMatch, confirmBulkUploadMatchFailure, confirmBulkUploadMatchSuccess, fetchBulkUploadBatchDetails, fetchBulkUploadBatchDetailsFailure, fetchBulkUploadBatchDetailsSuccess, fetchBulkUploadBatches, fetchBulkUploadBatchesFailure, fetchBulkUploadBatchesSuccess, fetchCompletedTransactions, fetchCompletedTransactionsFailure, fetchCompletedTransactionsSuccess, fetchMissingReceipts as fetchExpenseAutomationMissingReceipts, fetchMoreBatchDetails, fetchMoreBatchDetailsComplete, fetchMoreBatchDetailsFailure, markBatchDetailRefreshAttempted, markMissingReceiptAsDone as markExpenseAutomationMissingReceiptAsDone, pusherBatchStatusUpdate, refreshBatchDetailsForBatchId, requestMissingReceiptsTabNavigation, restoreBulkUploadAutomatchingOnMount, restoreBulkUploadMatchingState, searchTransactionsForManualMatch, searchTransactionsForManualMatchFailure, searchTransactionsForManualMatchSuccess, setBulkUploadCompletedSubTab, setBulkUploadResultsTab, setBulkUploadSortConfig, setBulkUploadUploadedFileCount, storeBatchDetails, updateBulkUploadProgress, updateMissingReceiptUploadState as updateExpenseAutomationMissingReceiptUploadState, updateMissingReceiptsUIState as updateExpenseAutomationMissingReceiptsUIState, uploadMissingReceiptSuccess as uploadExpenseAutomationMissingReceiptSuccess, } from './view/expenseAutomationView/reducers/missingReceiptsViewReducer';
|
|
176
|
-
import { deleteAccountStatement, excludeAccountFromReconciliation, fetchReconciliation as fetchReconciliationView, includeAccountInReconciliation, saveReconciliationDetail as saveExpenseAutomationReconciliationDetail, saveReconciliationReview as saveExpenseAutomationReconciliationReview, setConnectionInProgressForAccount as setConnectionInProgressForAccountReconciliation, setStatementParseInProgress, updateAccountReconciliationLocalData as updateExpenseAutomationAccountReconciliationLocalData, updateSelectedAccountId as updateExpenseAutomationAccountReconciliationSelectedAccountId, updateSelectedTab as updateExpenseAutomationAccountReconciliationSelectedTab, updateReconListScrollPosition as updateExpenseAutomationReconListScrollPosition, updateReviewTabSortState as updateExpenseAutomationReconReviewTabListSortState, updateReviewTabLocalData as updateExpenseAutomationReconReviewTabLocalData, updateReconcileTabListScrollState as updateExpenseAutomationReconcileTabListScrollState, updateReconcileTabListSortState as updateExpenseAutomationReconcileTabListSortState, updateReconcileTabLocalData as updateExpenseAutomationReconcileTabLocalData, updateSelectedDrawerAccountId as updateExpenseAutomationSelectedDrawerAccountId, updateNodeCollapseState, updateStatementUploadChosen, uploadAccountStatement, } from './view/expenseAutomationView/reducers/reconciliationViewReducer';
|
|
176
|
+
import { clearStatementDateConflict, deleteAccountStatement, excludeAccountFromReconciliation, fetchReconciliation as fetchReconciliationView, includeAccountInReconciliation, parseStatement, parseStatementFailure, parseStatementSuccess, reparseStatement, reparseStatementFailure, reparseStatementSuccess, resetReparseStatementStatus, saveReconciliationDetail as saveExpenseAutomationReconciliationDetail, saveReconciliationReview as saveExpenseAutomationReconciliationReview, setConnectionInProgressForAccount as setConnectionInProgressForAccountReconciliation, setStatementParseInProgress, submitStatementUpdate, updateAccountReconciliationLocalData as updateExpenseAutomationAccountReconciliationLocalData, updateSelectedAccountId as updateExpenseAutomationAccountReconciliationSelectedAccountId, updateSelectedTab as updateExpenseAutomationAccountReconciliationSelectedTab, updateReconListScrollPosition as updateExpenseAutomationReconListScrollPosition, updateReviewTabSortState as updateExpenseAutomationReconReviewTabListSortState, updateReviewTabLocalData as updateExpenseAutomationReconReviewTabLocalData, updateReconcileTabListScrollState as updateExpenseAutomationReconcileTabListScrollState, updateReconcileTabListSortState as updateExpenseAutomationReconcileTabListSortState, updateReconcileTabLocalData as updateExpenseAutomationReconcileTabLocalData, updateSelectedDrawerAccountId as updateExpenseAutomationSelectedDrawerAccountId, updateNodeCollapseState, updateParsedStatementData, updateStatementProcessingFailed, updateStatementUpdateLocalData, updateStatementUploadChosen, uploadAccountStatement, } from './view/expenseAutomationView/reducers/reconciliationViewReducer';
|
|
177
177
|
import { backgroundRefetchReviewTab, clearExpenseAutomationTransactionsView, fetchTransactionCategorization, fetchTransactionCategorizationFailure, fetchTransactionCategorizationView, initializeTransactionCategorizationViewLocalData, markCategoryClassRecommendationsFailureForCategorization, markTransactionAsNotMiscategorized, removeTransactionFromAllTabs, saveTransactionCategorization, saveTransactionCategorizationLocalData, setAllItemsToCategoryClassInLocalDataForCategorization, setEntityRecommendationForLineIdsForCategorization, syncTransactionCategorizationFromDetailSave, updateCurrentSelectedTransactionCategorizationTab, updateSelectedCheckboxTransactionIds, updateSelectedCustomerForTransaction, updateSelectedTransactionId, updateSelectedVendorForTransaction, updateTransactionCategorization, updateTransactionCategorizationCompletedSubTab, updateTransactionCategorizationSaveStatus, updateTransactionCategorizationUIState, updateTransactionCategorizationUploadReceiptState, updateTransactionFilters, uploadTransactionCategorizationReceiptSuccess, } from './view/expenseAutomationView/reducers/transactionsViewReducer';
|
|
178
178
|
import { getExpenseAutomationFluxAnalysisView } from './view/expenseAutomationView/selectors/fluxAnalysisViewSelector';
|
|
179
|
-
import { getExpenseAutomationReconciliationView, isAccountReconReport, } from './view/expenseAutomationView/selectors/reconciliationViewSelector';
|
|
179
|
+
import { getExpenseAutomationReconciliationView, getReparseStatementStatusByAccountId, isAccountReconReport, } from './view/expenseAutomationView/selectors/reconciliationViewSelector';
|
|
180
180
|
import { getExpenseAutomationTransactionView, getLastTransferEntryReplacement, } from './view/expenseAutomationView/selectors/transactionCategorizationSelector';
|
|
181
181
|
import { TRANSACTION_FILTER_CATEGORIES, applyTransactionFilters, } from './view/expenseAutomationView/transactionFilterHelpers';
|
|
182
182
|
import { DEFAULT_COMPLETED_SUB_TAB, toCompletedSubTab, } from './view/expenseAutomationView/types/completedSubTab';
|
|
@@ -221,7 +221,7 @@ import { getAiAgentsActivationCounts, getAiAgentsActivationPhases, getAiAgentsAc
|
|
|
221
221
|
import { ALL_ONBOARDING_STEPS, ALL_ONBOARDING_SUB_STEPS, toOnboardingStepType, toOnboardingSubStepType, } from './view/onboardingView/customerView/onboardingCustomerViewState';
|
|
222
222
|
import { fetchOpEx, fetchOpExWithForecast, updateOpExCOABalancesRange, updateOpExDownloadState, updateOpExUIState, } from './view/opEx/opExReducer';
|
|
223
223
|
import { getOperatingExpensesForHighlightedRange, getOperatingExpensesForSelectedRange, getOperatingExpensesReport, getOperatingExpensesReportFetchState, getOperatingExpensesUIState, } from './view/opEx/opExSelector';
|
|
224
|
-
import { clearOpExByVendorSearch, fetchOpExByVendor, fetchOpExByVendorReportForTimeframe, updateOpExByVendorAdditionalBalancesSelection, updateOpExByVendorDownloadState, updateOpExByVendorPageFetchInProgress, updateOpExByVendorPageLimit, updateOpExByVendorSearchString, updateOpExByVendorSort, updateOpExByVendorSortOrSearchInProgress, updateOpExByVendorTimeFrame, updateOpExByVendorUIState, } from './view/opExByVendor/opExByVendorReducer';
|
|
224
|
+
import { clearOpExByVendorSearch, fetchOpExByVendor, fetchOpExByVendorReportForTimeframe, refreshOpExByVendorReport, updateOpExByVendorAdditionalBalancesSelection, updateOpExByVendorDownloadState, updateOpExByVendorPageFetchInProgress, updateOpExByVendorPageLimit, updateOpExByVendorSearchString, updateOpExByVendorSort, updateOpExByVendorSortOrSearchInProgress, updateOpExByVendorTimeFrame, updateOpExByVendorUIState, } from './view/opExByVendor/opExByVendorReducer';
|
|
225
225
|
import { getOpExByVendorReport, getOpExByVendorUIState, getOpexVendorTimeframeKey, isOpexByVendorIDNotSpecifiedVendor, } from './view/opExByVendor/opExByVendorSelector';
|
|
226
226
|
import { toOpexByVendorSortKeyType, } from './view/opExByVendor/opExByVendorState';
|
|
227
227
|
import { fetchOpExClassesView, updateAccountViewMode as updateOpExAccountViewMode, updateClassesToFilterOut as updateOpExClassesToFilterOut, updateOpExClassesViewUIState, } from './view/opExClassesView/opExClassesViewReducer';
|
|
@@ -244,7 +244,7 @@ import { getProfitAndLossProjectView } from './view/profitAndLossProjectView/pro
|
|
|
244
244
|
import { fetchProjectList } from './view/projectList/projectListReducer';
|
|
245
245
|
import { getProjectList, } from './view/projectList/projectListSelector';
|
|
246
246
|
import { fetchEntityRecommendationsByTransactionId, fetchEntityRecommendationsForLineUpdate, fetchRecommendationByEntityId, fetchRecommendationByEntityName, } from './view/recommendation/recommendationReducer';
|
|
247
|
-
import { clearReferrals, fetchReferrals, fetchRewardsPlan, resendReferralInvite, saveReferralFormDataInLocalStore, sendReferralInvite, updateReferViewed, updateReferralListSortUiState, } from './view/referralView/referralReducer';
|
|
247
|
+
import { DEFAULT_REFERRER_AMOUNT, clearReferrals, fetchReferrals, fetchRewardsPlan, resendReferralInvite, saveReferralFormDataInLocalStore, sendReferralInvite, updateReferViewed, updateReferralListSortUiState, } from './view/referralView/referralReducer';
|
|
248
248
|
import { getInviteFormView, getReferralListView, getRewardsPlanCard, } from './view/referralView/referralSelector';
|
|
249
249
|
import { AmountStatusTypes, StatusTypes, toReferralListViewSortKeyType, } from './view/referralView/referralState';
|
|
250
250
|
import { fetchReimbursementCard } from './view/reimbursementCard/reimbursementCardReducer';
|
|
@@ -462,7 +462,7 @@ export {
|
|
|
462
462
|
// Bulk Upload Types
|
|
463
463
|
BATCH_FILE_STATUSES, isUnmatchedTabFileStatus, DEFAULT_COMPLETED_SUB_TAB, toBatchFileStatus, toBatchStatusValue, toBulkUploadPhase, toBulkUploadResultsTab, toBulkUploadSortKey, toCompletedSubTab, toMatchSource, toMissingReceiptsTab, toExpenseAutomationJEScheduleMainTab, toExpenseAutomationJEScheduleSortKey, getExpenseAutomationView, toExpenseAutomationMissingReceiptsSortKey, toExpenseAutomationTransactionsTabKey, toExpenseAutomationViewType, uploadExpenseAutomationMissingReceiptSuccess, markExpenseAutomationMissingReceiptAsDone, fetchAllExpenseAutomationTabs, refreshExpenseAutomationCurrentTab, updateCurrentSelectedTransactionCategorizationTab, updateTransactionCategorizationCompletedSubTab, fetchExpenseAutomationMissingReceipts,
|
|
464
464
|
// Bulk Upload Actions
|
|
465
|
-
bulkUploadReceipts, bulkUploadAutomatchingTimedOut, bulkUploadReceiptsSuccess, bulkUploadReceiptsFailure, restoreBulkUploadAutomatchingOnMount, restoreBulkUploadMatchingState, updateBulkUploadProgress, pusherBatchStatusUpdate, requestMissingReceiptsTabNavigation, clearMissingReceiptsTabNavigation, fetchBulkUploadBatchDetails, fetchBulkUploadBatchDetailsSuccess, fetchBulkUploadBatchDetailsFailure, storeBatchDetails, fetchMoreBatchDetails, fetchMoreBatchDetailsComplete, fetchMoreBatchDetailsFailure, fetchBulkUploadBatches, fetchBulkUploadBatchesSuccess, fetchBulkUploadBatchesFailure, clearBulkUploadBatchDetailsForScopeChange, markBatchDetailRefreshAttempted, refreshBatchDetailsForBatchId, confirmBulkUploadMatch, confirmBulkUploadMatchSuccess, confirmBulkUploadMatchFailure, setBulkUploadResultsTab, setBulkUploadCompletedSubTab, setBulkUploadSortConfig, setBulkUploadUploadedFileCount, clearBulkUpload, searchTransactionsForManualMatch, searchTransactionsForManualMatchSuccess, searchTransactionsForManualMatchFailure, clearManualSearchResults, acknowledgeBulkUploadConfirmMatchComplete, fetchCompletedTransactions, fetchCompletedTransactionsSuccess, fetchCompletedTransactionsFailure, fetchFluxAnalysisView, clearExpenseAutomationFluxAnalysisView, updateOperatingExpensesIdsForReview as updateFluxOperatingExpensesIdsForReview, updateSelectedSectionIdsForReview as updateFluxAnalysisSelectedSectionIdsForReview, reviewFluxAnalysisView, updateExpenseAutomationMissingReceiptUploadState, updateExpenseAutomationMissingReceiptsUIState, updateTransactionCategorizationUploadReceiptState, uploadTransactionCategorizationReceiptSuccess, getExpenseAutomationFluxAnalysisView, updateCurrentSelectedView, updateCurrentSelectedPeriod, getExpenseAutomationTransactionView, getLastTransferEntryReplacement, updateFluxAnalysisViewUIState, updateFluxAnalysisViewPageMetaData, MAX_SELECTION_LIMIT, checkIfAllLineItemsAreCategoryClassFilled, getLineItemsByTransactionIdsFromLocalData, isAnyItemWithUncategorizedExpenseAccount, excludeAccountFromReconciliation, includeAccountInReconciliation, saveExpenseAutomationReconciliationDetail, updateExpenseAutomationReconcileTabListScrollState, updateExpenseAutomationReconReviewTabListSortState, updateExpenseAutomationReconcileTabListSortState, updateExpenseAutomationReconcileTabLocalData, updateExpenseAutomationAccountReconciliationSelectedTab, updateExpenseAutomationAccountReconciliationSelectedAccountId, getExpenseAutomationReconciliationView, fetchReconciliationView, uploadAccountStatementIntoDocumentAI, updateExpenseAutomationReconListScrollPosition, setConnectionInProgressForAccountReconciliation, getAccountReconByAccountIdAndSelectedPeriod, toReconciliationTabsType, isAccountReconReport, updateExpenseAutomationReconReviewTabLocalData, updateExpenseAutomationSelectedDrawerAccountId, saveExpenseAutomationReconciliationReview, updateExpenseAutomationAccountReconciliationLocalData, toReconciliationAccountSource, deleteAccountStatement, uploadAccountStatement, updateNodeCollapseState, updateStatementUploadChosen, isReviewTransactionBankTransferType, isReviewTransactionBillPaymentType, isReviewTransactionCreditCardPaymentType, isReviewTransactionDepositType, isReviewTransactionExpenseType, isReviewTransactionCreditCardCreditType, setStatementParseInProgress, };
|
|
465
|
+
bulkUploadReceipts, bulkUploadAutomatchingTimedOut, bulkUploadReceiptsSuccess, bulkUploadReceiptsFailure, restoreBulkUploadAutomatchingOnMount, restoreBulkUploadMatchingState, updateBulkUploadProgress, pusherBatchStatusUpdate, requestMissingReceiptsTabNavigation, clearMissingReceiptsTabNavigation, fetchBulkUploadBatchDetails, fetchBulkUploadBatchDetailsSuccess, fetchBulkUploadBatchDetailsFailure, storeBatchDetails, fetchMoreBatchDetails, fetchMoreBatchDetailsComplete, fetchMoreBatchDetailsFailure, fetchBulkUploadBatches, fetchBulkUploadBatchesSuccess, fetchBulkUploadBatchesFailure, clearBulkUploadBatchDetailsForScopeChange, markBatchDetailRefreshAttempted, refreshBatchDetailsForBatchId, confirmBulkUploadMatch, confirmBulkUploadMatchSuccess, confirmBulkUploadMatchFailure, setBulkUploadResultsTab, setBulkUploadCompletedSubTab, setBulkUploadSortConfig, setBulkUploadUploadedFileCount, clearBulkUpload, searchTransactionsForManualMatch, searchTransactionsForManualMatchSuccess, searchTransactionsForManualMatchFailure, clearManualSearchResults, acknowledgeBulkUploadConfirmMatchComplete, fetchCompletedTransactions, fetchCompletedTransactionsSuccess, fetchCompletedTransactionsFailure, fetchFluxAnalysisView, clearExpenseAutomationFluxAnalysisView, updateOperatingExpensesIdsForReview as updateFluxOperatingExpensesIdsForReview, updateSelectedSectionIdsForReview as updateFluxAnalysisSelectedSectionIdsForReview, reviewFluxAnalysisView, updateExpenseAutomationMissingReceiptUploadState, updateExpenseAutomationMissingReceiptsUIState, updateTransactionCategorizationUploadReceiptState, uploadTransactionCategorizationReceiptSuccess, getExpenseAutomationFluxAnalysisView, updateCurrentSelectedView, updateCurrentSelectedPeriod, getExpenseAutomationTransactionView, getLastTransferEntryReplacement, updateFluxAnalysisViewUIState, updateFluxAnalysisViewPageMetaData, MAX_SELECTION_LIMIT, checkIfAllLineItemsAreCategoryClassFilled, getLineItemsByTransactionIdsFromLocalData, isAnyItemWithUncategorizedExpenseAccount, excludeAccountFromReconciliation, includeAccountInReconciliation, saveExpenseAutomationReconciliationDetail, updateExpenseAutomationReconcileTabListScrollState, updateExpenseAutomationReconReviewTabListSortState, updateExpenseAutomationReconcileTabListSortState, updateExpenseAutomationReconcileTabLocalData, updateExpenseAutomationAccountReconciliationSelectedTab, updateExpenseAutomationAccountReconciliationSelectedAccountId, getExpenseAutomationReconciliationView, getReparseStatementStatusByAccountId, fetchReconciliationView, uploadAccountStatementIntoDocumentAI, updateExpenseAutomationReconListScrollPosition, setConnectionInProgressForAccountReconciliation, getAccountReconByAccountIdAndSelectedPeriod, toReconciliationTabsType, isAccountReconReport, updateExpenseAutomationReconReviewTabLocalData, updateExpenseAutomationSelectedDrawerAccountId, updateStatementProcessingFailed, saveExpenseAutomationReconciliationReview, updateExpenseAutomationAccountReconciliationLocalData, toReconciliationAccountSource, deleteAccountStatement, uploadAccountStatement, parseStatement, parseStatementSuccess, parseStatementFailure, reparseStatement, reparseStatementSuccess, reparseStatementFailure, resetReparseStatementStatus, updateParsedStatementData, updateNodeCollapseState, updateStatementUploadChosen, submitStatementUpdate, clearStatementDateConflict, updateStatementUpdateLocalData, isReviewTransactionBankTransferType, isReviewTransactionBillPaymentType, isReviewTransactionCreditCardPaymentType, isReviewTransactionDepositType, isReviewTransactionExpenseType, isReviewTransactionCreditCardCreditType, setStatementParseInProgress, };
|
|
466
466
|
export { fetchTransactionCategorization, fetchTransactionCategorizationView, updateTransactionCategorizationUIState, updateTransactionFilters, updateSelectedCheckboxTransactionIds, markCategoryClassRecommendationsFailureForCategorization, setEntityRecommendationForLineIdsForCategorization, initializeTransactionCategorizationViewLocalData, setAllItemsToCategoryClassInLocalDataForCategorization, saveTransactionCategorizationLocalData, fetchTransactionCategorizationFailure, saveTransactionCategorization, updateTransactionCategorization, updateTransactionCategorizationSaveStatus, markTransactionAsNotMiscategorized, updateSelectedVendorForTransaction, updateSelectedCustomerForTransaction, updateSelectedTransactionId, syncTransactionCategorizationFromDetailSave, backgroundRefetchReviewTab, createTransferEntry, createTransferEntryFailure, createTransferEntryReplacedTransaction, createTransferEntrySuccess, resetCreateTransferEntryStatus, clearTransferEntryRouteReplacement, fetchAccountsForTransferFlow, removeTransactionFromAllTabs, clearExpenseAutomationTransactionsView, toTransactionsSortKey, };
|
|
467
467
|
export { TOP_EX_TIME_PERIODS };
|
|
468
468
|
export { toTimeframeTick, mapTimePeriodtoTimeframeTick, toTimePeriod, toAbsoluteDay, toMonthYearPeriodId, convertToPeriod, };
|
|
@@ -479,7 +479,7 @@ export { getCardBalance, fetchCardBalance, updateStatementCloseDay, };
|
|
|
479
479
|
export { getCashBalance, fetchCashBalance };
|
|
480
480
|
export { fetchBillPayCard, fetchReimbursementCard };
|
|
481
481
|
export { fetchOpEx, updateOpExCOABalancesRange, updateOpExDownloadState, updateOpExUIState, getOperatingExpensesReportFetchState, getOperatingExpensesReport, getOperatingExpensesUIState, getOperatingExpensesForSelectedRange, getOperatingExpensesForHighlightedRange, fetchOpExWithForecast, };
|
|
482
|
-
export { fetchOpExByVendor, fetchOpExByVendorReportForTimeframe, updateOpExByVendorTimeFrame, updateOpExByVendorUIState, getOpExByVendorReport, getOpExByVendorUIState, updateOpExByVendorAdditionalBalancesSelection, updateOpExByVendorSearchString, updateOpExByVendorSort, updateOpExByVendorPageFetchInProgress, updateOpExByVendorSortOrSearchInProgress, updateOpExByVendorDownloadState, clearOpExByVendorSearch, updateOpExByVendorPageLimit, toOpexByVendorSortKeyType, getOpexVendorTimeframeKey, isOpexByVendorIDNotSpecifiedVendor, };
|
|
482
|
+
export { fetchOpExByVendor, fetchOpExByVendorReportForTimeframe, refreshOpExByVendorReport, updateOpExByVendorTimeFrame, updateOpExByVendorUIState, getOpExByVendorReport, getOpExByVendorUIState, updateOpExByVendorAdditionalBalancesSelection, updateOpExByVendorSearchString, updateOpExByVendorSort, updateOpExByVendorPageFetchInProgress, updateOpExByVendorSortOrSearchInProgress, updateOpExByVendorDownloadState, clearOpExByVendorSearch, updateOpExByVendorPageLimit, toOpexByVendorSortKeyType, getOpexVendorTimeframeKey, isOpexByVendorIDNotSpecifiedVendor, };
|
|
483
483
|
export { fetchOpExClassesView, updateOpExAccountViewMode, updateOpExClassesToFilterOut, updateOpExClassesViewUIState, getOpExClassesView, getOpExClassesViewForHighlightedRange, getOpExClassesViewForSelectedRange, isOpExClassesViewSectionID, isOpExClassesViewCalculatedSectionID, };
|
|
484
484
|
export { fetchNetBurnOrIncomeClassesView, updateNetBurnOrIncomeAccountViewMode, updateNetBurnOrIncomeClassesToFilterOut, updateNetBurnOrIncomeClassesViewUIState, getNetBurnOrIncomeClassesView, getNetBurnOrIncomeClassesViewForHighlightedRange, getNetBurnOrIncomeClassesViewForSelectedRange, isNetBurnOrIncomeClassesViewSectionID, isNetBurnOrIncomeClassesViewCalculatedSectionID, };
|
|
485
485
|
export { fetchNetBurnOrIncome, updateNetBurnOrIncomeUIState, fetchNetBurnOrIncomeWithForecast, updateNetBurnOrIncomeCOABalancesRange, updateNetBurnOrIncomeDownloadState, getNetBurnOrIncomeReport, getNetBurnOrIncomeForSelectedRange, getNetBurnOrIncomeForHighlightedRange, getNetBurnOrIncomeUIState, getNetBurnOrIncomeReportFetchState, isNetBurnOrIncomeReportViewCalculatedSectionID, isNetBurnOrIncomeReportViewSectionID, };
|
|
@@ -643,7 +643,7 @@ export { toNotificationModeStrict, updateCommentsNotifications, updateCommentsNo
|
|
|
643
643
|
export { toNotificationSubTabTypeStrict, toNotificationTabTypeStrict, fetchNotificationView, fetchNotificationUnreadCount, fetchNotificationUnreadCountSuccess, updateNotificationViewAllNotificationsStatus, updateNotificationViewNotificationStatus, updateNotificationViewTabState, updateNotificationViewCurrentTabAndSubTab, updateNotificationViewSubTab, updateNotificationViewUIState, getNotificationView, getExternalNotificationsForSelectedSubTab, getNotificationsForSelectedSubTab, };
|
|
644
644
|
export { clearFeatureNotificationView, fetchRegisteredInterests, notifyMeForFeature, getFeatureNotificationView, getRegisteredInterests, getRegisteredInterestsByFeature, isFeatureInterestRegistered, };
|
|
645
645
|
export { pushToastNotification, getLastNotificationTime, getNotifications, };
|
|
646
|
-
export { getReferralListView, getInviteFormView, toReferralListViewSortKeyType, StatusTypes, AmountStatusTypes, fetchReferrals, sendReferralInvite, clearReferrals, saveReferralFormDataInLocalStore, updateReferralListSortUiState, resendReferralInvite, fetchRewardsPlan, getRewardsPlanCard, updateReferViewed, };
|
|
646
|
+
export { getReferralListView, getInviteFormView, toReferralListViewSortKeyType, StatusTypes, AmountStatusTypes, DEFAULT_REFERRER_AMOUNT, fetchReferrals, sendReferralInvite, clearReferrals, saveReferralFormDataInLocalStore, updateReferralListSortUiState, resendReferralInvite, fetchRewardsPlan, getRewardsPlanCard, updateReferViewed, };
|
|
647
647
|
export { ALL_WEEK_DAYS, SEMI_WEEKLY_REQUIRED_DAYS_COUNT, getMinAllowedEndDate, getRecurringEndDateFromCount, toDayOfWeek, toRecurringFrequency, };
|
|
648
648
|
export { fetchCockpitContext, fetchCompanyTaskManagerView, fetchTaskManagerMetrics, getCompanyTaskManagerView, createTaskFromTaskGroupTemplate, };
|
|
649
649
|
export { fetchInternationalVerificationForm, submitInternationalVerificationForm, updateVerificationFormLocalData, getIntlWireVerificationView, };
|
|
@@ -656,8 +656,8 @@ export { clearAllAiAccountantCustomers, updateAiAccountantCustomers, updateAiAcc
|
|
|
656
656
|
export { getAiAccountantCustomers, getAiAccountantJobsByTenantId, } from './entity/aiAccountantCustomer/aiAccountantCustomerSelector';
|
|
657
657
|
export { cancelAiAccountantOnboarding, clearAiAccountantView, fetchAiAccountantCustomers, fetchAiAccountantJobs, setSelectedTenantIdsForJobTrigger, triggerAiAccountantJob, updateAiAccountantUIState, } from './view/aiAccountantView/aiAccountantViewReducer';
|
|
658
658
|
export { getAiAccountantCockpitView, } from './view/aiAccountantView/aiAccountantViewSelector';
|
|
659
|
-
export { fetchChatSessionsForUser, createSession, submitQuestion, updateAiCfoViewScrollPosition, updateCurrentInput, updateCotCollapsedState, clearInput, setSession, clearAiCfoView, clearCurrentSessionId, clearDeleteChatSessionStatus, clearLastContextMessage, createSessionAndSubmit, stopSubmit, stopSubmitQuestion, fetchChatHistory, acceptMasterTOS, deleteChatSession, updateResponseState, fetchSuggestedQuestions, fetchSuggestedQuestionsSuccess, fetchSuggestedQuestionsFailure, applyAiCfoSidePanelHostPageTransition, clearAiCfoSidePanelHostPageContext, } from './view/aiCfoView/aiCfoViewReducer';
|
|
660
|
-
export { getAiCfoView, getSuggestedQuestionsForPageContext, } from './view/aiCfoView/aiCfoViewSelector';
|
|
659
|
+
export { fetchChatSessionsForUser, createSession, submitQuestion, updateAiCfoViewScrollPosition, updateCurrentInput, updateCotCollapsedState, clearInput, setSession, clearAiCfoView, clearCurrentSessionId, clearDeleteChatSessionStatus, clearLastContextMessage, createSessionAndSubmit, stopSubmit, stopSubmitQuestion, fetchChatHistory, acceptMasterTOS, deleteChatSession, updateResponseState, fetchSuggestedQuestions, fetchSuggestedQuestionsSuccess, fetchSuggestedQuestionsFailure, fetchSkills, fetchSkillsSuccess, fetchSkillsFailure, applyAiCfoSidePanelHostPageTransition, clearAiCfoSidePanelHostPageContext, } from './view/aiCfoView/aiCfoViewReducer';
|
|
660
|
+
export { getAiCfoView, getSuggestedQuestionsForPageContext, getSkills, } from './view/aiCfoView/aiCfoViewSelector';
|
|
661
661
|
export { setNewSession, setSessions, updateAiCfoAnswerCardPolicyWizardPlan, upsertAnswerPayload, upsertOrAddQuestionAnswerPayload, addQuestionPayload, clearSession, clearAiCfo, toAiCfoVisualization, appendSyntheticAiCfoAnswer, updateSyntheticAiCfoAnswer, removeSyntheticAiCfoAnswer, clearSyntheticAiCfoAnswers, } from './entity/aiCfo/aiCfoReducer';
|
|
662
662
|
export { getAllQuestionAnswersForChatSession, getQuestionAnswerByIdForChatSession, getAllQuestionsForChatSession, getAiCfoSelectorView, getSyntheticAiCfoAnswersForChatSession, getSyntheticAiCfoAnswerByQuestionAnswerId, } from './entity/aiCfo/aiCfoSelector';
|
|
663
663
|
export { ALL_AI_CFO_CHARTS_TYPES, ALL_AI_CFO_VISUALIZATION_TYPES, ALL_AI_CFO_ANSWER_STATE_TYPES, ALL_AI_CFO_ANSWER_RESPONSE_TYPES, ALL_INTERACTIVE_FORM_TYPES, toAiCfoVisualizationType, toAiCfoVisualizationTypeStrict, toAiCfoChartType, toAiCfoChartTypeStrict, toAiCfoAnswerStateType, toAiCfoAnswerStateTypeStrict, toAiCfoAnswerResponseType, toAiCfoAnswerResponseTypeStrict, toInteractiveFormType, toInteractiveFormTypeStrict, ALL_SYNTHETIC_AI_CFO_ANSWER_KINDS, toMessageSender, toMessageType, } from './entity/aiCfo/aiCfoState';
|
|
@@ -47,6 +47,7 @@ export const initialAiCfoViewState = {
|
|
|
47
47
|
responseStateByChatSessionId: {},
|
|
48
48
|
stopSubmitStateByChatSessionId: {},
|
|
49
49
|
suggestedQuestionsByPageContext: {},
|
|
50
|
+
skills: { fetchState: 'Not-Started', error: undefined, skills: [] },
|
|
50
51
|
};
|
|
51
52
|
const aiCfoView = createSlice({
|
|
52
53
|
name: 'aiCfoView',
|
|
@@ -62,7 +63,7 @@ const aiCfoView = createSlice({
|
|
|
62
63
|
answer: { fetchState: 'In-Progress', error: undefined },
|
|
63
64
|
};
|
|
64
65
|
},
|
|
65
|
-
prepare(sessionId, questionAnswerId, userId, questionId, createdAt, question, files) {
|
|
66
|
+
prepare(sessionId, questionAnswerId, userId, questionId, createdAt, question, files, macroId) {
|
|
66
67
|
return {
|
|
67
68
|
payload: {
|
|
68
69
|
sessionId,
|
|
@@ -72,6 +73,7 @@ const aiCfoView = createSlice({
|
|
|
72
73
|
createdAt,
|
|
73
74
|
question,
|
|
74
75
|
files,
|
|
76
|
+
macroId,
|
|
75
77
|
},
|
|
76
78
|
};
|
|
77
79
|
},
|
|
@@ -222,7 +224,7 @@ const aiCfoView = createSlice({
|
|
|
222
224
|
draft.createSessionAndSubmitState.fetchState = 'In-Progress';
|
|
223
225
|
draft.createSessionAndSubmitState.error = undefined;
|
|
224
226
|
},
|
|
225
|
-
prepare(agentId, userId, questionAnswerId, questionId, createdAt, question, files, pageContext) {
|
|
227
|
+
prepare(agentId, userId, questionAnswerId, questionId, createdAt, question, files, pageContext, macroId) {
|
|
226
228
|
return {
|
|
227
229
|
payload: {
|
|
228
230
|
agentId,
|
|
@@ -233,6 +235,7 @@ const aiCfoView = createSlice({
|
|
|
233
235
|
question,
|
|
234
236
|
files,
|
|
235
237
|
pageContext,
|
|
238
|
+
macroId,
|
|
236
239
|
},
|
|
237
240
|
};
|
|
238
241
|
},
|
|
@@ -445,6 +448,29 @@ const aiCfoView = createSlice({
|
|
|
445
448
|
error,
|
|
446
449
|
};
|
|
447
450
|
},
|
|
451
|
+
fetchSkills(draft) {
|
|
452
|
+
// Optional-chain: persisted/rehydrated state from before this slice existed
|
|
453
|
+
// may have no `skills`, so don't assume draft.skills is set.
|
|
454
|
+
draft.skills = {
|
|
455
|
+
fetchState: 'In-Progress',
|
|
456
|
+
error: undefined,
|
|
457
|
+
skills: draft.skills?.skills ?? [],
|
|
458
|
+
};
|
|
459
|
+
},
|
|
460
|
+
fetchSkillsSuccess(draft, action) {
|
|
461
|
+
draft.skills = {
|
|
462
|
+
fetchState: 'Completed',
|
|
463
|
+
error: undefined,
|
|
464
|
+
skills: action.payload.skills,
|
|
465
|
+
};
|
|
466
|
+
},
|
|
467
|
+
fetchSkillsFailure(draft, action) {
|
|
468
|
+
draft.skills = {
|
|
469
|
+
fetchState: 'Error',
|
|
470
|
+
error: action.payload,
|
|
471
|
+
skills: draft.skills?.skills ?? [],
|
|
472
|
+
};
|
|
473
|
+
},
|
|
448
474
|
clearAiCfoView(draft) {
|
|
449
475
|
Object.assign(draft, initialAiCfoViewState);
|
|
450
476
|
},
|
|
@@ -455,5 +481,5 @@ const aiCfoView = createSlice({
|
|
|
455
481
|
},
|
|
456
482
|
},
|
|
457
483
|
});
|
|
458
|
-
export const { submitQuestion, submitQuestionSuccess, submitQuestionFailure, updateResponseState, updateAiCfoViewScrollPosition, updateCurrentInput, clearInput, setSession, createSession, createSessionSuccess, createSessionFailure, createSessionAndSubmit, initializeNewSessionState, createSessionAndSubmitSuccess, createSessionAndSubmitFailure, fetchChatSessionsForUser, fetchChatSessionsForUserSuccess, fetchChatSessionsForUserFailure, fetchChatHistory, fetchChatHistorySuccess, fetchChatHistoryFailure, clearCurrentSessionId, clearLastContextMessage, stopSubmit, stopSubmitSuccess, stopSubmitFailure, stopSubmitQuestion, stopSubmitQuestionSuccess, stopSubmitQuestionFailure, acceptMasterTOS, acceptMasterTOSSuccess, acceptMasterTOSFailure, deleteChatSession, deleteChatSessionSuccess, deleteChatSessionFailure, clearDeleteChatSessionStatus, clearAiCfoView, updateCotCollapsedState, fetchSuggestedQuestions, fetchSuggestedQuestionsSuccess, fetchSuggestedQuestionsFailure, applyAiCfoSidePanelHostPageTransition, clearAiCfoSidePanelHostPageContext, } = aiCfoView.actions;
|
|
484
|
+
export const { submitQuestion, submitQuestionSuccess, submitQuestionFailure, updateResponseState, updateAiCfoViewScrollPosition, updateCurrentInput, clearInput, setSession, createSession, createSessionSuccess, createSessionFailure, createSessionAndSubmit, initializeNewSessionState, createSessionAndSubmitSuccess, createSessionAndSubmitFailure, fetchChatSessionsForUser, fetchChatSessionsForUserSuccess, fetchChatSessionsForUserFailure, fetchChatHistory, fetchChatHistorySuccess, fetchChatHistoryFailure, clearCurrentSessionId, clearLastContextMessage, stopSubmit, stopSubmitSuccess, stopSubmitFailure, stopSubmitQuestion, stopSubmitQuestionSuccess, stopSubmitQuestionFailure, acceptMasterTOS, acceptMasterTOSSuccess, acceptMasterTOSFailure, deleteChatSession, deleteChatSessionSuccess, deleteChatSessionFailure, clearDeleteChatSessionStatus, clearAiCfoView, updateCotCollapsedState, fetchSuggestedQuestions, fetchSuggestedQuestionsSuccess, fetchSuggestedQuestionsFailure, fetchSkills, fetchSkillsSuccess, fetchSkillsFailure, applyAiCfoSidePanelHostPageTransition, clearAiCfoSidePanelHostPageContext, } = aiCfoView.actions;
|
|
459
485
|
export default aiCfoView.reducer;
|
|
@@ -22,3 +22,14 @@ export const getAiCfoView = (state) => {
|
|
|
22
22
|
export function getSuggestedQuestionsForPageContext(state, pageContext) {
|
|
23
23
|
return state.aiCfoViewState?.suggestedQuestionsByPageContext?.[pageContext];
|
|
24
24
|
}
|
|
25
|
+
// Stable fallback so getSkills returns a referentially-stable object when skills
|
|
26
|
+
// state is absent — a fresh literal each call would defeat useSelector identity
|
|
27
|
+
// checks and cause needless re-renders.
|
|
28
|
+
const EMPTY_SKILLS_STATE = {
|
|
29
|
+
fetchState: 'Not-Started',
|
|
30
|
+
error: undefined,
|
|
31
|
+
skills: [],
|
|
32
|
+
};
|
|
33
|
+
export function getSkills(state) {
|
|
34
|
+
return state.aiCfoViewState?.skills ?? EMPTY_SKILLS_STATE;
|
|
35
|
+
}
|
|
@@ -66,7 +66,7 @@ function waitForChannelSubscription(pusherInstance, channelName, timeoutMs = 500
|
|
|
66
66
|
}));
|
|
67
67
|
}
|
|
68
68
|
export const createSessionAndSubmitEpic = (actions$, _state$, zeniAPI) => actions$.pipe(filter(createSessionAndSubmit.match), switchMap((action) => {
|
|
69
|
-
const { agentId, userId, questionAnswerId, questionId, createdAt, question, files, pageContext, } = action.payload;
|
|
69
|
+
const { agentId, userId, questionAnswerId, questionId, createdAt, question, files, pageContext, macroId, } = action.payload;
|
|
70
70
|
const payload = {
|
|
71
71
|
agent_id: agentId,
|
|
72
72
|
...(pageContext != null && { page_context: pageContext }),
|
|
@@ -113,7 +113,7 @@ export const createSessionAndSubmitEpic = (actions$, _state$, zeniAPI) => action
|
|
|
113
113
|
// This allows fetchChatHistory to run after the question is submitted
|
|
114
114
|
of(createSessionAndSubmitSuccess(),
|
|
115
115
|
// Submit the question after handlers are bound
|
|
116
|
-
submitQuestion(sessionId, questionAnswerId, userId, questionId, createdAt, question, files),
|
|
116
|
+
submitQuestion(sessionId, questionAnswerId, userId, questionId, createdAt, question, files, macroId),
|
|
117
117
|
// Add question payload optimistically after submitQuestion (matches original order)
|
|
118
118
|
// This is idempotent - won't create duplicates if called multiple times
|
|
119
119
|
// submitQuestionEpic will find the question already exists and only update the response
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { of } from 'rxjs';
|
|
2
|
+
import { catchError, filter, mergeMap, switchMap } from 'rxjs/operators';
|
|
3
|
+
import { createZeniAPIStatus, isSuccessResponse } from '../../../responsePayload';
|
|
4
|
+
import { fetchSkills, fetchSkillsFailure, fetchSkillsSuccess, } from '../aiCfoViewReducer';
|
|
5
|
+
const toSkill = (s) => ({
|
|
6
|
+
macroId: s.macro_id,
|
|
7
|
+
name: s.name,
|
|
8
|
+
displayName: s.display_name,
|
|
9
|
+
description: s.description,
|
|
10
|
+
semver: s.semver,
|
|
11
|
+
parameterHints: s.parameter_hints,
|
|
12
|
+
hasScripts: s.has_scripts,
|
|
13
|
+
});
|
|
14
|
+
/** GET {aiCfoMicroServiceBaseUrl}/1.0/skills — chat-visible skills for the `/` menu. */
|
|
15
|
+
export const fetchSkillsEpic = (actions$,
|
|
16
|
+
// state$ intentionally unused: the `/` menu dispatches this once per slash-entry
|
|
17
|
+
// (the composer dedupes), so we always re-fetch the (small, singleton) list.
|
|
18
|
+
_state$, zeniAPI) => actions$.pipe(filter(fetchSkills.match),
|
|
19
|
+
// switchMap: a singleton list endpoint with no key — cancel any in-flight
|
|
20
|
+
// fetch so the latest dispatch wins (no racing writes to `skills`).
|
|
21
|
+
switchMap(() => {
|
|
22
|
+
// aiCfoMicroServiceBaseUrl already targets the chat service (it serves the
|
|
23
|
+
// /1.0/agents/{id} submit route too); /1.0/skills lives on the same service.
|
|
24
|
+
const url = `${zeniAPI.apiEndPoints.aiCfoMicroServiceBaseUrl}/1.0/skills`;
|
|
25
|
+
return zeniAPI.getJSON(url).pipe(mergeMap((response) => {
|
|
26
|
+
if (isSuccessResponse(response) && response.data != null) {
|
|
27
|
+
// Guard the array: a malformed 2xx body without `skills` must not crash .map.
|
|
28
|
+
return of(fetchSkillsSuccess({
|
|
29
|
+
skills: (response.data.skills ?? []).map(toSkill),
|
|
30
|
+
}));
|
|
31
|
+
}
|
|
32
|
+
return of(fetchSkillsFailure(response.status));
|
|
33
|
+
}), catchError((error) => of(fetchSkillsFailure(createZeniAPIStatus('Unexpected Error', 'Fetch skills REST API call failed', error instanceof Error ? { message: error.message } : undefined)))));
|
|
34
|
+
}));
|
|
@@ -4,7 +4,7 @@ import { upsertOrAddQuestionAnswerPayload } from '../../../entity/aiCfo/aiCfoRed
|
|
|
4
4
|
import { createZeniAPIStatus, isSuccessResponse } from '../../../responsePayload';
|
|
5
5
|
import { submitQuestion, submitQuestionFailure, submitQuestionSuccess, } from '../aiCfoViewReducer';
|
|
6
6
|
export const submitQuestionEpic = (actions$, state$, zeniAPI) => actions$.pipe(filter(submitQuestion.match), mergeMap((action) => {
|
|
7
|
-
const { questionAnswerId, userId, sessionId, questionId, createdAt, question, files, } = action.payload;
|
|
7
|
+
const { questionAnswerId, userId, sessionId, questionId, createdAt, question, files, macroId, } = action.payload;
|
|
8
8
|
const { aiCfoViewState } = state$.value;
|
|
9
9
|
const { uiState } = aiCfoViewState;
|
|
10
10
|
const agentId = uiState.agentId;
|
|
@@ -17,15 +17,21 @@ export const submitQuestionEpic = (actions$, state$, zeniAPI) => actions$.pipe(f
|
|
|
17
17
|
const formData = new FormData();
|
|
18
18
|
formData.append('chat_session_id', sessionId);
|
|
19
19
|
formData.append('message', question);
|
|
20
|
+
if (macroId != null) {
|
|
21
|
+
formData.append('macro_id', macroId);
|
|
22
|
+
}
|
|
20
23
|
for (const file of files) {
|
|
21
24
|
formData.append('files', file, file.name);
|
|
22
25
|
}
|
|
23
26
|
apiCall = zeniAPI.postFormData(endpoint, formData);
|
|
24
27
|
}
|
|
25
28
|
else {
|
|
29
|
+
// `message` is the display token (e.g. "/flux"); `macro_id` tells the chat
|
|
30
|
+
// service to expand the skill's instructions as the actual agent prompt.
|
|
26
31
|
apiCall = zeniAPI.postAndGetJSON(endpoint, {
|
|
27
32
|
chat_session_id: sessionId,
|
|
28
33
|
message: question,
|
|
34
|
+
...(macroId != null && { macro_id: macroId }),
|
|
29
35
|
});
|
|
30
36
|
}
|
|
31
37
|
return apiCall.pipe(mergeMap((response) => {
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { from, of } from 'rxjs';
|
|
2
|
+
import { catchError, filter, mergeMap, switchMap } from 'rxjs/operators';
|
|
3
|
+
import { createZeniAPIStatus, isSuccessResponse, } from '../../../../responsePayload';
|
|
4
|
+
import { transformParseStatementPayloadToState, } from '../../payload/reconciliationPayload';
|
|
5
|
+
import { parseStatement, parseStatementFailure, parseStatementSuccess, updateParsedStatementData, } from '../../reducers/reconciliationViewReducer';
|
|
6
|
+
export const parseStatementEpic = (actions$, _state$, zeniAPI) => actions$.pipe(filter(parseStatement.match), switchMap((action) => {
|
|
7
|
+
const { accountId, selectedPeriod, statementUploadId } = action.payload;
|
|
8
|
+
const parseStatementApi$ = zeniAPI.getJSON(`${zeniAPI.apiEndPoints.reconciliationMicroServiceBaseUrl}/2.0/statement-uploads/${statementUploadId}`);
|
|
9
|
+
return parseStatementApi$.pipe(mergeMap((response) => {
|
|
10
|
+
if (isSuccessResponse(response) === true && response.data != null) {
|
|
11
|
+
const actions = [];
|
|
12
|
+
const transformedData = transformParseStatementPayloadToState(response.data);
|
|
13
|
+
actions.push(updateParsedStatementData({
|
|
14
|
+
accountId,
|
|
15
|
+
selectedPeriod,
|
|
16
|
+
parsedStatementData: transformedData,
|
|
17
|
+
}));
|
|
18
|
+
actions.push(parseStatementSuccess({ accountId, selectedPeriod }));
|
|
19
|
+
return from(actions);
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
return of(parseStatementFailure({
|
|
23
|
+
accountId,
|
|
24
|
+
selectedPeriod,
|
|
25
|
+
error: response.status,
|
|
26
|
+
}));
|
|
27
|
+
}
|
|
28
|
+
}), catchError((error) => of(parseStatementFailure({
|
|
29
|
+
accountId,
|
|
30
|
+
selectedPeriod,
|
|
31
|
+
error: createZeniAPIStatus('Unexpected Error', 'Parse Statement REST API call errored out ' +
|
|
32
|
+
(error instanceof Error ? error.message : String(error))),
|
|
33
|
+
}))));
|
|
34
|
+
}));
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { from, of } from 'rxjs';
|
|
2
|
+
import { catchError, filter, mergeMap, switchMap } from 'rxjs/operators';
|
|
3
|
+
import { updateAccountReconReparseStatement } from '../../../../entity/accountRecon/accountReconReducer';
|
|
4
|
+
import { toAccountReconKey } from '../../../../entity/accountRecon/accountReconState';
|
|
5
|
+
import { createZeniAPIStatus, isSuccessResponse, } from '../../../../responsePayload';
|
|
6
|
+
import { reparseStatement, reparseStatementFailure, reparseStatementSuccess, } from '../../reducers/reconciliationViewReducer';
|
|
7
|
+
export const reparseStatementEpic = (actions$, _state$, zeniAPI) => actions$.pipe(filter(reparseStatement.match), switchMap((action) => {
|
|
8
|
+
const { accountId, selectedPeriod, statementUploadId } = action.payload;
|
|
9
|
+
const reparseStatementApi$ = zeniAPI.postAndGetJSON(`${zeniAPI.apiEndPoints.reconciliationMicroServiceBaseUrl}/1.0/reconciliation/statements/${statementUploadId}/reparse`);
|
|
10
|
+
return reparseStatementApi$.pipe(mergeMap((response) => {
|
|
11
|
+
if (isSuccessResponse(response) === true && response.data != null) {
|
|
12
|
+
const accountReconKey = toAccountReconKey(accountId, selectedPeriod);
|
|
13
|
+
return from([
|
|
14
|
+
updateAccountReconReparseStatement(accountReconKey, response.data),
|
|
15
|
+
reparseStatementSuccess({ accountId, selectedPeriod }),
|
|
16
|
+
]);
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
return of(reparseStatementFailure({
|
|
20
|
+
accountId,
|
|
21
|
+
selectedPeriod,
|
|
22
|
+
error: response.status,
|
|
23
|
+
}));
|
|
24
|
+
}
|
|
25
|
+
}), catchError((error) => of(reparseStatementFailure({
|
|
26
|
+
accountId,
|
|
27
|
+
selectedPeriod,
|
|
28
|
+
error: createZeniAPIStatus('Unexpected Error', 'Reparse Statement REST API call errored out ' +
|
|
29
|
+
(error instanceof Error ? error.message : String(error))),
|
|
30
|
+
}))));
|
|
31
|
+
}));
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { of } from 'rxjs';
|
|
2
|
+
import { catchError, filter, mergeMap, switchMap } from 'rxjs/operators';
|
|
3
|
+
import { toMonthYearPeriodId } from '../../../../commonStateTypes/timePeriod';
|
|
4
|
+
import { createZeniAPIStatus, isSuccessResponse, } from '../../../../responsePayload';
|
|
5
|
+
import { isStatementDateConflictResponse, toStatementUpdateRequestBody, transformStatementDateConflictToState, transformUpdateStatementInfoPayloadToState, } from '../../payload/reconciliationPayload';
|
|
6
|
+
import { submitStatementUpdate, submitStatementUpdateFailure, submitStatementUpdateSuccess, updateParsedStatementData, } from '../../reducers/reconciliationViewReducer';
|
|
7
|
+
export const updateStatementInfoEpic = (actions$, state$, zeniAPI) => actions$.pipe(filter(submitStatementUpdate.match), switchMap((action) => {
|
|
8
|
+
const { accountId, selectedPeriod, statementUploadId } = action.payload;
|
|
9
|
+
const state = state$.value;
|
|
10
|
+
const reconciliationView = state.expenseAutomationReconciliationViewState;
|
|
11
|
+
const accountRecon = reconciliationView.accountReconciliationRecordsBySelectedPeriod[toMonthYearPeriodId(selectedPeriod)]?.reconciliationByAccountID[accountId];
|
|
12
|
+
const localData = accountRecon?.localData?.statementUpdateLocalData;
|
|
13
|
+
if (!localData) {
|
|
14
|
+
return of(submitStatementUpdateFailure({
|
|
15
|
+
accountId,
|
|
16
|
+
selectedPeriod,
|
|
17
|
+
error: createZeniAPIStatus('Missing Data', 'No statement update data found'),
|
|
18
|
+
}));
|
|
19
|
+
}
|
|
20
|
+
const hasInvalidUpdates = localData.statementTransactions.updated.some((txn) => txn.statementTransactionId == null);
|
|
21
|
+
if (hasInvalidUpdates) {
|
|
22
|
+
return of(submitStatementUpdateFailure({
|
|
23
|
+
accountId,
|
|
24
|
+
selectedPeriod,
|
|
25
|
+
error: createZeniAPIStatus('Invalid Data', 'One or more edited transactions are missing statement transaction ids'),
|
|
26
|
+
}));
|
|
27
|
+
}
|
|
28
|
+
const body = toStatementUpdateRequestBody(localData);
|
|
29
|
+
const updateStatementApi$ = zeniAPI.putAndGetJSON(`${zeniAPI.apiEndPoints.reconciliationMicroServiceBaseUrl}/2.0/statement-uploads/${statementUploadId}`, body);
|
|
30
|
+
return updateStatementApi$.pipe(mergeMap((response) => {
|
|
31
|
+
if (isSuccessResponse(response) === true && response.data != null) {
|
|
32
|
+
const parsedStatementData = transformUpdateStatementInfoPayloadToState(response.data);
|
|
33
|
+
return of(updateParsedStatementData({
|
|
34
|
+
accountId,
|
|
35
|
+
selectedPeriod,
|
|
36
|
+
parsedStatementData,
|
|
37
|
+
}), submitStatementUpdateSuccess({
|
|
38
|
+
accountId,
|
|
39
|
+
selectedPeriod,
|
|
40
|
+
}));
|
|
41
|
+
}
|
|
42
|
+
const dateConflict = isStatementDateConflictResponse(response)
|
|
43
|
+
? transformStatementDateConflictToState(response)
|
|
44
|
+
: null;
|
|
45
|
+
return of(submitStatementUpdateFailure({
|
|
46
|
+
accountId,
|
|
47
|
+
selectedPeriod,
|
|
48
|
+
error: response.status,
|
|
49
|
+
dateConflict,
|
|
50
|
+
}));
|
|
51
|
+
}), catchError((error) => of(submitStatementUpdateFailure({
|
|
52
|
+
accountId,
|
|
53
|
+
selectedPeriod,
|
|
54
|
+
error: createZeniAPIStatus('Unexpected Error', 'Update Statement REST API call errored out ' +
|
|
55
|
+
(error instanceof Error ? error.message : String(error))),
|
|
56
|
+
}))));
|
|
57
|
+
}));
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { from, of } from 'rxjs';
|
|
2
|
-
import { catchError, filter, mergeMap, switchMap } from 'rxjs/operators';
|
|
1
|
+
import { EMPTY, from, of } from 'rxjs';
|
|
2
|
+
import { catchError, filter, groupBy, mergeMap, switchMap } from 'rxjs/operators';
|
|
3
3
|
import { toString } from '../../../../commonStateTypes/timePeriod';
|
|
4
4
|
import { getCurrentTenant } from '../../../../entity/tenant/tenantSelector';
|
|
5
5
|
import { updateTransactions } from '../../../../entity/transaction/transactionReducer';
|
|
@@ -8,11 +8,15 @@ import { getLineItemsByTransactionsIdsFromResponse } from '../../helpers/transac
|
|
|
8
8
|
import { fetchTransactionCategorization, fetchTransactionCategorizationFailure, fetchTransactionCategorizationSuccess, initializeTransactionCategorizationViewLocalData, resetOtherTabsFetchState, updateParentTotalCountForTab, updateTotalCountForTransactionCategorization, updateTransactionCategorizationUIState, } from '../../reducers/transactionsViewReducer';
|
|
9
9
|
import { DEFAULT_COMPLETED_SUB_TAB } from '../../types/completedSubTab';
|
|
10
10
|
import { TRANSACTIONS_TABS, toTransactionsSortKey, } from '../../types/transactionsViewState';
|
|
11
|
-
export const fetchTransactionCategorizationEpic = (actions$, state$, zeniAPI) => actions$.pipe(filter(fetchTransactionCategorization.match),
|
|
11
|
+
export const fetchTransactionCategorizationEpic = (actions$, state$, zeniAPI) => actions$.pipe(filter(fetchTransactionCategorization.match),
|
|
12
|
+
// Per-tab switchMap: cancels in-flight requests for the same tab on a new
|
|
13
|
+
// request, but allows both tabs to fetch concurrently (e.g. dual search).
|
|
14
|
+
groupBy((action) => action.payload.selectedTab), mergeMap((group$) => group$.pipe(switchMap((action) => {
|
|
12
15
|
const { expenseAutomationViewState: { selectedPeriodByTenantId }, expenseAutomationTransactionsViewState, } = state$.value;
|
|
13
16
|
const { period, keepExistingListItems, selectedTab, refreshViewInBackground, } = action.payload;
|
|
14
17
|
const uiState = expenseAutomationTransactionsViewState.transactionCategorizationView[selectedTab].uiState;
|
|
15
18
|
const { pageToken, sortOrder, sortKey } = uiState;
|
|
19
|
+
const requestSearchString = uiState.searchString;
|
|
16
20
|
const currentTenant = getCurrentTenant(state$.value);
|
|
17
21
|
const selectedPeriod = selectedPeriodByTenantId[currentTenant.tenantId];
|
|
18
22
|
const queryParam = {
|
|
@@ -24,6 +28,10 @@ export const fetchTransactionCategorizationEpic = (actions$, state$, zeniAPI) =>
|
|
|
24
28
|
page_token: pageToken,
|
|
25
29
|
page_size: 25,
|
|
26
30
|
search_text: uiState.searchString,
|
|
31
|
+
// Always scope to the active tab's auto_categorized status;
|
|
32
|
+
// cross-status search (omit or true) is reserved for Receipts
|
|
33
|
+
// manual-match.
|
|
34
|
+
search_all_statuses: false,
|
|
27
35
|
sub_tab: selectedTab === 'autoCategorized'
|
|
28
36
|
? expenseAutomationTransactionsViewState.selectedTransactionCategorizationCompletedSubTab
|
|
29
37
|
: DEFAULT_COMPLETED_SUB_TAB,
|
|
@@ -31,15 +39,37 @@ export const fetchTransactionCategorizationEpic = (actions$, state$, zeniAPI) =>
|
|
|
31
39
|
return zeniAPI
|
|
32
40
|
.getJSON(`${zeniAPI.apiEndPoints.accountMicroServiceBaseUrl}/1.0/expense-automation/transactions?query=${encodeURIComponent(JSON.stringify(queryParam))}`)
|
|
33
41
|
.pipe(mergeMap((response) => {
|
|
42
|
+
// Stale-response guard: if search was cleared while this
|
|
43
|
+
// request was in-flight (restoreFullDatasetSnapshot ran),
|
|
44
|
+
// discard results and errors to avoid overwriting the restored
|
|
45
|
+
// IDs/counts or marking the tab as Error. Covers both the
|
|
46
|
+
// success and failure branches. switchMap only cancels on a new
|
|
47
|
+
// fetchTransactionCategorization for the same tab; restore
|
|
48
|
+
// doesn't dispatch one, so we guard here instead.
|
|
49
|
+
const currentSearchString = state$.value.expenseAutomationTransactionsViewState
|
|
50
|
+
.transactionCategorizationView[selectedTab].uiState
|
|
51
|
+
.searchString;
|
|
52
|
+
if (currentSearchString !== requestSearchString) {
|
|
53
|
+
return EMPTY;
|
|
54
|
+
}
|
|
34
55
|
if (isSuccessResponse(response) && response.data != null) {
|
|
35
56
|
const updateActions = [];
|
|
36
57
|
updateActions.push(updateTransactions(response.data.transactions, (value) => value.transaction_id, 'merge'));
|
|
37
58
|
const transactionIds = response.data.transactions.map((transaction) => transaction.transaction_id);
|
|
38
59
|
const lineItemsByTransactionIds = getLineItemsByTransactionsIdsFromResponse(response.data.transactions);
|
|
60
|
+
// Only propagate the fields the response provides (pageToken).
|
|
61
|
+
// Do NOT spread the captured uiState — that would re-apply
|
|
62
|
+
// searchString/sortKey/etc. from request-start and overwrite
|
|
63
|
+
// any state changes made during the in-flight request (e.g.
|
|
64
|
+
// user clearing search triggers restoreFullDatasetSnapshot
|
|
65
|
+
// before this response lands).
|
|
66
|
+
// pageToken is also set by saveTransactionCategorizationLocalData
|
|
67
|
+
// via initializeTransactionCategorizationViewLocalDataEpic, so
|
|
68
|
+
// null values are handled correctly there regardless of the
|
|
69
|
+
// != null guard in updateTransactionCategorizationUIState.
|
|
39
70
|
updateActions.push(updateTransactionCategorizationUIState({
|
|
40
71
|
selectedTab,
|
|
41
72
|
uiState: {
|
|
42
|
-
...uiState,
|
|
43
73
|
pageToken: response.data.next_page_token ?? null,
|
|
44
74
|
},
|
|
45
75
|
}));
|
|
@@ -73,10 +103,18 @@ export const fetchTransactionCategorizationEpic = (actions$, state$, zeniAPI) =>
|
|
|
73
103
|
status: response.status,
|
|
74
104
|
}));
|
|
75
105
|
}
|
|
76
|
-
}), catchError((error) =>
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
}
|
|
106
|
+
}), catchError((error) => {
|
|
107
|
+
const currentSearchString = state$.value.expenseAutomationTransactionsViewState
|
|
108
|
+
.transactionCategorizationView[selectedTab].uiState
|
|
109
|
+
.searchString;
|
|
110
|
+
if (currentSearchString !== requestSearchString) {
|
|
111
|
+
return EMPTY;
|
|
112
|
+
}
|
|
113
|
+
return of(fetchTransactionCategorizationFailure({
|
|
114
|
+
selectedPeriod,
|
|
115
|
+
selectedTab,
|
|
116
|
+
status: createZeniAPIStatus('Unexpected Error', 'fetch Transaction Categorization REST API call errored out' +
|
|
117
|
+
JSON.stringify(error)),
|
|
118
|
+
}));
|
|
119
|
+
}));
|
|
120
|
+
}))));
|
|
@@ -7,6 +7,7 @@ import { fetchClassList } from '../../../classList/classListReducer';
|
|
|
7
7
|
import { fetchOwnerList } from '../../../ownerList/ownerListReducer';
|
|
8
8
|
import { fetchProjectList } from '../../../projectList/projectListReducer';
|
|
9
9
|
import { fetchTransactionCategorization, fetchTransactionCategorizationView, } from '../../reducers/transactionsViewReducer';
|
|
10
|
+
import { TRANSACTIONS_TABS } from '../../types/transactionsViewState';
|
|
10
11
|
export const fetchTransactionCategorizationViewEpic = (actions$, state$) => actions$.pipe(filter(fetchTransactionCategorizationView.match), mergeMap((action) => {
|
|
11
12
|
const { selectedTab, cacheOverride, keepExistingListItems, pageToken, period, refreshViewInBackground, searchString, resetListItems, isUncategorizedExpenseCategoryEnabled, } = action.payload;
|
|
12
13
|
const updateActions = [];
|
|
@@ -16,8 +17,8 @@ export const fetchTransactionCategorizationViewEpic = (actions$, state$) => acti
|
|
|
16
17
|
month: period.start.month,
|
|
17
18
|
year: period.start.year,
|
|
18
19
|
};
|
|
19
|
-
const
|
|
20
|
-
|
|
20
|
+
const periodId = toMonthYearPeriodId(monthYearPeriod);
|
|
21
|
+
const transactionIds = transactionIdsBySelectedPeriod[periodId] ?? [];
|
|
21
22
|
const accountList = state$.value.accountListState.byReportId['accountList'];
|
|
22
23
|
if (accountList.hasValidState() === false &&
|
|
23
24
|
accountList.fetchState === 'Not-Started') {
|
|
@@ -39,10 +40,36 @@ export const fetchTransactionCategorizationViewEpic = (actions$, state$) => acti
|
|
|
39
40
|
vendorOwnerList.fetchState === 'Not-Started') {
|
|
40
41
|
updateActions.push(fetchOwnerList());
|
|
41
42
|
}
|
|
42
|
-
if (
|
|
43
|
+
if (searchString === '' ||
|
|
44
|
+
cacheOverride === true ||
|
|
43
45
|
fetchState === 'Not-Started' ||
|
|
44
46
|
transactionIds.length === 0) {
|
|
45
47
|
updateActions.push(fetchTransactionCategorization(selectedTab, period, cacheOverride, keepExistingListItems, searchString, pageToken, refreshViewInBackground, resetListItems, isUncategorizedExpenseCategoryEnabled));
|
|
46
48
|
}
|
|
49
|
+
// On the initial load of a tab (searchString undefined = non-search fetch),
|
|
50
|
+
// preload every other tab that hasn't been fetched yet for this period.
|
|
51
|
+
// This makes switching to the other tab instant instead of triggering a
|
|
52
|
+
// fresh fetch on click. refreshViewInBackground=true keeps it silent.
|
|
53
|
+
if (searchString === undefined) {
|
|
54
|
+
TRANSACTIONS_TABS.filter((tab) => tab !== selectedTab).forEach((otherTab) => {
|
|
55
|
+
const otherTabFetchState = expenseAutomationTransactionsViewState.transactionCategorizationView[otherTab].fetchState;
|
|
56
|
+
if (otherTabFetchState === 'Not-Started') {
|
|
57
|
+
updateActions.push(fetchTransactionCategorization(otherTab, period, false, false, undefined, undefined, true, undefined, isUncategorizedExpenseCategoryEnabled));
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
// When search changes (searchString defined, including empty string to
|
|
62
|
+
// clear), also update every other tab so all tabs always reflect the same
|
|
63
|
+
// search query. Skip if the other tab already has this search string to
|
|
64
|
+
// avoid redundant work on noop updates. On clear, restore from snapshot
|
|
65
|
+
// if available; otherwise issue a background fetch.
|
|
66
|
+
if (searchString !== undefined) {
|
|
67
|
+
TRANSACTIONS_TABS.filter((tab) => tab !== selectedTab).forEach((otherTab) => {
|
|
68
|
+
const otherTabSearchString = expenseAutomationTransactionsViewState.transactionCategorizationView[otherTab].uiState.searchString;
|
|
69
|
+
if (searchString !== otherTabSearchString) {
|
|
70
|
+
updateActions.push(fetchTransactionCategorization(otherTab, period, true, keepExistingListItems, searchString, undefined, true, true, isUncategorizedExpenseCategoryEnabled));
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
}
|
|
47
74
|
return from(updateActions);
|
|
48
75
|
}));
|