@zeniai/client-epic-state 5.0.81-betaJK7 → 5.0.81-betaML3
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/lib/commonStateTypes/viewAndReport/viewAndReport.d.ts +2 -2
- package/lib/commonStateTypes/viewAndReport/viewAndReport.js +2 -0
- package/lib/entity/account/accountSelector.d.ts +9 -0
- package/lib/entity/account/accountSelector.js +14 -1
- package/lib/entity/account/accountState.d.ts +1 -1
- package/lib/entity/accountGroup/accountGroupState.d.ts +1 -1
- package/lib/entity/class/classReducer.d.ts +4 -4
- package/lib/entity/class/classState.d.ts +1 -1
- package/lib/entity/forecast/forecastState.d.ts +1 -1
- package/lib/entity/sectionAccountsView/sectionAccountsView.d.ts +1 -1
- package/lib/entity/sectionClassesViewV2/sectionClassesView.d.ts +1 -1
- package/lib/entity/sectionClassesViewV2/sectionClassesViewReducer.d.ts +2 -2
- package/lib/entity/sectionProjectView/sectionProjectView.d.ts +1 -1
- package/lib/entity/sectionProjectView/sectionProjectViewReducer.d.ts +2 -2
- package/lib/entity/snackbar/snackbarTypes.d.ts +1 -1
- package/lib/entity/snackbar/snackbarTypes.js +1 -0
- package/lib/entity/task/taskPayload.d.ts +1 -3
- package/lib/entity/task/taskPayload.js +0 -2
- package/lib/entity/task/taskState.d.ts +0 -2
- package/lib/entity/tenant/clearAllEpic.d.ts +2 -1
- package/lib/entity/tenant/clearAllEpic.js +2 -0
- package/lib/entity/transaction/payloadTypes/transactionPayload.d.ts +4 -0
- package/lib/entity/transaction/payloadTypes/transactionPayload.js +18 -10
- package/lib/entity/transaction/stateTypes/transaction.d.ts +3 -0
- package/lib/epic.d.ts +3 -2
- package/lib/epic.js +3 -2
- package/lib/esm/commonStateTypes/viewAndReport/viewAndReport.js +2 -0
- package/lib/esm/entity/account/accountSelector.js +11 -0
- package/lib/esm/entity/snackbar/snackbarTypes.js +1 -0
- package/lib/esm/entity/task/taskPayload.js +0 -2
- package/lib/esm/entity/tenant/clearAllEpic.js +2 -0
- package/lib/esm/entity/transaction/payloadTypes/transactionPayload.js +18 -10
- package/lib/esm/epic.js +3 -2
- package/lib/esm/index.js +8 -7
- package/lib/esm/reducer.js +3 -0
- package/lib/esm/view/companyTaskManagerView/companyTaskManagerViewReducer.js +11 -26
- package/lib/esm/view/companyTaskManagerView/epics/fetchCompanyTaskManagerViewEpic.js +28 -37
- package/lib/esm/view/companyView/epic/fetchAllCockpitViewsEpic.js +2 -2
- package/lib/esm/view/createTransferEntry/createTransferEntryReducer.js +82 -0
- package/lib/esm/view/createTransferEntry/createTransferEntrySelector.js +64 -0
- package/lib/esm/view/createTransferEntry/createTransferEntryState.js +17 -0
- package/lib/esm/view/createTransferEntry/epics/createTransferEntryEpic.js +130 -0
- package/lib/esm/view/createTransferEntry/epics/fetchTransferAccountsEpic.js +37 -0
- package/lib/esm/view/expenseAutomationView/reducers/transactionsViewReducer.js +13 -1
- package/lib/esm/view/expenseAutomationView/selectors/transactionCategorizationSelector.js +9 -1
- package/lib/esm/view/transactionDetail/transactionDetailSelector.js +6 -1
- package/lib/index.d.ts +9 -8
- package/lib/index.js +46 -37
- package/lib/reducer.d.ts +3 -0
- package/lib/reducer.js +3 -0
- package/lib/view/auditReportView/auditReportViewState.d.ts +1 -1
- package/lib/view/billPayCard/billPayCardSelector.d.ts +1 -1
- package/lib/view/cardBalance/cardBalanceSelector.d.ts +1 -1
- package/lib/view/cashBalance/cashBalanceSelector.d.ts +1 -1
- package/lib/view/cashInCashOut/cashInCashOutSelector.d.ts +1 -1
- package/lib/view/cashPosition/cashPositionSelector.d.ts +1 -1
- package/lib/view/companyTaskManagerView/companyTaskManagerViewPayload.d.ts +15 -13
- package/lib/view/companyTaskManagerView/companyTaskManagerViewReducer.d.ts +4 -5
- package/lib/view/companyTaskManagerView/companyTaskManagerViewReducer.js +12 -27
- package/lib/view/companyTaskManagerView/companyTaskManagerViewState.d.ts +3 -3
- package/lib/view/companyTaskManagerView/epics/fetchCompanyTaskManagerViewEpic.d.ts +3 -1
- package/lib/view/companyTaskManagerView/epics/fetchCompanyTaskManagerViewEpic.js +28 -37
- package/lib/view/companyView/epic/fetchAllCockpitViewsEpic.js +2 -2
- package/lib/view/companyView/types/cockpitTypes.d.ts +1 -2
- package/lib/view/createTransferEntry/createTransferEntryReducer.d.ts +32 -0
- package/lib/view/createTransferEntry/createTransferEntryReducer.js +86 -0
- package/lib/view/createTransferEntry/createTransferEntrySelector.d.ts +39 -0
- package/lib/view/createTransferEntry/createTransferEntrySelector.js +69 -0
- package/lib/view/createTransferEntry/createTransferEntryState.d.ts +30 -0
- package/lib/view/createTransferEntry/createTransferEntryState.js +20 -0
- package/lib/view/createTransferEntry/epics/createTransferEntryEpic.d.ts +11 -0
- package/lib/view/createTransferEntry/epics/createTransferEntryEpic.js +134 -0
- package/lib/view/createTransferEntry/epics/fetchTransferAccountsEpic.d.ts +14 -0
- package/lib/view/createTransferEntry/epics/fetchTransferAccountsEpic.js +41 -0
- package/lib/view/dashboard/dashboardReducer.d.ts +2 -2
- package/lib/view/expenseAutomationView/helpers/transactionCategorizationLocalDataHelper.d.ts +1 -1
- package/lib/view/expenseAutomationView/reducers/transactionsViewReducer.d.ts +3 -1
- package/lib/view/expenseAutomationView/reducers/transactionsViewReducer.js +14 -2
- package/lib/view/expenseAutomationView/selectorTypes/transactionsViewSelectorTypes.d.ts +4 -1
- package/lib/view/expenseAutomationView/selectors/transactionCategorizationSelector.d.ts +1 -0
- package/lib/view/expenseAutomationView/selectors/transactionCategorizationSelector.js +11 -2
- package/lib/view/financeStatement/financeStatementReducer.d.ts +1 -1
- package/lib/view/globalMerchantView/globalMerchantViewReducer.d.ts +2 -2
- package/lib/view/reimbursementCard/reimbursementCardSelector.d.ts +1 -1
- package/lib/view/reportsResync/reportsResyncReducer.d.ts +2 -2
- package/lib/view/tasksCard/tasksCardSelector.d.ts +1 -1
- package/lib/view/topEx/topExSelector.d.ts +1 -1
- package/lib/view/transactionDetail/transactionDetailPayload.d.ts +1 -1
- package/lib/view/transactionDetail/transactionDetailSelector.d.ts +6 -1
- package/lib/view/transactionDetail/transactionDetailSelector.js +6 -1
- package/package.json +1 -1
- package/lib/esm/view/companyTaskManagerView/epics/updateCompanyTaskManagerViewUIStateEpic.js +0 -16
- package/lib/view/companyTaskManagerView/epics/updateCompanyTaskManagerViewUIStateEpic.d.ts +0 -6
- package/lib/view/companyTaskManagerView/epics/updateCompanyTaskManagerViewUIStateEpic.js +0 -20
package/lib/esm/index.js
CHANGED
|
@@ -144,7 +144,7 @@ import { clearCompanyHealthMetricView, fetchCompanyHealthMetricView, initializeC
|
|
|
144
144
|
import { companyHealthMetricDropDownOptions, getCompanyHealthMetricView, hasCompanyHealthMetricFormFieldChanged, isCompanyRunwayInfinite, } from './view/companyHealthMetricView/companyHealthMetricViewSelector';
|
|
145
145
|
import { fetchCompanyMonthEndReportHistoricData, fetchCompanyMonthEndReportHistoricDates, fetchCompanyMonthEndReportTemplates, fetchCompanyMonthEndReportView, fetchImproveUsingZeniGPT, resetCompanyMonthEndReportFetchStatus, resetSendCompanyMonthEndReportFetchStatus, saveCompanyMonthEndReport, sendCompanyMonthEndReport, } from './view/companyMonthEndReportView/companyMonthEndReportViewReducer';
|
|
146
146
|
import { getCompanyMonthEndReportHistoricData, getCompanyMonthEndReportSelectorView, } from './view/companyMonthEndReportView/companyMonthEndReportViewSelector';
|
|
147
|
-
import { fetchCompanyTaskManagerView, fetchTaskManagerMetrics,
|
|
147
|
+
import { fetchCompanyTaskManagerView, fetchTaskManagerMetrics, } from './view/companyTaskManagerView/companyTaskManagerViewReducer';
|
|
148
148
|
import { getCompanyTaskManagerView, } from './view/companyTaskManagerView/companyTaskManagerViewSelector';
|
|
149
149
|
import { clearCompanyView, companyManagementSaveUpdates, companyPassportClearDataInLocalStore, companyPassportSaveDataInLocalStore, deleteCompanyOfficerInLocalStore, fetchAllCockpitViews, fetchCompanyManagementView, fetchCompanyPassportView, fetchCompanyPortfolioView, fetchManagementView, fetchOnboardingView, fetchParentSubsidiaryManagementView, fetchPortfolioView, fetchSubscriptionView, fetchZeniUsers, saveCompanyPassportDetails, saveIndustryAndIncDateInCompanyPassportLocalStore, updateAccountingClassesEnabled, updateCompanyDownloadState, updateCompanyManagementUIState, updateCompanyPassportLocalStoreData, updateCompanyPortfolioUIState, } from './view/companyView/companyViewReducer';
|
|
150
150
|
import { canSendMonthEndEmailReport, shouldEnableCalendarPickerForLastReportSent, } from './view/companyView/helpers/cockpitHelpers';
|
|
@@ -156,6 +156,7 @@ import { getAllCockpitTabsFilterView, } from './view/companyView/selector/getAll
|
|
|
156
156
|
import { ALL_COCKPIT_TABS_FILE_TYPES, ALL_COCKPIT_TABS_IDS, toCockpitTabsFileTypeStrict, toCockpitTabsIDStrict, } from './view/companyView/types/cockpitTabsID';
|
|
157
157
|
import { toHealthSortKeyType, toManagementSortKeyType, toOnboardingSortKeyType, toPortfolioSortKeyType, toTaskManagerSortKeyType, } from './view/companyView/types/cockpitTypes';
|
|
158
158
|
import { toCompanyPassportLocalData, } from './view/companyView/types/companyPassport/companyPassportLocalData';
|
|
159
|
+
import { clearTransferEntryRouteReplacement, createTransferEntry, createTransferEntryFailure, createTransferEntryReplacedTransaction, createTransferEntrySuccess, fetchAccountsForTransferFlow, resetCreateTransferEntryStatus, } from './view/createTransferEntry/createTransferEntryReducer';
|
|
159
160
|
import { fetchDashboard, updateTreasuryVideoClosed, } from './view/dashboard/dashboardReducer';
|
|
160
161
|
import { getDashboard, } from './view/dashboard/dashboardSelector';
|
|
161
162
|
import { updateDashboardLayout } from './view/dashboardLayout/dashboardLayoutReducer';
|
|
@@ -169,11 +170,10 @@ import { clearExpenseAutomationFluxAnalysisView, fetchFluxAnalysisView, reviewFl
|
|
|
169
170
|
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';
|
|
170
171
|
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';
|
|
171
172
|
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';
|
|
172
|
-
import { backgroundRefetchReviewTab, clearExpenseAutomationTransactionsView, fetchTransactionCategorization, fetchTransactionCategorizationFailure, fetchTransactionCategorizationView, initializeTransactionCategorizationViewLocalData, markCategoryClassRecommendationsFailureForCategorization, markTransactionAsNotMiscategorized, saveTransactionCategorization, saveTransactionCategorizationLocalData, setAllItemsToCategoryClassInLocalDataForCategorization, setEntityRecommendationForLineIdsForCategorization, syncTransactionCategorizationFromDetailSave, updateCurrentSelectedTransactionCategorizationTab, updateSelectedCheckboxTransactionIds, updateSelectedCustomerForTransaction, updateSelectedTransactionId, updateSelectedVendorForTransaction, updateTransactionCategorization, updateTransactionCategorizationCompletedSubTab, updateTransactionCategorizationSaveStatus, updateTransactionCategorizationUIState, updateTransactionCategorizationUploadReceiptState, updateTransactionFilters, uploadTransactionCategorizationReceiptSuccess, } from './view/expenseAutomationView/reducers/transactionsViewReducer';
|
|
173
|
+
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';
|
|
173
174
|
import { getExpenseAutomationFluxAnalysisView } from './view/expenseAutomationView/selectors/fluxAnalysisViewSelector';
|
|
174
175
|
import { getExpenseAutomationReconciliationView, isAccountReconReport, } from './view/expenseAutomationView/selectors/reconciliationViewSelector';
|
|
175
|
-
import { getExpenseAutomationTransactionView } from './view/expenseAutomationView/selectors/transactionCategorizationSelector';
|
|
176
|
-
import { TRANSACTION_FILTER_CATEGORIES, applyTransactionFilters, } from './view/expenseAutomationView/transactionFilterHelpers';
|
|
176
|
+
import { getExpenseAutomationTransactionView, getLastTransferEntryReplacement, } from './view/expenseAutomationView/selectors/transactionCategorizationSelector';
|
|
177
177
|
import { DEFAULT_COMPLETED_SUB_TAB, toCompletedSubTab, } from './view/expenseAutomationView/types/completedSubTab';
|
|
178
178
|
import { toJEScheduleMainTab as toExpenseAutomationJEScheduleMainTab, toJEScheduleSortKey as toExpenseAutomationJEScheduleSortKey, } from './view/expenseAutomationView/types/jeSchedulesViewState';
|
|
179
179
|
import { BATCH_FILE_STATUSES, isUnmatchedTabFileStatus, toBatchFileStatus, toBatchStatusValue, toBulkUploadPhase, toBulkUploadResultsTab, toBulkUploadSortKey, toMatchSource, toMissingReceiptsTab, } from './view/expenseAutomationView/types/missingReceiptsViewState';
|
|
@@ -338,6 +338,7 @@ import { getRemiBusinessVerificationDetails, getRemiSetupViewDetails, } from './
|
|
|
338
338
|
import { approveOrRejectRemisBulkAction, autoReviewPendingApprovalRemis, cancelOrDeleteRemisBulkAction, clearAllRemisFromBulkActionList, clearRemiBulkActionView, incrementRemiBulkActionProcessedCount, removeRemiFromBulkActionList, reviewDraftRemisBulkAction, submitDraftRemisBulkAction, updateRemisBulkActionList, } from './view/spendManagement/reimbursement/remisBulkActionView/remisBulkActionViewReducer';
|
|
339
339
|
import { getRemisBulkOperationProgress, getRemisBulkReviewView, } from './view/spendManagement/reimbursement/remisBulkActionView/remisBulkActionViewSelector';
|
|
340
340
|
import { hideCreatedByFilter, } from './view/spendManagement/spendManagementFilterHelpers';
|
|
341
|
+
import { TRANSACTION_FILTER_CATEGORIES, applyTransactionFilters, } from './view/expenseAutomationView/transactionFilterHelpers';
|
|
341
342
|
import { acceptTreasuryTerms, clearTreasurySetupView, fetchPortfolioAllocation, fetchTreasuryFunds, fetchTreasurySetupView, updateFundAllocationLocalData, updatePortfolioAllocation, updateTreasuryVideoViewed, } from './view/spendManagement/treasury/treasurySetUp/treasurySetupViewReducer';
|
|
342
343
|
import { getTreasuryBusinessVerificationDetails, getTreasurySetupViewDetails, } from './view/spendManagement/treasury/treasurySetUp/treasurySetupViewSelector';
|
|
343
344
|
import { getTreasuryFundsMaximumYield, } from './view/spendManagement/treasury/treasurySetUp/treasurySetupViewState';
|
|
@@ -449,8 +450,8 @@ export {
|
|
|
449
450
|
// Bulk Upload Types
|
|
450
451
|
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,
|
|
451
452
|
// Bulk Upload Actions
|
|
452
|
-
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, 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, };
|
|
453
|
-
export { fetchTransactionCategorization, fetchTransactionCategorizationView, updateTransactionCategorizationUIState, updateTransactionFilters, updateSelectedCheckboxTransactionIds, markCategoryClassRecommendationsFailureForCategorization, setEntityRecommendationForLineIdsForCategorization, initializeTransactionCategorizationViewLocalData, setAllItemsToCategoryClassInLocalDataForCategorization, saveTransactionCategorizationLocalData, fetchTransactionCategorizationFailure, saveTransactionCategorization, updateTransactionCategorization, updateTransactionCategorizationSaveStatus, markTransactionAsNotMiscategorized, updateSelectedVendorForTransaction, updateSelectedCustomerForTransaction, updateSelectedTransactionId, syncTransactionCategorizationFromDetailSave, backgroundRefetchReviewTab, clearExpenseAutomationTransactionsView, toTransactionsSortKey, };
|
|
453
|
+
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, };
|
|
454
|
+
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, };
|
|
454
455
|
export { TOP_EX_TIME_PERIODS };
|
|
455
456
|
export { toTimeframeTick, mapTimePeriodtoTimeframeTick, toTimePeriod, toAbsoluteDay, toMonthYearPeriodId, convertToPeriod, };
|
|
456
457
|
export { toVendorSpendTrendFilterTabsTypeStrict, } from './entity/vendorExpense/vendorExpenseSelector';
|
|
@@ -535,7 +536,7 @@ export { getCompanyPortfolioView, isInfiniteRunway };
|
|
|
535
536
|
export { getAllCockpitTabsFilterView };
|
|
536
537
|
export { fetchImproveUsingZeniGPT, fetchCompanyMonthEndReportView, sendCompanyMonthEndReport, saveCompanyMonthEndReport, resetCompanyMonthEndReportFetchStatus, resetSendCompanyMonthEndReportFetchStatus, getCompanyMonthEndReportSelectorView, fetchCompanyMonthEndReportHistoricDates, fetchCompanyMonthEndReportHistoricData, fetchCompanyMonthEndReportTemplates, getCompanyMonthEndReportHistoricData, };
|
|
537
538
|
export { newAddressInLocalStore, getAddress, getNewAddress, getAllNewAddresses, getFormattedAddress, fetchAddress, clearAddressView, createAddress, removeNewAddressDataInLocalStore, };
|
|
538
|
-
export { toManagementSortKeyType, toOnboardingSortKeyType, toPortfolioSortKeyType, toHealthSortKeyType, toTaskManagerSortKeyType,
|
|
539
|
+
export { toManagementSortKeyType, toOnboardingSortKeyType, toPortfolioSortKeyType, toHealthSortKeyType, toTaskManagerSortKeyType, };
|
|
539
540
|
export { ALL_COCKPIT_TABS_FILE_TYPES, ALL_COCKPIT_TABS_IDS, toCockpitTabsIDStrict, toCockpitTabsFileTypeStrict, };
|
|
540
541
|
export { isAllowedValueWithCode, isAllowedValueWithID, };
|
|
541
542
|
export { fetchCompanyPassportView, getCompanyPassportView, getCompanyPassportLocalStoreData, isCompanyPassportDataToBeSaved, companyPassportSaveDataInLocalStore, saveIndustryAndIncDateInCompanyPassportLocalStore, deleteCompanyOfficerInLocalStore, companyPassportClearDataInLocalStore, updateCompanyPassportLocalStoreData, saveCompanyPassportDetails, updateAccountingClassesEnabled, clearCompanyView, };
|
package/lib/esm/reducer.js
CHANGED
|
@@ -98,6 +98,7 @@ import companyHealthMetricView, { initialState as initialCompanyHealthMetricView
|
|
|
98
98
|
import companyMonthEndReportView, { initialState as initialCompanyMonthEndReportViewState, } from './view/companyMonthEndReportView/companyMonthEndReportViewReducer';
|
|
99
99
|
import companyTaskManagerView, { initialState as initialCompanyTaskManagerViewState, } from './view/companyTaskManagerView/companyTaskManagerViewReducer';
|
|
100
100
|
import companyView, { initialState as initialCompanyViewState, } from './view/companyView/companyViewReducer';
|
|
101
|
+
import createTransferEntry, { initialState as initialCreateTransferEntryState, } from './view/createTransferEntry/createTransferEntryReducer';
|
|
101
102
|
import creditAgentView, { initialState as initialCreditAgentViewState, } from './view/creditAgentView/creditAgentViewReducer';
|
|
102
103
|
import dashboard, { initialState as initialDashboardState, } from './view/dashboard/dashboardReducer';
|
|
103
104
|
import dashboardLayout, { initialState as initialDashboardLayoutState, } from './view/dashboardLayout/dashboardLayoutReducer';
|
|
@@ -360,6 +361,7 @@ const initialViewsState = {
|
|
|
360
361
|
expenseAutomationReconciliationViewState: initialExpenseAutomationReconciliationViewState,
|
|
361
362
|
expenseAutomationTransactionsViewState: initialExpenseAutomationTransactionsViewState,
|
|
362
363
|
expenseAutomationViewState: initialExpenseAutomationViewState,
|
|
364
|
+
createTransferEntryState: initialCreateTransferEntryState,
|
|
363
365
|
expressPayState: initialExpressPayState,
|
|
364
366
|
featureNotificationViewState: initialFeatureNotificationViewState,
|
|
365
367
|
fileViewState: initialFileViewState,
|
|
@@ -595,6 +597,7 @@ const viewReducers = {
|
|
|
595
597
|
expenseAutomationReconciliationViewState: expenseAutomationReconciliationView,
|
|
596
598
|
expenseAutomationTransactionsViewState: expenseAutomationTransactionsView,
|
|
597
599
|
expenseAutomationViewState: expenseAutomationView,
|
|
600
|
+
createTransferEntryState: createTransferEntry,
|
|
598
601
|
expressPayState: expressPay,
|
|
599
602
|
featureNotificationViewState: featureNotificationView,
|
|
600
603
|
fileViewState: fileView,
|
|
@@ -3,8 +3,7 @@ export const initialUIState = {
|
|
|
3
3
|
filterText: '',
|
|
4
4
|
sortKey: 'dueDate',
|
|
5
5
|
sortOrder: 'descending',
|
|
6
|
-
|
|
7
|
-
filters: {},
|
|
6
|
+
pageToken: null,
|
|
8
7
|
};
|
|
9
8
|
const initialMetrics = {
|
|
10
9
|
closed: 0,
|
|
@@ -29,11 +28,10 @@ const companyTaskManagerView = createSlice({
|
|
|
29
28
|
initialState,
|
|
30
29
|
reducers: {
|
|
31
30
|
fetchCompanyTaskManagerView: {
|
|
32
|
-
prepare(
|
|
31
|
+
prepare(pageToken, sortKey, sortOrder, keepExistingListItems = true, searchString) {
|
|
33
32
|
return {
|
|
34
33
|
payload: {
|
|
35
|
-
|
|
36
|
-
filters,
|
|
34
|
+
pageToken,
|
|
37
35
|
searchString,
|
|
38
36
|
sortKey,
|
|
39
37
|
sortOrder,
|
|
@@ -42,10 +40,10 @@ const companyTaskManagerView = createSlice({
|
|
|
42
40
|
};
|
|
43
41
|
},
|
|
44
42
|
reducer(draft, action) {
|
|
45
|
-
const {
|
|
43
|
+
const { pageToken, searchString, sortKey, sortOrder, keepExistingListItems, } = action.payload;
|
|
46
44
|
draft.uiState.sortKey = sortKey;
|
|
47
45
|
draft.uiState.sortOrder = sortOrder;
|
|
48
|
-
draft.uiState.
|
|
46
|
+
draft.uiState.pageToken = pageToken;
|
|
49
47
|
if (keepExistingListItems === false) {
|
|
50
48
|
draft.taskIds = [];
|
|
51
49
|
}
|
|
@@ -58,14 +56,15 @@ const companyTaskManagerView = createSlice({
|
|
|
58
56
|
},
|
|
59
57
|
updateCompanyTaskManagerViewOnSuccess(draft, action) {
|
|
60
58
|
const { data } = action.payload;
|
|
61
|
-
const tasks = data
|
|
59
|
+
const { tasks, query, total_count } = data;
|
|
62
60
|
draft.fetchState = 'Completed';
|
|
63
61
|
draft.error = undefined;
|
|
64
62
|
draft.taskIds = [...draft.taskIds, ...tasks.map((task) => task.task_id)];
|
|
65
|
-
|
|
66
|
-
|
|
63
|
+
// consider total count only when fetching for first time
|
|
64
|
+
if (draft.uiState.filterText === '' && draft.uiState.pageToken == null) {
|
|
65
|
+
draft.totalTaskCount = total_count;
|
|
67
66
|
}
|
|
68
|
-
draft.uiState.
|
|
67
|
+
draft.uiState.pageToken = query.page_token;
|
|
69
68
|
},
|
|
70
69
|
updateCompanyTaskManagerViewOnFailure: {
|
|
71
70
|
reducer(draft, action) {
|
|
@@ -86,24 +85,10 @@ const companyTaskManagerView = createSlice({
|
|
|
86
85
|
updateTaskManagerMetricsOnFailure(draft) {
|
|
87
86
|
draft.metricsFetchState = 'Error';
|
|
88
87
|
},
|
|
89
|
-
updateCompanyTaskManagerViewUIState(draft, action) {
|
|
90
|
-
if (action.payload.filters != null) {
|
|
91
|
-
draft.uiState.filters = action.payload.filters;
|
|
92
|
-
}
|
|
93
|
-
if (action.payload.filterText != null) {
|
|
94
|
-
draft.uiState.filterText = action.payload.filterText;
|
|
95
|
-
}
|
|
96
|
-
if (action.payload.sortKey != null) {
|
|
97
|
-
draft.uiState.sortKey = action.payload.sortKey;
|
|
98
|
-
}
|
|
99
|
-
if (action.payload.sortOrder != null) {
|
|
100
|
-
draft.uiState.sortOrder = action.payload.sortOrder;
|
|
101
|
-
}
|
|
102
|
-
},
|
|
103
88
|
clearCompanyTaskManagerView(draft) {
|
|
104
89
|
Object.assign(draft, initialState);
|
|
105
90
|
},
|
|
106
91
|
},
|
|
107
92
|
});
|
|
108
|
-
export const { fetchCompanyTaskManagerView, updateCompanyTaskManagerViewOnSuccess, updateCompanyTaskManagerViewOnFailure, fetchTaskManagerMetrics, updateTaskManagerMetrics, updateTaskManagerMetricsOnFailure, clearCompanyTaskManagerView,
|
|
93
|
+
export const { fetchCompanyTaskManagerView, updateCompanyTaskManagerViewOnSuccess, updateCompanyTaskManagerViewOnFailure, fetchTaskManagerMetrics, updateTaskManagerMetrics, updateTaskManagerMetricsOnFailure, clearCompanyTaskManagerView, } = companyTaskManagerView.actions;
|
|
109
94
|
export default companyTaskManagerView.reducer;
|
|
@@ -1,35 +1,51 @@
|
|
|
1
1
|
import { from } from 'rxjs';
|
|
2
2
|
import { catchError, filter, mergeMap, switchMap } from 'rxjs/operators';
|
|
3
3
|
import { getSortOrder } from '../../../commonPayloadTypes/sortOrderPayload';
|
|
4
|
+
import { updateCompanies } from '../../../entity/company/companyReducer';
|
|
4
5
|
import { updateTags } from '../../../entity/tag/tagReducer';
|
|
5
6
|
import { updateTasks } from '../../../entity/task/taskReducer';
|
|
7
|
+
import { updateAllUsers } from '../../../entity/user/userReducer';
|
|
6
8
|
import { createZeniAPIStatus, isSuccessResponse } from '../../../responsePayload';
|
|
7
9
|
import { fetchCompanyTaskManagerView, updateCompanyTaskManagerViewOnFailure, updateCompanyTaskManagerViewOnSuccess, } from '../companyTaskManagerViewReducer';
|
|
8
|
-
const
|
|
10
|
+
const toSortKeyPayload = (sortKey) => {
|
|
11
|
+
switch (sortKey) {
|
|
12
|
+
case 'taskName':
|
|
13
|
+
return 'name';
|
|
14
|
+
case 'dueDate':
|
|
15
|
+
return 'due_date';
|
|
16
|
+
case 'createdBy':
|
|
17
|
+
return 'created_by';
|
|
18
|
+
case 'name':
|
|
19
|
+
return 'company_name';
|
|
20
|
+
default:
|
|
21
|
+
return sortKey;
|
|
22
|
+
}
|
|
23
|
+
};
|
|
9
24
|
export const fetchCompanyTaskManagerViewEpic = (actions$, _state$, zeniAPI) => actions$.pipe(filter(fetchCompanyTaskManagerView.match), switchMap((action) => {
|
|
10
|
-
const {
|
|
25
|
+
const { pageToken, sortKey, sortOrder, searchString } = action.payload;
|
|
11
26
|
const queryValue = {
|
|
12
|
-
|
|
13
|
-
size: DEFAULT_PAGE_SIZE,
|
|
14
|
-
from: fromOffset,
|
|
15
|
-
global_search: searchString ?? '',
|
|
27
|
+
page_token: pageToken,
|
|
16
28
|
sort_by: toSortKeyPayload(sortKey),
|
|
17
29
|
sort_order: getSortOrder(sortOrder),
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
: {}),
|
|
30
|
+
search_text: searchString ?? '',
|
|
31
|
+
view: 'cockpit_task_manager_view',
|
|
21
32
|
};
|
|
22
33
|
return zeniAPI
|
|
23
|
-
.getJSON(`${zeniAPI.apiEndPoints.tenantMicroServiceBaseUrl}/1.0/cockpit-panels/tasks
|
|
34
|
+
.getJSON(`${zeniAPI.apiEndPoints.tenantMicroServiceBaseUrl}/1.0/cockpit-panels/tasks?query=${encodeURIComponent(JSON.stringify(queryValue))}`)
|
|
24
35
|
.pipe(mergeMap((response) => {
|
|
25
36
|
if (isSuccessResponse(response) && response.data != null) {
|
|
26
|
-
const tasksList = response.data.
|
|
37
|
+
const tasksList = response.data.tasks;
|
|
27
38
|
const actions = [
|
|
28
39
|
updateCompanyTaskManagerViewOnSuccess({
|
|
29
40
|
data: response.data,
|
|
30
41
|
}),
|
|
31
42
|
updateTasks(tasksList),
|
|
32
|
-
|
|
43
|
+
updateCompanies({
|
|
44
|
+
payload: response.data.companies,
|
|
45
|
+
schema: {},
|
|
46
|
+
}),
|
|
47
|
+
updateTags(tasksList.map((task) => task.tags).flat()),
|
|
48
|
+
updateAllUsers({ users: response.data.users }),
|
|
33
49
|
];
|
|
34
50
|
return from(actions);
|
|
35
51
|
}
|
|
@@ -46,28 +62,3 @@ export const fetchCompanyTaskManagerViewEpic = (actions$, _state$, zeniAPI) => a
|
|
|
46
62
|
return from(actions);
|
|
47
63
|
}));
|
|
48
64
|
}));
|
|
49
|
-
const toSortKeyPayload = (sortKey) => {
|
|
50
|
-
switch (sortKey) {
|
|
51
|
-
case 'taskName':
|
|
52
|
-
return 'name';
|
|
53
|
-
case 'dueDate':
|
|
54
|
-
return 'due_date';
|
|
55
|
-
case 'createdBy':
|
|
56
|
-
return 'created_by';
|
|
57
|
-
case 'name':
|
|
58
|
-
return 'company_name';
|
|
59
|
-
default:
|
|
60
|
-
return sortKey;
|
|
61
|
-
}
|
|
62
|
-
};
|
|
63
|
-
const toFilterByPayload = (filters) => {
|
|
64
|
-
if (filters.categories == null) {
|
|
65
|
-
return [];
|
|
66
|
-
}
|
|
67
|
-
return filters.categories.map((category) => ({
|
|
68
|
-
field: category.field ?? '',
|
|
69
|
-
operator: category.matchingOperator === 'equal' ? 'is' : 'is_not',
|
|
70
|
-
values: category.values.map((v) => String(v)),
|
|
71
|
-
join: category.valuesCombinationOperator === 'ALL' ? 'and' : 'or',
|
|
72
|
-
}));
|
|
73
|
-
};
|
|
@@ -21,7 +21,7 @@ export const fetchAllCockpitViewsEpic = (actions$, state$) => actions$.pipe(filt
|
|
|
21
21
|
fetchReviewCompanyView(),
|
|
22
22
|
fetchCompanyHealthMetricView(),
|
|
23
23
|
fetchCompanyMetaData(),
|
|
24
|
-
fetchCompanyTaskManagerView(
|
|
24
|
+
fetchCompanyTaskManagerView(null, 'dueDate', 'descending', false),
|
|
25
25
|
fetchCompanyHealthMetricConfig(),
|
|
26
26
|
]);
|
|
27
27
|
}
|
|
@@ -74,7 +74,7 @@ export const fetchAllCockpitViewsEpic = (actions$, state$) => actions$.pipe(filt
|
|
|
74
74
|
}
|
|
75
75
|
if (state.companyTaskManagerViewState.fetchState !== 'In-Progress' &&
|
|
76
76
|
state.companyTaskManagerViewState.hasValidState() === false) {
|
|
77
|
-
fetchActions.push(fetchCompanyTaskManagerView(
|
|
77
|
+
fetchActions.push(fetchCompanyTaskManagerView(null, 'dueDate', 'descending', false));
|
|
78
78
|
}
|
|
79
79
|
return from(fetchActions);
|
|
80
80
|
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { createSlice } from '@reduxjs/toolkit';
|
|
2
|
+
import { initialCreateTransferEntryState, } from './createTransferEntryState';
|
|
3
|
+
export const initialState = initialCreateTransferEntryState;
|
|
4
|
+
const createTransferEntrySlice = createSlice({
|
|
5
|
+
name: 'createTransferEntry',
|
|
6
|
+
initialState,
|
|
7
|
+
reducers: {
|
|
8
|
+
fetchAccountsForTransferFlow(draft, action) {
|
|
9
|
+
const slice = draft.transferAccountsByType[action.payload.kind];
|
|
10
|
+
// Idempotent: a duplicate dispatch must not briefly downgrade
|
|
11
|
+
// 'Completed' back to 'In-Progress' (would clear loaded data from a
|
|
12
|
+
// consumer's perspective) nor restart the in-flight epic stream.
|
|
13
|
+
// The hook (`useFetchTransferAccountsForFlow`) is the sole caller and
|
|
14
|
+
// already dedupes via `store.getState()`; this guard is defense in
|
|
15
|
+
// depth for any future caller.
|
|
16
|
+
if (slice.fetchState === 'In-Progress' ||
|
|
17
|
+
slice.fetchState === 'Completed') {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
slice.fetchState = 'In-Progress';
|
|
21
|
+
},
|
|
22
|
+
updateAccountsForTransferFlow(draft, action) {
|
|
23
|
+
const slice = draft.transferAccountsByType[action.payload.kind];
|
|
24
|
+
slice.fetchState = 'Completed';
|
|
25
|
+
slice.accountIds = action.payload.accountIds;
|
|
26
|
+
},
|
|
27
|
+
updateAccountsForTransferFlowFailure(draft, action) {
|
|
28
|
+
draft.transferAccountsByType[action.payload.kind].fetchState = 'Error';
|
|
29
|
+
},
|
|
30
|
+
createTransferEntry: {
|
|
31
|
+
prepare(payload) {
|
|
32
|
+
return { payload };
|
|
33
|
+
},
|
|
34
|
+
/**
|
|
35
|
+
* Defense-in-depth: clear any stale `lastTransferEntryReplacement` on a
|
|
36
|
+
* fresh dispatch so a second `createTransferEntry` never inherits the
|
|
37
|
+
* previous run's replacement signal (e.g. if the prior `timer(0)` cleanup
|
|
38
|
+
* never fired). Mirrors the host hook's `consumedReplacementRef` guard
|
|
39
|
+
* (see `useTransferEntryRouteReplacement` in zeni-web-app-ui).
|
|
40
|
+
*/
|
|
41
|
+
reducer(draft) {
|
|
42
|
+
draft.createTransferEntryStatus = 'In-Progress';
|
|
43
|
+
draft.lastTransferEntryReplacement = undefined;
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
createTransferEntrySuccess(draft) {
|
|
47
|
+
draft.createTransferEntryStatus = 'Completed';
|
|
48
|
+
},
|
|
49
|
+
createTransferEntryFailure(draft) {
|
|
50
|
+
draft.createTransferEntryStatus = 'Error';
|
|
51
|
+
},
|
|
52
|
+
resetCreateTransferEntryStatus(draft) {
|
|
53
|
+
draft.createTransferEntryStatus = 'Not-Started';
|
|
54
|
+
},
|
|
55
|
+
createTransferEntryReplacedTransaction: {
|
|
56
|
+
prepare(previousTransactionId, newTransactionId) {
|
|
57
|
+
return { payload: { newTransactionId, previousTransactionId } };
|
|
58
|
+
},
|
|
59
|
+
reducer(draft, action) {
|
|
60
|
+
draft.lastTransferEntryReplacement = action.payload;
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
/**
|
|
64
|
+
* One-shot acknowledgement: the host has consumed the route-replacement
|
|
65
|
+
* signal and navigated to the new transaction url, so we can drop the
|
|
66
|
+
* record. Re-dispatching is idempotent.
|
|
67
|
+
*/
|
|
68
|
+
clearTransferEntryRouteReplacement(draft) {
|
|
69
|
+
draft.lastTransferEntryReplacement = undefined;
|
|
70
|
+
},
|
|
71
|
+
/**
|
|
72
|
+
* Full slice reset. Dispatched from `clearAllEpic` on tenant switch so
|
|
73
|
+
* stale per-tenant state (account-id pools, status, replacement signal)
|
|
74
|
+
* doesn't bleed across tenants.
|
|
75
|
+
*/
|
|
76
|
+
clearCreateTransferEntry(draft) {
|
|
77
|
+
Object.assign(draft, initialState);
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
});
|
|
81
|
+
export const { fetchAccountsForTransferFlow, updateAccountsForTransferFlow, updateAccountsForTransferFlowFailure, createTransferEntry, createTransferEntrySuccess, createTransferEntryFailure, resetCreateTransferEntryStatus, createTransferEntryReplacedTransaction, clearTransferEntryRouteReplacement, clearCreateTransferEntry, } = createTransferEntrySlice.actions;
|
|
82
|
+
export default createTransferEntrySlice.reducer;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { createSelector } from '@reduxjs/toolkit';
|
|
2
|
+
import { getAccountBase, getAccountBaseForCreditCardTransferAccounts, getAccountBaseForTransferAccounts, } from '../../entity/account/accountSelector';
|
|
3
|
+
import { getAccountList } from '../accountList/accountListSelector';
|
|
4
|
+
export function getCreateTransferEntryStatus(state) {
|
|
5
|
+
return state.createTransferEntryState.createTransferEntryStatus;
|
|
6
|
+
}
|
|
7
|
+
export function getLastTransferEntryReplacement(state) {
|
|
8
|
+
return state.createTransferEntryState.lastTransferEntryReplacement;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Shared resolver for the credit/debit dropdowns in the transfer drawer.
|
|
12
|
+
*
|
|
13
|
+
* Resolution policy (intentional):
|
|
14
|
+
* 1. Prefer the dedicated API fetch results (`transferEntryEligible` for the
|
|
15
|
+
* debit pool, `creditCardOnlyEligible` for the credit-card-payment credit
|
|
16
|
+
* pool).
|
|
17
|
+
* 2. If the dedicated fetch returns an empty list while the COA is loaded,
|
|
18
|
+
* fall back to the COA: the full account list for `transferEntryEligible`,
|
|
19
|
+
* and COA accounts filtered to `credit_card` for `creditCardOnlyEligible`.
|
|
20
|
+
* This keeps the dropdown populated for older tenants where the dedicated
|
|
21
|
+
* endpoints haven't been backfilled yet.
|
|
22
|
+
*
|
|
23
|
+
* Intent — what this selector deliberately does NOT do:
|
|
24
|
+
* - Does NOT distinguish "fetch in-flight" / "fetch errored" / "fetch returned
|
|
25
|
+
* empty" — all three collapse to the COA fallback. The product preference
|
|
26
|
+
* is "always show something selectable" over "show a spinner that may never
|
|
27
|
+
* resolve". Loading/error UI belongs in the view layer; if you need a
|
|
28
|
+
* spinner, observe the `fetchState` on `transferAccountsByType[kind]`
|
|
29
|
+
* separately rather than changing the resolution policy here.
|
|
30
|
+
* - Does NOT enforce "API result is authoritative even if empty" — a tenant
|
|
31
|
+
* whose dedicated endpoint is correctly returning `[]` (e.g. no eligible
|
|
32
|
+
* transfer destinations) will still see the COA. That trade-off is
|
|
33
|
+
* accepted because the alternative blocks the user from picking anything;
|
|
34
|
+
* the backend distinguishes "no result" from "endpoint not implemented" by
|
|
35
|
+
* surfacing an error response, which the view layer handles separately.
|
|
36
|
+
*
|
|
37
|
+
* Memoized with reselect so consuming view-models don't recompute on every
|
|
38
|
+
* unrelated state change.
|
|
39
|
+
*/
|
|
40
|
+
export const getResolvedTransferAccounts = createSelector([
|
|
41
|
+
(state) => state.accountState,
|
|
42
|
+
(state) => state.accountListState,
|
|
43
|
+
(state) => state.createTransferEntryState.transferAccountsByType
|
|
44
|
+
.transferEntryEligible.accountIds,
|
|
45
|
+
(state) => state.createTransferEntryState.transferAccountsByType
|
|
46
|
+
.creditCardOnlyEligible.accountIds,
|
|
47
|
+
], (accountState, accountListState, transferEligibleIds, creditCardOnlyIds) => {
|
|
48
|
+
const accountList = getAccountList(accountState, accountListState, 'accountList');
|
|
49
|
+
const transferEligibleFromApi = transferEligibleIds
|
|
50
|
+
.map((id) => getAccountBaseForTransferAccounts(accountState, id))
|
|
51
|
+
.filter((account) => account != null);
|
|
52
|
+
const coaFallbackAllAccounts = accountList.accounts
|
|
53
|
+
.map((a) => getAccountBase(accountState, a.accountId, 'account_list'))
|
|
54
|
+
.filter((account) => account != null);
|
|
55
|
+
const transferAccountsList = transferEligibleFromApi.length > 0
|
|
56
|
+
? transferEligibleFromApi
|
|
57
|
+
: coaFallbackAllAccounts;
|
|
58
|
+
const creditCardFromApi = creditCardOnlyIds
|
|
59
|
+
.map((id) => getAccountBaseForCreditCardTransferAccounts(accountState, id))
|
|
60
|
+
.filter((account) => account != null);
|
|
61
|
+
const coaFallbackCreditCards = coaFallbackAllAccounts.filter((a) => a.accountType === 'credit_card');
|
|
62
|
+
const creditCardTransferAccountsList = creditCardFromApi.length > 0 ? creditCardFromApi : coaFallbackCreditCards;
|
|
63
|
+
return { creditCardTransferAccountsList, transferAccountsList };
|
|
64
|
+
});
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/** Which pool `fetchAccountsForTransferFlow` / transfer-flow epic should load. */
|
|
2
|
+
export const TRANSFER_ACCOUNTS_FETCH_TYPE = [
|
|
3
|
+
'transferEntryEligible',
|
|
4
|
+
'creditCardOnlyEligible',
|
|
5
|
+
];
|
|
6
|
+
const initialTransferAccountsState = {
|
|
7
|
+
accountIds: [],
|
|
8
|
+
fetchState: 'Not-Started',
|
|
9
|
+
};
|
|
10
|
+
export const initialCreateTransferEntryState = {
|
|
11
|
+
createTransferEntryStatus: 'Not-Started',
|
|
12
|
+
lastTransferEntryReplacement: undefined,
|
|
13
|
+
transferAccountsByType: {
|
|
14
|
+
transferEntryEligible: initialTransferAccountsState,
|
|
15
|
+
creditCardOnlyEligible: initialTransferAccountsState,
|
|
16
|
+
},
|
|
17
|
+
};
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { concat, from, timer } from 'rxjs';
|
|
2
|
+
import { catchError, filter, mergeMap } from 'rxjs/operators';
|
|
3
|
+
import { openSnackbar } from '../../../entity/snackbar/snackbarReducer';
|
|
4
|
+
import { toTransactionID } from '../../../entity/transaction/payloadTypes/transactionIDPayload';
|
|
5
|
+
import { removeTransaction, updateTransaction, } from '../../../entity/transaction/transactionReducer';
|
|
6
|
+
import { isSuccessResponse } from '../../../responsePayload';
|
|
7
|
+
import { removeTransactionFromAllTabs } from '../../expenseAutomationView/reducers/transactionsViewReducer';
|
|
8
|
+
import { initializeTransactionDetailLocalData, removeTransactionDetail, } from '../../transactionDetail/transactionDetailReducer';
|
|
9
|
+
import { getTransactionDetailKey } from '../../transactionDetail/transactionDetailState';
|
|
10
|
+
import { clearTransferEntryRouteReplacement, createTransferEntry, createTransferEntryFailure, createTransferEntryReplacedTransaction, createTransferEntrySuccess, resetCreateTransferEntryStatus, } from '../createTransferEntryReducer';
|
|
11
|
+
// ─── Pure helpers ────────────────────────────────────────────────────────────
|
|
12
|
+
function transactionIdsAreEqual(a, b) {
|
|
13
|
+
return a.id === b.id && a.type === b.type;
|
|
14
|
+
}
|
|
15
|
+
const successSnackbar = () => openSnackbar({
|
|
16
|
+
messageSection: 'create_transfer_entry',
|
|
17
|
+
messageText: 'success',
|
|
18
|
+
type: 'success',
|
|
19
|
+
});
|
|
20
|
+
const failureSnackbar = () => openSnackbar({
|
|
21
|
+
messageSection: 'create_transfer_entry',
|
|
22
|
+
messageText: 'failed',
|
|
23
|
+
type: 'error',
|
|
24
|
+
});
|
|
25
|
+
function buildFailureActions() {
|
|
26
|
+
return [createTransferEntryFailure(), failureSnackbar()];
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Defensive guard: a BE response that returns 200 with `transaction != null`
|
|
30
|
+
* but where the body lacks a usable id/type is unsafe to seed into the store —
|
|
31
|
+
* downstream code would store under a garbage key and the host hook would try
|
|
32
|
+
* to navigate to a broken url. Treat that case as failure so the source row
|
|
33
|
+
* stays visible and the user can retry.
|
|
34
|
+
*/
|
|
35
|
+
function isWellFormedTransactionPayload(t) {
|
|
36
|
+
return (t != null &&
|
|
37
|
+
typeof t.transaction_id === 'string' &&
|
|
38
|
+
t.transaction_id !== '' &&
|
|
39
|
+
typeof t.transaction_type === 'string' &&
|
|
40
|
+
t.transaction_type !== '');
|
|
41
|
+
}
|
|
42
|
+
function buildSuccessSideEffects(sourceTransactionId) {
|
|
43
|
+
return [
|
|
44
|
+
createTransferEntrySuccess(),
|
|
45
|
+
removeTransactionFromAllTabs(sourceTransactionId),
|
|
46
|
+
successSnackbar(),
|
|
47
|
+
];
|
|
48
|
+
}
|
|
49
|
+
function buildPreviousTransactionCleanupActions(previousTransactionId) {
|
|
50
|
+
return [
|
|
51
|
+
removeTransaction(getTransactionDetailKey(previousTransactionId)),
|
|
52
|
+
removeTransactionDetail(previousTransactionId),
|
|
53
|
+
clearTransferEntryRouteReplacement(),
|
|
54
|
+
];
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Emits `resetCreateTransferEntryStatus()` (and, on the replacement path, the
|
|
58
|
+
* follow-up cleanup actions) one scheduler tick after the success actions.
|
|
59
|
+
*
|
|
60
|
+
* Why the `timer(0)` (and not synchronous emission):
|
|
61
|
+
* On the replacement path the host (web-app-ui) watches
|
|
62
|
+
* `lastTransferEntryReplacement`, navigates to the new transaction url, and
|
|
63
|
+
* then sees `clearTransferEntryRouteReplacement` clear the signal. If we
|
|
64
|
+
* dispatched the cleanup actions in the same tick as
|
|
65
|
+
* `createTransferEntryReplacedTransaction`, redux subscribers would observe
|
|
66
|
+
* `lastTransferEntryReplacement` flicker on then off in a single render, and
|
|
67
|
+
* the old transaction's state (which the still-mounted detail view may be
|
|
68
|
+
* reading) would be torn down before the host has had a chance to start
|
|
69
|
+
* navigating. Deferring by one microtask gives the host exactly one render
|
|
70
|
+
* pass to react before we tear down the previous transaction.
|
|
71
|
+
*/
|
|
72
|
+
function delayedResetAndPreviousCleanup(previousTransactionId) {
|
|
73
|
+
return timer(0).pipe(mergeMap(() => {
|
|
74
|
+
const actions = [resetCreateTransferEntryStatus()];
|
|
75
|
+
if (previousTransactionId != null) {
|
|
76
|
+
actions.push(...buildPreviousTransactionCleanupActions(previousTransactionId));
|
|
77
|
+
}
|
|
78
|
+
return from(actions);
|
|
79
|
+
}));
|
|
80
|
+
}
|
|
81
|
+
// ─── Success-path branches ───────────────────────────────────────────────────
|
|
82
|
+
function handleSuccessWithoutTransactionBody(transactionId) {
|
|
83
|
+
return concat(from(buildSuccessSideEffects(transactionId)), delayedResetAndPreviousCleanup(undefined));
|
|
84
|
+
}
|
|
85
|
+
function handleSuccessWithTransactionBody(transactionPayload, vendorPayload, previousTransactionId, sourceTransactionId) {
|
|
86
|
+
const newTransactionId = toTransactionID(transactionPayload);
|
|
87
|
+
const replaced = !transactionIdsAreEqual(previousTransactionId, newTransactionId);
|
|
88
|
+
const immediate = [
|
|
89
|
+
updateTransaction(getTransactionDetailKey(newTransactionId), transactionPayload),
|
|
90
|
+
initializeTransactionDetailLocalData({
|
|
91
|
+
transactionId: newTransactionId,
|
|
92
|
+
vendorId: vendorPayload?.[0]?.vendor_id,
|
|
93
|
+
}),
|
|
94
|
+
...buildSuccessSideEffects(sourceTransactionId),
|
|
95
|
+
];
|
|
96
|
+
if (replaced) {
|
|
97
|
+
immediate.push(createTransferEntryReplacedTransaction(previousTransactionId, newTransactionId));
|
|
98
|
+
}
|
|
99
|
+
return concat(from(immediate), delayedResetAndPreviousCleanup(replaced ? previousTransactionId : undefined));
|
|
100
|
+
}
|
|
101
|
+
// ─── Top-level epic ──────────────────────────────────────────────────────────
|
|
102
|
+
export const createTransferEntryEpic = (actions$, _state$, zeniAPI) => actions$.pipe(filter(createTransferEntry.match), mergeMap((action) => {
|
|
103
|
+
const { transactionId, creditAccountIntegrationId, debitAccountIntegrationId, memo, transactionType, sourceTransactionType, } = action.payload;
|
|
104
|
+
const previousTransactionId = {
|
|
105
|
+
id: transactionId,
|
|
106
|
+
type: sourceTransactionType,
|
|
107
|
+
};
|
|
108
|
+
const payload = {
|
|
109
|
+
transaction_type: transactionType,
|
|
110
|
+
transaction_id: transactionId,
|
|
111
|
+
to_account_integration_id: creditAccountIntegrationId,
|
|
112
|
+
from_account_integration_id: debitAccountIntegrationId,
|
|
113
|
+
memo,
|
|
114
|
+
};
|
|
115
|
+
return zeniAPI
|
|
116
|
+
.postAndGetJSON(`${zeniAPI.apiEndPoints.accountMicroServiceBaseUrl}/1.0/transactions/transaction-type-update`, payload)
|
|
117
|
+
.pipe(mergeMap((response) => {
|
|
118
|
+
if (!isSuccessResponse(response)) {
|
|
119
|
+
return from(buildFailureActions());
|
|
120
|
+
}
|
|
121
|
+
const transaction = response.data?.transaction;
|
|
122
|
+
if (transaction != null) {
|
|
123
|
+
if (!isWellFormedTransactionPayload(transaction)) {
|
|
124
|
+
return from(buildFailureActions());
|
|
125
|
+
}
|
|
126
|
+
return handleSuccessWithTransactionBody(transaction, response.data?.vendors, previousTransactionId, transactionId);
|
|
127
|
+
}
|
|
128
|
+
return handleSuccessWithoutTransactionBody(transactionId);
|
|
129
|
+
}), catchError(() => from(buildFailureActions())));
|
|
130
|
+
}));
|