diff --git a/apps/dokploy/components/layouts/navigation-tabs.tsx b/apps/dokploy/components/layouts/navigation-tabs.tsx index ab3dafcaa..c9392b10e 100644 --- a/apps/dokploy/components/layouts/navigation-tabs.tsx +++ b/apps/dokploy/components/layouts/navigation-tabs.tsx @@ -7,166 +7,176 @@ import { useEffect, useMemo, useState } from "react"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "../ui/tabs"; interface TabInfo { - label: string; - tabLabel?: string; - description: string; - index: string; - type: TabState; - isShow?: ({ rol, user }: { rol?: Auth["rol"]; user?: User }) => boolean; + label: string; + tabLabel?: string; + description: string; + index: string; + type: TabState; + isShow?: ({ rol, user }: { rol?: Auth["rol"]; user?: User }) => boolean; } export type TabState = - | "projects" - | "monitoring" - | "settings" - | "traefik" - | "requests" - | "docker"; + | "projects" + | "monitoring" + | "settings" + | "traefik" + | "requests" + | "docker" + | "swarm"; const getTabMaps = (isCloud: boolean) => { - const elements: TabInfo[] = [ - { - label: "Projects", - description: "Manage your projects", - index: "/dashboard/projects", - type: "projects", - }, - ]; + const elements: TabInfo[] = [ + { + label: "Projects", + description: "Manage your projects", + index: "/dashboard/projects", + type: "projects", + }, + ]; - if (!isCloud) { - elements.push( - { - label: "Monitoring", - description: "Monitor your projects", - index: "/dashboard/monitoring", - type: "monitoring", - }, - { - label: "Traefik", - tabLabel: "Traefik File System", - description: "Manage your traefik", - index: "/dashboard/traefik", - isShow: ({ rol, user }) => { - return Boolean(rol === "admin" || user?.canAccessToTraefikFiles); - }, - type: "traefik", - }, - { - label: "Docker", - description: "Manage your docker", - index: "/dashboard/docker", - isShow: ({ rol, user }) => { - return Boolean(rol === "admin" || user?.canAccessToDocker); - }, - type: "docker", - }, - { - label: "Requests", - description: "Manage your requests", - index: "/dashboard/requests", - isShow: ({ rol, user }) => { - return Boolean(rol === "admin" || user?.canAccessToDocker); - }, - type: "requests", - }, - ); - } + if (!isCloud) { + elements.push( + { + label: "Monitoring", + description: "Monitor your projects", + index: "/dashboard/monitoring", + type: "monitoring", + }, + { + label: "Traefik", + tabLabel: "Traefik File System", + description: "Manage your traefik", + index: "/dashboard/traefik", + isShow: ({ rol, user }) => { + return Boolean(rol === "admin" || user?.canAccessToTraefikFiles); + }, + type: "traefik", + }, + { + label: "Docker", + description: "Manage your docker", + index: "/dashboard/docker", + isShow: ({ rol, user }) => { + return Boolean(rol === "admin" || user?.canAccessToDocker); + }, + type: "docker", + }, + { + label: "Swarm", + description: "Manage your docker swarm", + index: "/dashboard/swarm", + isShow: ({ rol, user }) => { + return Boolean(rol === "admin" || user?.canAccessToDocker); + }, + type: "swarm", + }, + { + label: "Requests", + description: "Manage your requests", + index: "/dashboard/requests", + isShow: ({ rol, user }) => { + return Boolean(rol === "admin" || user?.canAccessToDocker); + }, + type: "requests", + } + ); + } - elements.push({ - label: "Settings", - description: "Manage your settings", - type: "settings", - index: isCloud - ? "/dashboard/settings/profile" - : "/dashboard/settings/server", - }); + elements.push({ + label: "Settings", + description: "Manage your settings", + type: "settings", + index: isCloud + ? "/dashboard/settings/profile" + : "/dashboard/settings/server", + }); - return elements; + return elements; }; interface Props { - tab: TabState; - children: React.ReactNode; + tab: TabState; + children: React.ReactNode; } export const NavigationTabs = ({ tab, children }: Props) => { - const router = useRouter(); - const { data } = api.auth.get.useQuery(); - const [activeTab, setActiveTab] = useState(tab); - const { data: isCloud } = api.settings.isCloud.useQuery(); - const tabMap = useMemo(() => getTabMaps(isCloud ?? false), [isCloud]); - const { data: user } = api.user.byAuthId.useQuery( - { - authId: data?.id || "", - }, - { - enabled: !!data?.id && data?.rol === "user", - }, - ); + const router = useRouter(); + const { data } = api.auth.get.useQuery(); + const [activeTab, setActiveTab] = useState(tab); + const { data: isCloud } = api.settings.isCloud.useQuery(); + const tabMap = useMemo(() => getTabMaps(isCloud ?? false), [isCloud]); + const { data: user } = api.user.byAuthId.useQuery( + { + authId: data?.id || "", + }, + { + enabled: !!data?.id && data?.rol === "user", + } + ); - useEffect(() => { - setActiveTab(tab); - }, [tab]); + useEffect(() => { + setActiveTab(tab); + }, [tab]); - const activeTabInfo = useMemo(() => { - return tabMap.find((tab) => tab.type === activeTab); - }, [activeTab]); + const activeTabInfo = useMemo(() => { + return tabMap.find((tab) => tab.type === activeTab); + }, [activeTab]); - return ( -
-
-
-

- {activeTabInfo?.label} -

-

- {activeTabInfo?.description} -

-
- {tab === "projects" && - (data?.rol === "admin" || user?.canCreateProjects) && } -
-
- { - setActiveTab(e as TabState); - const tab = tabMap.find((tab) => tab.type === e); - router.push(tab?.index || ""); - }} - > -
- - {tabMap.map((tab, index) => { - if (tab?.isShow && !tab?.isShow?.({ rol: data?.rol, user })) { - return null; - } - return ( - - - {tab?.tabLabel || tab?.label} - - {tab.type === activeTab && ( -
-
-
- )} - - ); - })} - -
+ return ( +
+
+
+

+ {activeTabInfo?.label} +

+

+ {activeTabInfo?.description} +

+
+ {tab === "projects" && + (data?.rol === "admin" || user?.canCreateProjects) && } +
+
+ { + setActiveTab(e as TabState); + const tab = tabMap.find((tab) => tab.type === e); + router.push(tab?.index || ""); + }} + > +
+ + {tabMap.map((tab, index) => { + if (tab?.isShow && !tab?.isShow?.({ rol: data?.rol, user })) { + return null; + } + return ( + + + {tab?.tabLabel || tab?.label} + + {tab.type === activeTab && ( +
+
+
+ )} + + ); + })} + +
- - {children} - - -
-
- ); + + {children} + + +
+
+ ); }; diff --git a/apps/dokploy/pages/dashboard/swarm.tsx b/apps/dokploy/pages/dashboard/swarm.tsx new file mode 100644 index 000000000..d353ceedd --- /dev/null +++ b/apps/dokploy/pages/dashboard/swarm.tsx @@ -0,0 +1,81 @@ +import { ShowSwarm } from "@/components/dashboard/swarm/show/node-list"; +import ShowSwarmNodes from "@/components/dashboard/swarm/show/show-nodes"; +import { DashboardLayout } from "@/components/layouts/dashboard-layout"; +import { appRouter } from "@/server/api/root"; +import { IS_CLOUD, validateRequest } from "@dokploy/server"; +import { createServerSideHelpers } from "@trpc/react-query/server"; +import type { GetServerSidePropsContext } from "next"; +import React, { type ReactElement } from "react"; +import superjson from "superjson"; + +const Dashboard = () => { + return ; +}; + +export default Dashboard; + +Dashboard.getLayout = (page: ReactElement) => { + return {page}; +}; +export async function getServerSideProps( + ctx: GetServerSidePropsContext<{ serviceId: string }> +) { + if (IS_CLOUD) { + return { + redirect: { + permanent: true, + destination: "/dashboard/projects", + }, + }; + } + const { user, session } = await validateRequest(ctx.req, ctx.res); + if (!user) { + return { + redirect: { + permanent: true, + destination: "/", + }, + }; + } + const { req, res } = ctx; + + const helpers = createServerSideHelpers({ + router: appRouter, + ctx: { + req: req as any, + res: res as any, + db: null as any, + session: session, + user: user, + }, + transformer: superjson, + }); + try { + await helpers.project.all.prefetch(); + const auth = await helpers.auth.get.fetch(); + + if (auth.rol === "user") { + const user = await helpers.user.byAuthId.fetch({ + authId: auth.id, + }); + + if (!user.canAccessToDocker) { + return { + redirect: { + permanent: true, + destination: "/", + }, + }; + } + } + return { + props: { + trpcState: helpers.dehydrate(), + }, + }; + } catch (error) { + return { + props: {}, + }; + } +}