diff --git a/src/utils/config/service-helpers.js b/src/utils/config/service-helpers.js index d82b56cb..c2ce1794 100644 --- a/src/utils/config/service-helpers.js +++ b/src/utils/config/service-helpers.js @@ -336,48 +336,87 @@ export function cleanServiceGroups(groups) { if (cleanedService.widget) { // whitelisted set of keys to pass to the frontend + // alphabetical, grouped by widget(s) const { - type, // all widgets + // all widgets fields, hideErrors, - server, // docker widget - container, - currency, // coinmarketcap widget - symbols, - slugs, - defaultinterval, - site, // unifi widget - namespace, // kubernetes widget - app, - podSelector, - wan, // opnsense widget, pfsense widget - enableBlocks, // emby/jellyfin - enableNowPlaying, - volume, // diskstation widget, - enableQueue, // sonarr/radarr - node, // Proxmox - snapshotHost, // kopia - snapshotPath, - userEmail, // azuredevops + type, + + // azuredevops repositoryId, - metric, // glances - chart, // glances - stream, // mjpeg - fit, - method, // openmediavault widget - mappings, // customapi widget - refreshInterval, - integrations, // calendar widget + userEmail, + + // calendar firstDayInWeek, - view, + integrations, maxEvents, - src, // iframe widget - classes, - referrerPolicy, - allowPolicy, + view, + + // coinmarketcap + currency, + defaultinterval, + slugs, + symbols, + + // customapi + mappings, + + // diskstation + volume, + + // docker + container, + server, + + // emby, jellyfin + enableBlocks, + enableNowPlaying, + + // glances + chart, + metric, + pointsLimit, + + // glances, customapi, iframe + refreshInterval, + + // iframe allowFullscreen, - loadingStrategy, + allowPolicy, allowScrolling, + classes, + loadingStrategy, + referrerPolicy, + src, + + // kopia + snapshotHost, + snapshotPath, + + // kubernetes + app, + namespace, + podSelector, + + // mjpeg + fit, + stream, + + // openmediavault + method, + + // opnsense, pfsense + wan, + + // proxmox + node, + + // sonarr, radarr + enableQueue, + + // unifi + site, } = cleanedService.widget; let fieldsList = fields; @@ -459,6 +498,8 @@ export function cleanServiceGroups(groups) { } else { cleanedService.widget.chart = true; } + if (refreshInterval) cleanedService.widget.refreshInterval = refreshInterval; + if (pointsLimit) cleanedService.widget.pointsLimit = pointsLimit; } if (type === "mjpeg") { if (stream) cleanedService.widget.stream = stream; diff --git a/src/widgets/glances/metrics/cpu.jsx b/src/widgets/glances/metrics/cpu.jsx index 5aaf985f..c36aba9d 100644 --- a/src/widgets/glances/metrics/cpu.jsx +++ b/src/widgets/glances/metrics/cpu.jsx @@ -10,17 +10,18 @@ import useWidgetAPI from "utils/proxy/use-widget-api"; const Chart = dynamic(() => import("../components/chart"), { ssr: false }); -const pointsLimit = 15; +const defaultPointsLimit = 15; +const defaultInterval = 1000; export default function Component({ service }) { const { t } = useTranslation(); const { widget } = service; - const { chart } = widget; + const { chart, refreshInterval = defaultInterval, pointsLimit = defaultPointsLimit } = widget; const [dataPoints, setDataPoints] = useState(new Array(pointsLimit).fill({ value: 0 }, 0, pointsLimit)); const { data, error } = useWidgetAPI(service.widget, "cpu", { - refreshInterval: 1000, + refreshInterval: Math.max(defaultInterval, refreshInterval), }); const { data: systemData, error: systemError } = useWidgetAPI(service.widget, "system"); @@ -35,7 +36,7 @@ export default function Component({ service }) { return newDataPoints; }); } - }, [data]); + }, [data, pointsLimit]); if (error) { return ( diff --git a/src/widgets/glances/metrics/disk.jsx b/src/widgets/glances/metrics/disk.jsx index 431627d2..d5cac477 100644 --- a/src/widgets/glances/metrics/disk.jsx +++ b/src/widgets/glances/metrics/disk.jsx @@ -10,12 +10,13 @@ import useWidgetAPI from "utils/proxy/use-widget-api"; const ChartDual = dynamic(() => import("../components/chart_dual"), { ssr: false }); -const pointsLimit = 15; +const defaultPointsLimit = 15; +const defaultInterval = 1000; export default function Component({ service }) { const { t } = useTranslation(); const { widget } = service; - const { chart } = widget; + const { chart, refreshInterval = defaultInterval, pointsLimit = defaultPointsLimit } = widget; const [, diskName] = widget.metric.split(":"); const [dataPoints, setDataPoints] = useState( @@ -24,7 +25,7 @@ export default function Component({ service }) { const [ratePoints, setRatePoints] = useState(new Array(pointsLimit).fill({ a: 0, b: 0 }, 0, pointsLimit)); const { data, error } = useWidgetAPI(service.widget, "diskio", { - refreshInterval: 1000, + refreshInterval: Math.max(defaultInterval, refreshInterval), }); const calculateRates = (d) => @@ -45,7 +46,7 @@ export default function Component({ service }) { return newDataPoints; }); } - }, [data, diskName]); + }, [data, diskName, pointsLimit]); useEffect(() => { setRatePoints(calculateRates(dataPoints)); diff --git a/src/widgets/glances/metrics/fs.jsx b/src/widgets/glances/metrics/fs.jsx index d5c535e1..9cd0cec6 100644 --- a/src/widgets/glances/metrics/fs.jsx +++ b/src/widgets/glances/metrics/fs.jsx @@ -6,14 +6,16 @@ import Block from "../components/block"; import useWidgetAPI from "utils/proxy/use-widget-api"; +const defaultInterval = 1000; + export default function Component({ service }) { const { t } = useTranslation(); const { widget } = service; - const { chart } = widget; + const { chart, refreshInterval = defaultInterval } = widget; const [, fsName] = widget.metric.split("fs:"); const { data, error } = useWidgetAPI(widget, "fs", { - refreshInterval: 1000, + refreshInterval: Math.max(defaultInterval, refreshInterval), }); if (error) { diff --git a/src/widgets/glances/metrics/gpu.jsx b/src/widgets/glances/metrics/gpu.jsx index c648dfae..c33c6396 100644 --- a/src/widgets/glances/metrics/gpu.jsx +++ b/src/widgets/glances/metrics/gpu.jsx @@ -10,18 +10,19 @@ import useWidgetAPI from "utils/proxy/use-widget-api"; const ChartDual = dynamic(() => import("../components/chart_dual"), { ssr: false }); -const pointsLimit = 15; +const defaultPointsLimit = 15; +const defaultInterval = 1000; export default function Component({ service }) { const { t } = useTranslation(); const { widget } = service; - const { chart } = widget; + const { chart, refreshInterval = defaultInterval, pointsLimit = defaultPointsLimit } = widget; const [, gpuName] = widget.metric.split(":"); const [dataPoints, setDataPoints] = useState(new Array(pointsLimit).fill({ a: 0, b: 0 }, 0, pointsLimit)); const { data, error } = useWidgetAPI(widget, "gpu", { - refreshInterval: 1000, + refreshInterval: Math.max(defaultInterval, refreshInterval), }); useEffect(() => { @@ -39,7 +40,7 @@ export default function Component({ service }) { }); } } - }, [data, gpuName]); + }, [data, gpuName, pointsLimit]); if (error) { return ( diff --git a/src/widgets/glances/metrics/info.jsx b/src/widgets/glances/metrics/info.jsx index f6b145d1..e7555bce 100644 --- a/src/widgets/glances/metrics/info.jsx +++ b/src/widgets/glances/metrics/info.jsx @@ -69,16 +69,19 @@ function Mem({ quicklookData, className = "" }) { ); } +const defaultInterval = 1000; +const defaultSystemInterval = 30000; // This data (OS, hostname, distribution) is usually super stable. + export default function Component({ service }) { const { widget } = service; - const { chart } = widget; + const { chart, refreshInterval = defaultInterval } = widget; const { data: quicklookData, errorL: quicklookError } = useWidgetAPI(service.widget, "quicklook", { - refreshInterval: 1000, + refreshInterval, }); const { data: systemData, errorL: systemError } = useWidgetAPI(service.widget, "system", { - refreshInterval: 30000, + refreshInterval: defaultSystemInterval, }); if (quicklookError) { diff --git a/src/widgets/glances/metrics/memory.jsx b/src/widgets/glances/metrics/memory.jsx index ddd37011..d6cc5e6c 100644 --- a/src/widgets/glances/metrics/memory.jsx +++ b/src/widgets/glances/metrics/memory.jsx @@ -10,17 +10,19 @@ import useWidgetAPI from "utils/proxy/use-widget-api"; const ChartDual = dynamic(() => import("../components/chart_dual"), { ssr: false }); -const pointsLimit = 15; +const defaultPointsLimit = 15; +const defaultInterval = (isChart) => (isChart ? 1000 : 5000); export default function Component({ service }) { const { t } = useTranslation(); const { widget } = service; const { chart } = widget; + const { refreshInterval = defaultInterval(chart), pointsLimit = defaultPointsLimit } = widget; const [dataPoints, setDataPoints] = useState(new Array(pointsLimit).fill({ value: 0 }, 0, pointsLimit)); const { data, error } = useWidgetAPI(service.widget, "mem", { - refreshInterval: chart ? 1000 : 5000, + refreshInterval: Math.max(defaultInterval(chart), refreshInterval), }); useEffect(() => { @@ -33,7 +35,7 @@ export default function Component({ service }) { return newDataPoints; }); } - }, [data]); + }, [data, pointsLimit]); if (error) { return ( diff --git a/src/widgets/glances/metrics/net.jsx b/src/widgets/glances/metrics/net.jsx index ad47d6cb..3bd92c22 100644 --- a/src/widgets/glances/metrics/net.jsx +++ b/src/widgets/glances/metrics/net.jsx @@ -10,18 +10,21 @@ import useWidgetAPI from "utils/proxy/use-widget-api"; const ChartDual = dynamic(() => import("../components/chart_dual"), { ssr: false }); -const pointsLimit = 15; +const defaultPointsLimit = 15; +const defaultInterval = (isChart) => (isChart ? 1000 : 5000); export default function Component({ service }) { const { t } = useTranslation(); const { widget } = service; const { chart, metric } = widget; + const { refreshInterval = defaultInterval(chart), pointsLimit = defaultPointsLimit } = widget; + const [, interfaceName] = metric.split(":"); const [dataPoints, setDataPoints] = useState(new Array(pointsLimit).fill({ value: 0 }, 0, pointsLimit)); const { data, error } = useWidgetAPI(widget, "network", { - refreshInterval: chart ? 1000 : 5000, + refreshInterval: Math.max(defaultInterval(chart), refreshInterval), }); useEffect(() => { @@ -44,7 +47,7 @@ export default function Component({ service }) { }); } } - }, [data, interfaceName]); + }, [data, interfaceName, pointsLimit]); if (error) { return ( diff --git a/src/widgets/glances/metrics/process.jsx b/src/widgets/glances/metrics/process.jsx index f145ce8a..cd21356d 100644 --- a/src/widgets/glances/metrics/process.jsx +++ b/src/widgets/glances/metrics/process.jsx @@ -17,13 +17,15 @@ const statusMap = { X: , // dead }; +const defaultInterval = 1000; + export default function Component({ service }) { const { t } = useTranslation(); const { widget } = service; - const { chart } = widget; + const { chart, refreshInterval = defaultInterval } = widget; const { data, error } = useWidgetAPI(service.widget, "processlist", { - refreshInterval: 1000, + refreshInterval: Math.max(defaultInterval, refreshInterval), }); if (error) { diff --git a/src/widgets/glances/metrics/sensor.jsx b/src/widgets/glances/metrics/sensor.jsx index d07e1610..60ea07c8 100644 --- a/src/widgets/glances/metrics/sensor.jsx +++ b/src/widgets/glances/metrics/sensor.jsx @@ -10,18 +10,19 @@ import useWidgetAPI from "utils/proxy/use-widget-api"; const Chart = dynamic(() => import("../components/chart"), { ssr: false }); -const pointsLimit = 15; +const defaultPointsLimit = 15; +const defaultInterval = 1000; export default function Component({ service }) { const { t } = useTranslation(); const { widget } = service; - const { chart } = widget; + const { chart, refreshInterval = defaultInterval, pointsLimit = defaultPointsLimit } = widget; const [, sensorName] = widget.metric.split(":"); const [dataPoints, setDataPoints] = useState(new Array(pointsLimit).fill({ value: 0 }, 0, pointsLimit)); const { data, error } = useWidgetAPI(service.widget, "sensors", { - refreshInterval: 1000, + refreshInterval: Math.max(defaultInterval, refreshInterval), }); useEffect(() => { @@ -35,7 +36,7 @@ export default function Component({ service }) { return newDataPoints; }); } - }, [data, sensorName]); + }, [data, sensorName, pointsLimit]); if (error) { return (