ChartIntervalDropdown.tsx 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. import { ChevronDown } from 'lucide-react'
  2. import {
  3. Button,
  4. DropdownMenu,
  5. DropdownMenuContent,
  6. DropdownMenuRadioGroup,
  7. DropdownMenuRadioItem,
  8. DropdownMenuTrigger,
  9. Tooltip,
  10. TooltipContent,
  11. TooltipTrigger,
  12. } from 'ui'
  13. import { CHART_INTERVALS } from './logs.utils'
  14. import { InlineLink } from '@/components/ui/InlineLink'
  15. import { useCheckEntitlements } from '@/hooks/misc/useCheckEntitlements'
  16. function getDaysRequired(startValue: number, startUnit: string): number {
  17. if (startUnit === 'day') return startValue
  18. if (startUnit === 'hour') return startValue / 24
  19. return 0
  20. }
  21. interface ChartIntervalDropdownProps {
  22. value: string
  23. onChange: (value: string) => void
  24. organizationSlug?: string
  25. dropdownAlign?: 'start' | 'center' | 'end'
  26. tooltipSide?: 'left' | 'right' | 'top' | 'bottom'
  27. }
  28. export const ChartIntervalDropdown = ({
  29. value,
  30. onChange,
  31. organizationSlug,
  32. dropdownAlign = 'start',
  33. tooltipSide = 'right',
  34. }: ChartIntervalDropdownProps) => {
  35. const selectedInterval = CHART_INTERVALS.find((i) => i.key === value) || CHART_INTERVALS[1]
  36. const { getEntitlementMax } = useCheckEntitlements('log.retention_days')
  37. const retentionDays = getEntitlementMax()
  38. return (
  39. <DropdownMenu>
  40. <DropdownMenuTrigger asChild>
  41. <Button type="default" iconRight={<ChevronDown size={14} />}>
  42. <span>{selectedInterval.label}</span>
  43. </Button>
  44. </DropdownMenuTrigger>
  45. <DropdownMenuContent side="bottom" align={dropdownAlign} className="w-40">
  46. <DropdownMenuRadioGroup value={value} onValueChange={onChange}>
  47. {CHART_INTERVALS.map((i) => {
  48. const daysRequired = getDaysRequired(i.startValue, i.startUnit)
  49. const disabled = retentionDays !== undefined && daysRequired > retentionDays
  50. if (disabled) {
  51. return (
  52. <Tooltip key={i.key}>
  53. <TooltipTrigger asChild>
  54. <DropdownMenuRadioItem disabled value={i.key} className="pointer-events-auto!">
  55. {i.label}
  56. </DropdownMenuRadioItem>
  57. </TooltipTrigger>
  58. <TooltipContent side={tooltipSide}>
  59. <p>
  60. Your plan only includes up to {retentionDays} day
  61. {retentionDays !== undefined && retentionDays > 1 ? 's' : ''} of log retention
  62. </p>
  63. <p className="text-foreground-light">
  64. {organizationSlug ? (
  65. <>
  66. <InlineLink
  67. className="text-foreground-light hover:text-foreground"
  68. href={`/org/${organizationSlug}/billing?panel=subscriptionPlan`}
  69. >
  70. Upgrade your plan
  71. </InlineLink>{' '}
  72. to increase log retention and view statistics for the{' '}
  73. {i.label.toLowerCase()}
  74. </>
  75. ) : (
  76. `Upgrade your plan to increase log retention and view statistics for the ${i.label.toLowerCase()}`
  77. )}
  78. </p>
  79. </TooltipContent>
  80. </Tooltip>
  81. )
  82. } else {
  83. return (
  84. <DropdownMenuRadioItem key={i.key} value={i.key}>
  85. {i.label}
  86. </DropdownMenuRadioItem>
  87. )
  88. }
  89. })}
  90. </DropdownMenuRadioGroup>
  91. </DropdownMenuContent>
  92. </DropdownMenu>
  93. )
  94. }