diff --git a/apps/docs/docs/widgets/timetable/index.mdx b/apps/docs/docs/widgets/timetable/index.mdx index 37f5abf05..1aede99cd 100644 --- a/apps/docs/docs/widgets/timetable/index.mdx +++ b/apps/docs/docs/widgets/timetable/index.mdx @@ -37,4 +37,4 @@ import streetDepartures from "./img/street-departures.png"; For security, all custom base URLs must resolve to a public IP address whenever Homarr uses them. Private and local hosts are rejected. -If a timetable refresh fails after departures have loaded, the widget keeps the previous departures visible and marks them with their last update time. +If a timetable refresh fails after departures have loaded, the widget keeps the previous departures visible and marks them as stale. The advanced view also shows their last update time. diff --git a/apps/nextjs/src/components/board/items/item-content.tsx b/apps/nextjs/src/components/board/items/item-content.tsx index 7985c8749..832500ab7 100644 --- a/apps/nextjs/src/components/board/items/item-content.tsx +++ b/apps/nextjs/src/components/board/items/item-content.tsx @@ -1,7 +1,7 @@ import type { CSSProperties, KeyboardEvent, MutableRefObject, PointerEvent } from "react"; import { useEffect, useRef } from "react"; import { ActionIcon, Badge, Box, Card, FocusTrap, Text } from "@mantine/core"; -import { useElementSize, useMergedRef, useViewportSize } from "@mantine/hooks"; +import { useElementSize, useViewportSize } from "@mantine/hooks"; import { IconMaximize, IconPin, IconX } from "@tabler/icons-react"; import { QueryErrorResetBoundary, useQueryClient } from "@tanstack/react-query"; import combineClasses from "clsx"; @@ -37,9 +37,8 @@ const getOverflowFromKind = (kind: SectionItem["kind"]) => { }; export const BoardItemContent = ({ item }: BoardItemContentProps) => { - const { ref, width, height } = useElementSize(); + const { ref: contentRef, width, height } = useElementSize(); const sourceRef = useRef(null); - const mergedRef = useMergedRef(ref, sourceRef); const { width: viewportWidth, height: viewportHeight } = useViewportSize(); const board = useRequiredBoard(); const t = useI18n(); @@ -86,7 +85,7 @@ export const BoardItemContent = ({ item }: BoardItemContentProps) => { <> { )} - + + + diff --git a/packages/translation/src/lang/en.json b/packages/translation/src/lang/en.json index f987f4c71..61d6d6e50 100644 --- a/packages/translation/src/lang/en.json +++ b/packages/translation/src/lang/en.json @@ -2003,7 +2003,8 @@ "stationSearch": "Unable to search stations. Check the custom URL and your board access." }, "warning": { - "stale": "The timetable could not be refreshed. Showing departures last updated at {time}." + "stale": "The timetable could not be refreshed. Showing departures last updated at {time}.", + "staleCompact": "Stale data" } }, "notebook": { diff --git a/packages/widgets/src/common/integration-error-indicator.tsx b/packages/widgets/src/common/integration-error-indicator.tsx index 818937ef4..6e9f27dd4 100644 --- a/packages/widgets/src/common/integration-error-indicator.tsx +++ b/packages/widgets/src/common/integration-error-indicator.tsx @@ -24,7 +24,7 @@ export function IntegrationErrorIndicator({ results }: IntegrationErrorIndicator const label = `${t("error")}: ${names}`; return ( - + diff --git a/packages/widgets/src/media-server/component.tsx b/packages/widgets/src/media-server/component.tsx index 7c8463042..ff2acd148 100644 --- a/packages/widgets/src/media-server/component.tsx +++ b/packages/widgets/src/media-server/component.tsx @@ -325,7 +325,7 @@ export default function MediaServerWidget({ )} {!isAdvanced && hasFailedIntegrations && ( - + )} diff --git a/packages/widgets/src/rssFeed/component.tsx b/packages/widgets/src/rssFeed/component.tsx index b09a94623..2fc2b9147 100644 --- a/packages/widgets/src/rssFeed/component.tsx +++ b/packages/widgets/src/rssFeed/component.tsx @@ -60,8 +60,8 @@ export default function RssFeed({ options, width, displayMode }: WidgetComponent return ( {warning && ( - } p="xs" mb="xs"> - {warning} + } p="xs" mb="xs"> + {warning} )} diff --git a/packages/widgets/src/timetable/component.tsx b/packages/widgets/src/timetable/component.tsx index d2c453777..c82f8b2e2 100644 --- a/packages/widgets/src/timetable/component.tsx +++ b/packages/widgets/src/timetable/component.tsx @@ -51,15 +51,24 @@ const TimetableWidgetInner = ({ station, baseUrl, itemId, displayMode, width }: if (error && timetable === undefined) throw error; const entries = timetable?.entries ?? []; - const staleWarning = - error && timetable ? t("warning.stale", { time: dayjs(timetable.timestamp).format("HH:mm:ss") }) : undefined; + const staleTime = timetable ? dayjs(timetable.timestamp).format("HH:mm:ss") : undefined; + const staleWarning = error && staleTime ? t("warning.stale", { time: staleTime }) : undefined; + const compactStaleWarning = error && staleTime ? t("warning.staleCompact") : undefined; return ( {t("title", { station: station.label })} - {staleWarning && ( - } p="xs"> - {staleWarning} + {compactStaleWarning && displayMode === "compact" && ( + + + + {compactStaleWarning} + + + )} + {staleWarning && displayMode === "advanced" && ( + } p="xs"> + {staleWarning} )}