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