feat(system-resources-widget): add visible charts option (#4069)

This commit is contained in:
Meier Lukas
2025-09-13 14:13:18 +02:00
committed by GitHub
parent 8c24da8732
commit b30cc21dbe
4 changed files with 46 additions and 35 deletions

View File

@@ -2498,7 +2498,17 @@
"systemResources": { "systemResources": {
"name": "System resources", "name": "System resources",
"description": "CPU, Memory, Disk and other hardware usage of your system", "description": "CPU, Memory, Disk and other hardware usage of your system",
"option": {}, "option": {
"visibleCharts": {
"label": "Visible charts",
"description": "Select the charts you want to be visible.",
"option": {
"cpu": "CPU",
"memory": "Memory",
"network": "Network"
}
}
},
"card": { "card": {
"cpu": "CPU", "cpu": "CPU",
"memory": "MEM", "memory": "MEM",

View File

@@ -1,14 +0,0 @@
.grid {
display: grid;
grid-template-rows: repeat(3, 1fr);
grid-template-columns: repeat(2, 1fr);
gap: 8px;
padding: 8px;
height: 100%;
}
.colSpanWide {
grid-column-start: 1;
grid-column-end: 3;
}

View File

@@ -1,6 +1,7 @@
"use client"; "use client";
import { useState } from "react"; import { useState } from "react";
import { Box, Group, Stack } from "@mantine/core";
import { useElementSize } from "@mantine/hooks"; import { useElementSize } from "@mantine/hooks";
import { clientApi } from "@homarr/api/client"; import { clientApi } from "@homarr/api/client";
@@ -10,11 +11,10 @@ import { CombinedNetworkTrafficChart } from "./chart/combined-network-traffic";
import { SystemResourceCPUChart } from "./chart/cpu-chart"; import { SystemResourceCPUChart } from "./chart/cpu-chart";
import { SystemResourceMemoryChart } from "./chart/memory-chart"; import { SystemResourceMemoryChart } from "./chart/memory-chart";
import { NetworkTrafficChart } from "./chart/network-traffic"; import { NetworkTrafficChart } from "./chart/network-traffic";
import classes from "./component.module.css";
const MAX_QUEUE_SIZE = 15; const MAX_QUEUE_SIZE = 15;
export default function SystemResources({ integrationIds }: WidgetComponentProps<"systemResources">) { export default function SystemResources({ integrationIds, options }: WidgetComponentProps<"systemResources">) {
const { ref, width } = useElementSize(); const { ref, width } = useElementSize();
const [data] = clientApi.widget.healthMonitoring.getSystemHealthStatus.useSuspenseQuery({ const [data] = clientApi.widget.healthMonitoring.getSystemHealthStatus.useSuspenseQuery({
@@ -49,34 +49,40 @@ export default function SystemResources({ integrationIds }: WidgetComponentProps
}, },
); );
const showNetwork = items.length === 0 || items.every((item) => item.network !== null); const showNetwork =
items.length === 0 || (items.every((item) => item.network !== null) && options.visibleCharts.includes("network"));
const rowHeight = `calc((100% - ${(options.visibleCharts.length - 1) * 8}px) / ${options.visibleCharts.length})`;
return ( return (
<div ref={ref} className={classes.grid}> <Stack gap="xs" p="xs" ref={ref} h="100%">
<div className={classes.colSpanWide}> {options.visibleCharts.includes("cpu") && (
<SystemResourceCPUChart cpuUsageOverTime={items.map((item) => item.cpu)} /> <Box h={rowHeight}>
</div> <SystemResourceCPUChart cpuUsageOverTime={items.map((item) => item.cpu)} />
<div className={classes.colSpanWide}> </Box>
<SystemResourceMemoryChart )}
memoryUsageOverTime={items.map((item) => item.memory)} {options.visibleCharts.includes("memory") && (
totalCapacityInBytes={memoryCapacityInBytes} <Box h={rowHeight}>
/> <SystemResourceMemoryChart
</div> memoryUsageOverTime={items.map((item) => item.memory)}
totalCapacityInBytes={memoryCapacityInBytes}
/>
</Box>
)}
{showNetwork && {showNetwork &&
(width > 200 ? ( (width > 256 ? (
<> <Group h={rowHeight} gap="xs" grow>
{/* eslint-disable-next-line @typescript-eslint/no-non-null-assertion */} {/* eslint-disable-next-line @typescript-eslint/no-non-null-assertion */}
<NetworkTrafficChart usageOverTime={items.map((item) => item.network!.down)} isUp={false} /> <NetworkTrafficChart usageOverTime={items.map((item) => item.network!.down)} isUp={false} />
{/* eslint-disable-next-line @typescript-eslint/no-non-null-assertion */} {/* eslint-disable-next-line @typescript-eslint/no-non-null-assertion */}
<NetworkTrafficChart usageOverTime={items.map((item) => item.network!.up)} isUp /> <NetworkTrafficChart usageOverTime={items.map((item) => item.network!.up)} isUp />
</> </Group>
) : ( ) : (
<div className={classes.colSpanWide}> <Box h={rowHeight}>
{/* eslint-disable-next-line @typescript-eslint/no-non-null-assertion */} {/* eslint-disable-next-line @typescript-eslint/no-non-null-assertion */}
<CombinedNetworkTrafficChart usageOverTime={items.map((item) => item.network!)} /> <CombinedNetworkTrafficChart usageOverTime={items.map((item) => item.network!)} />
</div> </Box>
))} ))}
</div> </Stack>
); );
} }

View File

@@ -7,6 +7,15 @@ export const { definition, componentLoader } = createWidgetDefinition("systemRes
icon: IconGraphFilled, icon: IconGraphFilled,
supportedIntegrations: ["dashDot", "openmediavault", "truenas"], supportedIntegrations: ["dashDot", "openmediavault", "truenas"],
createOptions() { createOptions() {
return optionsBuilder.from(() => ({})); return optionsBuilder.from((factory) => ({
visibleCharts: factory.multiSelect({
options: (["cpu", "memory", "network"] as const).map((key) => ({
value: key,
label: (t) => t(`widget.systemResources.option.visibleCharts.option.${key}`),
})),
defaultValue: ["cpu", "memory", "network"],
withDescription: true,
}),
}));
}, },
}).withDynamicImport(() => import("./component")); }).withDynamicImport(() => import("./component"));