@zeniai/client-epic-state 5.0.10 → 5.0.11-beta0ND

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. package/lib/coreEpics.js +2 -1
  2. package/lib/entity/tenant/SessionManager.d.ts +38 -0
  3. package/lib/entity/tenant/SessionManager.js +171 -0
  4. package/lib/entity/tenant/epic/sessionHeartbeatEpic.d.ts +16 -0
  5. package/lib/entity/tenant/epic/sessionHeartbeatEpic.js +16 -0
  6. package/lib/entity/tenant/sessionTypes.d.ts +26 -0
  7. package/lib/entity/tenant/sessionTypes.js +12 -0
  8. package/lib/entity/tenant/tenantReducer.d.ts +5 -1
  9. package/lib/entity/tenant/tenantReducer.js +23 -2
  10. package/lib/entity/tenant/tenantState.d.ts +1 -0
  11. package/lib/esm/coreEpics.js +2 -1
  12. package/lib/esm/entity/tenant/SessionManager.js +167 -0
  13. package/lib/esm/entity/tenant/epic/sessionHeartbeatEpic.js +12 -0
  14. package/lib/esm/entity/tenant/sessionTypes.js +9 -0
  15. package/lib/esm/entity/tenant/tenantReducer.js +21 -1
  16. package/lib/esm/index.js +5 -2
  17. package/lib/esm/view/expenseAutomationView/epics/missingReceipts/fetchCompletedTransactionsEpic.js +20 -5
  18. package/lib/esm/view/expenseAutomationView/epics/missingReceipts/watchBulkUploadBatchStatusEpic.js +9 -1
  19. package/lib/esm/view/expenseAutomationView/reducers/missingReceiptsViewReducer.js +3 -3
  20. package/lib/esm/view/spendManagement/billPay/billDetailView/epics/fetchBillDetailEpic.js +5 -5
  21. package/lib/index.d.ts +5 -2
  22. package/lib/index.js +36 -30
  23. package/lib/tsconfig.typecheck.tsbuildinfo +1 -1
  24. package/lib/view/expenseAutomationView/epics/missingReceipts/fetchCompletedTransactionsEpic.js +20 -5
  25. package/lib/view/expenseAutomationView/epics/missingReceipts/watchBulkUploadBatchStatusEpic.d.ts +2 -2
  26. package/lib/view/expenseAutomationView/epics/missingReceipts/watchBulkUploadBatchStatusEpic.js +8 -0
  27. package/lib/view/expenseAutomationView/reducers/missingReceiptsViewReducer.d.ts +6 -0
  28. package/lib/view/expenseAutomationView/reducers/missingReceiptsViewReducer.js +3 -3
  29. package/lib/view/spendManagement/billPay/billDetailView/epics/fetchBillDetailEpic.js +5 -5
  30. package/package.json +1 -1
@@ -15,7 +15,13 @@ const fetchCompletedTransactionsEpic = (actions$, state$, zeniAPI) => actions$.p
15
15
  const selectedPeriod = selectedPeriodByTenantId[currentTenant.tenantId];
16
16
  const periodId = (0, timePeriod_1.toMonthYearPeriodId)(selectedPeriod);
17
17
  const isInitialLoad = action.payload.pageToken == null;
18
- const cacheKey = (0, missingReceiptsViewReducer_1.getCompletedTransactionsCacheKey)(periodId, bulkUpload.sortKey, bulkUpload.sortOrder, bulkUpload.completedSubTab);
18
+ /**
19
+ * Snapshot sort config + subTab at request time so success/failure write
20
+ * into the same cache key the request was made under, even if the user
21
+ * toggles sort while the request is in flight.
22
+ */
23
+ const { sortKey, sortOrder, completedSubTab } = bulkUpload;
24
+ const cacheKey = (0, missingReceiptsViewReducer_1.getCompletedTransactionsCacheKey)(periodId, sortKey, sortOrder, completedSubTab);
19
25
  const existingData = bulkUpload.completedTransactionsByPeriod[cacheKey];
20
26
  if (isInitialLoad &&
21
27
  action.payload.cacheOverride !== true &&
@@ -27,13 +33,13 @@ const fetchCompletedTransactionsEpic = (actions$, state$, zeniAPI) => actions$.p
27
33
  const queryPayload = {
28
34
  start_date: period.start,
29
35
  end_date: period.end,
30
- sort_by: bulkUpload.sortKey,
31
- sort_order: bulkUpload.sortOrder === 'ascending' ? 'asc' : 'desc',
36
+ sort_by: sortKey,
37
+ sort_order: sortOrder === 'ascending' ? 'asc' : 'desc',
32
38
  page_token: action.payload.pageToken ?? null,
33
39
  page_size: 25,
34
40
  };
35
- if (bulkUpload.completedSubTab !== 'all') {
36
- queryPayload.match_type = bulkUpload.completedSubTab;
41
+ if (completedSubTab !== 'all') {
42
+ queryPayload.match_type = completedSubTab;
37
43
  }
38
44
  const encodedQuery = encodeURIComponent(JSON.stringify(queryPayload));
39
45
  return zeniAPI
@@ -49,17 +55,26 @@ const fetchCompletedTransactionsEpic = (actions$, state$, zeniAPI) => actions$.p
49
55
  nextPageToken: response.data.next_page_token,
50
56
  totalCount: response.data.total_count,
51
57
  selectedPeriod,
58
+ sortKey,
59
+ sortOrder,
60
+ completedSubTab,
52
61
  }));
53
62
  return (0, rxjs_1.from)(updateActions);
54
63
  }
55
64
  return (0, rxjs_1.of)((0, missingReceiptsViewReducer_1.fetchCompletedTransactionsFailure)({
56
65
  error: response.status,
57
66
  selectedPeriod,
67
+ sortKey,
68
+ sortOrder,
69
+ completedSubTab,
58
70
  }));
59
71
  }), (0, operators_1.catchError)((error) => (0, rxjs_1.of)((0, missingReceiptsViewReducer_1.fetchCompletedTransactionsFailure)({
60
72
  error: (0, responsePayload_1.createZeniAPIStatus)('Unexpected Error', 'Fetch completed transactions errored: ' +
61
73
  JSON.stringify(error)),
62
74
  selectedPeriod,
75
+ sortKey,
76
+ sortOrder,
77
+ completedSubTab,
63
78
  }))));
64
79
  }));
65
80
  exports.fetchCompletedTransactionsEpic = fetchCompletedTransactionsEpic;
@@ -4,8 +4,8 @@ import { openSnackbar } from '../../../../entity/snackbar/snackbarReducer';
4
4
  import { updateTransactions } from '../../../../entity/transaction/transactionReducer';
5
5
  import { RootState } from '../../../../reducer';
6
6
  import { ZeniAPI } from '../../../../zeniAPI';
7
- import { bulkUploadAutomatchingTimedOut, bulkUploadReceiptsSuccess, clearBulkUpload, fetchBulkUploadBatchDetailsSuccess, fetchBulkUploadBatches, pusherBatchStatusUpdate, requestMissingReceiptsTabNavigation, restoreBulkUploadMatchingState } from '../../reducers/missingReceiptsViewReducer';
8
- export type ActionType = ReturnType<typeof bulkUploadReceiptsSuccess> | ReturnType<typeof restoreBulkUploadMatchingState> | ReturnType<typeof pusherBatchStatusUpdate> | ReturnType<typeof fetchBulkUploadBatchDetailsSuccess> | ReturnType<typeof fetchBulkUploadBatches> | ReturnType<typeof requestMissingReceiptsTabNavigation> | ReturnType<typeof updateTransactions> | ReturnType<typeof clearBulkUpload> | ReturnType<typeof openSnackbar> | ReturnType<typeof bulkUploadAutomatchingTimedOut>;
7
+ import { bulkUploadAutomatchingTimedOut, bulkUploadReceiptsSuccess, clearBulkUpload, fetchBulkUploadBatchDetails, fetchBulkUploadBatchDetailsSuccess, fetchBulkUploadBatches, pusherBatchStatusUpdate, requestMissingReceiptsTabNavigation, restoreBulkUploadMatchingState } from '../../reducers/missingReceiptsViewReducer';
8
+ export type ActionType = ReturnType<typeof bulkUploadReceiptsSuccess> | ReturnType<typeof restoreBulkUploadMatchingState> | ReturnType<typeof pusherBatchStatusUpdate> | ReturnType<typeof fetchBulkUploadBatchDetails> | ReturnType<typeof fetchBulkUploadBatchDetailsSuccess> | ReturnType<typeof fetchBulkUploadBatches> | ReturnType<typeof requestMissingReceiptsTabNavigation> | ReturnType<typeof updateTransactions> | ReturnType<typeof clearBulkUpload> | ReturnType<typeof openSnackbar> | ReturnType<typeof bulkUploadAutomatchingTimedOut>;
9
9
  /**
10
10
  * On Pusher batch completion: refresh batch list (then fetchMultipleBatchDetailsEpic runs),
11
11
  * and request switching to the Unmatched tab. Debounced to reduce duplicate refreshes.
@@ -39,9 +39,17 @@ const bulkUploadAutomatchingTimeoutEpic = (actions$, state$) => actions$.pipe((0
39
39
  if (bulk.phase !== 'matching' || bulk.currentBatchId !== batchId) {
40
40
  return rxjs_1.EMPTY;
41
41
  }
42
+ /**
43
+ * Also request the single-batch details directly so the "X out of Y Receipts Matched"
44
+ * toast still fires when the backend actually completed between the last Pusher ping
45
+ * and this timeout. If Pusher already tagged the batch as still `processing`,
46
+ * `fetchBulkUploadBatchDetailsEpic`'s guard will skip the call and we simply rely on
47
+ * the list refresh to eventually populate details via `fetchMultipleBatchDetailsEpic`.
48
+ */
42
49
  return (0, rxjs_1.from)([
43
50
  (0, missingReceiptsViewReducer_1.bulkUploadAutomatchingTimedOut)(batchId),
44
51
  (0, missingReceiptsViewReducer_1.fetchBulkUploadBatches)({ cacheOverride: true }),
52
+ (0, missingReceiptsViewReducer_1.fetchBulkUploadBatchDetails)(),
45
53
  ]);
46
54
  }), (0, operators_1.takeUntil)((0, rxjs_1.merge)(actions$.pipe((0, operators_1.filter)(missingReceiptsViewReducer_1.clearBulkUpload.match)), actions$.pipe((0, operators_1.filter)(missingReceiptsViewReducer_1.pusherBatchStatusUpdate.match), (0, operators_1.filter)((a) => a.payload.batchId === batchId &&
47
55
  a.payload.status === 'completed')), actions$.pipe((0, operators_1.filter)(missingReceiptsViewReducer_1.fetchBulkUploadBatchDetailsSuccess.match), (0, operators_1.filter)((a) => a.payload.batchId === batchId)))));
@@ -101,14 +101,20 @@ export declare const fetchMissingReceipts: import("@reduxjs/toolkit").ActionCrea
101
101
  pageToken: string | undefined;
102
102
  cacheOverride: boolean | undefined;
103
103
  }, "expenseAutomationMissingReceiptsView/fetchCompletedTransactions", never, never>, fetchCompletedTransactionsSuccess: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
104
+ completedSubTab: CompletedSubTab;
104
105
  isInitialLoad: boolean;
105
106
  nextPageToken: string | null;
106
107
  selectedPeriod: MonthYearPeriod;
108
+ sortKey: BulkUploadSortKey;
109
+ sortOrder: SortOrder;
107
110
  totalCount: number;
108
111
  transactionIds: ID[];
109
112
  }, "expenseAutomationMissingReceiptsView/fetchCompletedTransactionsSuccess">, fetchCompletedTransactionsFailure: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
113
+ completedSubTab: CompletedSubTab;
110
114
  error: ZeniAPIStatus;
111
115
  selectedPeriod: MonthYearPeriod;
116
+ sortKey: BulkUploadSortKey;
117
+ sortOrder: SortOrder;
112
118
  }, "expenseAutomationMissingReceiptsView/fetchCompletedTransactionsFailure">;
113
119
  declare const _default: import("redux").Reducer<MissingReceiptsViewState>;
114
120
  export default _default;
@@ -527,9 +527,9 @@ const expenseAutomationMissingReceiptsView = (0, toolkit_1.createSlice)({
527
527
  },
528
528
  },
529
529
  fetchCompletedTransactionsSuccess(draft, action) {
530
- const { transactionIds, nextPageToken, totalCount, selectedPeriod, isInitialLoad, } = action.payload;
530
+ const { transactionIds, nextPageToken, totalCount, selectedPeriod, isInitialLoad, sortKey, sortOrder, completedSubTab, } = action.payload;
531
531
  const periodId = (0, timePeriod_1.toMonthYearPeriodId)(selectedPeriod);
532
- const cacheKey = (0, exports.getCompletedTransactionsCacheKey)(periodId, draft.bulkUpload.sortKey, draft.bulkUpload.sortOrder, draft.bulkUpload.completedSubTab);
532
+ const cacheKey = (0, exports.getCompletedTransactionsCacheKey)(periodId, sortKey, sortOrder, completedSubTab);
533
533
  if (isInitialLoad) {
534
534
  draft.bulkUpload.completedTransactionsByPeriod[cacheKey] = {
535
535
  transactionIds,
@@ -558,7 +558,7 @@ const expenseAutomationMissingReceiptsView = (0, toolkit_1.createSlice)({
558
558
  },
559
559
  fetchCompletedTransactionsFailure(draft, action) {
560
560
  const periodId = (0, timePeriod_1.toMonthYearPeriodId)(action.payload.selectedPeriod);
561
- const cacheKey = (0, exports.getCompletedTransactionsCacheKey)(periodId, draft.bulkUpload.sortKey, draft.bulkUpload.sortOrder, draft.bulkUpload.completedSubTab);
561
+ const cacheKey = (0, exports.getCompletedTransactionsCacheKey)(periodId, action.payload.sortKey, action.payload.sortOrder, action.payload.completedSubTab);
562
562
  const existing = draft.bulkUpload.completedTransactionsByPeriod[cacheKey];
563
563
  if (existing != null) {
564
564
  existing.fetchState = {
@@ -59,7 +59,7 @@ const fetchBillDetailEpic = (actions$, state$, zeniAPI) => actions$.pipe((0, ope
59
59
  response.data?.transaction?.transaction_id != null) {
60
60
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
61
61
  const transcationId = response.data.transaction.transaction_id;
62
- const vendorInResponse = response.data?.vendors[0];
62
+ const vendorInResponse = response.data?.vendors?.[0];
63
63
  const flattenedContacts = vendorInResponse?.contacts ?? [];
64
64
  const flattenedAddresses = (0, commonVendorViewHelper_1.getFlattenedAddress)(response.data?.vendors ?? []);
65
65
  const flattenedBankAccounts = vendorInResponse?.bank_accounts ?? [];
@@ -91,7 +91,7 @@ const fetchBillDetailEpic = (actions$, state$, zeniAPI) => actions$.pipe((0, ope
91
91
  ...response.data.bank_accounts,
92
92
  ]),
93
93
  (0, paymentInstrumentReducer_1.updatePaymentInstruments)(flattenedPaymentInstruments),
94
- (0, vendorReducer_1.updateVendors)(response.data.vendors),
94
+ (0, vendorReducer_1.updateVendors)(response.data.vendors ?? []),
95
95
  // end: save all vendor related entities
96
96
  ];
97
97
  if (vendorInResponse == null &&
@@ -100,15 +100,15 @@ const fetchBillDetailEpic = (actions$, state$, zeniAPI) => actions$.pipe((0, ope
100
100
  fetchActions.push((0, vendorListReducer_1.fetchVendorsList)({
101
101
  searchString: response.data?.transaction.candidate_vendor_name,
102
102
  }));
103
- fetchActions.push((0, billDetailViewReducer_1.waitForVendorByNameThenUpdateBillDetail)(billId, response.data, response.data.vendors[0]?.vendor_id));
103
+ fetchActions.push((0, billDetailViewReducer_1.waitForVendorByNameThenUpdateBillDetail)(billId, response.data, undefined));
104
104
  }
105
105
  else {
106
106
  fetchActions.push((0, billDetailViewReducer_1.updateBillDetail)({ billId, billDetail: response.data }));
107
- fetchActions.push((0, billDetailViewReducer_1.updateBillDetailFetchState)(transcationId, 'Completed', undefined, response.data.vendors[0]?.vendor_id));
107
+ fetchActions.push((0, billDetailViewReducer_1.updateBillDetailFetchState)(transcationId, 'Completed', undefined, vendorInResponse?.vendor_id));
108
108
  const transactionInResponse = response.data?.transaction;
109
109
  if (transactionInResponse != null &&
110
110
  transactionInResponse.total_amount != null &&
111
- Boolean(vendorInResponse) === true) {
111
+ vendorInResponse != null) {
112
112
  fetchActions.push((0, billPayReviewReducer_1.fetchDuplicateBill)(vendorInResponse.vendor_name, vendorInResponse.vendor_id, transactionInResponse.total_amount, transactionInResponse.recipient_total_amount, transactionInResponse.document_id, billId));
113
113
  }
114
114
  const billHasPaymentError = [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zeniai/client-epic-state",
3
- "version": "5.0.10",
3
+ "version": "5.0.11-beta0ND",
4
4
  "description": "Shared module between Web & Mobile containing required abstractions for state management, async network communication. ",
5
5
  "main": "lib/index.js",
6
6
  "module": "lib/esm/index.js",