diff --git a/client/ui/frontend/src/i18n/locales/de/common.json b/client/ui/frontend/src/i18n/locales/de/common.json index e56b9f2e5..7bc80ca6c 100644 --- a/client/ui/frontend/src/i18n/locales/de/common.json +++ b/client/ui/frontend/src/i18n/locales/de/common.json @@ -234,10 +234,10 @@ "update.card.versionAvailableInstall": "Version {version} ist zur Installation verfügbar.", "update.card.whatsNew": "Was ist neu?", "update.card.installNow": "Jetzt installieren", - "update.card.getInstaller": "Installer herunterladen", - "update.card.lastChecked": "Zuletzt geprüft am {date}", + "update.card.getInstaller": "Herunterladen", + "update.card.autoCheckInterval": "NetBird sucht im Hintergrund nach Updates.", "update.card.changelog": "Änderungsprotokoll", - "update.card.checkForUpdates": "Nach Updates suchen", + "update.card.onLatestVersion": "Du verwendest die neueste Version", "update.header.tooltip": "Update verfügbar", "update.overlay.updatingVersion": "NetBird wird auf v{version} aktualisiert", "update.overlay.updating": "NetBird wird aktualisiert", diff --git a/client/ui/frontend/src/i18n/locales/en/common.json b/client/ui/frontend/src/i18n/locales/en/common.json index 43dc31b35..fe544bf5e 100644 --- a/client/ui/frontend/src/i18n/locales/en/common.json +++ b/client/ui/frontend/src/i18n/locales/en/common.json @@ -94,6 +94,7 @@ "header.menu.settings": "Settings", "header.menu.defaultView": "Default View", "header.menu.advancedView": "Advanced View", + "header.menu.updateAvailable": "Update Available", "profile.deregister.title": "Deregister Profile", "profile.deregister.message": "Are you sure you want to deregister \"{name}\"? You will need to log in again to use it.", @@ -254,11 +255,11 @@ "update.card.versionAvailableDownload": "Version {version} is available for download.", "update.card.versionAvailableInstall": "Version {version} is available for install.", "update.card.whatsNew": "What's new?", - "update.card.installNow": "Install now", - "update.card.getInstaller": "Download installer", - "update.card.lastChecked": "Last checked on {date}", + "update.card.installNow": "Install Now", + "update.card.getInstaller": "Download", + "update.card.autoCheckInterval": "NetBird checks for updates in the background.", "update.card.changelog": "Changelog", - "update.card.checkForUpdates": "Check for updates", + "update.card.onLatestVersion": "You're on the latest version", "update.header.tooltip": "Update Available", "update.overlay.updatingVersion": "Updating NetBird to v{version}", "update.overlay.updating": "Updating NetBird", diff --git a/client/ui/frontend/src/i18n/locales/hu/common.json b/client/ui/frontend/src/i18n/locales/hu/common.json index b3b740f35..aee139b2d 100644 --- a/client/ui/frontend/src/i18n/locales/hu/common.json +++ b/client/ui/frontend/src/i18n/locales/hu/common.json @@ -234,10 +234,10 @@ "update.card.versionAvailableInstall": "A {version} verzió telepítésre elérhető.", "update.card.whatsNew": "Mi az újdonság?", "update.card.installNow": "Telepítés most", - "update.card.getInstaller": "Telepítő letöltése", - "update.card.lastChecked": "Utolsó ellenőrzés: {date}", + "update.card.getInstaller": "Letöltés", + "update.card.autoCheckInterval": "A NetBird a háttérben keres frissítéseket.", "update.card.changelog": "Változásnapló", - "update.card.checkForUpdates": "Frissítések keresése", + "update.card.onLatestVersion": "A legfrissebb verziót használod", "update.header.tooltip": "Frissítés elérhető", "update.overlay.updatingVersion": "NetBird frissítése a következőre: v{version}", "update.overlay.updating": "NetBird frissítése", diff --git a/client/ui/frontend/src/layouts/Header.tsx b/client/ui/frontend/src/layouts/Header.tsx index 69166eabd..122656d2a 100644 --- a/client/ui/frontend/src/layouts/Header.tsx +++ b/client/ui/frontend/src/layouts/Header.tsx @@ -1,6 +1,7 @@ import { useState } from "react"; import { useTranslation } from "react-i18next"; import { + ArrowUpCircleIcon, Check, MoreVertical, PanelsRightBottom, @@ -19,6 +20,7 @@ import { } from "@/components/DropdownMenu"; import { IconButton } from "@/components/IconButton"; import { ProfileDropdown } from "@/components/ProfileDropdown"; +import { useClientVersion } from "@/modules/auto-update/ClientVersionContext"; import { cn } from "@/lib/cn"; type ViewMode = "default" | "advanced"; @@ -35,12 +37,18 @@ export const Header = () => { const { t } = useTranslation(); const [menuOpen, setMenuOpen] = useState(false); const [viewMode, setViewMode] = useState("default"); + const { updateAvailable } = useClientVersion(); const openSettings = () => { setMenuOpen(false); void WindowManager.OpenSettings("").catch(() => {}); }; + const openAbout = () => { + setMenuOpen(false); + void WindowManager.OpenSettings("about").catch(() => {}); + }; + const openManageProfiles = () => { void WindowManager.OpenSettings("profiles").catch(() => {}); }; @@ -67,39 +75,75 @@ export const Header = () => {
- - - - - - -
- - {t("header.menu.settings")} -
-
- - selectMode("default")} - /> - selectMode("advanced")} - /> -
-
+
+ + + + + + {updateAvailable && ( + <> + +
+ + + {t("header.menu.updateAvailable")} + +
+
+ + + )} + +
+ + {t("header.menu.settings")} +
+
+ + selectMode("default")} + /> + selectMode("advanced")} + /> +
+
+ {updateAvailable && ( + + + + + )} +
); diff --git a/client/ui/frontend/src/modules/auto-update/UpdateAvailableBanner.tsx b/client/ui/frontend/src/modules/auto-update/UpdateAvailableBanner.tsx deleted file mode 100644 index c1baaf74b..000000000 --- a/client/ui/frontend/src/modules/auto-update/UpdateAvailableBanner.tsx +++ /dev/null @@ -1,45 +0,0 @@ -import { useState } from "react"; -import { useTranslation } from "react-i18next"; -import { Button } from "@/components/Button"; -import { useClientVersion } from "@/modules/auto-update/ClientVersionContext"; -import { cn } from "@/lib/cn"; - -// Shown only when management has auto-update enabled (enforced=true) and the -// daemon has not yet started the installer (installing=false). The -// download-only branch (enforced=false) routes the user to GitHub via the -// tray menu instead; the force-install branch (installing=true) takes over -// with the full-screen UpdatingOverlay. -export const UpdateAvailableBanner = () => { - const { t } = useTranslation(); - const { updateVersion, enforced, installing, triggerUpdate } = useClientVersion(); - const [dismissed, setDismissed] = useState(false); - - if (import.meta.env.DEV) return null; - if (!updateVersion || !enforced || installing || dismissed) return null; - - return ( -
-

- {t("update.banner.message", { version: updateVersion })} -

-
- - -
-
- ); -}; - -export default UpdateAvailableBanner; diff --git a/client/ui/frontend/src/modules/auto-update/UpdateHeaderTrigger.tsx b/client/ui/frontend/src/modules/auto-update/UpdateHeaderTrigger.tsx deleted file mode 100644 index bd882bf34..000000000 --- a/client/ui/frontend/src/modules/auto-update/UpdateHeaderTrigger.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import { useNavigate } from "react-router-dom"; -import { useTranslation } from "react-i18next"; -import { ArrowUpCircleIcon } from "lucide-react"; -import { IconButton } from "@/components/IconButton.tsx"; -import { Tooltip } from "@/components/Tooltip.tsx"; -import { useClientVersion } from "@/modules/auto-update/ClientVersionContext"; - -export const UpdateHeaderTrigger = () => { - const { t } = useTranslation(); - const navigate = useNavigate(); - const { updateAvailable } = useClientVersion(); - - if (!updateAvailable) return null; - - return ( - -
- - - navigate("/settings", { state: { tab: "about" } }) - } - className={"absolute inset-0"} - /> -
-
- ); -}; diff --git a/client/ui/frontend/src/modules/auto-update/UpdateVersionCard.tsx b/client/ui/frontend/src/modules/auto-update/UpdateVersionCard.tsx index 0eff79a0f..2b8205de9 100644 --- a/client/ui/frontend/src/modules/auto-update/UpdateVersionCard.tsx +++ b/client/ui/frontend/src/modules/auto-update/UpdateVersionCard.tsx @@ -1,6 +1,7 @@ import { ReactNode } from "react"; import { useTranslation } from "react-i18next"; import { Browser } from "@wailsio/runtime"; +import { DownloadIcon, NotepadText } from "lucide-react"; import { Button } from "@/components/Button"; import { useClientVersion } from "@/modules/auto-update/ClientVersionContext"; import { cn } from "@/lib/cn"; @@ -11,17 +12,8 @@ function openUrl(url: string) { void Browser.OpenURL(url).catch(() => window.open(url, "_blank")); } -function formatLastChecked(date: Date, locale?: string) { - return date.toLocaleString(locale, { - month: "short", - day: "numeric", - hour: "2-digit", - minute: "2-digit", - }); -} - export function UpdateVersionCard() { - const { t, i18n } = useTranslation(); + const { t } = useTranslation(); const { updateVersion, enforced, triggerUpdate } = useClientVersion(); if (updateVersion) { @@ -29,7 +21,7 @@ export function UpdateVersionCard() { ? "update.card.versionAvailableInstall" : "update.card.versionAvailableDownload"; return ( - +
{t(titleKey, { version: updateVersion })} openUrl(GITHUB_RELEASES)} > + {t("update.card.getInstaller")} )} @@ -56,17 +49,14 @@ export function UpdateVersionCard() { } return ( - +
- - {t("update.card.lastChecked", { - date: formatLastChecked(new Date(), i18n.language), - })} - - {t("update.card.changelog")} + {t("update.card.onLatestVersion")} +

{t("update.card.autoCheckInterval")}

-
); @@ -76,7 +66,7 @@ function Card({ children, className }: { children: ReactNode; className?: string return (