mirror of
https://github.com/ajnart/homarr.git
synced 2025-11-10 15:35:55 +01:00
🏗️ Migrate dnshole controls to tRPC
This commit is contained in:
@@ -5,6 +5,7 @@ import { configRouter } from './routers/config';
|
|||||||
import { dockerRouter } from './routers/docker/router';
|
import { dockerRouter } from './routers/docker/router';
|
||||||
import { iconRouter } from './routers/icon';
|
import { iconRouter } from './routers/icon';
|
||||||
import { dashDotRouter } from './routers/dash-dot';
|
import { dashDotRouter } from './routers/dash-dot';
|
||||||
|
import { dnsHoleRouter } from './routers/dns-hole';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is the primary router for your server.
|
* This is the primary router for your server.
|
||||||
@@ -18,6 +19,7 @@ export const rootRouter = createTRPCRouter({
|
|||||||
docker: dockerRouter,
|
docker: dockerRouter,
|
||||||
icon: iconRouter,
|
icon: iconRouter,
|
||||||
dashDot: dashDotRouter,
|
dashDot: dashDotRouter,
|
||||||
|
dnsHole: dnsHoleRouter,
|
||||||
});
|
});
|
||||||
|
|
||||||
// export type definition of API
|
// export type definition of API
|
||||||
|
|||||||
61
src/server/api/routers/dns-hole.ts
Normal file
61
src/server/api/routers/dns-hole.ts
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
import { z } from 'zod';
|
||||||
|
import { createTRPCRouter, publicProcedure } from '../trpc';
|
||||||
|
import { getConfig } from '~/tools/config/getConfig';
|
||||||
|
import { AdGuard } from '~/tools/server/sdk/adGuard/adGuard';
|
||||||
|
import { ConfigAppType } from '~/types/app';
|
||||||
|
import { findAppProperty } from '~/tools/client/app-properties';
|
||||||
|
import { PiHoleClient } from '~/tools/server/sdk/pihole/piHole';
|
||||||
|
|
||||||
|
export const dnsHoleRouter = createTRPCRouter({
|
||||||
|
control: publicProcedure
|
||||||
|
.input(
|
||||||
|
z.object({
|
||||||
|
status: z.enum(['enabled', 'disabled']),
|
||||||
|
configName: z.string(),
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.mutation(async ({ input }) => {
|
||||||
|
const config = getConfig(input.configName);
|
||||||
|
|
||||||
|
const applicableApps = config.apps.filter(
|
||||||
|
(x) => x.integration?.type && ['pihole', 'adGuardHome'].includes(x.integration?.type)
|
||||||
|
);
|
||||||
|
|
||||||
|
await Promise.all(
|
||||||
|
applicableApps.map(async (app) => {
|
||||||
|
if (app.integration?.type === 'pihole') {
|
||||||
|
await processPiHole(app, input.status === 'disabled');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await processAdGuard(app, input.status === 'disabled');
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
const processAdGuard = async (app: ConfigAppType, enable: boolean) => {
|
||||||
|
const adGuard = new AdGuard(
|
||||||
|
app.url,
|
||||||
|
findAppProperty(app, 'username'),
|
||||||
|
findAppProperty(app, 'password')
|
||||||
|
);
|
||||||
|
|
||||||
|
if (enable) {
|
||||||
|
await adGuard.disable();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await adGuard.enable();
|
||||||
|
};
|
||||||
|
|
||||||
|
const processPiHole = async (app: ConfigAppType, enable: boolean) => {
|
||||||
|
const pihole = new PiHoleClient(app.url, findAppProperty(app, 'password'));
|
||||||
|
|
||||||
|
if (enable) {
|
||||||
|
await pihole.enable();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await pihole.disable();
|
||||||
|
};
|
||||||
@@ -5,9 +5,10 @@ import { useConfigContext } from '../../config/provider';
|
|||||||
import { defineWidget } from '../helper';
|
import { defineWidget } from '../helper';
|
||||||
import { WidgetLoading } from '../loading';
|
import { WidgetLoading } from '../loading';
|
||||||
import { IWidget } from '../widgets';
|
import { IWidget } from '../widgets';
|
||||||
import { useDnsHoleControlMutation, useDnsHoleSummeryQuery } from './query';
|
import { useDnsHoleSummeryQuery } from './query';
|
||||||
import { PiholeApiSummaryType } from './type';
|
import { PiholeApiSummaryType } from './type';
|
||||||
import { queryClient } from '../../tools/server/configurations/tanstack/queryClient.tool';
|
import { queryClient } from '../../tools/server/configurations/tanstack/queryClient.tool';
|
||||||
|
import { api } from '~/utils/api';
|
||||||
|
|
||||||
const definition = defineWidget({
|
const definition = defineWidget({
|
||||||
id: 'dns-hole-controls',
|
id: 'dns-hole-controls',
|
||||||
@@ -33,9 +34,9 @@ function DnsHoleControlsWidgetTile({ widget }: DnsHoleControlsWidgetProps) {
|
|||||||
const { mutateAsync } = useDnsHoleControlMutation();
|
const { mutateAsync } = useDnsHoleControlMutation();
|
||||||
const { t } = useTranslation('common');
|
const { t } = useTranslation('common');
|
||||||
|
|
||||||
const { config } = useConfigContext();
|
const { name: configName, config } = useConfigContext();
|
||||||
|
|
||||||
if (isInitialLoading || !data) {
|
if (isInitialLoading || !data || !configName) {
|
||||||
return <WidgetLoading />;
|
return <WidgetLoading />;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,7 +45,10 @@ function DnsHoleControlsWidgetTile({ widget }: DnsHoleControlsWidgetProps) {
|
|||||||
<Group grow>
|
<Group grow>
|
||||||
<Button
|
<Button
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
await mutateAsync('enabled');
|
await mutateAsync({
|
||||||
|
status: 'enabled',
|
||||||
|
configName,
|
||||||
|
});
|
||||||
await queryClient.invalidateQueries({ queryKey: ['dns-hole-summary'] });
|
await queryClient.invalidateQueries({ queryKey: ['dns-hole-summary'] });
|
||||||
}}
|
}}
|
||||||
leftIcon={<IconPlayerPlay size={20} />}
|
leftIcon={<IconPlayerPlay size={20} />}
|
||||||
@@ -55,7 +59,10 @@ function DnsHoleControlsWidgetTile({ widget }: DnsHoleControlsWidgetProps) {
|
|||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
await mutateAsync('disabled');
|
await mutateAsync({
|
||||||
|
status: 'disabled',
|
||||||
|
configName,
|
||||||
|
});
|
||||||
await queryClient.invalidateQueries({ queryKey: ['dns-hole-summary'] });
|
await queryClient.invalidateQueries({ queryKey: ['dns-hole-summary'] });
|
||||||
}}
|
}}
|
||||||
leftIcon={<IconPlayerStop size={20} />}
|
leftIcon={<IconPlayerStop size={20} />}
|
||||||
@@ -117,4 +124,6 @@ const StatusBadge = ({ status }: { status: PiholeApiSummaryType['status'] }) =>
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const useDnsHoleControlMutation = () => api.dnsHole.control.useMutation();
|
||||||
|
|
||||||
export default definition;
|
export default definition;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { useMutation, useQuery } from '@tanstack/react-query';
|
import { useQuery } from '@tanstack/react-query';
|
||||||
import { AdStatistics, PiholeApiSummaryType } from './type';
|
import { AdStatistics } from './type';
|
||||||
|
|
||||||
export const useDnsHoleSummeryQuery = () =>
|
export const useDnsHoleSummeryQuery = () =>
|
||||||
useQuery({
|
useQuery({
|
||||||
@@ -10,14 +10,3 @@ export const useDnsHoleSummeryQuery = () =>
|
|||||||
},
|
},
|
||||||
refetchInterval: 3 * 60 * 1000,
|
refetchInterval: 3 * 60 * 1000,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const useDnsHoleControlMutation = () =>
|
|
||||||
useMutation({
|
|
||||||
mutationKey: ['dns-hole-control'],
|
|
||||||
mutationFn: async (status: PiholeApiSummaryType['status']) => {
|
|
||||||
const response = await fetch(`/api/modules/dns-hole/control?status=${status}`, {
|
|
||||||
method: 'POST',
|
|
||||||
});
|
|
||||||
return response.json();
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|||||||
Reference in New Issue
Block a user