import { DateTooltip } from "@/components/shared/date-tooltip"; import { StatusTooltip } from "@/components/shared/status-tooltip"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Card, CardContent, CardDescription, CardHeader, CardTitle, } from "@/components/ui/card"; import { type RouterOutputs, api } from "@/utils/api"; import { Clock, Loader2, RocketIcon, Settings, RefreshCcw } from "lucide-react"; import React, { useEffect, useState } from "react"; import { CancelQueues } from "./cancel-queues"; import { RefreshToken } from "./refresh-token"; import { ShowDeployment } from "./show-deployment"; import { ShowRollbackSettings } from "../rollbacks/show-rollback-settings"; import { DialogAction } from "@/components/shared/dialog-action"; import { toast } from "sonner"; interface Props { id: string; type: | "application" | "compose" | "schedule" | "server" | "backup" | "previewDeployment"; refreshToken?: string; serverId?: string; } export const formatDuration = (seconds: number) => { if (seconds < 60) return `${seconds}s`; const minutes = Math.floor(seconds / 60); const remainingSeconds = seconds % 60; return `${minutes}m ${remainingSeconds}s`; }; export const ShowDeployments = ({ id, type, refreshToken, serverId, }: Props) => { const [activeLog, setActiveLog] = useState< RouterOutputs["deployment"]["all"][number] | null >(null); const { data: deployments, isLoading: isLoadingDeployments } = api.deployment.allByType.useQuery( { id, type, }, { enabled: !!id, refetchInterval: 1000, }, ); const { mutateAsync: rollback, isLoading: isRollingBack } = api.rollback.rollback.useMutation(); const [url, setUrl] = React.useState(""); useEffect(() => { setUrl(document.location.origin); }, []); return (
Deployments See all the 10 last deployments for this {type}
{(type === "application" || type === "compose") && ( )} {type === "application" && ( )}
{refreshToken && (
If you want to re-deploy this application use this URL in the config of your git provider or docker
Webhook URL:
{`${url}/api/deploy${type === "compose" ? "/compose" : ""}/${refreshToken}`} {(type === "application" || type === "compose") && ( )}
)} {isLoadingDeployments ? (
Loading deployments...
) : deployments?.length === 0 ? (
No deployments found
) : (
{deployments?.map((deployment, index) => (
{index + 1}. {deployment.status} {deployment.title} {deployment.description && ( {deployment.description} )}
{deployment.startedAt && deployment.finishedAt && ( {formatDuration( Math.floor( (new Date(deployment.finishedAt).getTime() - new Date(deployment.startedAt).getTime()) / 1000, ), )} )}
{deployment?.rollback && deployment.status === "done" && type === "application" && ( { await rollback({ rollbackId: deployment.rollback.rollbackId, }) .then(() => { toast.success( "Rollback initiated successfully", ); }) .catch(() => { toast.error("Error initiating rollback"); }); }} > )}
))}
)} setActiveLog(null)} logPath={activeLog?.logPath || ""} errorMessage={activeLog?.errorMessage || ""} />
); };