refactor: add environment name links to service components for improved navigation and context clarity

This commit is contained in:
Mauricio Siu
2025-09-01 20:58:22 -06:00
parent 39d48d8bdf
commit e9322fc900
7 changed files with 218 additions and 131 deletions
@@ -100,6 +100,10 @@ const Service = (
name: data?.environment.project.name || "", name: data?.environment.project.name || "",
href: `/dashboard/project/${projectId}`, href: `/dashboard/project/${projectId}`,
}, },
{
name: data?.environment?.name || "",
href: `/dashboard/project/${projectId}/environment/${environmentId}`,
},
{ {
name: data?.name || "", name: data?.name || "",
href: `/dashboard/project/${projectId}/environment/${environmentId}/services/application/${applicationId}`, href: `/dashboard/project/${projectId}/environment/${environmentId}/services/application/${applicationId}`,
@@ -91,6 +91,10 @@ const Service = (
name: data?.environment?.project?.name || "", name: data?.environment?.project?.name || "",
href: `/dashboard/project/${projectId}`, href: `/dashboard/project/${projectId}`,
}, },
{
name: data?.environment?.name || "",
href: `/dashboard/project/${projectId}/environment/${environmentId}`,
},
{ {
name: data?.name || "", name: data?.name || "",
href: `/dashboard/project/${projectId}/environment/${environmentId}/services/compose/${composeId}`, href: `/dashboard/project/${projectId}/environment/${environmentId}/services/compose/${composeId}`,
@@ -72,6 +72,10 @@ const Mariadb = (
name: data?.environment?.project?.name || "", name: data?.environment?.project?.name || "",
href: `/dashboard/project/${projectId}`, href: `/dashboard/project/${projectId}`,
}, },
{
name: data?.environment?.name || "",
href: `/dashboard/project/${projectId}/environment/${environmentId}`,
},
{ {
name: data?.name || "", name: data?.name || "",
href: `/dashboard/project/${projectId}/environment/${environmentId}/services/mariadb/${mariadbId}`, href: `/dashboard/project/${projectId}/environment/${environmentId}/services/mariadb/${mariadbId}`,
@@ -72,6 +72,10 @@ const Mongo = (
name: data?.environment?.project?.name || "", name: data?.environment?.project?.name || "",
href: `/dashboard/project/${projectId}`, href: `/dashboard/project/${projectId}`,
}, },
{
name: data?.environment?.name || "",
href: `/dashboard/project/${projectId}/environment/${environmentId}`,
},
{ {
name: data?.name || "", name: data?.name || "",
href: `/dashboard/project/${projectId}/environment/${environmentId}/services/mongo/${mongoId}`, href: `/dashboard/project/${projectId}/environment/${environmentId}/services/mongo/${mongoId}`,
@@ -71,6 +71,10 @@ const MySql = (
name: data?.environment?.project?.name || "", name: data?.environment?.project?.name || "",
href: `/dashboard/project/${projectId}`, href: `/dashboard/project/${projectId}`,
}, },
{
name: data?.environment?.name || "",
href: `/dashboard/project/${projectId}/environment/${environmentId}`,
},
{ {
name: data?.name || "", name: data?.name || "",
href: `/dashboard/project/${projectId}/environment/${environmentId}/services/mysql/${mysqlId}`, href: `/dashboard/project/${projectId}/environment/${environmentId}/services/mysql/${mysqlId}`,
@@ -71,15 +71,23 @@ const Postgresql = (
name: data?.environment?.project?.name || "", name: data?.environment?.project?.name || "",
href: `/dashboard/project/${projectId}`, href: `/dashboard/project/${projectId}`,
}, },
{
name: data?.environment?.name || "",
href:
`/dashboard/project/${projectId}/environment/${environmentId}`,
},
{ {
name: data?.name || "", name: data?.name || "",
href: `/dashboard/project/${projectId}/environment/${environmentId}/services/postgres/${postgresId}`, href:
`/dashboard/project/${projectId}/environment/${environmentId}/services/postgres/${postgresId}`,
}, },
]} ]}
/> />
<Head> <Head>
<title> <title>
Database: {data?.name} - {data?.environment?.project?.name} | Dokploy Database: {data?.name} - {data?.environment?.project?.name}
{" "}
| Dokploy
</title> </title>
</Head> </Head>
<div className="w-full"> <div className="w-full">
@@ -90,7 +98,9 @@ const Postgresql = (
<CardTitle className="text-xl flex flex-row gap-2"> <CardTitle className="text-xl flex flex-row gap-2">
<div className="relative flex flex-row gap-4"> <div className="relative flex flex-row gap-4">
<div className="absolute -right-1 -top-2"> <div className="absolute -right-1 -top-2">
<StatusTooltip status={data?.applicationStatus} /> <StatusTooltip
status={data?.applicationStatus}
/>
</div> </div>
<PostgresqlIcon className="h-6 w-6 text-muted-foreground" /> <PostgresqlIcon className="h-6 w-6 text-muted-foreground" />
@@ -98,7 +108,9 @@ const Postgresql = (
{data?.name} {data?.name}
</CardTitle> </CardTitle>
{data?.description && ( {data?.description && (
<CardDescription>{data?.description}</CardDescription> <CardDescription>
{data?.description}
</CardDescription>
)} )}
<span className="text-sm text-muted-foreground"> <span className="text-sm text-muted-foreground">
@@ -108,17 +120,17 @@ const Postgresql = (
<div className="flex flex-col h-fit w-fit gap-2"> <div className="flex flex-col h-fit w-fit gap-2">
<div className="flex flex-row h-fit w-fit gap-2"> <div className="flex flex-row h-fit w-fit gap-2">
<Badge <Badge
variant={ variant={!data?.serverId
!data?.serverId ? "default"
? "default" : data?.server?.serverStatus ===
: data?.server?.serverStatus === "active" "active"
? "default" ? "default"
: "destructive" : "destructive"}
}
> >
{data?.server?.name || "Dokploy Server"} {data?.server?.name || "Dokploy Server"}
</Badge> </Badge>
{data?.server?.serverStatus === "inactive" && ( {data?.server?.serverStatus ===
"inactive" && (
<TooltipProvider delayDuration={0}> <TooltipProvider delayDuration={0}>
<Tooltip> <Tooltip>
<TooltipTrigger asChild> <TooltipTrigger asChild>
@@ -132,9 +144,11 @@ const Postgresql = (
side="top" side="top"
> >
<span> <span>
You cannot, deploy this application because the You cannot, deploy this
server is inactive, please upgrade your plan to add application because the
more servers. server is inactive,
please upgrade your plan
to add more servers.
</span> </span>
</TooltipContent> </TooltipContent>
</Tooltip> </Tooltip>
@@ -144,132 +158,178 @@ const Postgresql = (
<div className="flex flex-row gap-2 justify-end"> <div className="flex flex-row gap-2 justify-end">
<UpdatePostgres postgresId={postgresId} /> <UpdatePostgres postgresId={postgresId} />
{(auth?.role === "owner" || auth?.canDeleteServices) && ( {(auth?.role === "owner" ||
<DeleteService id={postgresId} type="postgres" /> auth?.canDeleteServices) && (
<DeleteService
id={postgresId}
type="postgres"
/>
)} )}
</div> </div>
</div> </div>
</CardHeader> </CardHeader>
<CardContent className="space-y-2 py-8 border-t"> <CardContent className="space-y-2 py-8 border-t">
{data?.server?.serverStatus === "inactive" ? ( {data?.server?.serverStatus === "inactive"
<div className="flex h-[55vh] border-2 rounded-xl border-dashed p-4"> ? (
<div className="max-w-3xl mx-auto flex flex-col items-center justify-center self-center gap-3"> <div className="flex h-[55vh] border-2 rounded-xl border-dashed p-4">
<ServerOff className="size-10 text-muted-foreground self-center" /> <div className="max-w-3xl mx-auto flex flex-col items-center justify-center self-center gap-3">
<span className="text-center text-base text-muted-foreground"> <ServerOff className="size-10 text-muted-foreground self-center" />
This service is hosted on the server {data.server.name}, <span className="text-center text-base text-muted-foreground">
but this server has been disabled because your current This service is hosted on the
plan doesn't include enough servers. Please purchase more server{" "}
servers to regain access to this application. {data.server.name}, but this
</span> server has been disabled because
<span className="text-center text-base text-muted-foreground"> your current plan doesn't
Go to{" "} include enough servers. Please
<Link purchase more servers to regain
href="/dashboard/settings/billing" access to this application.
className="text-primary" </span>
> <span className="text-center text-base text-muted-foreground">
Billing Go to{" "}
</Link> <Link
</span> href="/dashboard/settings/billing"
className="text-primary"
>
Billing
</Link>
</span>
</div>
</div> </div>
</div> )
) : ( : (
<Tabs <Tabs
value={tab} value={tab}
defaultValue="general" defaultValue="general"
className="w-full" className="w-full"
onValueChange={(e) => { onValueChange={(e) => {
setSab(e as TabState); setSab(e as TabState);
const newPath = `/dashboard/project/${projectId}/environment/${environmentId}/services/postgres/${postgresId}?tab=${e}`; const newPath =
`/dashboard/project/${projectId}/environment/${environmentId}/services/postgres/${postgresId}?tab=${e}`;
router.push(newPath, undefined, { shallow: true }); router.push(newPath, undefined, {
}} shallow: true,
> });
<div className="flex flex-row items-center justify-between w-full gap-4 overflow-x-scroll"> }}
<TabsList >
className={cn( <div className="flex flex-row items-center justify-between w-full gap-4 overflow-x-scroll">
"md:grid md:w-fit max-md:overflow-y-scroll justify-start", <TabsList
isCloud && data?.serverId className={cn(
? "md:grid-cols-6" "md:grid md:w-fit max-md:overflow-y-scroll justify-start",
: data?.serverId isCloud && data?.serverId
? "md:grid-cols-6"
: data?.serverId
? "md:grid-cols-5" ? "md:grid-cols-5"
: "md:grid-cols-6", : "md:grid-cols-6",
)}
>
<TabsTrigger value="general">General</TabsTrigger>
<TabsTrigger value="environment">Environment</TabsTrigger>
<TabsTrigger value="logs">Logs</TabsTrigger>
{((data?.serverId && isCloud) || !data?.server) && (
<TabsTrigger value="monitoring">Monitoring</TabsTrigger>
)}
<TabsTrigger value="backups">Backups</TabsTrigger>
<TabsTrigger value="advanced">Advanced</TabsTrigger>
</TabsList>
</div>
<TabsContent value="general">
<div className="flex flex-col gap-4 pt-2.5">
<ShowGeneralPostgres postgresId={postgresId} />
<ShowInternalPostgresCredentials
postgresId={postgresId}
/>
<ShowExternalPostgresCredentials
postgresId={postgresId}
/>
</div>
</TabsContent>
<TabsContent value="environment">
<div className="flex flex-col gap-4 pt-2.5">
<ShowEnvironment id={postgresId} type="postgres" />
</div>
</TabsContent>
<TabsContent value="monitoring">
<div className="pt-2.5">
<div className="flex flex-col gap-4 border rounded-lg p-6">
{data?.serverId && isCloud ? (
<ContainerPaidMonitoring
appName={data?.appName || ""}
baseUrl={`${data?.serverId ? `http://${data?.server?.ipAddress}:${data?.server?.metricsConfig?.server?.port}` : "http://localhost:4500"}`}
token={
data?.server?.metricsConfig?.server?.token || ""
}
/>
) : (
<>
<ContainerFreeMonitoring
appName={data?.appName || ""}
/>
</>
)} )}
>
<TabsTrigger value="general">
General
</TabsTrigger>
<TabsTrigger value="environment">
Environment
</TabsTrigger>
<TabsTrigger value="logs">
Logs
</TabsTrigger>
{((data?.serverId && isCloud) ||
!data?.server) && (
<TabsTrigger value="monitoring">
Monitoring
</TabsTrigger>
)}
<TabsTrigger value="backups">
Backups
</TabsTrigger>
<TabsTrigger value="advanced">
Advanced
</TabsTrigger>
</TabsList>
</div>
<TabsContent value="general">
<div className="flex flex-col gap-4 pt-2.5">
<ShowGeneralPostgres
postgresId={postgresId}
/>
<ShowInternalPostgresCredentials
postgresId={postgresId}
/>
<ShowExternalPostgresCredentials
postgresId={postgresId}
/>
</div> </div>
</div> </TabsContent>
</TabsContent> <TabsContent value="environment">
<TabsContent value="logs"> <div className="flex flex-col gap-4 pt-2.5">
<div className="flex flex-col gap-4 pt-2.5"> <ShowEnvironment
<ShowDockerLogs id={postgresId}
serverId={data?.serverId || ""} type="postgres"
appName={data?.appName || ""} />
/> </div>
</div> </TabsContent>
</TabsContent> <TabsContent value="monitoring">
<TabsContent value="backups"> <div className="pt-2.5">
<div className="flex flex-col gap-4 pt-2.5"> <div className="flex flex-col gap-4 border rounded-lg p-6">
<ShowBackups {data?.serverId && isCloud
id={postgresId} ? (
databaseType="postgres" <ContainerPaidMonitoring
backupType="database" appName={data
/> ?.appName ||
</div> ""}
</TabsContent> baseUrl={`${
<TabsContent value="advanced"> data?.serverId
<div className="flex flex-col gap-4 pt-2.5"> ? `http://${data?.server?.ipAddress}:${data?.server?.metricsConfig?.server?.port}`
<ShowDatabaseAdvancedSettings : "http://localhost:4500"
id={postgresId} }`}
type="postgres" token={data
/> ?.server
</div> ?.metricsConfig
</TabsContent> ?.server
</Tabs> ?.token ||
)} ""}
/>
)
: (
<>
<ContainerFreeMonitoring
appName={data
?.appName ||
""}
/>
</>
)}
</div>
</div>
</TabsContent>
<TabsContent value="logs">
<div className="flex flex-col gap-4 pt-2.5">
<ShowDockerLogs
serverId={data?.serverId ||
""}
appName={data?.appName ||
""}
/>
</div>
</TabsContent>
<TabsContent value="backups">
<div className="flex flex-col gap-4 pt-2.5">
<ShowBackups
id={postgresId}
databaseType="postgres"
backupType="database"
/>
</div>
</TabsContent>
<TabsContent value="advanced">
<div className="flex flex-col gap-4 pt-2.5">
<ShowDatabaseAdvancedSettings
id={postgresId}
type="postgres"
/>
</div>
</TabsContent>
</Tabs>
)}
</CardContent> </CardContent>
</div> </div>
</Card> </Card>
@@ -284,7 +344,9 @@ Postgresql.getLayout = (page: ReactElement) => {
}; };
export async function getServerSideProps( export async function getServerSideProps(
ctx: GetServerSidePropsContext<{ postgresId: string; activeTab: TabState; environmentId: string }>, ctx: GetServerSidePropsContext<
{ postgresId: string; activeTab: TabState; environmentId: string }
>,
) { ) {
const { query, params, req, res } = ctx; const { query, params, req, res } = ctx;
const activeTab = query.tab; const activeTab = query.tab;
@@ -71,6 +71,11 @@ const Redis = (
name: data?.environment?.project?.name || "", name: data?.environment?.project?.name || "",
href: `/dashboard/project/${projectId}`, href: `/dashboard/project/${projectId}`,
}, },
{
name: data?.environment?.name || "",
href:
`/dashboard/project/${projectId}/environment/${environmentId}`,
},
{ {
name: data?.name || "", name: data?.name || "",
href: `/dashboard/project/${projectId}/environment/${environmentId}/services/redis/${redisId}`, href: `/dashboard/project/${projectId}/environment/${environmentId}/services/redis/${redisId}`,