Files
calendar/packages/ui/components/toast/ProgressToast.tsx
T
+4
devin-ai-integration[bot]GitHubeunjae@cal.com <eunjae@cal.com>eunjae@cal.com <eunjae@cal.com>eunjae@cal.com <eunjae@cal.com>eunjae@cal.com <eunjae@cal.com>eunjae@cal.com <eunjae@cal.com>eunjae@cal.com <eunjae@cal.com>eunjae@cal.com <eunjae@cal.com>eunjae@cal.com <eunjae@cal.com>eunjae@cal.com <eunjae@cal.com>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>eunjae@cal.com <eunjae@cal.com>Eunjae Lee
e29f6af540 feat(insights): add progress indicator to download button on /insights and /insights/routing (CAL-5408) (#20631)
* feat(insights): add progress indicator to routing form responses download button (CAL-5408)

Co-Authored-By: eunjae@cal.com <eunjae@cal.com>

* fix: address PR feedback - remove initial progress update and ensure no decimal parts in percentage

Co-Authored-By: eunjae@cal.com <eunjae@cal.com>

* feat(insights): add progress indicator to Download component

Co-Authored-By: eunjae@cal.com <eunjae@cal.com>

* feat: paginate rawData endpoint and implement batch fetching in Download component

Co-Authored-By: eunjae@cal.com <eunjae@cal.com>

* refactor: simplify pagination logic in trpc-router.ts

Co-Authored-By: eunjae@cal.com <eunjae@cal.com>

* show progress on tooltip

* fix download for /insights

* fix download when there is no data

* feat: replace tooltip progress indicator with toast notification

Co-Authored-By: eunjae@cal.com <eunjae@cal.com>

* fix: remove duplicate ProgressToast component from showToast.tsx

Co-Authored-By: eunjae@cal.com <eunjae@cal.com>

* fix: export ProgressToast component from index.ts

Co-Authored-By: eunjae@cal.com <eunjae@cal.com>

* fix: add missing translation for downloading_data

Co-Authored-By: eunjae@cal.com <eunjae@cal.com>

* update progress toast implementation

* fix error

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: eunjae@cal.com <eunjae@cal.com>
Co-authored-by: Eunjae Lee <hey@eunjae.dev>
2025-04-23 15:59:09 +02:00

59 lines
1.9 KiB
TypeScript

import * as React from "react";
import { toast } from "sonner";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { Icon } from "../icon";
type ProgressToastProps = {
message?: string;
progress: number;
toastId: string | number;
onClose: (toastId: string | number) => void;
};
export const ProgressToast = ({ message, progress, onClose, toastId }: ProgressToastProps) => {
const { t } = useLocale();
const defaultMessage = t("downloading");
return (
<div className="animate-fade-in-up bg-subtle shadow-elevation-low border-subtle mb-2 flex h-auto flex-col space-y-2 rounded-lg border px-3 py-2.5 text-sm font-semibold md:max-w-sm">
<div className="flex items-center gap-2">
<span className="mt-0.5">
<Icon name="file-down" className="h-4 w-4" />
</span>
<p className="m-0 w-full text-left">{message || defaultMessage}</p>
<button onClick={() => onClose(toastId)}>
<Icon name="x" className="h-4 w-4 hover:cursor-pointer" />
</button>
</div>
<div className="h-2 w-full overflow-hidden rounded-full">
<div
className="bg-inverted h-2 rounded-full opacity-50 transition-all duration-300 ease-in-out"
style={{ width: `${progress}%` }}
/>
</div>
<div className="text-right text-xs font-normal">{Math.floor(progress)}%</div>
</div>
);
};
export function showProgressToast(progress: number, message?: string, toastId = "download-progress") {
const onClose = (id: string | number) => {
toast.dismiss(id);
};
return toast.custom(
(id) => <ProgressToast message={message} progress={progress} onClose={onClose} toastId={id} />,
{
id: toastId,
duration: Infinity, // Keep the toast visible until dismissed
position: "bottom-center",
}
);
}
export function hideProgressToast(toastId = "download-progress") {
toast.dismiss(toastId);
}