fix(dns-summary): improve responsive styles (#2535)
This commit is contained in:
@@ -63,7 +63,7 @@ export default function DnsHoleSummaryWidget({ options, integrationIds }: Widget
|
|||||||
const data = useMemo(() => summaries.flatMap(({ summary }) => summary), [summaries]);
|
const data = useMemo(() => summaries.flatMap(({ summary }) => summary), [summaries]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SimpleGrid cols={2} h="100%" p={"xs"} {...boxPropsByLayout(options.layout)}>
|
<SimpleGrid cols={2} spacing="xs" h="100%" p={"xs"} {...boxPropsByLayout(options.layout)}>
|
||||||
{data.length > 0 ? (
|
{data.length > 0 ? (
|
||||||
stats.map((item) => (
|
stats.map((item) => (
|
||||||
<StatCard key={item.color} item={item} usePiHoleColors={options.usePiHoleColors} data={data} t={t} />
|
<StatCard key={item.color} item={item} usePiHoleColors={options.usePiHoleColors} data={data} t={t} />
|
||||||
@@ -89,43 +89,43 @@ export default function DnsHoleSummaryWidget({ options, integrationIds }: Widget
|
|||||||
const stats = [
|
const stats = [
|
||||||
{
|
{
|
||||||
icon: IconBarrierBlock,
|
icon: IconBarrierBlock,
|
||||||
value: (data) =>
|
value: (data, size) =>
|
||||||
formatNumber(
|
formatNumber(
|
||||||
data.reduce((count, { adsBlockedToday }) => count + adsBlockedToday, 0),
|
data.reduce((count, { adsBlockedToday }) => count + adsBlockedToday, 0),
|
||||||
2,
|
size === "sm" ? 0 : 2,
|
||||||
),
|
),
|
||||||
label: (t) => t("widget.dnsHoleSummary.data.adsBlockedToday"),
|
label: (t) => t("widget.dnsHoleSummary.data.adsBlockedToday"),
|
||||||
color: "rgba(240, 82, 60, 0.4)", // RED
|
color: "rgba(240, 82, 60, 0.4)", // RED
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
icon: IconPercentage,
|
icon: IconPercentage,
|
||||||
value: (data) => {
|
value: (data, size) => {
|
||||||
const totalCount = data.reduce((count, { dnsQueriesToday }) => count + dnsQueriesToday, 0);
|
const totalCount = data.reduce((count, { dnsQueriesToday }) => count + dnsQueriesToday, 0);
|
||||||
const blocked = data.reduce((count, { adsBlockedToday }) => count + adsBlockedToday, 0);
|
const blocked = data.reduce((count, { adsBlockedToday }) => count + adsBlockedToday, 0);
|
||||||
return `${formatNumber(totalCount === 0 ? 0 : (blocked / totalCount) * 100, 2)}%`;
|
return `${formatNumber(totalCount === 0 ? 0 : (blocked / totalCount) * 100, size === "sm" ? 0 : 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
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
icon: IconSearch,
|
icon: IconSearch,
|
||||||
value: (data) =>
|
value: (data, size) =>
|
||||||
formatNumber(
|
formatNumber(
|
||||||
data.reduce((count, { dnsQueriesToday }) => count + dnsQueriesToday, 0),
|
data.reduce((count, { dnsQueriesToday }) => count + dnsQueriesToday, 0),
|
||||||
2,
|
size === "sm" ? 0 : 2,
|
||||||
),
|
),
|
||||||
label: (t) => t("widget.dnsHoleSummary.data.dnsQueriesToday"),
|
label: (t) => t("widget.dnsHoleSummary.data.dnsQueriesToday"),
|
||||||
color: "rgba(0, 175, 218, 0.4)", // BLUE
|
color: "rgba(0, 175, 218, 0.4)", // BLUE
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
icon: IconWorldWww,
|
icon: IconWorldWww,
|
||||||
value: (data) => {
|
value: (data, size) => {
|
||||||
// We use a suffix to indicate that there might be more domains in the at least two lists.
|
// We use a suffix to indicate that there might be more domains in the at least two lists.
|
||||||
const suffix = data.length >= 2 ? "+" : "";
|
const suffix = data.length >= 2 ? "+" : "";
|
||||||
return (
|
return (
|
||||||
formatNumber(
|
formatNumber(
|
||||||
data.reduce((count, { domainsBeingBlocked }) => count + domainsBeingBlocked, 0),
|
data.reduce((count, { domainsBeingBlocked }) => count + domainsBeingBlocked, 0),
|
||||||
2,
|
size === "sm" ? 0 : 2,
|
||||||
) + suffix
|
) + suffix
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
@@ -137,7 +137,7 @@ const stats = [
|
|||||||
|
|
||||||
interface StatItem {
|
interface StatItem {
|
||||||
icon: TablerIcon;
|
icon: TablerIcon;
|
||||||
value: (summaries: DnsHoleSummary[]) => string;
|
value: (summaries: DnsHoleSummary[], size: "sm" | "md") => string;
|
||||||
tooltip?: (summaries: DnsHoleSummary[], t: TranslationFunction) => string | undefined;
|
tooltip?: (summaries: DnsHoleSummary[], t: TranslationFunction) => string | undefined;
|
||||||
label: stringOrTranslation;
|
label: stringOrTranslation;
|
||||||
color: string;
|
color: string;
|
||||||
@@ -152,6 +152,7 @@ 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 hideLabel = (height <= 32 && width <= 256) || (height <= 64 && width <= 92);
|
||||||
const tooltip = item.tooltip?.(data, t);
|
const tooltip = item.tooltip?.(data, t);
|
||||||
const board = useRequiredBoard();
|
const board = useRequiredBoard();
|
||||||
|
|
||||||
@@ -174,25 +175,26 @@ const StatCard = ({ item, data, usePiHoleColors, t }: StatCardProps) => {
|
|||||||
align="center"
|
align="center"
|
||||||
justify="center"
|
justify="center"
|
||||||
direction={isLong ? "row" : "column"}
|
direction={isLong ? "row" : "column"}
|
||||||
style={{ containerType: "size" }}
|
gap={0}
|
||||||
>
|
>
|
||||||
<item.icon className="summary-card-icon" size={50} />
|
<item.icon className="summary-card-icon" size={24} style={{ minWidth: 24, minHeight: 24 }} />
|
||||||
<Flex
|
<Flex
|
||||||
className="summary-card-texts"
|
className="summary-card-texts"
|
||||||
justify="center"
|
justify="center"
|
||||||
direction="column"
|
align="center"
|
||||||
|
direction={isLong ? "row" : "column"}
|
||||||
style={{
|
style={{
|
||||||
flex: isLong ? 1 : undefined,
|
flex: isLong ? 1 : undefined,
|
||||||
}}
|
}}
|
||||||
mt={"xs"}
|
|
||||||
w="100%"
|
w="100%"
|
||||||
gap={0}
|
gap={isLong ? 4 : 0}
|
||||||
|
wrap="wrap"
|
||||||
>
|
>
|
||||||
<Text key={item.value(data)} className="summary-card-value text-flash" ta="center" size="lg" fw="bold">
|
<Text className="summary-card-value text-flash" ta="center" size="lg" fw="bold" maw="100%">
|
||||||
{item.value(data)}
|
{item.value(data, width <= 64 ? "sm" : "md")}
|
||||||
</Text>
|
</Text>
|
||||||
{item.label && (
|
{!hideLabel && (
|
||||||
<Text className="summary-card-label" ta="center" size="md">
|
<Text className="summary-card-label" ta="center" size="xs" maw="100%">
|
||||||
{translateIfNecessary(t, item.label)}
|
{translateIfNecessary(t, item.label)}
|
||||||
</Text>
|
</Text>
|
||||||
)}
|
)}
|
||||||
|
|||||||
Reference in New Issue
Block a user