feat: dnshole controls widget (#867)

* feat: dnshole controls widget

* feat: add duration and timer modal

* fix: code improvment

* fix: add support for many integrations

* fix: add support for more integrations

* fix: move ControlsCard outside of main component

* fix: deepsource
This commit is contained in:
Yossi Hillali
2024-08-04 18:47:00 +03:00
committed by GitHub
parent 9013d5dbf0
commit 65c6854e44
14 changed files with 501 additions and 29 deletions

View File

@@ -5,28 +5,90 @@ import type { DnsHoleSummary } from "@homarr/integrations/types";
import { logger } from "@homarr/log";
import { createCacheChannel } from "@homarr/redis";
import { createOneIntegrationMiddleware } from "../../middlewares/integration";
import { controlsInputSchema } from "../../../../integrations/src/pi-hole/pi-hole-types";
import { createManyIntegrationMiddleware, createOneIntegrationMiddleware } from "../../middlewares/integration";
import { createTRPCRouter, publicProcedure } from "../../trpc";
export const dnsHoleRouter = createTRPCRouter({
summary: publicProcedure.unstable_concat(createOneIntegrationMiddleware("query", "piHole")).query(async ({ ctx }) => {
const cache = createCacheChannel<DnsHoleSummary>(`dns-hole-summary:${ctx.integration.id}`);
summary: publicProcedure
.unstable_concat(createManyIntegrationMiddleware("query", "piHole", "adGuardHome"))
.query(async ({ ctx }) => {
const results = await Promise.all(
ctx.integrations.map(async (integration) => {
const cache = createCacheChannel<DnsHoleSummary>(`dns-hole-summary:${integration.id}`);
const { data } = await cache.consumeAsync(async () => {
let client;
switch (integration.kind) {
case "piHole":
client = new PiHoleIntegration(integration);
break;
// case 'adGuardHome':
// client = new AdGuardHomeIntegration(integration);
// break;
default:
throw new TRPCError({
code: "INTERNAL_SERVER_ERROR",
message: `Unsupported integration type: ${integration.kind}`,
});
}
const { data } = await cache.consumeAsync(async () => {
const client = new PiHoleIntegration(ctx.integration);
return await client.getSummaryAsync().catch((err) => {
logger.error("dns-hole router - ", err);
throw new TRPCError({
code: "INTERNAL_SERVER_ERROR",
message: `Failed to fetch DNS Hole summary for ${integration.name} (${integration.id})`,
});
});
});
return await client.getSummaryAsync().catch((err) => {
logger.error("dns-hole router - ", err);
throw new TRPCError({
code: "INTERNAL_SERVER_ERROR",
message: `Failed to fetch DNS Hole summary for ${ctx.integration.name} (${ctx.integration.id})`,
});
});
});
return {
integrationId: integration.id,
integrationKind: integration.kind,
summary: data,
};
}),
);
return results;
}),
return {
...data,
integrationId: ctx.integration.id,
};
}),
enable: publicProcedure
.unstable_concat(createOneIntegrationMiddleware("interact", "piHole", "adGuardHome"))
.mutation(async ({ ctx }) => {
let client;
switch (ctx.integration.kind) {
case "piHole":
client = new PiHoleIntegration(ctx.integration);
break;
// case 'adGuardHome':
// client = new AdGuardHomeIntegration(ctx.integration);
// break;
default:
throw new TRPCError({
code: "INTERNAL_SERVER_ERROR",
message: `Unsupported integration type: ${ctx.integration.kind}`,
});
}
await client.enableAsync();
}),
disable: publicProcedure
.input(controlsInputSchema)
.unstable_concat(createOneIntegrationMiddleware("interact", "piHole", "adGuardHome"))
.mutation(async ({ ctx, input }) => {
let client;
switch (ctx.integration.kind) {
case "piHole":
client = new PiHoleIntegration(ctx.integration);
break;
// case 'adGuardHome':
// client = new AdGuardHomeIntegration(ctx.integration);
// break;
default:
throw new TRPCError({
code: "INTERNAL_SERVER_ERROR",
message: `Unsupported integration type: ${ctx.integration.kind}`,
});
}
await client.disableAsync(input.duration);
}),
});