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": {
"name": "System resources",
"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": {
"cpu": "CPU",
"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";
import { useState } from "react";
import { Box, Group, Stack } from "@mantine/core";
import { useElementSize } from "@mantine/hooks";
import { clientApi } from "@homarr/api/client";
@@ -10,11 +11,10 @@ import { CombinedNetworkTrafficChart } from "./chart/combined-network-traffic";
import { SystemResourceCPUChart } from "./chart/cpu-chart";
import { SystemResourceMemoryChart } from "./chart/memory-chart";
import { NetworkTrafficChart } from "./chart/network-traffic";
import classes from "./component.module.css";
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 [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 (
<div ref={ref} className={classes.grid}>
<div className={classes.colSpanWide}>
<SystemResourceCPUChart cpuUsageOverTime={items.map((item) => item.cpu)} />
</div>
<div className={classes.colSpanWide}>
<SystemResourceMemoryChart
memoryUsageOverTime={items.map((item) => item.memory)}
totalCapacityInBytes={memoryCapacityInBytes}
/>
</div>
<Stack gap="xs" p="xs" ref={ref} h="100%">
{options.visibleCharts.includes("cpu") && (
<Box h={rowHeight}>
<SystemResourceCPUChart cpuUsageOverTime={items.map((item) => item.cpu)} />
</Box>
)}
{options.visibleCharts.includes("memory") && (
<Box h={rowHeight}>
<SystemResourceMemoryChart
memoryUsageOverTime={items.map((item) => item.memory)}
totalCapacityInBytes={memoryCapacityInBytes}
/>
</Box>
)}
{showNetwork &&
(width > 200 ? (
<>
(width > 256 ? (
<Group h={rowHeight} gap="xs" grow>
{/* eslint-disable-next-line @typescript-eslint/no-non-null-assertion */}
<NetworkTrafficChart usageOverTime={items.map((item) => item.network!.down)} isUp={false} />
{/* eslint-disable-next-line @typescript-eslint/no-non-null-assertion */}
<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 */}
<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,
supportedIntegrations: ["dashDot", "openmediavault", "truenas"],
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"));