mirror of
https://github.com/Dokploy/dokploy
synced 2025-06-26 18:27:59 +00:00
Refactor ShowSchedulesLogs and ShowSchedules components
- Updated the ShowSchedulesLogs component to replace the trigger prop with children for better flexibility in rendering. - Enhanced the display logic in ShowSchedulesLogs to show a message when no logs are found, improving user feedback. - Added a Play icon to the ShowSchedules component for the manual run action, along with a tooltip for better user guidance. - Refactored the delete schedule button to provide success notifications upon deletion, enhancing user experience.
This commit is contained in:
@@ -13,17 +13,18 @@ import {
|
|||||||
import type { RouterOutputs } from "@/utils/api";
|
import type { RouterOutputs } from "@/utils/api";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { ShowDeployment } from "../deployments/show-deployment";
|
import { ShowDeployment } from "../deployments/show-deployment";
|
||||||
|
import { ClipboardList } from "lucide-react";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
deployments: RouterOutputs["deployment"]["all"];
|
deployments: RouterOutputs["deployment"]["all"];
|
||||||
serverId?: string;
|
serverId?: string;
|
||||||
trigger?: React.ReactNode;
|
children?: React.ReactNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ShowSchedulesLogs = ({
|
export const ShowSchedulesLogs = ({
|
||||||
deployments,
|
deployments,
|
||||||
serverId,
|
serverId,
|
||||||
trigger,
|
children,
|
||||||
}: Props) => {
|
}: Props) => {
|
||||||
const [activeLog, setActiveLog] = useState<
|
const [activeLog, setActiveLog] = useState<
|
||||||
RouterOutputs["deployment"]["all"][number] | null
|
RouterOutputs["deployment"]["all"][number] | null
|
||||||
@@ -32,8 +33,8 @@ export const ShowSchedulesLogs = ({
|
|||||||
return (
|
return (
|
||||||
<Dialog open={isOpen} onOpenChange={setIsOpen}>
|
<Dialog open={isOpen} onOpenChange={setIsOpen}>
|
||||||
<DialogTrigger asChild>
|
<DialogTrigger asChild>
|
||||||
{trigger ? (
|
{children ? (
|
||||||
trigger
|
children
|
||||||
) : (
|
) : (
|
||||||
<Button className="sm:w-auto w-full" size="sm" variant="outline">
|
<Button className="sm:w-auto w-full" size="sm" variant="outline">
|
||||||
View Logs
|
View Logs
|
||||||
@@ -47,8 +48,9 @@ export const ShowSchedulesLogs = ({
|
|||||||
See all the logs for this schedule
|
See all the logs for this schedule
|
||||||
</DialogDescription>
|
</DialogDescription>
|
||||||
</DialogHeader>
|
</DialogHeader>
|
||||||
|
{deployments.length > 0 ? (
|
||||||
<div className="grid gap-4">
|
<div className="grid gap-4">
|
||||||
{deployments?.map((deployment, index) => (
|
{deployments.map((deployment, index) => (
|
||||||
<div
|
<div
|
||||||
key={deployment.deploymentId}
|
key={deployment.deploymentId}
|
||||||
className="flex items-center justify-between rounded-lg border p-4 gap-2"
|
className="flex items-center justify-between rounded-lg border p-4 gap-2"
|
||||||
@@ -86,6 +88,13 @@ export const ShowSchedulesLogs = ({
|
|||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
) : (
|
||||||
|
<div className="flex flex-col items-center justify-center py-12 text-muted-foreground">
|
||||||
|
<ClipboardList className="size-12 mb-4" />
|
||||||
|
<p className="text-lg font-medium">No logs found</p>
|
||||||
|
<p className="text-sm">This schedule hasn't been executed yet</p>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
<ShowDeployment
|
<ShowDeployment
|
||||||
serverId={serverId || ""}
|
serverId={serverId || ""}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import {
|
|||||||
} from "@/components/ui/table";
|
} from "@/components/ui/table";
|
||||||
import { api } from "@/utils/api";
|
import { api } from "@/utils/api";
|
||||||
import { HandleSchedules } from "./handle-schedules";
|
import { HandleSchedules } from "./handle-schedules";
|
||||||
import { Clock, Terminal, Trash2 } from "lucide-react";
|
import { Clock, Play, Terminal, Trash2 } from "lucide-react";
|
||||||
import {
|
import {
|
||||||
Card,
|
Card,
|
||||||
CardContent,
|
CardContent,
|
||||||
@@ -20,6 +20,12 @@ import {
|
|||||||
import { Badge } from "@/components/ui/badge";
|
import { Badge } from "@/components/ui/badge";
|
||||||
import { toast } from "sonner";
|
import { toast } from "sonner";
|
||||||
import { ShowSchedulesLogs } from "./show-schedules-logs";
|
import { ShowSchedulesLogs } from "./show-schedules-logs";
|
||||||
|
import {
|
||||||
|
Tooltip,
|
||||||
|
TooltipContent,
|
||||||
|
TooltipProvider,
|
||||||
|
TooltipTrigger,
|
||||||
|
} from "@/components/ui/tooltip";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
applicationId: string;
|
applicationId: string;
|
||||||
@@ -29,21 +35,22 @@ export const ShowSchedules = ({ applicationId }: Props) => {
|
|||||||
const { data: schedules } = api.schedule.list.useQuery({
|
const { data: schedules } = api.schedule.list.useQuery({
|
||||||
applicationId,
|
applicationId,
|
||||||
});
|
});
|
||||||
|
const utils = api.useUtils();
|
||||||
|
|
||||||
const { mutate: deleteSchedule } = api.schedule.delete.useMutation({
|
const { mutateAsync: deleteSchedule, isLoading: isDeleting } =
|
||||||
|
api.schedule.delete.useMutation({
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
utils.schedule.list.invalidate({ applicationId });
|
utils.schedule.list.invalidate({ applicationId });
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const { mutateAsync: runManually } = api.schedule.runManually.useMutation({
|
const { mutateAsync: runManually, isLoading } =
|
||||||
|
api.schedule.runManually.useMutation({
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
utils.schedule.list.invalidate({ applicationId });
|
utils.schedule.list.invalidate({ applicationId });
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const utils = api.useContext();
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card className="border px-4 shadow-none bg-transparent">
|
<Card className="border px-4 shadow-none bg-transparent">
|
||||||
<CardHeader className="px-0">
|
<CardHeader className="px-0">
|
||||||
@@ -114,15 +121,22 @@ export const ShowSchedules = ({ applicationId }: Props) => {
|
|||||||
deployments={deployments || []}
|
deployments={deployments || []}
|
||||||
serverId={application.serverId || undefined}
|
serverId={application.serverId || undefined}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<TooltipProvider delayDuration={0}>
|
||||||
|
<Tooltip>
|
||||||
|
<TooltipTrigger asChild>
|
||||||
<Button
|
<Button
|
||||||
|
type="button"
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
size="sm"
|
isLoading={isLoading}
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
await runManually({
|
await runManually({
|
||||||
scheduleId: schedule.scheduleId,
|
scheduleId: schedule.scheduleId,
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
toast.success("Schedule run successfully");
|
toast.success(
|
||||||
|
"Schedule run successfully",
|
||||||
|
);
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
toast.error(
|
toast.error(
|
||||||
@@ -133,8 +147,14 @@ export const ShowSchedules = ({ applicationId }: Props) => {
|
|||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Run Manual Schedule
|
<Play className="size-4" />
|
||||||
</Button>
|
</Button>
|
||||||
|
</TooltipTrigger>
|
||||||
|
<TooltipContent>
|
||||||
|
Run Manual Schedule
|
||||||
|
</TooltipContent>
|
||||||
|
</Tooltip>
|
||||||
|
</TooltipProvider>
|
||||||
|
|
||||||
<HandleSchedules
|
<HandleSchedules
|
||||||
scheduleId={schedule.scheduleId}
|
scheduleId={schedule.scheduleId}
|
||||||
@@ -145,11 +165,24 @@ export const ShowSchedules = ({ applicationId }: Props) => {
|
|||||||
variant="ghost"
|
variant="ghost"
|
||||||
size="sm"
|
size="sm"
|
||||||
className="text-destructive hover:text-destructive"
|
className="text-destructive hover:text-destructive"
|
||||||
onClick={() =>
|
isLoading={isDeleting}
|
||||||
deleteSchedule({
|
onClick={async () => {
|
||||||
|
await deleteSchedule({
|
||||||
scheduleId: schedule.scheduleId,
|
scheduleId: schedule.scheduleId,
|
||||||
})
|
})
|
||||||
}
|
.then(() => {
|
||||||
|
toast.success(
|
||||||
|
"Schedule deleted successfully",
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
toast.error(
|
||||||
|
error instanceof Error
|
||||||
|
? error.message
|
||||||
|
: "Error deleting schedule",
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<Trash2 className="w-4 h-4" />
|
<Trash2 className="w-4 h-4" />
|
||||||
<span className="sr-only">Delete</span>
|
<span className="sr-only">Delete</span>
|
||||||
|
|||||||
Reference in New Issue
Block a user