ErroredTableDetails.tsx 3.2 KB

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