mirror of
https://github.com/andwati/dokploy.git
synced 2026-10-29 00:02:16 +00:00
feat: move deployments into an overview page tab
This commit is contained in:
@@ -223,7 +223,7 @@ export const ShowHome = () => {
|
||||
</div>
|
||||
{canReadDeployments && (
|
||||
<Link
|
||||
href="/dashboard/deployments"
|
||||
href="/dashboard/overview?tab=deployments"
|
||||
className="text-xs text-muted-foreground hover:text-foreground transition-colors"
|
||||
>
|
||||
view all →
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
import { Rocket } from "lucide-react";
|
||||
import { useRouter } from "next/router";
|
||||
import { ShowDeploymentsTable } from "@/components/dashboard/deployments/show-deployments-table";
|
||||
import { ShowQueueTable } from "@/components/dashboard/deployments/show-queue-table";
|
||||
import {
|
||||
Card,
|
||||
CardDescription,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
} from "@/components/ui/card";
|
||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
||||
|
||||
const SUBTAB_VALUES = ["deployments", "queue"] as const;
|
||||
type SubtabValue = (typeof SUBTAB_VALUES)[number];
|
||||
const DEFAULT_SUBTAB: SubtabValue = "deployments";
|
||||
|
||||
function isValidSubtab(t: string): t is SubtabValue {
|
||||
return SUBTAB_VALUES.includes(t as SubtabValue);
|
||||
}
|
||||
|
||||
export const ShowOverviewDeployments = () => {
|
||||
const router = useRouter();
|
||||
const subtab =
|
||||
typeof router.query.subtab === "string" &&
|
||||
isValidSubtab(router.query.subtab)
|
||||
? router.query.subtab
|
||||
: DEFAULT_SUBTAB;
|
||||
|
||||
const setSubtab = (value: string) => {
|
||||
if (!isValidSubtab(value)) return;
|
||||
const { subtab: _current, ...query } = router.query;
|
||||
router.replace(
|
||||
{
|
||||
pathname: router.pathname,
|
||||
query: value === DEFAULT_SUBTAB ? query : { ...query, subtab: value },
|
||||
},
|
||||
undefined,
|
||||
{ shallow: true },
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<Card className="h-full bg-sidebar p-2.5 rounded-xl min-h-[45vh]">
|
||||
<div className="rounded-xl bg-background shadow-md h-full">
|
||||
<CardHeader>
|
||||
<div className="flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between">
|
||||
<div>
|
||||
<CardTitle className="text-xl font-bold flex items-center gap-2">
|
||||
<Rocket className="size-5" />
|
||||
Deployments
|
||||
</CardTitle>
|
||||
<CardDescription>
|
||||
All application and compose deployments in one place.
|
||||
</CardDescription>
|
||||
</div>
|
||||
</div>
|
||||
<Tabs
|
||||
value={subtab}
|
||||
onValueChange={setSubtab}
|
||||
className="w-full min-w-0"
|
||||
>
|
||||
<TabsList className="mt-2">
|
||||
<TabsTrigger value="deployments">Deployments</TabsTrigger>
|
||||
<TabsTrigger value="queue">Queue</TabsTrigger>
|
||||
</TabsList>
|
||||
<TabsContent value="deployments" className="mt-0 min-w-0 pt-4">
|
||||
<ShowDeploymentsTable />
|
||||
</TabsContent>
|
||||
<TabsContent value="queue" className="mt-0 pt-4">
|
||||
<ShowQueueTable />
|
||||
</TabsContent>
|
||||
</Tabs>
|
||||
</CardHeader>
|
||||
</div>
|
||||
</Card>
|
||||
);
|
||||
};
|
||||
@@ -4,6 +4,7 @@ import { ExternalLink, Loader2 } from "lucide-react";
|
||||
import Link from "next/link";
|
||||
import { useMemo, useState } from "react";
|
||||
import { toast } from "sonner";
|
||||
import { COMPOSE_REDEPLOY_TOAST } from "@/components/dashboard/application/domains/redeploy-hint";
|
||||
import { DateTooltip } from "@/components/shared/date-tooltip";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { Button } from "@/components/ui/button";
|
||||
@@ -71,7 +72,12 @@ export const ShowOverviewDomains = () => {
|
||||
try {
|
||||
const result = await toggleEnable({ domainId: domain.domainId });
|
||||
utils.overview.domains.invalidate();
|
||||
toast.success(result.enabled ? "Domain enabled" : "Domain disabled");
|
||||
toast.success(
|
||||
result.enabled ? "Domain enabled" : "Domain disabled",
|
||||
result.requiresRedeploy
|
||||
? { description: COMPOSE_REDEPLOY_TOAST }
|
||||
: undefined,
|
||||
);
|
||||
} catch {
|
||||
toast.error(`Error updating "${domain.host}"`);
|
||||
}
|
||||
|
||||
@@ -175,7 +175,7 @@ export const SearchCommand = () => {
|
||||
</CommandItem>
|
||||
<CommandItem
|
||||
onSelect={() => {
|
||||
router.push("/dashboard/deployments");
|
||||
router.push("/dashboard/overview?tab=deployments");
|
||||
setOpen(false);
|
||||
}}
|
||||
>
|
||||
|
||||
@@ -29,7 +29,6 @@ import {
|
||||
type LucideIcon,
|
||||
Package,
|
||||
Palette,
|
||||
Rocket,
|
||||
Server,
|
||||
ShieldCheck,
|
||||
Smartphone,
|
||||
@@ -179,10 +178,11 @@ const MENU: Menu = {
|
||||
},
|
||||
{
|
||||
isSingle: true,
|
||||
title: "Deployments",
|
||||
url: "/dashboard/deployments",
|
||||
icon: Rocket,
|
||||
isEnabled: ({ permissions }) => !!permissions?.deployment.read,
|
||||
title: "Overview",
|
||||
url: "/dashboard/overview",
|
||||
icon: LayoutGrid,
|
||||
// Only enabled for users with access to services
|
||||
isEnabled: ({ permissions }) => !!permissions?.service.read,
|
||||
},
|
||||
{
|
||||
isSingle: true,
|
||||
@@ -216,14 +216,6 @@ const MENU: Menu = {
|
||||
// Only enabled for users with access to Docker
|
||||
isEnabled: ({ permissions }) => !!permissions?.docker.read,
|
||||
},
|
||||
{
|
||||
isSingle: true,
|
||||
title: "Overview",
|
||||
url: "/dashboard/overview",
|
||||
icon: LayoutGrid,
|
||||
// Only enabled for users with access to services
|
||||
isEnabled: ({ permissions }) => !!permissions?.service.read,
|
||||
},
|
||||
{
|
||||
isSingle: true,
|
||||
title: "Requests",
|
||||
|
||||
Reference in New Issue
Block a user