@material-ui/core#TableSortLabel TypeScript Examples

The following examples show how to use @material-ui/core#TableSortLabel. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: TableHead.tsx    From frontegg-react with MIT License 5 votes vote down vote up
TableHead: FC<FeTableTHeadProps<any>> = <T extends object>(props: FeTableTHeadProps<T>) => {
  const {
    headerGroups,
    onSortChange,
    onFilterChange,
    toggleAllRowsSelected,
    selectedFlatRows,
    isAllRowsSelected,
  } = props;
  const classes = useStyles();

  return (
    <MaterialTableHead className={classes.head}>
      {headerGroups.map((headerGroup) => (
        <TableRow {...headerGroup.getHeaderGroupProps()}>
          {headerGroup.headers.map((c, index) => {
            const column = c as FeTableColumnProps<T>;
            if (column.id === 'fe-selection') {
              return (
                <TableCell {...column.getHeaderProps()}>
                  <Checkbox
                    className={classes.checkBox}
                    indeterminate={!isAllRowsSelected && (selectedFlatRows ?? []).length > 0}
                    checked={isAllRowsSelected}
                    onChange={() => toggleAllRowsSelected?.(!isAllRowsSelected)}
                  />
                </TableCell>
              );
            }
            const withExpander = headerGroup.headers[0].id === 'fe-expander';
            const tableCellProps = column.getHeaderProps(
              column.getSortByToggleProps((p: Partial<TableSortByToggleProps>) => ({
                ...p,
                onClick: column.canSort ? () => onSortChange?.(column) : undefined,
              }))
            );
            const minWidth = headerGroup.headers[0].minWidth || 0;
            const ownWidth = column.width || 0;
            const width = index === 1 && withExpander ? { width: Number(ownWidth) + minWidth, paddingLeft: 32 } : {};
            const cellStyle = { ...tableCellProps?.style, ...width };
            tableCellProps.className = classNames(tableCellProps.className, {
              [classes.firstHeadCell]: index === 0,
              [classes.expander]: index === 0 && withExpander,
            });
            return (
              <TableCell padding='default' {...tableCellProps} style={cellStyle}>
                <Box display='flex' alignItems='center' justifyContent='space-between' flexWrap='nowrap'>
                  <Box display='flex' flexGrow='1'>
                    {column.canSort ? (
                      <TableSortLabel
                        className='fe-sortLabel'
                        active={column.isSorted}
                        direction={column.isSortedDesc ? 'desc' : 'asc'}
                      >
                        {column.render('Header')}
                      </TableSortLabel>
                    ) : (
                      <>{column.render('Header')}</>
                    )}
                  </Box>
                  {column.canFilter && <TableFilterColumn column={column} onFilterChange={onFilterChange} />}
                </Box>
              </TableCell>
            );
          })}
        </TableRow>
      ))}
    </MaterialTableHead>
  );
}
Example #2
Source File: Pager.tsx    From glific-frontend with GNU Affero General Public License v3.0 5 votes vote down vote up
tableHeadColumns = (
  columnNames: Array<any>,
  columnStyles: any,
  tableVals: any,
  handleTableChange: Function,
  showCheckbox?: boolean,
  listName?: string,
  removeSortBy?: Array<any>
) => {
  let batchAction = null;
  if (showCheckbox) {
    batchAction = <Checkbox />;
  }
  return (
    <TableRow className={styles.TableHeadRow}>
      {batchAction}
      {columnNames.map((name: string, i: number) => (
        <TableCell
          key={name}
          className={`${styles.TableCell} ${columnStyles ? columnStyles[i] : null}`}
        >
          {i !== columnNames.length - 1 && name !== '' && !removeSortBy?.includes(name) ? (
            <TableSortLabel
              active={setColumnToBackendTerms(listName, name) === tableVals.sortCol}
              direction={tableVals.sortDirection}
              onClick={() => {
                if (setColumnToBackendTerms(listName, name) !== tableVals.sortCol) {
                  handleTableChange('sortCol', name);
                } else {
                  handleTableChange('sortCol', name);
                  handleTableChange(
                    'sortDirection',
                    tableVals.sortDirection === 'asc' ? 'desc' : 'asc'
                  );
                }
              }}
            >
              {name}
            </TableSortLabel>
          ) : (
            name
          )}
        </TableCell>
      ))}
    </TableRow>
  );
}
Example #3
Source File: DataTable.tsx    From interface-v2 with GNU General Public License v3.0 4 votes vote down vote up
DataTable: React.FC<DataTableProps<any>> = ({
  headCells,
  data,
  renderRow,
  toolbar,
  sortUpIcon,
  sortDownIcon,
  caption,
  defaultOrderBy = headCells[0],
  defaultOrder = 'asc',
  loading = false,
  isSinglelineHeader = false,
  size = 0,
  rowPerPage = 10,
  emptyMesage = 'No results.',
  showEmptyRows = true,
  showPagination,
}) => {
  const classes = useStyles({ isSinglelineHeader });
  const [order, setOrder] = useState<SortOrder>(defaultOrder);
  const [orderBy, setOrderBy] = useState<HeadCell<any>>(defaultOrderBy);
  const [page, setPage] = useState(0);
  const [rowsPerPage, setRowsPerPage] = useState(rowPerPage);
  const count = size || data.length;

  const handleRequestSort = (
    event: React.MouseEvent<unknown>,
    property: HeadCell<any>,
  ) => {
    const isAsc = orderBy.id === property.id && order === 'asc';
    setOrder(isAsc && !property.sortDisabled ? 'desc' : 'asc');
    setOrderBy(property);
  };

  const handleChangePage = (event: unknown, newPage: number) => {
    setPage(newPage);
  };

  const handleChangeRowsPerPage = (
    event: React.ChangeEvent<HTMLInputElement>,
  ) => {
    setRowsPerPage(parseInt(event.target.value, 10));
    setPage(0);
  };

  const emptyRows =
    rowsPerPage - Math.min(rowsPerPage, data.length - page * rowsPerPage);

  return (
    <Box>
      {toolbar}

      <TableContainer>
        <Table
          className={classes.table}
          aria-labelledby='tableTitle'
          size='medium'
          aria-label='enhanced table'
        >
          <TableHead>
            <TableRow>
              {headCells.map((headCell, index) => (
                <TableCell
                  className={headCell.buttonCell ? 'buttonCell' : ''}
                  key={`${headCell.id}_${index}`}
                  align={headCell.align}
                  padding='normal'
                  sortDirection={orderBy.id === headCell.id ? order : false}
                >
                  {headCell.element}
                  {sortUpIcon && sortDownIcon ? (
                    <Grid
                      container
                      alignItems='center'
                      className={classes.label}
                      onClick={(event: any) =>
                        handleRequestSort(event, headCell)
                      }
                    >
                      <Box
                        className={cx(
                          classes.headCellLabel,
                          orderBy.id === headCell.id &&
                            classes.sortRequestedHeadLabel,
                        )}
                      >
                        {headCell.label}
                      </Box>
                      {!headCell.sortDisabled && (
                        <Box
                          className={cx(
                            classes.sortIcon,
                            orderBy.id === headCell.id &&
                              classes.sortRequestedIcon,
                          )}
                        >
                          {order === 'asc' && orderBy.id === headCell.id
                            ? sortUpIcon
                            : sortDownIcon}
                        </Box>
                      )}
                    </Grid>
                  ) : (
                    <TableSortLabel
                      className={classes.label}
                      active={orderBy.id === headCell.id}
                      direction={orderBy.id === headCell.id ? order : 'asc'}
                      onClick={(event: any) =>
                        handleRequestSort(event, headCell)
                      }
                    >
                      {headCell.label}
                      {orderBy.id === headCell.id ? (
                        <span className={classes.visuallyHidden}>
                          {order === 'desc'
                            ? 'sorted descending'
                            : 'sorted ascending'}
                        </span>
                      ) : null}
                    </TableSortLabel>
                  )}
                </TableCell>
              ))}
            </TableRow>
          </TableHead>

          <TableBody>
            {loading && (
              <TableRow style={{ height: 53 * emptyRows }}>
                <TableCell colSpan={headCells.length}>
                  <Grid container justifyContent='center' alignItems='center'>
                    <CircularProgress />
                  </Grid>
                </TableCell>
              </TableRow>
            )}

            {stableSort(data, getComparator(order, orderBy))
              .slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage)
              .map((item, index) => renderRow(item, index, page, rowsPerPage))}

            {!loading && data.length < 1 && (
              <TableRow style={{ height: 53 }}>
                <TableCell colSpan={headCells.length} align='center'>
                  {emptyMesage}
                </TableCell>
              </TableRow>
            )}

            {!loading && emptyRows > 0 && showEmptyRows && (
              <TableRow
                style={{
                  height: 53 * (data.length < 1 ? emptyRows - 1 : emptyRows),
                }}
              >
                <TableCell colSpan={headCells.length} />
              </TableRow>
            )}
          </TableBody>

          {/* Todo: show captions */}
          {caption === false && (
            <caption style={{ marginTop: 24 }}>{caption}</caption>
          )}
        </Table>
      </TableContainer>

      {showPagination && (
        <TablePagination
          rowsPerPageOptions={[5, 10, 25, 50]}
          className={classes.tablePagination}
          component='div'
          count={count}
          rowsPerPage={rowsPerPage}
          page={page}
          onPageChange={handleChangePage}
          onRowsPerPageChange={handleChangeRowsPerPage}
        />
      )}
    </Box>
  );
}
Example #4
Source File: index.tsx    From prism-frontend with MIT License 4 votes vote down vote up
function AnalysisTable({ classes, tableData, columns }: AnalysisTableProps) {
  // only display local names if local language is selected, otherwise display english name
  const { t } = useSafeTranslation();
  const [page, setPage] = useState(0);
  const [rowsPerPage, setRowsPerPage] = useState(10);
  const [sortColumn, setSortColumn] = useState<Column['id']>();
  const [isAscending, setIsAscending] = useState(true);

  const dispatch = useDispatch();

  const handleChangePage = (event: unknown, newPage: number) => {
    setPage(newPage);
  };

  const handleChangeRowsPerPage = (
    event: React.ChangeEvent<HTMLInputElement>,
  ) => {
    setRowsPerPage(+event.target.value);
    setPage(0);
  };

  const handleChangeOrderBy = (newSortColumn: Column['id']) => {
    const newIsAsc = !(sortColumn === newSortColumn && isAscending);
    setPage(0);
    setSortColumn(newSortColumn);
    setIsAscending(newIsAsc);
  };
  return (
    <div>
      <TableContainer className={classes.tableContainer}>
        <Table stickyHeader aria-label="sticky table">
          <TableHead>
            <TableRow>
              {columns.map(column => (
                <TableCell key={column.id} className={classes.tableHead}>
                  <TableSortLabel
                    active={sortColumn === column.id}
                    direction={
                      sortColumn === column.id && !isAscending ? 'desc' : 'asc'
                    }
                    onClick={() => handleChangeOrderBy(column.id)}
                  >
                    {t(column.label)}
                  </TableSortLabel>
                </TableCell>
              ))}
            </TableRow>
          </TableHead>
          <TableBody>
            {orderBy(tableData, sortColumn, isAscending ? 'asc' : 'desc')
              .slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage)
              .map(row => {
                return (
                  <TableRow
                    hover
                    role="checkbox"
                    tabIndex={-1}
                    key={row.key}
                    onClick={() => {
                      // TODO if we decide to keep, add popup data?
                      if (row.coordinates) {
                        dispatch(
                          showPopup({
                            coordinates: row.coordinates,
                            locationName: row.name,
                            locationLocalName: row.localName,
                          }),
                        );
                      }
                    }}
                    style={{ cursor: row.coordinates ? 'pointer' : 'none' }}
                  >
                    {columns.map(column => {
                      const value = row[column.id];
                      return (
                        <TableCell key={column.id}>
                          {column.format && typeof value === 'number'
                            ? column.format(value)
                            : value}
                        </TableCell>
                      );
                    })}
                  </TableRow>
                );
              })}
          </TableBody>
        </Table>
      </TableContainer>
      <TablePagination
        rowsPerPageOptions={[10, 25, 100]}
        component="div"
        count={tableData.length}
        rowsPerPage={rowsPerPage}
        page={page}
        onChangePage={handleChangePage}
        onChangeRowsPerPage={handleChangeRowsPerPage}
        labelRowsPerPage={t('Rows Per Page')}
        // Temporary manual translation before we upgrade to MUI 5.
        labelDisplayedRows={({ from, to, count }) => {
          return `${from}–${to} ${t('of')} ${
            count !== -1 ? count : `${t('more than')} ${to}`
          }`;
        }}
      />
    </div>
  );
}
Example #5
Source File: tableHead.tsx    From aqualink-app with MIT License 4 votes vote down vote up
EnhancedTableHead = (props: EnhancedTableProps) => {
  const createSortHandler =
    (property: OrderKeys) => (event: React.MouseEvent<unknown>) => {
      props.onRequestSort(event, property);
    };

  const { isExtended } = props;

  const headCells: HeadCell[] = [
    {
      id: OrderKeys.LOCATION_NAME,
      label: "SITE",
      width: isExtended ? "20%" : "40%",
      display: true,
    },
    {
      id: OrderKeys.SST,
      label: "SST",
      unit: "°C",
      display: true,
    },
    {
      id: OrderKeys.HISTORIC_MAX,
      label: "HISTORIC MAX",
      unit: "°C",
      display: !!isExtended,
    },
    {
      id: OrderKeys.SST_ANOMALY,
      label: "SST ANOMALY",
      unit: "°C",
      display: !!isExtended,
    },
    {
      id: OrderKeys.DHW,
      label: "STRESS",
      unit: "DHW",
      display: true,
    },
    {
      id: OrderKeys.BUOY_TOP,
      label: "BUOY",
      unit: "1m",
      display: !!isExtended,
    },
    {
      id: OrderKeys.BUOY_BOTTOM,
      label: "BUOY",
      unit: "DEPTH",
      display: !!isExtended,
    },
    {
      id: OrderKeys.ALERT,
      label: "ALERT",
      display: true,
      width: isExtended ? undefined : "5%",
    },
  ];

  return (
    <TableHead style={{ backgroundColor: "rgb(244, 244, 244)" }}>
      <TableRow>
        {headCells.map(
          (headCell) =>
            headCell.display && (
              <TableCell
                className={props.classes.headCells}
                key={headCell.id}
                style={{ width: headCell.width }}
                align="left"
                padding="default"
                sortDirection={
                  props.orderBy === headCell.id ? props.order : false
                }
              >
                <TableSortLabel
                  active={props.orderBy === headCell.id}
                  direction={
                    props.orderBy === headCell.id ? props.order : "asc"
                  }
                  onClick={createSortHandler(headCell.id)}
                >
                  <ColumnTitle
                    title={headCell.label}
                    unit={headCell.unit}
                    bigText={!isExtended}
                  />
                </TableSortLabel>
              </TableCell>
            )
        )}
      </TableRow>
    </TableHead>
  );
}
Example #6
Source File: UserBookings.tsx    From office-booker with MIT License 4 votes vote down vote up
UserBookings: React.FC<RouteComponentProps<{ email: string }>> = (props) => {
  // Global state
  const { state, dispatch } = useContext(AppContext);
  const { user } = state;

  // Local state
  const [loading, setLoading] = useState(true);
  const [selectedUser, setSelectedUser] = useState<User | undefined>();
  const [bookings, setBookings] = useState<Booking[] | undefined>();
  const [bookingToCancel, setBookingToCancel] = useState<undefined | Booking>();
  const [sortedBookings, setSortedBookings] = useState<Booking[] | undefined>();

  const [sortBy, setSortBy] = useState<keyof Booking>('date');
  const [sortOrder, setSortOrder] = useState<SortOrder>('asc');

  // Theme
  const theme = useTheme();
  const fullScreen = useMediaQuery(theme.breakpoints.down('sm'));

  // Effects
  useEffect(() => {
    if (props.email) {
      getBookings({ user: props.email })
        .then((data) => {
          // Split for previous and upcoming
          setBookings(data);
        })
        .catch((err) => {
          // Handle errors
          setLoading(false);

          dispatch({
            type: 'SET_ALERT',
            payload: {
              message: formatError(err),
              color: 'error',
            },
          });
        });
    }
  }, [props.email, dispatch]);

  useEffect(() => {
    if (user && !user.permissions.canViewUsers) {
      // No permissions - Bounce to home page
      navigate('/');
    }
  }, [user]);

  useEffect(() => {
    if (user) {
      // Get selected user
      getUser(props.email || '')
        .then((selectedUser) => setSelectedUser(selectedUser))
        .catch((err) => {
          // Handle errors
          setLoading(false);

          dispatch({
            type: 'SET_ALERT',
            payload: {
              message: formatError(err),
              color: 'error',
            },
          });
        });
    }
  }, [user, props.email, dispatch]);

  useEffect(() => {
    if (bookings) {
      // Sort it!
      setSortedBookings(sortData([...bookings], sortBy, sortOrder));
    }
  }, [bookings, sortBy, sortOrder]);

  useEffect(() => {
    if (bookings) {
      // Wait for global state to be ready
      setLoading(false);
    }
  }, [bookings]);

  // Handlers
  const handleSort = (key: keyof Booking) => {
    if (key === sortBy) {
      setSortOrder(sortOrder === 'desc' ? 'asc' : 'desc');
    } else {
      setSortBy(key);
    }
  };

  const getAllBookings = useCallback(() => {
    if (state.user) {
      getBookings({ user: state.user.email })
        .then((data) => {
          // Split for previous and upcoming
          setBookings(data);
        })
        .catch((err) => {
          // Handle errors
          setLoading(false);

          dispatch({
            type: 'SET_ALERT',
            payload: {
              message: formatError(err),
              color: 'error',
            },
          });
        });
    }
  }, [state.user, dispatch]);

  const handleCancelBooking = (booking: Booking) => {
    cancelBooking(booking.id, booking.user)
      .then(() => {
        // Clear selected booking
        setBookingToCancel(undefined);

        // Retrieve updated bookings
        getAllBookings();

        // Show confirmation alert
        dispatch({
          type: 'SET_ALERT',
          payload: {
            message: 'Booking cancelled',
            color: 'success',
          },
        });
      })
      .catch((err) =>
        dispatch({
          type: 'SET_ALERT',
          payload: {
            message: formatError(err),
            color: 'error',
          },
        })
      );
  };

  // Render
  if (!user) {
    return null;
  }

  return (
    <AdminLayout currentRoute="users">
      <UserBookingsStyles>
        {loading || !selectedUser ? (
          <Loading />
        ) : (
          <>
            <h3>User Bookings</h3>

            <Paper square className="table-container">
              <h4>{selectedUser.email}</h4>
              <TableContainer className="table">
                <Table>
                  <TableHead>
                    <TableRow>
                      <TableCell className="table-header">
                        <TableSortLabel
                          active={sortBy === 'office'}
                          direction={sortOrder}
                          onClick={() => handleSort('office')}
                        >
                          Office
                        </TableSortLabel>
                      </TableCell>
                      <TableCell className="table-header">
                        <TableSortLabel
                          active={sortBy === 'date'}
                          direction={sortOrder}
                          onClick={() => handleSort('date')}
                        >
                          Date
                        </TableSortLabel>
                      </TableCell>
                      <TableCell className="table-header">
                        <TableSortLabel
                          active={sortBy === 'parking'}
                          direction={sortOrder}
                          onClick={() => handleSort('parking')}
                        >
                          Parking
                        </TableSortLabel>
                      </TableCell>
                      <TableCell />
                    </TableRow>
                  </TableHead>
                  <TableBody>
                    {sortedBookings && sortedBookings.length > 0 ? (
                      sortedBookings.map((booking, index) => {
                        const parsedDate = parseISO(booking.date);

                        return (
                          <TableRow key={index}>
                            <TableCell>{booking.office.name}</TableCell>
                            <TableCell>
                              {' '}
                              {format(
                                parse(booking.date, 'yyyy-MM-dd', new Date(), DATE_FNS_OPTIONS),
                                'do LLLL yyyy',
                                DATE_FNS_OPTIONS
                              )}
                            </TableCell>
                            <TableCell>{booking.parking ? 'Yes' : 'No'}</TableCell>
                            {isToday(parsedDate) || !isPast(parsedDate) ? (
                              <TableCell align="right">
                                <div className="btn-container">
                                  <OurButton
                                    type="submit"
                                    variant="contained"
                                    color="secondary"
                                    size="small"
                                    onClick={() => setBookingToCancel(booking)}
                                  >
                                    Cancel
                                  </OurButton>
                                </div>
                              </TableCell>
                            ) : (
                              <TableCell />
                            )}
                          </TableRow>
                        );
                      })
                    ) : (
                      <TableRow>
                        <TableCell>No bookings found</TableCell>
                        <TableCell />
                      </TableRow>
                    )}
                  </TableBody>
                </Table>
              </TableContainer>
            </Paper>
          </>
        )}

        {bookingToCancel && (
          <Dialog fullScreen={fullScreen} open={true} onClose={() => setBookingToCancel(undefined)}>
            <DialogTitle>{'Are you sure you want to cancel this booking?'}</DialogTitle>
            <DialogContent>
              <DialogContentText>
                Booking for <strong>{bookingToCancel.user}</strong> on{' '}
                <strong>{format(parseISO(bookingToCancel.date), 'do LLLL')}</strong> for{' '}
                <strong>{bookingToCancel.office.name}</strong>
              </DialogContentText>
            </DialogContent>
            <DialogActions>
              <Button onClick={() => setBookingToCancel(undefined)} color="primary" autoFocus>
                No
              </Button>
              <Button
                autoFocus
                onClick={() => handleCancelBooking(bookingToCancel)}
                color="primary"
              >
                Yes
              </Button>
            </DialogActions>
          </Dialog>
        )}
      </UserBookingsStyles>
    </AdminLayout>
  );
}