diff --git a/public/locales/en/modules/common.json b/public/locales/en/modules/common.json index 3f4b36b03..39adbd37b 100644 --- a/public/locales/en/modules/common.json +++ b/public/locales/en/modules/common.json @@ -1,5 +1,10 @@ { "settings": { "label": "Settings" + }, + "errors": { + "unmappedOptions": { + "text": "Un-used parameter in configuration detected
{{key}}. Homarr is unable to interprete and use this parameter. To avoid any unexpected behavior, back up your configuration and correct your configuration." + } } } \ No newline at end of file diff --git a/public/locales/en/modules/torrents.json b/public/locales/en/modules/torrents-status.json similarity index 76% rename from public/locales/en/modules/torrents.json rename to public/locales/en/modules/torrents-status.json index 0d199a8f7..d3ab4be86 100644 --- a/public/locales/en/modules/torrents.json +++ b/public/locales/en/modules/torrents-status.json @@ -1,10 +1,14 @@ { "descriptor": { - "name": "Torrent", - "description": "Show the current download speed of supported services", + "name": "BitTorrent", + "description": "Displays a list of the torrent which are currently downloading", "settings": { - "hideComplete": { - "label": "Hide completed torrents" + "title": "Settings for BitTorrent integration", + "displayCompletedTorrents": { + "label": "Display completed torrents" + }, + "displayStaleTorrents": { + "label": "Display stale torrents" } } }, diff --git a/src/components/Dashboard/Tiles/Widgets/WidgetsEditModal.tsx b/src/components/Dashboard/Tiles/Widgets/WidgetsEditModal.tsx index 70ef85a66..6872f6966 100644 --- a/src/components/Dashboard/Tiles/Widgets/WidgetsEditModal.tsx +++ b/src/components/Dashboard/Tiles/Widgets/WidgetsEditModal.tsx @@ -1,6 +1,7 @@ -import { Button, Group, MultiSelect, Stack, Switch, TextInput } from '@mantine/core'; +import { Alert, Button, Group, MultiSelect, Stack, Switch, TextInput, Text } from '@mantine/core'; import { ContextModalProps } from '@mantine/modals'; -import { useTranslation } from 'next-i18next'; +import { IconAlertTriangle } from '@tabler/icons'; +import { Trans, useTranslation } from 'next-i18next'; import { useState } from 'react'; import Widgets from '../../../../widgets'; import type { IWidgetOptionValue } from '../../../../widgets/widgets'; @@ -31,6 +32,8 @@ export const WidgetsEditModal = ({ if (!configName || !innerProps.options) return null; + console.log(`loaded namespace modules/${innerProps.widgetId}`); + const handleChange = (key: string, value: IntegrationOptionsValueType) => { setModuleProperties((prev) => { const copyOfPrev: any = { ...prev }; @@ -66,12 +69,28 @@ export const WidgetsEditModal = ({ return ( - {items.map(([key, value]) => { + {items.map(([key, value], index) => { const option = (currentWidgetDefinition as any).options[key] as IWidgetOptionValue; + + if (!option) { + return ( + } color="red"> + + , code: }} + /> + + + ); + } + switch (option.type) { case 'switch': return ( handleChange(key, ev.currentTarget.checked)} @@ -80,6 +99,7 @@ export const WidgetsEditModal = ({ case 'text': return ( handleChange(key, ev.currentTarget.value)} @@ -88,6 +108,7 @@ export const WidgetsEditModal = ({ case 'multi-select': return ( useQuery({ queryKey: ['torrentsData', params.appId], - queryFn: async () => fetchData(), + queryFn: fetchData, refetchOnWindowFocus: true, refetchInterval(_: any, query: Query) { if (query.state.fetchFailureCount < 3) { diff --git a/src/tools/translation-namespaces.ts b/src/tools/translation-namespaces.ts index 293a4ff35..2a8b50170 100644 --- a/src/tools/translation-namespaces.ts +++ b/src/tools/translation-namespaces.ts @@ -23,7 +23,7 @@ export const dashboardNamespaces = [ 'modules/dlspeed', 'modules/usenet', 'modules/search', - 'modules/torrents', + 'modules/torrents-status', 'modules/weather', 'modules/ping', 'modules/docker', diff --git a/src/widgets/WidgetWrapper.tsx b/src/widgets/WidgetWrapper.tsx index 5ccfe2d2b..c321cbc12 100644 --- a/src/widgets/WidgetWrapper.tsx +++ b/src/widgets/WidgetWrapper.tsx @@ -10,11 +10,9 @@ interface WidgetWrapperProps { children: ReactNode; } -export const WidgetWrapper = ({ widgetId, widget, className, children }: WidgetWrapperProps) => { - return ( +export const WidgetWrapper = ({ widgetId, widget, className, children }: WidgetWrapperProps) => ( {children} ); -}; diff --git a/src/widgets/bitTorrent/BitTorrentTile.tsx b/src/widgets/bitTorrent/BitTorrentTile.tsx index e261a2ec2..654ca0020 100644 --- a/src/widgets/bitTorrent/BitTorrentTile.tsx +++ b/src/widgets/bitTorrent/BitTorrentTile.tsx @@ -1,4 +1,4 @@ -import { NormalizedTorrent } from '@ctrl/shared-torrent'; +import { NormalizedTorrent, TorrentState } from '@ctrl/shared-torrent'; import { Center, Group, @@ -52,7 +52,7 @@ interface BitTorrentTileProps { } function BitTorrentTile({ widget }: BitTorrentTileProps) { - const { t } = useTranslation('modules/torrents'); + const { t } = useTranslation('modules/torrents-status'); const MIN_WIDTH_MOBILE = useMantineTheme().breakpoints.xs; const { width } = useElementSize(); @@ -112,6 +112,18 @@ function BitTorrentTile({ widget }: BitTorrentTileProps) { ); } + const filter = (torrent: NormalizedTorrent) => { + if (!widget.properties.displayCompletedTorrents && torrent.isCompleted) { + return false; + } + + if (!widget.properties.displayStaleTorrents && !torrent.isCompleted && torrent.eta <= 0) { + return false; + } + + return true; + }; + return ( @@ -126,7 +138,7 @@ function BitTorrentTile({ widget }: BitTorrentTileProps) { - {data.map((item: NormalizedTorrent, index: number) => ( + {data.filter(filter).map((item: NormalizedTorrent, index: number) => ( ))}