From 6f7692c08663a2684acb9ef10a61ea7bcf0f1a25 Mon Sep 17 00:00:00 2001 From: Manuel <30572287+manuel-rw@users.noreply.github.com> Date: Tue, 28 Feb 2023 20:35:57 +0100 Subject: [PATCH 01/22] =?UTF-8?q?=F0=9F=9A=91=20Fix=20RSS=20widget=20crash?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/api/modules/rss/index.ts | 9 +++++++++ src/widgets/rss/RssWidgetTile.tsx | 20 ++++++++++---------- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/src/pages/api/modules/rss/index.ts b/src/pages/api/modules/rss/index.ts index 0a5623158..0ee993be3 100644 --- a/src/pages/api/modules/rss/index.ts +++ b/src/pages/api/modules/rss/index.ts @@ -53,6 +53,7 @@ export const Get = async (request: NextApiRequest, response: NextApiResponse) => title: item.title ? decode(item.title) : undefined, content: decode(item.content), enclosure: createEnclosure(item), + link: createLink(item), })) .sort((a: { pubDate: number }, b: { pubDate: number }) => { if (!a.pubDate || !b.pubDate) { @@ -70,6 +71,14 @@ export const Get = async (request: NextApiRequest, response: NextApiResponse) => }); }; +const createLink = (item: any) => { + if (item.link) { + return item.link; + } + + return item.guid; +}; + const createEnclosure = (item: any) => { if (item.enclosure) { return item.enclosure; diff --git a/src/widgets/rss/RssWidgetTile.tsx b/src/widgets/rss/RssWidgetTile.tsx index 39b03db68..8877fff80 100644 --- a/src/widgets/rss/RssWidgetTile.tsx +++ b/src/widgets/rss/RssWidgetTile.tsx @@ -16,7 +16,6 @@ import { Title, UnstyledButton, } from '@mantine/core'; -import { useElementSize } from '@mantine/hooks'; import { IconBulldozer, IconCalendarTime, @@ -65,7 +64,6 @@ function RssTile({ widget }: RssTileProps) { ); const { classes } = useStyles(); const [loadingOverlayVisible, setLoadingOverlayVisible] = useState(false); - const { ref, height } = useElementSize(); if (!data || isLoading) { return ( @@ -88,7 +86,7 @@ function RssTile({ widget }: RssTileProps) { } return ( - + {data.feed.image ? ( @@ -121,7 +119,7 @@ function RssTile({ widget }: RssTileProps) { - - - - {data.feed.lastBuildDate} - - + {data.feed.lastBuildDate && ( + + + + {data.feed.lastBuildDate} + + + )} {data.feed.feedUrl && ( From 1dd205c441deba38010257564a2b98a3fc855489 Mon Sep 17 00:00:00 2001 From: ajnart Date: Thu, 2 Mar 2023 19:57:24 +0900 Subject: [PATCH 02/22] =?UTF-8?q?=F0=9F=90=9B=20Fix=20StatusCode=20not=20b?= =?UTF-8?q?eing=20used=20properly?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Dashboard/Tiles/Apps/AppPing.tsx | 4 +--- src/types/app.ts | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/components/Dashboard/Tiles/Apps/AppPing.tsx b/src/components/Dashboard/Tiles/Apps/AppPing.tsx index d94cdc676..0a14bb9f2 100644 --- a/src/components/Dashboard/Tiles/Apps/AppPing.tsx +++ b/src/components/Dashboard/Tiles/Apps/AppPing.tsx @@ -19,7 +19,7 @@ export const AppPing = ({ app }: AppPingProps) => { queryKey: ['ping', { id: app.id, name: app.name }], queryFn: async () => { const response = await fetch(`/api/modules/ping?url=${encodeURI(app.url)}`); - const isOk = app.network.okStatus.includes(response.status); + const isOk = app.network.statusCodes.includes(response.status.toString()); return { status: response.status, state: isOk ? 'online' : 'down', @@ -60,5 +60,3 @@ export const AppPing = ({ app }: AppPingProps) => { ); }; - -type PingState = 'loading' | 'down' | 'online'; diff --git a/src/types/app.ts b/src/types/app.ts index 2e611c031..ca933d2d4 100644 --- a/src/types/app.ts +++ b/src/types/app.ts @@ -23,7 +23,7 @@ interface AppBehaviourType { interface AppNetworkType { enabledStatusChecker: boolean; - okStatus: number[]; + statusCodes: string[]; } interface AppAppearanceType { From 5c183e83f32c14cb3c6c56fd83364377a3d981ca Mon Sep 17 00:00:00 2001 From: ajnart Date: Thu, 2 Mar 2023 20:11:52 +0900 Subject: [PATCH 03/22] =?UTF-8?q?=F0=9F=90=9B=20Fix=20defaultValue=20crash?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Modals/EditAppModal/Tabs/NetworkTab/NetworkTab.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/components/Dashboard/Modals/EditAppModal/Tabs/NetworkTab/NetworkTab.tsx b/src/components/Dashboard/Modals/EditAppModal/Tabs/NetworkTab/NetworkTab.tsx index 6b3cc6a81..2701639fd 100644 --- a/src/components/Dashboard/Modals/EditAppModal/Tabs/NetworkTab/NetworkTab.tsx +++ b/src/components/Dashboard/Modals/EditAppModal/Tabs/NetworkTab/NetworkTab.tsx @@ -10,6 +10,9 @@ interface NetworkTabProps { export const NetworkTab = ({ form }: NetworkTabProps) => { const { t } = useTranslation('layout/modals/add-app'); + const acceptableStatusCodes = (form.values.network.statusCodes ?? ['200']).map((x) => + x.toString() + ); return ( { data={StatusCodes} clearable searchable - defaultValue={form.values.network.okStatus.map((x) => `${x}`)} + defaultValue={acceptableStatusCodes} variant="default" {...form.getInputProps('network.statusCodes')} /> From faf5d11900d76bcfc3de344b3c78bb5b215853f6 Mon Sep 17 00:00:00 2001 From: ajnart Date: Thu, 2 Mar 2023 20:32:41 +0900 Subject: [PATCH 04/22] =?UTF-8?q?=F0=9F=92=9A=20Fix=20build?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Components/Overview/AvailableElementsOverview.tsx | 2 +- src/modules/Docker/ContainerActionBar.tsx | 2 +- src/tools/config/migrateConfig.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/Dashboard/Modals/SelectElement/Components/Overview/AvailableElementsOverview.tsx b/src/components/Dashboard/Modals/SelectElement/Components/Overview/AvailableElementsOverview.tsx index d746ae334..0ec7e091d 100644 --- a/src/components/Dashboard/Modals/SelectElement/Components/Overview/AvailableElementsOverview.tsx +++ b/src/components/Dashboard/Modals/SelectElement/Components/Overview/AvailableElementsOverview.tsx @@ -95,7 +95,7 @@ export const AvailableElementTypes = ({ }, network: { enabledStatusChecker: true, - okStatus: [200], + statusCodes: ['200'], }, behaviour: { isOpeningNewTab: true, diff --git a/src/modules/Docker/ContainerActionBar.tsx b/src/modules/Docker/ContainerActionBar.tsx index 3b8943908..427b877ea 100644 --- a/src/modules/Docker/ContainerActionBar.tsx +++ b/src/modules/Docker/ContainerActionBar.tsx @@ -177,7 +177,7 @@ export default function ContainerActionBar({ selected, reload }: ContainerAction }, network: { enabledStatusChecker: true, - okStatus: [200], + statusCodes: ['200'], }, behaviour: { isOpeningNewTab: true, diff --git a/src/tools/config/migrateConfig.ts b/src/tools/config/migrateConfig.ts index 7e8586524..f83734a57 100644 --- a/src/tools/config/migrateConfig.ts +++ b/src/tools/config/migrateConfig.ts @@ -159,7 +159,7 @@ const migrateService = (oldService: serviceItem, areaType: AreaType): ConfigAppT }, network: { enabledStatusChecker: oldService.ping ?? true, - okStatus: oldService.status?.map((str) => parseInt(str, 10)) ?? [200], + statusCodes: oldService.status ?? ['200'], }, appearance: { iconUrl: migrateIcon(oldService.icon), From c6d8bcd5742d8aaebff1ca6f5059b5d8fc703d59 Mon Sep 17 00:00:00 2001 From: ajnart Date: Fri, 3 Mar 2023 12:38:56 +0900 Subject: [PATCH 05/22] =?UTF-8?q?=F0=9F=92=84=20Icon=20selector=20style=20?= =?UTF-8?q?changes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Modals/EditAppModal/Tabs/AppereanceTab/IconSelector.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/Dashboard/Modals/EditAppModal/Tabs/AppereanceTab/IconSelector.tsx b/src/components/Dashboard/Modals/EditAppModal/Tabs/AppereanceTab/IconSelector.tsx index 0d4fd4249..c9c01035d 100644 --- a/src/components/Dashboard/Modals/EditAppModal/Tabs/AppereanceTab/IconSelector.tsx +++ b/src/components/Dashboard/Modals/EditAppModal/Tabs/AppereanceTab/IconSelector.tsx @@ -90,7 +90,8 @@ export const IconSelector = ({ } variant="default" withAsterisk - dropdownComponent={(props: any) => } + dropdownComponent={(props: any) => } + dropdownPosition="bottom" required onChange={(event) => { if (allowAppNamePropagation) { From 85120e381620570cc4609e647a5019b685aca1df Mon Sep 17 00:00:00 2001 From: ajnart Date: Fri, 3 Mar 2023 12:39:10 +0900 Subject: [PATCH 06/22] =?UTF-8?q?=F0=9F=92=84=20Icon=20selector=20style=20?= =?UTF-8?q?changes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Dashboard/Tiles/GenericTileMenu.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/Dashboard/Tiles/GenericTileMenu.tsx b/src/components/Dashboard/Tiles/GenericTileMenu.tsx index fba87edfa..d414d0613 100644 --- a/src/components/Dashboard/Tiles/GenericTileMenu.tsx +++ b/src/components/Dashboard/Tiles/GenericTileMenu.tsx @@ -24,9 +24,9 @@ export const GenericTileMenu = ({ } return ( - + - + From 68cea4b6a83592aa8bf2dbb76fba841728f0df90 Mon Sep 17 00:00:00 2001 From: ajnart Date: Fri, 3 Mar 2023 12:39:40 +0900 Subject: [PATCH 07/22] =?UTF-8?q?=E2=9A=A1=EF=B8=8F=20=20Icon=20selector?= =?UTF-8?q?=20performance=20changes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added caching for the icons --- src/hooks/icons/useGetDashboardIcons.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/hooks/icons/useGetDashboardIcons.tsx b/src/hooks/icons/useGetDashboardIcons.tsx index 854322693..707461eec 100644 --- a/src/hooks/icons/useGetDashboardIcons.tsx +++ b/src/hooks/icons/useGetDashboardIcons.tsx @@ -10,5 +10,7 @@ export const useGetDashboardIcons = () => return data as NormalizedIconRepositoryResult[]; }, refetchOnMount: false, + // Cache for infinity, refetch every so often. + cacheTime: Infinity, refetchOnWindowFocus: false, }); From 457e9cf2bdb29511e679f4e7c288398770877d8d Mon Sep 17 00:00:00 2001 From: ajnart Date: Fri, 3 Mar 2023 12:40:49 +0900 Subject: [PATCH 08/22] =?UTF-8?q?=F0=9F=8E=A8=20Format=20codebase?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Dashboard/Tiles/Apps/AppTile.tsx | 8 ++- .../Customization/CustomizationSettings.tsx | 4 +- .../Customization/Meta/LogoImageChanger.tsx | 4 +- .../download-speed/useGetNetworkSpeed.tsx | 17 ++--- src/pages/api/icons/index.ts | 24 +++++-- src/pages/api/modules/calendar.ts | 2 +- src/pages/api/modules/downloads/index.ts | 4 +- .../images/jsdelivr-icons-repository.ts | 2 +- src/types/api/media-server/session-info.ts | 62 ++++++++++--------- src/widgets/date/DateTile.tsx | 2 +- src/widgets/iframe/IFrameTile.tsx | 2 +- .../media-server/DetailCollapseable.tsx | 4 +- src/widgets/useNet/UseNetTile.tsx | 2 +- src/widgets/weather/WeatherTile.tsx | 2 +- 14 files changed, 86 insertions(+), 53 deletions(-) diff --git a/src/components/Dashboard/Tiles/Apps/AppTile.tsx b/src/components/Dashboard/Tiles/Apps/AppTile.tsx index 1c9edd328..42dacd806 100644 --- a/src/components/Dashboard/Tiles/Apps/AppTile.tsx +++ b/src/components/Dashboard/Tiles/Apps/AppTile.tsx @@ -36,7 +36,13 @@ export const AppTile = ({ className, app }: AppTileProps) => { className="dashboard-tile-app" > diff --git a/src/components/Settings/Customization/CustomizationSettings.tsx b/src/components/Settings/Customization/CustomizationSettings.tsx index f7dbc327d..30bbe4149 100644 --- a/src/components/Settings/Customization/CustomizationSettings.tsx +++ b/src/components/Settings/Customization/CustomizationSettings.tsx @@ -10,9 +10,7 @@ export default function CustomizationSettings() { return ( - - {t('text')} - + {t('text')} diff --git a/src/components/Settings/Customization/Meta/LogoImageChanger.tsx b/src/components/Settings/Customization/Meta/LogoImageChanger.tsx index 3d5563fe1..18fc8246a 100644 --- a/src/components/Settings/Customization/Meta/LogoImageChanger.tsx +++ b/src/components/Settings/Customization/Meta/LogoImageChanger.tsx @@ -8,7 +8,9 @@ export const LogoImageChanger = () => { const { t } = useTranslation('settings/customization/page-appearance'); const updateConfig = useConfigStore((x) => x.updateConfig); const { config, name: configName } = useConfigContext(); - const [logoImageSrc, setLogoImageSrc] = useState(config?.settings.customization.logoImageUrl ?? '/imgs/logo/logo.png'); + const [logoImageSrc, setLogoImageSrc] = useState( + config?.settings.customization.logoImageUrl ?? '/imgs/logo/logo.png' + ); if (!configName) return null; diff --git a/src/hooks/widgets/download-speed/useGetNetworkSpeed.tsx b/src/hooks/widgets/download-speed/useGetNetworkSpeed.tsx index 965607e1c..2af50a67e 100644 --- a/src/hooks/widgets/download-speed/useGetNetworkSpeed.tsx +++ b/src/hooks/widgets/download-speed/useGetNetworkSpeed.tsx @@ -1,11 +1,12 @@ import { useQuery } from '@tanstack/react-query'; import { NormalizedDownloadQueueResponse } from '../../../types/api/downloads/queue/NormalizedDownloadQueueResponse'; -export const useGetDownloadClientsQueue = () => useQuery({ - queryKey: ['network-speed'], - queryFn: async (): Promise => { - const response = await fetch('/api/modules/downloads'); - return response.json(); - }, - refetchInterval: 3000, -}); +export const useGetDownloadClientsQueue = () => + useQuery({ + queryKey: ['network-speed'], + queryFn: async (): Promise => { + const response = await fetch('/api/modules/downloads'); + return response.json(); + }, + refetchInterval: 3000, + }); diff --git a/src/pages/api/icons/index.ts b/src/pages/api/icons/index.ts index 7b1c6a4f9..9649f9cbe 100644 --- a/src/pages/api/icons/index.ts +++ b/src/pages/api/icons/index.ts @@ -6,10 +6,26 @@ import { UnpkgIconsRepository } from '../../../tools/server/images/unpkg-icons-r const Get = async (request: NextApiRequest, response: NextApiResponse) => { const respositories = [ new LocalIconsRepository(), - new JsdelivrIconsRepository(JsdelivrIconsRepository.tablerRepository, 'Walkxcode Dashboard Icons', 'Walkxcode on Github'), - new UnpkgIconsRepository(UnpkgIconsRepository.tablerRepository, 'Tabler Icons', 'Tabler Icons - GitHub (MIT)'), - new JsdelivrIconsRepository(JsdelivrIconsRepository.papirusRepository, 'Papirus Icons', 'Papirus Development Team on GitHub (Apache 2.0)'), - new JsdelivrIconsRepository(JsdelivrIconsRepository.homelabSvgAssetsRepository, 'Homelab Svg Assets', 'loganmarchione on GitHub (MIT)'), + new JsdelivrIconsRepository( + JsdelivrIconsRepository.tablerRepository, + 'Walkxcode Dashboard Icons', + 'Walkxcode on Github' + ), + new UnpkgIconsRepository( + UnpkgIconsRepository.tablerRepository, + 'Tabler Icons', + 'Tabler Icons - GitHub (MIT)' + ), + new JsdelivrIconsRepository( + JsdelivrIconsRepository.papirusRepository, + 'Papirus Icons', + 'Papirus Development Team on GitHub (Apache 2.0)' + ), + new JsdelivrIconsRepository( + JsdelivrIconsRepository.homelabSvgAssetsRepository, + 'Homelab Svg Assets', + 'loganmarchione on GitHub (MIT)' + ), ]; const fetches = respositories.map((rep) => rep.fetch()); const data = await Promise.all(fetches); diff --git a/src/pages/api/modules/calendar.ts b/src/pages/api/modules/calendar.ts index ab3694eda..275555656 100644 --- a/src/pages/api/modules/calendar.ts +++ b/src/pages/api/modules/calendar.ts @@ -53,7 +53,7 @@ async function Get(req: NextApiRequest, res: NextApiResponse) { ); const IntegrationTypeEndpointMap = new Map([ - ['sonarr', useSonarrv4 ? '/api/v3/calendar' : '/api/calendar'], + ['sonarr', useSonarrv4 ? '/api/v3/calendar' : '/api/calendar'], ['radarr', '/api/v3/calendar'], ['lidarr', '/api/v1/calendar'], ['readarr', '/api/v1/calendar'], diff --git a/src/pages/api/modules/downloads/index.ts b/src/pages/api/modules/downloads/index.ts index d7d5dc086..6d80db458 100644 --- a/src/pages/api/modules/downloads/index.ts +++ b/src/pages/api/modules/downloads/index.ts @@ -61,7 +61,9 @@ const Get = async (request: NextApiRequest, response: NextApiResponse) => { const responseBody = { apps: data, failedApps: failedClients } as NormalizedDownloadQueueResponse; if (failedClients.length > 0) { - Consola.warn(`${failedClients.length} download clients failed. Please check your configuration and the above log`); + Consola.warn( + `${failedClients.length} download clients failed. Please check your configuration and the above log` + ); } return response.status(200).json(responseBody); diff --git a/src/tools/server/images/jsdelivr-icons-repository.ts b/src/tools/server/images/jsdelivr-icons-repository.ts index 734f49853..acce25790 100644 --- a/src/tools/server/images/jsdelivr-icons-repository.ts +++ b/src/tools/server/images/jsdelivr-icons-repository.ts @@ -23,7 +23,7 @@ export class JsdelivrIconsRepository extends AbstractIconRepository { constructor( private readonly repository: JsdelivrRepositoryUrl, private readonly displayName: string, - copyright: string, + copyright: string ) { super(copyright); } diff --git a/src/types/api/media-server/session-info.ts b/src/types/api/media-server/session-info.ts index 5b8c25ab7..d9ee0cece 100644 --- a/src/types/api/media-server/session-info.ts +++ b/src/types/api/media-server/session-info.ts @@ -14,33 +14,39 @@ export type GenericCurrentlyPlaying = { episodeCount: number | undefined; type: 'audio' | 'video' | 'tv' | 'movie' | undefined; metadata: { - video: { - videoCodec: string | undefined; - videoFrameRate: string | undefined; - height: number | undefined; - width: number | undefined; - bitrate: number | undefined; - } | undefined; - audio: { - audioCodec: string | undefined; - audioChannels: number | undefined; - } | undefined; - transcoding: { - context: string | undefined; - sourceVideoCodec: string | undefined; - sourceAudioCodec: string | undefined; - videoDecision: string | undefined; - audioDecision: string | undefined; - container: string | undefined; - videoCodec: string | undefined; - audioCodec: string | undefined; - error: boolean | undefined; - duration: number | undefined; - audioChannels: number | undefined; - width: number | undefined; - height: number | undefined; - transcodeHwRequested: boolean | undefined; - timeStamp: number | undefined; - } | undefined; + video: + | { + videoCodec: string | undefined; + videoFrameRate: string | undefined; + height: number | undefined; + width: number | undefined; + bitrate: number | undefined; + } + | undefined; + audio: + | { + audioCodec: string | undefined; + audioChannels: number | undefined; + } + | undefined; + transcoding: + | { + context: string | undefined; + sourceVideoCodec: string | undefined; + sourceAudioCodec: string | undefined; + videoDecision: string | undefined; + audioDecision: string | undefined; + container: string | undefined; + videoCodec: string | undefined; + audioCodec: string | undefined; + error: boolean | undefined; + duration: number | undefined; + audioChannels: number | undefined; + width: number | undefined; + height: number | undefined; + transcodeHwRequested: boolean | undefined; + timeStamp: number | undefined; + } + | undefined; }; }; diff --git a/src/widgets/date/DateTile.tsx b/src/widgets/date/DateTile.tsx index b9f005873..07c26cb5c 100644 --- a/src/widgets/date/DateTile.tsx +++ b/src/widgets/date/DateTile.tsx @@ -25,7 +25,7 @@ const definition = defineWidget({ component: DateTile, }); -export type IDateWidget = IWidget; +export type IDateWidget = IWidget<(typeof definition)['id'], typeof definition>; interface DateTileProps { widget: IDateWidget; diff --git a/src/widgets/iframe/IFrameTile.tsx b/src/widgets/iframe/IFrameTile.tsx index 44b17d089..8cc2efe1f 100644 --- a/src/widgets/iframe/IFrameTile.tsx +++ b/src/widgets/iframe/IFrameTile.tsx @@ -43,7 +43,7 @@ function IFrameTile({ widget }: IFrameTileProps) { - {t('card.errors.noUrl.title')} + {t('card.errors.noUrl.title')} {t('card.errors.noUrl.text')} diff --git a/src/widgets/media-server/DetailCollapseable.tsx b/src/widgets/media-server/DetailCollapseable.tsx index 536e3d0e7..2517962bf 100644 --- a/src/widgets/media-server/DetailCollapseable.tsx +++ b/src/widgets/media-server/DetailCollapseable.tsx @@ -107,7 +107,9 @@ export const DetailCollapseable = ({ session }: { session: GenericSessionInfo }) {session.sessionName} - {details.length > 0 && } + {details.length > 0 && ( + + )} {details.map((detail, index) => ( diff --git a/src/widgets/useNet/UseNetTile.tsx b/src/widgets/useNet/UseNetTile.tsx index 832b8d2d7..bfe1345cb 100644 --- a/src/widgets/useNet/UseNetTile.tsx +++ b/src/widgets/useNet/UseNetTile.tsx @@ -46,7 +46,7 @@ const definition = defineWidget({ }, }); -export type IUsenetWidget = IWidget; +export type IUsenetWidget = IWidget<(typeof definition)['id'], typeof definition>; interface UseNetTileProps { widget: IUsenetWidget; diff --git a/src/widgets/weather/WeatherTile.tsx b/src/widgets/weather/WeatherTile.tsx index ba7b9eff7..b23731aa1 100644 --- a/src/widgets/weather/WeatherTile.tsx +++ b/src/widgets/weather/WeatherTile.tsx @@ -28,7 +28,7 @@ const definition = defineWidget({ component: WeatherTile, }); -export type IWeatherWidget = IWidget; +export type IWeatherWidget = IWidget<(typeof definition)['id'], typeof definition>; interface WeatherTileProps { widget: IWeatherWidget; From c8ef6bae1ad55eb5fb4c6ded787dc92ba4722a2d Mon Sep 17 00:00:00 2001 From: Manuel <30572287+manuel-rw@users.noreply.github.com> Date: Fri, 3 Mar 2023 20:27:30 +0100 Subject: [PATCH 09/22] =?UTF-8?q?=F0=9F=9A=91=20Fix=20URL=20malformed=20(#?= =?UTF-8?q?743)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 2 +- src/middleware.ts | 6 +-- yarn.lock | 127 ++++++++++++++++++++++++---------------------- 3 files changed, 69 insertions(+), 66 deletions(-) diff --git a/package.json b/package.json index c398dc5cc..b64160f85 100644 --- a/package.json +++ b/package.json @@ -53,7 +53,7 @@ "html-entities": "^2.3.3", "i18next": "^21.9.1", "js-file-download": "^0.4.12", - "next": "^13.1.6", + "next": "^13.2.1", "next-i18next": "^11.3.0", "nzbget-api": "^0.0.3", "prismjs": "^1.29.0", diff --git a/src/middleware.ts b/src/middleware.ts index 79f85b693..6652e8d41 100644 --- a/src/middleware.ts +++ b/src/middleware.ts @@ -1,8 +1,8 @@ -import { NextFetchEvent, NextRequest, NextResponse } from 'next/server'; +import { NextRequest, NextResponse } from 'next/server'; -// eslint-disable-next-line consistent-return -export function middleware(req: NextRequest, ev: NextFetchEvent) { +export function middleware(req: NextRequest) { const { cookies } = req; + // Don't even bother with the middleware if there is no defined password if (!process.env.PASSWORD) return NextResponse.next(); diff --git a/yarn.lock b/yarn.lock index 2d3338ba5..aa12f8a2d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1272,10 +1272,10 @@ __metadata: languageName: node linkType: hard -"@next/env@npm:13.1.6": - version: 13.1.6 - resolution: "@next/env@npm:13.1.6" - checksum: 0f911a18f0b3372007632fffa87f5d7f802c00d07b3bf757d2d09574735ae43f60000ecdf64b6f06e195971c508c2bcee82dd1e3aab27a08a4300eb0317652bb +"@next/env@npm:13.2.1": + version: 13.2.1 + resolution: "@next/env@npm:13.2.1" + checksum: 16a877479348b9d6a9e69e74312546889d6419a6dec0556cf7d9ed5876b4f69a0974c804f2c5ec81526522c243d97bd2d6919d3241cd165e10e8fd6c3bb4b975 languageName: node linkType: hard @@ -1288,93 +1288,93 @@ __metadata: languageName: node linkType: hard -"@next/swc-android-arm-eabi@npm:13.1.6": - version: 13.1.6 - resolution: "@next/swc-android-arm-eabi@npm:13.1.6" +"@next/swc-android-arm-eabi@npm:13.2.1": + version: 13.2.1 + resolution: "@next/swc-android-arm-eabi@npm:13.2.1" conditions: os=android & cpu=arm languageName: node linkType: hard -"@next/swc-android-arm64@npm:13.1.6": - version: 13.1.6 - resolution: "@next/swc-android-arm64@npm:13.1.6" +"@next/swc-android-arm64@npm:13.2.1": + version: 13.2.1 + resolution: "@next/swc-android-arm64@npm:13.2.1" conditions: os=android & cpu=arm64 languageName: node linkType: hard -"@next/swc-darwin-arm64@npm:13.1.6": - version: 13.1.6 - resolution: "@next/swc-darwin-arm64@npm:13.1.6" +"@next/swc-darwin-arm64@npm:13.2.1": + version: 13.2.1 + resolution: "@next/swc-darwin-arm64@npm:13.2.1" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@next/swc-darwin-x64@npm:13.1.6": - version: 13.1.6 - resolution: "@next/swc-darwin-x64@npm:13.1.6" +"@next/swc-darwin-x64@npm:13.2.1": + version: 13.2.1 + resolution: "@next/swc-darwin-x64@npm:13.2.1" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@next/swc-freebsd-x64@npm:13.1.6": - version: 13.1.6 - resolution: "@next/swc-freebsd-x64@npm:13.1.6" +"@next/swc-freebsd-x64@npm:13.2.1": + version: 13.2.1 + resolution: "@next/swc-freebsd-x64@npm:13.2.1" conditions: os=freebsd & cpu=x64 languageName: node linkType: hard -"@next/swc-linux-arm-gnueabihf@npm:13.1.6": - version: 13.1.6 - resolution: "@next/swc-linux-arm-gnueabihf@npm:13.1.6" +"@next/swc-linux-arm-gnueabihf@npm:13.2.1": + version: 13.2.1 + resolution: "@next/swc-linux-arm-gnueabihf@npm:13.2.1" conditions: os=linux & cpu=arm languageName: node linkType: hard -"@next/swc-linux-arm64-gnu@npm:13.1.6": - version: 13.1.6 - resolution: "@next/swc-linux-arm64-gnu@npm:13.1.6" +"@next/swc-linux-arm64-gnu@npm:13.2.1": + version: 13.2.1 + resolution: "@next/swc-linux-arm64-gnu@npm:13.2.1" conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard -"@next/swc-linux-arm64-musl@npm:13.1.6": - version: 13.1.6 - resolution: "@next/swc-linux-arm64-musl@npm:13.1.6" +"@next/swc-linux-arm64-musl@npm:13.2.1": + version: 13.2.1 + resolution: "@next/swc-linux-arm64-musl@npm:13.2.1" conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard -"@next/swc-linux-x64-gnu@npm:13.1.6": - version: 13.1.6 - resolution: "@next/swc-linux-x64-gnu@npm:13.1.6" +"@next/swc-linux-x64-gnu@npm:13.2.1": + version: 13.2.1 + resolution: "@next/swc-linux-x64-gnu@npm:13.2.1" conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard -"@next/swc-linux-x64-musl@npm:13.1.6": - version: 13.1.6 - resolution: "@next/swc-linux-x64-musl@npm:13.1.6" +"@next/swc-linux-x64-musl@npm:13.2.1": + version: 13.2.1 + resolution: "@next/swc-linux-x64-musl@npm:13.2.1" conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard -"@next/swc-win32-arm64-msvc@npm:13.1.6": - version: 13.1.6 - resolution: "@next/swc-win32-arm64-msvc@npm:13.1.6" +"@next/swc-win32-arm64-msvc@npm:13.2.1": + version: 13.2.1 + resolution: "@next/swc-win32-arm64-msvc@npm:13.2.1" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@next/swc-win32-ia32-msvc@npm:13.1.6": - version: 13.1.6 - resolution: "@next/swc-win32-ia32-msvc@npm:13.1.6" +"@next/swc-win32-ia32-msvc@npm:13.2.1": + version: 13.2.1 + resolution: "@next/swc-win32-ia32-msvc@npm:13.2.1" conditions: os=win32 & cpu=ia32 languageName: node linkType: hard -"@next/swc-win32-x64-msvc@npm:13.1.6": - version: 13.1.6 - resolution: "@next/swc-win32-x64-msvc@npm:13.1.6" +"@next/swc-win32-x64-msvc@npm:13.2.1": + version: 13.2.1 + resolution: "@next/swc-win32-x64-msvc@npm:13.2.1" conditions: os=win32 & cpu=x64 languageName: node linkType: hard @@ -4990,7 +4990,7 @@ __metadata: i18next: ^21.9.1 jest: ^28.1.3 js-file-download: ^0.4.12 - next: ^13.1.6 + next: ^13.2.1 next-i18next: ^11.3.0 nzbget-api: ^0.0.3 prettier: ^2.7.1 @@ -6697,29 +6697,30 @@ __metadata: languageName: node linkType: hard -"next@npm:^13.1.6": - version: 13.1.6 - resolution: "next@npm:13.1.6" +"next@npm:^13.2.1": + version: 13.2.1 + resolution: "next@npm:13.2.1" dependencies: - "@next/env": 13.1.6 - "@next/swc-android-arm-eabi": 13.1.6 - "@next/swc-android-arm64": 13.1.6 - "@next/swc-darwin-arm64": 13.1.6 - "@next/swc-darwin-x64": 13.1.6 - "@next/swc-freebsd-x64": 13.1.6 - "@next/swc-linux-arm-gnueabihf": 13.1.6 - "@next/swc-linux-arm64-gnu": 13.1.6 - "@next/swc-linux-arm64-musl": 13.1.6 - "@next/swc-linux-x64-gnu": 13.1.6 - "@next/swc-linux-x64-musl": 13.1.6 - "@next/swc-win32-arm64-msvc": 13.1.6 - "@next/swc-win32-ia32-msvc": 13.1.6 - "@next/swc-win32-x64-msvc": 13.1.6 + "@next/env": 13.2.1 + "@next/swc-android-arm-eabi": 13.2.1 + "@next/swc-android-arm64": 13.2.1 + "@next/swc-darwin-arm64": 13.2.1 + "@next/swc-darwin-x64": 13.2.1 + "@next/swc-freebsd-x64": 13.2.1 + "@next/swc-linux-arm-gnueabihf": 13.2.1 + "@next/swc-linux-arm64-gnu": 13.2.1 + "@next/swc-linux-arm64-musl": 13.2.1 + "@next/swc-linux-x64-gnu": 13.2.1 + "@next/swc-linux-x64-musl": 13.2.1 + "@next/swc-win32-arm64-msvc": 13.2.1 + "@next/swc-win32-ia32-msvc": 13.2.1 + "@next/swc-win32-x64-msvc": 13.2.1 "@swc/helpers": 0.4.14 caniuse-lite: ^1.0.30001406 postcss: 8.4.14 styled-jsx: 5.1.1 peerDependencies: + "@opentelemetry/api": ^1.4.0 fibers: ">= 3.1.0" node-sass: ^6.0.0 || ^7.0.0 react: ^18.2.0 @@ -6753,6 +6754,8 @@ __metadata: "@next/swc-win32-x64-msvc": optional: true peerDependenciesMeta: + "@opentelemetry/api": + optional: true fibers: optional: true node-sass: @@ -6761,7 +6764,7 @@ __metadata: optional: true bin: next: dist/bin/next - checksum: 584977e382bd826c21e7fc5f67bca50e4d95741a854b1686394d45331404479c7266569671227421975fc18e5cf70769a4ad7edede7450d4497213205bba77c8 + checksum: 2dba145ef4d604cd8eadc27f9e5a537df799614d1a801b9161a997f77a432684871eae51642580972a80ef363d724789677ae7c5fe44dc3dd66e71cd43f609c8 languageName: node linkType: hard From c6fa03ba8cb6462a3fe669f690cb0eee4dc5ae9d Mon Sep 17 00:00:00 2001 From: Manuel <30572287+manuel-rw@users.noreply.github.com> Date: Mon, 6 Mar 2023 11:05:27 +0100 Subject: [PATCH 10/22] Update bug.yml --- .github/ISSUE_TEMPLATE/bug.yml | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug.yml index 55879bb7a..2e8c262ca 100644 --- a/.github/ISSUE_TEMPLATE/bug.yml +++ b/.github/ISSUE_TEMPLATE/bug.yml @@ -32,8 +32,15 @@ body: - type: textarea id: logs attributes: - label: Additional info - description: Logs? Screenshots? More info? + label: Logs + description: Provide your Homarr logs so we can investigate what's going on + validations: + required: true + - type: textarea + id: context + attributes: + label: Context + description: Screenshots? More info? validations: required: false - type: checkboxes @@ -42,9 +49,11 @@ body: label: Please tick the boxes description: Before submitting, please ensure that options: - - label: You've read the [docs](https://github.com/ajnart/homarr#readme) + - label: I confirm that I attached the proper logs required: true - - label: You've checked for [duplicate issues](https://github.com/ajnart/homarr/issues) + - label: I've read the [docs](https://github.com/ajnart/homarr#readme) required: true - - label: You've tried to debug yourself + - label: I've checked for [duplicate issues](https://github.com/ajnart/homarr/issues) + required: true + - label: I've tried to debug myself required: true From 13999e44eb08c1454964f0d7befacfd965f3f8d4 Mon Sep 17 00:00:00 2001 From: Manuel <30572287+manuel-rw@users.noreply.github.com> Date: Tue, 7 Mar 2023 19:52:56 +0100 Subject: [PATCH 11/22] =?UTF-8?q?=F0=9F=92=84=20Add=20conditional=20render?= =?UTF-8?q?ing=20for=20image?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/widgets/rss/RssWidgetTile.tsx | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/widgets/rss/RssWidgetTile.tsx b/src/widgets/rss/RssWidgetTile.tsx index 39b03db68..dd3bf80f9 100644 --- a/src/widgets/rss/RssWidgetTile.tsx +++ b/src/widgets/rss/RssWidgetTile.tsx @@ -137,15 +137,17 @@ function RssTile({ widget }: RssTileProps) { )} - - - + {item.enclosure && ( + + + + )} {item.categories && ( From 47cb9cd5b62361eb1231d36c55a72d73d23d3e03 Mon Sep 17 00:00:00 2001 From: Manuel <30572287+manuel-rw@users.noreply.github.com> Date: Tue, 7 Mar 2023 20:09:51 +0100 Subject: [PATCH 12/22] =?UTF-8?q?=F0=9F=92=84=20Fix=20overflow=20of=20item?= =?UTF-8?q?s=20in=20RSS=20widget?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/widgets/rss/RssWidgetTile.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/widgets/rss/RssWidgetTile.tsx b/src/widgets/rss/RssWidgetTile.tsx index dd3bf80f9..c441fa48f 100644 --- a/src/widgets/rss/RssWidgetTile.tsx +++ b/src/widgets/rss/RssWidgetTile.tsx @@ -148,7 +148,7 @@ function RssTile({ widget }: RssTileProps) { /> )} - + {item.categories && ( {item.categories.map((category: any, categoryIndex: number) => ( From 04a304dcd68285f71f3d1858107ffaedf6c6b5ba Mon Sep 17 00:00:00 2001 From: Thomas Camlong <49837342+ajnart@users.noreply.github.com> Date: Sat, 18 Mar 2023 18:19:28 +0800 Subject: [PATCH 13/22] Turbo cache (#767) * Try to add vercel caching with turbo * Update lockfile * Update turbo json file * Fix CI * Add new rule * re-launch ci * Update CI to use Turbo * Use yarn turbo build --- .github/workflows/docker_dev.yml | 7 ++-- .gitignore | 1 + package.json | 3 +- turbo.json | 11 ++++++ yarn.lock | 58 ++++++++++++++++---------------- 5 files changed, 48 insertions(+), 32 deletions(-) create mode 100644 turbo.json diff --git a/.github/workflows/docker_dev.yml b/.github/workflows/docker_dev.yml index db5961ed4..d65cbea87 100644 --- a/.github/workflows/docker_dev.yml +++ b/.github/workflows/docker_dev.yml @@ -24,11 +24,14 @@ env: REGISTRY: ghcr.io # github.repository as / IMAGE_NAME: ${{ github.repository }} + TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }} + TURBO_TEAM: ${{ secrets.TURBO_TEAM }} + jobs: # Push image to GitHub Packages. # See also https://docs.docker.com/docker-hub/builds/ - yarn_install_and_build: + yarn_install_and_build_dev: runs-on: ubuntu-latest permissions: packages: write @@ -67,7 +70,7 @@ jobs: - run: yarn install --immutable - - run: yarn build + - run: yarn turbo build - name: Docker meta if: github.event_name != 'pull_request' diff --git a/.gitignore b/.gitignore index 92b9ea013..1731b2f41 100644 --- a/.gitignore +++ b/.gitignore @@ -32,6 +32,7 @@ yarn-error.log* # vercel .vercel +.turbo *.tsbuildinfo # storybook diff --git a/package.json b/package.json index b64160f85..6d904f4b1 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "scripts": { "dev": "next dev", "build": "next build", + "turbo" : "turbo run build", "analyze": "ANALYZE=true next build", "start": "next start", "typecheck": "tsc --noEmit", @@ -92,7 +93,7 @@ "jest": "^28.1.3", "prettier": "^2.7.1", "sass": "^1.56.1", - "turbo": "^1.7.4", + "turbo": "^1.8.3", "typescript": "^4.7.4", "video.js": "^8.0.3" }, diff --git a/turbo.json b/turbo.json new file mode 100644 index 000000000..833e96950 --- /dev/null +++ b/turbo.json @@ -0,0 +1,11 @@ +{ + "$schema": "https://turbo.build/schema.json", + "pipeline": { + "build": { + "outputs": [ + ".next/**", + "!.next/cache/**" + ] + } + } +} \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index aa12f8a2d..1b4d1f91d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5001,7 +5001,7 @@ __metadata: rss-parser: ^3.12.0 sabnzbd-api: ^1.5.0 sass: ^1.56.1 - turbo: ^1.7.4 + turbo: ^1.8.3 typescript: ^4.7.4 uuid: ^8.3.2 video.js: ^8.0.3 @@ -8366,58 +8366,58 @@ __metadata: languageName: node linkType: hard -"turbo-darwin-64@npm:1.8.0": - version: 1.8.0 - resolution: "turbo-darwin-64@npm:1.8.0" +"turbo-darwin-64@npm:1.8.3": + version: 1.8.3 + resolution: "turbo-darwin-64@npm:1.8.3" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"turbo-darwin-arm64@npm:1.8.0": - version: 1.8.0 - resolution: "turbo-darwin-arm64@npm:1.8.0" +"turbo-darwin-arm64@npm:1.8.3": + version: 1.8.3 + resolution: "turbo-darwin-arm64@npm:1.8.3" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"turbo-linux-64@npm:1.8.0": - version: 1.8.0 - resolution: "turbo-linux-64@npm:1.8.0" +"turbo-linux-64@npm:1.8.3": + version: 1.8.3 + resolution: "turbo-linux-64@npm:1.8.3" conditions: os=linux & cpu=x64 languageName: node linkType: hard -"turbo-linux-arm64@npm:1.8.0": - version: 1.8.0 - resolution: "turbo-linux-arm64@npm:1.8.0" +"turbo-linux-arm64@npm:1.8.3": + version: 1.8.3 + resolution: "turbo-linux-arm64@npm:1.8.3" conditions: os=linux & cpu=arm64 languageName: node linkType: hard -"turbo-windows-64@npm:1.8.0": - version: 1.8.0 - resolution: "turbo-windows-64@npm:1.8.0" +"turbo-windows-64@npm:1.8.3": + version: 1.8.3 + resolution: "turbo-windows-64@npm:1.8.3" conditions: os=win32 & cpu=x64 languageName: node linkType: hard -"turbo-windows-arm64@npm:1.8.0": - version: 1.8.0 - resolution: "turbo-windows-arm64@npm:1.8.0" +"turbo-windows-arm64@npm:1.8.3": + version: 1.8.3 + resolution: "turbo-windows-arm64@npm:1.8.3" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"turbo@npm:^1.7.4": - version: 1.8.0 - resolution: "turbo@npm:1.8.0" +"turbo@npm:^1.8.3": + version: 1.8.3 + resolution: "turbo@npm:1.8.3" dependencies: - turbo-darwin-64: 1.8.0 - turbo-darwin-arm64: 1.8.0 - turbo-linux-64: 1.8.0 - turbo-linux-arm64: 1.8.0 - turbo-windows-64: 1.8.0 - turbo-windows-arm64: 1.8.0 + turbo-darwin-64: 1.8.3 + turbo-darwin-arm64: 1.8.3 + turbo-linux-64: 1.8.3 + turbo-linux-arm64: 1.8.3 + turbo-windows-64: 1.8.3 + turbo-windows-arm64: 1.8.3 dependenciesMeta: turbo-darwin-64: optional: true @@ -8433,7 +8433,7 @@ __metadata: optional: true bin: turbo: bin/turbo - checksum: 7f97068d7f9a155e088d3575b1f9922e68fa3015aae0c92625238d44b4e6c275bec2a281907702dedb402fca29a6cd4690499e916cb334d7c24c98099bc3d8b0 + checksum: 4a07d120ef8adf6c8e58a48abd02e075ffa215287cc6c3ef843d4fb08aeb0a566fe810ec9bfc376254468a2aa4f29bae154a60804a83af78dfa86d0e8e995476 languageName: node linkType: hard From b3aae68469bc633b4571cf15a079a3f6c62828dd Mon Sep 17 00:00:00 2001 From: ajnart Date: Sat, 18 Mar 2023 19:09:21 +0800 Subject: [PATCH 14/22] =?UTF-8?q?=E2=9C=A8=20Make=20integrations=20fields?= =?UTF-8?q?=20required?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Minor integration styling, bigger tooltips, longer texts, removed clear secret button --- .../InputElements/GenericSecretInput.tsx | 44 +++++++------------ 1 file changed, 17 insertions(+), 27 deletions(-) diff --git a/src/components/Dashboard/Modals/EditAppModal/Tabs/IntegrationTab/Components/InputElements/GenericSecretInput.tsx b/src/components/Dashboard/Modals/EditAppModal/Tabs/IntegrationTab/Components/InputElements/GenericSecretInput.tsx index 895dbf015..b65b0f5b7 100644 --- a/src/components/Dashboard/Modals/EditAppModal/Tabs/IntegrationTab/Components/InputElements/GenericSecretInput.tsx +++ b/src/components/Dashboard/Modals/EditAppModal/Tabs/IntegrationTab/Components/InputElements/GenericSecretInput.tsx @@ -6,7 +6,6 @@ import { Grid, Group, PasswordInput, - Stack, ThemeIcon, Title, Text, @@ -40,7 +39,7 @@ export const GenericSecretInput = ({ const Icon = setIcon; - const [displayUpdateField, setDisplayUpdateField] = useState(false); + const [displayUpdateField, setDisplayUpdateField] = useState(!secretIsPresent); const { t } = useTranslation(['layout/modals/add-app', 'common']); return ( @@ -51,26 +50,26 @@ export const GenericSecretInput = ({ - + {t(label)} - {secretIsPresent ? ( - - {t('integration.type.defined')} - - ) : ( - - {t('integration.type.undefined')} - - )} + + {secretIsPresent + ? t('integration.type.defined') + : t('integration.type.undefined')} + {type === 'private' ? ( - + {type === 'private' ? 'Private: Once saved, you cannot read out this value again' : 'Public: Can be read out repeatedly'} - + - {displayUpdateField === true ? ( Date: Sat, 18 Mar 2023 12:28:11 +0100 Subject: [PATCH 15/22] =?UTF-8?q?=E2=9C=A8=20Add=20beforeunload=20hook=20(?= =?UTF-8?q?#762)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Actions/ToggleEditMode/ToggleEditMode.tsx | 22 ++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/src/components/layout/header/Actions/ToggleEditMode/ToggleEditMode.tsx b/src/components/layout/header/Actions/ToggleEditMode/ToggleEditMode.tsx index 794d992be..365431379 100644 --- a/src/components/layout/header/Actions/ToggleEditMode/ToggleEditMode.tsx +++ b/src/components/layout/header/Actions/ToggleEditMode/ToggleEditMode.tsx @@ -1,18 +1,20 @@ +import { ActionIcon, Button, Group, Text, Title, Tooltip } from '@mantine/core'; +import { useHotkeys, useWindowEvent } from '@mantine/hooks'; +import { hideNotification, showNotification } from '@mantine/notifications'; +import { IconEditCircle, IconEditCircleOff } from '@tabler/icons'; import axios from 'axios'; import Consola from 'consola'; -import { ActionIcon, Button, Group, Text, Title, Tooltip } from '@mantine/core'; -import { IconEditCircle, IconEditCircleOff } from '@tabler/icons'; import { getCookie } from 'cookies-next'; import { Trans, useTranslation } from 'next-i18next'; -import { useHotkeys } from '@mantine/hooks'; -import { hideNotification, showNotification } from '@mantine/notifications'; import { useConfigContext } from '../../../../../config/provider'; import { useScreenSmallerThan } from '../../../../../hooks/useScreenSmallerThan'; import { useEditModeStore } from '../../../../Dashboard/Views/useEditModeStore'; -import { AddElementAction } from '../AddElementAction/AddElementAction'; import { useNamedWrapperColumnCount } from '../../../../Dashboard/Wrappers/gridstack/store'; import { useCardStyles } from '../../../useCardStyles'; +import { AddElementAction } from '../AddElementAction/AddElementAction'; + +const beforeUnloadEventText = 'Exit the edit mode to save your changes'; export const ToggleEditModeAction = () => { const { enabled, toggleEditMode } = useEditModeStore(); @@ -29,6 +31,16 @@ export const ToggleEditModeAction = () => { useHotkeys([['ctrl+E', toggleEditMode]]); + useWindowEvent('beforeunload', (event: BeforeUnloadEvent) => { + if (enabled) { + // eslint-disable-next-line no-param-reassign + event.returnValue = beforeUnloadEventText; + return beforeUnloadEventText; + } + + return undefined; + }); + const toggleButtonClicked = () => { toggleEditMode(); if (enabled || config === undefined || config?.schemaVersion === undefined) { From 4c28a77e00f7f3ef70c6ea1228f5b700723ea5b8 Mon Sep 17 00:00:00 2001 From: Manuel <30572287+manuel-rw@users.noreply.github.com> Date: Sat, 18 Mar 2023 12:29:10 +0100 Subject: [PATCH 16/22] =?UTF-8?q?=E2=9C=A8=20Add=20widget=20error=20bounda?= =?UTF-8?q?ry=20(#753)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/locales/en/widgets/error-boundary.json | 14 ++ src/tools/server/translation-namespaces.ts | 1 + src/widgets/WidgetWrapper.tsx | 11 +- src/widgets/boundary.tsx | 127 ++++++++++++++++++ 4 files changed, 149 insertions(+), 4 deletions(-) create mode 100644 public/locales/en/widgets/error-boundary.json create mode 100644 src/widgets/boundary.tsx diff --git a/public/locales/en/widgets/error-boundary.json b/public/locales/en/widgets/error-boundary.json new file mode 100644 index 000000000..9b75f4080 --- /dev/null +++ b/public/locales/en/widgets/error-boundary.json @@ -0,0 +1,14 @@ +{ + "card": { + "title": "Oops, there was an error!", + "buttons": { + "details": "Details", + "tryAgain": "Try again" + } + }, + "modal": { + "text": "We're sorry for the inconvinience! This shouln't happen - please report this issue on GitHub.", + "label": "Your error", + "reportButton": "Report this error" + } +} \ No newline at end of file diff --git a/src/tools/server/translation-namespaces.ts b/src/tools/server/translation-namespaces.ts index 5fe821c3f..90aedada9 100644 --- a/src/tools/server/translation-namespaces.ts +++ b/src/tools/server/translation-namespaces.ts @@ -36,6 +36,7 @@ export const dashboardNamespaces = [ 'modules/media-server', 'modules/common-media-cards', 'modules/video-stream', + 'widgets/error-boundary', ]; export const loginNamespaces = ['authentication/login']; diff --git a/src/widgets/WidgetWrapper.tsx b/src/widgets/WidgetWrapper.tsx index bb7323073..457890537 100644 --- a/src/widgets/WidgetWrapper.tsx +++ b/src/widgets/WidgetWrapper.tsx @@ -2,6 +2,7 @@ import { ComponentType, useMemo } from 'react'; import Widgets from '.'; import { HomarrCardWrapper } from '../components/Dashboard/Tiles/HomarrCardWrapper'; import { WidgetsMenu } from '../components/Dashboard/Tiles/Widgets/WidgetsMenu'; +import ErrorBoundary from './boundary'; import { IWidget } from './widgets'; interface WidgetWrapperProps { @@ -40,9 +41,11 @@ export const WidgetWrapper = ({ const widgetWithDefaultProps = useWidget(widget); return ( - - - - + + + + + + ); }; diff --git a/src/widgets/boundary.tsx b/src/widgets/boundary.tsx new file mode 100644 index 000000000..21530f9f3 --- /dev/null +++ b/src/widgets/boundary.tsx @@ -0,0 +1,127 @@ +import Consola from 'consola'; +import React, { ReactNode } from 'react'; +import { openModal } from '@mantine/modals'; +import { withTranslation } from 'next-i18next'; +import { Button, Card, Center, Code, Group, Stack, Text, Title } from '@mantine/core'; +import { IconBrandGithub, IconBug, IconInfoCircle, IconRefresh } from '@tabler/icons'; + +type ErrorBoundaryState = { + hasError: boolean; + error: Error | undefined; +}; + +type ErrorBoundaryProps = { + t: (key: string) => string; + children: ReactNode; +}; + +/** + * A custom error boundary, that catches errors within widgets and renders an error component. + * The error component can be refreshed and shows a modal with error details + */ +class ErrorBoundary extends React.Component { + constructor(props: any) { + super(props); + + // Define a state variable to track whether is an error or not + this.state = { hasError: false, error: undefined }; + } + + static getDerivedStateFromError(error: Error) { + // Update state so the next render will show the fallback UI + return { hasError: true, error }; + } + + componentDidCatch(error: Error, errorInfo: any) { + Consola.error(`Error while rendering widget, ${error}: ${errorInfo}`); + } + + render() { + // Check if the error is thrown + if (this.state.hasError) { + return ( + ({ + backgroundColor: theme.colors.red[5], + })} + radius="lg" + shadow="sm" + withBorder + > +
+ + + + + {this.props.t('card.title')} + + {this.state.error && ( + + {this.state.error.toString()} + + )} + + + + + ), + }) + } + leftIcon={} + variant="light" + > + {this.props.t('card.buttons.details')} + + + + +
+
+ ); + } + + // Return children components in case of no error + return this.props.children; + } +} + +export default withTranslation('widgets/error-boundary')(ErrorBoundary); From 63f82971c8f725e2f497640eaead6e07b95e4954 Mon Sep 17 00:00:00 2001 From: Manuel <30572287+manuel-rw@users.noreply.github.com> Date: Sat, 18 Mar 2023 12:29:39 +0100 Subject: [PATCH 17/22] =?UTF-8?q?=E2=9C=A8=20Environment=20variable=20for?= =?UTF-8?q?=20default=20color=20scheme=20#237=20(#744)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/_app.tsx | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx index e55dd6bef..b8178c006 100644 --- a/src/pages/_app.tsx +++ b/src/pages/_app.tsx @@ -38,6 +38,7 @@ function App( colorScheme: ColorScheme; packageAttributes: ServerSidePackageAttributesType; editModeEnabled: boolean; + defaultColorScheme: ColorScheme; } ) { const { Component, pageProps } = props; @@ -55,7 +56,7 @@ function App( // hook will return either 'dark' or 'light' on client // and always 'light' during ssr as window.matchMedia is not available - const preferredColorScheme = useColorScheme(); + const preferredColorScheme = useColorScheme(props.defaultColorScheme); const [colorScheme, setColorScheme] = useLocalStorage({ key: 'mantine-color-scheme', defaultValue: preferredColorScheme, @@ -144,10 +145,18 @@ App.getInitialProps = ({ ctx }: { ctx: GetServerSidePropsContext }) => { 'EXPERIMENTAL: You have disabled the edit mode. Modifications are no longer possible and any requests on the API will be dropped. If you want to disable this, unset the DISABLE_EDIT_MODE environment variable. This behaviour may be removed in future versions of Homarr' ); } + + if (process.env.DEFAULT_COLOR_SCHEME !== undefined) { + Consola.debug(`Overriding the default color scheme with ${process.env.DEFAULT_COLOR_SCHEME}`); + } + + const colorScheme: ColorScheme = process.env.DEFAULT_COLOR_SCHEME as ColorScheme ?? 'light'; + return { colorScheme: getCookie('color-scheme', ctx) || 'light', packageAttributes: getServiceSidePackageAttributes(), editModeEnabled: !disableEditMode, + defaultColorScheme: colorScheme, }; }; From 9aebcf0c698c12756c3d6b08fa1c097db97b62a3 Mon Sep 17 00:00:00 2001 From: ajnart Date: Mon, 20 Mar 2023 10:54:46 +0800 Subject: [PATCH 18/22] =?UTF-8?q?=E2=9C=A8=20Add=20a=20simple=20keybind=20?= =?UTF-8?q?viewer=20in=20about=20menu=20#751?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Modals/AboutModal/AboutModal.tsx | 39 +++++++++++++++++-- .../Actions/ToggleEditMode/ToggleEditMode.tsx | 2 +- 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/src/components/Dashboard/Modals/AboutModal/AboutModal.tsx b/src/components/Dashboard/Modals/AboutModal/AboutModal.tsx index 8f366fd9f..952018c0f 100644 --- a/src/components/Dashboard/Modals/AboutModal/AboutModal.tsx +++ b/src/components/Dashboard/Modals/AboutModal/AboutModal.tsx @@ -1,13 +1,14 @@ import { + Accordion, ActionIcon, Anchor, Badge, Button, createStyles, - Divider, Grid, Group, HoverCard, + Kbd, Modal, Stack, Table, @@ -35,6 +36,7 @@ import { useConfigContext } from '../../../../config/provider'; import { useConfigStore } from '../../../../config/store'; import { useEditModeInformationStore } from '../../../../hooks/useEditModeInformation'; import { usePackageAttributesStore } from '../../../../tools/client/zustands/usePackageAttributesStore'; +import Tip from '../../../layout/Tip'; import { usePrimaryGradient } from '../../../layout/useGradient'; import Credits from '../../../Settings/Common/Credits'; @@ -50,6 +52,21 @@ export const AboutModal = ({ opened, closeModal, newVersionAvailable }: AboutMod const informations = useInformationTableItems(newVersionAvailable); const { t } = useTranslation(['common', 'layout/modals/about']); + const keybinds = [ + { key: 'Mod + J', shortcut: 'Toggle light/dark mode' }, + { key: 'Mod + K', shortcut: 'Focus on search bar' }, + { key: 'Mod + B', shortcut: 'Open docker widget' }, + { key: 'Mod + E', shortcut: 'Toggle Edit mode' }, + ]; + const rows = keybinds.map((element) => ( + + + {element.key} + + {element.shortcut} + + )); + return ( closeModal()} @@ -76,7 +93,7 @@ export const AboutModal = ({ opened, closeModal, newVersionAvailable }: AboutMod
- +
{informations.map((item, index) => ( @@ -100,8 +117,24 @@ export const AboutModal = ({ opened, closeModal, newVersionAvailable }: AboutMod ))}
+ + + }>Keybinds + + + + + + + + + {rows} +
KeyShortcut
+ Mod refers to your modifier key, it is Ctrl and Command/Super/Windows key +
+
+
- {t('layout/modals/about:contact')} diff --git a/src/components/layout/header/Actions/ToggleEditMode/ToggleEditMode.tsx b/src/components/layout/header/Actions/ToggleEditMode/ToggleEditMode.tsx index 365431379..c1f4445ff 100644 --- a/src/components/layout/header/Actions/ToggleEditMode/ToggleEditMode.tsx +++ b/src/components/layout/header/Actions/ToggleEditMode/ToggleEditMode.tsx @@ -29,7 +29,7 @@ export const ToggleEditModeAction = () => { const { config } = useConfigContext(); const { classes } = useCardStyles(true); - useHotkeys([['ctrl+E', toggleEditMode]]); + useHotkeys([['mod+E', toggleEditMode]]); useWindowEvent('beforeunload', (event: BeforeUnloadEvent) => { if (enabled) { From c799d507d2533701aac17146c8f7d4c99da09bf3 Mon Sep 17 00:00:00 2001 From: ajnart Date: Tue, 21 Mar 2023 11:11:50 +0800 Subject: [PATCH 19/22] =?UTF-8?q?=F0=9F=8E=A8=20Wrap=20shortcut=20with=20t?= =?UTF-8?q?ext=20component?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Dashboard/Modals/AboutModal/AboutModal.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Dashboard/Modals/AboutModal/AboutModal.tsx b/src/components/Dashboard/Modals/AboutModal/AboutModal.tsx index 952018c0f..1914c59f9 100644 --- a/src/components/Dashboard/Modals/AboutModal/AboutModal.tsx +++ b/src/components/Dashboard/Modals/AboutModal/AboutModal.tsx @@ -63,7 +63,7 @@ export const AboutModal = ({ opened, closeModal, newVersionAvailable }: AboutMod {element.key} - {element.shortcut} + {element.shortcut} )); From ed159ea3c3af0776971e85280d5295ae07c6275b Mon Sep 17 00:00:00 2001 From: ajnart Date: Tue, 21 Mar 2023 11:18:19 +0800 Subject: [PATCH 20/22] =?UTF-8?q?=F0=9F=8C=90=20Add=20translations?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/locales/en/layout/modals/about.json | 3 +++ src/components/Dashboard/Modals/AboutModal/AboutModal.tsx | 6 +++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/public/locales/en/layout/modals/about.json b/public/locales/en/layout/modals/about.json index aa99318db..d85feef8b 100644 --- a/public/locales/en/layout/modals/about.json +++ b/public/locales/en/layout/modals/about.json @@ -2,6 +2,9 @@ "description": "Homarr is a sleek, modern dashboard that puts all of your apps and services at your fingertips. With Homarr, you can access and control everything in one convenient location. Homarr seamlessly integrates with the apps you've added, providing you with valuable information and giving you complete control. Installation is a breeze, and Homarr supports a wide range of deployment methods.", "contact": "Having trouble or questions? Connect with us!", "addToDashboard": "Add to Dashboard", + "tip": "Mod refers to your modifier key, it is Ctrl and Command/Super/Windows key", + "key": "Shortcut key", + "action": "Action", "metrics": { "configurationSchemaVersion": "Configuration schema version", "configurationsCount": "Available configurations", diff --git a/src/components/Dashboard/Modals/AboutModal/AboutModal.tsx b/src/components/Dashboard/Modals/AboutModal/AboutModal.tsx index 1914c59f9..0dffd9487 100644 --- a/src/components/Dashboard/Modals/AboutModal/AboutModal.tsx +++ b/src/components/Dashboard/Modals/AboutModal/AboutModal.tsx @@ -124,13 +124,13 @@ export const AboutModal = ({ opened, closeModal, newVersionAvailable }: AboutMod - - + + {rows}
KeyShortcutt{'layout/modals/about:key'}t{'layout/modals/about:action'}
- Mod refers to your modifier key, it is Ctrl and Command/Super/Windows key + {t('layout/modals/about:tip')} From 850375767e745340be010939425d8e9949c79343 Mon Sep 17 00:00:00 2001 From: ajnart Date: Tue, 21 Mar 2023 11:20:15 +0800 Subject: [PATCH 21/22] =?UTF-8?q?=F0=9F=8C=90=20Add=20translations?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/locales/en/layout/modals/about.json | 1 + src/components/Dashboard/Modals/AboutModal/AboutModal.tsx | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/public/locales/en/layout/modals/about.json b/public/locales/en/layout/modals/about.json index d85feef8b..83109b624 100644 --- a/public/locales/en/layout/modals/about.json +++ b/public/locales/en/layout/modals/about.json @@ -5,6 +5,7 @@ "tip": "Mod refers to your modifier key, it is Ctrl and Command/Super/Windows key", "key": "Shortcut key", "action": "Action", + "keybinds": "Keybinds", "metrics": { "configurationSchemaVersion": "Configuration schema version", "configurationsCount": "Available configurations", diff --git a/src/components/Dashboard/Modals/AboutModal/AboutModal.tsx b/src/components/Dashboard/Modals/AboutModal/AboutModal.tsx index 0dffd9487..89d796001 100644 --- a/src/components/Dashboard/Modals/AboutModal/AboutModal.tsx +++ b/src/components/Dashboard/Modals/AboutModal/AboutModal.tsx @@ -119,7 +119,7 @@ export const AboutModal = ({ opened, closeModal, newVersionAvailable }: AboutMod - }>Keybinds + }>t{'layout/modals/about:keybinds'} From e0eb195097f836368e4d3923a3dcb5a3822b84e2 Mon Sep 17 00:00:00 2001 From: ajnart Date: Tue, 21 Mar 2023 11:43:10 +0800 Subject: [PATCH 22/22] =?UTF-8?q?=F0=9F=9A=A8=20Fix=20compilation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Dashboard/Modals/AboutModal/AboutModal.tsx | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/components/Dashboard/Modals/AboutModal/AboutModal.tsx b/src/components/Dashboard/Modals/AboutModal/AboutModal.tsx index 89d796001..936779bff 100644 --- a/src/components/Dashboard/Modals/AboutModal/AboutModal.tsx +++ b/src/components/Dashboard/Modals/AboutModal/AboutModal.tsx @@ -63,7 +63,9 @@ export const AboutModal = ({ opened, closeModal, newVersionAvailable }: AboutMod - + )); @@ -119,13 +121,15 @@ export const AboutModal = ({ opened, closeModal, newVersionAvailable }: AboutMod
{element.key} {element.shortcut} + {element.shortcut} +
- }>t{'layout/modals/about:keybinds'} + }> + {t('layout/modals/about:keybinds')} + - - + + {rows}
t{'layout/modals/about:key'}t{'layout/modals/about:action'}{t('layout/modals/about:key')}{t('layout/modals/about:action')}