feat(system-resources-widget): add has-shadow option (#4093)
This commit is contained in:
@@ -9,12 +9,14 @@ import { CommonChart } from "./common-chart";
|
||||
|
||||
export const CombinedNetworkTrafficChart = ({
|
||||
usageOverTime,
|
||||
hasShadow,
|
||||
labelDisplayMode,
|
||||
}: {
|
||||
usageOverTime: {
|
||||
up: number;
|
||||
down: number;
|
||||
}[];
|
||||
hasShadow: boolean;
|
||||
labelDisplayMode: LabelDisplayModeOption;
|
||||
}) => {
|
||||
const chartData = usageOverTime.map((usage, index) => ({ index, up: usage.up, down: usage.down }));
|
||||
@@ -31,6 +33,7 @@ export const CombinedNetworkTrafficChart = ({
|
||||
title={t("network")}
|
||||
icon={IconNetwork}
|
||||
yAxisProps={{ domain: [0, "dataMax"] }}
|
||||
chartType={hasShadow ? "area" : "line"}
|
||||
labelDisplayMode={labelDisplayMode}
|
||||
tooltipProps={{
|
||||
content: ({ payload }) => {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
import type { ReactNode } from "react";
|
||||
import type { LineChartSeries } from "@mantine/charts";
|
||||
import { LineChart } from "@mantine/charts";
|
||||
import type { AreaChartSeries } from "@mantine/charts";
|
||||
import { AreaChart, LineChart } from "@mantine/charts";
|
||||
import { Card, Center, Group, Loader, Stack, Text, useMantineColorScheme, useMantineTheme } from "@mantine/core";
|
||||
import { useElementSize, useHover, useMergedRef } from "@mantine/hooks";
|
||||
import type { TooltipProps, YAxisProps } from "recharts";
|
||||
@@ -21,16 +21,18 @@ export const CommonChart = ({
|
||||
tooltipProps,
|
||||
yAxisProps,
|
||||
lastValue,
|
||||
chartType = "line",
|
||||
}: {
|
||||
data: Record<string, any>[];
|
||||
dataKey: string;
|
||||
series: LineChartSeries[];
|
||||
series: AreaChartSeries[];
|
||||
title: ReactNode;
|
||||
icon: TablerIcon;
|
||||
labelDisplayMode: LabelDisplayModeOption;
|
||||
tooltipProps?: TooltipProps<number, any>;
|
||||
yAxisProps?: Omit<YAxisProps, "ref">;
|
||||
lastValue?: string;
|
||||
chartType?: "line" | "area";
|
||||
}) => {
|
||||
const { ref: elementSizeRef, height } = useElementSize();
|
||||
const theme = useMantineTheme();
|
||||
@@ -43,6 +45,7 @@ export const CommonChart = ({
|
||||
const backgroundColor =
|
||||
scheme.colorScheme === "dark" ? `rgba(57, 57, 57, ${opacity})` : `rgba(246, 247, 248, ${opacity})`;
|
||||
|
||||
const ChartComponent = chartType === "line" ? LineChart : AreaChart;
|
||||
const showIcon = labelDisplayMode === "icon" || labelDisplayMode === "textWithIcon";
|
||||
const showText = labelDisplayMode === "text" || labelDisplayMode === "textWithIcon";
|
||||
|
||||
@@ -88,7 +91,7 @@ export const CommonChart = ({
|
||||
</Stack>
|
||||
</Center>
|
||||
) : (
|
||||
<LineChart
|
||||
<ChartComponent
|
||||
data={data}
|
||||
dataKey={dataKey}
|
||||
h={"100%"}
|
||||
@@ -105,6 +108,7 @@ export const CommonChart = ({
|
||||
tooltipProps={tooltipProps}
|
||||
withTooltip={height >= 64}
|
||||
yAxisProps={yAxisProps}
|
||||
fillOpacity={chartType === "area" ? 0.3 : undefined}
|
||||
/>
|
||||
)}
|
||||
</Card>
|
||||
|
||||
@@ -3,14 +3,16 @@ import { IconCpu } from "@tabler/icons-react";
|
||||
|
||||
import { useScopedI18n } from "@homarr/translation/client";
|
||||
|
||||
import { LabelDisplayModeOption } from "..";
|
||||
import type { LabelDisplayModeOption } from "..";
|
||||
import { CommonChart } from "./common-chart";
|
||||
|
||||
export const SystemResourceCPUChart = ({
|
||||
cpuUsageOverTime,
|
||||
hasShadow,
|
||||
labelDisplayMode,
|
||||
}: {
|
||||
cpuUsageOverTime: number[];
|
||||
hasShadow: boolean;
|
||||
labelDisplayMode: LabelDisplayModeOption;
|
||||
}) => {
|
||||
const chartData = cpuUsageOverTime.map((usage, index) => ({ index, usage }));
|
||||
@@ -27,6 +29,7 @@ export const SystemResourceCPUChart = ({
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
cpuUsageOverTime.length > 0 ? `${Math.round(cpuUsageOverTime[cpuUsageOverTime.length - 1]!)}%` : undefined
|
||||
}
|
||||
chartType={hasShadow ? "area" : "line"}
|
||||
yAxisProps={{ domain: [0, 100] }}
|
||||
labelDisplayMode={labelDisplayMode}
|
||||
tooltipProps={{
|
||||
|
||||
@@ -10,10 +10,12 @@ import { CommonChart } from "./common-chart";
|
||||
export const SystemResourceMemoryChart = ({
|
||||
memoryUsageOverTime,
|
||||
totalCapacityInBytes,
|
||||
hasShadow,
|
||||
labelDisplayMode,
|
||||
}: {
|
||||
memoryUsageOverTime: number[];
|
||||
totalCapacityInBytes: number;
|
||||
hasShadow: boolean;
|
||||
labelDisplayMode: LabelDisplayModeOption;
|
||||
}) => {
|
||||
const chartData = memoryUsageOverTime.map((usage, index) => ({ index, usage }));
|
||||
@@ -35,6 +37,7 @@ export const SystemResourceMemoryChart = ({
|
||||
labelDisplayMode={labelDisplayMode}
|
||||
yAxisProps={{ domain: [0, totalCapacityInBytes] }}
|
||||
lastValue={percentageUsed !== undefined ? `${Math.round(percentageUsed * 100)}%` : undefined}
|
||||
chartType={hasShadow ? "area" : "line"}
|
||||
tooltipProps={{
|
||||
content: ({ payload }) => {
|
||||
if (!payload) {
|
||||
|
||||
@@ -10,10 +10,12 @@ import { CommonChart } from "./common-chart";
|
||||
export const NetworkTrafficChart = ({
|
||||
usageOverTime,
|
||||
isUp,
|
||||
hasShadow,
|
||||
labelDisplayMode,
|
||||
}: {
|
||||
usageOverTime: number[];
|
||||
isUp: boolean;
|
||||
hasShadow: boolean;
|
||||
labelDisplayMode: LabelDisplayModeOption;
|
||||
}) => {
|
||||
const chartData = usageOverTime.map((usage, index) => ({ index, usage }));
|
||||
@@ -31,6 +33,7 @@ export const NetworkTrafficChart = ({
|
||||
icon={isUp ? IconArrowUp : IconArrowDown}
|
||||
yAxisProps={{ domain: [0, upperBound] }}
|
||||
lastValue={`${humanFileSize(Math.round(max))}/s`}
|
||||
chartType={hasShadow ? "area" : "line"}
|
||||
labelDisplayMode={labelDisplayMode}
|
||||
tooltipProps={{
|
||||
content: ({ payload }) => {
|
||||
|
||||
@@ -59,6 +59,7 @@ export default function SystemResources({ integrationIds, options }: WidgetCompo
|
||||
<Box h={rowHeight}>
|
||||
<SystemResourceCPUChart
|
||||
cpuUsageOverTime={items.map((item) => item.cpu)}
|
||||
hasShadow={options.hasShadow}
|
||||
labelDisplayMode={options.labelDisplayMode}
|
||||
/>
|
||||
</Box>
|
||||
@@ -68,6 +69,7 @@ export default function SystemResources({ integrationIds, options }: WidgetCompo
|
||||
<SystemResourceMemoryChart
|
||||
memoryUsageOverTime={items.map((item) => item.memory)}
|
||||
totalCapacityInBytes={memoryCapacityInBytes}
|
||||
hasShadow={options.hasShadow}
|
||||
labelDisplayMode={options.labelDisplayMode}
|
||||
/>
|
||||
</Box>
|
||||
@@ -79,6 +81,7 @@ export default function SystemResources({ integrationIds, options }: WidgetCompo
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
usageOverTime={items.map((item) => item.network!.down)}
|
||||
isUp={false}
|
||||
hasShadow={options.hasShadow}
|
||||
labelDisplayMode={options.labelDisplayMode}
|
||||
/>
|
||||
|
||||
@@ -86,6 +89,7 @@ export default function SystemResources({ integrationIds, options }: WidgetCompo
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
usageOverTime={items.map((item) => item.network!.up)}
|
||||
isUp
|
||||
hasShadow={options.hasShadow}
|
||||
labelDisplayMode={options.labelDisplayMode}
|
||||
/>
|
||||
</Group>
|
||||
@@ -94,6 +98,7 @@ export default function SystemResources({ integrationIds, options }: WidgetCompo
|
||||
<CombinedNetworkTrafficChart
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
usageOverTime={items.map((item) => item.network!)}
|
||||
hasShadow={options.hasShadow}
|
||||
labelDisplayMode={options.labelDisplayMode}
|
||||
/>
|
||||
</Box>
|
||||
|
||||
@@ -17,6 +17,7 @@ export const { definition, componentLoader } = createWidgetDefinition("systemRes
|
||||
supportedIntegrations: ["dashDot", "openmediavault", "truenas"],
|
||||
createOptions() {
|
||||
return optionsBuilder.from((factory) => ({
|
||||
hasShadow: factory.switch({ defaultValue: true }),
|
||||
visibleCharts: factory.multiSelect({
|
||||
options: (["cpu", "memory", "network"] as const).map((key) => ({
|
||||
value: key,
|
||||
|
||||
Reference in New Issue
Block a user