fix(widgets): fix downloads widget and add SSR prefetch

Remove WidgetEmptyState guard from downloads (widget renders fine with
empty data). Fix columnsSort filter logic from .some() to .every() so
non-sortable columns are correctly excluded. Add server-side prefetch
via tRPC caller so download data is available immediately on page load.
This commit is contained in:
Thomas Camlong committed 2026-05-29 17:26:15 +02:00
1 parent f49ae79c99
commit 682f6bd3ea
4 files changed
+32 -2

No files matched your search

@@ -101,7 +101,6 @@ export default function DownloadClientsWidget({
);
const utils = clientApi.useUtils();
//Translations
const t = useScopedI18n("widget.downloads");
const tCommon = useScopedI18n("common");
+1 -1
View File
@@ -28,7 +28,7 @@ const columnsList = [
] as const satisfies (keyof ExtendedDownloadClientItem)[];
const sortingExclusion = ["actions", "id", "state"] as const satisfies readonly (typeof columnsList)[number][];
const columnsSort = columnsList.filter((column) =>
sortingExclusion.some((exclusion) => exclusion !== column),
sortingExclusion.every((exclusion) => exclusion !== column),
) as Exclude<typeof columnsList, (typeof sortingExclusion)[number]>;
export const { definition, componentLoader } = createWidgetDefinition("downloads", {
@@ -0,0 +1,29 @@
import { api, trpc } from "@homarr/api/server";
import { createLogger } from "@homarr/core/infrastructure/logs";
import type { Prefetch } from "../definition";
const logger = createLogger({ module: "downloadsWidgetPrefetch" });
const prefetchAllAsync: Prefetch<"downloads"> = async (queryClient, items) => {
await Promise.all(
items.map(async (item) => {
if (item.integrationIds.length === 0) return;
const input = {
integrationIds: item.integrationIds,
limitPerIntegration: Number(item.options.limitPerIntegration) || 50,
};
try {
const data = await api.widget.downloads.getJobsAndStatuses(input);
queryClient.setQueryData(trpc.widget.downloads.getJobsAndStatuses.queryKey(input), data);
logger.info("Prefetched downloads widget data", { integrations: item.integrationIds.length });
} catch (error) {
logger.warn("Failed to prefetch downloads widget data", { error });
}
}),
);
};
export default prefetchAllAsync;
+2
View File
@@ -9,6 +9,7 @@ import { createSettings } from "@homarr/settings/creator";
import { reduceWidgetOptionsWithDefaultValues } from ".";
import prefetchForApps from "./app/prefetch";
import prefetchForBookmarks from "./bookmarks/prefetch";
import prefetchForDownloads from "./downloads/prefetch";
import type { Prefetch, WidgetOptionsRecordOf } from "./definition";
import type { inferOptionsFromCreator } from "./options";
@@ -19,6 +20,7 @@ const prefetchCallbacks: Partial<{
}> = {
bookmarks: prefetchForBookmarks,
app: prefetchForApps,
downloads: prefetchForDownloads,
};
export const prefetchForKindAsync = async <TKind extends WidgetKind>(