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  }