@zeniai/client-epic-state 4.19.84-betaVR11 → 4.19.84-betaVR12

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/esm/index.js CHANGED
@@ -612,5 +612,6 @@ export { fetchTreasuryStatementList } from './view/spendManagement/treasury/trea
612
612
  export { getTreasuryStatements, } from './view/spendManagement/treasury/treasuryStatementList/treasuryStatementListSelector';
613
613
  export { fetchTreasuryTaxLetterList } from './view/spendManagement/treasury/treasuryTaxLetterList/treasuryTaxLetterListReducer';
614
614
  export { getTreasuryTaxLetters, } from './view/spendManagement/treasury/treasuryTaxLetterList/treasuryTaxLetterListSelector';
615
+ export { BULK_UPLOAD_BAR_COMPLETE_HOLD_MS } from './view/expenseAutomationView/bulkUploadTiming';
615
616
  export { fetchTransactionActivityLog } from './view/transactionActivityLogView/transactionActivityLogViewReducer';
616
617
  export { getTransactionActivityLogView, } from './view/transactionActivityLogView/transactionActivityLogViewSelector';
@@ -0,0 +1,5 @@
1
+ /**
2
+ * After upload API success, hold the bar at 100% this long before transitioning to matching,
3
+ * so the fill animation can complete without an abrupt swap to the auto-matching banner.
4
+ */
5
+ export const BULK_UPLOAD_BAR_COMPLETE_HOLD_MS = 400;
@@ -1,7 +1,8 @@
1
- import { of } from 'rxjs';
1
+ import { concat, of, timer } from 'rxjs';
2
2
  import { catchError, filter, mergeMap } from 'rxjs/operators';
3
3
  import { createZeniAPIStatus, isSuccessResponse, } from '../../../../responsePayload';
4
- import { bulkUploadReceipts, bulkUploadReceiptsFailure, bulkUploadReceiptsSuccess, } from '../../reducers/missingReceiptsViewReducer';
4
+ import { BULK_UPLOAD_BAR_COMPLETE_HOLD_MS } from '../../bulkUploadTiming';
5
+ import { bulkUploadReceipts, bulkUploadReceiptsFailure, bulkUploadReceiptsSuccess, updateBulkUploadProgress, } from '../../reducers/missingReceiptsViewReducer';
5
6
  export const bulkUploadReceiptsEpic = (actions$, _state$, zeniAPI) => actions$.pipe(filter(bulkUploadReceipts.match), mergeMap((action) => {
6
7
  const { files } = action.payload;
7
8
  const formData = new FormData();
@@ -18,7 +19,7 @@ export const bulkUploadReceiptsEpic = (actions$, _state$, zeniAPI) => actions$.p
18
19
  error: createZeniAPIStatus('Unexpected Error', 'Bulk upload succeeded but batch_id was missing or empty.'),
19
20
  }));
20
21
  }
21
- return of(bulkUploadReceiptsSuccess({ batchId }));
22
+ return concat(of(updateBulkUploadProgress(100)), timer(BULK_UPLOAD_BAR_COMPLETE_HOLD_MS).pipe(mergeMap(() => of(bulkUploadReceiptsSuccess({ batchId })))));
22
23
  }
23
24
  return of(bulkUploadReceiptsFailure({ error: response.status }));
24
25
  }), catchError((error) => of(bulkUploadReceiptsFailure({
@@ -1,6 +1,6 @@
1
1
  import { toURL } from '../../../commonPayloadTypes/urlPayload';
2
2
  import { getTransactionPayloadAmount, } from '../../../entity/transaction/payloadTypes/transactionPayload';
3
- import { toBatchStatusValue, toMatchSource, } from '../types/missingReceiptsViewState';
3
+ import { toBatchFileStatus, toBatchStatusValue, toMatchSource, } from '../types/missingReceiptsViewState';
4
4
  // -- Converter functions --
5
5
  /**
6
6
  * Maps batch-details API `files[].status` strings to canonical {@link BatchFileStatus}.
@@ -45,7 +45,7 @@ export function toBatchFile(payload, filesEndPoint) {
45
45
  ? toMatchSource(payload.match_source)
46
46
  : undefined,
47
47
  matchedTransactionId: payload.matched_transaction?.transaction_id,
48
- status: parseBatchFileStatus(payload.status),
48
+ status: toBatchFileStatus(payload.status),
49
49
  };
50
50
  }
51
51
  export function extractTransactionPayloadsFromBatchFiles(files) {
@@ -1,4 +1,4 @@
1
- import { createSlice } from '@reduxjs/toolkit';
1
+ import { createAction, createSlice } from '@reduxjs/toolkit';
2
2
  import { toMonthYearPeriodId } from '../../../commonStateTypes/timePeriod';
3
3
  import { MIN_MANUAL_TRANSACTION_SEARCH_LENGTH, } from '../types/missingReceiptsViewState';
4
4
  export const getCompletedTransactionsCacheKey = (periodId, sortKey, sortOrder, subTab) => `completed-${subTab}-${sortKey}-${sortOrder === 'ascending' ? 'asc' : 'desc'}-${periodId}`;
@@ -51,6 +51,8 @@ export const initialState = {
51
51
  return this.fetchState == 'Completed';
52
52
  },
53
53
  };
54
+ /** Epic trigger only; batch-details fetch is handled in epics. */
55
+ export const fetchBulkUploadBatchDetails = createAction('expenseAutomationMissingReceiptsView/fetchBulkUploadBatchDetails');
54
56
  const expenseAutomationMissingReceiptsView = createSlice({
55
57
  name: 'expenseAutomationMissingReceiptsView',
56
58
  initialState,
@@ -154,8 +156,7 @@ const expenseAutomationMissingReceiptsView = createSlice({
154
156
  },
155
157
  // -- Bulk Upload Actions --
156
158
  bulkUploadReceipts: {
157
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
158
- reducer(draft, _action) {
159
+ reducer(draft) {
159
160
  draft.bulkUpload.phase = 'uploading';
160
161
  draft.bulkUpload.uploadProgress = 0;
161
162
  draft.bulkUpload.uploadStatus = {
@@ -172,6 +173,7 @@ const expenseAutomationMissingReceiptsView = createSlice({
172
173
  },
173
174
  bulkUploadReceiptsSuccess(draft, action) {
174
175
  draft.bulkUpload.currentBatchId = action.payload.batchId;
176
+ draft.bulkUpload.uploadProgress = 100;
175
177
  draft.bulkUpload.uploadStatus = {
176
178
  fetchState: 'Completed',
177
179
  error: undefined,
@@ -205,18 +207,18 @@ const expenseAutomationMissingReceiptsView = createSlice({
205
207
  clearMissingReceiptsTabNavigation(draft) {
206
208
  draft.pendingMissingReceiptsTabNavigation = null;
207
209
  },
208
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
209
- fetchBulkUploadBatchDetails(_draft) {
210
- // trigger epic, no state change needed
211
- },
212
210
  fetchBulkUploadBatchDetailsSuccess(draft, action) {
213
211
  const details = action.payload;
214
212
  draft.bulkUpload.batchDetailsById[details.batchId] = details;
215
213
  draft.bulkUpload.phase = 'completed';
216
214
  },
217
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
218
- fetchBulkUploadBatchDetailsFailure(draft, _action) {
219
- draft.bulkUpload.phase = 'completed';
215
+ fetchBulkUploadBatchDetailsFailure: {
216
+ reducer(draft) {
217
+ draft.bulkUpload.phase = 'completed';
218
+ },
219
+ prepare(payload) {
220
+ return { payload };
221
+ },
220
222
  },
221
223
  storeBatchDetails(draft, action) {
222
224
  const details = action.payload;
@@ -247,8 +249,8 @@ const expenseAutomationMissingReceiptsView = createSlice({
247
249
  error: undefined,
248
250
  };
249
251
  },
250
- fetchMoreBatchDetails(_draft) {
251
- _draft.bulkUpload.batchDetailsPaginationState = {
252
+ fetchMoreBatchDetails(draft) {
253
+ draft.bulkUpload.batchDetailsPaginationState = {
252
254
  fetchState: 'In-Progress',
253
255
  error: undefined,
254
256
  };
@@ -324,8 +326,7 @@ const expenseAutomationMissingReceiptsView = createSlice({
324
326
  };
325
327
  },
326
328
  confirmBulkUploadMatch: {
327
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
328
- reducer(draft, _action) {
329
+ reducer(draft) {
329
330
  draft.bulkUpload.confirmMatchStatus = {
330
331
  fetchState: 'In-Progress',
331
332
  error: undefined,
@@ -426,7 +427,7 @@ const expenseAutomationMissingReceiptsView = createSlice({
426
427
  const { append, nextPageToken, results, totalCount } = action.payload;
427
428
  if (append) {
428
429
  const merged = [...draft.bulkUpload.manualSearch.results, ...results];
429
- const byId = new Map(merged.map((r) => [r.transactionId, r]));
430
+ const byId = new Map(merged.map((result) => [result.transactionId, result]));
430
431
  draft.bulkUpload.manualSearch.results = Array.from(byId.values());
431
432
  }
432
433
  else {
@@ -531,7 +532,7 @@ const expenseAutomationMissingReceiptsView = createSlice({
531
532
  });
532
533
  export const { fetchMissingReceipts, fetchMissingReceiptsSuccess, fetchMissingReceiptsFailure, uploadMissingReceiptSuccess, updateMissingReceiptUploadState, updateMissingReceiptsUIState, markMissingReceiptAsDone, clearExpenseAutomationMissingReceiptsView,
533
534
  // Bulk Upload
534
- bulkUploadReceipts, updateBulkUploadProgress, bulkUploadReceiptsSuccess, bulkUploadReceiptsFailure, pusherBatchStatusUpdate, requestMissingReceiptsTabNavigation, clearMissingReceiptsTabNavigation, fetchBulkUploadBatchDetails, fetchBulkUploadBatchDetailsSuccess, fetchBulkUploadBatchDetailsFailure, storeBatchDetails, batchDetailFetchFailed, setInitialBatchDetailsLoading, fetchMoreBatchDetails, fetchMoreBatchDetailsComplete, fetchMoreBatchDetailsFailure, fetchBulkUploadBatches, fetchBulkUploadBatchesSuccess, fetchBulkUploadBatchesFailure, confirmBulkUploadMatch, confirmBulkUploadMatchSuccess, confirmBulkUploadMatchFailure, setBulkUploadResultsTab, setBulkUploadCompletedSubTab, setBulkUploadSortConfig, clearBulkUpload, searchTransactionsForManualMatch, searchTransactionsForManualMatchSuccess, searchTransactionsForManualMatchFailure, clearManualSearchResults, acknowledgeBulkUploadConfirmMatchComplete,
535
+ bulkUploadReceipts, updateBulkUploadProgress, bulkUploadReceiptsSuccess, bulkUploadReceiptsFailure, pusherBatchStatusUpdate, requestMissingReceiptsTabNavigation, clearMissingReceiptsTabNavigation, fetchBulkUploadBatchDetailsSuccess, fetchBulkUploadBatchDetailsFailure, storeBatchDetails, batchDetailFetchFailed, setInitialBatchDetailsLoading, fetchMoreBatchDetails, fetchMoreBatchDetailsComplete, fetchMoreBatchDetailsFailure, fetchBulkUploadBatches, fetchBulkUploadBatchesSuccess, fetchBulkUploadBatchesFailure, confirmBulkUploadMatch, confirmBulkUploadMatchSuccess, confirmBulkUploadMatchFailure, setBulkUploadResultsTab, setBulkUploadCompletedSubTab, setBulkUploadSortConfig, clearBulkUpload, searchTransactionsForManualMatch, searchTransactionsForManualMatchSuccess, searchTransactionsForManualMatchFailure, clearManualSearchResults, acknowledgeBulkUploadConfirmMatchComplete,
535
536
  // Completed Transactions
536
537
  fetchCompletedTransactions, fetchCompletedTransactionsSuccess, fetchCompletedTransactionsFailure, } = expenseAutomationMissingReceiptsView.actions;
537
538
  export default expenseAutomationMissingReceiptsView.reducer;
@@ -64,10 +64,33 @@ export function getExpenseAutomationMissingReceiptsView(state) {
64
64
  * so we do not block the whole tab while other rows are not fetched yet.
65
65
  */
66
66
  const primaryBatchIdFromDetailsOrder = getPrimaryBatchIdFromBatchListOrder(batchList, bulkUpload.batchDetailsById, bulkUpload.failedBatchDetailIds);
67
- /** During upload/matching, the in-flight batch may not appear in batchList yet — prefer currentBatchId. */
68
- const unmatchedSectionBatchId = bulkUpload.phase === 'matching' || bulkUpload.phase === 'uploading'
69
- ? bulkUpload.currentBatchId ?? primaryBatchIdFromDetailsOrder
70
- : primaryBatchIdFromDetailsOrder;
67
+ /**
68
+ * During upload/matching, prefer `currentBatchId` only when it is not yet in the period
69
+ * `batchList` (true in-flight), or when its details are completed and include unmatched-tab work.
70
+ * Otherwise keep `primaryBatchIdFromDetailsOrder` so a new batch with no `possible_matches` /
71
+ * `no_match` rows yet does not vacate the primary column and push older batches into "past".
72
+ */
73
+ const unmatchedSectionBatchId = (() => {
74
+ const phase = bulkUpload.phase;
75
+ if (phase !== 'matching' && phase !== 'uploading') {
76
+ return primaryBatchIdFromDetailsOrder;
77
+ }
78
+ const currentId = bulkUpload.currentBatchId;
79
+ if (currentId == null) {
80
+ return primaryBatchIdFromDetailsOrder;
81
+ }
82
+ const currentInBatchList = batchList.some((b) => b.batchId === currentId);
83
+ if (!currentInBatchList) {
84
+ return currentId;
85
+ }
86
+ const currentDetails = bulkUpload.batchDetailsById[currentId];
87
+ if (currentDetails != null &&
88
+ currentDetails.status === 'completed' &&
89
+ batchDetailsHasUnmatchedWork(currentDetails)) {
90
+ return currentId;
91
+ }
92
+ return primaryBatchIdFromDetailsOrder;
93
+ })();
71
94
  const completedBatchesInApiOrder = batchList.filter((batchListItem) => isBatchListStatusCompleted(batchListItem.status));
72
95
  const currentBatchDetails = unmatchedSectionBatchId != null
73
96
  ? bulkUpload.batchDetailsById[unmatchedSectionBatchId]
package/lib/index.d.ts CHANGED
@@ -870,5 +870,6 @@ export { fetchTreasuryTaxLetterList } from './view/spendManagement/treasury/trea
870
870
  export { TreasuryTaxLettersSelectorView, getTreasuryTaxLetters, } from './view/spendManagement/treasury/treasuryTaxLetterList/treasuryTaxLetterListSelector';
871
871
  export { TreasuryTransactionStatus } from './view/spendManagement/treasury/treasuryList/treasuryDetailPayload';
872
872
  export type { TransactionActivityLog } from './entity/transactionActivityLog/transactionActivityLogState';
873
+ export { BULK_UPLOAD_BAR_COMPLETE_HOLD_MS } from './view/expenseAutomationView/bulkUploadTiming';
873
874
  export { fetchTransactionActivityLog } from './view/transactionActivityLogView/transactionActivityLogViewReducer';
874
875
  export { TransactionActivityLogViewSelectorView, getTransactionActivityLogView, } from './view/transactionActivityLogView/transactionActivityLogViewSelector';
package/lib/index.js CHANGED
@@ -68,7 +68,7 @@ exports.allTaskStatus = exports.updateTaskListUIState = exports.updateTaskListSe
68
68
  exports.updateCommentsNotificationsStatuses = exports.updateCommentsNotifications = exports.toNotificationModeStrict = exports.fetchZeniAccountsPromoCard = exports.getZeniAccountsPromoCard = exports.getAuthenticationView = exports.fetchCollaborationAuthToken = exports.clearAuditReportGroupViewByCompanyId = exports.saveReasonForAuditRule = exports.fetchAuditReportGroupView = exports.fetchAuditRuleGroupView = exports.getUserFromAllUsers = exports.getAuditRuleGroupViewSelectorView = exports.getAuditReportGroupViewSelectorView = exports.clearCardPaymentView = exports.resetCardPaymentErrorStatuses = exports.fetchPaymentSources = exports.addCardPaymentSource = exports.confirmCardSetupIntent = exports.createCardSetupIntent = exports.getAllCardsAndBankPaymentMethods = exports.deleteTag = exports.createTag = exports.fetchTagList = exports.getAllTags = exports.initialTaskDetailLocalData = exports.convertHHMMStrToMinutes = exports.updateTaskFromListView = exports.toDueDateGroupKeyType = exports.toTaskStatusCodeType = exports.toPriorityCodeType = exports.getDueDateValueFromDueDateGroupId = exports.initialTaskDetail = exports.fetchAllTaskGroups = exports.getTaskUpdates = exports.toTaskListGroupByKeyTypeStrict = exports.toTaskListGroupByKeyType = exports.updateTaskGroupName = exports.dragNDropTasks = exports.updateTaskListLocalData = exports.deleteTaskGroup = exports.initiateTaskListLocalData = exports.createNewTaskGroup = exports.bulkUpdateTaskList = exports.discardTaskUpdatesInLocalStore = exports.deleteTask = exports.TASK_LIST_GROUP_BY_CATEGORIES = exports.TASK_LIST_FILTER_CATEGORIES = exports.updateTaskFilters = exports.allTaskPriority = void 0;
69
69
  exports.fetchTreasuryFunds = exports.clearTreasurySetupView = exports.fetchTreasurySetupView = exports.acceptTreasuryTerms = exports.getExpressPayView = exports.resetExpressPayLocalData = exports.submitExpressPay = exports.updateExpressPayFormLocalData = exports.fetchExpressPayInitialDetails = exports.getIntlWireVerificationView = exports.updateVerificationFormLocalData = exports.submitInternationalVerificationForm = exports.fetchInternationalVerificationForm = exports.createTaskFromTaskGroupTemplate = exports.getCompanyTaskManagerView = exports.fetchCompanyTaskManagerView = exports.getMinAllowedEndDate = exports.toRecurringFrequency = exports.getRecurringEndDateFromCount = exports.updateReferViewed = exports.getRewardsPlanCard = exports.fetchRewardsPlan = exports.resendReferralInvite = exports.updateReferralListSortUiState = exports.saveReferralFormDataInLocalStore = exports.clearReferrals = exports.sendReferralInvite = exports.fetchReferrals = exports.AmountStatusTypes = exports.StatusTypes = exports.toReferralListViewSortKeyType = exports.getInviteFormView = exports.getReferralListView = exports.getNotifications = exports.getLastNotificationTime = exports.pushToastNotification = exports.getNotificationsForSelectedSubTab = exports.getExternalNotificationsForSelectedSubTab = exports.getNotificationView = exports.updateNotificationViewUIState = exports.updateNotificationViewSubTab = exports.updateNotificationViewCurrentTabAndSubTab = exports.updateNotificationViewTabState = exports.updateNotificationViewNotificationStatus = exports.updateNotificationViewAllNotificationsStatus = exports.fetchNotificationUnreadCountSuccess = exports.fetchNotificationUnreadCount = exports.fetchNotificationView = exports.toNotificationTabTypeStrict = exports.toNotificationSubTabTypeStrict = void 0;
70
70
  exports.toAiCfoAnswerResponseTypeStrict = exports.toAiCfoAnswerResponseType = exports.toAiCfoAnswerStateTypeStrict = exports.toAiCfoAnswerStateType = exports.toAiCfoChartTypeStrict = exports.toAiCfoChartType = exports.toAiCfoVisualizationTypeStrict = exports.toAiCfoVisualizationType = exports.ALL_AI_CFO_ANSWER_RESPONSE_TYPES = exports.ALL_AI_CFO_ANSWER_STATE_TYPES = exports.ALL_AI_CFO_VISUALIZATION_TYPES = exports.ALL_AI_CFO_CHARTS_TYPES = exports.getAiCfoSelectorView = exports.getAllQuestionsForChatSession = exports.getQuestionAnswerByIdForChatSession = exports.getAllQuestionAnswersForChatSession = exports.toAiCfoVisualization = exports.clearAiCfo = exports.clearSession = exports.addQuestionPayload = exports.upsertOrAddQuestionAnswerPayload = exports.upsertAnswerPayload = exports.setSessions = exports.setNewSession = exports.getAiCfoView = exports.updateResponseState = exports.deleteChatSession = exports.acceptMasterTOS = exports.fetchChatHistory = exports.stopSubmitQuestion = exports.stopSubmit = exports.createSessionAndSubmit = exports.clearLastContextMessage = exports.clearDeleteChatSessionStatus = exports.clearCurrentSessionId = exports.clearAiCfoView = exports.setSession = exports.clearInput = exports.updateCotCollapsedState = exports.updateCurrentInput = exports.updateAiCfoViewScrollPosition = exports.submitQuestion = exports.createSession = exports.fetchChatSessionsForUser = exports.getTreasuryFundsMaximumYield = exports.getTreasurySetupViewDetails = exports.updateTreasuryVideoViewed = exports.updateFundAllocationLocalData = exports.fetchPortfolioAllocation = exports.updatePortfolioAllocation = void 0;
71
- exports.getTransactionActivityLogView = exports.fetchTransactionActivityLog = exports.getTreasuryTaxLetters = exports.fetchTreasuryTaxLetterList = exports.getTreasuryStatements = exports.fetchTreasuryStatementList = exports.getTreasuryTransferMoney = exports.clearTreasuryTransferMoney = exports.updateTreasuryTransferMoneyLocalData = exports.executeTreasuryTransferMoney = exports.getTreasuryDetail = exports.updateTreasuryTransactionListUIState = exports.fetchTreasuryTransactionList = exports.fetchTreasuryOverviewDetail = exports.toMessageType = exports.toMessageSender = void 0;
71
+ exports.getTransactionActivityLogView = exports.fetchTransactionActivityLog = exports.BULK_UPLOAD_BAR_COMPLETE_HOLD_MS = exports.getTreasuryTaxLetters = exports.fetchTreasuryTaxLetterList = exports.getTreasuryStatements = exports.fetchTreasuryStatementList = exports.getTreasuryTransferMoney = exports.clearTreasuryTransferMoney = exports.updateTreasuryTransferMoneyLocalData = exports.executeTreasuryTransferMoney = exports.getTreasuryDetail = exports.updateTreasuryTransactionListUIState = exports.fetchTreasuryTransactionList = exports.fetchTreasuryOverviewDetail = exports.toMessageType = exports.toMessageSender = void 0;
72
72
  const allowedValue_1 = require("./commonStateTypes/allowedValue");
73
73
  Object.defineProperty(exports, "isAllowedValueWithCode", { enumerable: true, get: function () { return allowedValue_1.isAllowedValueWithCode; } });
74
74
  Object.defineProperty(exports, "isAllowedValueWithID", { enumerable: true, get: function () { return allowedValue_1.isAllowedValueWithID; } });
@@ -2113,6 +2113,8 @@ var treasuryTaxLetterListReducer_1 = require("./view/spendManagement/treasury/tr
2113
2113
  Object.defineProperty(exports, "fetchTreasuryTaxLetterList", { enumerable: true, get: function () { return treasuryTaxLetterListReducer_1.fetchTreasuryTaxLetterList; } });
2114
2114
  var treasuryTaxLetterListSelector_1 = require("./view/spendManagement/treasury/treasuryTaxLetterList/treasuryTaxLetterListSelector");
2115
2115
  Object.defineProperty(exports, "getTreasuryTaxLetters", { enumerable: true, get: function () { return treasuryTaxLetterListSelector_1.getTreasuryTaxLetters; } });
2116
+ var bulkUploadTiming_1 = require("./view/expenseAutomationView/bulkUploadTiming");
2117
+ Object.defineProperty(exports, "BULK_UPLOAD_BAR_COMPLETE_HOLD_MS", { enumerable: true, get: function () { return bulkUploadTiming_1.BULK_UPLOAD_BAR_COMPLETE_HOLD_MS; } });
2116
2118
  var transactionActivityLogViewReducer_1 = require("./view/transactionActivityLogView/transactionActivityLogViewReducer");
2117
2119
  Object.defineProperty(exports, "fetchTransactionActivityLog", { enumerable: true, get: function () { return transactionActivityLogViewReducer_1.fetchTransactionActivityLog; } });
2118
2120
  var transactionActivityLogViewSelector_1 = require("./view/transactionActivityLogView/transactionActivityLogViewSelector");