ErroredTableDetails.tsx78 lines · main
1import { useParams } from 'common'
2import { CriticalIcon } from 'ui'
3
4import { isValidRetryPolicy } from './ReplicationPipelineStatus/ReplicationPipelineStatus.utils'
5import { RetryCountdown } from './RetryCountdown'
6import { InlineLink } from '@/components/ui/InlineLink'
7import { ReplicationPipelineTableStatus } from '@/data/replication/pipeline-replication-status-query'
8
9interface ErroredTableDetailsProps {
10 table: ReplicationPipelineTableStatus
11}
12
13export const ErroredTableDetails = ({ table }: ErroredTableDetailsProps) => {
14 const { ref: projectRef } = useParams()
15
16 const state = table.state as Extract<ReplicationPipelineTableStatus['state'], { name: 'error' }>
17 const tableName = table.table_name
18 const retryPolicy = state.retry_policy.policy
19
20 if (!isValidRetryPolicy(state.retry_policy)) {
21 return (
22 <div
23 role="region"
24 className="flex flex-col gap-y-3"
25 aria-label={`Error details for table ${tableName}`}
26 >
27 {state.solution && <div className="text-xs text-foreground-light">{state.solution}</div>}
28 <div className="text-xs text-foreground-lighter">Invalid retry policy configuration</div>
29 </div>
30 )
31 }
32
33 return (
34 <div role="region" aria-label={`Error details for table ${tableName}`}>
35 {retryPolicy === 'no_retry' ? (
36 <div className="flex flex-col gap-y-3">
37 <p className="text-xs text-foreground-lighter">
38 This error requires manual intervention from our{' '}
39 <InlineLink
40 className="text-foreground-lighter hover:text-foreground"
41 href={`/support?projectRef=${projectRef}&category=dashboard_bug&subject=Database%20replication%20error&error=${encodeURIComponent(state.reason ?? '')}`}
42 >
43 support
44 </InlineLink>
45 . Alternatively, you may also recreate the pipeline. Use the table actions menu on the
46 right to view the full error details.
47 </p>
48 </div>
49 ) : retryPolicy === 'manual_retry' ? (
50 <div className="flex flex-col gap-y-3">
51 <div className="rounded-md border border-destructive-400 bg-destructive-100 px-3 py-3 space-y-2">
52 <div className="flex items-start gap-x-2">
53 <CriticalIcon />
54 <div className="flex-1 text-xs text-destructive-900">
55 <p className="font-semibold mb-1">Action required to continue replication</p>
56 <p className="text-foreground-light">
57 {state.solution}
58 {state.solution && !/[.!?]$/.test(state.solution.trim()) && '.'}
59 </p>
60 <p className="text-foreground-light mt-2">
61 Restart table replication from the table actions menu on the right. The pipeline
62 will restart automatically.
63 </p>
64 </div>
65 </div>
66 </div>
67 </div>
68 ) : retryPolicy === 'timed_retry' ? (
69 <div className="flex flex-col text-foreground-lighter gap-y-3">
70 <p className="text-xs">
71 Replication will retry automatically. The pipeline will restart to apply the retry.
72 </p>
73 <RetryCountdown nextRetryTime={state.retry_policy.next_retry} />
74 </div>
75 ) : null}
76 </div>
77 )
78}