mirror of
https://github.com/supabase/supabase.git
synced 2026-10-14 05:39:11 +03:00
Fix
This commit is contained in:
6 files changed
+66
-29
No files matched your search
@@ -11,12 +11,9 @@ import {
|
||||
PipelineStatusRequestStatus,
|
||||
usePipelineRequestStatus,
|
||||
} from 'state/replication-pipeline-request-status'
|
||||
import { getStatusName } from './Pipeline.utils'
|
||||
import { getStatusName, PIPELINE_ERROR_MESSAGES } from './Pipeline.utils'
|
||||
import { useParams } from 'common'
|
||||
import {
|
||||
ReplicationPipelineStatusData,
|
||||
useReplicationPipelineStatusQuery,
|
||||
} from 'data/replication/pipeline-status-query'
|
||||
import { useReplicationPipelineStatusQuery } from 'data/replication/pipeline-status-query'
|
||||
import { useState, useEffect } from 'react'
|
||||
import { toast } from 'sonner'
|
||||
import { useStartPipelineMutation } from 'data/replication/start-pipeline-mutation'
|
||||
@@ -96,14 +93,14 @@ const DestinationRow = ({
|
||||
return
|
||||
}
|
||||
if (!pipeline) {
|
||||
toast.error('No pipeline found')
|
||||
toast.error(PIPELINE_ERROR_MESSAGES.NO_PIPELINE_FOUND)
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
await startPipeline({ projectRef, pipelineId: pipeline.id })
|
||||
} catch (error) {
|
||||
toast.error('Failed to enable destination')
|
||||
toast.error(PIPELINE_ERROR_MESSAGES.ENABLE_DESTINATION)
|
||||
}
|
||||
setGlobalRequestStatus(pipeline.id, PipelineStatusRequestStatus.EnableRequested)
|
||||
}
|
||||
@@ -113,14 +110,14 @@ const DestinationRow = ({
|
||||
return
|
||||
}
|
||||
if (!pipeline) {
|
||||
toast.error('No pipeline found')
|
||||
toast.error(PIPELINE_ERROR_MESSAGES.NO_PIPELINE_FOUND)
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
await stopPipeline({ projectRef, pipelineId: pipeline.id })
|
||||
} catch (error) {
|
||||
toast.error('Failed to disable destination')
|
||||
toast.error(PIPELINE_ERROR_MESSAGES.DISABLE_DESTINATION)
|
||||
}
|
||||
setGlobalRequestStatus(pipeline.id, PipelineStatusRequestStatus.DisableRequested)
|
||||
}
|
||||
@@ -132,7 +129,7 @@ const DestinationRow = ({
|
||||
return
|
||||
}
|
||||
if (!pipeline) {
|
||||
toast.error('No pipeline found')
|
||||
toast.error(PIPELINE_ERROR_MESSAGES.NO_PIPELINE_FOUND)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -142,14 +139,14 @@ const DestinationRow = ({
|
||||
// so we don't need to call deletePipeline explicitly
|
||||
await deleteDestination({ projectRef, destinationId: destinationId })
|
||||
} catch (error) {
|
||||
toast.error('Failed to delete destination')
|
||||
toast.error(PIPELINE_ERROR_MESSAGES.DELETE_DESTINATION)
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{isPipelineError && (
|
||||
<AlertError error={pipelineError} subject="Failed to retrieve pipeline" />
|
||||
<AlertError error={pipelineError} subject={PIPELINE_ERROR_MESSAGES.RETRIEVE_PIPELINE} />
|
||||
)}
|
||||
{isPipelineSuccess && (
|
||||
<Table.tr>
|
||||
|
||||
@@ -11,6 +11,7 @@ import { useState } from 'react'
|
||||
import NewDestinationPanel from './DestinationPanel'
|
||||
import { useReplicationSourcesQuery } from 'data/replication/sources-query'
|
||||
import { noop } from 'lodash'
|
||||
import { PIPELINE_ERROR_MESSAGES } from './Pipeline.utils'
|
||||
|
||||
interface DestinationsProps {
|
||||
onSelectPipeline?: (pipelineId: number, destinationName: string) => void
|
||||
@@ -92,7 +93,7 @@ const Destinations = ({ onSelectPipeline = noop }: DestinationsProps) => {
|
||||
{(isSourcesError || isDestinationsError) && (
|
||||
<AlertError
|
||||
error={sourcesError || destinationsError}
|
||||
subject="Failed to retrieve destinations"
|
||||
subject={PIPELINE_ERROR_MESSAGES.RETRIEVE_DESTINATIONS}
|
||||
/>
|
||||
)}
|
||||
|
||||
|
||||
@@ -1,6 +1,19 @@
|
||||
import { ReplicationPipelineStatusData } from 'data/replication/pipeline-status-query'
|
||||
import { PipelineStatusRequestStatus } from 'state/replication-pipeline-request-status'
|
||||
|
||||
// Shared error messages for consistency
|
||||
export const PIPELINE_ERROR_MESSAGES = {
|
||||
RETRIEVE_PIPELINE: 'Failed to retrieve pipeline information',
|
||||
RETRIEVE_PIPELINE_STATUS: 'Failed to retrieve pipeline status',
|
||||
RETRIEVE_REPLICATION_STATUS: 'Failed to retrieve table replication status',
|
||||
RETRIEVE_DESTINATIONS: 'Failed to retrieve destinations',
|
||||
ENABLE_DESTINATION: 'Failed to enable destination',
|
||||
DISABLE_DESTINATION: 'Failed to disable destination',
|
||||
DELETE_DESTINATION: 'Failed to delete destination',
|
||||
NO_PIPELINE_FOUND: 'No pipeline found',
|
||||
COPY_TABLE_STATUS: 'Failed to copy table status',
|
||||
} as const
|
||||
|
||||
export const getStatusName = (
|
||||
status: ReplicationPipelineStatusData['status'] | undefined
|
||||
): string | undefined => {
|
||||
@@ -37,6 +50,11 @@ export const PIPELINE_STATE_MESSAGES = {
|
||||
message: 'Initializing replication. Table status will be available once running.',
|
||||
badge: 'Starting',
|
||||
},
|
||||
running: {
|
||||
title: 'Pipeline Running',
|
||||
message: 'Replication is active and processing data',
|
||||
badge: 'Running',
|
||||
},
|
||||
unknown: {
|
||||
title: 'Pipeline Status Unknown',
|
||||
message: 'Unable to determine replication status. Check the logs for more information.',
|
||||
@@ -49,7 +67,6 @@ export const PIPELINE_STATE_MESSAGES = {
|
||||
},
|
||||
} as const
|
||||
|
||||
// Helper to get consistent state messages based on request status and pipeline status
|
||||
export const getPipelineStateMessages = (
|
||||
requestStatus: PipelineStatusRequestStatus | undefined,
|
||||
statusName: string | undefined
|
||||
@@ -71,6 +88,8 @@ export const getPipelineStateMessages = (
|
||||
return PIPELINE_STATE_MESSAGES.stopped
|
||||
case 'starting':
|
||||
return PIPELINE_STATE_MESSAGES.starting
|
||||
case 'started':
|
||||
return PIPELINE_STATE_MESSAGES.running
|
||||
case 'unknown':
|
||||
return PIPELINE_STATE_MESSAGES.unknown
|
||||
default:
|
||||
|
||||
@@ -6,7 +6,11 @@ import { Loader2, AlertTriangle } from 'lucide-react'
|
||||
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from 'ui'
|
||||
import { ReplicationPipelineStatusData } from 'data/replication/pipeline-status-query'
|
||||
import { PipelineStatusRequestStatus } from 'state/replication-pipeline-request-status'
|
||||
import { PIPELINE_STATE_MESSAGES } from './Pipeline.utils'
|
||||
import {
|
||||
getPipelineStateMessages,
|
||||
PIPELINE_STATE_MESSAGES,
|
||||
PIPELINE_ERROR_MESSAGES,
|
||||
} from './Pipeline.utils'
|
||||
|
||||
export enum PipelineStatusName {
|
||||
FAILED = 'failed',
|
||||
@@ -58,7 +62,7 @@ const PipelineStatus = ({
|
||||
</div>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>
|
||||
<p>{PIPELINE_STATE_MESSAGES.failed.message}</p>
|
||||
<p>{getPipelineStateMessages(requestStatus, 'failed').message}</p>
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
</TooltipProvider>
|
||||
@@ -66,12 +70,20 @@ const PipelineStatus = ({
|
||||
}
|
||||
// Map backend statuses to UX-friendly display
|
||||
const getStatusConfig = () => {
|
||||
const statusName =
|
||||
pipelineStatus && typeof pipelineStatus === 'object' && 'name' in pipelineStatus
|
||||
? pipelineStatus.name
|
||||
: undefined
|
||||
|
||||
// Get consistent tooltip message using the same logic as other components
|
||||
const stateMessages = getPipelineStateMessages(requestStatus, statusName)
|
||||
|
||||
if (requestStatus === PipelineStatusRequestStatus.EnableRequested) {
|
||||
return {
|
||||
label: 'Enabling...',
|
||||
dot: <Loader2 className="animate-spin w-3 h-3 text-brand-600" />,
|
||||
color: 'text-brand-600',
|
||||
tooltip: PIPELINE_STATE_MESSAGES.enabling.message,
|
||||
tooltip: stateMessages.message,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,7 +92,7 @@ const PipelineStatus = ({
|
||||
label: 'Disabling...',
|
||||
dot: <Loader2 className="animate-spin w-3 h-3 text-warning-600" />,
|
||||
color: 'text-warning-600',
|
||||
tooltip: PIPELINE_STATE_MESSAGES.disabling.message,
|
||||
tooltip: stateMessages.message,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,35 +110,35 @@ const PipelineStatus = ({
|
||||
label: 'Starting',
|
||||
dot: <Loader2 className="animate-spin w-3 h-3 text-warning-600" />,
|
||||
color: 'text-warning-600',
|
||||
tooltip: PIPELINE_STATE_MESSAGES.starting.message,
|
||||
tooltip: stateMessages.message,
|
||||
}
|
||||
case PipelineStatusName.STARTED:
|
||||
return {
|
||||
label: 'Running',
|
||||
dot: <div className="w-2 h-2 bg-brand-600 rounded-full" />,
|
||||
color: 'text-brand-600',
|
||||
tooltip: 'Replication is active and processing data',
|
||||
tooltip: stateMessages.message,
|
||||
}
|
||||
case PipelineStatusName.STOPPED:
|
||||
return {
|
||||
label: 'Stopped',
|
||||
dot: <div className="w-2 h-2 bg-foreground-lighter rounded-full" />,
|
||||
color: 'text-foreground-light',
|
||||
tooltip: PIPELINE_STATE_MESSAGES.stopped.message,
|
||||
tooltip: stateMessages.message,
|
||||
}
|
||||
case PipelineStatusName.UNKNOWN:
|
||||
return {
|
||||
label: 'Unknown',
|
||||
dot: <div className="w-2 h-2 bg-warning-600 rounded-full" />,
|
||||
color: 'text-warning-600',
|
||||
tooltip: PIPELINE_STATE_MESSAGES.unknown.message,
|
||||
tooltip: stateMessages.message,
|
||||
}
|
||||
default:
|
||||
return {
|
||||
label: 'Unknown',
|
||||
dot: <div className="w-2 h-2 bg-destructive-600 rounded-full" />,
|
||||
color: 'text-destructive-600',
|
||||
tooltip: PIPELINE_STATE_MESSAGES.unknown.message,
|
||||
tooltip: stateMessages.message,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -145,7 +157,9 @@ const PipelineStatus = ({
|
||||
return (
|
||||
<>
|
||||
{isLoading && <ShimmeringLoader></ShimmeringLoader>}
|
||||
{isError && <AlertError error={error} subject="Failed to retrieve pipeline status" />}
|
||||
{isError && (
|
||||
<AlertError error={error} subject={PIPELINE_ERROR_MESSAGES.RETRIEVE_PIPELINE_STATUS} />
|
||||
)}
|
||||
{isSuccess && (
|
||||
<>
|
||||
{statusConfig.isFailedStatus ? (
|
||||
|
||||
+7
-4
@@ -9,7 +9,7 @@ import {
|
||||
usePipelineRequestStatus,
|
||||
PipelineStatusRequestStatus,
|
||||
} from 'state/replication-pipeline-request-status'
|
||||
import { getStatusName, getPipelineStateMessages } from './Pipeline.utils'
|
||||
import { getStatusName, getPipelineStateMessages, PIPELINE_ERROR_MESSAGES } from './Pipeline.utils'
|
||||
import { useState, useEffect } from 'react'
|
||||
import {
|
||||
Button,
|
||||
@@ -116,7 +116,7 @@ const ReplicationPipelineStatus = ({
|
||||
await copyToClipboard(statusText)
|
||||
toast.success('Table status copied to clipboard')
|
||||
} catch {
|
||||
toast.error('Failed to copy table status')
|
||||
toast.error(PIPELINE_ERROR_MESSAGES.COPY_TABLE_STATUS)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -255,7 +255,7 @@ const ReplicationPipelineStatus = ({
|
||||
<h3 className="text-xl font-semibold">Pipeline Status</h3>
|
||||
</div>
|
||||
</div>
|
||||
<AlertError error={pipelineError} subject="Failed to retrieve pipeline details" />
|
||||
<AlertError error={pipelineError} subject={PIPELINE_ERROR_MESSAGES.RETRIEVE_PIPELINE} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -305,7 +305,10 @@ const ReplicationPipelineStatus = ({
|
||||
{(isPipelineLoading || isStatusLoading) && <GenericSkeletonLoader />}
|
||||
|
||||
{isStatusError && (
|
||||
<AlertError error={statusError} subject="Failed to retrieve table replication status" />
|
||||
<AlertError
|
||||
error={statusError}
|
||||
subject={PIPELINE_ERROR_MESSAGES.RETRIEVE_REPLICATION_STATUS}
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* Error alert */}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import AlertError from 'components/ui/AlertError'
|
||||
import { PIPELINE_ERROR_MESSAGES } from './Pipeline.utils'
|
||||
import { Edit, MoreVertical, Pause, Play, Trash } from 'lucide-react'
|
||||
import { ResponseError } from 'types'
|
||||
import {
|
||||
@@ -46,7 +47,9 @@ const RowMenu = ({
|
||||
return (
|
||||
<div className="flex justify-end items-center space-x-2">
|
||||
{isLoading && <ShimmeringLoader></ShimmeringLoader>}
|
||||
{isError && <AlertError error={error} subject="Failed to retrieve pipeline status" />}
|
||||
{isError && (
|
||||
<AlertError error={error} subject={PIPELINE_ERROR_MESSAGES.RETRIEVE_PIPELINE_STATUS} />
|
||||
)}
|
||||
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
|
||||
Reference in new issue
Block a user