github.com/pyroscope-io/pyroscope@v0.37.3-0.20230725203016-5f6947968bd0/webapp/javascript/components/Settings/Users/getUserTableRows.tsx (about) 1 import React, { useState } from 'react'; 2 import type { ClickEvent } from '@webapp/ui/Menu'; 3 import { formatRelative } from 'date-fns'; 4 import { faTimes } from '@fortawesome/free-solid-svg-icons/faTimes'; 5 import { faCheck } from '@fortawesome/free-solid-svg-icons/faCheck'; 6 import { faToggleOff } from '@fortawesome/free-solid-svg-icons/faToggleOff'; 7 import { faToggleOn } from '@fortawesome/free-solid-svg-icons/faToggleOn'; 8 9 import Button from '@webapp/ui/Button'; 10 import Icon from '@webapp/ui/Icon'; 11 import Dropdown, { MenuItem } from '@webapp/ui/Dropdown'; 12 import { reloadUsers, changeUserRole } from '@webapp/redux/reducers/settings'; 13 import { useAppDispatch } from '@webapp/redux/hooks'; 14 import confirmDelete from '@webapp/components/Modals/ConfirmDelete'; 15 import type { User, Users } from '@webapp/models/users'; 16 import type { BodyRow } from '@webapp/ui/Table'; 17 import styles from './UserTableItem.module.css'; 18 19 function DisableButton(props: { onDisable: (user: User) => void; user: User }) { 20 const { user, onDisable } = props; 21 const icon = user.isDisabled ? faToggleOff : faToggleOn; 22 23 return ( 24 <Button type="button" kind="secondary" onClick={() => onDisable(user)}> 25 <Icon icon={icon} /> 26 </Button> 27 ); 28 } 29 30 function EditRoleDropdown({ user }: { user: User }) { 31 const { role } = user; 32 const dispatch = useAppDispatch(); 33 const [status, setStatus] = useState(false); 34 35 const handleEdit = (e: ClickEvent) => { 36 if (e.value !== user.role) { 37 dispatch(changeUserRole({ id: user.id, role: e.value })) 38 .unwrap() 39 .then(() => dispatch(reloadUsers())) 40 .then(() => setStatus(true)); 41 } 42 }; 43 44 return ( 45 <div className={styles.role}> 46 <Dropdown label={`Role ${role}`} value={role} onItemClick={handleEdit}> 47 <MenuItem value="Admin">Admin</MenuItem> 48 <MenuItem value="ReadOnly">Readonly</MenuItem> 49 </Dropdown> 50 {status ? <Icon icon={faCheck} /> : null} 51 </div> 52 ); 53 } 54 55 function DeleteButton(props: { onDelete: (user: User) => void; user: User }) { 56 const { onDelete, user } = props; 57 58 const handleDeleteClick = () => { 59 confirmDelete({ 60 objectName: user.name, 61 objectType: 'user', 62 onConfirm: () => onDelete(user), 63 }); 64 }; 65 66 return ( 67 <Button type="button" kind="danger" onClick={handleDeleteClick}> 68 <Icon icon={faTimes} /> 69 </Button> 70 ); 71 } 72 73 export function getUserTableRows( 74 currentUserId: number, 75 displayUsers: Users, 76 handleDisableUser: (user: User) => void, 77 handleDeleteUser: (user: User) => void 78 ): BodyRow[] { 79 const bodyRows = displayUsers.reduce((acc, user) => { 80 const { id, isDisabled, fullName, role, updatedAt, email, name } = user; 81 const isCurrent = id === currentUserId; 82 83 const row = { 84 isRowDisabled: isDisabled, 85 cells: [ 86 { value: id }, 87 { value: name }, 88 { value: email }, 89 { value: fullName }, 90 { value: isCurrent ? role : <EditRoleDropdown user={user} /> }, 91 { value: formatRelative(new Date(updatedAt), new Date()) }, 92 { 93 value: !isCurrent ? ( 94 <div className={styles.actions}> 95 <DisableButton user={user} onDisable={handleDisableUser} /> 96 <DeleteButton user={user} onDelete={handleDeleteUser} /> 97 </div> 98 ) : null, 99 align: 'center', 100 }, 101 ], 102 }; 103 104 acc.push(row); 105 return acc; 106 }, [] as BodyRow[]); 107 108 return bodyRows; 109 }