Merge branch 'dev_environment' of gitlab.com:brandx/bxt-app into dev_environment

This commit is contained in:
Carter 2025-04-02 11:08:14 -06:00
commit dd952bebe6
4 changed files with 96 additions and 11 deletions

View file

@ -92,6 +92,7 @@ interface Props<T> {
rowSelect?: (row: T, index: number, checked: boolean) => void; //row select function that passes the the row back up, when this function is passed in render a column of checkboxes rowSelect?: (row: T, index: number, checked: boolean) => void; //row select function that passes the the row back up, when this function is passed in render a column of checkboxes
selectedRows?: number[]; //which rows are selected will need to be controlled by the parent in order to keep track between page changes selectedRows?: number[]; //which rows are selected will need to be controlled by the parent in order to keep track between page changes
customElement?: JSX.Element //element that will be placed in the table head between the table actions and the column header rows 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
} }
export default function ResponsiveTable<T extends Object>(props: Props<T>) { export default function ResponsiveTable<T extends Object>(props: Props<T>) {
@ -118,7 +119,8 @@ export default function ResponsiveTable<T extends Object>(props: Props<T>) {
actions, actions,
rowSelect, rowSelect,
selectedRows, selectedRows,
customElement customElement,
mobileView
} = props } = props
const classes = useStyles(); const classes = useStyles();
const columns = typeof(props.columns) === "function" ? props.columns() : props.columns const columns = typeof(props.columns) === "function" ? props.columns() : props.columns
@ -303,7 +305,7 @@ export default function ResponsiveTable<T extends Object>(props: Props<T>) {
} }
if (isMobile) return ( if (isMobile || mobileView) return (
<Box> <Box>
<Box className={classes.mobileTitleBox}> <Box className={classes.mobileTitleBox}>
{renderTitle()} {renderTitle()}
@ -472,7 +474,7 @@ export default function ResponsiveTable<T extends Object>(props: Props<T>) {
transform: openGutters.includes(index) ? transform: openGutters.includes(index) ?
'rotate(90deg)' : 'rotate(0deg)', 'rotate(90deg)' : 'rotate(0deg)',
transition: 'transform 0.3s ease', transition: 'transform 0.3s ease',
marginRight: isMobile ? -1 : 0 marginRight: (isMobile || mobileView) ? -1 : 0
}} }}
onClick={(event) => handleCollapse(index, event)}> onClick={(event) => handleCollapse(index, event)}>
<ChevronRight/> <ChevronRight/>

View file

@ -1,10 +1,15 @@
import { Box } from "@mui/material"; import { Box, Grid2, Typography } from "@mui/material";
import DisplayDrawer from "common/DisplayDrawer"; import DisplayDrawer from "common/DisplayDrawer";
import ResponsiveTable from "common/ResponsiveTable";
//import DeviceCardList from "device/DeviceCardList"; //import DeviceCardList from "device/DeviceCardList";
import { useGroupAPI, useSnackbar } from "hooks"; import { useGroupAPI, useSnackbar } from "hooks";
import { Group } from "models"; import { Group } from "models";
import moment from "moment";
import { describePower } from "pbHelpers/Power";
import BindaptIcon from "products/Bindapt/BindaptIcon";
import { pond } from "protobuf-ts/pond"; import { pond } from "protobuf-ts/pond";
import React, { useEffect, useState, useCallback } from "react"; import React, { useEffect, useState, useCallback } from "react";
import { useNavigate } from "react-router-dom";
import { or } from "utils"; import { or } from "utils";
interface Props { interface Props {
@ -22,6 +27,9 @@ export default function GroupDrawer(props: Props) {
const groupAPI = useGroupAPI(); const groupAPI = useGroupAPI();
const { openSnack } = useSnackbar(); const { openSnack } = useSnackbar();
const [grpDevs, setGrpDevs] = useState<pond.ComprehensiveDevice[]>([]); const [grpDevs, setGrpDevs] = useState<pond.ComprehensiveDevice[]>([]);
const navigate = useNavigate();
const [tablePage, setTablePage] = useState(0)
const [pageSize, setPageSize] = useState(10)
const loadDevs = useCallback(() => { const loadDevs = useCallback(() => {
groupAPI groupAPI
@ -121,8 +129,69 @@ export default function GroupDrawer(props: Props) {
}); });
}; };
const toDevice = (comprehensiveDevice: pond.ComprehensiveDevice) => {
let device = comprehensiveDevice.device
if(device){
let url = "/groups/" + selectedGroup
url = url + "/devices/" + device.settings?.deviceId
navigate(url, { replace: true, state: {device: device} })
}
};
const mobile = (row: pond.ComprehensiveDevice) => {
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.device?.settings?.name}
</Grid2>
<Grid2>
Last Active: {moment(row.device?.status?.lastActive).fromNow()}
</Grid2>
</Grid2>
</Grid2>
<Grid2 >
{describePower(row.device?.status?.power).icon}
</Grid2>
</Grid2>
</Box>
)
}
const gutter = (row: pond.ComprehensiveDevice) => {
return (
<Box padding={1}>
<Typography>{row.device?.settings?.description}</Typography>
</Box>
)
}
const drawerBody = () => { const drawerBody = () => {
return (<Box>Use the responsive table here</Box>) // TODO: will need to update the rows and setPage functions if we decide to have the table only show a number of items matching its page size rether than everything passed in
return (
<Box>
<ResponsiveTable<pond.ComprehensiveDevice>
page={tablePage}
pageSize={pageSize}
onRowClick={toDevice}
handleRowsPerPageChange={()=>{}}
setPage={()=>{}}
total={grpDevs.length}
rows={grpDevs}
renderMobile={mobile}
renderGutter={gutter}
gutterPadding={0}
mobileView
/>
</Box>
)
//return <DeviceCardList devices={grpDevs} refreshCallback={loadDevs} showMobile={true} />; //return <DeviceCardList devices={grpDevs} refreshCallback={loadDevs} showMobile={true} />;
}; };
@ -141,4 +210,4 @@ export default function GroupDrawer(props: Props) {
/> />
</React.Fragment> </React.Fragment>
); );
} }

View file

@ -26,12 +26,10 @@ import { useGlobalState } from "providers";
import { import {
IsAdaptiveAgriculture, IsAdaptiveAgriculture,
// hasTutorialPlaylist, // hasTutorialPlaylist,
// IsAdaptiveAgriculture, IsAdCon,
// IsAdCon,
// isBXT, // isBXT,
IsMiVent, IsMiVent,
IsOmniAir, IsOmniAir,
// IsOmniAir
} from "services/whiteLabel"; } from "services/whiteLabel";
import MiningIcon from "products/ventilation/MiningIcon"; import MiningIcon from "products/ventilation/MiningIcon";
import { useAuth0 } from "@auth0/auth0-react"; import { useAuth0 } from "@auth0/auth0-react";
@ -144,6 +142,7 @@ export default function SideNavigator(props: Props) {
const isMiVent = IsMiVent(); const isMiVent = IsMiVent();
const isAg = IsAdaptiveAgriculture() const isAg = IsAdaptiveAgriculture()
const isMiPCA = IsOmniAir() const isMiPCA = IsOmniAir()
const isAdCon = IsAdCon()
return ( return (
<List className={classes.list} component="nav"> <List className={classes.list} component="nav">
{(isAg || user.hasFeature("admin")) && ( {(isAg || user.hasFeature("admin")) && (
@ -238,7 +237,7 @@ export default function SideNavigator(props: Props) {
</ListItemButton> </ListItemButton>
</Tooltip> </Tooltip>
)} )}
{(IsOmniAir() || user.hasFeature("admin")) && ( {(isMiPCA || user.hasFeature("admin")) && (
<Tooltip title="Aviation Map" placement="right"> <Tooltip title="Aviation Map" placement="right">
<ListItemButton <ListItemButton
id="tour-aviation-map" id="tour-aviation-map"
@ -248,7 +247,21 @@ export default function SideNavigator(props: Props) {
<ListItemIcon> <ListItemIcon>
<AirportMapIcon /> <AirportMapIcon />
</ListItemIcon> </ListItemIcon>
{open && <ListItemText primary="Visual Farm" />} {open && <ListItemText primary="Airport Map" />}
</ListItemButton>
</Tooltip>
)}
{(isAdCon || user.hasFeature("admin")) && (
<Tooltip title="Construction Map" placement="right">
<ListItemButton
id="tour-construction-map"
onClick={() => goTo("/constructionMap")}
classes={getClasses("/constructionMap")}
>
<ListItemIcon>
<FieldsIcon />
</ListItemIcon>
{open && <ListItemText primary="Construction Map" />}
</ListItemButton> </ListItemButton>
</Tooltip> </Tooltip>
)} )}

View file

@ -51,6 +51,7 @@ export default function DevicePage() {
const [addComponentManualDialogOpen, setAddComponentManualDialogOpen] = useState(false) const [addComponentManualDialogOpen, setAddComponentManualDialogOpen] = useState(false)
const loadDevice = () => { const loadDevice = () => {
console.log("load device page data")
if (loading) return if (loading) return
setLoading(true) setLoading(true)
deviceAPI.getPageData(deviceID, getContextKeys(), getContextTypes()).then(resp => { deviceAPI.getPageData(deviceID, getContextKeys(), getContextTypes()).then(resp => {