ValidationFailuresSection.tsx 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. import { Accordion, AccordionContent, AccordionItem, AccordionTrigger, Badge, Card } from 'ui'
  2. import { Admonition } from 'ui-patterns'
  3. import type { ValidationFailure } from '@/data/replication/validate-destination-mutation'
  4. interface ValidationFailuresSectionProps {
  5. destinationFailures: ValidationFailure[]
  6. pipelineFailures: ValidationFailure[]
  7. }
  8. export const ValidationFailuresSection = ({
  9. destinationFailures,
  10. pipelineFailures,
  11. }: ValidationFailuresSectionProps) => {
  12. const validationIssues = [...destinationFailures, ...pipelineFailures].sort((a, _b) =>
  13. a.failure_type === 'critical' ? -1 : 1
  14. )
  15. const criticalFailures = validationIssues.filter((f) => f.failure_type === 'critical')
  16. const warnings = validationIssues.filter((f) => f.failure_type === 'warning')
  17. const hasCriticalFailures = criticalFailures.length > 0
  18. const hasWarnings = warnings.length > 0
  19. if (validationIssues.length === 0) {
  20. return null
  21. }
  22. return (
  23. <Admonition
  24. type={hasCriticalFailures ? 'warning' : 'default'}
  25. className="px-5 rounded-none border-0"
  26. title="Destination configuration issues"
  27. >
  28. <p className="text-sm text-foreground-light mb-2!">
  29. {hasCriticalFailures
  30. ? `Please fix all required issues below${hasWarnings ? ' and review the others' : ''} before continuing.`
  31. : 'The following issues were identified, although you may still proceed to create the destination.'}
  32. </p>
  33. <Card>
  34. <Accordion type="multiple">
  35. {validationIssues.map((failure, idx) => (
  36. <AccordionItem key={idx} value={`${failure.name}+${idx}`} className="last:border-b-0">
  37. <AccordionTrigger className="text-sm px-3 text-foreground decoration-foreground-lighter">
  38. <p className="flex items-center gap-x-2">
  39. {failure.name}
  40. {failure.failure_type === 'critical' && <Badge variant="warning">Required</Badge>}
  41. </p>
  42. </AccordionTrigger>
  43. <AccordionContent className="px-3">
  44. <p className="whitespace-pre-wrap text-sm">
  45. {failure.reason.replaceAll('\n\n', '\n')}
  46. </p>
  47. </AccordionContent>
  48. </AccordionItem>
  49. ))}
  50. </Accordion>
  51. </Card>
  52. </Admonition>
  53. )
  54. }