diff --git a/packages/translation/src/type.ts b/packages/translation/src/type.ts index 9f71587e5..e2baf031f 100644 --- a/packages/translation/src/type.ts +++ b/packages/translation/src/type.ts @@ -2,6 +2,8 @@ import type { useI18n, useScopedI18n } from "./client"; import type enTranslation from "./lang/en"; export type TranslationFunction = ReturnType; -export type ScopedTranslationFunction[0]> = ReturnType>; +export type ScopedTranslationFunction[0]> = ReturnType< + typeof useScopedI18n +>; export type TranslationObject = typeof enTranslation; export type stringOrTranslation = string | ((t: TranslationFunction) => string); diff --git a/packages/widgets/src/media-requests/list/component.tsx b/packages/widgets/src/media-requests/list/component.tsx index d26961897..c97faa2e3 100644 --- a/packages/widgets/src/media-requests/list/component.tsx +++ b/packages/widgets/src/media-requests/list/component.tsx @@ -16,6 +16,7 @@ import { import { IconThumbDown, IconThumbUp } from "@tabler/icons-react"; import { clientApi } from "@homarr/api/client"; +import type { ScopedTranslationFunction } from "@homarr/translation"; import { useScopedI18n } from "@homarr/translation/client"; import { @@ -23,30 +24,25 @@ import { MediaRequestStatus, } from "../../../../integrations/src/interfaces/media-requests/media-request"; import type { WidgetComponentProps } from "../../definition"; -import type { ScopedTranslationFunction } from "@homarr/translation"; export default function MediaServerWidget({ integrationIds, isEditMode, options, serverData, - itemId + itemId, }: WidgetComponentProps<"mediaRequests-requestList">) { const t = useScopedI18n("widget.mediaRequests-requestList"); const tCommon = useScopedI18n("common"); const isQueryEnabled = Boolean(itemId); - const { - data: mediaRequests, - isError: _isError, - } = clientApi.widget.mediaRequests.getLatestRequests.useQuery( + const { data: mediaRequests, isError: _isError } = clientApi.widget.mediaRequests.getLatestRequests.useQuery( { integrationIds, // eslint-disable-next-line @typescript-eslint/no-non-null-assertion itemId: itemId!, }, { - initialData: - !serverData ? [] : serverData.initialData, + initialData: !serverData ? undefined : serverData.initialData, refetchOnMount: false, refetchOnWindowFocus: false, refetchOnReconnect: false, @@ -57,7 +53,7 @@ export default function MediaServerWidget({ const sortedMediaRequests = useMemo( () => mediaRequests - .filter((group) => group != null) + ?.filter((group) => group != null) .flatMap((group) => group.data) .flatMap(({ medias, integration }) => medias.map((media) => ({ ...media, integrationId: integration.id }))) .sort(({ status: statusA }, { status: statusB }) => { @@ -68,7 +64,7 @@ export default function MediaServerWidget({ return 1; } return 0; - }), + }) ?? [], [mediaRequests, integrationIds], ); @@ -218,7 +214,10 @@ export default function MediaServerWidget({ ); } -function GetAvailabilityProperties(mediaRequestAvailability: MediaAvailability, t: ScopedTranslationFunction<"widget.mediaRequests-requestList">) { +function GetAvailabilityProperties( + mediaRequestAvailability: MediaAvailability, + t: ScopedTranslationFunction<"widget.mediaRequests-requestList">, +) { switch (mediaRequestAvailability) { case MediaAvailability.Available: return { color: "green", label: t("availability.available") }; diff --git a/packages/widgets/src/media-requests/list/serverData.ts b/packages/widgets/src/media-requests/list/serverData.ts index 284874568..8784e4dd3 100644 --- a/packages/widgets/src/media-requests/list/serverData.ts +++ b/packages/widgets/src/media-requests/list/serverData.ts @@ -7,7 +7,7 @@ import type { WidgetProps } from "../../definition"; export default async function getServerDataAsync({ integrationIds, itemId }: WidgetProps<"mediaRequests-requestList">) { if (integrationIds.length === 0 || !itemId) { return { - initialData: [], + initialData: undefined, }; } diff --git a/packages/widgets/src/media-requests/stats/component.tsx b/packages/widgets/src/media-requests/stats/component.tsx index 885bd9224..55eb88090 100644 --- a/packages/widgets/src/media-requests/stats/component.tsx +++ b/packages/widgets/src/media-requests/stats/component.tsx @@ -15,6 +15,7 @@ import { } from "@tabler/icons-react"; import combineClasses from "clsx"; +import { clientApi } from "@homarr/api/client"; import { useScopedI18n } from "@homarr/translation/client"; import type { RequestStats } from "../../../../integrations/src/interfaces/media-requests/media-request"; @@ -25,27 +26,57 @@ export default function MediaServerWidget({ integrationIds, isEditMode, serverData, + itemId, }: WidgetComponentProps<"mediaRequests-requestStats">) { const t = useScopedI18n("widget.mediaRequests-requestStats"); const tCommon = useScopedI18n("common"); + const isQueryEnabled = Boolean(itemId); + const { data: requestStats, isError: _isError } = clientApi.widget.mediaRequests.getStats.useQuery( + { + integrationIds, + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + itemId: itemId!, + }, + { + initialData: !serverData ? undefined : serverData.initialData, + refetchOnMount: false, + refetchOnWindowFocus: false, + refetchOnReconnect: false, + enabled: integrationIds.length > 0 && isQueryEnabled, + }, + ); const { width, height, ref } = useElementSize(); - const stats = useMemo(() => serverData?.initialData.flatMap(({ stats }) => stats), [serverData, integrationIds]); + const baseData = useMemo( + () => requestStats?.filter((group) => group != null).flatMap((group) => group.data) ?? [], + [requestStats], + ); + + const stats = useMemo(() => baseData.flatMap(({ stats }) => stats), [baseData]); const users = useMemo( () => - serverData?.initialData + baseData .flatMap(({ integration, users }) => users.flatMap((user) => ({ ...user, appKind: integration.kind, appName: integration.name })), ) - .sort(({ requestCount: countA }, { requestCount: countB }) => countB - countA) - .slice(0, Math.max(Math.trunc((height / width) * 5), 1)), - [serverData, integrationIds, width, height], + .sort(({ requestCount: countA }, { requestCount: countB }) => countB - countA), + [baseData], ); - if (integrationIds.length === 0) return
{tCommon("errors.noIntegration")}
; + if (integrationIds.length === 0) + return ( +
+ {tCommon("errors.noIntegration")} +
+ ); - if (!users || users.length === 0 || !stats || stats.length === 0) return
{tCommon("errors.noData")}
; + if (users.length === 0 || stats.length === 0) + return ( +
+ {tCommon("errors.noData")} +
+ ); //Add processing and available const data = [ @@ -138,7 +169,7 @@ export default function MediaServerWidget({ gap="2cqmin" style={{ overflow: "hidden" }} > - {users.map((user) => ( + {users.slice(0, Math.max(Math.floor((height / width) * 5), 1)).map((user) => ( ) { if (integrationIds.length === 0 || !itemId) { return { - initialData: [], + initialData: undefined, }; } @@ -20,6 +20,6 @@ export default async function getServerDataAsync({ }); return { - initialData: stats.filter((group) => group != null).flatMap((group) => group.data), + initialData: stats.filter((group) => group != null), }; }