aboutsummaryrefslogtreecommitdiffstats
path: root/src/tools/emcoui/src/compositeApps/dialogs/SortableTable.jsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools/emcoui/src/compositeApps/dialogs/SortableTable.jsx')
-rw-r--r--src/tools/emcoui/src/compositeApps/dialogs/SortableTable.jsx410
1 files changed, 410 insertions, 0 deletions
diff --git a/src/tools/emcoui/src/compositeApps/dialogs/SortableTable.jsx b/src/tools/emcoui/src/compositeApps/dialogs/SortableTable.jsx
new file mode 100644
index 00000000..f1a6ac2d
--- /dev/null
+++ b/src/tools/emcoui/src/compositeApps/dialogs/SortableTable.jsx
@@ -0,0 +1,410 @@
+//=======================================================================
+// Copyright (c) 2017-2020 Aarna Networks, Inc.
+// All rights reserved.
+// ======================================================================
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+// http://www.apache.org/licenses/LICENSE-2.0
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// ========================================================================
+import Table from "@material-ui/core/Table";
+import TableBody from "@material-ui/core/TableBody";
+import TableCell from "@material-ui/core/TableCell";
+import TableContainer from "@material-ui/core/TableContainer";
+import TableHead from "@material-ui/core/TableHead";
+import TableRow from "@material-ui/core/TableRow";
+import TableSortLabel from "@material-ui/core/TableSortLabel";
+import { makeStyles } from "@material-ui/core/styles";
+import React, { useEffect, useState } from "react";
+import Checkbox from "@material-ui/core/Checkbox";
+import PropTypes from "prop-types";
+import Typography from "@material-ui/core/Typography";
+import Toolbar from "@material-ui/core/Toolbar";
+
+import clsx from "clsx";
+import TablePagination from "@material-ui/core/TablePagination";
+import { lighten } from "@material-ui/core/styles";
+
+function descendingComparator(a, b, orderBy) {
+ if (b[orderBy] < a[orderBy]) {
+ return -1;
+ }
+ if (b[orderBy] > a[orderBy]) {
+ return 1;
+ }
+ return 0;
+}
+
+function getComparator(order, orderBy) {
+ return order === "desc"
+ ? (a, b) => descendingComparator(a, b, orderBy)
+ : (a, b) => -descendingComparator(a, b, orderBy);
+}
+
+function stableSort(array, comparator) {
+ const stabilizedThis = array.map((el, index) => [el, index]);
+ stabilizedThis.sort((a, b) => {
+ const order = comparator(a[0], b[0]);
+ if (order !== 0) return order;
+ return a[1] - b[1];
+ });
+ return stabilizedThis.map((el) => el[0]);
+}
+
+const headCells = [
+ {
+ id: "name",
+ numeric: false,
+ sortable: true,
+ disablePadding: true,
+ label: "Cluster",
+ },
+ {
+ id: "description",
+ numeric: true,
+ sortable: false,
+ disablePadding: false,
+ label: "Description",
+ },
+];
+
+function EnhancedTableHead(props) {
+ const {
+ classes,
+ onSelectAllClick,
+ order,
+ orderBy,
+ numSelected,
+ rowCount,
+ onRequestSort,
+ } = props;
+ const createSortHandler = (property) => (event) => {
+ onRequestSort(event, property);
+ };
+
+ return (
+ <TableHead>
+ <TableRow>
+ <TableCell padding="checkbox">
+ <Checkbox
+ indeterminate={numSelected > 0 && numSelected < rowCount}
+ checked={rowCount > 0 && numSelected === rowCount}
+ onChange={onSelectAllClick}
+ />
+ </TableCell>
+ {headCells.map((headCell) =>
+ headCell.sortable ? (
+ <TableCell
+ style={{ fontWeight: "520" }}
+ key={headCell.id}
+ align={headCell.numeric ? "right" : "left"}
+ padding={headCell.disablePadding ? "none" : "default"}
+ sortDirection={orderBy === headCell.id ? order : false}
+ >
+ <TableSortLabel
+ active={orderBy === headCell.id}
+ direction={orderBy === headCell.id ? order : "asc"}
+ onClick={createSortHandler(headCell.id)}
+ >
+ {headCell.label}
+ {orderBy === headCell.id ? (
+ <span className={classes.visuallyHidden}>
+ {order === "desc"
+ ? "sorted descending"
+ : "sorted ascending"}
+ </span>
+ ) : null}
+ </TableSortLabel>
+ </TableCell>
+ ) : (
+ <TableCell
+ key={headCell.id}
+ style={{ fontWeight: "520" }}
+ padding={headCell.disablePadding ? "none" : "default"}
+ align={headCell.numeric ? "right" : "left"}
+ >
+ {headCell.label}
+ </TableCell>
+ )
+ )}
+ </TableRow>
+ </TableHead>
+ );
+}
+
+EnhancedTableHead.propTypes = {
+ classes: PropTypes.object.isRequired,
+ numSelected: PropTypes.number.isRequired,
+ onRequestSort: PropTypes.func.isRequired,
+ onSelectAllClick: PropTypes.func.isRequired,
+ order: PropTypes.oneOf(["asc", "desc"]).isRequired,
+ orderBy: PropTypes.string.isRequired,
+ rowCount: PropTypes.number.isRequired,
+};
+
+const useToolbarStyles = makeStyles((theme) => ({
+ root: {
+ paddingLeft: theme.spacing(2),
+ paddingRight: theme.spacing(1),
+ },
+ highlight:
+ theme.palette.type === "light"
+ ? {
+ color: theme.palette.primary.main,
+ backgroundColor: lighten(theme.palette.primary.light, 0.85),
+ }
+ : {
+ color: theme.palette.text.primary,
+ backgroundColor: theme.palette.primary.dark,
+ },
+ title: {
+ flex: "1 1 100%",
+ },
+}));
+
+const EnhancedTableToolbar = (props) => {
+ const classes = useToolbarStyles();
+ const { numSelected } = props;
+
+ return (
+ <Toolbar
+ className={clsx(classes.root, {
+ [classes.highlight]: numSelected > 0,
+ })}
+ >
+ <Typography
+ className={classes.title}
+ variant="h6"
+ id="tableTitle"
+ component="div"
+ >
+ {props.tableName}
+ </Typography>
+
+ <Typography
+ className={classes.title}
+ style={{ textAlign: "right" }}
+ color="inherit"
+ variant="subtitle1"
+ component="div"
+ >
+ {numSelected} selected
+ </Typography>
+ </Toolbar>
+ );
+};
+
+EnhancedTableToolbar.propTypes = {
+ numSelected: PropTypes.number.isRequired,
+};
+
+const useStyles = makeStyles((theme) => ({
+ tableRoot: {
+ width: "100%",
+ },
+ paper: {
+ width: "100%",
+ marginBottom: theme.spacing(2),
+ },
+ table: {
+ minWidth: 550,
+ },
+ visuallyHidden: {
+ border: 0,
+ clip: "rect(0 0 0 0)",
+ height: 1,
+ margin: -1,
+ overflow: "hidden",
+ padding: 0,
+ position: "absolute",
+ top: 20,
+ width: 1,
+ },
+ appBar: {
+ position: "relative",
+ },
+ title: {
+ marginLeft: theme.spacing(2),
+ flex: 1,
+ },
+ demo: {
+ backgroundColor: theme.palette.background.paper,
+ },
+ root: {
+ flexGrow: 1,
+ backgroundColor: theme.palette.background.paper,
+ display: "flex",
+ height: 424,
+ },
+ tabs: {
+ borderRight: `1px solid ${theme.palette.divider}`,
+ },
+}));
+
+function EnhancedTable({
+ clusters,
+ formikValues,
+ tableName,
+ onRowSelect,
+ ...props
+}) {
+ const classes = useStyles();
+ const [order, setOrder] = useState("asc");
+ const [orderBy, setOrderBy] = useState("name");
+ const [selected, setSelected] = useState([]);
+ const [page, setPage] = useState(0);
+ const [rowsPerPage, setRowsPerPage] = useState(5);
+ const [rows, setRows] = useState([]);
+
+ const handleRequestSort = (event, property) => {
+ const isAsc = orderBy === property && order === "asc";
+ setOrder(isAsc ? "desc" : "asc");
+ setOrderBy(property);
+ };
+
+ useEffect(() => {
+ if (formikValues) {
+ let formikClusterData = formikValues.filter(
+ (cluster) => cluster.provider === tableName
+ );
+ if (formikClusterData && formikClusterData.length > 0) {
+ let data = [];
+ formikClusterData[0].selectedClusters.forEach((selectedCluster) => {
+ data.push(selectedCluster.name);
+ });
+ setSelected(data);
+ }
+ }
+ setRows(clusters);
+ }, []);
+
+ useEffect(() => {
+ onRowSelect(tableName, selected);
+ }, [selected]);
+
+ const handleSelectAllClick = (event) => {
+ if (event.target.checked) {
+ const newSelecteds = rows.map((n) => n.name);
+ setSelected(newSelecteds);
+ return;
+ }
+ setSelected([]);
+ };
+
+ const handleClick = (event, name) => {
+ const selectedIndex = selected.indexOf(name);
+ let newSelected = [];
+
+ if (selectedIndex === -1) {
+ newSelected = newSelected.concat(selected, name);
+ } else if (selectedIndex === 0) {
+ newSelected = newSelected.concat(selected.slice(1));
+ } else if (selectedIndex === selected.length - 1) {
+ newSelected = newSelected.concat(selected.slice(0, -1));
+ } else if (selectedIndex > 0) {
+ newSelected = newSelected.concat(
+ selected.slice(0, selectedIndex),
+ selected.slice(selectedIndex + 1)
+ );
+ }
+ setSelected(newSelected);
+ };
+
+ const handleChangePage = (event, newPage) => {
+ setPage(newPage);
+ };
+
+ const handleChangeRowsPerPage = (event) => {
+ setRowsPerPage(parseInt(event.target.value, 10));
+ setPage(0);
+ };
+
+ const isSelected = (name) => selected.indexOf(name) !== -1;
+
+ const emptyRows =
+ rowsPerPage - Math.min(rowsPerPage, rows.length - page * rowsPerPage);
+
+ return (
+ <div className={classes.tableRoot}>
+ <EnhancedTableToolbar
+ tableName={tableName}
+ numSelected={selected.length}
+ />
+ <TableContainer>
+ <Table
+ className={classes.table}
+ aria-labelledby="tableTitle"
+ size={"small"}
+ aria-label="enhanced table"
+ >
+ <EnhancedTableHead
+ classes={classes}
+ numSelected={selected.length}
+ order={order}
+ orderBy={orderBy}
+ onSelectAllClick={handleSelectAllClick}
+ onRequestSort={handleRequestSort}
+ rowCount={rows.length}
+ />
+ <TableBody>
+ {stableSort(rows, getComparator(order, orderBy))
+ .slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage)
+ .map((row, index) => {
+ const isItemSelected = isSelected(row.name);
+ const labelId = `enhanced-table-checkbox-${index}`;
+
+ return (
+ <TableRow
+ hover
+ onClick={(event) => handleClick(event, row.name)}
+ role="checkbox"
+ aria-checked={isItemSelected}
+ tabIndex={-1}
+ key={row.name}
+ selected={isItemSelected}
+ >
+ <TableCell padding="checkbox">
+ <Checkbox
+ checked={isItemSelected}
+ inputProps={{ "aria-labelledby": labelId }}
+ />
+ </TableCell>
+ <TableCell
+ component="th"
+ id={labelId}
+ scope="row"
+ padding="none"
+ >
+ {row.name}
+ </TableCell>
+ <TableCell align="right">{row.description}</TableCell>
+ </TableRow>
+ );
+ })}
+ {emptyRows > 0 && (
+ <TableRow style={{ height: 33 * emptyRows }}>
+ <TableCell colSpan={6} />
+ </TableRow>
+ )}
+ </TableBody>
+ </Table>
+ </TableContainer>
+ <TablePagination
+ rowsPerPageOptions={[5, 10, 25]}
+ component="div"
+ count={rows.length}
+ rowsPerPage={rowsPerPage}
+ page={page}
+ onChangePage={handleChangePage}
+ onChangeRowsPerPage={handleChangeRowsPerPage}
+ />
+ </div>
+ );
+}
+
+export default EnhancedTable;