From eb895b44ae434895445a9caca5c4ef7ddc9be420 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Sat, 12 Oct 2024 09:34:19 +0200 Subject: [PATCH 1/5] fix uom display for digital_out --- src/web/WebDataService.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/web/WebDataService.cpp b/src/web/WebDataService.cpp index e06eaf556..15fed15ed 100644 --- a/src/web/WebDataService.cpp +++ b/src/web/WebDataService.cpp @@ -422,11 +422,11 @@ void WebDataService::dashboard_data(AsyncWebServerRequest * request) { l.add(Helpers::render_boolean(s, true, true)); } else { dv["v"] = Helpers::transformNumFloat(sensor.value(), 0); + dv["u"] = sensor.uom(); } if (sensor.type() == AnalogSensor::AnalogType::COUNTER || sensor.type() >= AnalogSensor::AnalogType::DIGITAL_OUT) { dv["c"] = sensor.name(); } - dv["u"] = sensor.uom(); } } } From e71542d9aa51bbe408c90a614b22f3d611146150 Mon Sep 17 00:00:00 2001 From: proddy Date: Sun, 13 Oct 2024 22:45:12 +0100 Subject: [PATCH 2/5] formatting --- interface/src/utils/useInterval.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/interface/src/utils/useInterval.ts b/interface/src/utils/useInterval.ts index 61ed2c9e6..9b3c89bf2 100644 --- a/interface/src/utils/useInterval.ts +++ b/interface/src/utils/useInterval.ts @@ -4,9 +4,11 @@ import { useEffect, useRef } from 'react'; export const useInterval = (callback: () => void, delay: number) => { const intervalRef = useRef(null); const savedCallback = useRef<() => void>(callback); + useEffect(() => { savedCallback.current = callback; }, [callback]); + useEffect(() => { const tick = () => savedCallback.current(); if (typeof delay === 'number') { @@ -18,5 +20,6 @@ export const useInterval = (callback: () => void, delay: number) => { }; } }, [delay]); + return intervalRef; }; From f66832c7f3d724f30603e5e78b65f591f1589904 Mon Sep 17 00:00:00 2001 From: proddy Date: Sun, 13 Oct 2024 22:45:34 +0100 Subject: [PATCH 3/5] retain toggle in dashboard, refresh when new devices loaded --- interface/src/app/main/Dashboard.tsx | 21 +++++++++++---------- interface/src/utils/index.ts | 1 + interface/src/utils/usePersistState.ts | 26 ++++++++++++++++++++++++++ 3 files changed, 38 insertions(+), 10 deletions(-) create mode 100644 interface/src/utils/usePersistState.ts diff --git a/interface/src/app/main/Dashboard.tsx b/interface/src/app/main/Dashboard.tsx index dda4a907f..a2892d55c 100644 --- a/interface/src/app/main/Dashboard.tsx +++ b/interface/src/app/main/Dashboard.tsx @@ -24,7 +24,7 @@ import { useRequest } from 'alova/client'; import { FormLoader, SectionContent, useLayoutTitle } from 'components'; import { AuthenticatedContext } from 'contexts/authentication'; import { useI18nContext } from 'i18n/i18n-react'; -import { useInterval } from 'utils'; +import { useInterval, usePersistState } from 'utils'; import { readDashboard, writeDeviceValue } from '../../api/app'; import DeviceIcon from './DeviceIcon'; @@ -44,11 +44,10 @@ const Dashboard = () => { useLayoutTitle(LL.DASHBOARD()); - const [firstLoad, setFirstLoad] = useState(true); - const [showAll, setShowAll] = useState(true); + const [showAll, setShowAll] = usePersistState(true, 'showAll'); const [deviceValueDialogOpen, setDeviceValueDialogOpen] = useState(false); - + const [parentNodes, setParentNodes] = useState(0); const [selectedDashboardItem, setSelectedDashboardItem] = useState(); @@ -59,6 +58,10 @@ const Dashboard = () => { loading } = useRequest(readDashboard, { initialData: [] + }).onSuccess((event) => { + if (event.data.length > parentNodes) { + setParentNodes(event.data.length); // count number of parents/devices + } }); const { loading: submitting, send: sendDeviceValue } = useRequest( @@ -145,13 +148,11 @@ const Dashboard = () => { } }, 3000); - // auto expand on first load useEffect(() => { - if (firstLoad && Array.isArray(data) && data.length && !tree.state.ids.length) { - tree.fns.onToggleAll({}); - setFirstLoad(false); - } - }, [loading]); + showAll + ? tree.fns.onAddAll(data.map((item: DashboardItem) => item.id)) // expand tree + : tree.fns.onRemoveAll(); // collapse tree + }, [parentNodes]); const showType = (n?: string, t?: number) => { // if we have a name show it diff --git a/interface/src/utils/index.ts b/interface/src/utils/index.ts index e704f66e5..87fdbc07c 100644 --- a/interface/src/utils/index.ts +++ b/interface/src/utils/index.ts @@ -6,3 +6,4 @@ export * from './useRest'; export * from './useInterval'; export * from './props'; export * from './file'; +export * from './usePersistState'; diff --git a/interface/src/utils/usePersistState.ts b/interface/src/utils/usePersistState.ts new file mode 100644 index 000000000..d8cb8a19a --- /dev/null +++ b/interface/src/utils/usePersistState.ts @@ -0,0 +1,26 @@ +import { useEffect, useMemo, useState } from 'react'; + +export const usePersistState = ( + initial_value: T, + id: string +): [T, (new_state: T) => void] => { + // Set initial value + const _initial_value = useMemo(() => { + const local_storage_value_str = localStorage.getItem('state:' + id); + // If there is a value stored in localStorage, use that + if (local_storage_value_str) { + return JSON.parse(local_storage_value_str); + } + // Otherwise use initial_value that was passed to the function + return initial_value; + }, []); + + const [state, setState] = useState(_initial_value); + + useEffect(() => { + const state_str = JSON.stringify(state); // Stringified state + localStorage.setItem('state:' + id, state_str); // Set stringified state as item in localStorage + }, [state]); + + return [state, setState]; +}; From 079cae767c48bf6eebaab7601e57f2bd7c6342b2 Mon Sep 17 00:00:00 2001 From: proddy Date: Sun, 13 Oct 2024 23:13:55 +0100 Subject: [PATCH 4/5] fix count --- interface/src/app/main/Dashboard.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/app/main/Dashboard.tsx b/interface/src/app/main/Dashboard.tsx index a2892d55c..389311787 100644 --- a/interface/src/app/main/Dashboard.tsx +++ b/interface/src/app/main/Dashboard.tsx @@ -59,7 +59,7 @@ const Dashboard = () => { } = useRequest(readDashboard, { initialData: [] }).onSuccess((event) => { - if (event.data.length > parentNodes) { + if (event.data.length !== parentNodes) { setParentNodes(event.data.length); // count number of parents/devices } }); From 6964620bd428f458226e92c2efbd531e75c5d96b Mon Sep 17 00:00:00 2001 From: proddy Date: Mon, 14 Oct 2024 00:06:08 +0100 Subject: [PATCH 5/5] consistent hover effect in tables --- interface/src/app/main/CustomEntities.tsx | 7 +------ interface/src/app/main/Customizations.tsx | 5 +---- interface/src/app/main/Scheduler.tsx | 7 +------ interface/src/app/main/Sensors.tsx | 11 +---------- 4 files changed, 4 insertions(+), 26 deletions(-) diff --git a/interface/src/app/main/CustomEntities.tsx b/interface/src/app/main/CustomEntities.tsx index 68fac89d2..095f4ebdd 100644 --- a/interface/src/app/main/CustomEntities.tsx +++ b/interface/src/app/main/CustomEntities.tsx @@ -125,15 +125,10 @@ const CustomEntities = () => { position: relative; cursor: pointer; .td { - border-top: 1px solid #565656; border-bottom: 1px solid #565656; } &:hover .td { - border-top: 1px solid #177ac9; - border-bottom: 1px solid #177ac9; - } - &:nth-of-type(odd) .td { - background-color: #303030; + background-color: #177ac9; } ` }); diff --git a/interface/src/app/main/Customizations.tsx b/interface/src/app/main/Customizations.tsx index 72babe728..87ac23822 100644 --- a/interface/src/app/main/Customizations.tsx +++ b/interface/src/app/main/Customizations.tsx @@ -190,10 +190,7 @@ const Customizations = () => { } &:hover .td { border-top: 1px solid #177ac9; - border-bottom: 1px solid #177ac9; - } - &:nth-of-type(odd) .td { - background-color: #303030; + background-color: #177ac9; } `, Cell: ` diff --git a/interface/src/app/main/Scheduler.tsx b/interface/src/app/main/Scheduler.tsx index d57e5b246..9ea48ba04 100644 --- a/interface/src/app/main/Scheduler.tsx +++ b/interface/src/app/main/Scheduler.tsx @@ -117,15 +117,10 @@ const Scheduler = () => { position: relative; cursor: pointer; .td { - border-top: 1px solid #565656; border-bottom: 1px solid #565656; } &:hover .td { - border-top: 1px solid #177ac9; - border-bottom: 1px solid #177ac9; - } - &:nth-of-type(odd) .td { - background-color: #303030; + background-color: #177ac9; } ` }); diff --git a/interface/src/app/main/Sensors.tsx b/interface/src/app/main/Sensors.tsx index 8be8cffad..eebc08384 100644 --- a/interface/src/app/main/Sensors.tsx +++ b/interface/src/app/main/Sensors.tsx @@ -116,19 +116,10 @@ const Sensors = () => { cursor: pointer; .td { padding: 8px; - border-top: 1px solid #565656; border-bottom: 1px solid #565656; } - &.tr.tr-body.row-select.row-select-single-selected { - background-color: #3d4752; - font-weight: normal; - } &:hover .td { - border-top: 1px solid #177ac9; - border-bottom: 1px solid #177ac9; - } - &:nth-of-type(odd) .td { - background-color: #303030; + background-color: #177ac9; } `, Cell: `