fix(dns-hole-summary): calculation for domains and percentage for multiple integrations (#1894)

This commit is contained in:
Meier Lukas
2025-01-10 14:46:21 +01:00
committed by GitHub
parent a12dd10269
commit 546c824888
2 changed files with 67 additions and 56 deletions

View File

@@ -1091,7 +1091,8 @@
"adsBlockedTodayPercentage": "Blocked today", "adsBlockedTodayPercentage": "Blocked today",
"dnsQueriesToday": "Queries today", "dnsQueriesToday": "Queries today",
"domainsBeingBlocked": "Domains on blocklist" "domainsBeingBlocked": "Domains on blocklist"
} },
"domainsTooltip": "Due to multiple integrations Homarr can't calculate the exact number of domains being blocked"
}, },
"dnsHoleControls": { "dnsHoleControls": {
"name": "DNS Hole Controls", "name": "DNS Hole Controls",

View File

@@ -2,7 +2,7 @@
import { useMemo } from "react"; import { useMemo } from "react";
import type { BoxProps } from "@mantine/core"; import type { BoxProps } from "@mantine/core";
import { Avatar, AvatarGroup, Box, Card, Flex, Stack, Text, Tooltip } from "@mantine/core"; import { Avatar, AvatarGroup, Box, Card, Flex, Stack, Text, Tooltip, TooltipFloating } from "@mantine/core";
import { useElementSize } from "@mantine/hooks"; import { useElementSize } from "@mantine/hooks";
import { IconBarrierBlock, IconPercentage, IconSearch, IconWorldWww } from "@tabler/icons-react"; import { IconBarrierBlock, IconPercentage, IconSearch, IconWorldWww } from "@tabler/icons-react";
@@ -98,11 +98,11 @@ const stats = [
}, },
{ {
icon: IconPercentage, icon: IconPercentage,
value: (data) => value: (data) => {
`${formatNumber( const totalCount = data.reduce((count, { dnsQueriesToday }) => count + dnsQueriesToday, 0);
data.reduce((count, { adsBlockedTodayPercentage }) => count + adsBlockedTodayPercentage, 0), const blocked = data.reduce((count, { adsBlockedToday }) => count + adsBlockedToday, 0);
2, return `${formatNumber(totalCount === 0 ? 0 : (blocked / totalCount) * 100, 2)}%`;
)}%`, },
label: (t) => t("widget.dnsHoleSummary.data.adsBlockedTodayPercentage"), label: (t) => t("widget.dnsHoleSummary.data.adsBlockedTodayPercentage"),
color: "rgba(255, 165, 20, 0.4)", // YELLOW color: "rgba(255, 165, 20, 0.4)", // YELLOW
}, },
@@ -118,11 +118,17 @@ const stats = [
}, },
{ {
icon: IconWorldWww, icon: IconWorldWww,
value: (data) => value: (data) => {
// We use a suffix to indicate that there might be more domains in the at least two lists.
const suffix = data.length >= 2 ? "+" : "";
return (
formatNumber( formatNumber(
data.reduce((count, { domainsBeingBlocked }) => count + domainsBeingBlocked, 0), data.reduce((count, { domainsBeingBlocked }) => count + domainsBeingBlocked, 0),
2, 2,
), ) + suffix
);
},
tooltip: (data, t) => (data.length >= 2 ? t("widget.dnsHoleSummary.domainsTooltip") : undefined),
label: (t) => t("widget.dnsHoleSummary.data.domainsBeingBlocked"), label: (t) => t("widget.dnsHoleSummary.data.domainsBeingBlocked"),
color: "rgba(0, 176, 96, 0.4)", // GREEN color: "rgba(0, 176, 96, 0.4)", // GREEN
}, },
@@ -130,7 +136,8 @@ const stats = [
interface StatItem { interface StatItem {
icon: TablerIcon; icon: TablerIcon;
value: (x: DnsHoleSummary[]) => string; value: (summaries: DnsHoleSummary[]) => string;
tooltip?: (summaries: DnsHoleSummary[], t: TranslationFunction) => string | undefined;
label: stringOrTranslation; label: stringOrTranslation;
color: string; color: string;
} }
@@ -144,8 +151,10 @@ interface StatCardProps {
const StatCard = ({ item, data, usePiHoleColors, t }: StatCardProps) => { const StatCard = ({ item, data, usePiHoleColors, t }: StatCardProps) => {
const { ref, height, width } = useElementSize(); const { ref, height, width } = useElementSize();
const isLong = width > height + 20; const isLong = width > height + 20;
const tooltip = item.tooltip?.(data, t);
return ( return (
<TooltipFloating label={tooltip} disabled={!tooltip} w={250} multiline>
<Card <Card
ref={ref} ref={ref}
className="summary-card" className="summary-card"
@@ -196,6 +205,7 @@ const StatCard = ({ item, data, usePiHoleColors, t }: StatCardProps) => {
</Flex> </Flex>
</Flex> </Flex>
</Card> </Card>
</TooltipFloating>
); );
}; };