From e07018d2f93bcf36e6bc8fba135993af9adddd55 Mon Sep 17 00:00:00 2001 From: chbndrhnns <7534547+chbndrhnns@users.noreply.github.com> Date: Tue, 8 Sep 2026 13:41:12 +0000 Subject: [PATCH] fix(deployments): prevent false-positive redeploy domain warning (#858) - Check project and service domain rows in redeploy unreachable services check - Support multi-route publicEndpoints on services - Direct user to Domains tab in warning modal action and suggested fix copy --- .../deploy/[slug]/components/Sidebar.tsx | 13 ++ .../projects/[id]/components/Deployments.tsx | 32 ++-- .../redeploy-unreachable-warning.test.ts | 181 ++++++++++++++++++ .../redeploy-unreachable-warning.ts | 67 +++++++ .../src/i18n/locales/ar/projects.json | 7 +- .../src/i18n/locales/de/projects.json | 7 +- .../src/i18n/locales/en/projects.json | 7 +- .../src/i18n/locales/es/projects.json | 7 +- .../src/i18n/locales/fr/projects.json | 7 +- .../src/i18n/locales/ja/projects.json | 7 +- .../src/i18n/locales/pt/projects.json | 7 +- .../src/i18n/locales/tr/projects.json | 7 +- .../src/i18n/locales/zh/projects.json | 7 +- 13 files changed, 309 insertions(+), 47 deletions(-) create mode 100644 apps/dashboard/src/app/(dashboard)/projects/[id]/components/redeploy-unreachable-warning.test.ts create mode 100644 apps/dashboard/src/app/(dashboard)/projects/[id]/components/redeploy-unreachable-warning.ts diff --git a/apps/dashboard/src/app/(dashboard)/(deployment)/deploy/[slug]/components/Sidebar.tsx b/apps/dashboard/src/app/(dashboard)/(deployment)/deploy/[slug]/components/Sidebar.tsx index c89ad87b7..64f20e5c1 100644 --- a/apps/dashboard/src/app/(dashboard)/(deployment)/deploy/[slug]/components/Sidebar.tsx +++ b/apps/dashboard/src/app/(dashboard)/(deployment)/deploy/[slug]/components/Sidebar.tsx @@ -595,8 +595,21 @@ function hasConnectedDomain(service: { customDomain?: string; domain?: string; name?: string; + publicEndpoints?: Array<{ + domainType?: "free" | "custom"; + customDomain?: string; + domain?: string; + }>; }) { if (!service.exposed) return false; + if (service.publicEndpoints && service.publicEndpoints.length > 0) { + const hasEndpointDomain = service.publicEndpoints.some((ep) => + ep.domainType === "custom" + ? Boolean(ep.customDomain?.trim()) + : Boolean(ep.domain?.trim()), + ); + if (hasEndpointDomain) return true; + } if (service.domainType === "custom") return Boolean(service.customDomain?.trim()); return Boolean(service.domain?.trim() || service.name?.trim()); } diff --git a/apps/dashboard/src/app/(dashboard)/projects/[id]/components/Deployments.tsx b/apps/dashboard/src/app/(dashboard)/projects/[id]/components/Deployments.tsx index 401ac493b..5aec60ecd 100644 --- a/apps/dashboard/src/app/(dashboard)/projects/[id]/components/Deployments.tsx +++ b/apps/dashboard/src/app/(dashboard)/projects/[id]/components/Deployments.tsx @@ -14,7 +14,11 @@ import { useRouter } from "next/navigation"; import { Rocket, ChevronDown, RefreshCw, Layers } from "lucide-react"; import DropdownMenu from "@/components/ui/DropdownMenu"; import WarningCallout from "@/components/shared/WarningCallout"; - +import { + hasConnectedDomain, + isPotentiallyPublicService, + shouldWarnAboutUnreachableServices, +} from "./redeploy-unreachable-warning"; export const Deployments = () => { const { id, @@ -23,6 +27,7 @@ export const Deployments = () => { servicesData, refreshServices, hasMultipleServices, + domainsData, } = useProjectSettings(); const { t } = useI18n(); const { showToast } = useToast(); @@ -179,8 +184,10 @@ export const Deployments = () => { if (hasMultipleServices) { const services = servicesData.services.length > 0 ? servicesData.services : await refreshServices(); - if (shouldWarnAboutUnreachableServices(services)) { - const candidateServices = services.filter(isPotentiallyPublicService); + if (shouldWarnAboutUnreachableServices(services, domainsData.domains)) { + const candidateServices = services.filter( + (s) => isPotentiallyPublicService(s) && !hasConnectedDomain(s, domainsData.domains), + ); let modalId = ""; modalId = showModal({ customContent: ( @@ -200,10 +207,10 @@ export const Deployments = () => { className="rounded-lg bg-foreground/[0.06] px-3 py-1.5 text-[12px] font-medium text-foreground transition-colors hover:bg-foreground/[0.1]" onClick={() => { hideModal(modalId); - setActiveTab("services"); + setActiveTab("domains"); }} > - {t.projects.redeploy.openServices} + {t.projects.redeploy.openDomains ?? t.projects.redeploy.openServices}