mirror of
https://github.com/andwati/dokploy.git
synced 2026-11-10 14:05:18 +00:00
feat: refine home page and fix libsql in bulk actions
- Home: 4 KPI cards (projects, services, deploys/7d, status list), server column with icon in recent deployments, empty state with icon, dashboard card frame to match other pages. - Include libsql in project services count sort. - Fix bulk actions in environment page: libsql was missing from start, stop, move, delete and deploy handlers.
This commit is contained in:
@@ -1,27 +1,31 @@
|
|||||||
import { formatDistanceToNow } from "date-fns";
|
import { formatDistanceToNow } from "date-fns";
|
||||||
import { Plus, Rocket } from "lucide-react";
|
import { ArrowRight, Rocket, Server } from "lucide-react";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { useMemo } from "react";
|
import { useMemo } from "react";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
|
import { Card } from "@/components/ui/card";
|
||||||
import { api } from "@/utils/api";
|
import { api } from "@/utils/api";
|
||||||
|
|
||||||
type DeploymentStatus = "idle" | "running" | "done" | "error";
|
type DeploymentStatus = "idle" | "running" | "done" | "error";
|
||||||
|
|
||||||
const statusDotClass: Record<string, string> = {
|
const statusDotClass: Record<string, string> = {
|
||||||
done: "bg-muted-foreground/60",
|
done: "bg-emerald-500",
|
||||||
running: "bg-amber-500",
|
running: "bg-amber-500",
|
||||||
error: "bg-red-500",
|
error: "bg-red-500",
|
||||||
idle: "bg-muted-foreground/30",
|
idle: "bg-muted-foreground/40",
|
||||||
};
|
};
|
||||||
|
|
||||||
function getServiceInfo(d: any) {
|
function getServiceInfo(d: any) {
|
||||||
const app = d.application;
|
const app = d.application;
|
||||||
const comp = d.compose;
|
const comp = d.compose;
|
||||||
|
const serverName: string =
|
||||||
|
d.server?.name ?? app?.server?.name ?? comp?.server?.name ?? "Dokploy";
|
||||||
if (app?.environment?.project && app.environment) {
|
if (app?.environment?.project && app.environment) {
|
||||||
return {
|
return {
|
||||||
name: app.name as string,
|
name: app.name as string,
|
||||||
environment: app.environment.name as string,
|
environment: app.environment.name as string,
|
||||||
projectName: app.environment.project.name as string,
|
projectName: app.environment.project.name as string,
|
||||||
|
serverName,
|
||||||
href: `/dashboard/project/${app.environment.project.projectId}/environment/${app.environment.environmentId}/services/application/${app.applicationId}`,
|
href: `/dashboard/project/${app.environment.project.projectId}/environment/${app.environment.environmentId}/services/application/${app.applicationId}`,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -30,6 +34,7 @@ function getServiceInfo(d: any) {
|
|||||||
name: comp.name as string,
|
name: comp.name as string,
|
||||||
environment: comp.environment.name as string,
|
environment: comp.environment.name as string,
|
||||||
projectName: comp.environment.project.name as string,
|
projectName: comp.environment.project.name as string,
|
||||||
|
serverName,
|
||||||
href: `/dashboard/project/${comp.environment.project.projectId}/environment/${comp.environment.environmentId}/services/compose/${comp.composeId}`,
|
href: `/dashboard/project/${comp.environment.project.projectId}/environment/${comp.environment.environmentId}/services/compose/${comp.composeId}`,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -46,7 +51,7 @@ function StatCard({
|
|||||||
delta?: string;
|
delta?: string;
|
||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
<div className="rounded-xl border bg-background p-5 min-h-[120px] flex flex-col justify-between">
|
<div className="rounded-xl border bg-background p-5 min-h-[140px] flex flex-col justify-between">
|
||||||
<span className="text-xs uppercase tracking-wider text-muted-foreground">
|
<span className="text-xs uppercase tracking-wider text-muted-foreground">
|
||||||
{label}
|
{label}
|
||||||
</span>
|
</span>
|
||||||
@@ -60,6 +65,34 @@ function StatCard({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function StatusListCard({
|
||||||
|
label,
|
||||||
|
items,
|
||||||
|
}: {
|
||||||
|
label: string;
|
||||||
|
items: { dotClass: string; label: string; count: number }[];
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<div className="rounded-xl border bg-background p-5 min-h-[140px] flex flex-col gap-3">
|
||||||
|
<span className="text-xs uppercase tracking-wider text-muted-foreground">
|
||||||
|
{label}
|
||||||
|
</span>
|
||||||
|
<ul className="flex flex-col gap-1.5">
|
||||||
|
{items.map((item) => (
|
||||||
|
<li key={item.label} className="flex items-center gap-2.5 text-sm">
|
||||||
|
<span
|
||||||
|
className={`size-2 rounded-full shrink-0 ${item.dotClass}`}
|
||||||
|
aria-hidden
|
||||||
|
/>
|
||||||
|
<span className="font-semibold tabular-nums w-8">{item.count}</span>
|
||||||
|
<span className="text-muted-foreground">{item.label}</span>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export const ShowHome = () => {
|
export const ShowHome = () => {
|
||||||
const { data: auth } = api.user.get.useQuery();
|
const { data: auth } = api.user.get.useQuery();
|
||||||
const { data: projects } = api.project.all.useQuery();
|
const { data: projects } = api.project.all.useQuery();
|
||||||
@@ -76,10 +109,12 @@ export const ShowHome = () => {
|
|||||||
|
|
||||||
const firstName = auth?.user?.firstName?.trim();
|
const firstName = auth?.user?.firstName?.trim();
|
||||||
|
|
||||||
const { totals, serverCount } = useMemo(() => {
|
const { totals, statusBreakdown } = useMemo(() => {
|
||||||
let applications = 0;
|
let applications = 0;
|
||||||
let compose = 0;
|
let compose = 0;
|
||||||
let databases = 0;
|
let databases = 0;
|
||||||
|
let environments = 0;
|
||||||
|
const breakdown = { running: 0, error: 0, idle: 0 };
|
||||||
const dbKeys = [
|
const dbKeys = [
|
||||||
"postgres",
|
"postgres",
|
||||||
"mysql",
|
"mysql",
|
||||||
@@ -88,24 +123,37 @@ export const ShowHome = () => {
|
|||||||
"redis",
|
"redis",
|
||||||
"libsql",
|
"libsql",
|
||||||
] as const;
|
] as const;
|
||||||
|
const bump = (status?: string) => {
|
||||||
|
if (status === "done") breakdown.running++;
|
||||||
|
else if (status === "error") breakdown.error++;
|
||||||
|
else breakdown.idle++;
|
||||||
|
};
|
||||||
for (const p of projects ?? []) {
|
for (const p of projects ?? []) {
|
||||||
for (const env of p.environments ?? []) {
|
for (const env of p.environments ?? []) {
|
||||||
|
environments++;
|
||||||
applications += env.applications?.length ?? 0;
|
applications += env.applications?.length ?? 0;
|
||||||
compose += env.compose?.length ?? 0;
|
compose += env.compose?.length ?? 0;
|
||||||
|
for (const a of env.applications ?? []) bump(a.applicationStatus);
|
||||||
|
for (const c of env.compose ?? []) bump((c as any).composeStatus);
|
||||||
for (const key of dbKeys) {
|
for (const key of dbKeys) {
|
||||||
databases += (env as any)[key]?.length ?? 0;
|
const list = ((env as any)[key] ?? []) as Array<{
|
||||||
|
applicationStatus?: string;
|
||||||
|
}>;
|
||||||
|
databases += list.length;
|
||||||
|
for (const s of list) bump(s.applicationStatus);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
totals: {
|
totals: {
|
||||||
projects: projects?.length ?? 0,
|
projects: projects?.length ?? 0,
|
||||||
|
environments,
|
||||||
applications,
|
applications,
|
||||||
compose,
|
compose,
|
||||||
databases,
|
databases,
|
||||||
services: applications + compose + databases,
|
services: applications + compose + databases,
|
||||||
},
|
},
|
||||||
serverCount: servers?.length ?? 0,
|
statusBreakdown: breakdown,
|
||||||
};
|
};
|
||||||
}, [projects, servers]);
|
}, [projects, servers]);
|
||||||
|
|
||||||
@@ -119,101 +167,160 @@ export const ShowHome = () => {
|
|||||||
.slice(0, 10);
|
.slice(0, 10);
|
||||||
}, [deployments]);
|
}, [deployments]);
|
||||||
|
|
||||||
|
const deployStats = useMemo(() => {
|
||||||
|
const now = Date.now();
|
||||||
|
const weekMs = 7 * 24 * 60 * 60 * 1000;
|
||||||
|
const lastStart = now - weekMs;
|
||||||
|
const prevStart = now - 2 * weekMs;
|
||||||
|
|
||||||
|
const last: NonNullable<typeof deployments> = [];
|
||||||
|
const prev: NonNullable<typeof deployments> = [];
|
||||||
|
for (const d of deployments ?? []) {
|
||||||
|
const t = new Date(d.createdAt).getTime();
|
||||||
|
if (t >= lastStart) last.push(d);
|
||||||
|
else if (t >= prevStart) prev.push(d);
|
||||||
|
}
|
||||||
|
|
||||||
|
const lastCount = last.length;
|
||||||
|
const prevCount = prev.length;
|
||||||
|
let delta: string | undefined;
|
||||||
|
if (prevCount > 0) {
|
||||||
|
const pct = Math.round(((lastCount - prevCount) / prevCount) * 100);
|
||||||
|
delta = `${pct >= 0 ? "+" : ""}${pct}% vs prev 7d`;
|
||||||
|
} else if (lastCount > 0) {
|
||||||
|
delta = "no prior data";
|
||||||
|
} else {
|
||||||
|
delta = "no activity yet";
|
||||||
|
}
|
||||||
|
|
||||||
|
return { value: String(lastCount), delta };
|
||||||
|
}, [deployments]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="w-full flex flex-col gap-6">
|
<div className="w-full">
|
||||||
<div className="flex flex-col gap-6 sm:flex-row sm:items-end sm:justify-between">
|
<Card className="h-full bg-sidebar p-2.5 rounded-xl">
|
||||||
<div className="flex flex-col gap-1">
|
<div className="rounded-xl bg-background shadow-md p-6 flex flex-col gap-6">
|
||||||
<h1 className="text-3xl font-semibold tracking-tight">
|
<div className="flex flex-col gap-6 sm:flex-row sm:items-end sm:justify-between">
|
||||||
{firstName ? `Welcome back, ${firstName}` : "Welcome back"}
|
<h1 className="text-3xl font-semibold tracking-tight">
|
||||||
</h1>
|
{firstName ? `Welcome back, ${firstName}` : "Welcome back"}
|
||||||
<p className="text-sm text-muted-foreground">
|
</h1>
|
||||||
{totals.services} services across {serverCount}{" "}
|
<Button asChild variant="secondary" className="w-fit">
|
||||||
{serverCount === 1 ? "server" : "servers"} · {totals.projects}{" "}
|
<Link href="/dashboard/projects">
|
||||||
{totals.projects === 1 ? "project" : "projects"}
|
Go to projects
|
||||||
</p>
|
<ArrowRight className="size-4" />
|
||||||
</div>
|
</Link>
|
||||||
<Button asChild className="w-fit">
|
</Button>
|
||||||
<Link href="/dashboard/projects">
|
</div>
|
||||||
<Plus className="size-4" />
|
|
||||||
New project
|
|
||||||
</Link>
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">
|
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">
|
||||||
<StatCard
|
<StatCard
|
||||||
label="Deploys / 24h"
|
label="Projects"
|
||||||
value={String(recentDeployments.length)}
|
value={String(totals.projects)}
|
||||||
delta="placeholder"
|
delta={`${totals.environments} ${totals.environments === 1 ? "environment" : "environments"}`}
|
||||||
/>
|
/>
|
||||||
<StatCard label="Avg build" value="—" delta="placeholder" />
|
<StatCard
|
||||||
<StatCard label="CPU" value="—" delta="placeholder" />
|
label="Services"
|
||||||
<StatCard label="Memory" value="—" delta="placeholder" />
|
value={String(totals.services)}
|
||||||
</div>
|
delta={`${totals.applications} apps · ${totals.compose} compose · ${totals.databases} db`}
|
||||||
|
/>
|
||||||
|
<StatCard
|
||||||
|
label="Deploys / 7d"
|
||||||
|
value={deployStats.value}
|
||||||
|
delta={deployStats.delta}
|
||||||
|
/>
|
||||||
|
<StatusListCard
|
||||||
|
label="Status"
|
||||||
|
items={[
|
||||||
|
{
|
||||||
|
dotClass: "bg-emerald-500",
|
||||||
|
label: "running",
|
||||||
|
count: statusBreakdown.running,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dotClass: "bg-red-500",
|
||||||
|
label: "errored",
|
||||||
|
count: statusBreakdown.error,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dotClass: "bg-muted-foreground/40",
|
||||||
|
label: "idle",
|
||||||
|
count: statusBreakdown.idle,
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div className="rounded-xl border bg-background">
|
<div className="rounded-xl border bg-background">
|
||||||
<div className="flex items-center justify-between px-5 py-4 border-b">
|
<div className="flex items-center justify-between px-5 py-4 border-b">
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<Rocket className="size-4 text-muted-foreground" />
|
<Rocket className="size-4 text-muted-foreground" />
|
||||||
<h2 className="text-sm font-semibold">Recent deployments</h2>
|
<h2 className="text-sm font-semibold">Recent deployments</h2>
|
||||||
|
</div>
|
||||||
|
{canReadDeployments && (
|
||||||
|
<Link
|
||||||
|
href="/dashboard/deployments"
|
||||||
|
className="text-xs text-muted-foreground hover:text-foreground transition-colors"
|
||||||
|
>
|
||||||
|
view all →
|
||||||
|
</Link>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
{!canReadDeployments ? (
|
||||||
|
<div className="min-h-[400px] flex flex-col items-center justify-center gap-3 text-center text-sm text-muted-foreground p-10">
|
||||||
|
<Rocket className="size-8 opacity-40" />
|
||||||
|
<span>You do not have permission to view deployments.</span>
|
||||||
|
</div>
|
||||||
|
) : recentDeployments.length === 0 ? (
|
||||||
|
<div className="min-h-[400px] flex flex-col items-center justify-center gap-3 text-center text-sm text-muted-foreground p-10">
|
||||||
|
<Rocket className="size-8 opacity-40" />
|
||||||
|
<span>No deployments yet.</span>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<ul className="divide-y">
|
||||||
|
{recentDeployments.map((d) => {
|
||||||
|
const info = getServiceInfo(d);
|
||||||
|
if (!info) return null;
|
||||||
|
const status = (d.status ?? "idle") as DeploymentStatus;
|
||||||
|
return (
|
||||||
|
<li key={d.deploymentId}>
|
||||||
|
<Link
|
||||||
|
href={info.href}
|
||||||
|
className="flex items-center gap-4 px-5 py-4 hover:bg-muted/40 transition-colors"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
className={`size-2 rounded-full shrink-0 ${statusDotClass[status] ?? statusDotClass.idle}`}
|
||||||
|
aria-hidden
|
||||||
|
/>
|
||||||
|
<div className="flex flex-col min-w-0 flex-1">
|
||||||
|
<span className="text-sm truncate">{info.name}</span>
|
||||||
|
<span className="text-xs text-muted-foreground truncate">
|
||||||
|
{info.projectName} · {info.environment}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<span className="text-xs text-muted-foreground w-36 hidden lg:flex items-center justify-end gap-1.5 truncate">
|
||||||
|
<Server className="size-3 shrink-0" />
|
||||||
|
<span className="truncate">{info.serverName}</span>
|
||||||
|
</span>
|
||||||
|
<span className="text-xs text-muted-foreground w-20 text-right hidden sm:inline">
|
||||||
|
{status}
|
||||||
|
</span>
|
||||||
|
<span className="text-xs text-muted-foreground w-24 text-right hidden md:inline">
|
||||||
|
{formatDistanceToNow(new Date(d.createdAt), {
|
||||||
|
addSuffix: true,
|
||||||
|
})}
|
||||||
|
</span>
|
||||||
|
<span className="text-xs text-muted-foreground hover:text-foreground transition-colors">
|
||||||
|
logs →
|
||||||
|
</span>
|
||||||
|
</Link>
|
||||||
|
</li>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</ul>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
{canReadDeployments && (
|
|
||||||
<Link
|
|
||||||
href="/dashboard/deployments"
|
|
||||||
className="text-xs text-muted-foreground hover:text-foreground transition-colors"
|
|
||||||
>
|
|
||||||
view all →
|
|
||||||
</Link>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
{!canReadDeployments ? (
|
</Card>
|
||||||
<div className="p-10 text-center text-sm text-muted-foreground">
|
|
||||||
You do not have permission to view deployments.
|
|
||||||
</div>
|
|
||||||
) : recentDeployments.length === 0 ? (
|
|
||||||
<div className="p-10 text-center text-sm text-muted-foreground">
|
|
||||||
No deployments yet.
|
|
||||||
</div>
|
|
||||||
) : (
|
|
||||||
<ul className="divide-y">
|
|
||||||
{recentDeployments.map((d) => {
|
|
||||||
const info = getServiceInfo(d);
|
|
||||||
if (!info) return null;
|
|
||||||
const status = (d.status ?? "idle") as DeploymentStatus;
|
|
||||||
return (
|
|
||||||
<li key={d.deploymentId}>
|
|
||||||
<Link
|
|
||||||
href={info.href}
|
|
||||||
className="flex items-center gap-4 px-5 py-4 hover:bg-muted/40 transition-colors"
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
className={`size-2 rounded-full shrink-0 ${statusDotClass[status] ?? statusDotClass.idle}`}
|
|
||||||
aria-hidden
|
|
||||||
/>
|
|
||||||
<div className="flex flex-col min-w-0 flex-1">
|
|
||||||
<span className="text-sm truncate">{info.name}</span>
|
|
||||||
<span className="text-xs text-muted-foreground truncate">
|
|
||||||
{info.projectName} · {info.environment}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<span className="text-xs text-muted-foreground w-20 text-right hidden sm:inline">
|
|
||||||
{status}
|
|
||||||
</span>
|
|
||||||
<span className="text-xs text-muted-foreground w-24 text-right hidden md:inline">
|
|
||||||
{formatDistanceToNow(new Date(d.createdAt), {
|
|
||||||
addSuffix: true,
|
|
||||||
})}
|
|
||||||
</span>
|
|
||||||
<span className="text-xs text-muted-foreground hover:text-foreground transition-colors">
|
|
||||||
logs →
|
|
||||||
</span>
|
|
||||||
</Link>
|
|
||||||
</li>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</ul>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -166,6 +166,7 @@ export const ShowProjects = () => {
|
|||||||
return (
|
return (
|
||||||
total +
|
total +
|
||||||
(env.applications?.length || 0) +
|
(env.applications?.length || 0) +
|
||||||
|
(env.libsql?.length || 0) +
|
||||||
(env.mariadb?.length || 0) +
|
(env.mariadb?.length || 0) +
|
||||||
(env.mongo?.length || 0) +
|
(env.mongo?.length || 0) +
|
||||||
(env.mysql?.length || 0) +
|
(env.mysql?.length || 0) +
|
||||||
@@ -178,6 +179,7 @@ export const ShowProjects = () => {
|
|||||||
return (
|
return (
|
||||||
total +
|
total +
|
||||||
(env.applications?.length || 0) +
|
(env.applications?.length || 0) +
|
||||||
|
(env.libsql?.length || 0) +
|
||||||
(env.mariadb?.length || 0) +
|
(env.mariadb?.length || 0) +
|
||||||
(env.mongo?.length || 0) +
|
(env.mongo?.length || 0) +
|
||||||
(env.mysql?.length || 0) +
|
(env.mysql?.length || 0) +
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ import { AddTemplate } from "@/components/dashboard/project/add-template";
|
|||||||
import { AdvancedEnvironmentSelector } from "@/components/dashboard/project/advanced-environment-selector";
|
import { AdvancedEnvironmentSelector } from "@/components/dashboard/project/advanced-environment-selector";
|
||||||
import { DuplicateProject } from "@/components/dashboard/project/duplicate-project";
|
import { DuplicateProject } from "@/components/dashboard/project/duplicate-project";
|
||||||
import { EnvironmentVariables } from "@/components/dashboard/project/environment-variables";
|
import { EnvironmentVariables } from "@/components/dashboard/project/environment-variables";
|
||||||
import { ProjectEnvironment } from "@/components/dashboard/home/project-environment";
|
import { ProjectEnvironment } from "@/components/dashboard/projects/project-environment";
|
||||||
import {
|
import {
|
||||||
LibsqlIcon,
|
LibsqlIcon,
|
||||||
MariadbIcon,
|
MariadbIcon,
|
||||||
@@ -509,6 +509,14 @@ const EnvironmentPage = (
|
|||||||
deploy: api.mongo.deploy.useMutation(),
|
deploy: api.mongo.deploy.useMutation(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const libsqlActions = {
|
||||||
|
start: api.libsql.start.useMutation(),
|
||||||
|
stop: api.libsql.stop.useMutation(),
|
||||||
|
move: api.libsql.move.useMutation(),
|
||||||
|
delete: api.libsql.remove.useMutation(),
|
||||||
|
deploy: api.libsql.deploy.useMutation(),
|
||||||
|
};
|
||||||
|
|
||||||
const handleBulkStart = async () => {
|
const handleBulkStart = async () => {
|
||||||
let success = 0;
|
let success = 0;
|
||||||
setIsBulkActionLoading(true);
|
setIsBulkActionLoading(true);
|
||||||
@@ -541,6 +549,9 @@ const EnvironmentPage = (
|
|||||||
case "mongo":
|
case "mongo":
|
||||||
await mongoActions.start.mutateAsync({ mongoId: serviceId });
|
await mongoActions.start.mutateAsync({ mongoId: serviceId });
|
||||||
break;
|
break;
|
||||||
|
case "libsql":
|
||||||
|
await libsqlActions.start.mutateAsync({ libsqlId: serviceId });
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
success++;
|
success++;
|
||||||
} catch {
|
} catch {
|
||||||
@@ -588,6 +599,9 @@ const EnvironmentPage = (
|
|||||||
case "mongo":
|
case "mongo":
|
||||||
await mongoActions.stop.mutateAsync({ mongoId: serviceId });
|
await mongoActions.stop.mutateAsync({ mongoId: serviceId });
|
||||||
break;
|
break;
|
||||||
|
case "libsql":
|
||||||
|
await libsqlActions.stop.mutateAsync({ libsqlId: serviceId });
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
success++;
|
success++;
|
||||||
} catch {
|
} catch {
|
||||||
@@ -664,6 +678,12 @@ const EnvironmentPage = (
|
|||||||
targetEnvironmentId: selectedTargetEnvironment,
|
targetEnvironmentId: selectedTargetEnvironment,
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
|
case "libsql":
|
||||||
|
await libsqlActions.move.mutateAsync({
|
||||||
|
libsqlId: serviceId,
|
||||||
|
targetEnvironmentId: selectedTargetEnvironment,
|
||||||
|
});
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
await utils.environment.one.invalidate({
|
await utils.environment.one.invalidate({
|
||||||
environmentId,
|
environmentId,
|
||||||
@@ -733,6 +753,11 @@ const EnvironmentPage = (
|
|||||||
mongoId: serviceId,
|
mongoId: serviceId,
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
|
case "libsql":
|
||||||
|
await libsqlActions.delete.mutateAsync({
|
||||||
|
libsqlId: serviceId,
|
||||||
|
});
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
await utils.environment.one.invalidate({
|
await utils.environment.one.invalidate({
|
||||||
environmentId,
|
environmentId,
|
||||||
@@ -799,6 +824,11 @@ const EnvironmentPage = (
|
|||||||
mongoId: serviceId,
|
mongoId: serviceId,
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
|
case "libsql":
|
||||||
|
await libsqlActions.deploy.mutateAsync({
|
||||||
|
libsqlId: serviceId,
|
||||||
|
});
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
success++;
|
success++;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
Reference in New Issue
Block a user