mirror of
https://github.com/umami-software/umami.git
synced 2026-02-05 05:07:15 +01:00
# Conflicts: # db/mysql/schema.prisma # package.json # pnpm-lock.yaml # src/app/(main)/reports/[reportId]/ReportBody.tsx # src/app/(main)/reports/[reportId]/ReportPage.tsx # src/app/(main)/reports/utm/UTMView.tsx # src/app/(main)/websites/[websiteId]/WebsiteMetricsBar.tsx # src/app/(main)/websites/[websiteId]/WebsiteTableView.tsx # src/app/(main)/websites/[websiteId]/events/EventsPage.tsx # src/app/api/reports/[reportId]/route.ts # src/app/api/websites/[websiteId]/metrics/route.ts # src/components/hooks/queries/useReport.ts # src/components/icons.ts # src/components/messages.ts # src/components/metrics/MetricsTable.module.css # src/components/metrics/MetricsTable.tsx # src/queries/sql/events/getEventMetrics.ts # src/queries/sql/reports/getUTM.ts
64 lines
1.8 KiB
TypeScript
64 lines
1.8 KiB
TypeScript
import { useState } from 'react';
|
|
import { Icon, Tooltip, TooltipTrigger, LoadingButton } from '@umami/react-zen';
|
|
import { Download } from '@/components/icons';
|
|
import { useMessages, useApi } from '@/components/hooks';
|
|
import { useSearchParams } from 'next/navigation';
|
|
import { useDateParameters } from '@/components/hooks/useDateParameters';
|
|
import { useFilterParameters } from '@/components/hooks/useFilterParameters';
|
|
|
|
export function ExportButton({ websiteId }: { websiteId: string }) {
|
|
const { formatMessage, labels } = useMessages();
|
|
const [isLoading, setIsLoading] = useState(false);
|
|
const date = useDateParameters(websiteId);
|
|
const filters = useFilterParameters();
|
|
const searchParams = useSearchParams();
|
|
const { get } = useApi();
|
|
|
|
const handleClick = async () => {
|
|
setIsLoading(true);
|
|
|
|
const { zip } = await get(`/websites/${websiteId}/export`, {
|
|
...date,
|
|
...filters,
|
|
...searchParams,
|
|
format: 'json',
|
|
});
|
|
|
|
await loadZip(zip);
|
|
|
|
setIsLoading(false);
|
|
};
|
|
|
|
return (
|
|
<TooltipTrigger delay={0}>
|
|
<LoadingButton
|
|
variant="quiet"
|
|
showText={!isLoading}
|
|
isLoading={isLoading}
|
|
onClick={handleClick}
|
|
>
|
|
<Icon>
|
|
<Download />
|
|
</Icon>
|
|
</LoadingButton>
|
|
<Tooltip>{formatMessage(labels.download)}</Tooltip>
|
|
</TooltipTrigger>
|
|
);
|
|
}
|
|
|
|
async function loadZip(zip: string) {
|
|
const binary = atob(zip);
|
|
const bytes = new Uint8Array(binary.length);
|
|
for (let i = 0; i < binary.length; i++) {
|
|
bytes[i] = binary.charCodeAt(i);
|
|
}
|
|
|
|
const blob = new Blob([bytes], { type: 'application/zip' });
|
|
const url = URL.createObjectURL(blob);
|
|
|
|
const a = document.createElement('a');
|
|
a.href = url;
|
|
a.download = 'download.zip';
|
|
a.click();
|
|
URL.revokeObjectURL(url);
|
|
}
|