@zeniai/client-epic-state 4.19.37-betaVR8 → 4.19.37
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/entity/snackbar/snackbarTypes.d.ts +1 -1
- package/lib/entity/snackbar/snackbarTypes.js +0 -1
- package/lib/epic.d.ts +1 -9
- package/lib/epic.js +1 -9
- package/lib/esm/entity/snackbar/snackbarTypes.js +0 -1
- package/lib/esm/epic.js +1 -9
- package/lib/esm/index.js +2 -4
- package/lib/esm/view/expenseAutomationView/payload/missingReceiptsPayload.js +1 -100
- package/lib/esm/view/expenseAutomationView/reducers/missingReceiptsViewReducer.js +1 -264
- package/lib/esm/view/expenseAutomationView/selectors/missingReceiptsSelector.js +1 -128
- package/lib/esm/zeniAPI.js +3 -41
- package/lib/index.d.ts +5 -7
- package/lib/index.js +30 -58
- package/lib/tsconfig.typecheck.tsbuildinfo +1 -0
- package/lib/view/expenseAutomationView/helpers/transactionCategorizationLocalDataHelper.d.ts +1 -1
- package/lib/view/expenseAutomationView/payload/missingReceiptsPayload.d.ts +0 -108
- package/lib/view/expenseAutomationView/payload/missingReceiptsPayload.js +0 -107
- package/lib/view/expenseAutomationView/reducers/missingReceiptsViewReducer.d.ts +3 -51
- package/lib/view/expenseAutomationView/reducers/missingReceiptsViewReducer.js +2 -265
- package/lib/view/expenseAutomationView/selectorTypes/missingReceiptsSelectorTypes.d.ts +1 -61
- package/lib/view/expenseAutomationView/selectors/missingReceiptsSelector.d.ts +1 -1
- package/lib/view/expenseAutomationView/selectors/missingReceiptsSelector.js +0 -127
- package/lib/view/expenseAutomationView/types/missingReceiptsViewState.d.ts +0 -104
- package/lib/zeniAPI.d.ts +0 -9
- package/lib/zeniAPI.js +2 -40
- package/package.json +2 -2
- package/lib/esm/view/expenseAutomationView/epics/missingReceipts/bulkUploadReceiptsEpic.js +0 -24
- package/lib/esm/view/expenseAutomationView/epics/missingReceipts/confirmBulkUploadMatchEpic.js +0 -49
- package/lib/esm/view/expenseAutomationView/epics/missingReceipts/fetchBulkUploadBatchDetailsEpic.js +0 -31
- package/lib/esm/view/expenseAutomationView/epics/missingReceipts/fetchBulkUploadBatchesEpic.js +0 -41
- package/lib/esm/view/expenseAutomationView/epics/missingReceipts/fetchCompletedTransactionsEpic.js +0 -57
- package/lib/esm/view/expenseAutomationView/epics/missingReceipts/fetchMultipleBatchDetailsEpic.js +0 -35
- package/lib/esm/view/expenseAutomationView/epics/missingReceipts/searchTransactionsForManualMatchEpic.js +0 -27
- package/lib/esm/view/expenseAutomationView/epics/missingReceipts/watchBulkUploadBatchStatusEpic.js +0 -41
- package/lib/view/expenseAutomationView/epics/missingReceipts/bulkUploadReceiptsEpic.d.ts +0 -15
- package/lib/view/expenseAutomationView/epics/missingReceipts/bulkUploadReceiptsEpic.js +0 -28
- package/lib/view/expenseAutomationView/epics/missingReceipts/confirmBulkUploadMatchEpic.d.ts +0 -7
- package/lib/view/expenseAutomationView/epics/missingReceipts/confirmBulkUploadMatchEpic.js +0 -53
- package/lib/view/expenseAutomationView/epics/missingReceipts/fetchBulkUploadBatchDetailsEpic.d.ts +0 -8
- package/lib/view/expenseAutomationView/epics/missingReceipts/fetchBulkUploadBatchDetailsEpic.js +0 -35
- package/lib/view/expenseAutomationView/epics/missingReceipts/fetchBulkUploadBatchesEpic.d.ts +0 -7
- package/lib/view/expenseAutomationView/epics/missingReceipts/fetchBulkUploadBatchesEpic.js +0 -45
- package/lib/view/expenseAutomationView/epics/missingReceipts/fetchCompletedTransactionsEpic.d.ts +0 -8
- package/lib/view/expenseAutomationView/epics/missingReceipts/fetchCompletedTransactionsEpic.js +0 -61
- package/lib/view/expenseAutomationView/epics/missingReceipts/fetchMultipleBatchDetailsEpic.d.ts +0 -8
- package/lib/view/expenseAutomationView/epics/missingReceipts/fetchMultipleBatchDetailsEpic.js +0 -39
- package/lib/view/expenseAutomationView/epics/missingReceipts/searchTransactionsForManualMatchEpic.d.ts +0 -6
- package/lib/view/expenseAutomationView/epics/missingReceipts/searchTransactionsForManualMatchEpic.js +0 -31
- package/lib/view/expenseAutomationView/epics/missingReceipts/watchBulkUploadBatchStatusEpic.d.ts +0 -15
- package/lib/view/expenseAutomationView/epics/missingReceipts/watchBulkUploadBatchStatusEpic.js +0 -46
|
@@ -1,68 +1,8 @@
|
|
|
1
1
|
import { CompletionStatusType, FetchStateAndError, ID } from '../../../commonStateTypes/common';
|
|
2
2
|
import { SelectorView } from '../../../commonStateTypes/viewAndReport/viewAndReport';
|
|
3
3
|
import { SupportedTransaction } from '../../../entity/transaction/transactionState';
|
|
4
|
-
import {
|
|
5
|
-
import type { BatchFileStatus, BatchListItem, BatchStatus, BulkUploadPhase, BulkUploadResultsTab, BulkUploadSortKey, CompletedSubTab, ManualSearchState, MatchSource, MissingReceiptsViewUIState } from '../types/missingReceiptsViewState';
|
|
6
|
-
export interface CompletedTransactionsSelectorData {
|
|
7
|
-
fetchState: FetchStateAndError;
|
|
8
|
-
nextPageToken: string | null;
|
|
9
|
-
totalCount: number;
|
|
10
|
-
transactions: SupportedTransaction[];
|
|
11
|
-
}
|
|
12
|
-
export interface ResolvedCandidate {
|
|
13
|
-
matchScore: number;
|
|
14
|
-
transaction: SupportedTransaction;
|
|
15
|
-
}
|
|
16
|
-
export interface ResolvedBatchFile {
|
|
17
|
-
attachmentId: ID;
|
|
18
|
-
fileId: ID;
|
|
19
|
-
filename: string;
|
|
20
|
-
filePreviewUrl: string | null;
|
|
21
|
-
status: BatchFileStatus;
|
|
22
|
-
candidates?: ResolvedCandidate[];
|
|
23
|
-
matchedTransaction?: SupportedTransaction;
|
|
24
|
-
matchSource?: MatchSource;
|
|
25
|
-
}
|
|
26
|
-
export interface BulkUploadSelectorData {
|
|
27
|
-
batchDetails: ResolvedBatchDetails | undefined;
|
|
28
|
-
batchList: BatchListItem[];
|
|
29
|
-
batchListFetchState: FetchStateAndError;
|
|
30
|
-
batchStatus: BatchStatus | undefined;
|
|
31
|
-
completedSubTab: CompletedSubTab;
|
|
32
|
-
completedTransactions: CompletedTransactionsSelectorData;
|
|
33
|
-
confirmMatchStatus: FetchStateAndError;
|
|
34
|
-
currentResultsTab: BulkUploadResultsTab;
|
|
35
|
-
manualSearch: ManualSearchState;
|
|
36
|
-
matchedFiles: ResolvedBatchFile[];
|
|
37
|
-
pastBatches: BatchListItem[];
|
|
38
|
-
pastUnmatchedFiles: ResolvedBatchFile[];
|
|
39
|
-
phase: BulkUploadPhase;
|
|
40
|
-
progress: {
|
|
41
|
-
percentage: number;
|
|
42
|
-
processed: number;
|
|
43
|
-
total: number;
|
|
44
|
-
};
|
|
45
|
-
sortKey: BulkUploadSortKey;
|
|
46
|
-
sortOrder: SortOrder;
|
|
47
|
-
unmatchedFiles: ResolvedBatchFile[];
|
|
48
|
-
uploadProgress: number;
|
|
49
|
-
uploadStatus: FetchStateAndError;
|
|
50
|
-
}
|
|
51
|
-
export interface ResolvedBatchDetails {
|
|
52
|
-
batchId: ID;
|
|
53
|
-
createdAt: string;
|
|
54
|
-
files: ResolvedBatchFile[];
|
|
55
|
-
status: string;
|
|
56
|
-
summary: {
|
|
57
|
-
failed: number;
|
|
58
|
-
matched: number;
|
|
59
|
-
noMatch: number;
|
|
60
|
-
possibleMatches: number;
|
|
61
|
-
total: number;
|
|
62
|
-
};
|
|
63
|
-
}
|
|
4
|
+
import { MissingReceiptsViewUIState } from '../types/missingReceiptsViewState';
|
|
64
5
|
export interface ExpenseAutomationMissingReceiptsViewSelector extends SelectorView {
|
|
65
|
-
bulkUpload: BulkUploadSelectorData;
|
|
66
6
|
completionStatus: CompletionStatusType;
|
|
67
7
|
refreshStatus: FetchStateAndError;
|
|
68
8
|
transactions: SupportedTransaction[];
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { RootState } from '../../../reducer';
|
|
2
|
-
import
|
|
2
|
+
import { ExpenseAutomationMissingReceiptsViewSelector } from '../selectorTypes/missingReceiptsSelectorTypes';
|
|
3
3
|
export declare function getExpenseAutomationMissingReceiptsView(state: RootState): ExpenseAutomationMissingReceiptsViewSelector;
|
|
@@ -53,79 +53,6 @@ function getExpenseAutomationMissingReceiptsView(state) {
|
|
|
53
53
|
const completionStatus = missingReceiptsCompletionStatus != null
|
|
54
54
|
? missingReceiptsCompletionStatus
|
|
55
55
|
: 'incomplete';
|
|
56
|
-
const { bulkUpload } = expenseAutomationMissingReceiptsViewState;
|
|
57
|
-
const currentBatchStatus = bulkUpload.currentBatchId != null
|
|
58
|
-
? bulkUpload.batchStatusById[bulkUpload.currentBatchId]
|
|
59
|
-
: undefined;
|
|
60
|
-
const currentBatchDetails = bulkUpload.currentBatchId != null
|
|
61
|
-
? bulkUpload.batchDetailsById[bulkUpload.currentBatchId]
|
|
62
|
-
: undefined;
|
|
63
|
-
const resolvedFiles = currentBatchDetails?.files.map((file) => resolveBatchFile(file, transactionState));
|
|
64
|
-
const getSortValue = (file) => {
|
|
65
|
-
const t = file.matchedTransaction;
|
|
66
|
-
if (t == null) {
|
|
67
|
-
return null;
|
|
68
|
-
}
|
|
69
|
-
switch (bulkUpload.sortKey) {
|
|
70
|
-
case 'vendor':
|
|
71
|
-
return (t.vendorName ?? t.description)?.toLowerCase() ?? null;
|
|
72
|
-
case 'category': {
|
|
73
|
-
const line = t.lines?.[0];
|
|
74
|
-
return line?.account?.accountName?.toLowerCase() ?? null;
|
|
75
|
-
}
|
|
76
|
-
case 'class': {
|
|
77
|
-
const line = t.lines?.[0];
|
|
78
|
-
return line?.class?.className?.toLowerCase() ?? null;
|
|
79
|
-
}
|
|
80
|
-
case 'date':
|
|
81
|
-
return t.date.valueOf();
|
|
82
|
-
case 'amount':
|
|
83
|
-
return t.amount.amount;
|
|
84
|
-
default:
|
|
85
|
-
return null;
|
|
86
|
-
}
|
|
87
|
-
};
|
|
88
|
-
const bulkUploadSortDirection = bulkUpload.sortOrder === 'ascending' ? 'asc' : 'desc';
|
|
89
|
-
const matchedFiles = (0, orderBy_1.default)(resolvedFiles?.filter((f) => f.status === 'matched') ?? [], getSortValue, bulkUploadSortDirection);
|
|
90
|
-
const unmatchedFiles = (0, orderBy_1.default)(resolvedFiles?.filter((f) => f.status === 'un_matched' || f.status === 'no_match') ?? [], getSortValue, bulkUploadSortDirection);
|
|
91
|
-
const progress = currentBatchStatus != null
|
|
92
|
-
? {
|
|
93
|
-
...currentBatchStatus.progress,
|
|
94
|
-
percentage: currentBatchStatus.progress.total > 0
|
|
95
|
-
? Math.round((currentBatchStatus.progress.processed /
|
|
96
|
-
currentBatchStatus.progress.total) *
|
|
97
|
-
100)
|
|
98
|
-
: 0,
|
|
99
|
-
}
|
|
100
|
-
: { total: 0, processed: 0, percentage: 0 };
|
|
101
|
-
const batchList = monthYearPeriodId != null
|
|
102
|
-
? bulkUpload.batchListByPeriod[monthYearPeriodId] ?? []
|
|
103
|
-
: [];
|
|
104
|
-
const batchListFetchState = bulkUpload.batchListFetchState;
|
|
105
|
-
const pastBatches = batchList.filter((b) => b.batchId !== bulkUpload.currentBatchId);
|
|
106
|
-
const pastUnmatchedFiles = pastBatches.flatMap((b) => {
|
|
107
|
-
const details = bulkUpload.batchDetailsById[b.batchId];
|
|
108
|
-
if (details == null) {
|
|
109
|
-
return [];
|
|
110
|
-
}
|
|
111
|
-
return details.files
|
|
112
|
-
.filter((f) => f.status === 'un_matched' || f.status === 'no_match')
|
|
113
|
-
.map((f) => resolveBatchFile(f, transactionState));
|
|
114
|
-
});
|
|
115
|
-
const completedTransactionsForPeriod = monthYearPeriodId != null
|
|
116
|
-
? bulkUpload.completedTransactionsByPeriod[monthYearPeriodId]
|
|
117
|
-
: undefined;
|
|
118
|
-
const completedTransactionIds = completedTransactionsForPeriod?.transactionIds ?? [];
|
|
119
|
-
const resolvedCompletedTransactions = (0, transactionSelector_1.getSupportedTransactionsByIds)(transactionState, completedTransactionIds);
|
|
120
|
-
const resolvedBatchDetails = currentBatchDetails != null && resolvedFiles != null
|
|
121
|
-
? {
|
|
122
|
-
batchId: currentBatchDetails.batchId,
|
|
123
|
-
createdAt: currentBatchDetails.createdAt,
|
|
124
|
-
files: resolvedFiles,
|
|
125
|
-
status: currentBatchDetails.status,
|
|
126
|
-
summary: currentBatchDetails.summary,
|
|
127
|
-
}
|
|
128
|
-
: undefined;
|
|
129
56
|
return {
|
|
130
57
|
fetchState,
|
|
131
58
|
error,
|
|
@@ -134,59 +61,5 @@ function getExpenseAutomationMissingReceiptsView(state) {
|
|
|
134
61
|
refreshStatus,
|
|
135
62
|
transactions: sortedTransactions,
|
|
136
63
|
completionStatus,
|
|
137
|
-
bulkUpload: {
|
|
138
|
-
phase: bulkUpload.phase,
|
|
139
|
-
uploadStatus: bulkUpload.uploadStatus,
|
|
140
|
-
batchStatus: currentBatchStatus,
|
|
141
|
-
batchDetails: resolvedBatchDetails,
|
|
142
|
-
completedSubTab: bulkUpload.completedSubTab,
|
|
143
|
-
completedTransactions: {
|
|
144
|
-
fetchState: completedTransactionsForPeriod?.fetchState ?? {
|
|
145
|
-
fetchState: 'Not-Started',
|
|
146
|
-
error: undefined,
|
|
147
|
-
},
|
|
148
|
-
nextPageToken: completedTransactionsForPeriod?.nextPageToken ?? null,
|
|
149
|
-
totalCount: completedTransactionsForPeriod?.totalCount ?? 0,
|
|
150
|
-
transactions: resolvedCompletedTransactions,
|
|
151
|
-
},
|
|
152
|
-
matchedFiles,
|
|
153
|
-
unmatchedFiles,
|
|
154
|
-
progress,
|
|
155
|
-
currentResultsTab: bulkUpload.currentResultsTab,
|
|
156
|
-
sortKey: bulkUpload.sortKey,
|
|
157
|
-
sortOrder: bulkUpload.sortOrder,
|
|
158
|
-
batchList,
|
|
159
|
-
batchListFetchState,
|
|
160
|
-
pastBatches,
|
|
161
|
-
pastUnmatchedFiles,
|
|
162
|
-
confirmMatchStatus: bulkUpload.confirmMatchStatus,
|
|
163
|
-
manualSearch: bulkUpload.manualSearch,
|
|
164
|
-
uploadProgress: bulkUpload.uploadProgress,
|
|
165
|
-
},
|
|
166
|
-
};
|
|
167
|
-
}
|
|
168
|
-
function resolveBatchFile(file, transactionState) {
|
|
169
|
-
const matchedTransaction = file.matchedTransactionId != null
|
|
170
|
-
? (0, transactionSelector_1.getSupportedTransactionById)(transactionState, file.matchedTransactionId)
|
|
171
|
-
: undefined;
|
|
172
|
-
const candidates = file.candidates
|
|
173
|
-
?.map((ref) => {
|
|
174
|
-
const transaction = (0, transactionSelector_1.getSupportedTransactionById)(transactionState, ref.transactionId);
|
|
175
|
-
return transaction != null
|
|
176
|
-
? { transaction, matchScore: ref.matchScore }
|
|
177
|
-
: undefined;
|
|
178
|
-
})
|
|
179
|
-
.filter((c) => c != null);
|
|
180
|
-
return {
|
|
181
|
-
attachmentId: file.attachmentId,
|
|
182
|
-
fileId: file.fileId,
|
|
183
|
-
filename: file.filename,
|
|
184
|
-
filePreviewUrl: file.filePreviewUrl,
|
|
185
|
-
status: file.status,
|
|
186
|
-
matchedTransaction,
|
|
187
|
-
candidates: candidates != null && candidates.length > 0
|
|
188
|
-
? candidates
|
|
189
|
-
: undefined,
|
|
190
|
-
matchSource: file.matchSource,
|
|
191
64
|
};
|
|
192
65
|
}
|
|
@@ -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;
|
|
@@ -13,110 +12,7 @@ export interface MissingReceiptsViewUIState {
|
|
|
13
12
|
sortKey: MissingReceiptsSortKey;
|
|
14
13
|
sortOrder: SortOrder;
|
|
15
14
|
}
|
|
16
|
-
export type BatchStatusValue = 'pending' | 'processing' | 'completed';
|
|
17
|
-
export type BatchFileStatus = 'matched' | 'un_matched' | 'no_match' | 'failed';
|
|
18
|
-
export type BulkUploadPhase = 'idle' | 'uploading' | 'matching' | 'completed';
|
|
19
|
-
export type BulkUploadResultsTab = 'completed' | 'unmatched';
|
|
20
|
-
export type MissingReceiptsTab = 'missing' | BulkUploadResultsTab;
|
|
21
|
-
export type CompletedSubTab = 'all' | 'ai_accountant' | 'manual';
|
|
22
|
-
export type MatchSource = 'ai' | 'manual';
|
|
23
|
-
export interface CandidateRef {
|
|
24
|
-
matchScore: number;
|
|
25
|
-
transactionId: ID;
|
|
26
|
-
}
|
|
27
|
-
export interface MatchCandidate {
|
|
28
|
-
amount: number;
|
|
29
|
-
currencyCode: string;
|
|
30
|
-
matchScore: number;
|
|
31
|
-
transactionDate: string;
|
|
32
|
-
transactionId: ID;
|
|
33
|
-
transactionType: string;
|
|
34
|
-
vendorName: string;
|
|
35
|
-
vendorLogo?: string;
|
|
36
|
-
}
|
|
37
|
-
export interface BatchFile {
|
|
38
|
-
attachmentId: ID;
|
|
39
|
-
fileId: ID;
|
|
40
|
-
filename: string;
|
|
41
|
-
filePreviewUrl: string | null;
|
|
42
|
-
status: BatchFileStatus;
|
|
43
|
-
candidates?: CandidateRef[];
|
|
44
|
-
matchedTransactionId?: ID;
|
|
45
|
-
matchSource?: MatchSource;
|
|
46
|
-
}
|
|
47
|
-
export interface BatchSummary {
|
|
48
|
-
failed: number;
|
|
49
|
-
matched: number;
|
|
50
|
-
noMatch: number;
|
|
51
|
-
possibleMatches: number;
|
|
52
|
-
total: number;
|
|
53
|
-
}
|
|
54
|
-
export interface BatchStatus {
|
|
55
|
-
batchId: ID;
|
|
56
|
-
progress: {
|
|
57
|
-
processed: number;
|
|
58
|
-
total: number;
|
|
59
|
-
};
|
|
60
|
-
status: BatchStatusValue;
|
|
61
|
-
}
|
|
62
|
-
export interface BatchDetails {
|
|
63
|
-
batchId: ID;
|
|
64
|
-
createdAt: string;
|
|
65
|
-
files: BatchFile[];
|
|
66
|
-
status: BatchStatusValue;
|
|
67
|
-
summary: BatchSummary;
|
|
68
|
-
}
|
|
69
|
-
export interface BatchListItem {
|
|
70
|
-
batchId: ID;
|
|
71
|
-
createdAt: string;
|
|
72
|
-
failedCount: number;
|
|
73
|
-
matchedCount: number;
|
|
74
|
-
noMatchCount: number;
|
|
75
|
-
possibleMatchesCount: number;
|
|
76
|
-
status: string;
|
|
77
|
-
totalFiles: number;
|
|
78
|
-
}
|
|
79
|
-
export interface ManualSearchResult {
|
|
80
|
-
amount: number;
|
|
81
|
-
currencyCode: string;
|
|
82
|
-
entityId: string;
|
|
83
|
-
memo: string;
|
|
84
|
-
transactionDate: string;
|
|
85
|
-
transactionId: ID;
|
|
86
|
-
transactionType: string;
|
|
87
|
-
vendorName: string;
|
|
88
|
-
}
|
|
89
|
-
export interface ManualSearchState {
|
|
90
|
-
fetchState: FetchStateAndError;
|
|
91
|
-
results: ManualSearchResult[];
|
|
92
|
-
searchQuery: string;
|
|
93
|
-
}
|
|
94
|
-
export type CompletedTransactionsMatchType = 'all' | 'ai_accountant' | 'manual';
|
|
95
|
-
export interface CompletedTransactionsState {
|
|
96
|
-
fetchState: FetchStateAndError;
|
|
97
|
-
nextPageToken: string | null;
|
|
98
|
-
totalCount: number;
|
|
99
|
-
transactionIds: ID[];
|
|
100
|
-
}
|
|
101
|
-
export interface BulkUploadState {
|
|
102
|
-
batchDetailsById: Record<ID, BatchDetails>;
|
|
103
|
-
batchListByPeriod: Record<MonthYearPeriodId, BatchListItem[]>;
|
|
104
|
-
batchListFetchState: FetchStateAndError;
|
|
105
|
-
batchStatusById: Record<ID, BatchStatus>;
|
|
106
|
-
completedSubTab: CompletedSubTab;
|
|
107
|
-
completedTransactionsByPeriod: Record<MonthYearPeriodId, CompletedTransactionsState>;
|
|
108
|
-
confirmMatchStatus: FetchStateAndError;
|
|
109
|
-
currentResultsTab: BulkUploadResultsTab;
|
|
110
|
-
manualSearch: ManualSearchState;
|
|
111
|
-
phase: BulkUploadPhase;
|
|
112
|
-
sortKey: BulkUploadSortKey;
|
|
113
|
-
sortOrder: SortOrder;
|
|
114
|
-
uploadProgress: number;
|
|
115
|
-
uploadStatus: FetchStateAndError;
|
|
116
|
-
currentBatchId?: ID;
|
|
117
|
-
}
|
|
118
15
|
export interface MissingReceiptsViewState extends FetchedState {
|
|
119
|
-
bulkUpload: BulkUploadState;
|
|
120
16
|
refreshStatus: FetchStateAndError;
|
|
121
17
|
transactionIdsBySelectedPeriod: Record<MonthYearPeriodId, ID[]>;
|
|
122
18
|
uiState: MissingReceiptsViewUIState;
|
package/lib/zeniAPI.d.ts
CHANGED
|
@@ -1,12 +1,5 @@
|
|
|
1
1
|
import { fetch } from 'cross-fetch';
|
|
2
2
|
import { Observable } from 'rxjs';
|
|
3
|
-
export type FormDataUploadEvent<T> = {
|
|
4
|
-
percentage: number;
|
|
5
|
-
type: 'progress';
|
|
6
|
-
} | {
|
|
7
|
-
data: T;
|
|
8
|
-
type: 'response';
|
|
9
|
-
};
|
|
10
3
|
type ThenArgRecursive<T> = T extends PromiseLike<infer U> ? ThenArgRecursive<U> : T;
|
|
11
4
|
export type FetchResponse = ThenArgRecursive<ReturnType<typeof fetch>>;
|
|
12
5
|
export interface RESTAPIEndpoints {
|
|
@@ -41,7 +34,6 @@ export interface ZeniAPI<ResponseType = FetchResponse> {
|
|
|
41
34
|
patchAndGetJSON<T>(restEndPoint: string, body?: Record<string, unknown>, headers?: Record<string, unknown>, signal?: AbortSignal): Observable<T>;
|
|
42
35
|
postAndGetJSON<T>(restEndPoint: string, body?: Record<string, unknown>, headers?: Record<string, unknown>, signal?: AbortSignal): Observable<T>;
|
|
43
36
|
postFormData<T>(restEndPoint: string, formData: FormData, signal?: AbortSignal): Observable<T>;
|
|
44
|
-
postFormDataWithProgress<T>(restEndPoint: string, formData: FormData, signal?: AbortSignal): Observable<FormDataUploadEvent<T>>;
|
|
45
37
|
postJSON(restEndPoint: string, body?: Record<string, unknown>, headers?: Record<string, unknown>, signal?: AbortSignal): Observable<ResponseType>;
|
|
46
38
|
putAndGetJSON<T>(restEndPoint: string, body?: Record<string, unknown>, headers?: Record<string, unknown>, signal?: AbortSignal): Observable<T>;
|
|
47
39
|
update(userId?: string, sessionId?: string, tenantId?: string): void;
|
|
@@ -69,7 +61,6 @@ export declare class ZeniAPIClient implements ZeniAPI {
|
|
|
69
61
|
postJSON(restEndPoint: string, body?: Record<string, unknown>, headers?: Record<string, unknown>, signal?: AbortSignal): Observable<FetchResponse>;
|
|
70
62
|
postAndGetJSON<T>(restEndPoint: string, body?: Record<string, unknown>, headers?: Record<string, unknown>, signal?: AbortSignal): Observable<T>;
|
|
71
63
|
postFormData<T>(restEndPoint: string, formData: FormData, signal?: AbortSignal): Observable<T>;
|
|
72
|
-
postFormDataWithProgress<T>(restEndPoint: string, formData: FormData, signal?: AbortSignal): Observable<FormDataUploadEvent<T>>;
|
|
73
64
|
deleteAndGetJSON<T>(restEndPoint: string, body?: Record<string, unknown>, headers?: Record<string, unknown>, signal?: AbortSignal): Observable<T>;
|
|
74
65
|
putAndGetJSON<T>(restEndPoint: string, body?: Record<string, unknown>, headers?: Record<string, unknown>, signal?: AbortSignal): Observable<T>;
|
|
75
66
|
patchAndGetJSON<T>(restEndPoint: string, body?: Record<string, unknown>, headers?: Record<string, unknown>, signal?: AbortSignal): Observable<T>;
|
package/lib/zeniAPI.js
CHANGED
|
@@ -82,6 +82,8 @@ class ZeniAPIClient {
|
|
|
82
82
|
return (0, rxjs_1.from)(promise);
|
|
83
83
|
}
|
|
84
84
|
postFormData(restEndPoint, formData, signal) {
|
|
85
|
+
// Use apiHeaders for auth headers, then remove Content-Type
|
|
86
|
+
// so the browser sets multipart/form-data with the correct boundary
|
|
85
87
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
86
88
|
const { 'Content-Type': _contentType, ...headers } = this.apiHeaders();
|
|
87
89
|
const promise = (0, cross_fetch_1.fetch)(restEndPoint, {
|
|
@@ -92,46 +94,6 @@ class ZeniAPIClient {
|
|
|
92
94
|
}).then((response) => this.processJsonResponse(response));
|
|
93
95
|
return (0, rxjs_1.from)(promise);
|
|
94
96
|
}
|
|
95
|
-
postFormDataWithProgress(restEndPoint, formData, signal) {
|
|
96
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
97
|
-
const { 'Content-Type': _ct, ...headers } = this.apiHeaders();
|
|
98
|
-
return new rxjs_1.Observable((subscriber) => {
|
|
99
|
-
const xhr = new XMLHttpRequest();
|
|
100
|
-
xhr.upload.onprogress = (event) => {
|
|
101
|
-
if (event.lengthComputable) {
|
|
102
|
-
const percentage = Math.round((event.loaded / event.total) * 100);
|
|
103
|
-
subscriber.next({ type: 'progress', percentage });
|
|
104
|
-
}
|
|
105
|
-
};
|
|
106
|
-
xhr.onload = () => {
|
|
107
|
-
try {
|
|
108
|
-
const json = JSON.parse(xhr.responseText);
|
|
109
|
-
this.checkSessionValidity(json);
|
|
110
|
-
subscriber.next({ type: 'response', data: json });
|
|
111
|
-
subscriber.complete();
|
|
112
|
-
}
|
|
113
|
-
catch (e) {
|
|
114
|
-
subscriber.error(e);
|
|
115
|
-
}
|
|
116
|
-
};
|
|
117
|
-
xhr.onerror = () => {
|
|
118
|
-
subscriber.error(new Error('Upload failed'));
|
|
119
|
-
};
|
|
120
|
-
xhr.open('POST', restEndPoint);
|
|
121
|
-
Object.entries(headers).forEach(([key, value]) => {
|
|
122
|
-
xhr.setRequestHeader(key, String(value));
|
|
123
|
-
});
|
|
124
|
-
xhr.send(formData);
|
|
125
|
-
if (signal != null) {
|
|
126
|
-
signal.addEventListener('abort', () => xhr.abort());
|
|
127
|
-
}
|
|
128
|
-
return () => {
|
|
129
|
-
if (xhr.readyState !== XMLHttpRequest.DONE) {
|
|
130
|
-
xhr.abort();
|
|
131
|
-
}
|
|
132
|
-
};
|
|
133
|
-
});
|
|
134
|
-
}
|
|
135
97
|
deleteAndGetJSON(restEndPoint, body, headers, signal) {
|
|
136
98
|
let apiHeaders = this.apiHeaders(headers);
|
|
137
99
|
if (body != null) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zeniai/client-epic-state",
|
|
3
|
-
"version": "4.19.37
|
|
3
|
+
"version": "4.19.37",
|
|
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",
|
|
@@ -111,7 +111,7 @@
|
|
|
111
111
|
"find-dead-code": "ts-prune | grep -v '(used in module)'",
|
|
112
112
|
"find-unused-exports": "ts-unused-exports ./tsconfig.json",
|
|
113
113
|
"circular-dependency": "npx madge --circular --extensions ts ./src",
|
|
114
|
-
"build": "concurrently --kill-others-on-fail --handle-input \"echo 'Running ESLint...' && eslint . --ext .js,.jsx,.ts,.tsx\" \"echo 'TypeScript build in progress...' && time tsc && echo 'ESM build...' && tsc -p tsconfig.esm.json\"",
|
|
114
|
+
"build": "concurrently --kill-others-on-fail --handle-input \"echo 'Running ESLint...' && eslint . --ext .js,.jsx,.ts,.tsx\" \"echo 'TypeScript build in progress...' && time tsc && echo 'ESM build...' && tsc -p tsconfig.esm.json\" \"echo 'Running tests and typecheck...' && pnpm test\" && rimraf \"lib/**/__mocks__\" \"lib/**/__testHelpers__\"",
|
|
115
115
|
"only-build": "eslint . --ext .js,.jsx,.ts,.tsx && time tsc && tsc -p tsconfig.esm.json && rimraf \"lib/**/__mocks__\" \"lib/**/__testHelpers__\"",
|
|
116
116
|
"format": "prettier --write --ignore-unknown \"src/**/*\" && pnpm lint",
|
|
117
117
|
"format-watch": "(git diff --name-only --diff-filter=ACM && git ls-files --others --exclude-standard) | grep -E '\\.(ts|tsx)$' | xargs prettier --write",
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { of } from 'rxjs';
|
|
2
|
-
import { catchError, filter, mergeMap } from 'rxjs/operators';
|
|
3
|
-
import { createZeniAPIStatus, isSuccessResponse, } from '../../../../responsePayload';
|
|
4
|
-
import { bulkUploadReceipts, bulkUploadReceiptsFailure, bulkUploadReceiptsSuccess, } from '../../reducers/missingReceiptsViewReducer';
|
|
5
|
-
export const bulkUploadReceiptsEpic = (actions$, _state$, zeniAPI) => actions$.pipe(filter(bulkUploadReceipts.match), mergeMap((action) => {
|
|
6
|
-
const { files } = action.payload;
|
|
7
|
-
const formData = new FormData();
|
|
8
|
-
for (const file of files) {
|
|
9
|
-
formData.append('files', file, file.name);
|
|
10
|
-
}
|
|
11
|
-
return zeniAPI
|
|
12
|
-
.postFormData(`${zeniAPI.apiEndPoints.communicationAgentMicroServiceBaseUrl}/1.0/receipts/bulk-upload`, formData)
|
|
13
|
-
.pipe(mergeMap((response) => {
|
|
14
|
-
if (isSuccessResponse(response) && response.data != null) {
|
|
15
|
-
return of(bulkUploadReceiptsSuccess({
|
|
16
|
-
batchId: response.data.batch_id,
|
|
17
|
-
}));
|
|
18
|
-
}
|
|
19
|
-
return of(bulkUploadReceiptsFailure({ error: response.status }));
|
|
20
|
-
}), catchError((error) => of(bulkUploadReceiptsFailure({
|
|
21
|
-
error: createZeniAPIStatus('Unexpected Error', 'Bulk upload receipts API call errored out: ' +
|
|
22
|
-
JSON.stringify(error)),
|
|
23
|
-
}))));
|
|
24
|
-
}));
|
package/lib/esm/view/expenseAutomationView/epics/missingReceipts/confirmBulkUploadMatchEpic.js
DELETED
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import { from } from 'rxjs';
|
|
2
|
-
import { catchError, filter, mergeMap } from 'rxjs/operators';
|
|
3
|
-
import { openSnackbar } from '../../../../entity/snackbar/snackbarReducer';
|
|
4
|
-
import { createZeniAPIStatus, isSuccessResponse, } from '../../../../responsePayload';
|
|
5
|
-
import { confirmBulkUploadMatch, confirmBulkUploadMatchFailure, confirmBulkUploadMatchSuccess, } from '../../reducers/missingReceiptsViewReducer';
|
|
6
|
-
export const confirmBulkUploadMatchEpic = (actions$, _state$, zeniAPI) => actions$.pipe(filter(confirmBulkUploadMatch.match), mergeMap((action) => {
|
|
7
|
-
const { batchId, attachmentId, transactionId, transactionType, fileName } = action.payload;
|
|
8
|
-
return zeniAPI
|
|
9
|
-
.postAndGetJSON(`${zeniAPI.apiEndPoints.communicationAgentMicroServiceBaseUrl}/1.0/receipts/manual-match`, {
|
|
10
|
-
attachment_id: attachmentId,
|
|
11
|
-
transaction_id: transactionId,
|
|
12
|
-
transaction_type: transactionType,
|
|
13
|
-
file_name: fileName,
|
|
14
|
-
})
|
|
15
|
-
.pipe(mergeMap((response) => {
|
|
16
|
-
if (isSuccessResponse(response)) {
|
|
17
|
-
return from([
|
|
18
|
-
confirmBulkUploadMatchSuccess({
|
|
19
|
-
batchId,
|
|
20
|
-
attachmentId,
|
|
21
|
-
transactionId,
|
|
22
|
-
}),
|
|
23
|
-
openSnackbar({
|
|
24
|
-
messageSection: 'receipt_match',
|
|
25
|
-
messageText: 'success',
|
|
26
|
-
type: 'success',
|
|
27
|
-
}),
|
|
28
|
-
]);
|
|
29
|
-
}
|
|
30
|
-
return from([
|
|
31
|
-
confirmBulkUploadMatchFailure({ error: response.status }),
|
|
32
|
-
openSnackbar({
|
|
33
|
-
messageSection: 'receipt_match',
|
|
34
|
-
messageText: 'failed',
|
|
35
|
-
type: 'error',
|
|
36
|
-
}),
|
|
37
|
-
]);
|
|
38
|
-
}), catchError((error) => from([
|
|
39
|
-
confirmBulkUploadMatchFailure({
|
|
40
|
-
error: createZeniAPIStatus('Unexpected Error', 'Confirm bulk upload match errored out: ' +
|
|
41
|
-
JSON.stringify(error)),
|
|
42
|
-
}),
|
|
43
|
-
openSnackbar({
|
|
44
|
-
messageSection: 'receipt_match',
|
|
45
|
-
messageText: 'failed',
|
|
46
|
-
type: 'error',
|
|
47
|
-
}),
|
|
48
|
-
])));
|
|
49
|
-
}));
|
package/lib/esm/view/expenseAutomationView/epics/missingReceipts/fetchBulkUploadBatchDetailsEpic.js
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { from, of } from 'rxjs';
|
|
2
|
-
import { catchError, filter, mergeMap } from 'rxjs/operators';
|
|
3
|
-
import { updateTransactions } from '../../../../entity/transaction/transactionReducer';
|
|
4
|
-
import { createZeniAPIStatus, isSuccessResponse, } from '../../../../responsePayload';
|
|
5
|
-
import { extractTransactionPayloadsFromBatchFiles, toBatchDetails, } from '../../payload/missingReceiptsPayload';
|
|
6
|
-
import { fetchBulkUploadBatchDetails, fetchBulkUploadBatchDetailsFailure, fetchBulkUploadBatchDetailsSuccess, fetchBulkUploadBatches, } from '../../reducers/missingReceiptsViewReducer';
|
|
7
|
-
export const fetchBulkUploadBatchDetailsEpic = (actions$, state$, zeniAPI) => actions$.pipe(filter(fetchBulkUploadBatchDetails.match), mergeMap(() => {
|
|
8
|
-
const { currentBatchId } = state$.value.expenseAutomationMissingReceiptsViewState.bulkUpload;
|
|
9
|
-
if (currentBatchId == null) {
|
|
10
|
-
return of(fetchBulkUploadBatchDetailsFailure({
|
|
11
|
-
error: createZeniAPIStatus('Unexpected Error', 'No current batch ID available'),
|
|
12
|
-
}));
|
|
13
|
-
}
|
|
14
|
-
return zeniAPI
|
|
15
|
-
.getJSON(`${zeniAPI.apiEndPoints.accountMicroServiceBaseUrl}/1.0/receipts/batches/${currentBatchId}`)
|
|
16
|
-
.pipe(mergeMap((response) => {
|
|
17
|
-
if (isSuccessResponse(response) && response.data != null) {
|
|
18
|
-
const actions = [];
|
|
19
|
-
const transactionPayloads = extractTransactionPayloadsFromBatchFiles(response.data.files);
|
|
20
|
-
if (transactionPayloads.length > 0) {
|
|
21
|
-
actions.push(updateTransactions(transactionPayloads, (value) => value.transaction_id));
|
|
22
|
-
}
|
|
23
|
-
actions.push(fetchBulkUploadBatchDetailsSuccess(toBatchDetails(response.data)));
|
|
24
|
-
actions.push(fetchBulkUploadBatches(true));
|
|
25
|
-
return from(actions);
|
|
26
|
-
}
|
|
27
|
-
return of(fetchBulkUploadBatchDetailsFailure({ error: response.status }));
|
|
28
|
-
}), catchError((error) => of(fetchBulkUploadBatchDetailsFailure({
|
|
29
|
-
error: createZeniAPIStatus('Unexpected Error', 'Fetch batch details errored out: ' + JSON.stringify(error)),
|
|
30
|
-
}))));
|
|
31
|
-
}));
|
package/lib/esm/view/expenseAutomationView/epics/missingReceipts/fetchBulkUploadBatchesEpic.js
DELETED
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import { of } from 'rxjs';
|
|
2
|
-
import { catchError, filter, mergeMap, switchMap } from 'rxjs/operators';
|
|
3
|
-
import { convertToPeriod, toMonthYearPeriodId, } from '../../../../commonStateTypes/timePeriod';
|
|
4
|
-
import { getCurrentTenant } from '../../../../entity/tenant/tenantSelector';
|
|
5
|
-
import { createZeniAPIStatus, isSuccessResponse, } from '../../../../responsePayload';
|
|
6
|
-
import { toBatchListItem, } from '../../payload/missingReceiptsPayload';
|
|
7
|
-
import { fetchBulkUploadBatches, fetchBulkUploadBatchesFailure, fetchBulkUploadBatchesSuccess, } from '../../reducers/missingReceiptsViewReducer';
|
|
8
|
-
export const fetchBulkUploadBatchesEpic = (actions$, state$, zeniAPI) => actions$.pipe(filter(fetchBulkUploadBatches.match), switchMap((action) => {
|
|
9
|
-
const { cacheOverride } = action.payload;
|
|
10
|
-
const state = state$.value;
|
|
11
|
-
const { expenseAutomationViewState: { selectedPeriodByTenantId }, expenseAutomationMissingReceiptsViewState: { bulkUpload }, } = state;
|
|
12
|
-
const currentTenant = getCurrentTenant(state);
|
|
13
|
-
const selectedPeriod = selectedPeriodByTenantId[currentTenant.tenantId];
|
|
14
|
-
const periodId = toMonthYearPeriodId(selectedPeriod);
|
|
15
|
-
const existingBatches = bulkUpload.batchListByPeriod[periodId] ?? [];
|
|
16
|
-
if (cacheOverride !== true && existingBatches.length > 0) {
|
|
17
|
-
return of(fetchBulkUploadBatchesSuccess({
|
|
18
|
-
batchList: existingBatches,
|
|
19
|
-
selectedPeriod,
|
|
20
|
-
}));
|
|
21
|
-
}
|
|
22
|
-
const period = convertToPeriod(selectedPeriod);
|
|
23
|
-
return zeniAPI
|
|
24
|
-
.getJSON(`${zeniAPI.apiEndPoints.accountMicroServiceBaseUrl}/1.0/receipts/batches?start_date=${period.start}&end_date=${period.end}`)
|
|
25
|
-
.pipe(mergeMap((response) => {
|
|
26
|
-
if (isSuccessResponse(response) && response.data != null) {
|
|
27
|
-
return of(fetchBulkUploadBatchesSuccess({
|
|
28
|
-
batchList: response.data.batches.map(toBatchListItem),
|
|
29
|
-
selectedPeriod,
|
|
30
|
-
}));
|
|
31
|
-
}
|
|
32
|
-
return of(fetchBulkUploadBatchesFailure({
|
|
33
|
-
error: response.status,
|
|
34
|
-
selectedPeriod,
|
|
35
|
-
}));
|
|
36
|
-
}), catchError((error) => of(fetchBulkUploadBatchesFailure({
|
|
37
|
-
error: createZeniAPIStatus('Unexpected Error', 'Fetch bulk upload batches errored out: ' +
|
|
38
|
-
JSON.stringify(error)),
|
|
39
|
-
selectedPeriod,
|
|
40
|
-
}))));
|
|
41
|
-
}));
|
package/lib/esm/view/expenseAutomationView/epics/missingReceipts/fetchCompletedTransactionsEpic.js
DELETED
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import { from, of } from 'rxjs';
|
|
2
|
-
import { catchError, filter, mergeMap, switchMap } from 'rxjs/operators';
|
|
3
|
-
import { convertToPeriod, toMonthYearPeriodId, } from '../../../../commonStateTypes/timePeriod';
|
|
4
|
-
import { getCurrentTenant } from '../../../../entity/tenant/tenantSelector';
|
|
5
|
-
import { updateTransactions } from '../../../../entity/transaction/transactionReducer';
|
|
6
|
-
import { createZeniAPIStatus, isSuccessResponse, } from '../../../../responsePayload';
|
|
7
|
-
import { fetchCompletedTransactions, fetchCompletedTransactionsFailure, fetchCompletedTransactionsSuccess, } from '../../reducers/missingReceiptsViewReducer';
|
|
8
|
-
export const fetchCompletedTransactionsEpic = (actions$, state$, zeniAPI) => actions$.pipe(filter(fetchCompletedTransactions.match), switchMap((action) => {
|
|
9
|
-
const state = state$.value;
|
|
10
|
-
const { expenseAutomationViewState: { selectedPeriodByTenantId }, expenseAutomationMissingReceiptsViewState: { bulkUpload }, } = state;
|
|
11
|
-
const currentTenant = getCurrentTenant(state);
|
|
12
|
-
const selectedPeriod = selectedPeriodByTenantId[currentTenant.tenantId];
|
|
13
|
-
const periodId = toMonthYearPeriodId(selectedPeriod);
|
|
14
|
-
const isInitialLoad = action.payload.pageToken == null;
|
|
15
|
-
const existingData = bulkUpload.completedTransactionsByPeriod[periodId];
|
|
16
|
-
if (isInitialLoad && existingData != null && existingData.transactionIds.length > 0) {
|
|
17
|
-
return from([]);
|
|
18
|
-
}
|
|
19
|
-
const period = convertToPeriod(selectedPeriod);
|
|
20
|
-
const queryPayload = {
|
|
21
|
-
start_date: period.start,
|
|
22
|
-
end_date: period.end,
|
|
23
|
-
sort_by: bulkUpload.sortKey,
|
|
24
|
-
sort_order: bulkUpload.sortOrder === 'ascending' ? 'asc' : 'desc',
|
|
25
|
-
page_token: action.payload.pageToken ?? null,
|
|
26
|
-
page_size: 25,
|
|
27
|
-
};
|
|
28
|
-
if (bulkUpload.completedSubTab !== 'all') {
|
|
29
|
-
queryPayload.match_type = bulkUpload.completedSubTab;
|
|
30
|
-
}
|
|
31
|
-
const encodedQuery = encodeURIComponent(JSON.stringify(queryPayload));
|
|
32
|
-
return zeniAPI
|
|
33
|
-
.getJSON(`${zeniAPI.apiEndPoints.communicationAgentMicroServiceBaseUrl}/1.0/receipt-agent/transactions/completed?query=${encodedQuery}`)
|
|
34
|
-
.pipe(mergeMap((response) => {
|
|
35
|
-
if (isSuccessResponse(response) && response.data != null) {
|
|
36
|
-
const transactionIds = response.data.transactions.map((t) => t.transaction_id);
|
|
37
|
-
const updateActions = [];
|
|
38
|
-
updateActions.push(updateTransactions(response.data.transactions, (value) => value.transaction_id));
|
|
39
|
-
updateActions.push(fetchCompletedTransactionsSuccess({
|
|
40
|
-
isInitialLoad,
|
|
41
|
-
transactionIds,
|
|
42
|
-
nextPageToken: response.data.next_page_token,
|
|
43
|
-
totalCount: response.data.total_count,
|
|
44
|
-
selectedPeriod,
|
|
45
|
-
}));
|
|
46
|
-
return from(updateActions);
|
|
47
|
-
}
|
|
48
|
-
return of(fetchCompletedTransactionsFailure({
|
|
49
|
-
error: response.status,
|
|
50
|
-
selectedPeriod,
|
|
51
|
-
}));
|
|
52
|
-
}), catchError((error) => of(fetchCompletedTransactionsFailure({
|
|
53
|
-
error: createZeniAPIStatus('Unexpected Error', 'Fetch completed transactions errored: ' +
|
|
54
|
-
JSON.stringify(error)),
|
|
55
|
-
selectedPeriod,
|
|
56
|
-
}))));
|
|
57
|
-
}));
|