Skip to content

Commit

Permalink
fix(dns-hole-summary): calculation for domains and percentage for mul…
Browse files Browse the repository at this point in the history
…tiple integrations (#1894)
  • Loading branch information
Meierschlumpf authored Jan 10, 2025
1 parent a12dd10 commit 546c824
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 56 deletions.
3 changes: 2 additions & 1 deletion packages/translation/src/lang/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -1091,7 +1091,8 @@
"adsBlockedTodayPercentage": "Blocked today",
"dnsQueriesToday": "Queries today",
"domainsBeingBlocked": "Domains on blocklist"
}
},
"domainsTooltip": "Due to multiple integrations Homarr can't calculate the exact number of domains being blocked"
},
"dnsHoleControls": {
"name": "DNS Hole Controls",
Expand Down
120 changes: 65 additions & 55 deletions packages/widgets/src/dns-hole/summary/component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import { useMemo } from "react";
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 { IconBarrierBlock, IconPercentage, IconSearch, IconWorldWww } from "@tabler/icons-react";

Expand Down Expand Up @@ -98,11 +98,11 @@ const stats = [
},
{
icon: IconPercentage,
value: (data) =>
`${formatNumber(
data.reduce((count, { adsBlockedTodayPercentage }) => count + adsBlockedTodayPercentage, 0),
2,
)}%`,
value: (data) => {
const totalCount = data.reduce((count, { dnsQueriesToday }) => count + dnsQueriesToday, 0);
const blocked = data.reduce((count, { adsBlockedToday }) => count + adsBlockedToday, 0);
return `${formatNumber(totalCount === 0 ? 0 : (blocked / totalCount) * 100, 2)}%`;
},
label: (t) => t("widget.dnsHoleSummary.data.adsBlockedTodayPercentage"),
color: "rgba(255, 165, 20, 0.4)", // YELLOW
},
Expand All @@ -118,19 +118,26 @@ const stats = [
},
{
icon: IconWorldWww,
value: (data) =>
formatNumber(
data.reduce((count, { domainsBeingBlocked }) => count + domainsBeingBlocked, 0),
2,
),
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(
data.reduce((count, { domainsBeingBlocked }) => count + domainsBeingBlocked, 0),
2,
) + suffix
);
},
tooltip: (data, t) => (data.length >= 2 ? t("widget.dnsHoleSummary.domainsTooltip") : undefined),
label: (t) => t("widget.dnsHoleSummary.data.domainsBeingBlocked"),
color: "rgba(0, 176, 96, 0.4)", // GREEN
},
] satisfies StatItem[];

interface StatItem {
icon: TablerIcon;
value: (x: DnsHoleSummary[]) => string;
value: (summaries: DnsHoleSummary[]) => string;
tooltip?: (summaries: DnsHoleSummary[], t: TranslationFunction) => string | undefined;
label: stringOrTranslation;
color: string;
}
Expand All @@ -144,58 +151,61 @@ interface StatCardProps {
const StatCard = ({ item, data, usePiHoleColors, t }: StatCardProps) => {
const { ref, height, width } = useElementSize();
const isLong = width > height + 20;
const tooltip = item.tooltip?.(data, t);

return (
<Card
ref={ref}
className="summary-card"
m="2cqmin"
p="2.5cqmin"
bg={usePiHoleColors ? item.color : "rgba(96, 96, 96, 0.1)"}
style={{
flex: 1,
}}
withBorder
>
<Flex
className="summary-card-elements"
h="100%"
w="100%"
align="center"
justify="space-evenly"
direction={isLong ? "row" : "column"}
style={{ containerType: "size" }}
<TooltipFloating label={tooltip} disabled={!tooltip} w={250} multiline>
<Card
ref={ref}
className="summary-card"
m="2cqmin"
p="2.5cqmin"
bg={usePiHoleColors ? item.color : "rgba(96, 96, 96, 0.1)"}
style={{
flex: 1,
}}
withBorder
>
<item.icon className="summary-card-icon" size="40cqmin" style={{ margin: "2.5cqmin" }} />
<Flex
className="summary-card-texts"
justify="center"
direction="column"
style={{
flex: isLong ? 1 : undefined,
}}
w="100%"
className="summary-card-elements"
h="100%"
gap="1cqmin"
w="100%"
align="center"
justify="space-evenly"
direction={isLong ? "row" : "column"}
style={{ containerType: "size" }}
>
<Text
key={item.value(data)}
className="summary-card-value text-flash"
ta="center"
size="20cqmin"
fw="bold"
style={{ "--glow-size": "2.5cqmin" }}
<item.icon className="summary-card-icon" size="40cqmin" style={{ margin: "2.5cqmin" }} />
<Flex
className="summary-card-texts"
justify="center"
direction="column"
style={{
flex: isLong ? 1 : undefined,
}}
w="100%"
h="100%"
gap="1cqmin"
>
{item.value(data)}
</Text>
{item.label && (
<Text className="summary-card-label" ta="center" size="15cqmin">
{translateIfNecessary(t, item.label)}
<Text
key={item.value(data)}
className="summary-card-value text-flash"
ta="center"
size="20cqmin"
fw="bold"
style={{ "--glow-size": "2.5cqmin" }}
>
{item.value(data)}
</Text>
)}
{item.label && (
<Text className="summary-card-label" ta="center" size="15cqmin">
{translateIfNecessary(t, item.label)}
</Text>
)}
</Flex>
</Flex>
</Flex>
</Card>
</Card>
</TooltipFloating>
);
};

Expand Down

0 comments on commit 546c824

Please sign in to comment.