formatted mobile devices list

This commit is contained in:
Carter 2025-02-25 13:48:19 -06:00
parent 8743cba65a
commit 80683e29e5
3 changed files with 79 additions and 9 deletions

View file

@ -4,6 +4,7 @@ import { ChevronRight, Close, Search, ViewColumn } from "@mui/icons-material"
import { useEffect, useState } from "react";
import React from "react";
import { useMobile } from "hooks";
import classNames from "classnames";
const useStyles = makeStyles((theme: Theme) => {
// const isMobile = useMobile()
@ -140,7 +141,8 @@ export default function ResponsiveTable<T extends Object>(props: Props<T>) {
return () => clearTimeout(handler); // Cleanup on change
}, [inputSearchText]);
const handleCollapse = (index: number) => {
const handleCollapse = (index: number, event: React.MouseEvent<HTMLDivElement | HTMLButtonElement, MouseEvent>) => {
event.stopPropagation();
if (multiGutter) {
if (openGutters.includes(index)) {
setOpenGutters(openGutters => openGutters.filter(num => num !== index));
@ -285,11 +287,10 @@ export default function ResponsiveTable<T extends Object>(props: Props<T>) {
{renderTitle()}
{renderSubtitle()}
{setSearchText && searchBar()}
</Box>
{rows.map((row, index) => {
return (
<Card className={classes.card} key={"mobile-card-"+index}>
<Card className={classNames(classes.card, onRowClick&&classes.rowHover)} key={"mobile-card-"+index} onClick={() => onRowClick&&onRowClick(row)}>
{renderMobileRow(row)}
{renderGutter &&
<>
@ -304,7 +305,8 @@ export default function ResponsiveTable<T extends Object>(props: Props<T>) {
display: "flex",
justifyContent: "center"
}}
onClick={() => handleCollapse(index)}
onClick={(event) => handleCollapse(index, event)}
// style={{pre}}
>
<IconButton
sx={{
@ -427,7 +429,7 @@ export default function ResponsiveTable<T extends Object>(props: Props<T>) {
transition: 'transform 0.3s ease',
marginRight: isMobile ? -1 : 0
}}
onClick={() => handleCollapse(index)}>
onClick={(event) => handleCollapse(index, event)}>
<ChevronRight/>
</IconButton>
</TableCell>

View file

@ -18,6 +18,10 @@ import SmartBreadcrumb from "common/SmartBreadcrumb";
import GroupActions from "group/GroupActions";
// import CircleGraphIcon from "common/CircleGraphIcon";
import DevicesSummary from "device/DevicesSummary";
import { GetDeviceProductIcon } from "products/DeviceProduct";
import BindaptIcon from "products/Bindapt/BindaptIcon";
import { describePower } from "pbHelpers/Power";
import moment from "moment";
const useStyles = makeStyles((theme: Theme) => {
return ({
@ -359,6 +363,64 @@ export default function Devices() {
return group
}
const mobile = (row: Device) => {
return (
<Box sx={{ margin: 2 }}>
<Grid2 spacing={1} container direction={"row"} justifyContent="space-between" alignItems={"center"}>
<Grid2 >
{/* {GetDeviceProductIcon(row)} */}
{/* {icon} */}
<BindaptIcon />
</Grid2>
<Grid2 size={{ xs: 9}}>
<Grid2 container direction="column">
<Grid2>
{row.name()}
</Grid2>
<Grid2>
Last Active: {moment(row.status.lastActive).fromNow()}
</Grid2>
</Grid2>
</Grid2>
<Grid2 >
{describePower(row.status.power).icon}
</Grid2>
</Grid2>
</Box>
)
}
const gutter = (row: Device) => {
return (
<Box sx={{ margin: 1 }}>
<Grid2 container spacing={1} direction="column">
<Grid2>
{row.settings.description}
</Grid2>
{row.status.plenum &&
<Grid2 container direction="row" spacing={0}>
<Grid2>
<Typography color={orange[400]}>
{row.status.plenum.temperature}°C
</Typography>
</Grid2>
<Grid2 >
<Typography marginRight={1}>
{", "}
</Typography>
</Grid2>
<Grid2>
<Typography color={blue[300]}>
{row.status.plenum.humidity}%
</Typography>
</Grid2>
</Grid2>
}
</Grid2>
</Box>
)
}
return(
<PageContainer padding={isMobile ? 0 : 2}>
<Box
@ -392,7 +454,9 @@ export default function Devices() {
title={<SmartBreadcrumb prependPaths={getGroup() && ["groups", getGroup().id().toString()]} groupName={getGroup() && getGroup().name()} paddingBottom={1}/>}
subtitle={subtitle()}
rows={devices}
renderGutter={gutter}
columns={columns()}
renderMobile={mobile}
total={total}
pageSize={limit}
page={page}

View file

@ -16,6 +16,9 @@ import {
import { NexusST } from "./Nexus/NexusDescriber";
import { MiPCAV2, OmniAir } from "./OmniAir/OmniAirDescriber";
import { ConfigurablePin } from "pbHelpers/AddressTypes";
import { useTheme } from "@mui/material";
import { Device } from "models";
import { or } from "utils";
export type ProductTab = "components" | "presets";
@ -101,11 +104,12 @@ export function GetDeviceProductLabel(product: pond.DeviceProduct): string {
}
export function GetDeviceProductIcon(
product: pond.DeviceProduct,
platform: pond.DevicePlatform,
theme?: "dark" | "light"
device: pond.Device | Device
): string | undefined {
return getDescriber(product).icon(platform, theme);
const theme = useTheme()
const product = or(device.settings?.product, pond.DeviceProduct.DEVICE_PRODUCT_NONE)
const platform = or(device.settings?.platform, pond.DevicePlatform.DEVICE_PLATFORM_INVALID)
return getDescriber(product).icon(platform, theme.palette.mode);
}
export function IsCardController(product?: pond.DeviceProduct): boolean {