diff --git a/src/components/Dashboard/Tiles/DashDot/DashDotCompactStorage.tsx b/src/components/Dashboard/Tiles/DashDot/DashDotCompactStorage.tsx index 1bf40c048..967c81a68 100644 --- a/src/components/Dashboard/Tiles/DashDot/DashDotCompactStorage.tsx +++ b/src/components/Dashboard/Tiles/DashDot/DashDotCompactStorage.tsx @@ -2,33 +2,25 @@ import { Group, Stack, Text } from '@mantine/core'; import { useQuery } from '@tanstack/react-query'; import axios from 'axios'; import { useTranslation } from 'next-i18next'; +import { useConfigContext } from '../../../../config/provider'; import { bytes } from '../../../../tools/bytesHelper'; import { percentage } from '../../../../tools/percentage'; import { DashDotInfo } from './DashDotTile'; interface DashDotCompactStorageProps { info: DashDotInfo; - dashDotUrl: string; } -export const DashDotCompactStorage = ({ info, dashDotUrl }: DashDotCompactStorageProps) => { +export const DashDotCompactStorage = ({ info }: DashDotCompactStorageProps) => { const { t } = useTranslation('modules/dashdot'); - const { data: storageLoad } = useQuery({ - queryKey: [ - 'dashdot/storageLoad', - { - dashDotUrl, - }, - ], - queryFn: () => fetchDashDotStorageLoad(dashDotUrl), - }); + const { data: storageLoad } = useDashDotStorage(); const totalUsed = calculateTotalLayoutSize({ layout: storageLoad?.layout ?? [], key: 'load', }); const totalSize = calculateTotalLayoutSize({ - layout: info?.storage.layout ?? [], + layout: info?.storage?.layout ?? [], key: 'size', }); @@ -61,9 +53,26 @@ interface CalculateTotalLayoutSizeProps { key: keyof TLayoutItem; } -const fetchDashDotStorageLoad = async (targetUrl: string) => { +const useDashDotStorage = () => { + const { name: configName, config } = useConfigContext(); + + return useQuery({ + queryKey: [ + 'dashdot/storage', + { + configName, + url: config?.integrations.dashDot?.properties.url, + }, + ], + queryFn: () => fetchDashDotStorageLoad(configName), + }); +}; + +const fetchDashDotStorageLoad = async (configName: string | undefined) => { + console.log('storage request: ' + configName); + if (!configName) return; return (await ( - await axios.get('/api/modules/dashdot', { params: { url: '/load/storage', base: targetUrl } }) + await axios.get('/api/modules/dashdot/storage', { params: { configName } }) ).data) as DashDotStorageLoad; }; diff --git a/src/components/Dashboard/Tiles/DashDot/DashDotTile.tsx b/src/components/Dashboard/Tiles/DashDot/DashDotTile.tsx index 89ceb5612..e3c7535ba 100644 --- a/src/components/Dashboard/Tiles/DashDot/DashDotTile.tsx +++ b/src/components/Dashboard/Tiles/DashDot/DashDotTile.tsx @@ -17,6 +17,8 @@ import { BaseTileProps } from '../type'; import { DashDotGraph } from './DashDotGraph'; import { DashDotIntegrationType } from '../../../../types/integration'; import { IntegrationsMenu } from '../Integrations/IntegrationsMenu'; +import { useConfigContext } from '../../../../config/provider'; +import { HomarrCardWrapper } from '../HomarrCardWrapper'; interface DashDotTileProps extends BaseTileProps { module: DashDotIntegrationType | undefined; @@ -28,7 +30,7 @@ export const DashDotTile = ({ module, className }: DashDotTileProps) => { const dashDotUrl = module?.properties.url; - const { data: info } = useDashDotInfo(dashDotUrl); + const { data: info } = useDashDotInfo(); const graphs = module?.properties.graphs.map((g) => ({ id: g, @@ -62,13 +64,13 @@ export const DashDotTile = ({ module, className }: DashDotTileProps) => { if (!dashDotUrl) { return ( - + {menu}
{heading}

{t('card.errors.noService')}

-
+ ); } @@ -83,16 +85,14 @@ export const DashDotTile = ({ module, className }: DashDotTileProps) => { ); return ( - + {menu} {heading} {!info &&

{t('card.errors.noInformation')}

} {info && (
- {isCompactStorageVisible && ( - - )} + {isCompactStorageVisible && } {isCompactNetworkVisible && } @@ -107,26 +107,28 @@ export const DashDotTile = ({ module, className }: DashDotTileProps) => {
)} -
+ ); }; -const useDashDotInfo = (dashDotUrl: string | undefined) => { +const useDashDotInfo = () => { + const { name: configName, config } = useConfigContext(); return useQuery({ queryKey: [ 'dashdot/info', { - dashDotUrl, + configName, + url: config?.integrations.dashDot?.properties.url, }, ], - queryFn: () => fetchDashDotInfo(dashDotUrl), + queryFn: () => fetchDashDotInfo(configName), }); }; -const fetchDashDotInfo = async (targetUrl: string | undefined) => { - if (!targetUrl) return {} as DashDotInfo; +const fetchDashDotInfo = async (configName: string | undefined) => { + if (!configName) return {} as DashDotInfo; return (await ( - await axios.get('/api/modules/dashdot', { params: { url: '/info', base: targetUrl } }) + await axios.get('/api/modules/dashdot/info', { params: { configName } }) ).data) as DashDotInfo; }; diff --git a/src/components/Dashboard/Tiles/tilesDefinitions.tsx b/src/components/Dashboard/Tiles/tilesDefinitions.tsx index 3bd3aebfe..4d1b66c1c 100644 --- a/src/components/Dashboard/Tiles/tilesDefinitions.tsx +++ b/src/components/Dashboard/Tiles/tilesDefinitions.tsx @@ -1,6 +1,7 @@ import { IntegrationsType } from '../../../types/integration'; import { CalendarTile } from './Calendar/CalendarTile'; import { ClockTile } from './Clock/ClockTile'; +import { DashDotTile } from './DashDot/DashDotTile'; import { EmptyTile } from './EmptyTile'; import { ServiceTile } from './Service/ServiceTile'; import { UseNetTile } from './UseNet/UseNetTile'; @@ -50,7 +51,7 @@ export const Tiles: TileDefinitionProps = { maxHeight: 12, }, dashDot: { - component: EmptyTile, //DashDotTile, + component: DashDotTile, minWidth: 4, maxWidth: 9, minHeight: 5, diff --git a/src/pages/api/modules/calendar.ts b/src/pages/api/modules/calendar.ts index 7607f667c..60b7ba113 100644 --- a/src/pages/api/modules/calendar.ts +++ b/src/pages/api/modules/calendar.ts @@ -3,73 +3,6 @@ import { NextApiRequest, NextApiResponse } from 'next'; import { getConfig } from '../../../tools/config/getConfig'; import { ServiceIntegrationType, ServiceType } from '../../../types/service'; -/*async function Post(req: NextApiRequest, res: NextApiResponse) { - // Parse req.body as a ServiceItem - const { id } = req.body; - const { type } = req.query; - const configName = getCookie('config-name', { req }); - const { config }: { config: Config } = getConfig(configName?.toString() ?? 'default').props; - // Find service with serviceId in config - const service = config.services.find((service) => service.id === id); - if (!service) { - return res.status(500).json({ - statusCode: 500, - message: 'Missing service', - }); - } - - const nextMonth = new Date(new Date().setMonth(new Date().getMonth() + 2)).toISOString(); - const lastMonth = new Date(new Date().setMonth(new Date().getMonth() - 2)).toISOString(); - const TypeToUrl: { service: string; url: string }[] = [ - { - service: 'sonarr', - url: '/api/calendar', - }, - { - service: 'radarr', - url: '/api/v3/calendar', - }, - { - service: 'lidarr', - url: '/api/v1/calendar', - }, - { - service: 'readarr', - url: '/api/v1/calendar', - }, - ]; - if (!type) { - return res.status(400).json({ - message: 'Missing required parameter in url: type', - }); - } - if (!service) { - return res.status(400).json({ - message: 'Missing required parameter in body: service', - }); - } - // Match the type to the correct url - const url = TypeToUrl.find((x) => x.service === type); - if (!url) { - return res.status(400).json({ - message: 'Invalid type', - }); - } - // Get the origin URL - let { href: origin } = new URL(service.url); - if (origin.endsWith('/')) { - origin = origin.slice(0, -1); - } - const pined = `${origin}${url?.url}?apiKey=${service.apiKey}&end=${nextMonth}&start=${lastMonth}`; - return axios - .get(`${origin}${url?.url}?apiKey=${service.apiKey}&end=${nextMonth}&start=${lastMonth}`) - .then((response) => res.status(200).json(response.data)) - .catch((e) => res.status(500).json(e)); - // // Make a request to the URL - // const response = await axios.get(url); - // // Return the response -}*/ - export default async (req: NextApiRequest, res: NextApiResponse) => { // Filter out if the reuqest is a POST or a GET if (req.method === 'GET') { diff --git a/src/pages/api/modules/dashdot.ts b/src/pages/api/modules/dashdot.ts deleted file mode 100644 index 8f9a990a5..000000000 --- a/src/pages/api/modules/dashdot.ts +++ /dev/null @@ -1,29 +0,0 @@ -import axios from 'axios'; -import { NextApiRequest, NextApiResponse } from 'next'; - -async function Get(req: NextApiRequest, res: NextApiResponse) { - // Extract url from req.query as string - const { url, base } = req.query; - - // If no url is provided, return an error - if (!url || !base) { - return res.status(400).json({ - message: 'Missing required parameter in url', - }); - } - // Get the origin URL - const response = await axios.get(url as string, { baseURL: base as string }); - // Return the response - return res.status(200).json(response.data); -} - -export default async (req: NextApiRequest, res: NextApiResponse) => { - // Filter out if the reuqest is a POST or a GET - if (req.method === 'GET') { - return Get(req, res); - } - return res.status(405).json({ - statusCode: 405, - message: 'Method not allowed', - }); -}; diff --git a/src/pages/api/modules/dashdot/info.ts b/src/pages/api/modules/dashdot/info.ts new file mode 100644 index 000000000..c4d03bd3f --- /dev/null +++ b/src/pages/api/modules/dashdot/info.ts @@ -0,0 +1,42 @@ +import axios from 'axios'; +import { NextApiRequest, NextApiResponse } from 'next'; +import { getConfig } from '../../../../tools/config/getConfig'; + +async function Get(req: NextApiRequest, res: NextApiResponse) { + const { configName } = req.query; + + if (!configName || typeof configName !== 'string') { + return res.status(400).json({ + message: 'Missing required configName in url', + }); + } + + const config = getConfig(configName); + + const dashDotUrl = config.integrations.dashDot?.properties.url; + + if (!dashDotUrl) { + return res.status(400).json({ + message: 'Dashdot url must be defined in config', + }); + } + + // Get the origin URL + const url = dashDotUrl.endsWith('/') + ? dashDotUrl.substring(0, dashDotUrl.length - 1) + : dashDotUrl; + const response = await axios.get(`${url}/info`); + // Return the response + return res.status(200).json(response.data); +} + +export default async (req: NextApiRequest, res: NextApiResponse) => { + // Filter out if the reuqest is a POST or a GET + if (req.method === 'GET') { + return Get(req, res); + } + return res.status(405).json({ + statusCode: 405, + message: 'Method not allowed', + }); +}; diff --git a/src/pages/api/modules/dashdot/storage.ts b/src/pages/api/modules/dashdot/storage.ts new file mode 100644 index 000000000..a74965900 --- /dev/null +++ b/src/pages/api/modules/dashdot/storage.ts @@ -0,0 +1,42 @@ +import axios from 'axios'; +import { NextApiRequest, NextApiResponse } from 'next'; +import { getConfig } from '../../../../tools/config/getConfig'; + +async function Get(req: NextApiRequest, res: NextApiResponse) { + const { configName } = req.query; + + if (!configName || typeof configName !== 'string') { + return res.status(400).json({ + message: 'Missing required configName in url', + }); + } + + const config = getConfig(configName); + + const dashDotUrl = config.integrations.dashDot?.properties.url; + + if (!dashDotUrl) { + return res.status(400).json({ + message: 'Dashdot url must be defined in config', + }); + } + + // Get the origin URL + const url = dashDotUrl.endsWith('/') + ? dashDotUrl.substring(0, dashDotUrl.length - 1) + : dashDotUrl; + const response = await axios.get(`${url}/load/storage`); + // Return the response + return res.status(200).json(response.data); +} + +export default async (req: NextApiRequest, res: NextApiResponse) => { + // Filter out if the reuqest is a POST or a GET + if (req.method === 'GET') { + return Get(req, res); + } + return res.status(405).json({ + statusCode: 405, + message: 'Method not allowed', + }); +};