diff --git a/.agents/skills/homarr-local-harness/SKILL.md b/.agents/skills/homarr-local-harness/SKILL.md deleted file mode 100644 index 19ae5a412..000000000 --- a/.agents/skills/homarr-local-harness/SKILL.md +++ /dev/null @@ -1,60 +0,0 @@ ---- -name: homarr-local-harness -description: Build and inspect a writable Docker demo harness from the current Homarr checkout when validating a local branch in a browser. ---- - -# Homarr Local Harness - -Use this skill when a Homarr change needs a real production image and browser validation. Work from the repository root and keep the harness name Docker-safe, such as `feature-board`. - -## Set up the harness - -Run the TypeScript operations CLI; this workflow does not use the interactive developer TUI: - -```sh -pnpm cli harness setup feature-board -``` - -`setup` builds the current checkout as `homarr:feature-board`, replaces the named harness container, and starts it with a persistent data volume. It enables demo mode, mock integrations, and writable demo mutations by default: - -- `DEMO_MODE=true` -- `DEMO_READ_ONLY=false` -- `UNSAFE_ENABLE_MOCK_INTEGRATION=true` - -Pass repeatable environment overrides when the feature needs them: - -```sh -pnpm cli harness setup feature-board \ - --env WORKSHOP_WEB_URL=https://example.test \ - --env FEATURE_FLAG=true -``` - -Use `pnpm cli harness build ` when only the image is needed, and `pnpm cli harness run ` to start an already-built image. `--port ` pins a host port; otherwise Docker assigns one. - -Always use the URL printed by the command. If the output is no longer available, query it directly: - -```sh -pnpm cli harness port feature-board -``` - -Do not assume port `7575`; the container listens on `7575`, but the host port is dynamic by default. - -## Browser validation - -Open the printed URL with the environment's `browser-harness` tool. In this workspace, the `agent-browser` CLI is the supported browser automation fallback. Load its current workflow before invoking it: - -```sh -agent-browser skills get core -``` - -Navigate to the exact harness URL, wait for the app to become usable, exercise the changed flow, and capture screenshots or other browser evidence. Keep browser state in a named session when the workflow needs login persistence. Report the exact URL, viewport/session used, and screenshot paths; a Docker process or HTTP health response alone is not browser acceptance. - -## Cleanup - -Stop the named container when finished: - -```sh -pnpm cli harness stop feature-board -``` - -Stopping keeps the data volume so the same harness can be restarted. A later `setup` rebuilds the image and replaces only the container. Preserve unrelated containers, images, volumes, and working-tree changes. diff --git a/.agents/skills/homarr-local-harness/agents/openai.yaml b/.agents/skills/homarr-local-harness/agents/openai.yaml deleted file mode 100644 index fbe8007db..000000000 --- a/.agents/skills/homarr-local-harness/agents/openai.yaml +++ /dev/null @@ -1,4 +0,0 @@ -interface: - display_name: "Homarr Local Harness" - short_description: "Build and browse a writable local Homarr branch harness" - default_prompt: "Use $homarr-local-harness to set up a writable Homarr harness for the current branch and validate it in the browser." diff --git a/apps/nextjs/src/components/assistant/assistant-panel.module.css b/apps/nextjs/src/components/assistant/assistant-panel.module.css index 7c73ffcc2..291b5fbda 100644 --- a/apps/nextjs/src/components/assistant/assistant-panel.module.css +++ b/apps/nextjs/src/components/assistant/assistant-panel.module.css @@ -184,10 +184,6 @@ min-width: 0; } -.widgetPanel[data-editing] .panelActions { - padding-inline-end: 2.75rem; -} - .panelHeader { min-width: 0; min-height: 3.75rem; diff --git a/apps/nextjs/src/components/board/items/item-content.module.css b/apps/nextjs/src/components/board/items/item-content.module.css index 7ec4b3a16..71116baec 100644 --- a/apps/nextjs/src/components/board/items/item-content.module.css +++ b/apps/nextjs/src/components/board/items/item-content.module.css @@ -12,6 +12,10 @@ } .settingsButton { + position: absolute; + top: -34px; + right: 14px; + z-index: 201; opacity: 0; pointer-events: none; transition: opacity 120ms ease; @@ -58,3 +62,11 @@ transition: none; } } + +@media (max-width: 768px) { + .settingsButton { + right: 4px; + opacity: 1; + pointer-events: auto; + } +} diff --git a/apps/nextjs/src/components/board/items/item-menu.tsx b/apps/nextjs/src/components/board/items/item-menu.tsx index 2b3a79dcc..4d8e0dab3 100644 --- a/apps/nextjs/src/components/board/items/item-menu.tsx +++ b/apps/nextjs/src/components/board/items/item-menu.tsx @@ -106,10 +106,6 @@ const BoardItemMenuInner = ({ item, definition, resetErrorBoundary }: BoardItemM variant="default" size={24} radius="sm" - pos="absolute" - top={4} - right={4} - style={{ zIndex: 30 }} className={itemContentClasses.settingsButton} data-menu-open={isMenuOpen || undefined} data-board-widget-settings diff --git a/apps/nextjs/src/components/board/items/widget-hover-overlay.module.css b/apps/nextjs/src/components/board/items/widget-hover-overlay.module.css index 6beb289a7..25a8708f9 100644 --- a/apps/nextjs/src/components/board/items/widget-hover-overlay.module.css +++ b/apps/nextjs/src/components/board/items/widget-hover-overlay.module.css @@ -31,7 +31,7 @@ align-items: center; gap: 8px; min-height: 28px; - padding: 4px 8px; + padding: 4px 40px 4px 8px; border: 1px solid var(--border-color); border-radius: var(--mantine-radius-md); background-color: var(--background-color); diff --git a/packages/translation/src/lang/en.json b/packages/translation/src/lang/en.json index dc27c91c8..88e7b4d32 100644 --- a/packages/translation/src/lang/en.json +++ b/packages/translation/src/lang/en.json @@ -1904,8 +1904,7 @@ } }, "widgetQuery": { - "loading": "Loading widget data", - "stale": "Could not refresh {widget}; showing saved data" + "loading": "Loading widget data" }, "total": "Total", "filesystemUsage": "{count, plural, one {Show usage for # filesystem} other {Show usage for # filesystems}}", diff --git a/packages/widgets/src/air-quality/component.tsx b/packages/widgets/src/air-quality/component.tsx index 7ab1ff6b7..91f522dd9 100644 --- a/packages/widgets/src/air-quality/component.tsx +++ b/packages/widgets/src/air-quality/component.tsx @@ -11,7 +11,7 @@ import { useCurrentIntlLocale, useI18n } from "@homarr/translation/client"; import { WidgetEmptyState } from "../common/empty-state"; import { formatLocalizedDate, formatLocalizedTime } from "../common/locale"; import { getUsableWidgetQueryData, isInitialWidgetQueryPending } from "../common/query-state"; -import { WidgetQueryErrorIndicator, WidgetQueryLoadingState } from "../common/query-state-indicator"; +import { WidgetQueryLoadingState } from "../common/query-state-indicator"; import type { WidgetComponentProps } from "../definition"; import type { AirQualityData, PollutantKey, PollenKey } from "./display"; import { @@ -28,7 +28,6 @@ import { } from "./display"; export default function AirQualityWidget({ options, width, height, displayMode }: WidgetComponentProps<"airQuality">) { - const t = useI18n("widget.airQuality"); const query = clientApi.widget.airQuality.atLocation.useQuery({ latitude: options.location.latitude, longitude: options.location.longitude, @@ -45,11 +44,6 @@ export default function AirQualityWidget({ options, width, height, displayMode } ) : ( )} - {query.error && ( - - - - )} ); } diff --git a/packages/widgets/src/anchor-note/component.tsx b/packages/widgets/src/anchor-note/component.tsx index b0c93333f..692ac1ef6 100644 --- a/packages/widgets/src/anchor-note/component.tsx +++ b/packages/widgets/src/anchor-note/component.tsx @@ -14,7 +14,6 @@ import { useCurrentIntlLocale, useI18n } from "@homarr/translation/client"; import { WidgetEmptyState } from "../common/empty-state"; import type { WidgetComponentProps } from "../definition"; import { getUsableWidgetQueryData } from "../common/query-state"; -import { WidgetQueryErrorIndicator } from "../common/query-state-indicator"; import actionTargetClasses from "../common/action-target.module.css"; import { storedContentToPlainText } from "./content"; @@ -239,7 +238,6 @@ const AnchorNoteWidgetContent = ({ )} - {(isEditing || canEdit) && ( {isEditing ? ( diff --git a/packages/widgets/src/app/component.tsx b/packages/widgets/src/app/component.tsx index 54efea3d7..8b95ad157 100644 --- a/packages/widgets/src/app/component.tsx +++ b/packages/widgets/src/app/component.tsx @@ -16,7 +16,7 @@ import { MaskedOrNormalImage } from "@homarr/ui"; import { WidgetEmptyState } from "../common/empty-state"; import { getSafeAppHref, SAFE_NEW_TAB_REL } from "../common/application-url"; import { getUsableWidgetQueryData, isInitialWidgetQueryPending } from "../common/query-state"; -import { WidgetQueryErrorIndicator, WidgetQueryLoadingState } from "../common/query-state-indicator"; +import { WidgetQueryLoadingState } from "../common/query-state-indicator"; import type { WidgetComponentProps } from "../definition"; import classes from "./app.module.css"; import { PingDot } from "./ping/ping-dot"; @@ -24,7 +24,6 @@ import { PingIndicator } from "./ping/ping-indicator"; export default function AppWidget({ options, isEditMode, height, width }: WidgetComponentProps<"app">) { const tCommon = useI18n("common"); - const tApp = useI18n("widget.app"); const settings = useSettings(); const board = useRequiredBoard(); const appQuery = clientApi.app.byId.useQuery({ id: options.appId }, { enabled: Boolean(options.appId) }); @@ -127,11 +126,6 @@ export default function AppWidget({ options, isEditMode, height, width }: Widget ) : null} - {appQuery.error && ( - - - - )} ); } diff --git a/packages/widgets/src/archive-team-warrior/component.tsx b/packages/widgets/src/archive-team-warrior/component.tsx index 81c1c64c4..04c49ed4d 100644 --- a/packages/widgets/src/archive-team-warrior/component.tsx +++ b/packages/widgets/src/archive-team-warrior/component.tsx @@ -8,7 +8,6 @@ import { getIconUrl } from "@homarr/definitions"; import { useCurrentIntlLocale, useI18n } from "@homarr/translation/client"; import type { WidgetComponentProps } from "../definition"; -import { WidgetQueryErrorIndicator } from "../common/query-state-indicator"; export default function ArchiveTeamWarriorWidget({ integrationIds, @@ -50,7 +49,7 @@ const ArchiveTeamWarriorWidgetContent = ({ const t = useI18n("widget.archiveTeamWarrior"); const tWidgetCommon = useI18n("widget.common"); const locale = useCurrentIntlLocale(); - const [data, statusQuery] = clientApi.widget.archiveTeamWarrior.getStatus.useSuspenseQuery({ integrationId }); + const [data] = clientApi.widget.archiveTeamWarrior.getStatus.useSuspenseQuery({ integrationId }); const status = data.status; const projectName = status.project?.title ?? status.selectedProject ?? t("noProjectSelected"); @@ -74,7 +73,6 @@ const ArchiveTeamWarriorWidgetContent = ({ - {t(`status.${statusKey}`)} diff --git a/packages/widgets/src/audio-stats/component.tsx b/packages/widgets/src/audio-stats/component.tsx index 520158508..f4aaca4a8 100644 --- a/packages/widgets/src/audio-stats/component.tsx +++ b/packages/widgets/src/audio-stats/component.tsx @@ -6,11 +6,9 @@ import { getQueryKey } from "@trpc/react-query"; import { clientApi } from "@homarr/api/client"; import { formatBytes, formatDuration } from "@homarr/common"; import type { AudiobookshelfDashboardData } from "@homarr/integrations/types"; -import { useI18n } from "@homarr/translation/client"; import { WidgetEmptyState } from "../common/empty-state"; import { IntegrationErrorIndicator } from "../common/integration-error-indicator"; -import { WidgetQueryErrorIndicator } from "../common/query-state-indicator"; import type { WidgetComponentProps } from "../definition"; import { useWidgetRuntimeQueries } from "../runtime-hooks"; import { AudioStatsContent } from "./audio-stats-content"; @@ -23,8 +21,6 @@ export default function AudioStatsWidget({ displayMode = "compact", widgetRuntimeRef, }: WidgetComponentProps<"audioStats">) { - const tAudio = useI18n("widget.audioStats"); - const tMediaServer = useI18n("widget.mediaServer"); const statsInput = { integrationId: integrationIds[0] ?? "" }; const { data: response, error: statsError } = clientApi.widget.audioStats.getStats.useQuery(statsInput); const streamsInput = { integrationIds: [statsInput.integrationId], showOnlyPlaying: true }; @@ -56,9 +52,6 @@ export default function AudioStatsWidget({ if (displayMode === "compact") { return ( - - - {summary} ); @@ -73,10 +66,8 @@ export default function AudioStatsWidget({ return (
{summary}
- {(statsError || streamsError || hasStreamErrors) && ( + {hasStreamErrors && ( - - )} diff --git a/packages/widgets/src/beszel-alerts/component.tsx b/packages/widgets/src/beszel-alerts/component.tsx index 715f12984..083d63ee6 100644 --- a/packages/widgets/src/beszel-alerts/component.tsx +++ b/packages/widgets/src/beszel-alerts/component.tsx @@ -28,7 +28,6 @@ import { useI18n } from "@homarr/translation/client"; import type { WidgetComponentProps } from "../definition"; import { IntegrationErrorIndicator } from "../common/integration-error-indicator"; import { getUsableWidgetQueryData } from "../common/query-state"; -import { WidgetQueryErrorIndicator } from "../common/query-state-indicator"; import { useWidgetRuntimeQueries } from "../runtime-hooks"; import { getBeszelAlertsQueryInput } from "./display"; import { buildBeszelSystemNameMap, getBeszelSystemName } from "./system-name-map"; @@ -126,7 +125,6 @@ export default function BeszelAlertsWidget({ - diff --git a/packages/widgets/src/beszel-system-grid/component.tsx b/packages/widgets/src/beszel-system-grid/component.tsx index 260e33ed7..3cb6ce591 100644 --- a/packages/widgets/src/beszel-system-grid/component.tsx +++ b/packages/widgets/src/beszel-system-grid/component.tsx @@ -52,7 +52,6 @@ import { import { useBeszelFilteredSystems } from "../beszel/_shared/hooks"; import { IntegrationErrorIndicator } from "../common/integration-error-indicator"; import { getUsableWidgetQueryData } from "../common/query-state"; -import { WidgetQueryErrorIndicator } from "../common/query-state-indicator"; import { BeszelSystemStatsModal } from "../beszel/_shared/system-stats-modal"; import { DiskUsage } from "../beszel/_shared/disk-usage"; import { isBeszelGridMetricVisible } from "./display"; @@ -460,7 +459,6 @@ export default function BeszelSystemGridWidget({ displayMode, }: WidgetComponentProps<"beszelSystemGrid">) { const t = useI18n("widget.beszel"); - const tFeature = useI18n("widget.beszelSystemGrid"); const tCommon = useI18n("common"); const board = useRequiredBoard(); const { openModal } = useModalAction(BeszelSystemStatsModal); @@ -485,7 +483,6 @@ export default function BeszelSystemGridWidget({ return ( -
@@ -514,7 +511,6 @@ export default function BeszelSystemGridWidget({ return ( - -
@@ -184,7 +182,6 @@ export default function BeszelSystemStatsWidget({ - diff --git a/packages/widgets/src/beszel-system-table/component.tsx b/packages/widgets/src/beszel-system-table/component.tsx index d65e3a870..3c68fa0de 100644 --- a/packages/widgets/src/beszel-system-table/component.tsx +++ b/packages/widgets/src/beszel-system-table/component.tsx @@ -42,7 +42,6 @@ import { } from "../beszel/_shared/format"; import { useBeszelFilteredSystems } from "../beszel/_shared/hooks"; import { IntegrationErrorIndicator } from "../common/integration-error-indicator"; -import { WidgetQueryErrorIndicator } from "../common/query-state-indicator"; import { BeszelSystemStatsModal } from "../beszel/_shared/system-stats-modal"; import { DiskUsage } from "../beszel/_shared/disk-usage"; import { getBeszelTableVisibleMetricKeys } from "./display"; @@ -453,7 +452,6 @@ export default function BeszelSystemTableWidget({
-
diff --git a/packages/widgets/src/calendar/component.tsx b/packages/widgets/src/calendar/component.tsx index 4a46d8f21..d2f6ddc25 100644 --- a/packages/widgets/src/calendar/component.tsx +++ b/packages/widgets/src/calendar/component.tsx @@ -16,7 +16,6 @@ import { useCurrentIntlLocale, useI18n } from "@homarr/translation/client"; import actionTargetClasses from "../common/action-target.module.css"; import type { WidgetComponentProps } from "../definition"; import { getUsableWidgetQueryData } from "../common/query-state"; -import { WidgetQueryErrorIndicator } from "../common/query-state-indicator"; import { useWidgetRuntimeQueries } from "../runtime-hooks"; import { IntegrationErrorIndicator } from "../common/integration-error-indicator"; import { CalendarDay } from "./calender-day"; @@ -54,7 +53,6 @@ export default function CalendarWidget(props: WidgetComponentProps<"calendar">) events={[]} failedIntegrations={[]} isPending={false} - queryError={undefined} month={month} setMonth={setMonth} /> @@ -106,7 +104,6 @@ const FetchCalendar = ({ month, setMonth, isEditMode, integrationIds, options, d events={events} failedIntegrations={failedIntegrations} isPending={isPending} - queryError={calendarQuery.error} month={month} setMonth={setMonth} options={options} @@ -120,7 +117,6 @@ interface CalendarBaseProps { events: CalendarEventWithSource[]; failedIntegrations: { integrationId: string; integrationName: string; error: string }[]; isPending: boolean; - queryError: unknown; month: Date; setMonth: (date: Date) => void; options: WidgetComponentProps<"calendar">["options"]; @@ -132,13 +128,11 @@ const CalendarBase = ({ events, failedIntegrations, isPending, - queryError, month, setMonth, options, displayMode, }: CalendarBaseProps) => { - const t = useI18n("widget.calendar"); const locale = useCurrentIntlLocale(); const { firstDayOfWeek } = useSettings(); const board = useRequiredBoard(); @@ -170,8 +164,6 @@ const CalendarBase = ({ events={agendaEvents} failedIntegrations={failedIntegrations} isPending={isPending} - queryError={queryError} - queryErrorLabel={t("name")} isEditMode={isEditMode} locale={locale} month={month} @@ -180,8 +172,6 @@ const CalendarBase = ({ ); } - const hasErrors = failedIntegrations.length > 0 || Boolean(queryError); - return ( ); }} /> - {hasErrors && ( + {failedIntegrations.length > 0 && ( - )} @@ -270,8 +257,6 @@ interface CalendarAgendaProps { events: CalendarEventWithSource[]; failedIntegrations: CalendarBaseProps["failedIntegrations"]; isPending: boolean; - queryError: unknown; - queryErrorLabel: string; isEditMode: boolean; locale: string; month: Date; @@ -282,8 +267,6 @@ const CalendarAgenda = ({ events, failedIntegrations, isPending, - queryError, - queryErrorLabel, isEditMode, locale, month, @@ -331,7 +314,6 @@ const CalendarAgenda = ({ - diff --git a/packages/widgets/src/clock/weather-summary.tsx b/packages/widgets/src/clock/weather-summary.tsx index 093a7c742..1bcd55a71 100644 --- a/packages/widgets/src/clock/weather-summary.tsx +++ b/packages/widgets/src/clock/weather-summary.tsx @@ -4,7 +4,6 @@ import { clientApi } from "@homarr/api/client"; import { useI18n } from "@homarr/translation/client"; import { isInitialWidgetQueryPending } from "../common/query-state"; -import { WidgetQueryErrorIndicator } from "../common/query-state-indicator"; import { AnimatedWeatherIcon } from "../weather/animated-icon"; import { WeatherDescription } from "../weather/icon"; @@ -25,17 +24,16 @@ export const ClockWeatherSummary = ({ animateIcon, detailed, }: ClockWeatherSummaryProps) => { - const t = useI18n(); const tCommon = useI18n("common"); const weatherQuery = clientApi.widget.weather.atLocation.useQuery({ latitude, longitude }); const weather = weatherQuery.data; if (!weather) { - return isInitialWidgetQueryPending(weatherQuery) ? ( - - ) : ( - - ); + if (isInitialWidgetQueryPending(weatherQuery)) { + return ; + } + + return null; } const temperature = isFahrenheit ? weather.current.temperature * (9 / 5) + 32 : weather.current.temperature; @@ -72,7 +70,6 @@ export const ClockWeatherSummary = ({ )} - ); }; diff --git a/packages/widgets/src/common/homarr-data-table.tsx b/packages/widgets/src/common/homarr-data-table.tsx index cc73c222d..c971419fd 100644 --- a/packages/widgets/src/common/homarr-data-table.tsx +++ b/packages/widgets/src/common/homarr-data-table.tsx @@ -149,8 +149,8 @@ export function HomarrDataTable({ defaultColumnProps={{ ...defaultColumnProps, noWrap: defaultColumnProps?.noWrap ?? true, - draggable: !isEditMode, - resizable: !isEditMode, + draggable: true, + resizable: true, cellsStyle: defaultColumnProps?.cellsStyle ?? (() => ({ padding: cellPadding })), }} scrollAreaProps={{ type: "auto", scrollbarSize: 6, ...scrollAreaProps }} diff --git a/packages/widgets/src/common/query-state-indicator.spec.ts b/packages/widgets/src/common/query-state-indicator.spec.ts index 38678a2e3..9ccb35260 100644 --- a/packages/widgets/src/common/query-state-indicator.spec.ts +++ b/packages/widgets/src/common/query-state-indicator.spec.ts @@ -5,11 +5,10 @@ import { createRoot } from "react-dom/client"; import { MantineProvider } from "@mantine/core"; import { afterEach, describe, expect, test, vi } from "vitest"; -import { WidgetQueryErrorIndicator, WidgetQueryLoadingState } from "./query-state-indicator"; +import { WidgetQueryLoadingState } from "./query-state-indicator"; vi.mock("@homarr/translation/client", () => ({ - useI18n: () => (key: string, values?: { widget?: string }) => { - if (key === "stale") return `Could not refresh ${values?.widget}; showing saved data`; + useI18n: () => (key: string) => { if (key === "loading") return "Loading widget data"; return key; }, @@ -26,7 +25,7 @@ const matchMedia = (query: string) => ({ dispatchEvent: () => false, }); -describe("WidgetQueryErrorIndicator", () => { +describe("WidgetQueryLoadingState", () => { let host: HTMLDivElement | undefined; let root: ReturnType | undefined; @@ -36,28 +35,6 @@ describe("WidgetQueryErrorIndicator", () => { vi.unstubAllGlobals(); }); - test("uses a localized label without exposing the raw failure", async () => { - vi.stubGlobal("IS_REACT_ACT_ENVIRONMENT", true); - vi.stubGlobal("matchMedia", matchMedia); - host = document.createElement("div"); - document.body.append(host); - root = createRoot(host); - const secret = "http://admin:password@private.local/path?token=secret"; - - await act(async () => - root?.render( - createElement( - MantineProvider, - null, - createElement(WidgetQueryErrorIndicator, { error: new Error(secret), label: "Weather" }), - ), - ), - ); - - expect(host.querySelector("[aria-label='Could not refresh Weather; showing saved data']")).not.toBeNull(); - expect(host.textContent).not.toMatch(/password|private\.local|token=secret/); - }); - test("announces the loading state to assistive technology", async () => { vi.stubGlobal("IS_REACT_ACT_ENVIRONMENT", true); vi.stubGlobal("matchMedia", matchMedia); diff --git a/packages/widgets/src/common/query-state-indicator.tsx b/packages/widgets/src/common/query-state-indicator.tsx index cb51c5b24..46ecb7947 100644 --- a/packages/widgets/src/common/query-state-indicator.tsx +++ b/packages/widgets/src/common/query-state-indicator.tsx @@ -1,39 +1,9 @@ "use client"; -import { ActionIcon, Center, Loader, Tooltip, VisuallyHidden } from "@mantine/core"; -import { IconAlertTriangle } from "@tabler/icons-react"; +import { Center, Loader, VisuallyHidden } from "@mantine/core"; import { useI18n } from "@homarr/translation/client"; -interface WidgetQueryErrorIndicatorProps { - error: unknown; - label: string; -} - -/** Localized warning for stale or optional-query failures. Never renders the raw error. */ -export function WidgetQueryErrorIndicator({ error, label }: WidgetQueryErrorIndicatorProps) { - const t = useI18n("common.widgetQuery"); - if (!error) return null; - - const accessibleLabel = t("stale", { widget: label }); - return ( - - - - - - ); -} - export function WidgetQueryLoadingState() { const t = useI18n("common.widgetQuery"); return ( diff --git a/packages/widgets/src/coolify/component.tsx b/packages/widgets/src/coolify/component.tsx index 1fc62d4f8..9fc46f402 100644 --- a/packages/widgets/src/coolify/component.tsx +++ b/packages/widgets/src/coolify/component.tsx @@ -3,11 +3,9 @@ import { Badge, Box, Group, ScrollArea, SimpleGrid, Stack, Text } from "@mantine/core"; import { clientApi } from "@homarr/api/client"; -import { getIntegrationName } from "@homarr/definitions"; import { useI18n } from "@homarr/translation/client"; import { getUsableWidgetQueryData } from "../common/query-state"; -import { WidgetQueryErrorIndicator } from "../common/query-state-indicator"; import { WidgetEmptyState } from "../common/empty-state"; import type { WidgetComponentProps } from "../definition"; import { createWidgetKey, getCoolifySectionVisibility } from "./coolify-utils"; @@ -148,9 +146,6 @@ const FailedSourceBadges = ({ {t("source.unavailable", { source: source.integrationName })} ))} - - - ); }; diff --git a/packages/widgets/src/dns-hole/controls/component.tsx b/packages/widgets/src/dns-hole/controls/component.tsx index deacf81bc..5a17b33bc 100644 --- a/packages/widgets/src/dns-hole/controls/component.tsx +++ b/packages/widgets/src/dns-hole/controls/component.tsx @@ -35,7 +35,6 @@ import type { widgetKind } from "."; import type { WidgetComponentProps } from "../../definition"; import { IntegrationErrorIndicator } from "../../common/integration-error-indicator"; import { getUsableWidgetQueryData } from "../../common/query-state"; -import { WidgetQueryErrorIndicator } from "../../common/query-state-indicator"; import actionTargetClasses from "../../common/action-target.module.css"; import classes from "./component.module.css"; import TimerModal from "./TimerModal"; @@ -165,7 +164,6 @@ export default function DnsHoleControlsWidget({ - {controlAllButtonsVisible && ( diff --git a/packages/widgets/src/dns-hole/summary/component.tsx b/packages/widgets/src/dns-hole/summary/component.tsx index b3f7e1426..8d50262d8 100644 --- a/packages/widgets/src/dns-hole/summary/component.tsx +++ b/packages/widgets/src/dns-hole/summary/component.tsx @@ -32,7 +32,6 @@ import type { widgetKind } from "."; import type { WidgetComponentProps, WidgetProps } from "../../definition"; import { IntegrationErrorIndicator } from "../../common/integration-error-indicator"; import { getUsableWidgetQueryData } from "../../common/query-state"; -import { WidgetQueryErrorIndicator } from "../../common/query-state-indicator"; export default function DnsHoleSummaryWidget({ options, @@ -71,7 +70,6 @@ export default function DnsHoleSummaryWidget({ - diff --git a/packages/widgets/src/downloads/component.tsx b/packages/widgets/src/downloads/component.tsx index d758bc2b4..8d246d26a 100644 --- a/packages/widgets/src/downloads/component.tsx +++ b/packages/widgets/src/downloads/component.tsx @@ -55,7 +55,6 @@ import { useCurrentIntlLocale, useI18n } from "@homarr/translation/client"; import type { WidgetComponentProps } from "../definition"; import { IntegrationErrorIndicator } from "../common/integration-error-indicator"; import { getUsableWidgetQueryData } from "../common/query-state"; -import { WidgetQueryErrorIndicator } from "../common/query-state-indicator"; import { HomarrDataTable } from "../common/homarr-data-table"; import { formatLocalizedDateTime } from "../common/locale"; import { usePersistedTableLayout, useTableLayoutPersistence } from "../common/use-persisted-table-layout"; @@ -314,7 +313,6 @@ export default function DownloadClientsWidget({ const queryIndicators = ( - ); diff --git a/packages/widgets/src/health-monitoring/cluster/cluster-health.tsx b/packages/widgets/src/health-monitoring/cluster/cluster-health.tsx index 6d0fd5c57..5e55c9cdf 100644 --- a/packages/widgets/src/health-monitoring/cluster/cluster-health.tsx +++ b/packages/widgets/src/health-monitoring/cluster/cluster-health.tsx @@ -1,5 +1,5 @@ import { useState } from "react"; -import { Accordion, Box, Center, Flex, Group, RingProgress, Stack, Text } from "@mantine/core"; +import { Accordion, Center, Flex, Group, RingProgress, Stack, Text } from "@mantine/core"; import { IconBrain, IconCpu, IconCube, IconDatabase, IconDeviceLaptop, IconServer } from "@tabler/icons-react"; import { clientApi } from "@homarr/api/client"; @@ -9,7 +9,6 @@ import { useI18n } from "@homarr/translation/client"; import { WidgetEmptyState } from "../../common/empty-state"; import { getUsableWidgetQueryData } from "../../common/query-state"; -import { WidgetQueryErrorIndicator } from "../../common/query-state-indicator"; import type { WidgetComponentProps } from "../../definition"; import { formatUptime } from "../system-health"; import { getClusterAccordionDefault, getClusterVisibleSections } from "./accordion-state"; @@ -71,9 +70,6 @@ export const ClusterHealthMonitoring = ({ const isTiny = displayMode !== "advanced" && width < 256; return ( - - - {(isAdvanced || options.showUptime) && !isTiny && ( diff --git a/packages/widgets/src/health-monitoring/system-health.tsx b/packages/widgets/src/health-monitoring/system-health.tsx index e99ff99da..6fccb6c29 100644 --- a/packages/widgets/src/health-monitoring/system-health.tsx +++ b/packages/widgets/src/health-monitoring/system-health.tsx @@ -45,7 +45,7 @@ import { filterStorageVolumes, normalizeStorageDeviceName } from "../filter-stor import { WidgetEmptyState } from "../common/empty-state"; import { IntegrationErrorIndicator } from "../common/integration-error-indicator"; import { getUsableWidgetQueryData, isInitialWidgetQueryPending } from "../common/query-state"; -import { WidgetQueryErrorIndicator, WidgetQueryLoadingState } from "../common/query-state-indicator"; +import { WidgetQueryLoadingState } from "../common/query-state-indicator"; import type { WidgetComponentProps } from "../definition"; import actionTargetClasses from "../common/action-target.module.css"; import { CpuRing } from "./rings/cpu-ring"; @@ -81,7 +81,6 @@ export const SystemHealthMonitoring = ({ const queryIndicators = ( - ); diff --git a/packages/widgets/src/immich/album-carousel/component.tsx b/packages/widgets/src/immich/album-carousel/component.tsx index 765075ffd..0c220cf5d 100644 --- a/packages/widgets/src/immich/album-carousel/component.tsx +++ b/packages/widgets/src/immich/album-carousel/component.tsx @@ -20,7 +20,6 @@ import { WidgetEmptyState } from "../../common/empty-state"; import type { WidgetComponentProps } from "../../definition"; import { useWidgetRuntimeActions } from "../../runtime-hooks"; import { getUsableWidgetQueryData } from "../../common/query-state"; -import { WidgetQueryErrorIndicator } from "../../common/query-state-indicator"; import classes from "./component.module.css"; import { ALL_PHOTOS_ALBUM_ID } from "./constants"; @@ -32,7 +31,6 @@ export default function ImmichAlbumCarouselWidget({ }: WidgetComponentProps<"immich-albumCarousel">) { const [currentPhotoIndex, setCurrentPhotoIndex] = useState(0); const [paused, setPaused] = useState(false); - const t = useI18n("widget.immich-albumCarousel"); const albumQuery = clientApi.widget.immich.getAlbum.useQuery( { @@ -71,9 +69,6 @@ export default function ImmichAlbumCarouselWidget({ return ( - - - {album.assets.length === 0 || photoAssets.length === 0 ? ( ) : ( diff --git a/packages/widgets/src/immich/server-stats/component.tsx b/packages/widgets/src/immich/server-stats/component.tsx index a0f7e8720..a98d0fa63 100644 --- a/packages/widgets/src/immich/server-stats/component.tsx +++ b/packages/widgets/src/immich/server-stats/component.tsx @@ -1,7 +1,7 @@ "use client"; import React from "react"; -import { Box, Center, Group, Progress, ScrollArea, SimpleGrid, Stack, Text } from "@mantine/core"; +import { Group, Progress, ScrollArea, SimpleGrid, Stack, Text } from "@mantine/core"; import { IconDatabase, IconPhoto, IconUsers, IconVideo } from "@tabler/icons-react"; import { getQueryKey } from "@trpc/react-query"; @@ -12,7 +12,7 @@ import { useCurrentIntlLocale, useI18n } from "@homarr/translation/client"; import { WidgetEmptyState } from "../../common/empty-state"; import type { WidgetComponentProps } from "../../definition"; import { getUsableWidgetQueryData, isInitialWidgetQueryPending } from "../../common/query-state"; -import { WidgetQueryErrorIndicator, WidgetQueryLoadingState } from "../../common/query-state-indicator"; +import { WidgetQueryLoadingState } from "../../common/query-state-indicator"; import { useWidgetRuntimeQueries } from "../../runtime-hooks"; import classes from "./component.module.css"; @@ -103,11 +103,6 @@ export default function ImmichServerStatsWidget({ return ( {statsContent} - {statsQuery.error && ( - - - - )} ); } @@ -121,15 +116,10 @@ export default function ImmichServerStatsWidget({ {t("albumLimit", { count: MAX_ADVANCED_ALBUMS })} - {isInitialWidgetQueryPending(albumsQuery) ? ( - ) : albumsQuery.error && albumsQuery.data === undefined ? ( -
- -
) : albums.length === 0 ? ( ) : ( diff --git a/packages/widgets/src/indexer-manager/component.tsx b/packages/widgets/src/indexer-manager/component.tsx index d0ce0c0a6..b1918a968 100644 --- a/packages/widgets/src/indexer-manager/component.tsx +++ b/packages/widgets/src/indexer-manager/component.tsx @@ -29,7 +29,6 @@ import { useWidgetRuntimeActions } from "../runtime-hooks"; import { getSafeApplicationUrl, SAFE_NEW_TAB_REL } from "../common/application-url"; import { WidgetEmptyState } from "../common/empty-state"; import { getUsableWidgetQueryData, isInitialWidgetQueryPending } from "../common/query-state"; -import { WidgetQueryErrorIndicator } from "../common/query-state-indicator"; import actionTargetClasses from "../common/action-target.module.css"; import classes from "./component.module.css"; import { getIndexerDisplayStatus } from "./status"; @@ -118,7 +117,6 @@ export default function IndexerManagerWidget({ )} )} - ); - const queryFailure = ; - if (isAdvanced) { return ( - - {queryFailure} - {partialFailures} - + {partialFailures} {showMissing && ( @@ -211,10 +205,7 @@ export default function MediaMissingWidget({ h="100%" style={{ display: "flex", flexDirection: "column" }} > - - {queryFailure} - {partialFailures} - + {partialFailures} {showMissing && ( ) { - const t = useI18n("widget.mediaReleases"); const releasesQuery = clientApi.widget.mediaRelease.getMediaReleases.useQuery({ integrationIds }); const response = getUsableWidgetQueryData(releasesQuery); @@ -70,10 +69,9 @@ export default function MediaReleasesWidget({
)} - {(failedIntegrations.length > 0 || releasesQuery.error) && ( + {failedIntegrations.length > 0 && ( - )} diff --git a/packages/widgets/src/media-server/component.tsx b/packages/widgets/src/media-server/component.tsx index 210e4dd30..2900d1043 100644 --- a/packages/widgets/src/media-server/component.tsx +++ b/packages/widgets/src/media-server/component.tsx @@ -40,7 +40,6 @@ import type { TablerIcon } from "@homarr/ui"; import type { WidgetComponentProps } from "../definition"; import { getUsableWidgetQueryData } from "../common/query-state"; import { IntegrationErrorIndicator } from "../common/integration-error-indicator"; -import { WidgetQueryErrorIndicator } from "../common/query-state-indicator"; import classes from "./component.module.css"; type TranscodingDecision = NonNullable["metadata"]>["transcoding"]; @@ -262,14 +261,12 @@ export default function MediaServerWidget({ aria-label={tSearch("placeholder")} leftSection={} /> - )} - {!isAdvanced && (hasFailedIntegrations || currentStreamsQuery.error) && ( + {!isAdvanced && hasFailedIntegrations && ( - )} diff --git a/packages/widgets/src/media-transcoding/component.tsx b/packages/widgets/src/media-transcoding/component.tsx index d2fca7536..d85db6a58 100644 --- a/packages/widgets/src/media-transcoding/component.tsx +++ b/packages/widgets/src/media-transcoding/component.tsx @@ -4,7 +4,6 @@ import { useEffect, useMemo, useState } from "react"; import type { ReactNode } from "react"; import { getQueryKey } from "@trpc/react-query"; import { - Box, Button, Divider, Group, @@ -26,7 +25,6 @@ import { views } from "."; import { WidgetEmptyState } from "../common/empty-state"; import type { WidgetComponentProps } from "../definition"; import { getUsableWidgetQueryData } from "../common/query-state"; -import { WidgetQueryErrorIndicator } from "../common/query-state-indicator"; import { useWidgetRuntimeQueries } from "../runtime-hooks"; import { HealthCheckStatus } from "./health-check-status"; import { QueuePanel } from "./panels/queue.panel"; @@ -115,16 +113,9 @@ export default function MediaTranscodingWidget({ const queuePageCount = totalQueuePages ?? 1; const isTiny = !isAdvanced && (width < 280 || height < 140); const footerLayout = getTranscodingFooterLayout(width, height); - const queryIndicator = ( - - - - ); - if (isAdvanced) { return ( - {queryIndicator} @@ -155,7 +146,6 @@ export default function MediaTranscodingWidget({ return ( - {queryIndicator} {view === "workers" ? ( ) : view === "queue" ? ( diff --git a/packages/widgets/src/network-controller/network-status/component.tsx b/packages/widgets/src/network-controller/network-status/component.tsx index 669fee3f2..2159b4c71 100644 --- a/packages/widgets/src/network-controller/network-status/component.tsx +++ b/packages/widgets/src/network-controller/network-status/component.tsx @@ -9,7 +9,6 @@ import { useCurrentIntlLocale, useI18n } from "@homarr/translation/client"; import type { WidgetComponentProps } from "../../definition"; import { IntegrationErrorIndicator } from "../../common/integration-error-indicator"; import { getUsableWidgetQueryData } from "../../common/query-state"; -import { WidgetQueryErrorIndicator } from "../../common/query-state-indicator"; import { getNetworkControllerStatusLayout } from "./layout"; import { WifiVariant } from "./variants/wifi-variant"; import { WiredVariant } from "./variants/wired-variant"; @@ -35,7 +34,6 @@ export default function NetworkControllerNetworkStatusWidget({ ), [results], ); - const t = useI18n("widget.networkControllerStatus"); const tWidgetCommon = useI18n("widget.common"); const tCommon = useI18n("common"); const locale = useCurrentIntlLocale(); @@ -49,7 +47,6 @@ export default function NetworkControllerNetworkStatusWidget({ const queryIndicators = ( - ); diff --git a/packages/widgets/src/network-controller/summary/component.tsx b/packages/widgets/src/network-controller/summary/component.tsx index e07c3a420..c2e92a482 100644 --- a/packages/widgets/src/network-controller/summary/component.tsx +++ b/packages/widgets/src/network-controller/summary/component.tsx @@ -15,7 +15,6 @@ import type { WidgetComponentProps } from "../../definition"; import { IntegrationErrorIndicator } from "../../common/integration-error-indicator"; import { getBinaryStatusKey } from "../../common/locale"; import { getUsableWidgetQueryData } from "../../common/query-state"; -import { WidgetQueryErrorIndicator } from "../../common/query-state-indicator"; import type { NetworkControllerMatrixMetricKey, NetworkControllerMatrixSectionKey } from "./display"; import { getNetworkControllerMatrix } from "./display"; @@ -57,7 +56,6 @@ export default function NetworkControllerSummaryWidget({ const queryIndicators = ( - ); diff --git a/packages/widgets/src/notifications/component.tsx b/packages/widgets/src/notifications/component.tsx index 0cfaaa23f..442442ed3 100644 --- a/packages/widgets/src/notifications/component.tsx +++ b/packages/widgets/src/notifications/component.tsx @@ -11,7 +11,6 @@ import { useI18n } from "@homarr/translation/client"; import { getSafeApplicationUrl, SAFE_NEW_TAB_REL } from "../common/application-url"; import { getUsableWidgetQueryData } from "../common/query-state"; -import { WidgetQueryErrorIndicator } from "../common/query-state-indicator"; import type { WidgetComponentProps } from "../definition"; import { getNotificationDisplay } from "./display"; import classes from "./component.module.css"; @@ -67,11 +66,6 @@ export default function NotificationsWidget({ return ( - {notificationsQuery.error && ( - - - - )} {failedIntegrations.length > 0 && ( {failedIntegrations.map((integration) => ( diff --git a/packages/widgets/src/patchmon/component.module.css b/packages/widgets/src/patchmon/component.module.css index 078ccbdc5..988615d19 100644 --- a/packages/widgets/src/patchmon/component.module.css +++ b/packages/widgets/src/patchmon/component.module.css @@ -29,13 +29,6 @@ min-height: 220px; } -.queryIndicator { - position: absolute; - top: 4px; - right: 4px; - z-index: 2; -} - .compactRoot { padding: clamp(4px, 3cqi, 8px); gap: 2px; diff --git a/packages/widgets/src/patchmon/component.tsx b/packages/widgets/src/patchmon/component.tsx index 82710a5d1..0b328f6cf 100644 --- a/packages/widgets/src/patchmon/component.tsx +++ b/packages/widgets/src/patchmon/component.tsx @@ -16,13 +16,12 @@ import dayjs from "dayjs"; import relativeTime from "dayjs/plugin/relativeTime"; import { clientApi } from "@homarr/api/client"; -import { getIntegrationName } from "@homarr/definitions"; import { useI18n } from "@homarr/translation/client"; import type { TablerIcon } from "@homarr/ui"; import { WidgetEmptyState } from "../common/empty-state"; import { getUsableWidgetQueryData, isInitialWidgetQueryPending } from "../common/query-state"; -import { WidgetQueryErrorIndicator, WidgetQueryLoadingState } from "../common/query-state-indicator"; +import { WidgetQueryLoadingState } from "../common/query-state-indicator"; import type { WidgetComponentProps } from "../definition"; import classes from "./component.module.css"; import { getGridCols, getVisiblePatchMonStatKeys, shouldShowComplianceHeroText } from "./layout-utils"; @@ -278,9 +277,6 @@ export default function PatchMonWidget({ return (
-
- -
{showHero && ( - @@ -131,7 +129,6 @@ export default function SpeedtestTrackerWidget({ - {dashboardData.length > 1 && ( diff --git a/packages/widgets/src/stocks/component.tsx b/packages/widgets/src/stocks/component.tsx index fb1a89ad7..e3b3af46e 100644 --- a/packages/widgets/src/stocks/component.tsx +++ b/packages/widgets/src/stocks/component.tsx @@ -9,7 +9,7 @@ import { useCurrentIntlLocale, useI18n } from "@homarr/translation/client"; import { WidgetEmptyState } from "../common/empty-state"; import { getUsableWidgetQueryData, isInitialWidgetQueryPending } from "../common/query-state"; -import { WidgetQueryErrorIndicator, WidgetQueryLoadingState } from "../common/query-state-indicator"; +import { WidgetQueryLoadingState } from "../common/query-state-indicator"; import type { WidgetComponentProps } from "../definition"; function round(value: number) { @@ -196,11 +196,6 @@ export default function StockPriceWidget({ return ( {content} - {stockQuery.error && ( - - - - )} ); } diff --git a/packages/widgets/src/system-disks/component.tsx b/packages/widgets/src/system-disks/component.tsx index 956d8c00d..9e7cf4d67 100644 --- a/packages/widgets/src/system-disks/component.tsx +++ b/packages/widgets/src/system-disks/component.tsx @@ -11,7 +11,7 @@ import { useI18n } from "@homarr/translation/client"; import { WidgetEmptyState } from "../common/empty-state"; import { IntegrationErrorIndicator } from "../common/integration-error-indicator"; import { getUsableWidgetQueryData, isInitialWidgetQueryPending } from "../common/query-state"; -import { WidgetQueryErrorIndicator, WidgetQueryLoadingState } from "../common/query-state-indicator"; +import { WidgetQueryLoadingState } from "../common/query-state-indicator"; import type { WidgetComponentProps } from "../definition"; import { filterStorageVolumes, normalizeStorageDeviceName } from "../filter-storage-volumes"; import { NoIntegrationDataError } from "../errors/no-data-integration"; @@ -253,7 +253,6 @@ export default function SystemResources({ const queryIndicators = ( - ); const emptyState = ( diff --git a/packages/widgets/src/system-resources/component.tsx b/packages/widgets/src/system-resources/component.tsx index 65b8714b8..f17b1cfab 100644 --- a/packages/widgets/src/system-resources/component.tsx +++ b/packages/widgets/src/system-resources/component.tsx @@ -4,13 +4,11 @@ import { useEffect, useMemo, useRef, useState } from "react"; import { Box, Center, Group, Loader, ScrollArea, SimpleGrid, Stack, Text } from "@mantine/core"; import { clientApi } from "@homarr/api/client"; -import { useI18n } from "@homarr/translation/client"; import { WidgetEmptyState } from "../common/empty-state"; import { IntegrationErrorIndicator } from "../common/integration-error-indicator"; import type { WidgetComponentProps } from "../definition"; import { getUsableWidgetQueryData } from "../common/query-state"; -import { WidgetQueryErrorIndicator } from "../common/query-state-indicator"; import { CombinedNetworkTrafficChart } from "./chart/combined-network-traffic"; import { SystemResourceCPUChart } from "./chart/cpu-chart"; import { SystemResourceGPUChart } from "./chart/gpu-chart"; @@ -84,7 +82,6 @@ export default function SystemResources({ height, displayMode, }: WidgetComponentProps<"systemResources">) { - const t = useI18n("widget.systemResources"); const healthQuery = clientApi.widget.healthMonitoring.getSystemHealthStatus.useQuery({ integrationIds }); const results = getUsableWidgetQueryData(healthQuery) ?? []; const data = results.filter( @@ -98,7 +95,6 @@ export default function SystemResources({ const queryIndicators = ( - ); diff --git a/packages/widgets/src/tracearr/component.tsx b/packages/widgets/src/tracearr/component.tsx index 331bd9f1f..74d5542d5 100644 --- a/packages/widgets/src/tracearr/component.tsx +++ b/packages/widgets/src/tracearr/component.tsx @@ -3,14 +3,12 @@ import { Box, Group, ScrollArea, SimpleGrid, Stack, Text } from "@mantine/core"; import { clientApi } from "@homarr/api/client"; -import { getIntegrationName } from "@homarr/definitions"; import type { TracearrDashboardData } from "@homarr/integrations/types"; import { useI18n } from "@homarr/translation/client"; import type { WidgetComponentProps } from "../definition"; import { IntegrationErrorIndicator } from "../common/integration-error-indicator"; import { getUsableWidgetQueryData } from "../common/query-state"; -import { WidgetQueryErrorIndicator } from "../common/query-state-indicator"; import { NoIntegrationDataError } from "../errors/no-data-integration"; import { formatTotalTracearrBitrate } from "./bitrate"; import { RecentActivityList } from "./recent-activity-section"; @@ -186,7 +184,6 @@ function TracearrContent({ integrationIds, options, width, height, displayMode } - - diff --git a/packages/widgets/src/traefik/component.tsx b/packages/widgets/src/traefik/component.tsx index 5c4c36524..6eb850f8f 100644 --- a/packages/widgets/src/traefik/component.tsx +++ b/packages/widgets/src/traefik/component.tsx @@ -12,7 +12,6 @@ import { } from "@tabler/icons-react"; import { clientApi } from "@homarr/api/client"; -import { getIntegrationName } from "@homarr/definitions"; import type { TraefikDashboardData, TraefikProtocolSummary, TraefikResourceSummary } from "@homarr/integrations/types"; import { useI18n } from "@homarr/translation/client"; @@ -20,7 +19,6 @@ import { WidgetEmptyState } from "../common/empty-state"; import { IntegrationErrorIndicator } from "../common/integration-error-indicator"; import type { WidgetComponentProps } from "../definition"; import { getUsableWidgetQueryData } from "../common/query-state"; -import { WidgetQueryErrorIndicator } from "../common/query-state-indicator"; import { NoIntegrationDataError } from "../errors/no-data-integration"; import classes from "./component.module.css"; @@ -212,7 +210,6 @@ function TraefikWidgetContent({ - {summary} @@ -265,7 +262,6 @@ function TraefikWidgetContent({ - @@ -281,7 +277,6 @@ function TraefikWidgetContent({ - {summary} diff --git a/packages/widgets/src/umami/umami-content.tsx b/packages/widgets/src/umami/umami-content.tsx index bde67ad7b..494a69980 100644 --- a/packages/widgets/src/umami/umami-content.tsx +++ b/packages/widgets/src/umami/umami-content.tsx @@ -15,7 +15,7 @@ import { UmamiTopPagesContent, UmamiTopReferrersContent } from "./umami-top-list import { formatTimeFrameLabel, formatXLabel, umamiQueryOptions } from "./umami-utils"; import type { TimeFrame } from "./umami-utils"; import { getUsableWidgetQueryData, isInitialWidgetQueryPending } from "../common/query-state"; -import { WidgetQueryErrorIndicator, WidgetQueryLoadingState } from "../common/query-state-indicator"; +import { WidgetQueryLoadingState } from "../common/query-state-indicator"; interface UmamiContentProps { integrationIds: string[]; @@ -270,14 +270,6 @@ export function UmamiContent({ {displayMode === "advanced" ? advancedContent : selectedView} - {(statsQuery.error || activeVisitorsQuery.error || multiEventQuery.error) && ( - - - - )} ); } diff --git a/packages/widgets/src/ups/component.tsx b/packages/widgets/src/ups/component.tsx index 055384821..ce9ee3042 100644 --- a/packages/widgets/src/ups/component.tsx +++ b/packages/widgets/src/ups/component.tsx @@ -24,7 +24,6 @@ import { WidgetEmptyState } from "../common/empty-state"; import { IntegrationErrorIndicator } from "../common/integration-error-indicator"; import type { WidgetComponentProps } from "../definition"; import { getUsableWidgetQueryData } from "../common/query-state"; -import { WidgetQueryErrorIndicator } from "../common/query-state-indicator"; import { NoIntegrationSelectedError } from "../errors/no-integration-selected"; const statusColors: Record = { @@ -87,7 +86,6 @@ function UpsContent({ integrationIds, options, width, height, displayMode }: Ups - @@ -118,7 +116,6 @@ function UpsContent({ integrationIds, options, width, height, displayMode }: Ups - {displayMode === "advanced" ? ( diff --git a/packages/widgets/src/uptime-kuma/component.tsx b/packages/widgets/src/uptime-kuma/component.tsx index 7016a61c3..929c82bf1 100644 --- a/packages/widgets/src/uptime-kuma/component.tsx +++ b/packages/widgets/src/uptime-kuma/component.tsx @@ -6,14 +6,12 @@ import { IconArrowDown, IconArrowUp, IconClockPause, IconServer } from "@tabler/ import { clientApi } from "@homarr/api/client"; import { formatNumber } from "@homarr/common"; -import { getIntegrationName } from "@homarr/definitions"; import { useI18n } from "@homarr/translation/client"; import { WidgetEmptyState } from "../common/empty-state"; import { IntegrationErrorIndicator } from "../common/integration-error-indicator"; import type { WidgetComponentProps } from "../definition"; import { getUsableWidgetQueryData } from "../common/query-state"; -import { WidgetQueryErrorIndicator } from "../common/query-state-indicator"; import { NoIntegrationDataError } from "../errors/no-data-integration"; import classes from "./component.module.css"; import { aggregateUptimeKumaDashboards } from "./aggregate"; @@ -254,7 +252,6 @@ function UptimeKumaContent({ integrationIds, options, width, height, displayMode - {summaryContent} @@ -291,7 +288,6 @@ function UptimeKumaContent({ integrationIds, options, width, height, displayMode - @@ -307,7 +303,6 @@ function UptimeKumaContent({ integrationIds, options, width, height, displayMode - {summaryContent} diff --git a/packages/widgets/src/weather/component.module.css b/packages/widgets/src/weather/component.module.css index 0b5645767..5a2f017bb 100644 --- a/packages/widgets/src/weather/component.module.css +++ b/packages/widgets/src/weather/component.module.css @@ -110,10 +110,6 @@ outline-offset: 0.125rem; } -.errorIndicator { - z-index: 2; -} - @media (any-pointer: coarse) { .detailsButton, .forecastButton, diff --git a/packages/widgets/src/weather/component.tsx b/packages/widgets/src/weather/component.tsx index e5199a1e6..9b47565d2 100644 --- a/packages/widgets/src/weather/component.tsx +++ b/packages/widgets/src/weather/component.tsx @@ -3,11 +3,10 @@ import { Box } from "@mantine/core"; import { clientApi } from "@homarr/api/client"; -import { useI18n } from "@homarr/translation/client"; import { WidgetEmptyState } from "../common/empty-state"; import { getUsableWidgetQueryData, isInitialWidgetQueryPending } from "../common/query-state"; -import { WidgetQueryErrorIndicator, WidgetQueryLoadingState } from "../common/query-state-indicator"; +import { WidgetQueryLoadingState } from "../common/query-state-indicator"; import type { WidgetComponentProps } from "../definition"; import { AdvancedWeather } from "./advanced"; import classes from "./component.module.css"; @@ -20,7 +19,6 @@ export default function WeatherWidget({ height, displayMode, }: WidgetComponentProps<"weather">) { - const t = useI18n("widget.weather"); const input = { latitude: options.location.latitude, longitude: options.location.longitude, @@ -40,11 +38,6 @@ export default function WeatherWidget({ )} - {weatherQuery.error && ( - - - - )} ); } diff --git a/packages/widgets/src/wud/component.tsx b/packages/widgets/src/wud/component.tsx index 933048dc7..6ed6c58ef 100644 --- a/packages/widgets/src/wud/component.tsx +++ b/packages/widgets/src/wud/component.tsx @@ -12,7 +12,6 @@ import { useI18n } from "@homarr/translation/client"; import { WidgetEmptyState } from "../common/empty-state"; import { getSafeApplicationUrl, SAFE_NEW_TAB_REL } from "../common/application-url"; -import { WidgetQueryErrorIndicator } from "../common/query-state-indicator"; import type { WidgetComponentProps } from "../definition"; import classes from "./component.module.css"; @@ -41,7 +40,7 @@ const WudWidgetContent = ({ isAdvanced: boolean; }) => { const t = useI18n("widget.wud"); - const [data, statsQuery] = clientApi.widget.wud.getStats.useSuspenseQuery({ integrationId }); + const [data] = clientApi.widget.wud.getStats.useSuspenseQuery({ integrationId }); const board = useRequiredBoard(); const isTiny = !isAdvanced && width < 256; @@ -115,11 +114,6 @@ const WudWidgetContent = ({ return ( - {Boolean(statsQuery.error) && ( - - - - )} {showTitle && !isTiny && (