From 0cd0921c638550112d5cab160e7328484803b27a Mon Sep 17 00:00:00 2001 From: Carter Date: Mon, 26 May 2025 13:55:48 -0600 Subject: [PATCH 01/20] formatted column titles to have a size grabber thing --- src/common/ResponsiveTable.tsx | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/src/common/ResponsiveTable.tsx b/src/common/ResponsiveTable.tsx index 628836c..de6ae6a 100644 --- a/src/common/ResponsiveTable.tsx +++ b/src/common/ResponsiveTable.tsx @@ -139,7 +139,6 @@ export default function ResponsiveTable(props: Props) { 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 endTitleElement = typeof(props.endTitleElement) === "function" ? props.endTitleElement() : props.endTitleElement const isMobile = useMobile() @@ -423,9 +422,9 @@ export default function ResponsiveTable(props: Props) { const sortKey = column.sortKey ? column.sortKey : column.title.toLowerCase() if (sortKey === orderBy) { if (order === "asc") { - return + return } else { - return + return } } return null; @@ -487,11 +486,24 @@ export default function ResponsiveTable(props: Props) { return ( !column.disableSort && columnClick(column)} - sx={{ cursor: column.disableSort ? "default" : "pointer" }} + style={{ border: "1px solid red" }} + // onClick={() => !column.disableSort && columnClick(column)} + // sx={{ cursor: column.disableSort ? "default" : "pointer" }} > - - {column.title} {showOrderIcon(column)} + + !column.disableSort && columnClick(column)} + sx={{ cursor: column.disableSort ? "default" : "pointer" }} + > + {column.title} {showOrderIcon(column)} + + + | + ) From cefb34dbbb075acbc7e5edeb4eb13fbc4d7269f0 Mon Sep 17 00:00:00 2001 From: Carter Date: Tue, 27 May 2025 11:08:50 -0600 Subject: [PATCH 02/20] groups tab is now saved to session storage --- src/pages/Devices.tsx | 37 +++++++++++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/src/pages/Devices.tsx b/src/pages/Devices.tsx index 9e8bb0d..e500cef 100644 --- a/src/pages/Devices.tsx +++ b/src/pages/Devices.tsx @@ -27,6 +27,8 @@ import StatusSen5x from "common/StatusSen5x"; import StatusDust from "common/StatusDust"; import StatusGas from "common/StatusGas"; import { cloneDeep } from "lodash"; +import { or } from "utils"; +import LoadingScreen from "app/LoadingScreen"; const useStyles = makeStyles((theme: Theme) => { return ({ @@ -140,9 +142,22 @@ export default function Devices() { // const [totalGroups, setTotalGroups] = useState(0); const [groupPermissions, setGroupPermissions] = useState([]) + const [groupsLoaded, setGroupsLoaded] = useState(false) const groupID = useParams<{ groupID: string }>()?.groupID ?? "all"; - const [tab, setTab] = useState(groupID==="all" ? groupID : groupID); + // const [tab, setTab] = useState(groupID==="all" ? groupID : groupID); + const [tab, setTab] = useState(() => { + console.log("groupID: "+groupID) + if (groupID!=="all") return groupID + const stored = sessionStorage.getItem(location.pathname+"-groups-tab"); + console.log("stored: "+stored) + return stored !== null ? stored : "all"; + }); + + useEffect(() => { + console.log(tab) + sessionStorage.setItem(location.pathname+"-groups-tab", tab); + }, [tab]); const [selectedGroup, setSelectedGroup] = useState(undefined); const [groupSettingsMode, setGroupSettingsMode] = useState< @@ -184,7 +199,7 @@ export default function Devices() { useEffect(() => { setGroupPermissions([]) - if (tab === "all") return + if (tab === "all" || !getGroup()) return groupAPI.getGroupPermissions(getGroup().id()).then(resp => { setGroupPermissions(resp.data.permissions) }) @@ -232,7 +247,7 @@ export default function Devices() { }; const getKeys = () => { - if (tab !== "all") { + if (tab !== "all" && getGroup()) { let keys = getContextKeys() //keys.splice(keys.length - 1, 0, getGroup().id().toString()); keys.push(getGroup().id().toString()); @@ -274,11 +289,13 @@ export default function Devices() { updateGroups(newGroups) }).finally(() => { setGroupsLoading(false) + setGroupsLoaded(true) }) } const loadDevices = () => { setDevicesLoading(true) + if (!groupsLoaded) return deviceAPI.list( limit, page*limit, @@ -316,7 +333,7 @@ export default function Devices() { useEffect(() => { loadDevices() - }, [limit, page, order, orderBy, fieldContains, search, tab, as]) + }, [limit, page, order, orderBy, fieldContains, search, tab, as, groupsLoaded]) useEffect(() => { loadGroups() @@ -703,6 +720,14 @@ export default function Devices() { ) } + useEffect(() => { + console.log('Current tab value:', tab, typeof tab); + }, [tab]); + + if (!groupsLoaded) return ( + + ) + return( }/> : groups.map((group, index) => { if (group.id()) return ( - {group.name()}} key={"group-tab-"+index}/> + {group.name()}} key={"group-tab-"+index}/> ) })} } onClick={() => openGroupSettings(undefined, "add")} /> @@ -784,7 +809,7 @@ export default function Devices() { newDevices.push(Device.create(device)) }) setDevices(currentRows.concat(newDevices)) - }).catch(err => { + }).catch(_err => { }) }} From e35e6992943659be322cfc76ee255a66f0e63a44 Mon Sep 17 00:00:00 2001 From: Carter Date: Fri, 30 May 2025 14:16:29 -0600 Subject: [PATCH 03/20] fixed sorting Peak Height in cable estimator --- src/cableEstimator/cableEstimator.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cableEstimator/cableEstimator.tsx b/src/cableEstimator/cableEstimator.tsx index 17f909c..86a27b7 100644 --- a/src/cableEstimator/cableEstimator.tsx +++ b/src/cableEstimator/cableEstimator.tsx @@ -140,7 +140,7 @@ export default function CableEstimator() { }, { title: "Peak Height" + (getDistanceUnit() === pond.DistanceUnit.DISTANCE_UNIT_FEET ? "(ft)" : "(m)"), - sortKey: "PeakHeight", + sortKey: "Peak", render: (row: jsonBin) => {distanceConversion(row.Peak).toFixed(2)} }, { From 6cc29c37c77b6c20b09933966d34c741a2ce0a3d Mon Sep 17 00:00:00 2001 From: Carter Date: Tue, 3 Jun 2025 09:16:49 -0600 Subject: [PATCH 04/20] drag resize is working --- src/common/ResponsiveTable.tsx | 113 +++++++++++++++++++++++++++++++-- src/pages/Devices.tsx | 21 +++--- 2 files changed, 118 insertions(+), 16 deletions(-) diff --git a/src/common/ResponsiveTable.tsx b/src/common/ResponsiveTable.tsx index b2fa240..c2c2bf5 100644 --- a/src/common/ResponsiveTable.tsx +++ b/src/common/ResponsiveTable.tsx @@ -148,6 +148,14 @@ export default function ResponsiveTable(props: Props) { const [handler, setHandler] = useState(undefined); const [columnAnchor, setColumnAnchor] = useState(null) + const [columnSizes, setColumnSizes] = useState>(new Map()) + const [tempWidth, setTempWidth] = useState(undefined) + const [tempWidth2, setTempWidth2] = useState(undefined) + const [dragX, setDragX] = useState(0) + const [dragStart, setDragStart] = useState(undefined) + const [rowWidths, setRowWidths] = useState([]) + const [dragIndex, setDragIndex] = useState(undefined) + const filterKey = window.location.pathname.split('/').pop() + "-table-filter-list"; const [filterList, setFilterList] = useState(() => { @@ -298,8 +306,7 @@ export default function ResponsiveTable(props: Props) { } return ( Object.keys(row).map((key, index) => { - let value = row[key as keyof typeof row] - + const value = row[key as keyof typeof row] return ( @@ -345,7 +352,6 @@ export default function ResponsiveTable(props: Props) { padding: gutterPadding }} onClick={(event) => handleCollapse(index, event)} - // style={{pre}} > (props: Props) { return null; } + const resizeClick = (event: React.MouseEvent, index: number) => { + console.log("click!") + // console.log(event.currentTarget.clientWidth) + // console.log(event.currentTarget.offsetWidth) + // console.log(event.currentTarget.scrollWidth) + // console.log(event.currentTarget.parentElement?.clientWidth) + // console.log(event.currentTarget.parentElement?.offsetWidth) + // console.log(event.currentTarget.parentElement?.scrollWidth) + // console.log(event.currentTarget.parentElement?.childNodes.keys) + let newWidths: number[] = [] + event.currentTarget.parentElement?.parentElement?.parentElement?.childNodes.forEach(node => { + // console.log(node.textContent) + // console.log(node) + if (node instanceof HTMLElement) { + // console.log(node.clientWidth); + newWidths.push(node.clientWidth) + } + }) + // console.log(event.clientX) + setRowWidths(newWidths) + setTempWidth(event.currentTarget.parentElement?.clientWidth) + setDragStart(event.clientX) + setDragIndex(index) + + window.addEventListener('mousemove', resizeDrag); + window.addEventListener('mouseup', resizeUnclick); + // return ( + + // ) + } + + // useEffect(() => { + // console.log(tempWidth) + // console.log(tempWidth) + // }, [tempWidth]) + + const resizeUnclick = () => { + console.log("unclick!") + // setDragStart(undefined) + window.removeEventListener('mousemove', resizeDrag); + window.removeEventListener('mouseup', resizeUnclick); + } + + const resizeDrag = (e: any) => { + if (!dragIndex) return + if (!rowWidths[dragIndex]) return + if (!rowWidths[dragIndex+1]) return + if (!dragStart) return + + console.log((dragStart - e.clientX)) + + let newWidths: number[] = [...rowWidths] + newWidths[dragIndex] = newWidths[dragIndex] - (dragStart - e.clientX) + newWidths[dragIndex+1] = newWidths[dragIndex+1] + (dragStart - e.clientX) + setRowWidths(newWidths) + // if (!dragStart) return + // console.log(dragStart) + // console.log(e.clientX) + // if (dragStart) console.log(dragStart - e.clientX) + // console.log("drag!") + // if (dragStart && tempWidth) setTempWidth(tempWidth - (dragStart - e.clientX)) + // return ( + + // ) + } + + useEffect(() => { + console.log(rowWidths) + }, [rowWidths]) + return ( @@ -501,6 +577,7 @@ export default function ResponsiveTable(props: Props) { resizeClick(event, index)} > | @@ -559,15 +636,41 @@ export default function ResponsiveTable(props: Props) { } {columns ? columns.map((column, j) => { + // console.log(j) if (filterList.includes(column.title) || column.hidden) return null if (column.render) return ( - + // + {column.render(row)} ) + // if (column.render && j!==undefined && j === 1) return ( + // // + // + // {column.render(row)} + // + // ) + // if (column.render && j!==undefined && j === 2) return ( + // // + // + // {column.render(row)} + // + // ) + // if (column.render && j!==undefined && j === 3) return ( + // // + // + // {column.render(row)} + // + // ) + // if (column.render) return ( + // // + // + // {column.render(row)} + // + // ) return ( - {Object.values(row)[j].toString()} + {Object.values(row)[j] && Object.values(row)[j].toString()} ) }) diff --git a/src/pages/Devices.tsx b/src/pages/Devices.tsx index e500cef..2bcb7f9 100644 --- a/src/pages/Devices.tsx +++ b/src/pages/Devices.tsx @@ -27,7 +27,6 @@ import StatusSen5x from "common/StatusSen5x"; import StatusDust from "common/StatusDust"; import StatusGas from "common/StatusGas"; import { cloneDeep } from "lodash"; -import { or } from "utils"; import LoadingScreen from "app/LoadingScreen"; const useStyles = makeStyles((theme: Theme) => { @@ -388,12 +387,14 @@ export default function Devices() { let columns: Column[] = [ { title: "State", + // cellStyle: {width: 100000}, // sortKey: "state", render: (device: Device) => { const status = device.status ?? pond.DeviceStatus.create() const deviceStateHelper = getDeviceStateHelper(status.state); return ( - + // + {deviceStateHelper.icon} ) @@ -408,10 +409,12 @@ export default function Devices() { }, { title: "Device", + cellStyle: { width: 160 }, sortKey: "name", render: (device: Device) => { return ( - + // + { const description = device.settings?.description ?? "" let size = (hasCo2 && !groupGas) ? 26 : 36 return ( - + {description.length > size @@ -697,9 +701,7 @@ export default function Devices() { dense > - + @@ -709,10 +711,7 @@ export default function Devices() { dense > - + From 4d26cb0f05ade0ec956a98558762649604aba9e2 Mon Sep 17 00:00:00 2001 From: Carter Date: Tue, 3 Jun 2025 09:48:35 -0600 Subject: [PATCH 05/20] using referece to get widths and darg indexes --- src/common/ResponsiveTable.tsx | 103 ++++++++------------------------- src/pages/Devices.tsx | 8 +-- 2 files changed, 27 insertions(+), 84 deletions(-) diff --git a/src/common/ResponsiveTable.tsx b/src/common/ResponsiveTable.tsx index c2c2bf5..bb13c51 100644 --- a/src/common/ResponsiveTable.tsx +++ b/src/common/ResponsiveTable.tsx @@ -1,7 +1,7 @@ import { Box, Button, 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 { ArrowDownward, ArrowUpward, ChevronRight, Close, Search, ViewColumn } from "@mui/icons-material" -import { useEffect, useState } from "react"; +import { useEffect, useRef, useState } from "react"; import React from "react"; import { useMobile } from "hooks"; import classNames from "classnames"; @@ -147,14 +147,11 @@ export default function ResponsiveTable(props: Props) { const [openGutters, setOpenGutters] = useState([]) const [handler, setHandler] = useState(undefined); const [columnAnchor, setColumnAnchor] = useState(null) - - const [columnSizes, setColumnSizes] = useState>(new Map()) - const [tempWidth, setTempWidth] = useState(undefined) - const [tempWidth2, setTempWidth2] = useState(undefined) - const [dragX, setDragX] = useState(0) - const [dragStart, setDragStart] = useState(undefined) + const [rowWidths, setRowWidths] = useState([]) - const [dragIndex, setDragIndex] = useState(undefined) + const dragIndexRef = useRef(undefined); + const dragStartRef = useRef(undefined); + const rowWidthsRef = useRef([]); const filterKey = window.location.pathname.split('/').pop() + "-table-filter-list"; @@ -437,75 +434,46 @@ export default function ResponsiveTable(props: Props) { } const resizeClick = (event: React.MouseEvent, index: number) => { - console.log("click!") - // console.log(event.currentTarget.clientWidth) - // console.log(event.currentTarget.offsetWidth) - // console.log(event.currentTarget.scrollWidth) - // console.log(event.currentTarget.parentElement?.clientWidth) - // console.log(event.currentTarget.parentElement?.offsetWidth) - // console.log(event.currentTarget.parentElement?.scrollWidth) - // console.log(event.currentTarget.parentElement?.childNodes.keys) + let newWidths: number[] = [] event.currentTarget.parentElement?.parentElement?.parentElement?.childNodes.forEach(node => { - // console.log(node.textContent) - // console.log(node) if (node instanceof HTMLElement) { - // console.log(node.clientWidth); newWidths.push(node.clientWidth) } }) - // console.log(event.clientX) - setRowWidths(newWidths) - setTempWidth(event.currentTarget.parentElement?.clientWidth) - setDragStart(event.clientX) - setDragIndex(index) + + rowWidthsRef.current = newWidths + dragIndexRef.current = index; + dragStartRef.current = event.clientX; window.addEventListener('mousemove', resizeDrag); window.addEventListener('mouseup', resizeUnclick); - // return ( - - // ) } - // useEffect(() => { - // console.log(tempWidth) - // console.log(tempWidth) - // }, [tempWidth]) - const resizeUnclick = () => { - console.log("unclick!") - // setDragStart(undefined) + dragIndexRef.current = undefined; + dragStartRef.current = undefined; window.removeEventListener('mousemove', resizeDrag); window.removeEventListener('mouseup', resizeUnclick); } const resizeDrag = (e: any) => { - if (!dragIndex) return - if (!rowWidths[dragIndex]) return - if (!rowWidths[dragIndex+1]) return + // console.log(dragIndex) + const index = dragIndexRef.current; + const dragStart = dragStartRef.current + const rowWidths = rowWidthsRef.current + if (!index) return + if (!rowWidths[index]) return + if (!rowWidths[index+1]) return if (!dragStart) return - console.log((dragStart - e.clientX)) - let newWidths: number[] = [...rowWidths] - newWidths[dragIndex] = newWidths[dragIndex] - (dragStart - e.clientX) - newWidths[dragIndex+1] = newWidths[dragIndex+1] + (dragStart - e.clientX) + newWidths[index] = newWidths[index] - (dragStart - e.clientX) + newWidths[index+1] = newWidths[index+1] + (dragStart - e.clientX) setRowWidths(newWidths) - // if (!dragStart) return - // console.log(dragStart) - // console.log(e.clientX) - // if (dragStart) console.log(dragStart - e.clientX) - // console.log("drag!") - // if (dragStart && tempWidth) setTempWidth(tempWidth - (dragStart - e.clientX)) - // return ( - - // ) + } - useEffect(() => { - console.log(rowWidths) - }, [rowWidths]) - return (
@@ -562,7 +530,7 @@ export default function ResponsiveTable(props: Props) { return ( !column.disableSort && columnClick(column)} // sx={{ cursor: column.disableSort ? "default" : "pointer" }} > @@ -639,35 +607,10 @@ export default function ResponsiveTable(props: Props) { // console.log(j) if (filterList.includes(column.title) || column.hidden) return null if (column.render) return ( - // {column.render(row)} ) - // if (column.render && j!==undefined && j === 1) return ( - // // - // - // {column.render(row)} - // - // ) - // if (column.render && j!==undefined && j === 2) return ( - // // - // - // {column.render(row)} - // - // ) - // if (column.render && j!==undefined && j === 3) return ( - // // - // - // {column.render(row)} - // - // ) - // if (column.render) return ( - // // - // - // {column.render(row)} - // - // ) return ( {Object.values(row)[j] && Object.values(row)[j].toString()} diff --git a/src/pages/Devices.tsx b/src/pages/Devices.tsx index 2bcb7f9..8631451 100644 --- a/src/pages/Devices.tsx +++ b/src/pages/Devices.tsx @@ -393,8 +393,8 @@ export default function Devices() { const status = device.status ?? pond.DeviceStatus.create() const deviceStateHelper = getDeviceStateHelper(status.state); return ( - // - + + {/* */} {deviceStateHelper.icon} ) @@ -413,8 +413,8 @@ export default function Devices() { sortKey: "name", render: (device: Device) => { return ( - // - + + {/* // */} Date: Tue, 3 Jun 2025 09:50:36 -0600 Subject: [PATCH 06/20] got rid of last column size grabber --- src/common/ResponsiveTable.tsx | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/common/ResponsiveTable.tsx b/src/common/ResponsiveTable.tsx index bb13c51..e6d1f7c 100644 --- a/src/common/ResponsiveTable.tsx +++ b/src/common/ResponsiveTable.tsx @@ -543,12 +543,14 @@ export default function ResponsiveTable(props: Props) { > {column.title} {showOrderIcon(column)} - resizeClick(event, index)} - > - | - + {index < columns.length-1 && + resizeClick(event, index)} + > + | + + } ) From 5229aff9ab53724c57136df846bc77c5e7bbb7ea Mon Sep 17 00:00:00 2001 From: Carter Date: Tue, 3 Jun 2025 12:21:02 -0600 Subject: [PATCH 07/20] minor spacing changes --- src/common/ResponsiveTable.tsx | 2 +- src/pages/Devices.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/common/ResponsiveTable.tsx b/src/common/ResponsiveTable.tsx index e6d1f7c..e7e46ce 100644 --- a/src/common/ResponsiveTable.tsx +++ b/src/common/ResponsiveTable.tsx @@ -609,7 +609,7 @@ export default function ResponsiveTable(props: Props) { // console.log(j) if (filterList.includes(column.title) || column.hidden) return null if (column.render) return ( - + {column.render(row)} ) diff --git a/src/pages/Devices.tsx b/src/pages/Devices.tsx index 8631451..8790f68 100644 --- a/src/pages/Devices.tsx +++ b/src/pages/Devices.tsx @@ -431,7 +431,7 @@ export default function Devices() { const description = device.settings?.description ?? "" let size = (hasCo2 && !groupGas) ? 26 : 36 return ( - + {description.length > size From 6a1c61606c6115fe30e47590269162bbb62a43a0 Mon Sep 17 00:00:00 2001 From: Carter Date: Tue, 3 Jun 2025 12:27:07 -0600 Subject: [PATCH 08/20] stopped resize selected from text highlighting --- src/common/ResponsiveTable.tsx | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/common/ResponsiveTable.tsx b/src/common/ResponsiveTable.tsx index e7e46ce..8c26891 100644 --- a/src/common/ResponsiveTable.tsx +++ b/src/common/ResponsiveTable.tsx @@ -474,6 +474,10 @@ export default function ResponsiveTable(props: Props) { } + useEffect(() => { + + }) + return (
@@ -528,12 +532,7 @@ export default function ResponsiveTable(props: Props) { columns.map((column, index) => { if (filterList.includes(column.title) || column.hidden) return null return ( - !column.disableSort && columnClick(column)} - // sx={{ cursor: column.disableSort ? "default" : "pointer" }} - > + (props: Props) { {index < columns.length-1 && resizeClick(event, index)} > | From 5b555638869be791e8759854be2918fde85eeeb4 Mon Sep 17 00:00:00 2001 From: Carter Date: Wed, 4 Jun 2025 10:43:48 -0600 Subject: [PATCH 09/20] rendering cells without width instead of skipping render to fix index issue --- src/common/ResponsiveTable.tsx | 28 +++++++++++++++------------- src/pages/Devices.tsx | 9 +++++++-- 2 files changed, 22 insertions(+), 15 deletions(-) diff --git a/src/common/ResponsiveTable.tsx b/src/common/ResponsiveTable.tsx index 8c26891..a26cfe4 100644 --- a/src/common/ResponsiveTable.tsx +++ b/src/common/ResponsiveTable.tsx @@ -278,9 +278,7 @@ export default function ResponsiveTable(props: Props) { } const renderMobileRow = (row: T, index: number) => { - if (renderMobile) return ( - renderMobile(row, index) - ) + if (renderMobile) return renderMobile(row, index) if (columns) { return ( @@ -441,6 +439,9 @@ export default function ResponsiveTable(props: Props) { newWidths.push(node.clientWidth) } }) + console.log(index) + console.log(newWidths.length) + console.log(newWidths) rowWidthsRef.current = newWidths dragIndexRef.current = index; @@ -458,15 +459,16 @@ export default function ResponsiveTable(props: Props) { } const resizeDrag = (e: any) => { - // console.log(dragIndex) const index = dragIndexRef.current; const dragStart = dragStartRef.current const rowWidths = rowWidthsRef.current - if (!index) return - if (!rowWidths[index]) return - if (!rowWidths[index+1]) return + if (index === undefined) return + if (rowWidths[index] === undefined) return + if (rowWidths[index+1] === undefined) return if (!dragStart) return + console.log("dragging") + let newWidths: number[] = [...rowWidths] newWidths[index] = newWidths[index] - (dragStart - e.clientX) newWidths[index+1] = newWidths[index+1] + (dragStart - e.clientX) @@ -474,10 +476,6 @@ export default function ResponsiveTable(props: Props) { } - useEffect(() => { - - }) - return (
@@ -530,7 +528,9 @@ export default function ResponsiveTable(props: Props) { { renderGutter && } { columns ? columns.map((column, index) => { - if (filterList.includes(column.title) || column.hidden) return null + if (filterList.includes(column.title) || column.hidden) return ( + + ) return ( @@ -606,7 +606,9 @@ export default function ResponsiveTable(props: Props) { {columns ? columns.map((column, j) => { // console.log(j) - if (filterList.includes(column.title) || column.hidden) return null + if (filterList.includes(column.title) || column.hidden) return ( + + ) if (column.render) return ( {column.render(row)} diff --git a/src/pages/Devices.tsx b/src/pages/Devices.tsx index 8790f68..8cdacc3 100644 --- a/src/pages/Devices.tsx +++ b/src/pages/Devices.tsx @@ -57,6 +57,11 @@ const useStyles = makeStyles((theme: Theme) => { width: theme.spacing(10) // justifyContent: "center", }, + deviceContainer: { + margin: theme.spacing(1), + display: "flex", + width: theme.spacing(10) + }, descriptionCellContainer: { margin: theme.spacing(1), marginLeft: theme.spacing(2), @@ -68,7 +73,7 @@ const useStyles = makeStyles((theme: Theme) => { margin: theme.spacing(1), marginLeft: theme.spacing(2), display: "flex", - width: theme.spacing(18) + minWidth: theme.spacing(10) // justifyContent: "center", }, green: { @@ -413,7 +418,7 @@ export default function Devices() { sortKey: "name", render: (device: Device) => { return ( - + {/* // */} Date: Wed, 4 Jun 2025 10:55:14 -0600 Subject: [PATCH 10/20] using a loop to determine the next table cell to shrink --- src/common/ResponsiveTable.tsx | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/common/ResponsiveTable.tsx b/src/common/ResponsiveTable.tsx index a26cfe4..b60f6af 100644 --- a/src/common/ResponsiveTable.tsx +++ b/src/common/ResponsiveTable.tsx @@ -471,7 +471,14 @@ export default function ResponsiveTable(props: Props) { let newWidths: number[] = [...rowWidths] newWidths[index] = newWidths[index] - (dragStart - e.clientX) - newWidths[index+1] = newWidths[index+1] + (dragStart - e.clientX) + // newWidths[index+1] = newWidths[index+1] + (dragStart - e.clientX) + newWidths.every((width, j) => { + if (j <= index || width === 0) return true + else if (newWidths[j] !== undefined) { + newWidths[j] = newWidths[j] + (dragStart - e.clientX) + return false + } + }) setRowWidths(newWidths) } From e1b3afd543f76e87045e91fc17bdabacb72314ae Mon Sep 17 00:00:00 2001 From: Carter Date: Wed, 4 Jun 2025 10:56:06 -0600 Subject: [PATCH 11/20] code cleaning --- src/common/ResponsiveTable.tsx | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/common/ResponsiveTable.tsx b/src/common/ResponsiveTable.tsx index b60f6af..4a6e85b 100644 --- a/src/common/ResponsiveTable.tsx +++ b/src/common/ResponsiveTable.tsx @@ -401,7 +401,6 @@ export default function ResponsiveTable(props: Props) { const columnClick = (column: Column) => { const sortKey = column.sortKey ? column.sortKey : column.title.toLowerCase() - // console.log(column.sortKey) if (setOrderBy) { if (orderBy === sortKey && setOrder && order) { if (order === "desc") { @@ -409,13 +408,11 @@ export default function ResponsiveTable(props: Props) { } else { setOrderBy("") } - // setOrder(order === "asc" ? "desc" : "asc") } else { if (setOrder) setOrder("desc") setOrderBy(sortKey) } } - // if (setOrder && order) setOrder(order === "asc" ? "desc" : "asc") } const showOrderIcon = (column: Column) => { @@ -439,9 +436,6 @@ export default function ResponsiveTable(props: Props) { newWidths.push(node.clientWidth) } }) - console.log(index) - console.log(newWidths.length) - console.log(newWidths) rowWidthsRef.current = newWidths dragIndexRef.current = index; @@ -467,11 +461,8 @@ export default function ResponsiveTable(props: Props) { if (rowWidths[index+1] === undefined) return if (!dragStart) return - console.log("dragging") - let newWidths: number[] = [...rowWidths] newWidths[index] = newWidths[index] - (dragStart - e.clientX) - // newWidths[index+1] = newWidths[index+1] + (dragStart - e.clientX) newWidths.every((width, j) => { if (j <= index || width === 0) return true else if (newWidths[j] !== undefined) { @@ -612,7 +603,6 @@ export default function ResponsiveTable(props: Props) { } {columns ? columns.map((column, j) => { - // console.log(j) if (filterList.includes(column.title) || column.hidden) return ( ) From b710c03edecaee182de969a43049c325d8d03ec2 Mon Sep 17 00:00:00 2001 From: Carter Date: Wed, 4 Jun 2025 12:34:23 -0600 Subject: [PATCH 12/20] made "resizeable" and optional prop for the responsive table --- src/common/ResponsiveTable.tsx | 9 ++++++--- src/pages/Devices.tsx | 1 + 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/common/ResponsiveTable.tsx b/src/common/ResponsiveTable.tsx index 4a6e85b..32fd229 100644 --- a/src/common/ResponsiveTable.tsx +++ b/src/common/ResponsiveTable.tsx @@ -99,7 +99,8 @@ interface Props { order?: string; setOrder?: React.Dispatch>; endTitleElement?: string | JSX.Element | (() => string | JSX.Element); - loadMore?: () => void + loadMore?: () => void; + resizeable?: boolean; } export default function ResponsiveTable(props: Props) { @@ -133,13 +134,15 @@ export default function ResponsiveTable(props: Props) { setOrderBy, order, setOrder, - loadMore + loadMore, + // resizeable, } = 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 endTitleElement = typeof(props.endTitleElement) === "function" ? props.endTitleElement() : props.endTitleElement + const resizeable = props.resizeable === undefined ? false : props.resizeable const isMobile = useMobile() @@ -540,7 +543,7 @@ export default function ResponsiveTable(props: Props) { > {column.title} {showOrderIcon(column)} - {index < columns.length-1 && + {index < columns.length-1 && resizeable && resizeClick(event, index)} diff --git a/src/pages/Devices.tsx b/src/pages/Devices.tsx index 8cdacc3..8236074 100644 --- a/src/pages/Devices.tsx +++ b/src/pages/Devices.tsx @@ -782,6 +782,7 @@ export default function Devices() { orderBy={orderBy} setOrderBy={setOrderBy} endTitleElement={preferencesButton} + resizeable loadMore={()=>{ let currentRows = cloneDeep(devices) deviceAPI.list( From f328c4036abc5c95b26d434ee6d5ce2c363e5344 Mon Sep 17 00:00:00 2001 From: Carter Date: Wed, 4 Jun 2025 14:15:04 -0600 Subject: [PATCH 13/20] directing webserver traffic to indexV2.html to force V1 users to re-cache --- indexV2.html | 14 ++++++++++++++ nginx.conf | 7 ++++++- 2 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 indexV2.html diff --git a/indexV2.html b/indexV2.html new file mode 100644 index 0000000..31b4ca1 --- /dev/null +++ b/indexV2.html @@ -0,0 +1,14 @@ + + + + + + + Adaptive Dashboard + + + +
+ + + diff --git a/nginx.conf b/nginx.conf index 8e8fc75..adb8457 100644 --- a/nginx.conf +++ b/nginx.conf @@ -61,7 +61,12 @@ http { expires $cache_expires; root /usr/share/nginx/html; - try_files $uri /index.html; + try_files $uri /indexV2.html; + + location = /index.html { + return 301 /indexV2.html; + } + } # Healthcheck From 43b519ca37334f3a47a0cdf3282f391785b504b3 Mon Sep 17 00:00:00 2001 From: Carter Date: Wed, 4 Jun 2025 15:54:43 -0600 Subject: [PATCH 14/20] column widths save to local storage --- src/common/ResponsiveTable.tsx | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/common/ResponsiveTable.tsx b/src/common/ResponsiveTable.tsx index 32fd229..a065606 100644 --- a/src/common/ResponsiveTable.tsx +++ b/src/common/ResponsiveTable.tsx @@ -151,7 +151,15 @@ export default function ResponsiveTable(props: Props) { const [handler, setHandler] = useState(undefined); const [columnAnchor, setColumnAnchor] = useState(null) - const [rowWidths, setRowWidths] = useState([]) + const rowKey = window.location.pathname.split('/').pop() + "-table-row-widths"; + const [rowWidths, setRowWidths] = useState(() => { + const saved = localStorage.getItem(rowKey); + return saved ? JSON.parse(saved) : []; + }) + useEffect(() => { + localStorage.setItem(rowKey, JSON.stringify(rowWidths)); + }, [rowWidths]) + const dragIndexRef = useRef(undefined); const dragStartRef = useRef(undefined); const rowWidthsRef = useRef([]); From 371185e8a545fd12f579812e497778316adb1070 Mon Sep 17 00:00:00 2001 From: Carter Date: Wed, 4 Jun 2025 16:03:14 -0600 Subject: [PATCH 15/20] can reset widths to default from the column settings menu --- src/common/ResponsiveTable.tsx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/common/ResponsiveTable.tsx b/src/common/ResponsiveTable.tsx index a065606..f904e0a 100644 --- a/src/common/ResponsiveTable.tsx +++ b/src/common/ResponsiveTable.tsx @@ -684,9 +684,8 @@ export default function ResponsiveTable(props: Props) { filter(column.title)} key={"column-list-"+index} - aria-label="Open User Settings" dense - sx={{ marginLeft: -0.75 }} + sx={{ marginLeft: -0.75, paddingRight: 3 }} > (props: Props) { ) })} + setRowWidths([])}> + + Reset Widths + + ) From cfe05f8517c5d163f9c19db6f797fac464a3b1e5 Mon Sep 17 00:00:00 2001 From: Carter Date: Wed, 4 Jun 2025 16:18:06 -0600 Subject: [PATCH 16/20] back to original index --- nginx.conf | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/nginx.conf b/nginx.conf index adb8457..8e8fc75 100644 --- a/nginx.conf +++ b/nginx.conf @@ -61,12 +61,7 @@ http { expires $cache_expires; root /usr/share/nginx/html; - try_files $uri /indexV2.html; - - location = /index.html { - return 301 /indexV2.html; - } - + try_files $uri /index.html; } # Healthcheck From 727a20292fccf892db682a05e64be853bc6f228c Mon Sep 17 00:00:00 2001 From: Carter Date: Wed, 4 Jun 2025 16:33:18 -0600 Subject: [PATCH 17/20] brought it back to V2, added it to vite config --- nginx.conf | 7 ++++++- vite.config.ts | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/nginx.conf b/nginx.conf index 8e8fc75..adb8457 100644 --- a/nginx.conf +++ b/nginx.conf @@ -61,7 +61,12 @@ http { expires $cache_expires; root /usr/share/nginx/html; - try_files $uri /index.html; + try_files $uri /indexV2.html; + + location = /index.html { + return 301 /indexV2.html; + } + } # Healthcheck diff --git a/vite.config.ts b/vite.config.ts index 551f1ce..ec8ea02 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -14,7 +14,7 @@ export default defineConfig({ globPatterns: ['**/*.{js,css,html,png,jpg,svg}'], // Cache all common asset types maximumFileSizeToCacheInBytes: 20 * 1024 * 1024, // 20 MiB cleanupOutdatedCaches: true, - navigateFallback: "/index.html", + navigateFallback: "/indexV2.html", runtimeCaching: [ { urlPattern: ({ request }) => request.destination === 'document', From 5545271322ae2d2e757ae5b37510eefc9604295e Mon Sep 17 00:00:00 2001 From: Carter Date: Thu, 5 Jun 2025 10:23:13 -0600 Subject: [PATCH 18/20] trying nginx conf change-up --- nginx.conf | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/nginx.conf b/nginx.conf index adb8457..13da466 100644 --- a/nginx.conf +++ b/nginx.conf @@ -55,13 +55,17 @@ http { listen 80; listen [::]:80; + root /usr/share/nginx/html; + index indexV2.html; + access_log /dev/stdout; error_log /dev/stderr error; expires $cache_expires; - root /usr/share/nginx/html; - try_files $uri /indexV2.html; + location / { + try_files $uri /indexV2.html; + } location = /index.html { return 301 /indexV2.html; From 9c94585de0d1d255d9eb2aec6351ccdc3ebf6770 Mon Sep 17 00:00:00 2001 From: Carter Date: Thu, 5 Jun 2025 10:38:03 -0600 Subject: [PATCH 19/20] trying nginx conf change-up --- nginx.conf | 21 ++++++++++++++------- src/pages/Devices.tsx | 15 --------------- 2 files changed, 14 insertions(+), 22 deletions(-) diff --git a/nginx.conf b/nginx.conf index 13da466..a2c0d11 100644 --- a/nginx.conf +++ b/nginx.conf @@ -52,27 +52,34 @@ http { } server { - listen 80; + listen 80; listen [::]:80; root /usr/share/nginx/html; index indexV2.html; - access_log /dev/stdout; - error_log /dev/stderr error; + access_log /dev/stdout; + error_log /dev/stderr error; expires $cache_expires; - location / { - try_files $uri /indexV2.html; - } - + # Redirect old /index.html requests to new file location = /index.html { return 301 /indexV2.html; } + # Serve indexV2.html directly without redirect loop + location = /indexV2.html { + root /usr/share/nginx/html; + } + + # Fallback for SPA routing — all unmatched routes go to indexV2.html + location / { + try_files $uri /indexV2.html; + } } + # Healthcheck server { listen 8080; diff --git a/src/pages/Devices.tsx b/src/pages/Devices.tsx index 8236074..972f451 100644 --- a/src/pages/Devices.tsx +++ b/src/pages/Devices.tsx @@ -151,18 +151,11 @@ export default function Devices() { const groupID = useParams<{ groupID: string }>()?.groupID ?? "all"; // const [tab, setTab] = useState(groupID==="all" ? groupID : groupID); const [tab, setTab] = useState(() => { - console.log("groupID: "+groupID) if (groupID!=="all") return groupID const stored = sessionStorage.getItem(location.pathname+"-groups-tab"); - console.log("stored: "+stored) return stored !== null ? stored : "all"; }); - useEffect(() => { - console.log(tab) - sessionStorage.setItem(location.pathname+"-groups-tab", tab); - }, [tab]); - const [selectedGroup, setSelectedGroup] = useState(undefined); const [groupSettingsMode, setGroupSettingsMode] = useState< "add" | "update" | "remove" | undefined @@ -373,10 +366,6 @@ export default function Devices() { return '/' + newSegments.join('/'); } - // useEffect(() => { - // console.log(devices) - // }, [devices]) - const toDevice = (device: Device) => { let url = getGroup() ? insertGroupContext(getGroup().id().toString(), device.id().toString()) : "" if (url.length < 1) url = device.id().toString() @@ -724,10 +713,6 @@ export default function Devices() { ) } - useEffect(() => { - console.log('Current tab value:', tab, typeof tab); - }, [tab]); - if (!groupsLoaded) return ( ) From a0bb90099c6bd883b47da1f66a9e8a9ce32a0d28 Mon Sep 17 00:00:00 2001 From: Carter Date: Thu, 5 Jun 2025 13:02:53 -0600 Subject: [PATCH 20/20] adding indexV2 to the build path --- vite.config.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/vite.config.ts b/vite.config.ts index ec8ea02..d347c76 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -2,6 +2,7 @@ import { defineConfig } from 'vite' import react from '@vitejs/plugin-react' import tsconfigPaths from 'vite-tsconfig-paths' import { VitePWA } from 'vite-plugin-pwa'; +import * as path from 'path' // ✅ Import path module // https://vitejs.dev/config/ export default defineConfig({ @@ -39,7 +40,12 @@ export default defineConfig({ outDir: './build', sourcemap: true, minify: false, - target: 'esnext' + target: 'esnext', + rollupOptions: { + input: { + main: path.resolve(__dirname, 'indexV2.html') + } + } }, esbuild: { keepNames: true, // Prevent function name mangling