diff --git a/apps/docs/docs/management/boards/index.mdx b/apps/docs/docs/management/boards/index.mdx index ef408e221..13e1955ec 100644 --- a/apps/docs/docs/management/boards/index.mdx +++ b/apps/docs/docs/management/boards/index.mdx @@ -44,7 +44,7 @@ The main canvas and enabled rails stay at least one viewport tall, and the canva ### Public This will enable public access for everyone - regardless of whether they are logged in or not. -This can be really useful if you want to have public boards in your company or for family and friends. +This can be really useful if you want to have public boards in your company or for family and fiends. Modifications for public boards must be allowed explicitly using user groups and their permissions. ## Board settings diff --git a/apps/nextjs/src/components/board/mobile/mobile-board.module.css b/apps/nextjs/src/components/board/mobile/mobile-board.module.css index 80783dd08..78026b2f1 100644 --- a/apps/nextjs/src/components/board/mobile/mobile-board.module.css +++ b/apps/nextjs/src/components/board/mobile/mobile-board.module.css @@ -13,7 +13,7 @@ padding: 0; margin: -1px; overflow: hidden; - clip-path: inset(50%); + clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; } diff --git a/packages/api/src/router/widgets/beszel.ts b/packages/api/src/router/widgets/beszel.ts index 65fdf53d1..c52ca1717 100644 --- a/packages/api/src/router/widgets/beszel.ts +++ b/packages/api/src/router/widgets/beszel.ts @@ -44,7 +44,6 @@ export const beszelRouter = createTRPCRouter({ }; }, { - throwOnAllFailure: true, fallback: (integration, error) => ({ integrationId: integration.id, integrationName: integration.name, @@ -117,7 +116,6 @@ export const beszelRouter = createTRPCRouter({ }; }, { - throwOnAllFailure: true, fallback: (integration, error) => ({ integrationId: integration.id, integrationName: integration.name, diff --git a/packages/api/src/settle-integrations.spec.ts b/packages/api/src/settle-integrations.spec.ts index ca032b700..52f0d3697 100644 --- a/packages/api/src/settle-integrations.spec.ts +++ b/packages/api/src/settle-integrations.spec.ts @@ -23,22 +23,6 @@ describe("settleIntegrationQueries", () => { expect(results).toEqual(["Second"]); }); - it("retains fallback and successful results for a partial failure", async () => { - const results = await settleIntegrationQueries( - integrations, - vi.fn(async (integration) => { - if (integration.id === "first") throw new Error("offline"); - return integration.name; - }), - { - throwOnAllFailure: true, - fallback: (integration) => `${integration.name} unavailable`, - }, - ); - - expect(results).toEqual(["First unavailable", "Second"]); - }); - it("throws when every integration fails and throwOnAllFailure is enabled", async () => { await expect( settleIntegrationQueries( @@ -51,21 +35,6 @@ describe("settleIntegrationQueries", () => { ).rejects.toThrow("offline"); }); - it("throws on total failure even when fallbacks are configured", async () => { - await expect( - settleIntegrationQueries( - integrations, - vi.fn(async () => { - throw new Error("offline"); - }), - { - throwOnAllFailure: true, - fallback: (integration) => `${integration.name} unavailable`, - }, - ), - ).rejects.toThrow("offline"); - }); - it("does not treat an empty integration list as a failure", async () => { await expect( settleIntegrationQueries( diff --git a/packages/widgets/src/beszel/_shared/mobile-summary.tsx b/packages/widgets/src/beszel/_shared/mobile-summary.tsx index d573b50e7..7f1caa6a0 100644 --- a/packages/widgets/src/beszel/_shared/mobile-summary.tsx +++ b/packages/widgets/src/beszel/_shared/mobile-summary.tsx @@ -5,7 +5,6 @@ import { useI18n } from "@homarr/translation/client"; import { WidgetMobileLoading, WidgetMobileSummary } from "../../common/mobile-summary"; import { useBeszelFilteredSystems } from "./hooks"; -import { hasStaleIntegrationData } from "./query-status"; interface BeszelSystemsMobileSummaryProps { integrationIds: string[]; @@ -19,18 +18,12 @@ export const BeszelSystemsMobileSummary = ({ statusFilter, }: BeszelSystemsMobileSummaryProps) => { const t = useI18n(); - const { - data: results = [], - error, - isPending, - isLoadingError, - isRefetchError, - } = clientApi.widget.beszel.getSystems.useQuery({ integrationIds }); + const { data: results = [], error, isPending } = clientApi.widget.beszel.getSystems.useQuery({ integrationIds }); const systems = useBeszelFilteredSystems(results, statusFilter); const failedResults = results.filter((result) => "error" in result); if (isPending) return ; - if (isLoadingError) throw error; + if (error) throw error; if (results.length > 0 && failedResults.length === results.length) { throw new Error(String(failedResults[0]?.error ?? "Unable to connect to Beszel")); } @@ -45,7 +38,7 @@ export const BeszelSystemsMobileSummary = ({ up, attention: systems.length - up, })} - isStale={hasStaleIntegrationData(isRefetchError, failedResults)} + isStale={failedResults.length > 0} /> ); }; diff --git a/packages/widgets/src/beszel/_shared/query-status.spec.ts b/packages/widgets/src/beszel/_shared/query-status.spec.ts deleted file mode 100644 index 7663babb7..000000000 --- a/packages/widgets/src/beszel/_shared/query-status.spec.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { describe, expect, test } from "vitest"; - -import { hasStaleIntegrationData } from "./query-status"; - -describe("Beszel query status", () => { - test("marks cached data stale after outer or per-integration failures", () => { - expect(hasStaleIntegrationData(true, [])).toBe(true); - expect(hasStaleIntegrationData(false, [{ error: "offline" }])).toBe(true); - expect(hasStaleIntegrationData(false, [])).toBe(false); - }); -}); diff --git a/packages/widgets/src/beszel/_shared/query-status.ts b/packages/widgets/src/beszel/_shared/query-status.ts deleted file mode 100644 index 4d4827486..000000000 --- a/packages/widgets/src/beszel/_shared/query-status.ts +++ /dev/null @@ -1,2 +0,0 @@ -export const hasStaleIntegrationData = (isRefetchError: boolean, failedResults: readonly unknown[]) => - isRefetchError || failedResults.length > 0; diff --git a/packages/widgets/src/filter-storage-volumes.ts b/packages/widgets/src/filter-storage-volumes.ts index f5d294508..5e88584be 100644 --- a/packages/widgets/src/filter-storage-volumes.ts +++ b/packages/widgets/src/filter-storage-volumes.ts @@ -28,14 +28,18 @@ export const toScopedStorageVolumeValue = (integrationId: string, value: string) return `${integrationId}:${volumeName}`; }; -export const storageDeviceNamesMatch = (leftDeviceName: string, rightDeviceName: string): boolean => { +const storageDeviceNamesMatch = (leftDeviceName: string, rightDeviceName: string): boolean => { return ( leftDeviceName === rightDeviceName || normalizeStorageDeviceName(leftDeviceName) === normalizeStorageDeviceName(rightDeviceName) ); }; -const matchesVisibleStorageVolume = (visibleVolume: string, integrationId: string, deviceName: string): boolean => { +const matchesVisibleStorageVolume = ( + visibleVolume: string, + integrationId: string, + deviceName: string, +): boolean => { const separatorIndex = visibleVolume.indexOf(":"); if (separatorIndex === -1) { return storageDeviceNamesMatch(visibleVolume, deviceName); diff --git a/packages/widgets/src/system-disks/mobile-summary.spec.ts b/packages/widgets/src/system-disks/mobile-summary.spec.ts deleted file mode 100644 index ebe754c57..000000000 --- a/packages/widgets/src/system-disks/mobile-summary.spec.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { describe, expect, test } from "vitest"; - -import { formatDiskTemperature } from "./mobile-summary"; - -describe("formatDiskTemperature", () => { - test("preserves a valid zero-degree reading", () => { - expect(formatDiskTemperature(0, true)).toBe("0°C"); - }); - - test("omits unavailable or disabled readings", () => { - expect(formatDiskTemperature(null, true)).toBeUndefined(); - expect(formatDiskTemperature(undefined, true)).toBeUndefined(); - expect(formatDiskTemperature(20, false)).toBeUndefined(); - }); -}); diff --git a/packages/widgets/src/system-disks/mobile-summary.ts b/packages/widgets/src/system-disks/mobile-summary.ts deleted file mode 100644 index 123d0dd7d..000000000 --- a/packages/widgets/src/system-disks/mobile-summary.ts +++ /dev/null @@ -1,2 +0,0 @@ -export const formatDiskTemperature = (temperature: number | null | undefined, shouldShow: boolean) => - shouldShow && temperature != null ? `${temperature}°C` : undefined; diff --git a/packages/widgets/src/weather/temperature.spec.ts b/packages/widgets/src/weather/temperature.spec.ts deleted file mode 100644 index d22b96619..000000000 --- a/packages/widgets/src/weather/temperature.spec.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { describe, expect, test } from "vitest"; - -import { getPreferredUnit } from "./temperature"; - -describe("getPreferredUnit", () => { - test("preserves zero in Celsius and Fahrenheit", () => { - expect(getPreferredUnit(0)).toBe("0.0°C"); - expect(getPreferredUnit(0, true)).toBe("32.0°F"); - }); - - test("only uses the unavailable placeholder for missing values", () => { - expect(getPreferredUnit(undefined)).toBe("?"); - }); - - test("respects the decimal preference", () => { - expect(getPreferredUnit(0, false, true)).toBe("0°C"); - expect(getPreferredUnit(0, true, true)).toBe("32°F"); - expect(getPreferredUnit(12.6, false, true)).toBe("13°C"); - }); -}); diff --git a/packages/widgets/src/weather/temperature.ts b/packages/widgets/src/weather/temperature.ts deleted file mode 100644 index 73edf7f87..000000000 --- a/packages/widgets/src/weather/temperature.ts +++ /dev/null @@ -1,6 +0,0 @@ -export const getPreferredUnit = (value?: number, isFahrenheit = false, disableTemperatureDecimals = false): string => - value !== undefined - ? isFahrenheit - ? `${(value * (9 / 5) + 32).toFixed(disableTemperatureDecimals ? 0 : 1)}°F` - : `${value.toFixed(disableTemperatureDecimals ? 0 : 1)}°C` - : "?";