Skip to content

Commit 76e46b9

Browse files
authored
Merge pull request Expensify#90706 from truph01/feat/90295
[NO QA] feat: Add ExportDownload Onyx foundation and shared export action functions
2 parents c33afdd + cb69351 commit 76e46b9

11 files changed

Lines changed: 232 additions & 0 deletions

File tree

src/CONST/index.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,14 @@ const CONST = {
455455
MAX_LENGTH: 83,
456456
},
457457

458+
EXPORT_DOWNLOAD: {
459+
STATE: {
460+
PREPARING: 'preparing',
461+
READY: 'ready',
462+
FAILED: 'failed',
463+
},
464+
},
465+
458466
EXPORT_LABELS: {
459467
NETSUITE: 'NetSuite',
460468
QBO: 'QuickBooks Online',

src/ONYXKEYS.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -729,6 +729,7 @@ const ONYXKEYS = {
729729
ATTACHMENT: 'attachment_',
730730
DOMAIN: 'domain_',
731731
DOWNLOAD: 'download_',
732+
EXPORT_DOWNLOAD: 'nvp_exportDownload_',
732733
POLICY: 'policy_',
733734
POLICY_DRAFTS: 'policyDrafts_',
734735
POLICY_JOIN_MEMBER: 'policyJoinMember_',
@@ -1301,6 +1302,7 @@ type OnyxCollectionValuesMapping = {
13011302
[ONYXKEYS.COLLECTION.ATTACHMENT]: OnyxTypes.Attachment;
13021303
[ONYXKEYS.COLLECTION.DOMAIN]: OnyxTypes.Domain;
13031304
[ONYXKEYS.COLLECTION.DOWNLOAD]: OnyxTypes.Download;
1305+
[ONYXKEYS.COLLECTION.EXPORT_DOWNLOAD]: OnyxTypes.ExportDownload;
13041306
[ONYXKEYS.COLLECTION.POLICY]: OnyxTypes.Policy;
13051307
[ONYXKEYS.COLLECTION.POLICY_DRAFTS]: OnyxTypes.Policy;
13061308
[ONYXKEYS.COLLECTION.POLICY_CATEGORIES]: OnyxTypes.PolicyCategories;
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
type ClearExportDownloadParams = {
2+
exportID: string;
3+
};
4+
5+
export default ClearExportDownloadParams;
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
type SendExportFileFromConciergeParams = {
2+
exportID: string;
3+
};
4+
5+
export default SendExportFileFromConciergeParams;

src/libs/API/parameters/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -545,3 +545,5 @@ export type {default as UpdateAgentNameParams} from './UpdateAgentNameParams';
545545
export type {default as UpdateAgentPromptParams} from './UpdateAgentPromptParams';
546546
export type {default as UpdateAgentAvatarParams} from './UpdateAgentAvatarParams';
547547
export type {default as DeleteAgentParams} from './DeleteAgentParams';
548+
export type {default as SendExportFileFromConciergeParams} from './SendExportFileFromConciergeParams';
549+
export type {default as ClearExportDownloadParams} from './ClearExportDownloadParams';

src/libs/API/types.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -619,6 +619,8 @@ const WRITE_COMMANDS = {
619619
UPDATE_AGENT_PROMPT: 'UpdateAgentPrompt',
620620
UPDATE_AGENT_AVATAR: 'UpdateAgentAvatar',
621621
DELETE_AGENT: 'DeleteAgent',
622+
SEND_EXPORT_FILE_FROM_CONCIERGE: 'SendExportFileFromConcierge',
623+
CLEAR_EXPORT_DOWNLOAD: 'ClearExportDownload',
622624
} as const;
623625

624626
type WriteCommand = ValueOf<typeof WRITE_COMMANDS>;
@@ -1260,6 +1262,8 @@ type WriteCommandParameters = {
12601262
[WRITE_COMMANDS.UPDATE_AGENT_PROMPT]: Parameters.UpdateAgentPromptParams;
12611263
[WRITE_COMMANDS.UPDATE_AGENT_AVATAR]: Parameters.UpdateAgentAvatarParams;
12621264
[WRITE_COMMANDS.DELETE_AGENT]: Parameters.DeleteAgentParams;
1265+
[WRITE_COMMANDS.SEND_EXPORT_FILE_FROM_CONCIERGE]: Parameters.SendExportFileFromConciergeParams;
1266+
[WRITE_COMMANDS.CLEAR_EXPORT_DOWNLOAD]: Parameters.ClearExportDownloadParams;
12631267
};
12641268

12651269
const READ_COMMANDS = {

src/libs/Navigation/AppNavigator/AuthScreensInitHandler.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import {endSpan, getSpan, startSpan} from '@libs/telemetry/activeSpans';
2020
import {getSearchParamFromUrl} from '@libs/Url';
2121
import * as App from '@userActions/App';
2222
import * as Download from '@userActions/Download';
23+
import {clearStaleExportDownloads} from '@userActions/Export';
2324
import * as Report from '@userActions/Report';
2425
import * as Session from '@userActions/Session';
2526
import * as User from '@userActions/User';
@@ -140,6 +141,7 @@ function AuthScreensInitHandler() {
140141
);
141142

142143
Download.clearDownloads();
144+
clearStaleExportDownloads();
143145

144146
return () => {
145147
Session.cleanupSession();

src/libs/actions/Export.ts

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import type {OnyxEntry} from 'react-native-onyx';
2+
import Onyx from 'react-native-onyx';
3+
import {write} from '@libs/API';
4+
import {WRITE_COMMANDS} from '@libs/API/types';
5+
import CONST from '@src/CONST';
6+
import ONYXKEYS from '@src/ONYXKEYS';
7+
import type ExportDownload from '@src/types/onyx/ExportDownload';
8+
import type {AnyOnyxUpdate} from '@src/types/onyx/Request';
9+
10+
function sendExportFileFromConcierge(exportID: string, exportDownload: OnyxEntry<ExportDownload>) {
11+
const onyxKey = `${ONYXKEYS.COLLECTION.EXPORT_DOWNLOAD}${exportID}` as const;
12+
13+
const optimisticData: AnyOnyxUpdate[] = [
14+
{
15+
onyxMethod: Onyx.METHOD.MERGE,
16+
key: onyxKey,
17+
value: {shouldSendFromConcierge: true},
18+
},
19+
];
20+
21+
const failureData: AnyOnyxUpdate[] = [
22+
{
23+
onyxMethod: Onyx.METHOD.MERGE,
24+
key: onyxKey,
25+
value: {shouldSendFromConcierge: exportDownload?.shouldSendFromConcierge ?? null},
26+
},
27+
];
28+
29+
write(WRITE_COMMANDS.SEND_EXPORT_FILE_FROM_CONCIERGE, {exportID}, {optimisticData, failureData});
30+
}
31+
32+
function clearExportDownload(exportID: string, exportDownload: OnyxEntry<ExportDownload>) {
33+
const onyxKey = `${ONYXKEYS.COLLECTION.EXPORT_DOWNLOAD}${exportID}` as const;
34+
35+
const optimisticData: AnyOnyxUpdate[] = [
36+
{
37+
onyxMethod: Onyx.METHOD.SET,
38+
key: onyxKey,
39+
value: null,
40+
},
41+
];
42+
43+
const failureData: AnyOnyxUpdate[] = [
44+
{
45+
onyxMethod: Onyx.METHOD.SET,
46+
key: onyxKey,
47+
value: exportDownload ?? null,
48+
},
49+
];
50+
51+
write(WRITE_COMMANDS.CLEAR_EXPORT_DOWNLOAD, {exportID}, {optimisticData, failureData});
52+
}
53+
54+
function clearStaleExportDownloads() {
55+
// Uses connectWithoutView instead of useOnyx to avoid subscribing the caller component
56+
// to the entire collection, which would cause unnecessary re-renders on every change.
57+
const connectionID = Onyx.connectWithoutView({
58+
key: ONYXKEYS.COLLECTION.EXPORT_DOWNLOAD,
59+
waitForCollectionCallback: true,
60+
callback: (exportDownloads) => {
61+
Onyx.disconnect(connectionID);
62+
if (!exportDownloads) {
63+
return;
64+
}
65+
for (const key of Object.keys(exportDownloads)) {
66+
const exportDownload = exportDownloads[key];
67+
if (!exportDownload || exportDownload.state === CONST.EXPORT_DOWNLOAD.STATE.PREPARING) {
68+
continue;
69+
}
70+
const exportID = key.replace(ONYXKEYS.COLLECTION.EXPORT_DOWNLOAD, '');
71+
clearExportDownload(exportID, exportDownload);
72+
}
73+
},
74+
});
75+
}
76+
77+
export {sendExportFileFromConcierge, clearExportDownload, clearStaleExportDownloads};

src/types/onyx/ExportDownload.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import type {ValueOf} from 'type-fest';
2+
import type CONST from '@src/CONST';
3+
4+
/** Possible states of an export download */
5+
type ExportDownloadState = ValueOf<typeof CONST.EXPORT_DOWNLOAD.STATE>;
6+
7+
/** Model of an export download entry */
8+
type ExportDownload = {
9+
/** Current state of the export download */
10+
state: ExportDownloadState;
11+
12+
/** Number of reports included in the export (PDF exports only) */
13+
reportCount?: number;
14+
15+
/** Number of reports that failed to export (PDF exports only) */
16+
failedReportCount?: number;
17+
18+
/** Whether the export file should be sent from Concierge */
19+
shouldSendFromConcierge?: boolean;
20+
};
21+
22+
export default ExportDownload;

src/types/onyx/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ import type ExpenseRule from './ExpenseRule';
7070
import type ExpensifyCardBankAccountMetadata from './ExpensifyCardBankAccountMetadata';
7171
import type ExpensifyCardSettings from './ExpensifyCardSettings';
7272
import type {ExpensifyCardSettingsBase, NestedExpensifyCardSettings} from './ExpensifyCardSettings';
73+
import type ExportDownload from './ExportDownload';
7374
import type ExportTemplate from './ExportTemplate';
7475
import type FrequentlyUsedEmoji from './FrequentlyUsedEmoji';
7576
import type {FundList} from './Fund';
@@ -221,6 +222,7 @@ export type {
221222
DismissedReferralBanners,
222223
Domain,
223224
Download,
225+
ExportDownload,
224226
DuplicateWorkspace,
225227
CopyPolicySettings,
226228
WorkspaceCardsList,

0 commit comments

Comments
 (0)