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

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 (20) hide show
  1. package/lib/esm/index.js +4 -2
  2. package/lib/esm/view/expenseAutomationView/epics/missingReceipts/searchTransactionsForManualMatchEpic.js +5 -5
  3. package/lib/esm/view/expenseAutomationView/epics/missingReceipts/watchBulkUploadBatchStatusEpic.js +1 -1
  4. package/lib/esm/view/expenseAutomationView/payload/missingReceiptsPayload.js +13 -10
  5. package/lib/esm/view/expenseAutomationView/reducers/missingReceiptsViewReducer.js +4 -4
  6. package/lib/esm/view/expenseAutomationView/selectors/missingReceiptsSelector.js +30 -30
  7. package/lib/esm/view/expenseAutomationView/types/missingReceiptsViewState.js +30 -1
  8. package/lib/index.d.ts +2 -2
  9. package/lib/index.js +41 -32
  10. package/lib/tsconfig.typecheck.tsbuildinfo +1 -1
  11. package/lib/view/expenseAutomationView/epics/missingReceipts/searchTransactionsForManualMatchEpic.js +5 -5
  12. package/lib/view/expenseAutomationView/epics/missingReceipts/watchBulkUploadBatchStatusEpic.js +1 -1
  13. package/lib/view/expenseAutomationView/payload/missingReceiptsPayload.d.ts +1 -1
  14. package/lib/view/expenseAutomationView/payload/missingReceiptsPayload.js +13 -10
  15. package/lib/view/expenseAutomationView/reducers/missingReceiptsViewReducer.d.ts +1 -1
  16. package/lib/view/expenseAutomationView/reducers/missingReceiptsViewReducer.js +4 -4
  17. package/lib/view/expenseAutomationView/selectors/missingReceiptsSelector.js +30 -30
  18. package/lib/view/expenseAutomationView/types/missingReceiptsViewState.d.ts +20 -9
  19. package/lib/view/expenseAutomationView/types/missingReceiptsViewState.js +39 -2
  20. package/package.json +1 -1
@@ -18,14 +18,14 @@ const transactionsViewState_1 = require("../../types/transactionsViewState");
18
18
  exports.MANUAL_TRANSACTION_SEARCH_AUTO_CATEGORIZED = false;
19
19
  const searchTransactionsForManualMatchEpic = (actions$, state$, zeniAPI) => {
20
20
  const searchActions$ = actions$.pipe((0, operators_1.filter)(missingReceiptsViewReducer_1.searchTransactionsForManualMatch.match));
21
- const pagination$ = searchActions$.pipe((0, operators_1.filter)((a) => a.payload.pageToken != null));
21
+ const pagination$ = searchActions$.pipe((0, operators_1.filter)((action) => action.payload.pageToken != null));
22
22
  /**
23
23
  * No API for empty or 1-char queries; immediate merge so switchMap cancels any in-flight HTTP.
24
24
  */
25
- const newSearchTooShortOrClear$ = searchActions$.pipe((0, operators_1.filter)((a) => a.payload.pageToken == null &&
26
- a.payload.query.trim().length < 2));
27
- const newSearchDebounced$ = searchActions$.pipe((0, operators_1.filter)((a) => a.payload.pageToken == null &&
28
- a.payload.query.trim().length >= 2), (0, operators_1.debounceTime)(300));
25
+ const newSearchTooShortOrClear$ = searchActions$.pipe((0, operators_1.filter)((action) => action.payload.pageToken == null &&
26
+ action.payload.query.trim().length < 2));
27
+ const newSearchDebounced$ = searchActions$.pipe((0, operators_1.filter)((action) => action.payload.pageToken == null &&
28
+ action.payload.query.trim().length >= 2), (0, operators_1.debounceTime)(300));
29
29
  return (0, rxjs_1.merge)(pagination$, newSearchTooShortOrClear$, newSearchDebounced$).pipe((0, operators_1.switchMap)((action) => {
30
30
  const { query, pageToken } = action.payload;
31
31
  if (pageToken == null &&
@@ -31,7 +31,7 @@ exports.pusherBatchStatusCompletionEpic = pusherBatchStatusCompletionEpic;
31
31
  const pollBulkUploadBatchStatusEpic = (actions$, _state$, zeniAPI) => actions$.pipe((0, operators_1.filter)(missingReceiptsViewReducer_1.bulkUploadReceiptsSuccess.match), (0, operators_1.mergeMap)((action) => {
32
32
  const { batchId } = action.payload;
33
33
  let pollErrorNotified = false;
34
- return (0, rxjs_1.timer)(FALLBACK_FIRST_DELAY_MS, FALLBACK_POLL_INTERVAL_MS).pipe((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)), actions$.pipe((0, operators_1.filter)(missingReceiptsViewReducer_1.fetchBulkUploadBatchDetailsSuccess.match), (0, operators_1.filter)((a) => a.payload.batchId === batchId)))), (0, operators_1.switchMap)(() => zeniAPI
34
+ return (0, rxjs_1.timer)(FALLBACK_FIRST_DELAY_MS, FALLBACK_POLL_INTERVAL_MS).pipe((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)((action) => action.payload.batchId === batchId)), actions$.pipe((0, operators_1.filter)(missingReceiptsViewReducer_1.fetchBulkUploadBatchDetailsSuccess.match), (0, operators_1.filter)((action) => action.payload.batchId === batchId)))), (0, operators_1.switchMap)(() => zeniAPI
35
35
  .getJSON(`${zeniAPI.apiEndPoints.communicationAgentMicroServiceBaseUrl}/1.0/batches/${batchId}`)
36
36
  .pipe((0, operators_1.mergeMap)((response) => {
37
37
  /** Same batch-details URL; polls until `status` is completed (Pusher may win first). */
@@ -3,7 +3,7 @@ import { TransactionPayload } from '../../../entity/transaction/payloadTypes/tra
3
3
  import { SupportedTransactionPayload } from '../../../entity/transaction/transactionState';
4
4
  import { ZeniAPIResponse } from '../../../responsePayload';
5
5
  import type { MonthYearPeriodId } from '../../../commonStateTypes/timePeriod';
6
- import type { BatchDetails, BatchFile, BatchFileStatus, BatchListItem, BatchStatus, BatchSummary, ManualSearchResult } from '../types/missingReceiptsViewState';
6
+ import { type BatchDetails, type BatchFile, type BatchFileStatus, type BatchListItem, type BatchStatus, type BatchSummary, type ManualSearchResult } from '../types/missingReceiptsViewState';
7
7
  export interface MissingReceiptsQueryPayload {
8
8
  end_date: string;
9
9
  is_attachment_missing_only: boolean;
@@ -14,6 +14,7 @@ exports.toBatchListItem = toBatchListItem;
14
14
  exports.supportedTransactionPayloadToManualSearchResult = supportedTransactionPayloadToManualSearchResult;
15
15
  const urlPayload_1 = require("../../../commonPayloadTypes/urlPayload");
16
16
  const transactionPayload_1 = require("../../../entity/transaction/payloadTypes/transactionPayload");
17
+ const missingReceiptsViewState_1 = require("../types/missingReceiptsViewState");
17
18
  // -- Converter functions --
18
19
  /**
19
20
  * Maps batch-details API `files[].status` strings to canonical {@link BatchFileStatus}.
@@ -21,8 +22,8 @@ const transactionPayload_1 = require("../../../entity/transaction/payloadTypes/t
21
22
  * holds untyped status values.
22
23
  */
23
24
  function parseBatchFileStatus(raw) {
24
- const s = raw.trim().toLowerCase().replace(/-/g, '_');
25
- switch (s) {
25
+ const normalizedStatus = raw.trim().toLowerCase().replace(/-/g, '_');
26
+ switch (normalizedStatus) {
26
27
  case 'exact_match':
27
28
  case 'matched':
28
29
  return 'exact_match';
@@ -44,9 +45,9 @@ function parseBatchFileStatus(raw) {
44
45
  function toBatchFile(payload, filesEndPoint) {
45
46
  return {
46
47
  attachmentId: payload.attachment_id,
47
- candidates: payload.candidates?.map((c) => ({
48
- transactionId: c.transaction_id,
49
- matchScore: c.match_score,
48
+ candidates: payload.candidates?.map((candidate) => ({
49
+ transactionId: candidate.transaction_id,
50
+ matchScore: candidate.match_score,
50
51
  })),
51
52
  fileDownloadUrl: payload.file_id != null && filesEndPoint != null
52
53
  ? `${filesEndPoint}/1.0/files/${payload.file_id}?query=${encodeURIComponent(JSON.stringify({ download_file: true }))}`
@@ -54,7 +55,9 @@ function toBatchFile(payload, filesEndPoint) {
54
55
  fileId: payload.file_id,
55
56
  filePreviewUrl: payload.file_preview_url,
56
57
  filename: payload.filename,
57
- matchSource: payload.match_source,
58
+ matchSource: payload.match_source != null
59
+ ? (0, missingReceiptsViewState_1.toMatchSource)(payload.match_source)
60
+ : undefined,
58
61
  matchedTransactionId: payload.matched_transaction?.transaction_id,
59
62
  status: parseBatchFileStatus(payload.status),
60
63
  };
@@ -106,8 +109,8 @@ function toBatchDetails(payload, filesEndPoint) {
106
109
  return {
107
110
  batchId: payload.batch_id,
108
111
  createdAt: payload.created_at,
109
- files: payload.files.map((f) => toBatchFile(f, filesEndPoint)),
110
- status: payload.status,
112
+ files: payload.files.map((file) => toBatchFile(file, filesEndPoint)),
113
+ status: (0, missingReceiptsViewState_1.toBatchStatusValue)(payload.status),
111
114
  summary: toBatchSummary(payload.summary),
112
115
  };
113
116
  }
@@ -121,7 +124,7 @@ function isBatchListStatusCompleted(status) {
121
124
  * statuses for UI; only `completed` rows should trigger batch-details requests.
122
125
  */
123
126
  function filterBatchListItemsForBatchDetailsFetch(batches) {
124
- return batches.filter((b) => isBatchListStatusCompleted(b.status));
127
+ return batches.filter((batch) => isBatchListStatusCompleted(batch.status));
125
128
  }
126
129
  /**
127
130
  * Batch details API response `status` field — only completed payloads should be stored from
@@ -132,7 +135,7 @@ function isBatchDetailsApiStatusCompleted(status) {
132
135
  }
133
136
  function findBatchListItemForBatchId(batchListByPeriod, batchId) {
134
137
  for (const list of Object.values(batchListByPeriod)) {
135
- const found = list.find((b) => b.batchId === batchId);
138
+ const found = list.find((batch) => batch.batchId === batchId);
136
139
  if (found != null) {
137
140
  return found;
138
141
  }
@@ -68,7 +68,7 @@ export declare const fetchMissingReceipts: import("@reduxjs/toolkit").ActionCrea
68
68
  transactionId: ID;
69
69
  }, "expenseAutomationMissingReceiptsView/confirmBulkUploadMatchSuccess">, confirmBulkUploadMatchFailure: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
70
70
  error: ZeniAPIStatus;
71
- }, "expenseAutomationMissingReceiptsView/confirmBulkUploadMatchFailure">, setBulkUploadResultsTab: import("@reduxjs/toolkit").ActionCreatorWithPayload<BulkUploadResultsTab, "expenseAutomationMissingReceiptsView/setBulkUploadResultsTab">, setBulkUploadCompletedSubTab: import("@reduxjs/toolkit").ActionCreatorWithPayload<CompletedSubTab, "expenseAutomationMissingReceiptsView/setBulkUploadCompletedSubTab">, setBulkUploadSortConfig: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
71
+ }, "expenseAutomationMissingReceiptsView/confirmBulkUploadMatchFailure">, setBulkUploadResultsTab: import("@reduxjs/toolkit").ActionCreatorWithPayload<"completed" | "unmatched", "expenseAutomationMissingReceiptsView/setBulkUploadResultsTab">, setBulkUploadCompletedSubTab: import("@reduxjs/toolkit").ActionCreatorWithPayload<"all" | "manual" | "ai_accountant", "expenseAutomationMissingReceiptsView/setBulkUploadCompletedSubTab">, setBulkUploadSortConfig: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
72
72
  sortKey: BulkUploadSortKey;
73
73
  sortOrder: SortOrder;
74
74
  }, "expenseAutomationMissingReceiptsView/setBulkUploadSortConfig">, clearBulkUpload: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"expenseAutomationMissingReceiptsView/clearBulkUpload">, searchTransactionsForManualMatch: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[query: string, pageToken?: string | null | undefined], {
@@ -291,11 +291,11 @@ const expenseAutomationMissingReceiptsView = (0, toolkit_1.createSlice)({
291
291
  };
292
292
  },
293
293
  prepare(input) {
294
- const o = input ?? {};
294
+ const fetchOptions = input ?? {};
295
295
  return {
296
296
  payload: {
297
- cacheOverride: o.cacheOverride === true,
298
- invalidateBatchDetailsCache: o.invalidateBatchDetailsCache === true,
297
+ cacheOverride: fetchOptions.cacheOverride === true,
298
+ invalidateBatchDetailsCache: fetchOptions.invalidateBatchDetailsCache === true,
299
299
  },
300
300
  };
301
301
  },
@@ -348,7 +348,7 @@ const expenseAutomationMissingReceiptsView = (0, toolkit_1.createSlice)({
348
348
  };
349
349
  const details = draft.bulkUpload.batchDetailsById[batchId];
350
350
  if (details != null) {
351
- const file = details.files.find((f) => f.attachmentId === attachmentId);
351
+ const file = details.files.find((batchFile) => batchFile.attachmentId === attachmentId);
352
352
  if (file != null) {
353
353
  const originalStatus = file.status;
354
354
  file.status = 'exact_match';
@@ -74,41 +74,41 @@ function getExpenseAutomationMissingReceiptsView(state) {
74
74
  const unmatchedSectionBatchId = bulkUpload.phase === 'matching' || bulkUpload.phase === 'uploading'
75
75
  ? bulkUpload.currentBatchId ?? primaryBatchIdFromDetailsOrder
76
76
  : primaryBatchIdFromDetailsOrder;
77
- const completedBatchesInApiOrder = batchList.filter((b) => (0, missingReceiptsPayload_1.isBatchListStatusCompleted)(b.status));
77
+ const completedBatchesInApiOrder = batchList.filter((batchListItem) => (0, missingReceiptsPayload_1.isBatchListStatusCompleted)(batchListItem.status));
78
78
  const currentBatchDetails = unmatchedSectionBatchId != null
79
79
  ? bulkUpload.batchDetailsById[unmatchedSectionBatchId]
80
80
  : undefined;
81
81
  const resolvedFiles = currentBatchDetails?.files.map((file) => resolveBatchFile(file, currentBatchDetails.batchId, transactionState));
82
82
  const failedIds = new Set(bulkUpload.failedBatchDetailIds);
83
- const hasMoreBatchDetails = completedBatchesInApiOrder.some((b) => bulkUpload.batchDetailsById[b.batchId] == null &&
84
- !failedIds.has(b.batchId));
83
+ const hasMoreBatchDetails = completedBatchesInApiOrder.some((batchListItem) => bulkUpload.batchDetailsById[batchListItem.batchId] == null &&
84
+ !failedIds.has(batchListItem.batchId));
85
85
  const getSortValue = (file) => {
86
- const t = file.matchedTransaction;
87
- if (t == null) {
86
+ const matchedTransaction = file.matchedTransaction;
87
+ if (matchedTransaction == null) {
88
88
  return null;
89
89
  }
90
90
  switch (bulkUpload.sortKey) {
91
91
  case 'vendor':
92
- return (t.vendorName ?? t.description)?.toLowerCase() ?? null;
92
+ return (matchedTransaction.vendorName ?? matchedTransaction.description)?.toLowerCase() ?? null;
93
93
  case 'category': {
94
- const line = t.lines?.[0];
94
+ const line = matchedTransaction.lines?.[0];
95
95
  return line?.account?.accountName?.toLowerCase() ?? null;
96
96
  }
97
97
  case 'class': {
98
- const line = t.lines?.[0];
98
+ const line = matchedTransaction.lines?.[0];
99
99
  return line?.class?.className?.toLowerCase() ?? null;
100
100
  }
101
101
  case 'date':
102
- return t.date.valueOf();
102
+ return matchedTransaction.date.valueOf();
103
103
  case 'amount':
104
- return t.amount.amount;
104
+ return matchedTransaction.amount.amount;
105
105
  default:
106
106
  return null;
107
107
  }
108
108
  };
109
109
  const bulkUploadSortDirection = bulkUpload.sortOrder === 'ascending' ? 'asc' : 'desc';
110
- const matchedFiles = (0, orderBy_1.default)(resolvedFiles?.filter((f) => f.status === 'exact_match') ?? [], getSortValue, bulkUploadSortDirection);
111
- const unmatchedFiles = (0, orderBy_1.default)(resolvedFiles?.filter((f) => (0, missingReceiptsViewState_1.isUnmatchedTabFileStatus)(f.status)) ?? [], getSortValue, bulkUploadSortDirection);
110
+ const matchedFiles = (0, orderBy_1.default)(resolvedFiles?.filter((resolvedFile) => resolvedFile.status === 'exact_match') ?? [], getSortValue, bulkUploadSortDirection);
111
+ const unmatchedFiles = (0, orderBy_1.default)(resolvedFiles?.filter((resolvedFile) => (0, missingReceiptsViewState_1.isUnmatchedTabFileStatus)(resolvedFile.status)) ?? [], getSortValue, bulkUploadSortDirection);
112
112
  const progress = currentBatchStatus != null
113
113
  ? {
114
114
  ...currentBatchStatus.progress,
@@ -125,16 +125,16 @@ function getExpenseAutomationMissingReceiptsView(state) {
125
125
  * that has details loaded (otherwise past is empty and receipts vanish from the UI).
126
126
  */
127
127
  const pastBatches = unmatchedSectionBatchId != null
128
- ? batchList.filter((b) => b.batchId !== unmatchedSectionBatchId)
128
+ ? batchList.filter((batchListItem) => batchListItem.batchId !== unmatchedSectionBatchId)
129
129
  : batchList;
130
- const pastUnmatchedFiles = pastBatches.flatMap((b) => {
131
- const details = bulkUpload.batchDetailsById[b.batchId];
130
+ const pastUnmatchedFiles = pastBatches.flatMap((pastBatch) => {
131
+ const details = bulkUpload.batchDetailsById[pastBatch.batchId];
132
132
  if (details == null) {
133
133
  return [];
134
134
  }
135
135
  return details.files
136
- .filter((f) => (0, missingReceiptsViewState_1.isUnmatchedTabFileStatus)(f.status))
137
- .map((f) => resolveBatchFile(f, b.batchId, transactionState));
136
+ .filter((batchFile) => (0, missingReceiptsViewState_1.isUnmatchedTabFileStatus)(batchFile.status))
137
+ .map((batchFile) => resolveBatchFile(batchFile, pastBatch.batchId, transactionState));
138
138
  });
139
139
  const completedTransactionsCacheKey = monthYearPeriodId != null
140
140
  ? (0, missingReceiptsViewReducer_1.getCompletedTransactionsCacheKey)(monthYearPeriodId, bulkUpload.sortKey, bulkUpload.sortOrder, bulkUpload.completedSubTab)
@@ -153,11 +153,11 @@ function getExpenseAutomationMissingReceiptsView(state) {
153
153
  summary: currentBatchDetails.summary,
154
154
  }
155
155
  : undefined;
156
- const manualSearchResults = bulkUpload.manualSearch.results.map((r) => {
157
- const t = (0, transactionSelector_1.getSupportedTransactionById)(transactionState, r.transactionId);
156
+ const manualSearchResults = bulkUpload.manualSearch.results.map((result) => {
157
+ const transaction = (0, transactionSelector_1.getSupportedTransactionById)(transactionState, result.transactionId);
158
158
  return {
159
- ...r,
160
- vendorLogo: r.vendorLogo ?? t?.logo?.href,
159
+ ...result,
160
+ vendorLogo: result.vendorLogo ?? transaction?.logo?.href,
161
161
  };
162
162
  });
163
163
  return {
@@ -207,7 +207,7 @@ function getExpenseAutomationMissingReceiptsView(state) {
207
207
  };
208
208
  }
209
209
  function batchDetailsHasUnmatchedWork(details) {
210
- return details.files.some((f) => (0, missingReceiptsViewState_1.isUnmatchedTabFileStatus)(f.status));
210
+ return details.files.some((file) => (0, missingReceiptsViewState_1.isUnmatchedTabFileStatus)(file.status));
211
211
  }
212
212
  /** List row summary before batch details load — aligns with unmatched / possible-match work. */
213
213
  function batchListItemHasUnmatchedWork(batch) {
@@ -224,17 +224,17 @@ function batchListItemHasUnmatchedWork(batch) {
224
224
  */
225
225
  function getPrimaryBatchIdFromBatchListOrder(batchListInPlatformOrder, batchDetailsById, failedBatchDetailIds) {
226
226
  const failedIds = new Set(failedBatchDetailIds);
227
- const anyCompletedBatchHasUnmatchedWork = batchListInPlatformOrder.some((b) => {
228
- if (failedIds.has(b.batchId)) {
227
+ const anyCompletedBatchHasUnmatchedWork = batchListInPlatformOrder.some((batch) => {
228
+ if (failedIds.has(batch.batchId)) {
229
229
  return false;
230
230
  }
231
- const d = batchDetailsById[b.batchId];
232
- if (d != null &&
233
- d.status === 'completed' &&
234
- batchDetailsHasUnmatchedWork(d)) {
231
+ const details = batchDetailsById[batch.batchId];
232
+ if (details != null &&
233
+ details.status === 'completed' &&
234
+ batchDetailsHasUnmatchedWork(details)) {
235
235
  return true;
236
236
  }
237
- return d == null && batchListItemHasUnmatchedWork(b);
237
+ return details == null && batchListItemHasUnmatchedWork(batch);
238
238
  });
239
239
  for (const batch of batchListInPlatformOrder) {
240
240
  if (failedIds.has(batch.batchId)) {
@@ -271,7 +271,7 @@ function resolveBatchFile(file, batchId, transactionState) {
271
271
  ? { transaction, matchScore: ref.matchScore }
272
272
  : undefined;
273
273
  })
274
- .filter((c) => c != null);
274
+ .filter((candidate) => candidate != null);
275
275
  return {
276
276
  attachmentId: file.attachmentId,
277
277
  batchId,
@@ -3,7 +3,6 @@ import { SortOrder } from '../../../commonStateTypes/selectorTypes/sortOrderType
3
3
  import { MonthYearPeriodId } from '../../../commonStateTypes/timePeriod';
4
4
  export declare const toMissingReceiptsSortKey: (v: string) => "date" | "amount" | "vendor" | "category" | "class";
5
5
  export type MissingReceiptsSortKey = ReturnType<typeof toMissingReceiptsSortKey>;
6
- export type BulkUploadSortKey = 'amount' | 'category' | 'class' | 'date' | 'vendor';
7
6
  export interface MissingReceiptsViewUIState {
8
7
  scrollPosition: {
9
8
  scrollTop: number;
@@ -18,15 +17,26 @@ export interface MissingReceiptsViewUIState {
18
17
  * Kept in sync with `ManualSearchInput` in web-components (fires search only when length ≥ this).
19
18
  */
20
19
  export declare const MIN_MANUAL_TRANSACTION_SEARCH_LENGTH = 2;
21
- export type BatchStatusValue = 'pending' | 'processing' | 'completed';
22
- export type BatchFileStatus = 'exact_match' | 'possible_matches' | 'no_match' | 'failed';
20
+ export declare const toBatchStatusValue: (v: string) => "pending" | "processing" | "completed";
21
+ export type BatchStatusValue = ReturnType<typeof toBatchStatusValue>;
22
+ /** Canonical batch file statuses (API ingress may use aliases; see `parseBatchFileStatus`). */
23
+ export declare const BATCH_FILE_STATUSES: readonly ["exact_match", "possible_matches", "no_match", "failed"];
24
+ export declare const toBatchFileStatus: (v: string) => "failed" | "exact_match" | "possible_matches" | "no_match";
25
+ export type BatchFileStatus = ReturnType<typeof toBatchFileStatus>;
23
26
  /** True for files that belong in the Unmatched tab (possible matches or no match). */
24
27
  export declare function isUnmatchedTabFileStatus(status: BatchFileStatus): boolean;
25
- export type BulkUploadPhase = 'idle' | 'uploading' | 'matching' | 'completed';
26
- export type BulkUploadResultsTab = 'completed' | 'unmatched';
27
- export type MissingReceiptsTab = 'missing' | BulkUploadResultsTab;
28
- export type CompletedSubTab = 'all' | 'ai_accountant' | 'manual';
29
- export type MatchSource = 'ai' | 'manual';
28
+ export declare const toBulkUploadPhase: (v: string) => "completed" | "idle" | "uploading" | "matching";
29
+ export type BulkUploadPhase = ReturnType<typeof toBulkUploadPhase>;
30
+ export declare const toBulkUploadResultsTab: (v: string) => "completed" | "unmatched";
31
+ export type BulkUploadResultsTab = ReturnType<typeof toBulkUploadResultsTab>;
32
+ export declare const toMissingReceiptsTab: (v: string) => "completed" | "unmatched" | "missing";
33
+ export type MissingReceiptsTab = ReturnType<typeof toMissingReceiptsTab>;
34
+ export declare const toCompletedSubTab: (v: string) => "all" | "manual" | "ai_accountant";
35
+ export type CompletedSubTab = ReturnType<typeof toCompletedSubTab>;
36
+ export declare const toMatchSource: (v: string) => "manual" | "ai";
37
+ export type MatchSource = ReturnType<typeof toMatchSource>;
38
+ export declare const toBulkUploadSortKey: (v: string) => "date" | "amount" | "vendor" | "category" | "class";
39
+ export type BulkUploadSortKey = ReturnType<typeof toBulkUploadSortKey>;
30
40
  export interface CandidateRef {
31
41
  matchScore: number;
32
42
  transactionId: ID;
@@ -106,7 +116,8 @@ export interface ManualSearchState {
106
116
  searchQuery: string;
107
117
  totalCount: number;
108
118
  }
109
- export type CompletedTransactionsMatchType = 'all' | 'ai_accountant' | 'manual';
119
+ /** Same union as {@link CompletedSubTab} — used for completed-transactions API `match_type`. */
120
+ export type CompletedTransactionsMatchType = CompletedSubTab;
110
121
  export interface CompletedTransactionsState {
111
122
  fetchState: FetchStateAndError;
112
123
  nextPageToken: string | null;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.MIN_MANUAL_TRANSACTION_SEARCH_LENGTH = exports.toMissingReceiptsSortKey = void 0;
3
+ exports.toBulkUploadSortKey = exports.toMatchSource = exports.toCompletedSubTab = exports.toMissingReceiptsTab = exports.toBulkUploadResultsTab = exports.toBulkUploadPhase = exports.toBatchFileStatus = exports.BATCH_FILE_STATUSES = exports.toBatchStatusValue = exports.MIN_MANUAL_TRANSACTION_SEARCH_LENGTH = exports.toMissingReceiptsSortKey = void 0;
4
4
  exports.isUnmatchedTabFileStatus = isUnmatchedTabFileStatus;
5
5
  const stringToUnion_1 = require("../../../commonStateTypes/stringToUnion");
6
6
  const MISSING_RECEIPTS_SORT_KEYS = [
@@ -18,7 +18,44 @@ exports.toMissingReceiptsSortKey = toMissingReceiptsSortKey;
18
18
  * Kept in sync with `ManualSearchInput` in web-components (fires search only when length ≥ this).
19
19
  */
20
20
  exports.MIN_MANUAL_TRANSACTION_SEARCH_LENGTH = 2;
21
+ const BATCH_STATUS_VALUES = ['pending', 'processing', 'completed'];
22
+ const toBatchStatusValue = (v) => (0, stringToUnion_1.stringToUnion)(v.trim().toLowerCase(), BATCH_STATUS_VALUES);
23
+ exports.toBatchStatusValue = toBatchStatusValue;
24
+ /** Canonical batch file statuses (API ingress may use aliases; see `parseBatchFileStatus`). */
25
+ exports.BATCH_FILE_STATUSES = [
26
+ 'exact_match',
27
+ 'possible_matches',
28
+ 'no_match',
29
+ 'failed',
30
+ ];
31
+ const toBatchFileStatus = (v) => (0, stringToUnion_1.stringToUnion)(v.trim().toLowerCase().replace(/-/g, '_'), exports.BATCH_FILE_STATUSES);
32
+ exports.toBatchFileStatus = toBatchFileStatus;
33
+ const UNMATCHED_TAB_FILE_STATUSES = ['possible_matches', 'no_match'];
21
34
  /** True for files that belong in the Unmatched tab (possible matches or no match). */
22
35
  function isUnmatchedTabFileStatus(status) {
23
- return status === 'possible_matches' || status === 'no_match';
36
+ return UNMATCHED_TAB_FILE_STATUSES.includes(status);
24
37
  }
38
+ const BULK_UPLOAD_PHASES = ['idle', 'uploading', 'matching', 'completed'];
39
+ const toBulkUploadPhase = (v) => (0, stringToUnion_1.stringToUnion)(v.trim().toLowerCase(), BULK_UPLOAD_PHASES);
40
+ exports.toBulkUploadPhase = toBulkUploadPhase;
41
+ const BULK_UPLOAD_RESULTS_TABS = ['completed', 'unmatched'];
42
+ const toBulkUploadResultsTab = (v) => (0, stringToUnion_1.stringToUnion)(v.trim().toLowerCase(), BULK_UPLOAD_RESULTS_TABS);
43
+ exports.toBulkUploadResultsTab = toBulkUploadResultsTab;
44
+ const MISSING_RECEIPTS_TABS = ['missing', 'completed', 'unmatched'];
45
+ const toMissingReceiptsTab = (v) => (0, stringToUnion_1.stringToUnion)(v.trim().toLowerCase(), MISSING_RECEIPTS_TABS);
46
+ exports.toMissingReceiptsTab = toMissingReceiptsTab;
47
+ const COMPLETED_SUB_TABS = ['all', 'ai_accountant', 'manual'];
48
+ const toCompletedSubTab = (v) => (0, stringToUnion_1.stringToUnion)(v.trim().toLowerCase(), COMPLETED_SUB_TABS);
49
+ exports.toCompletedSubTab = toCompletedSubTab;
50
+ const MATCH_SOURCES = ['ai', 'manual'];
51
+ const toMatchSource = (v) => (0, stringToUnion_1.stringToUnion)(v.trim().toLowerCase(), MATCH_SOURCES);
52
+ exports.toMatchSource = toMatchSource;
53
+ const BULK_UPLOAD_SORT_KEYS = [
54
+ 'amount',
55
+ 'category',
56
+ 'class',
57
+ 'date',
58
+ 'vendor',
59
+ ];
60
+ const toBulkUploadSortKey = (v) => (0, stringToUnion_1.stringToUnion)(v.trim().toLowerCase(), BULK_UPLOAD_SORT_KEYS);
61
+ exports.toBulkUploadSortKey = toBulkUploadSortKey;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zeniai/client-epic-state",
3
- "version": "4.19.84-betaVR10",
3
+ "version": "4.19.84-betaVR11",
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",