+
+
{isUpdateAvailable ? (
) : (
)}
@@ -96,3 +229,5 @@ export const UpdateServer = () => {
);
};
+
+export default UpdateServer;
diff --git a/apps/dokploy/components/dashboard/settings/web-server/update-webserver.tsx b/apps/dokploy/components/dashboard/settings/web-server/update-webserver.tsx
index 47d38310..c1e5de70 100644
--- a/apps/dokploy/components/dashboard/settings/web-server/update-webserver.tsx
+++ b/apps/dokploy/components/dashboard/settings/web-server/update-webserver.tsx
@@ -11,24 +11,53 @@ import {
} from "@/components/ui/alert-dialog";
import { Button } from "@/components/ui/button";
import { api } from "@/utils/api";
+import { HardDriveDownload } from "lucide-react";
import { toast } from "sonner";
-export const UpdateWebServer = () => {
+interface Props {
+ isNavbar?: boolean;
+}
+
+export const UpdateWebServer = ({ isNavbar }: Props) => {
const { mutateAsync: updateServer, isLoading } =
api.settings.updateServer.useMutation();
+
+ const buttonLabel = isNavbar ? "Update available" : "Update Server";
+
+ const handleConfirm = async () => {
+ try {
+ await updateServer();
+ toast.success(
+ "The server has been updated. The page will be reloaded to reflect the changes...",
+ );
+ setTimeout(() => {
+ // Allow seeing the toast before reloading
+ window.location.reload();
+ }, 2000);
+ } catch (error) {
+ console.error("Error updating server:", error);
+ toast.error(
+ "An error occurred while updating the server, please try again.",
+ );
+ }
+ };
+
return (
@@ -36,19 +65,12 @@ export const UpdateWebServer = () => {
Are you absolutely sure?
This action cannot be undone. This will update the web server to the
- new version.
+ new version. The page will be reloaded once the update is finished.
Cancel
- {
- await updateServer();
- toast.success("Please reload the browser to see the changes");
- }}
- >
- Confirm
-
+ Confirm
diff --git a/apps/dokploy/components/layouts/navbar.tsx b/apps/dokploy/components/layouts/navbar.tsx
index cead4683..0e52d701 100644
--- a/apps/dokploy/components/layouts/navbar.tsx
+++ b/apps/dokploy/components/layouts/navbar.tsx
@@ -12,11 +12,16 @@ import { api } from "@/utils/api";
import { HeartIcon } from "lucide-react";
import Link from "next/link";
import { useRouter } from "next/router";
+import { useEffect, useRef, useState } from "react";
+import { UpdateWebServer } from "../dashboard/settings/web-server/update-webserver";
import { Logo } from "../shared/logo";
import { Avatar, AvatarFallback, AvatarImage } from "../ui/avatar";
import { buttonVariants } from "../ui/button";
+const AUTO_CHECK_UPDATES_INTERVAL_MINUTES = 7;
+
export const Navbar = () => {
+ const [isUpdateAvailable, setIsUpdateAvailable] = useState
(false);
const router = useRouter();
const { data } = api.auth.get.useQuery();
const { data: isCloud } = api.settings.isCloud.useQuery();
@@ -29,6 +34,59 @@ export const Navbar = () => {
},
);
const { mutateAsync } = api.auth.logout.useMutation();
+ const { mutateAsync: getUpdateData } =
+ api.settings.getUpdateData.useMutation();
+
+ const checkUpdatesIntervalRef = useRef(null);
+
+ useEffect(() => {
+ // Handling of automatic check for server updates
+ if (isCloud) {
+ return;
+ }
+
+ if (!localStorage.getItem("enableAutoCheckUpdates")) {
+ // Enable auto update checking by default if user didn't change it
+ localStorage.setItem("enableAutoCheckUpdates", "true");
+ }
+
+ const clearUpdatesInterval = () => {
+ if (checkUpdatesIntervalRef.current) {
+ clearInterval(checkUpdatesIntervalRef.current);
+ }
+ };
+
+ const checkUpdates = async () => {
+ try {
+ if (localStorage.getItem("enableAutoCheckUpdates") !== "true") {
+ return;
+ }
+
+ const { updateAvailable } = await getUpdateData();
+
+ if (updateAvailable) {
+ // Stop interval when update is available
+ clearUpdatesInterval();
+ setIsUpdateAvailable(true);
+ }
+ } catch (error) {
+ console.error("Error auto-checking for updates:", error);
+ }
+ };
+
+ checkUpdatesIntervalRef.current = setInterval(
+ checkUpdates,
+ AUTO_CHECK_UPDATES_INTERVAL_MINUTES * 60000,
+ );
+
+ // Also check for updates on initial page load
+ checkUpdates();
+
+ return () => {
+ clearUpdatesInterval();
+ };
+ }, []);
+
return (
+ {isUpdateAvailable && (
+