mirror of
https://github.com/supabase/supabase.git
synced 2026-07-03 23:54:20 +08:00
* feat(replication): Add new UI for new table state handling * Fix * Fix * Fix * Fix * Fix * Fix * Fix * Improve * Fix * Fix * Fix TS * Some UI tweaks * Tweaaakk * Fix semantics * Small optimization * Some adjustments * Bit more fixes * Small UI tweak to simplify UI * Fixy fix * gahhh tiny tiny tiny * Last bit of cleanup * I swear one final tweak --------- Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
123 lines
3.9 KiB
TypeScript
123 lines
3.9 KiB
TypeScript
import { ReplicationPipelineStatusData } from 'data/replication/pipeline-status-query'
|
|
import { Activity, Clock, HelpCircle, Loader2, XCircle } from 'lucide-react'
|
|
import { PipelineStatusRequestStatus } from 'state/replication-pipeline-request-status'
|
|
import { Badge } from 'ui'
|
|
import { getPipelineStateMessages } from './Pipeline.utils'
|
|
import { RetryPolicy, TableState } from './ReplicationPipelineStatus.types'
|
|
|
|
export const getStatusConfig = (state: TableState['state']) => {
|
|
switch (state.name) {
|
|
case 'queued':
|
|
return {
|
|
badge: <Badge variant="warning">Queued</Badge>,
|
|
description: 'Waiting to start replication',
|
|
color: 'text-warning-600',
|
|
}
|
|
case 'copying_table':
|
|
return {
|
|
badge: <Badge variant="brand">Copying</Badge>,
|
|
description: 'Initial data copy in progress',
|
|
color: 'text-brand-600',
|
|
}
|
|
case 'copied_table':
|
|
return {
|
|
badge: <Badge variant="success">Copied</Badge>,
|
|
description: 'Initial copy completed',
|
|
color: 'text-success-600',
|
|
}
|
|
case 'following_wal':
|
|
return {
|
|
badge: <Badge variant="success">Live</Badge>,
|
|
description: `Replicating live changes`,
|
|
color: 'text-success-600',
|
|
}
|
|
case 'error':
|
|
return {
|
|
badge: <Badge variant="destructive">Error</Badge>,
|
|
description: <pre className="text-xs font-mono">{state.reason}</pre>,
|
|
color: 'text-destructive-600',
|
|
}
|
|
default:
|
|
return {
|
|
badge: <Badge variant="warning">Unknown</Badge>,
|
|
description: 'Unknown status',
|
|
color: 'text-warning-600',
|
|
}
|
|
}
|
|
}
|
|
|
|
export const getDisabledStateConfig = ({
|
|
requestStatus,
|
|
statusName,
|
|
}: {
|
|
requestStatus: PipelineStatusRequestStatus
|
|
statusName?: ReplicationPipelineStatusData['status']['name']
|
|
}) => {
|
|
const { title, message, badge } = getPipelineStateMessages(requestStatus, statusName)
|
|
|
|
// Get icon and colors based on current state
|
|
const isEnabling = requestStatus === PipelineStatusRequestStatus.EnableRequested
|
|
const isDisabling = requestStatus === PipelineStatusRequestStatus.DisableRequested
|
|
const isTransitioning = isEnabling || isDisabling
|
|
|
|
const icon = isTransitioning ? (
|
|
<Loader2 className="w-6 h-6 animate-spin" />
|
|
) : statusName === 'failed' ? (
|
|
<XCircle className="w-6 h-6" />
|
|
) : statusName === 'starting' ? (
|
|
<Clock className="w-6 h-6" />
|
|
) : statusName === 'unknown' ? (
|
|
<HelpCircle className="w-6 h-6" />
|
|
) : (
|
|
<Activity className="w-6 h-6" />
|
|
)
|
|
|
|
const colors = isEnabling
|
|
? {
|
|
bg: 'bg-brand-50',
|
|
text: 'text-brand-900',
|
|
subtext: 'text-brand-700',
|
|
iconBg: 'bg-brand-600',
|
|
icon: 'text-white dark:text-black',
|
|
}
|
|
: isDisabling || statusName === 'starting' || statusName === 'unknown'
|
|
? {
|
|
bg: 'bg-warning-50',
|
|
text: 'text-warning-900',
|
|
subtext: 'text-warning-700',
|
|
iconBg: 'bg-warning-600',
|
|
icon: 'text-white dark:text-black',
|
|
}
|
|
: statusName === 'failed'
|
|
? {
|
|
bg: 'bg-destructive-50',
|
|
text: 'text-destructive-900',
|
|
subtext: 'text-destructive-700',
|
|
iconBg: 'bg-destructive-600',
|
|
icon: 'text-white dark:text-black',
|
|
}
|
|
: {
|
|
bg: 'bg-surface-100',
|
|
text: 'text-foreground',
|
|
subtext: 'text-foreground-light',
|
|
iconBg: 'bg-foreground-lighter',
|
|
icon: 'text-white dark:text-black',
|
|
}
|
|
|
|
return { title, message, badge, icon, colors }
|
|
}
|
|
|
|
export const isValidRetryPolicy = (policy: any): policy is RetryPolicy => {
|
|
if (!policy || typeof policy !== 'object' || !policy.policy) return false
|
|
|
|
switch (policy.policy) {
|
|
case 'no_retry':
|
|
case 'manual_retry':
|
|
return true
|
|
case 'timed_retry':
|
|
return typeof policy.next_retry === 'string'
|
|
default:
|
|
return false
|
|
}
|
|
}
|