SandboxManagement.tsx 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. import { Box, Loader2, LogOut, RefreshCw } from 'lucide-react'
  2. import { Badge, Button } from 'ui'
  3. import { Admonition } from 'ui-patterns'
  4. import { ButtonTooltip } from '@/components/ui/ButtonTooltip'
  5. import { usePostgresSandbox } from '@/state/postgres-sandbox/sandbox'
  6. export const SandboxManagement = () => {
  7. const { status, error, isSyncing, startSandbox, destroySandbox, syncSandbox } =
  8. usePostgresSandbox()
  9. if (status === 'idle') {
  10. return (
  11. <Admonition
  12. type="default"
  13. layout="horizontal"
  14. className="min-h-min border-none [&>div>div>div>div>p]:!mb-0"
  15. actions={[
  16. <Button key="set-up" type="default" onClick={() => startSandbox()}>
  17. Set up sandbox
  18. </Button>,
  19. ]}
  20. >
  21. <div className="flex items-center gap-x-2">
  22. <p className="text-foreground !m-0">Set up sandbox for testing</p>
  23. <Badge variant="success">Recommended</Badge>
  24. </div>
  25. <p className="text-foreground-light !m-0">
  26. Ensure that queries do not affect your actual database
  27. </p>
  28. </Admonition>
  29. )
  30. }
  31. if (status === 'loading') {
  32. return (
  33. <Admonition
  34. showIcon={false}
  35. type="default"
  36. className="min-h-min border-none py-2 [&>div>div]:flex [&>div>div]:items-center [&>div>div]:justify-between"
  37. >
  38. <div className="flex items-center gap-x-3">
  39. <div className="bg w-6 h-6 rounded border border-border flex items-center justify-center">
  40. <Loader2 size={14} className="animate-spin" />
  41. </div>
  42. <p className="text-xs !mb-0 font-mono uppercase tracking-tight">Setting up sandbox</p>
  43. </div>
  44. </Admonition>
  45. )
  46. }
  47. if (status === 'error') {
  48. return (
  49. <Admonition
  50. type="warning"
  51. layout="horizontal"
  52. title="Unable to set up sandbox"
  53. description={error ?? 'Please try again'}
  54. className="min-h-min border-none"
  55. actions={[
  56. <Button key="set-up" type="default" onClick={() => startSandbox()}>
  57. Retry set up
  58. </Button>,
  59. ]}
  60. />
  61. )
  62. }
  63. return (
  64. <Admonition
  65. showIcon={false}
  66. type="default"
  67. layout="horizontal"
  68. className="min-h-min border-none py-2 [&>div>div>div>div>p]:!mb-0 [&>div>div]:gap-x-2"
  69. actions={[
  70. <ButtonTooltip
  71. key="destroy"
  72. type="default"
  73. icon={<LogOut />}
  74. className="w-7"
  75. disabled={isSyncing}
  76. tooltip={{ content: { side: 'bottom', text: 'Exit sandbox' } }}
  77. onClick={() => destroySandbox()}
  78. />,
  79. <ButtonTooltip
  80. key="refresh"
  81. type="default"
  82. icon={<RefreshCw />}
  83. className="w-7"
  84. loading={isSyncing}
  85. tooltip={{ content: { side: 'bottom', text: 'Refresh schema' } }}
  86. onClick={() => syncSandbox()}
  87. />,
  88. ]}
  89. >
  90. <div className="flex items-center gap-x-3">
  91. <div className="bg-brand-300 w-6 h-6 rounded border border-brand-500 flex items-center justify-center">
  92. <Box size={14} className="text-brand" />
  93. </div>
  94. <p className="text-xs text-foreground font-mono uppercase tracking-tight">Sandbox active</p>
  95. <p className="text-xs text-foreground-lighter ">Your database is never modified</p>
  96. </div>
  97. </Admonition>
  98. )
  99. }