mirror of
https://github.com/ajnart/homarr.git
synced 2026-02-28 01:10:54 +01:00
fix: DnsHole controls timer (#953)
* fix: DnsHole controls timer * fix: use plural naming * fix: reviewed changes * fix: change ControlsCard to jsx component * fix: DeepSource
This commit is contained in:
@@ -123,7 +123,7 @@ export class AdGuardHomeIntegration extends Integration implements DnsHoleSummar
|
||||
}
|
||||
}
|
||||
|
||||
public async disableAsync(duration?: number): Promise<void> {
|
||||
public async disableAsync(duration = 0): Promise<void> {
|
||||
const response = await fetch(`${this.integration.url}/control/protection`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
@@ -132,7 +132,7 @@ export class AdGuardHomeIntegration extends Integration implements DnsHoleSummar
|
||||
},
|
||||
body: JSON.stringify({
|
||||
enabled: false,
|
||||
duration: duration,
|
||||
duration: duration * 1000,
|
||||
}),
|
||||
});
|
||||
if (!response.ok) {
|
||||
|
||||
@@ -8,11 +8,11 @@ import { useI18n } from "@homarr/translation/client";
|
||||
interface TimerModalProps {
|
||||
opened: boolean;
|
||||
close: () => void;
|
||||
integrationIds: string[];
|
||||
selectedIntegrationIds: string[];
|
||||
disableDns: (data: { duration: number; integrationId: string }) => void;
|
||||
}
|
||||
|
||||
const TimerModal = ({ opened, close, integrationIds, disableDns }: TimerModalProps) => {
|
||||
const TimerModal = ({ opened, close, selectedIntegrationIds, disableDns }: TimerModalProps) => {
|
||||
const t = useI18n();
|
||||
const [hours, setHours] = useState(0);
|
||||
const [minutes, setMinutes] = useState(0);
|
||||
@@ -21,7 +21,7 @@ const TimerModal = ({ opened, close, integrationIds, disableDns }: TimerModalPro
|
||||
|
||||
const handleSetTimer = () => {
|
||||
const duration = hours * 3600 + minutes * 60;
|
||||
integrationIds.forEach((integrationId) => {
|
||||
selectedIntegrationIds.forEach((integrationId) => {
|
||||
disableDns({ duration, integrationId });
|
||||
});
|
||||
setHours(0);
|
||||
|
||||
@@ -24,6 +24,7 @@ export default function DnsHoleControlsWidget({ options, integrationIds }: Widge
|
||||
const [status, setStatus] = useState<{ integrationId: string; enabled: boolean }[]>(
|
||||
integrationIds.map((id) => ({ integrationId: id, enabled: false })),
|
||||
);
|
||||
const [selectedIntegrationIds, setSelectedIntegrationIds] = useState<string[]>([]);
|
||||
const [opened, { close, open }] = useDisclosure(false);
|
||||
|
||||
const [data] = clientApi.widget.dnsHole.summary.useSuspenseQuery(
|
||||
@@ -67,8 +68,10 @@ export default function DnsHoleControlsWidget({ options, integrationIds }: Widge
|
||||
}
|
||||
};
|
||||
|
||||
const allEnabled = status.every((item) => item.enabled);
|
||||
const allDisabled = status.every((item) => !item.enabled);
|
||||
const enabledIntegrations = integrationIds.filter((id) => status.find((item) => item.integrationId === id)?.enabled);
|
||||
const disabledIntegrations = integrationIds.filter(
|
||||
(id) => !status.find((item) => item.integrationId === id)?.enabled,
|
||||
);
|
||||
|
||||
return (
|
||||
<Flex h="100%" direction="column" gap={0} p="2.5cqmin">
|
||||
@@ -76,10 +79,8 @@ export default function DnsHoleControlsWidget({ options, integrationIds }: Widge
|
||||
<Flex gap="2.5cqmin">
|
||||
<Tooltip label={t("widget.dnsHoleControls.controls.enableAll")}>
|
||||
<Button
|
||||
onClick={() => {
|
||||
integrationIds.forEach((integrationId) => enableDns({ integrationId }));
|
||||
}}
|
||||
disabled={allEnabled}
|
||||
onClick={() => disabledIntegrations.forEach((integrationId) => enableDns({ integrationId }))}
|
||||
disabled={disabledIntegrations.length === 0}
|
||||
variant="light"
|
||||
color="green"
|
||||
fullWidth
|
||||
@@ -90,17 +91,25 @@ export default function DnsHoleControlsWidget({ options, integrationIds }: Widge
|
||||
</Tooltip>
|
||||
|
||||
<Tooltip label={t("widget.dnsHoleControls.controls.setTimer")}>
|
||||
<Button onClick={open} disabled={allDisabled} variant="light" color="yellow" fullWidth h="2rem">
|
||||
<Button
|
||||
onClick={() => {
|
||||
setSelectedIntegrationIds(enabledIntegrations);
|
||||
open();
|
||||
}}
|
||||
disabled={enabledIntegrations.length === 0}
|
||||
variant="light"
|
||||
color="yellow"
|
||||
fullWidth
|
||||
h="2rem"
|
||||
>
|
||||
<IconClockPause size={20} />
|
||||
</Button>
|
||||
</Tooltip>
|
||||
|
||||
<Tooltip label={t("widget.dnsHoleControls.controls.disableAll")}>
|
||||
<Button
|
||||
onClick={() => {
|
||||
integrationIds.forEach((integrationId) => disableDns({ integrationId, duration: 0 }));
|
||||
}}
|
||||
disabled={allDisabled}
|
||||
onClick={() => enabledIntegrations.forEach((integrationId) => disableDns({ integrationId, duration: 0 }))}
|
||||
disabled={enabledIntegrations.length === 0}
|
||||
variant="light"
|
||||
color="red"
|
||||
fullWidth
|
||||
@@ -113,24 +122,49 @@ export default function DnsHoleControlsWidget({ options, integrationIds }: Widge
|
||||
)}
|
||||
|
||||
<Stack gap="2.5cqmin" flex={1} justify={options.showToggleAllButtons ? "flex-end" : "space-evenly"}>
|
||||
{data.map((integrationData) =>
|
||||
ControlsCard(integrationData.integrationId, integrationData.integrationKind, toggleDns, status, open, t),
|
||||
)}
|
||||
{data.map((integrationData) => (
|
||||
<ControlsCard
|
||||
key={integrationData.integrationId}
|
||||
integrationId={integrationData.integrationId}
|
||||
integrationKind={integrationData.integrationKind}
|
||||
toggleDns={toggleDns}
|
||||
status={status}
|
||||
setSelectedIntegrationIds={setSelectedIntegrationIds}
|
||||
open={open}
|
||||
t={t}
|
||||
/>
|
||||
))}
|
||||
</Stack>
|
||||
|
||||
<TimerModal opened={opened} close={close} integrationIds={integrationIds} disableDns={disableDns} />
|
||||
<TimerModal
|
||||
opened={opened}
|
||||
close={close}
|
||||
selectedIntegrationIds={selectedIntegrationIds}
|
||||
disableDns={disableDns}
|
||||
/>
|
||||
</Flex>
|
||||
);
|
||||
}
|
||||
|
||||
const ControlsCard = (
|
||||
integrationId: string,
|
||||
integrationKind: string,
|
||||
toggleDns: (integrationId: string) => void,
|
||||
status: { integrationId: string; enabled: boolean }[],
|
||||
open: () => void,
|
||||
t: TranslationFunction,
|
||||
) => {
|
||||
interface ControlsCardProps {
|
||||
integrationId: string;
|
||||
integrationKind: string;
|
||||
toggleDns: (integrationId: string) => void;
|
||||
status: { integrationId: string; enabled: boolean }[];
|
||||
setSelectedIntegrationIds: (integrationId: string[]) => void;
|
||||
open: () => void;
|
||||
t: TranslationFunction;
|
||||
}
|
||||
|
||||
const ControlsCard: React.FC<ControlsCardProps> = ({
|
||||
integrationId,
|
||||
integrationKind,
|
||||
toggleDns,
|
||||
status,
|
||||
setSelectedIntegrationIds,
|
||||
open,
|
||||
t,
|
||||
}) => {
|
||||
const integrationStatus = status.find((item) => item.integrationId === integrationId);
|
||||
const isEnabled = integrationStatus?.enabled ?? false;
|
||||
const integrationDef = integrationKind === "piHole" ? integrationDefs.piHole : integrationDefs.adGuardHome;
|
||||
@@ -149,7 +183,17 @@ const ControlsCard = (
|
||||
{t(`widget.dnsHoleControls.controls.${isEnabled ? "enabled" : "disabled"}`)}
|
||||
</Badge>
|
||||
</UnstyledButton>
|
||||
<ActionIcon disabled={!isEnabled} size={20} radius="xl" top="2.67px" variant="default" onClick={open}>
|
||||
<ActionIcon
|
||||
disabled={!isEnabled}
|
||||
size={20}
|
||||
radius="xl"
|
||||
top="2.67px"
|
||||
variant="default"
|
||||
onClick={() => {
|
||||
setSelectedIntegrationIds([integrationId]);
|
||||
open();
|
||||
}}
|
||||
>
|
||||
<IconClockPause size={20} color="red" />
|
||||
</ActionIcon>
|
||||
</Flex>
|
||||
|
||||
Reference in New Issue
Block a user