Skip to content

Commit 139b2c8

Browse files
authored
Merge pull request #91490 from truph01/feat/90296
[NO QA] feat: introduce ExportDownloadStatusModal
2 parents 377d37b + 297f9da commit 139b2c8

13 files changed

Lines changed: 502 additions & 0 deletions

File tree

Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
import {hasSeenTourSelector} from '@selectors/Onboarding';
2+
import React, {useEffect} from 'react';
3+
import {View} from 'react-native';
4+
import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails';
5+
import useLocalize from '@hooks/useLocalize';
6+
import useOnyx from '@hooks/useOnyx';
7+
import usePreviousDefined from '@hooks/usePreviousDefined';
8+
import useResponsiveLayout from '@hooks/useResponsiveLayout';
9+
import useThemeStyles from '@hooks/useThemeStyles';
10+
import fileDownload from '@libs/fileDownload';
11+
import {clearExportDownload, sendExportFileFromConcierge} from '@userActions/Export';
12+
import {navigateToConciergeChat} from '@userActions/Report';
13+
import CONST from '@src/CONST';
14+
import ONYXKEYS from '@src/ONYXKEYS';
15+
import ActivityIndicator from './ActivityIndicator';
16+
import Button from './Button';
17+
import Modal from './Modal';
18+
import Text from './Text';
19+
20+
type ExportDownloadStatusModalProps = {
21+
/** The export ID to subscribe to */
22+
exportID: string;
23+
24+
/** Whether the modal is visible */
25+
isVisible: boolean;
26+
27+
/** Callback when the modal is closed */
28+
onClose: () => void;
29+
30+
/** Body text for the failed state — PDF and CSV use different copy */
31+
failedBody?: string;
32+
};
33+
34+
function ExportDownloadStatusModal({exportID, isVisible, onClose, failedBody}: ExportDownloadStatusModalProps) {
35+
const styles = useThemeStyles();
36+
const {translate} = useLocalize();
37+
// isSmallScreenWidth is needed here because the modal type depends on actual screen width, not layout mode
38+
// eslint-disable-next-line rulesdir/prefer-shouldUseNarrowLayout-instead-of-isSmallScreenWidth
39+
const {isSmallScreenWidth} = useResponsiveLayout();
40+
const {accountID: currentUserAccountID} = useCurrentUserPersonalDetails();
41+
42+
const [conciergeReportID] = useOnyx(ONYXKEYS.CONCIERGE_REPORT_ID);
43+
const [introSelected] = useOnyx(ONYXKEYS.NVP_INTRO_SELECTED);
44+
const [betas] = useOnyx(ONYXKEYS.BETAS);
45+
const [isSelfTourViewed] = useOnyx(ONYXKEYS.NVP_ONBOARDING, {selector: hasSeenTourSelector});
46+
47+
const [exportDownload] = useOnyx(`${ONYXKEYS.COLLECTION.EXPORT_DOWNLOAD}${exportID}`);
48+
const displayedExport = usePreviousDefined(exportDownload);
49+
50+
const state = displayedExport?.state;
51+
const shouldSendFromConcierge = displayedExport?.shouldSendFromConcierge;
52+
const downloadURL = displayedExport?.downloadURL;
53+
const isPreparing = state === CONST.EXPORT_DOWNLOAD.STATE.PREPARING && !shouldSendFromConcierge;
54+
const isConcierge = !!shouldSendFromConcierge;
55+
const isReady = state === CONST.EXPORT_DOWNLOAD.STATE.READY;
56+
const isFailed = state === CONST.EXPORT_DOWNLOAD.STATE.FAILED;
57+
58+
useEffect(() => {
59+
if (!isReady || !downloadURL || shouldSendFromConcierge) {
60+
return;
61+
}
62+
fileDownload(translate, downloadURL);
63+
}, [isReady, downloadURL, translate, shouldSendFromConcierge]);
64+
65+
const handleSendFromConcierge = () => {
66+
sendExportFileFromConcierge(exportID, displayedExport ?? undefined);
67+
};
68+
69+
const handleGoToConcierge = () => {
70+
onClose();
71+
navigateToConciergeChat(conciergeReportID, introSelected, currentUserAccountID, isSelfTourViewed, betas);
72+
};
73+
74+
const handleDownloadFile = () => {
75+
if (!downloadURL) {
76+
return;
77+
}
78+
fileDownload(translate, downloadURL);
79+
};
80+
81+
const handleClose = () => {
82+
clearExportDownload(exportID, displayedExport ?? undefined);
83+
onClose();
84+
};
85+
86+
const isNonDismissible = isPreparing;
87+
88+
const renderContent = () => {
89+
if (isPreparing) {
90+
return (
91+
<>
92+
<ActivityIndicator
93+
size="large"
94+
style={styles.mb4}
95+
reasonAttributes={{context: 'ExportDownloadStatusModal.preparing'}}
96+
/>
97+
<Text style={[styles.textHeadlineH1, styles.textAlignCenter, styles.mb2]}>{translate('exportDownload.preparingTitle')}</Text>
98+
<Text style={[styles.textAlignCenter, styles.mb5]}>{translate('exportDownload.preparingBody')}</Text>
99+
<Button
100+
success
101+
text={translate('exportDownload.sendFromConcierge')}
102+
onPress={handleSendFromConcierge}
103+
style={styles.w100}
104+
/>
105+
</>
106+
);
107+
}
108+
109+
if (isConcierge) {
110+
return (
111+
<>
112+
<Text style={[styles.textHeadlineH1, styles.textAlignCenter, styles.mb2]}>{translate('exportDownload.conciergeTitle')}</Text>
113+
<Text style={[styles.textAlignCenter, styles.mb5]}>{translate('exportDownload.conciergeBody')}</Text>
114+
<Button
115+
success
116+
text={translate('exportDownload.goToConcierge')}
117+
onPress={handleGoToConcierge}
118+
style={styles.w100}
119+
/>
120+
<Button
121+
text={translate('exportDownload.dismiss')}
122+
onPress={onClose}
123+
style={[styles.w100, styles.mt3]}
124+
/>
125+
</>
126+
);
127+
}
128+
129+
if (isReady) {
130+
return (
131+
<>
132+
<Text style={[styles.textHeadlineH1, styles.textAlignCenter, styles.mb2]}>{translate('exportDownload.readyTitle')}</Text>
133+
<Text style={[styles.textAlignCenter, styles.mb5]}>{translate('exportDownload.readyBody')}</Text>
134+
<Button
135+
success
136+
text={translate('exportDownload.downloadFile')}
137+
onPress={handleDownloadFile}
138+
style={styles.w100}
139+
/>
140+
<Button
141+
text={translate('exportDownload.close')}
142+
onPress={handleClose}
143+
style={[styles.w100, styles.mt3]}
144+
/>
145+
</>
146+
);
147+
}
148+
149+
if (isFailed) {
150+
return (
151+
<>
152+
<Text style={[styles.textHeadlineH1, styles.textAlignCenter, styles.mb2]}>{translate('exportDownload.failedTitle')}</Text>
153+
{!!failedBody && <Text style={[styles.textAlignCenter, styles.mb5]}>{failedBody}</Text>}
154+
<Button
155+
text={translate('exportDownload.close')}
156+
onPress={handleClose}
157+
style={styles.w100}
158+
/>
159+
</>
160+
);
161+
}
162+
163+
return null;
164+
};
165+
166+
return (
167+
<Modal
168+
isVisible={isVisible}
169+
onClose={isNonDismissible ? () => {} : onClose}
170+
onBackdropPress={isNonDismissible ? () => {} : undefined}
171+
type={isSmallScreenWidth ? CONST.MODAL.MODAL_TYPE.BOTTOM_DOCKED : CONST.MODAL.MODAL_TYPE.CONFIRM}
172+
innerContainerStyle={styles.pv0}
173+
>
174+
<View style={[styles.m5, styles.alignItemsCenter]}>{renderContent()}</View>
175+
</Modal>
176+
);
177+
}
178+
179+
ExportDownloadStatusModal.displayName = 'ExportDownloadStatusModal';
180+
181+
export default ExportDownloadStatusModal;

src/languages/de.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9322,6 +9322,20 @@ Hier ist ein *Testbeleg*, um dir zu zeigen, wie es funktioniert:`,
93229322
exportInProgress: 'Export wird ausgeführt',
93239323
conciergeWillSend: 'Concierge wird dir die Datei in Kürze senden.',
93249324
},
9325+
exportDownload: {
9326+
preparingTitle: 'Preparing download...',
9327+
preparingBody: 'You can either wait for the download to finish or Concierge can send it to you via chat.',
9328+
sendFromConcierge: "Send me the file when it's ready",
9329+
conciergeTitle: 'You bet!',
9330+
conciergeBody: 'Concierge will send you a message when the file is ready.',
9331+
goToConcierge: 'Go to Concierge',
9332+
dismiss: 'Dismiss',
9333+
readyTitle: 'Your file is ready!',
9334+
readyBody: "If it didn't automatically download, use the button below.",
9335+
downloadFile: 'Download file',
9336+
failedTitle: 'Export failed',
9337+
close: 'Close',
9338+
},
93259339
domain: {
93269340
notVerified: 'Nicht verifiziert',
93279341
retry: 'Wiederholen',

src/languages/en.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9327,6 +9327,20 @@ const translations = {
93279327
exportInProgress: 'Export in progress',
93289328
conciergeWillSend: 'Concierge will send you the file shortly.',
93299329
},
9330+
exportDownload: {
9331+
preparingTitle: 'Preparing download...',
9332+
preparingBody: 'You can either wait for the download to finish or Concierge can send it to you via chat.',
9333+
sendFromConcierge: "Send me the file when it's ready",
9334+
conciergeTitle: 'You bet!',
9335+
conciergeBody: 'Concierge will send you a message when the file is ready.',
9336+
goToConcierge: 'Go to Concierge',
9337+
dismiss: 'Dismiss',
9338+
readyTitle: 'Your file is ready!',
9339+
readyBody: "If it didn't automatically download, use the button below.",
9340+
downloadFile: 'Download file',
9341+
failedTitle: 'Export failed',
9342+
close: 'Close',
9343+
},
93309344
domain: {
93319345
notVerified: 'Not verified',
93329346
retry: 'Retry',

src/languages/es.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9478,6 +9478,20 @@ ${amount} para ${merchant} - ${date}`,
94789478
exportInProgress: 'Exportación en curso',
94799479
conciergeWillSend: 'Concierge te enviará el archivo en breve.',
94809480
},
9481+
exportDownload: {
9482+
preparingTitle: 'Preparando descarga...',
9483+
preparingBody: 'Puedes esperar a que termine la descarga o Concierge puede enviártelo por chat.',
9484+
sendFromConcierge: 'Envíame el archivo cuando esté listo',
9485+
conciergeTitle: '¡Por supuesto!',
9486+
conciergeBody: 'Concierge te enviará un mensaje cuando el archivo esté listo.',
9487+
goToConcierge: 'Ir a Concierge',
9488+
dismiss: 'Descartar',
9489+
readyTitle: '¡Tu archivo está listo!',
9490+
readyBody: 'Si no se descargó automáticamente, usa el botón de abajo.',
9491+
downloadFile: 'Descargar archivo',
9492+
failedTitle: 'Exportación fallida',
9493+
close: 'Cerrar',
9494+
},
94819495
openAppFailureModal: {
94829496
title: 'Algo salió mal...',
94839497
subtitle: `No hemos podido cargar todos sus datos. Hemos sido notificados y estamos investigando el problema. Si esto persiste, por favor comuníquese con`,

src/languages/fr.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9350,6 +9350,20 @@ Voici un *reçu test* pour vous montrer comment ça fonctionne :`,
93509350
exportInProgress: 'Export en cours',
93519351
conciergeWillSend: 'Concierge vous enverra le fichier sous peu.',
93529352
},
9353+
exportDownload: {
9354+
preparingTitle: 'Preparing download...',
9355+
preparingBody: 'You can either wait for the download to finish or Concierge can send it to you via chat.',
9356+
sendFromConcierge: "Send me the file when it's ready",
9357+
conciergeTitle: 'You bet!',
9358+
conciergeBody: 'Concierge will send you a message when the file is ready.',
9359+
goToConcierge: 'Go to Concierge',
9360+
dismiss: 'Dismiss',
9361+
readyTitle: 'Your file is ready!',
9362+
readyBody: "If it didn't automatically download, use the button below.",
9363+
downloadFile: 'Download file',
9364+
failedTitle: 'Export failed',
9365+
close: 'Close',
9366+
},
93539367
domain: {
93549368
notVerified: 'Non vérifié',
93559369
retry: 'Réessayer',

src/languages/it.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9311,6 +9311,20 @@ Ecco una *ricevuta di prova* per mostrarti come funziona:`,
93119311
exportInProgress: 'Esportazione in corso',
93129312
conciergeWillSend: 'Concierge ti invierà il file a breve.',
93139313
},
9314+
exportDownload: {
9315+
preparingTitle: 'Preparing download...',
9316+
preparingBody: 'You can either wait for the download to finish or Concierge can send it to you via chat.',
9317+
sendFromConcierge: "Send me the file when it's ready",
9318+
conciergeTitle: 'You bet!',
9319+
conciergeBody: 'Concierge will send you a message when the file is ready.',
9320+
goToConcierge: 'Go to Concierge',
9321+
dismiss: 'Dismiss',
9322+
readyTitle: 'Your file is ready!',
9323+
readyBody: "If it didn't automatically download, use the button below.",
9324+
downloadFile: 'Download file',
9325+
failedTitle: 'Export failed',
9326+
close: 'Close',
9327+
},
93149328
domain: {
93159329
notVerified: 'Non verificato',
93169330
retry: 'Riprova',

src/languages/ja.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9194,6 +9194,20 @@ ${reportName}
91949194
exportInProgress: 'エクスポート処理中',
91959195
conciergeWillSend: 'Conciergeがまもなくファイルを送信します。',
91969196
},
9197+
exportDownload: {
9198+
preparingTitle: 'Preparing download...',
9199+
preparingBody: 'You can either wait for the download to finish or Concierge can send it to you via chat.',
9200+
sendFromConcierge: "Send me the file when it's ready",
9201+
conciergeTitle: 'You bet!',
9202+
conciergeBody: 'Concierge will send you a message when the file is ready.',
9203+
goToConcierge: 'Go to Concierge',
9204+
dismiss: 'Dismiss',
9205+
readyTitle: 'Your file is ready!',
9206+
readyBody: "If it didn't automatically download, use the button below.",
9207+
downloadFile: 'Download file',
9208+
failedTitle: 'Export failed',
9209+
close: 'Close',
9210+
},
91979211
domain: {
91989212
notVerified: '未確認',
91999213
retry: '再試行',

src/languages/nl.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9279,6 +9279,20 @@ Hier is een *proefbon* om je te laten zien hoe het werkt:`,
92799279
exportInProgress: 'Export bezig',
92809280
conciergeWillSend: 'Concierge stuurt je het bestand zo meteen.',
92819281
},
9282+
exportDownload: {
9283+
preparingTitle: 'Preparing download...',
9284+
preparingBody: 'You can either wait for the download to finish or Concierge can send it to you via chat.',
9285+
sendFromConcierge: "Send me the file when it's ready",
9286+
conciergeTitle: 'You bet!',
9287+
conciergeBody: 'Concierge will send you a message when the file is ready.',
9288+
goToConcierge: 'Go to Concierge',
9289+
dismiss: 'Dismiss',
9290+
readyTitle: 'Your file is ready!',
9291+
readyBody: "If it didn't automatically download, use the button below.",
9292+
downloadFile: 'Download file',
9293+
failedTitle: 'Export failed',
9294+
close: 'Close',
9295+
},
92829296
domain: {
92839297
notVerified: 'Niet geverifieerd',
92849298
retry: 'Opnieuw proberen',

src/languages/pl.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9261,6 +9261,20 @@ Oto *paragon testowy*, żeby pokazać Ci, jak to działa:`,
92619261
exportInProgress: 'Trwa eksport',
92629262
conciergeWillSend: 'Concierge wkrótce wyśle Ci plik.',
92639263
},
9264+
exportDownload: {
9265+
preparingTitle: 'Preparing download...',
9266+
preparingBody: 'You can either wait for the download to finish or Concierge can send it to you via chat.',
9267+
sendFromConcierge: "Send me the file when it's ready",
9268+
conciergeTitle: 'You bet!',
9269+
conciergeBody: 'Concierge will send you a message when the file is ready.',
9270+
goToConcierge: 'Go to Concierge',
9271+
dismiss: 'Dismiss',
9272+
readyTitle: 'Your file is ready!',
9273+
readyBody: "If it didn't automatically download, use the button below.",
9274+
downloadFile: 'Download file',
9275+
failedTitle: 'Export failed',
9276+
close: 'Close',
9277+
},
92649278
domain: {
92659279
notVerified: 'Niezweryfikowane',
92669280
retry: 'Ponów próbę',

src/languages/pt-BR.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9270,6 +9270,20 @@ Aqui está um *comprovante de teste* para mostrar como funciona:`,
92709270
exportInProgress: 'Exportação em andamento',
92719271
conciergeWillSend: 'O Concierge enviará o arquivo para você em breve.',
92729272
},
9273+
exportDownload: {
9274+
preparingTitle: 'Preparing download...',
9275+
preparingBody: 'You can either wait for the download to finish or Concierge can send it to you via chat.',
9276+
sendFromConcierge: "Send me the file when it's ready",
9277+
conciergeTitle: 'You bet!',
9278+
conciergeBody: 'Concierge will send you a message when the file is ready.',
9279+
goToConcierge: 'Go to Concierge',
9280+
dismiss: 'Dismiss',
9281+
readyTitle: 'Your file is ready!',
9282+
readyBody: "If it didn't automatically download, use the button below.",
9283+
downloadFile: 'Download file',
9284+
failedTitle: 'Export failed',
9285+
close: 'Close',
9286+
},
92739287
domain: {
92749288
notVerified: 'Não verificado',
92759289
retry: 'Tentar novamente',

0 commit comments

Comments
 (0)