Files
supabase/apps/studio/components/interfaces/Database/Replication/PipelineStatePill.tsx
Danny White a4be167491 fix(studio): clarify Warehouse status and navigation (#50554)
## What kind of change does this PR introduce?

Bug fix and UI polish.

## What is the current behavior?

The Warehouse Connect option repeats its own name, and a configured
Warehouse has no direct route back to its management page. Warehouse
table states also use badges instead of the status-dot pattern used by
Replication, and a backfilling table can misleadingly appear as “Caught
up”.

## What is the new behavior?

- Describes Warehouse as an analytical endpoint and adds a low-emphasis
“Manage Warehouse” link from the Connect sheet.
- Shares Replication’s status-dot presentation with Warehouse while
keeping feature-specific state mapping separate.
- Shows replication lag only for live tables, so backfilling and “Caught
up” are never presented together.

| Before | After |
| --- | --- |
| <img width="1244" height="1156" alt="CleanShot 2026-09-18 at 14 03
49@2x"
src="https://github.com/user-attachments/assets/60aa3496-6930-491a-af9e-9ffcfb035a0f"
/> | <img width="1216" height="1214" alt="CleanShot 2026-09-18 at 14 04
33@2x"
src="https://github.com/user-attachments/assets/84a8c80e-d8d1-4ee5-9cce-352d1f6477c2"
/> |
| <img width="1314" height="1414" alt="CleanShot 2026-09-18 at 14 02
50@2x"
src="https://github.com/user-attachments/assets/8871a4a5-0543-4290-91a7-9da949ec4c49"
/> | <img width="1308" height="1498" alt="CleanShot 2026-09-18 at 14 02
43@2x"
src="https://github.com/user-attachments/assets/ac3fc6d1-5b4d-4a3a-8ab7-bb54025e2145"
/> |

## To test

1. Open `/project/<ref>?showConnect=true&connectTab=warehouse` for a
project with Warehouse configured. Confirm the mode subtitle says
“Analytical endpoint”. Confirm the new “Manage Warehouse” button opens
`/project/<ref>/integrations/warehouse/overview`.
2. Open `/project/<ref>/integrations/warehouse/overview` while a table
is backfilling. Confirm it has a pulsing amber status dot and does not
show “Caught up”.
3. Once the table is live, confirm it has a green “Live” status dot and
its lag appears normally.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Added clearer Warehouse setup progress messaging with a “View
progress” action while setup is running.
- Connection details are shown once the Warehouse is provisioned or has
live tables.
- Added a Cancel action when editing changed Warehouse table selections.
- Updated table statuses with live, syncing, and warning indicators,
including animated syncing states.
  - Lag details are displayed for live tables when available.
  - Renamed the Warehouse connection option to “Analytical endpoint.”

- **Style**
  - Improved Warehouse management controls and table name readability.
  - Removed the table Size column from the Warehouse overview.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-09-22 12:21:40 +10:00

92 lines
3.1 KiB
TypeScript

import { cn, Tooltip, TooltipContent, TooltipTrigger } from 'ui'
import { ShimmeringLoader } from 'ui-patterns/ShimmeringLoader'
import { TOOLTIP_UNDERLINE_CLASS_NAME } from './DetailSubtext'
import { getPipelineDisplayState, getStatusName } from './Pipeline.utils'
import type { PipelineDisplayType } from './Pipeline.utils'
import { PipelineStatusName } from './Replication.constants'
import { StateDot, type StateDotVariant } from '@/components/ui/StateDot'
import { ReplicationPipelineStatusData } from '@/data/replication/pipeline-status-query'
import { PipelineStatusRequestStatus } from '@/state/replication-pipeline-request-status'
import type { ResponseError } from '@/types'
const VARIANT_BY_TYPE: Record<PipelineDisplayType, StateDotVariant> = {
success: 'success',
failure: 'destructive',
loading: 'warning',
idle: 'default',
}
interface PipelineStatePillProps {
pipelineStatus: ReplicationPipelineStatusData['status'] | undefined
error: ResponseError | null
isLoading: boolean
isError: boolean
isSuccess: boolean
requestStatus: PipelineStatusRequestStatus
projectRef?: string
pipelineId?: number
}
/**
* Status of a pipeline as a dot and label. The label carries a dotted underline because its
* explanation lives in the tooltip. Tooltips stay plain text (no links).
*/
export const PipelineStatePill = ({
pipelineStatus,
error,
isLoading,
isError,
isSuccess,
requestStatus,
}: PipelineStatePillProps) => {
const statusName = getStatusName(pipelineStatus)
const { type, message, label } = getPipelineDisplayState(requestStatus, statusName)
const isRequestPending = requestStatus !== PipelineStatusRequestStatus.None
const shouldShowError = isError && !isRequestPending
const shouldShowLogsHint =
isSuccess &&
!isRequestPending &&
[PipelineStatusName.UNKNOWN, PipelineStatusName.FAILED].includes(
statusName as PipelineStatusName
)
if (isLoading && !isRequestPending) {
return (
<span className="inline-flex" aria-live="polite" aria-atomic="true">
<span className="sr-only">Loading pipeline status</span>
<ShimmeringLoader className="w-20" />
</span>
)
}
let tooltipMessage = message
if (shouldShowError) {
tooltipMessage = `Unable to retrieve status: ${error?.message}`
} else if (shouldShowLogsHint) {
tooltipMessage = `${message}. Check the logs for more information.`
}
return (
<span className="inline-flex" aria-live="polite" aria-atomic="true">
<Tooltip>
<TooltipTrigger asChild>
<StateDot
tabIndex={0}
variant={shouldShowError ? 'default' : VARIANT_BY_TYPE[type]}
isPulsing={!shouldShowError && type === 'loading'}
labelClassName={cn('text-foreground-light', TOOLTIP_UNDERLINE_CLASS_NAME)}
>
{shouldShowError ? 'Unknown' : label}
</StateDot>
</TooltipTrigger>
<TooltipContent side="bottom" className="max-w-xs">
{tooltipMessage}
{isError && isRequestPending && ` Unable to refresh status: ${error?.message}.`}
</TooltipContent>
</Tooltip>
</span>
)
}