UsersGridComponents.tsx 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. import { ChevronDown, SortAsc, SortDesc } from 'lucide-react'
  2. import { useEffect, useRef, useState } from 'react'
  3. import { useHeaderRowSelection } from 'react-data-grid'
  4. import {
  5. Button,
  6. DropdownMenu,
  7. DropdownMenuContent,
  8. DropdownMenuItem,
  9. DropdownMenuTrigger,
  10. } from 'ui'
  11. // [Joshen] Currently not being used, refer to Users.utils -> formatUserColumns for more info
  12. export const SelectHeaderCell = ({
  13. selectedUsers,
  14. allRowsSelected,
  15. }: {
  16. selectedUsers: Set<any>
  17. allRowsSelected: boolean
  18. }) => {
  19. const inputRef = useRef<HTMLInputElement>(null)
  20. const { isRowSelected, onRowSelectionChange } = useHeaderRowSelection()
  21. const isIndeterminate = selectedUsers.size > 0 && !allRowsSelected
  22. useEffect(() => {
  23. if (inputRef.current) inputRef.current.indeterminate = isIndeterminate
  24. }, [isIndeterminate])
  25. return (
  26. <div className="px-4 flex items-center sb-grid">
  27. <div className="sb-grid-select-cell__header">
  28. <input
  29. ref={inputRef}
  30. type="checkbox"
  31. aria-label="Select-all"
  32. className="sb-grid-select-cell__header__input"
  33. disabled={false}
  34. checked={isRowSelected}
  35. onChange={(e) => onRowSelectionChange({ checked: e.target.checked })}
  36. />
  37. </div>
  38. </div>
  39. )
  40. }
  41. export const HeaderCell = ({
  42. col,
  43. specificFilterColumn,
  44. setSortByValue,
  45. }: {
  46. col: any
  47. specificFilterColumn: string
  48. setSortByValue: (value: string) => void
  49. }) => {
  50. const ref = useRef<number>(0)
  51. const [open, setOpen] = useState(false)
  52. useEffect(() => {
  53. ref.current = Number(new Date())
  54. }, [open])
  55. return (
  56. <div className="flex items-center justify-between font-normal text-xs w-full">
  57. <div className="flex items-center gap-x-2">
  58. <p className="text-foreground!">{col.name}</p>
  59. </div>
  60. {specificFilterColumn === 'freeform' && ['created_at', 'email', 'phone'].includes(col.id) && (
  61. <DropdownMenu
  62. open={open}
  63. onOpenChange={(val) => {
  64. // [Joshen] This is a temp hack between the DropdownMenu and react data grid
  65. // as the header cell is selectable, which takes the focus away from the dropdown menu
  66. // causing it to close immediately.
  67. if (val === false && Number(new Date()) - ref.current > 100) setOpen(val)
  68. }}
  69. >
  70. <DropdownMenuTrigger asChild>
  71. <Button
  72. type="text"
  73. icon={<ChevronDown />}
  74. className="p-0 h-5 w-5"
  75. onClick={() => setOpen(!open)}
  76. />
  77. </DropdownMenuTrigger>
  78. <DropdownMenuContent className="w-36">
  79. <DropdownMenuItem
  80. className="flex items-center gap-x-2"
  81. onClick={() => {
  82. setOpen(false)
  83. setSortByValue(`${col.id}:desc`)
  84. }}
  85. >
  86. <SortDesc size={14} />
  87. Sort descending
  88. </DropdownMenuItem>
  89. <DropdownMenuItem
  90. className="flex items-center gap-x-2"
  91. onClick={() => {
  92. setOpen(false)
  93. setSortByValue(`${col.id}:asc`)
  94. }}
  95. >
  96. <SortAsc size={14} />
  97. Sort ascending
  98. </DropdownMenuItem>
  99. </DropdownMenuContent>
  100. </DropdownMenu>
  101. )}
  102. </div>
  103. )
  104. }