From 843313ddb9cbe6fee109eeab7f737a001400fe37 Mon Sep 17 00:00:00 2001 From: HarikrishnanD Date: Tue, 11 Nov 2025 13:10:47 +0530 Subject: [PATCH] feat: add expandable commit messages for deployment logs --- .../deployments/show-deployments.tsx | 106 ++++++++++++++++-- 1 file changed, 97 insertions(+), 9 deletions(-) diff --git a/apps/dokploy/components/dashboard/application/deployments/show-deployments.tsx b/apps/dokploy/components/dashboard/application/deployments/show-deployments.tsx index 1045856c2..5848a046f 100644 --- a/apps/dokploy/components/dashboard/application/deployments/show-deployments.tsx +++ b/apps/dokploy/components/dashboard/application/deployments/show-deployments.tsx @@ -1,4 +1,4 @@ -import { Clock, Loader2, RefreshCcw, RocketIcon, Settings } from "lucide-react"; +import { ChevronDown, ChevronUp, Clock, Loader2, RefreshCcw, RocketIcon, Settings } from "lucide-react"; import React, { useEffect, useMemo, useState } from "react"; import { toast } from "sonner"; import { AlertBlock } from "@/components/shared/alert-block"; @@ -80,6 +80,52 @@ export const ShowDeployments = ({ } = api.compose.cancelDeployment.useMutation(); const [url, setUrl] = React.useState(""); + const [expandedDescriptions, setExpandedDescriptions] = useState>( + new Set(), + ); + + // Maximum character length before truncating commit messages + const MAX_DESCRIPTION_LENGTH = 150; + + // Helper function to truncate description intelligently + const truncateDescription = (description: string, maxLength: number): string => { + if (maxLength <= 0) { + return description; // Don't truncate if maxLength is 0 or negative + } + if (description.length <= maxLength) { + return description; + } + // Try to truncate at a word boundary if possible + const truncated = description.slice(0, maxLength); + const lastSpace = truncated.lastIndexOf(" "); + // If we find a space near the end (within last 20 chars), use it for cleaner truncation + if (lastSpace > maxLength - 20 && lastSpace > 0) { + return `${truncated.slice(0, lastSpace)}...`; + } + return `${truncated}...`; + }; + + // Check if description should be truncated + const shouldTruncate = (description: string): boolean => { + // Only truncate if MAX_DESCRIPTION_LENGTH is greater than 0 + if (MAX_DESCRIPTION_LENGTH <= 0) { + return false; + } + return description.length > MAX_DESCRIPTION_LENGTH; + }; + + // Toggle expand/collapse state for a specific deployment + const toggleDescription = (deploymentId: string) => { + setExpandedDescriptions((prev) => { + const next = new Set(prev); + if (next.has(deploymentId)) { + next.delete(deploymentId); + } else { + next.add(deploymentId); + } + return next; + }); + }; // Check for stuck deployment (more than 9 minutes) - only for the most recent deployment const stuckDeployment = useMemo(() => { @@ -230,14 +276,56 @@ export const ShowDeployments = ({ className="size-2.5" /> - - {deployment.title} - - {deployment.description && ( - - {deployment.description} - - )} + {(() => { + // The commit message is in the title field, so we truncate that + const titleText = deployment.title.trim(); + const needsTruncation = shouldTruncate(titleText); + const isExpanded = expandedDescriptions.has(deployment.deploymentId); + + return ( +
+ {/* Commit message (from title) - truncated */} + + {isExpanded || !needsTruncation + ? titleText + : truncateDescription( + titleText, + MAX_DESCRIPTION_LENGTH, + )} + + {needsTruncation && ( + + )} + {/* Hash (from description) - shown in compact form */} + {deployment.description && deployment.description.trim() && ( + + {deployment.description} + + )} +
+ ); + })()}