import {Fragment} from 'react'; import type {RouteComponentProps} from 'react-router'; import styled from '@emotion/styled'; import {Button, LinkButton} from 'sentry/components/button'; import {ExportQueryType} from 'sentry/components/dataExport'; import {DateTime} from 'sentry/components/dateTime'; import LoadingIndicator from 'sentry/components/loadingIndicator'; import SentryDocumentTitle from 'sentry/components/sentryDocumentTitle'; import {IconDownload} from 'sentry/icons'; import {t, tct} from 'sentry/locale'; import {space} from 'sentry/styles/space'; import {useApiQuery} from 'sentry/utils/queryClient'; import normalizeUrl from 'sentry/utils/url/normalizeUrl'; import {useRouteContext} from 'sentry/utils/useRouteContext'; import Layout from 'sentry/views/auth/layout'; export enum DownloadStatus { EARLY = 'EARLY', VALID = 'VALID', EXPIRED = 'EXPIRED', } type RouteParams = { dataExportId: string; orgId: string; }; type Download = { checksum: string; dateCreated: string; id: number; query: { info: object; type: ExportQueryType; }; status: DownloadStatus; user: { email: string; id: number; username: string; }; dateExpired?: string; dateFinished?: string; }; type Props = {} & RouteComponentProps; function DataDownload({params: {orgId, dataExportId}}: Props) { const { data: download, isPending, isError, error, } = useApiQuery([`/organizations/${orgId}/data-export/${dataExportId}/`], { staleTime: 0, }); const route = useRouteContext(); if (isError) { const errDetail = error?.responseJSON?.detail; return (

{error.status} - {error.statusText}

{errDetail && (

{errDetail as string}

)}
); } if (isPending) { return ; } const getActionLink = (queryType): string => { switch (queryType) { case ExportQueryType.ISSUES_BY_TAG: return `/organizations/${orgId}/issues/`; case ExportQueryType.DISCOVER: return `/organizations/${orgId}/discover/queries/`; default: return '/'; } }; const renderDate = (date: string | undefined): React.ReactNode => { if (!date) { return null; } const d = new Date(date); return ( ); }; const renderEarly = (): React.ReactNode => { return (

{t('What are')} {t(' you ')} {t('doing here?')}

{t( "Not that its any of our business, but were you invited to this page? It's just that we don't exactly remember emailing you about it." )}

{t("Close this window and we'll email you when your download is ready.")}

); }; const renderExpired = (): React.ReactNode => { const {query} = download; const actionLink = getActionLink(query.type); return (

{t('This is awkward.')}

{t( "That link expired, so your download doesn't live here anymore. Just picked up one day and left town." )}

{t( 'Make a new one with your latest data. Your old download will never see it coming.' )}

{t('Start a New Download')}
); }; const openInDiscover = () => { const navigator = route.router; const { query: {info}, } = download; const to = { pathname: `/organizations/${orgId}/discover/results/`, query: info, }; navigator.push(normalizeUrl(to)); }; const renderOpenInDiscover = () => { const { query = { type: ExportQueryType.ISSUES_BY_TAG, info: {}, }, } = download; // default to IssuesByTag because we don't want to // display this unless we're sure its a discover query const {type = ExportQueryType.ISSUES_BY_TAG} = query; return type === 'Discover' ? (

{t('Need to make changes?')}


) : null; }; const renderValid = (): React.ReactNode => { const {dateExpired, checksum} = download; return (

{t('All done.')}

{t("See, that wasn't so bad. Your data is all ready for download.")}

} href={`/api/0/organizations/${orgId}/data-export/${dataExportId}/?download=true`} > {t('Download CSV')}

{t("That link won't last forever — it expires:")}
{renderDate(dateExpired)}

{renderOpenInDiscover()}

SHA1:{checksum}
{tct('Need help verifying? [link].', { link: ( {t('Check out our docs')} ), })}

); }; const renderContent = () => { switch (download.status) { case DownloadStatus.EARLY: return renderEarly(); case DownloadStatus.EXPIRED: return renderExpired(); default: return renderValid(); } }; return (
{renderContent()}
); } const Header = styled('header')` border-bottom: 1px solid ${p => p.theme.border}; padding: ${space(3)} 40px 0; h3 { font-size: 24px; margin: 0 0 ${space(3)} 0; } `; const Body = styled('div')` padding: ${space(2)} 40px; max-width: 500px; p { margin: ${space(1.5)} 0; } `; const DownloadButton = styled(LinkButton)` margin-bottom: ${space(1.5)}; `; export default DataDownload;