[FE-4184] fix(studio): hide view logs link for disabled services (#49487)

On Multigres/HA projects, Realtime is intentionally shown as
**Disabled** in the project home status hover card, but the row still
linked to logs with a "View logs" hover affordance and used the same
warning triangle as an unhealthy service. Disabled services now render
as a non-interactive row with a neutral "off" icon.

**Changed:**
- `ServiceStatus.tsx` – services with status `DISABLED` render a plain
`div` instead of a `Link` (no hover background, no "View logs" +
chevron). All other services keep the existing click-to-logs behavior.
- `DISABLED` services now show a muted `MinusCircle` icon instead of the
`AlertTriangle` used for unhealthy services, so "off" no longer reads as
"broken".
- "View logs" affordance is also revealed on keyboard focus
(`group-focus-visible`), not just hover.
- Applies to any `DISABLED` service, not just Realtime – PostgREST also
resolves to `DISABLED` when its `db_schema` is empty.

## To test

- Open the home page of a Multigres/HA project and hover the **Status**
stat to open the service hover card
- Realtime row shows a muted circle-minus icon with "Disabled", no hover
highlight and no "View logs" link
- Other rows (Database, Auth, Storage, etc.) still highlight on hover,
show "View logs" on hover or keyboard focus, and navigate to their logs
page on click
- Unhealthy services still show the warning triangle
- On a non-HA project, all rows (including Realtime) behave as before

Addresses FE-4184

---------

Co-authored-by: Alaister Young <10985857+alaister@users.noreply.github.com>
This commit is contained in:
Alaister YoungandAlaister Young authored and GitHub committed 2026-08-25 05:20:06 +00:00
1 parent f1526d2d1b
commit 002be81efb
1 file changed
+33 -14
@@ -1,6 +1,6 @@
import { useParams } from 'common'
import dayjs from 'dayjs'
import { AlertTriangle, CheckCircle2, ChevronRight, Loader2 } from 'lucide-react'
import { AlertTriangle, CheckCircle2, ChevronRight, Loader2, MinusCircle } from 'lucide-react'
import Link from 'next/link'
import { cn, HoverCard, HoverCardContent, HoverCardTrigger, InfoIcon } from 'ui'
@@ -21,6 +21,9 @@ import { DOCS_URL } from '@/lib/constants'
const SERVICE_STATUS_THRESHOLD = 5 // minutes
const SERVICE_ROW_CLASS =
'px-3 py-2 text-xs flex items-center justify-between border-b last:border-none'
const iconProps = {
size: 18,
strokeWidth: 1.5,
@@ -28,6 +31,7 @@ const iconProps = {
const LoaderIcon = () => <Loader2 {...iconProps} className="animate-spin" />
const AlertIcon = () => <AlertTriangle {...iconProps} />
const CheckIcon = () => <CheckCircle2 {...iconProps} className="text-brand" />
const DisabledIcon = () => <MinusCircle {...iconProps} className="text-foreground-lighter" />
export const StatusIcon = ({
isLoading,
@@ -40,7 +44,7 @@ export const StatusIcon = ({
}) => {
//
if (projectStatus === 'ACTIVE_HEALTHY') return <CheckIcon />
if (projectStatus === 'DISABLED') return <AlertIcon />
if (projectStatus === 'DISABLED') return <DisabledIcon />
if (projectStatus === 'COMING_UP') return <LoaderIcon />
if (isLoading) return <LoaderIcon />
// isProjectNew has to be above UNHEALTHY because in the first few minutes, some services might be starting up and show as UNHEALTHY
@@ -341,12 +345,8 @@ export const ServiceStatus = () => {
/>
</HoverCardTrigger>
<HoverCardContent className="p-0 w-60" side="bottom" align="start">
{services.map((service) => (
<Link
href={`/project/${ref}${service.logsUrl}`}
key={service.name}
className="transition px-3 py-2 text-xs flex items-center justify-between border-b last:border-none group relative hover:bg-surface-300"
>
{services.map((service) => {
const serviceInfo = (
<div className="flex gap-x-2">
<StatusIcon
isLoading={service.isLoading}
@@ -368,12 +368,31 @@ export const ServiceStatus = () => {
</p>
</div>
</div>
<div className="flex items-center gap-x-1 transition opacity-0 group-hover:opacity-100">
<span className="text-xs text-foreground">View logs</span>
<ChevronRight size={14} className="text-foreground" />
</div>
</Link>
))}
)
// Disabled services have no logs to link out to
if (service.status === 'DISABLED') {
return (
<div key={service.name} className={SERVICE_ROW_CLASS}>
{serviceInfo}
</div>
)
}
return (
<Link
href={`/project/${ref}${service.logsUrl}`}
key={service.name}
className={cn(SERVICE_ROW_CLASS, 'transition group relative hover:bg-surface-300')}
>
{serviceInfo}
<div className="flex items-center gap-x-1 transition opacity-0 group-hover:opacity-100 group-focus-visible:opacity-100">
<span className="text-xs text-foreground">View logs</span>
<ChevronRight size={14} className="text-foreground" />
</div>
</Link>
)
})}
{!allServicesOperational && (
<div className="flex gap-2 text-xs text-foreground-light px-3 py-2">
<div className="mt-0.5">