Merge pull request #5590 from GlebsonS4ntos/fix/prevent-service-header-overflow-mobile

fix(ui): prevent service header overflow on mobile
This commit is contained in:
Mauricio Siu
2026-10-16 09:14:28 -06:00
committed by GitHub
9 changed files with 108 additions and 73 deletions
@@ -357,7 +357,10 @@ export const AdvanceBreadcrumb = () => {
className="h-auto px-2 py-1.5 hover:bg-accent gap-2"
>
<FolderInput className="size-4 text-muted-foreground" />
<span className="font-medium max-w-[50px] md:max-w-[150px] truncate">
<span
className="font-medium max-w-[50px] md:max-w-[150px] truncate"
title={currentProject?.name}
>
{currentProject?.name || "Select Project"}
</span>
<ChevronDown className="size-4 text-muted-foreground" />
@@ -123,9 +123,9 @@ const Service = (
<div className="w-full">
<Card className="h-full bg-sidebar p-2.5 rounded-xl w-full">
<div className="rounded-xl bg-background shadow-md ">
<CardHeader className="flex flex-row justify-between items-center">
<div className="flex flex-col">
<CardTitle className="text-xl flex flex-row gap-2 items-center">
<CardHeader className="flex w-full min-w-0 flex-row justify-between items-center">
<div className="flex min-w-0 flex-1 flex-col">
<CardTitle className="text-xl flex min-w-0 flex-row gap-2 items-center">
<div className="relative flex flex-row gap-4 items-center">
<ShowIconSettings
serviceId={applicationId}
@@ -136,20 +136,22 @@ const Service = (
<StatusTooltip status={data?.applicationStatus} />
</div>
</div>
{data?.name}
<span className="min-w-0 truncate" title={data?.name}>
{data?.name}
</span>
</CardTitle>
{data?.description && (
<CardDescription>{data?.description}</CardDescription>
)}
<span className="text-sm text-muted-foreground">
<span className="text-sm text-muted-foreground min-w-0 truncate">
{data?.appName}
</span>
</div>
<div className="flex flex-col h-fit w-fit gap-2">
<div className="flex flex-row h-fit w-fit gap-2">
<div className="flex max-w-[45%] min-w-0 flex-col h-fit gap-2 md:max-w-none md:w-fit">
<div className="flex max-w-full min-w-0 flex-row h-fit gap-2">
<Badge
className="cursor-pointer"
className="min-w-0 max-w-full cursor-pointer overflow-hidden"
onClick={() => {
const ip = data?.server?.ipAddress || serverIp;
if (ip) {
@@ -165,7 +167,9 @@ const Service = (
: "destructive"
}
>
{data?.server?.name || "Dokploy Server"}
<span className="truncate">
{data?.server?.name || "Dokploy Server"}
</span>
</Badge>
{data?.server?.serverStatus === "inactive" && (
<TooltipProvider delayDuration={0}>
@@ -114,9 +114,9 @@ const Service = (
<Card className="h-full bg-sidebar p-2.5 rounded-xl w-full">
<div className="rounded-xl bg-background shadow-md ">
<div className="flex flex-col gap-4">
<CardHeader className="flex flex-row justify-between items-center">
<div className="flex flex-col">
<CardTitle className="text-xl flex flex-row gap-2 items-center">
<CardHeader className="flex w-full min-w-0 flex-row justify-between items-center">
<div className="flex min-w-0 flex-1 flex-col">
<CardTitle className="text-xl flex min-w-0 flex-row gap-2 items-center">
<div className="relative flex flex-row gap-4 items-center">
<ShowIconSettings
serviceId={composeId}
@@ -127,20 +127,22 @@ const Service = (
<StatusTooltip status={data?.composeStatus} />
</div>
</div>
{data?.name}
<span className="min-w-0 truncate" title={data?.name}>
{data?.name}
</span>
</CardTitle>
{data?.description && (
<CardDescription>{data?.description}</CardDescription>
)}
<span className="text-sm text-muted-foreground">
<span className="text-sm text-muted-foreground min-w-0 truncate">
{data?.appName}
</span>
</div>
<div className="flex flex-col h-fit w-fit gap-2">
<div className="flex flex-row h-fit w-fit gap-2">
<div className="flex max-w-[45%] min-w-0 flex-col h-fit gap-2 md:max-w-none md:w-fit">
<div className="flex max-w-full min-w-0 flex-row h-fit gap-2">
<Badge
className="cursor-pointer"
className="min-w-0 max-w-full cursor-pointer overflow-hidden"
onClick={() => {
const ip = data?.server?.ipAddress || serverIp;
if (ip) {
@@ -156,7 +158,9 @@ const Service = (
: "destructive"
}
>
{data?.server?.name || "Dokploy Server"}
<span className="truncate">
{data?.server?.name || "Dokploy Server"}
</span>
</Badge>
{data?.server?.serverStatus === "inactive" && (
<TooltipProvider>
@@ -80,9 +80,9 @@ const Libsql = (
</Head>
<Card className="h-full bg-sidebar p-2.5 rounded-xl w-full">
<div className="rounded-xl bg-background shadow-md ">
<CardHeader className="flex flex-row justify-between items-center">
<div className="flex flex-col">
<CardTitle className="text-xl flex flex-row gap-2">
<CardHeader className="flex w-full min-w-0 flex-row justify-between items-center">
<div className="flex min-w-0 flex-1 flex-col">
<CardTitle className="text-xl flex min-w-0 flex-row gap-2">
<div className="relative flex flex-row gap-4">
<div className="absolute -right-1 -top-2">
<StatusTooltip status={data?.applicationStatus} />
@@ -90,20 +90,22 @@ const Libsql = (
<LibsqlIcon className="h-6 w-6 text-muted-foreground" />
</div>
{data?.name}
<span className="min-w-0 truncate" title={data?.name}>
{data?.name}
</span>
</CardTitle>
{data?.description && (
<CardDescription>{data?.description}</CardDescription>
)}
<span className="text-sm text-muted-foreground">
<span className="text-sm text-muted-foreground min-w-0 truncate">
{data?.appName}
</span>
</div>
<div className="flex flex-col h-fit w-fit gap-2">
<div className="flex flex-row h-fit w-fit gap-2">
<div className="flex max-w-[45%] min-w-0 flex-col h-fit gap-2 md:max-w-none md:w-fit">
<div className="flex max-w-full min-w-0 flex-row h-fit gap-2">
<Badge
className="cursor-pointer"
className="min-w-0 max-w-full cursor-pointer overflow-hidden"
onClick={() => {
const ip = data?.server?.ipAddress || serverIp;
if (ip) {
@@ -119,7 +121,9 @@ const Libsql = (
: "destructive"
}
>
{data?.server?.name || "Dokploy Server"}
<span className="truncate">
{data?.server?.name || "Dokploy Server"}
</span>
</Badge>
{data?.server?.serverStatus === "inactive" && (
<TooltipProvider delayDuration={0}>
@@ -92,9 +92,9 @@ const Mariadb = (
</Head>
<Card className="h-full bg-sidebar p-2.5 rounded-xl w-full">
<div className="rounded-xl bg-background shadow-md ">
<CardHeader className="flex flex-row justify-between items-center">
<div className="flex flex-col">
<CardTitle className="text-xl flex flex-row gap-2">
<CardHeader className="flex w-full min-w-0 flex-row justify-between items-center">
<div className="flex min-w-0 flex-1 flex-col">
<CardTitle className="text-xl flex min-w-0 flex-row gap-2">
<div className="relative flex flex-row gap-4">
<div className="absolute -right-1 -top-2">
<StatusTooltip status={data?.applicationStatus} />
@@ -102,20 +102,22 @@ const Mariadb = (
<MariadbIcon className="h-6 w-6 text-muted-foreground" />
</div>
{data?.name}
<span className="min-w-0 truncate" title={data?.name}>
{data?.name}
</span>
</CardTitle>
{data?.description && (
<CardDescription>{data?.description}</CardDescription>
)}
<span className="text-sm text-muted-foreground">
<span className="text-sm text-muted-foreground min-w-0 truncate">
{data?.appName}
</span>
</div>
<div className="flex flex-col h-fit w-fit gap-2">
<div className="flex flex-row h-fit w-fit gap-2">
<div className="flex max-w-[45%] min-w-0 flex-col h-fit gap-2 md:max-w-none md:w-fit">
<div className="flex max-w-full min-w-0 flex-row h-fit gap-2">
<Badge
className="cursor-pointer"
className="min-w-0 max-w-full cursor-pointer overflow-hidden"
onClick={() => {
const ip = data?.server?.ipAddress || serverIp;
if (ip) {
@@ -131,7 +133,9 @@ const Mariadb = (
: "destructive"
}
>
{data?.server?.name || "Dokploy Server"}
<span className="truncate">
{data?.server?.name || "Dokploy Server"}
</span>
</Badge>
{data?.server?.serverStatus === "inactive" && (
<TooltipProvider delayDuration={0}>
@@ -91,9 +91,9 @@ const Mongo = (
<div className="w-full">
<Card className="h-full bg-sidebar p-2.5 rounded-xl w-full">
<div className="rounded-xl bg-background shadow-md ">
<CardHeader className="flex flex-row justify-between items-center">
<div className="flex flex-col">
<CardTitle className="text-xl flex flex-row gap-2">
<CardHeader className="flex w-full min-w-0 flex-row justify-between items-center">
<div className="flex min-w-0 flex-1 flex-col">
<CardTitle className="text-xl flex min-w-0 flex-row gap-2">
<div className="relative flex flex-row gap-4">
<div className="absolute -right-1 -top-2">
<StatusTooltip status={data?.applicationStatus} />
@@ -101,20 +101,22 @@ const Mongo = (
<MongodbIcon className="h-6 w-6 text-muted-foreground" />
</div>
{data?.name}
<span className="min-w-0 truncate" title={data?.name}>
{data?.name}
</span>
</CardTitle>
{data?.description && (
<CardDescription>{data?.description}</CardDescription>
)}
<span className="text-sm text-muted-foreground">
<span className="text-sm text-muted-foreground min-w-0 truncate">
{data?.appName}
</span>
</div>
<div className="flex flex-col h-fit w-fit gap-2">
<div className="flex flex-row h-fit w-fit gap-2">
<div className="flex max-w-[45%] min-w-0 flex-col h-fit gap-2 md:max-w-none md:w-fit">
<div className="flex max-w-full min-w-0 flex-row h-fit gap-2">
<Badge
className="cursor-pointer"
className="min-w-0 max-w-full cursor-pointer overflow-hidden"
onClick={() => {
const ip = data?.server?.ipAddress || serverIp;
if (ip) {
@@ -130,7 +132,9 @@ const Mongo = (
: "destructive"
}
>
{data?.server?.name || "Dokploy Server"}
<span className="truncate">
{data?.server?.name || "Dokploy Server"}
</span>
</Badge>
{data?.server?.serverStatus === "inactive" && (
<TooltipProvider delayDuration={0}>
@@ -91,9 +91,9 @@ const MySql = (
<div className="w-full">
<Card className="h-full bg-sidebar p-2.5 rounded-xl w-full">
<div className="rounded-xl bg-background shadow-md ">
<CardHeader className="flex flex-row justify-between items-center">
<div className="flex flex-col">
<CardTitle className="text-xl flex flex-row gap-2">
<CardHeader className="flex w-full min-w-0 flex-row justify-between items-center">
<div className="flex min-w-0 flex-1 flex-col">
<CardTitle className="text-xl flex min-w-0 flex-row gap-2">
<div className="relative flex flex-row gap-4">
<div className="absolute -right-1 -top-2">
<StatusTooltip status={data?.applicationStatus} />
@@ -101,20 +101,22 @@ const MySql = (
<MysqlIcon className="h-6 w-6 text-muted-foreground" />
</div>
{data?.name}
<span className="min-w-0 truncate" title={data?.name}>
{data?.name}
</span>
</CardTitle>
{data?.description && (
<CardDescription>{data?.description}</CardDescription>
)}
<span className="text-sm text-muted-foreground">
<span className="text-sm text-muted-foreground min-w-0 truncate">
{data?.appName}
</span>
</div>
<div className="flex flex-col h-fit w-fit gap-2">
<div className="flex flex-row h-fit w-fit gap-2">
<div className="flex max-w-[45%] min-w-0 flex-col h-fit gap-2 md:max-w-none md:w-fit">
<div className="flex max-w-full min-w-0 flex-row h-fit gap-2">
<Badge
className="cursor-pointer"
className="min-w-0 max-w-full cursor-pointer overflow-hidden"
onClick={() => {
const ip = data?.server?.ipAddress || serverIp;
if (ip) {
@@ -130,7 +132,9 @@ const MySql = (
: "destructive"
}
>
{data?.server?.name || "Dokploy Server"}
<span className="truncate">
{data?.server?.name || "Dokploy Server"}
</span>
</Badge>
{data?.server?.serverStatus === "inactive" && (
<TooltipProvider delayDuration={0}>
@@ -90,9 +90,9 @@ const Postgresql = (
<div className="w-full">
<Card className="h-full bg-sidebar p-2.5 rounded-xl w-full">
<div className="rounded-xl bg-background shadow-md ">
<CardHeader className="flex flex-row justify-between items-center">
<div className="flex flex-col">
<CardTitle className="text-xl flex flex-row gap-2">
<CardHeader className="flex w-full min-w-0 flex-row justify-between items-center">
<div className="flex min-w-0 flex-1 flex-col">
<CardTitle className="text-xl flex min-w-0 flex-row gap-2">
<div className="relative flex flex-row gap-4">
<div className="absolute -right-1 -top-2">
<StatusTooltip status={data?.applicationStatus} />
@@ -100,20 +100,22 @@ const Postgresql = (
<PostgresqlIcon className="h-6 w-6 text-muted-foreground" />
</div>
{data?.name}
<span className="min-w-0 truncate" title={data?.name}>
{data?.name}
</span>
</CardTitle>
{data?.description && (
<CardDescription>{data?.description}</CardDescription>
)}
<span className="text-sm text-muted-foreground">
<span className="text-sm text-muted-foreground min-w-0 truncate">
{data?.appName}
</span>
</div>
<div className="flex flex-col h-fit w-fit gap-2">
<div className="flex flex-row h-fit w-fit gap-2">
<div className="flex max-w-[45%] min-w-0 flex-col h-fit gap-2 md:max-w-none md:w-fit">
<div className="flex max-w-full min-w-0 flex-row h-fit gap-2">
<Badge
className="cursor-pointer"
className="min-w-0 max-w-full cursor-pointer overflow-hidden"
onClick={() => {
const ip = data?.server?.ipAddress || serverIp;
if (ip) {
@@ -129,7 +131,9 @@ const Postgresql = (
: "destructive"
}
>
{data?.server?.name || "Dokploy Server"}
<span className="truncate">
{data?.server?.name || "Dokploy Server"}
</span>
</Badge>
{data?.server?.serverStatus === "inactive" && (
<TooltipProvider delayDuration={0}>
@@ -90,9 +90,9 @@ const Redis = (
<div className="w-full">
<Card className="h-full bg-sidebar p-2.5 rounded-xl w-full">
<div className="rounded-xl bg-background shadow-md ">
<CardHeader className="flex flex-row justify-between items-center">
<div className="flex flex-col">
<CardTitle className="text-xl flex flex-row gap-2">
<CardHeader className="flex w-full min-w-0 flex-row justify-between items-center">
<div className="flex min-w-0 flex-1 flex-col">
<CardTitle className="text-xl flex min-w-0 flex-row gap-2">
<div className="relative flex flex-row gap-4">
<div className="absolute -right-1 -top-2">
<StatusTooltip status={data?.applicationStatus} />
@@ -100,20 +100,22 @@ const Redis = (
<RedisIcon className="h-6 w-6 text-muted-foreground" />
</div>
{data?.name}
<span className="min-w-0 truncate" title={data?.name}>
{data?.name}
</span>
</CardTitle>
{data?.description && (
<CardDescription>{data?.description}</CardDescription>
)}
<span className="text-sm text-muted-foreground">
<span className="text-sm text-muted-foreground min-w-0 truncate">
{data?.appName}
</span>
</div>
<div className="flex flex-col h-fit w-fit gap-2">
<div className="flex flex-row h-fit w-fit gap-2">
<div className="flex max-w-[45%] min-w-0 flex-col h-fit gap-2 md:max-w-none md:w-fit">
<div className="flex max-w-full min-w-0 flex-row h-fit gap-2">
<Badge
className="cursor-pointer"
className="min-w-0 max-w-full cursor-pointer overflow-hidden"
onClick={() => {
const ip = data?.server?.ipAddress || serverIp;
if (ip) {
@@ -129,7 +131,9 @@ const Redis = (
: "destructive"
}
>
{data?.server?.name || "Dokploy Server"}
<span className="truncate">
{data?.server?.name || "Dokploy Server"}
</span>
</Badge>
{data?.server?.serverStatus === "inactive" && (
<TooltipProvider delayDuration={0}>