import React from "react"; import type { clutch as IClutch } from "@clutch-sh/api"; import styled from "@emotion/styled"; import { Paper, Table, TableBody, TableCell, TableContainer as MuiTableContainer, TableHead, TablePagination, TableRow, TableSortLabel, } from "@mui/material"; import makeStyles from "@mui/styles/makeStyles"; import { compareProperties, propertyToString } from "./property-helpers"; const useStyles = makeStyles(() => ({ root: { width: "100%", }, paper: { width: "100%", marginBottom: "8px", }, table: { minWidth: 750, }, })); const TableContainer = styled(MuiTableContainer)({ overflow: "auto", maxHeight: "75vh", display: "flex", }); type Ordering = "asc" | "desc"; type ListViewItem = IClutch.chaos.experimentation.v1.ListViewItem; function getComparator( order: Ordering, orderBy: string ): (a: ListViewItem, b: ListViewItem) => number { return order === "desc" ? (a: ListViewItem, b: ListViewItem) => compareProperties(a.properties.items[orderBy], b.properties.items[orderBy]) : (a: ListViewItem, b: ListViewItem) => -compareProperties(a.properties.items[orderBy], b.properties.items[orderBy]); } // Stable sort for the list of properties. function stableSort( array: ListViewItem[], comparator: (a: ListViewItem, b: ListViewItem) => number ): ListViewItem[] { const stabilizedThis = array.map((el, index) => { return { item: el, index }; }); stabilizedThis.sort((a, b) => { const order = comparator(a.item, b.item); if (order !== 0) { return order; } return a.index - b.index; }); return stabilizedThis.map(el => el.item); } interface EnhancedTableHeadProps { columns: Column[]; order: Ordering; orderBy: string; onRequestSort: (event: any, columnId: string) => void; } const EnhancedTableHead: React.FC = ({ columns, order, orderBy, onRequestSort, }) => { const createSortHandler = (columnId: string) => (event: any) => { onRequestSort(event, columnId); }; return ( {columns.map(column => ( {column.sortable && ( {column.header} )} {!column.sortable && column.header} ))} ); }; export interface Column { id: string; header: string; sortable?: boolean; } interface ListViewProps { columns: Column[]; items: ListViewItem[]; onRowSelection: (event: any, item: ListViewItem) => void; } const ListView: React.FC = ({ columns, items, onRowSelection }) => { const classes = useStyles(); const [order, setOrder] = React.useState("asc"); const [orderBy, setOrderBy] = React.useState(""); const [page, setPage] = React.useState(0); const [rowsPerPage, setRowsPerPage] = React.useState(25); const handleRequestSort = (event: any, columnId: string) => { const isAsc = orderBy === columnId && order === "asc"; setOrder(isAsc ? "desc" : "asc"); setOrderBy(columnId); }; const handleClick = (event: any, item: ListViewItem) => { onRowSelection(event, item); }; const handleChangePage = (event: any, newPage: number) => { setPage(newPage); }; const handleChangeRowsPerPage = (event: any) => { setRowsPerPage(parseInt(event.target.value, 10)); setPage(0); }; return (
{items && ( {stableSort(items, getComparator(order, orderBy)) .slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage) .map((item: ListViewItem) => { return ( handleClick(event, item)} key={item.id.toString()} > {columns && columns.map(column => { return ( {propertyToString(item.properties.items[column.id])} ); })} ); })} )}
); }; export default ListView;