diff --git a/src/common/ResponsiveTable.tsx b/src/common/ResponsiveTable.tsx index de23f1b..5e48220 100644 --- a/src/common/ResponsiveTable.tsx +++ b/src/common/ResponsiveTable.tsx @@ -1,6 +1,6 @@ import { Box, Card, Checkbox, CircularProgress, Collapse, darken, Divider, Grid2, IconButton, InputAdornment, ListItemButton, ListItemIcon, ListItemText, Menu, MenuItem, Paper, SxProps, Table, TableBody, TableCell, TableContainer, TableHead, TablePagination, TableRow, TextField, Theme, Typography } from "@mui/material"; import { makeStyles } from "@mui/styles"; -import { ChevronRight, Close, Search, ViewColumn } from "@mui/icons-material" +import { ArrowDownward, ArrowUpward, ChevronRight, Close, Search, ViewColumn } from "@mui/icons-material" import { useEffect, useState } from "react"; import React from "react"; import { useMobile } from "hooks"; @@ -64,6 +64,8 @@ export interface Column { cellStyle?: SxProps; hidden?: boolean; render: (row: T) => JSX.Element; + sortKey?: string; + disableSort?: boolean; } interface Props { @@ -92,6 +94,10 @@ interface Props { customElement?: JSX.Element //element that will be placed in the table head between the table actions and the column header rows mobileView?: boolean //can be used to force the table to use its mobile view for narrow containing elements ie, drawer hidePagination?: boolean //when passed in will hide the pagination at the bottom of the table + orderBy?: string; + setOrderBy?: React.Dispatch>; + order?: string; + setOrder?: React.Dispatch>; } export default function ResponsiveTable(props: Props) { @@ -120,12 +126,17 @@ export default function ResponsiveTable(props: Props) { selectedRows, customElement, mobileView, - hidePagination + hidePagination, + orderBy, + setOrderBy, + order, + setOrder } = props const classes = useStyles(); const columns = typeof(props.columns) === "function" ? props.columns() : props.columns const subtitle = typeof(props.subtitle) === "function" ? props.subtitle() : props.subtitle const title = typeof(props.title) === "function" ? props.title() : props.title + // const order = props.order ? props.order : "asc" const isMobile = useMobile() @@ -373,12 +384,30 @@ export default function ResponsiveTable(props: Props) { setFilterList(newFilterList) } + const columnClick = (column: Column) => { + const sortKey = column.sortKey ? column.sortKey : column.title + console.log(column.sortKey) + if (setOrderBy) setOrderBy(sortKey) + if (setOrder && order) setOrder(order === "asc" ? "desc" : "asc") + } + + const showOrderIcon = (column: Column) => { + if (!orderBy) return + const sortKey = column.sortKey ? column.sortKey : column.title + if (sortKey === orderBy) { + if (order === "asc") { + return + } else { + return + } + } + return null; + } return ( - + - @@ -418,7 +447,6 @@ export default function ResponsiveTable(props: Props) { } - { rowSelect && } @@ -427,8 +455,14 @@ export default function ResponsiveTable(props: Props) { columns.map((column, index) => { if (filterList.includes(column.title) || column.hidden) return null return ( - - {column.title} + !column.disableSort && columnClick(column)} + sx={{ cursor: column.disableSort ? "default" : "pointer" }} + > + + {column.title} {showOrderIcon(column)} + ) }) diff --git a/src/pages/Devices.tsx b/src/pages/Devices.tsx index c4239c5..036d718 100644 --- a/src/pages/Devices.tsx +++ b/src/pages/Devices.tsx @@ -92,8 +92,8 @@ export default function Devices() { const [devicesLoading, setDevicesLoading] = useState(false) const [limit, setLimit] = useState(10); const [page, setPage] = useState(0); - const [order, ] = useState<"asc" | "desc">("asc"); - const [orderBy, ] = useState("name"); + const [order, setOrder] = useState<"asc" | "desc">("asc"); + const [orderBy, setOrderBy] = useState("name"); const [search, setSearch] = useState(""); const [total, setTotal] = useState(0); const [devices, setDevices] = useState([]) @@ -293,10 +293,15 @@ export default function Devices() { if (newValue === "never") openGroupSettings(undefined, "add"); }; + useEffect(() => { + console.log(devices) + }, [devices]) + const columns = (): Column[] => { - let columns = [ + let columns: Column[] = [ { title: "State", + sortKey: "state", render: (device: Device) => { const status = device.status ?? pond.DeviceStatus.create() const deviceStateHelper = getDeviceStateHelper(status.state); @@ -309,12 +314,14 @@ export default function Devices() { }, { title: "ID", + sortKey: "deviceId", render: (device: Device) => {device.settings?.deviceId} }, { title: "Device", + sortKey: "name", render: (device: Device) => { return ( @@ -346,6 +353,7 @@ export default function Devices() { }, { title: "Tags", + sortKey: "tags", render: (device: Device) => { return ( @@ -362,6 +370,8 @@ export default function Devices() { if (hasPlenums) { columns.push({ title: "Plenum", + sortKey: "hi", + disableSort: true, render: (device: Device) => { if (device.status.plenum?.temperature) { return ( @@ -380,6 +390,8 @@ export default function Devices() { if (hasSen5x) { columns.push({ title: "Sen5X", + sortKey: "hi", + disableSort: true, render: (device: Device) => { if (device.status.sen5x?.temperature) { return ( @@ -532,6 +544,10 @@ export default function Devices() { setSearchText={setSearch} isLoading={devicesLoading} actions={getGroup() && } + order={order} + setOrder={setOrder} + orderBy={orderBy} + setOrderBy={setOrderBy} />