mirror of
https://github.com/Dokploy/dokploy
synced 2025-06-26 18:27:59 +00:00
add dropdown link
This commit is contained in:
parent
9b255964fe
commit
21ee22d4f5
@ -15,14 +15,18 @@ import { Card, CardFooter, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuGroup,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuLabel,
|
||||
DropdownMenuSeparator,
|
||||
DropdownMenuTrigger,
|
||||
} from "@/components/ui/dropdown-menu";
|
||||
import { api } from "@/utils/api";
|
||||
import {
|
||||
AlertTriangle,
|
||||
BookIcon,
|
||||
CircuitBoard,
|
||||
ExternalLink,
|
||||
ExternalLinkIcon,
|
||||
FolderInput,
|
||||
MoreHorizontalIcon,
|
||||
@ -31,6 +35,7 @@ import {
|
||||
import Link from "next/link";
|
||||
import { toast } from "sonner";
|
||||
import { UpdateProject } from "./update";
|
||||
import { Fragment } from "react";
|
||||
|
||||
export const ShowProjects = () => {
|
||||
const utils = api.useUtils();
|
||||
@ -45,6 +50,7 @@ export const ShowProjects = () => {
|
||||
},
|
||||
);
|
||||
const { mutateAsync } = api.project.remove.useMutation();
|
||||
|
||||
return (
|
||||
<>
|
||||
{data?.length === 0 && (
|
||||
@ -74,17 +80,85 @@ export const ShowProjects = () => {
|
||||
project?.redis.length +
|
||||
project?.applications.length +
|
||||
project?.compose.length;
|
||||
|
||||
const flattedDomains = [
|
||||
...project.applications.flatMap((a) => a.domains),
|
||||
...project.compose.flatMap((a) => a.domains),
|
||||
];
|
||||
|
||||
const renderDomainsDropdown = (
|
||||
item: typeof project.compose | typeof project.applications,
|
||||
) =>
|
||||
item[0] ? (
|
||||
<DropdownMenuGroup>
|
||||
<DropdownMenuLabel>
|
||||
{"applicationId" in item[0] ? "Applications" : "Compose"}
|
||||
</DropdownMenuLabel>
|
||||
{item.map((a) => (
|
||||
<Fragment
|
||||
key={"applicationId" in a ? a.applicationId : a.composeId}
|
||||
>
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuGroup>
|
||||
<DropdownMenuLabel className="font-normal capitalize text-xs ">
|
||||
{a.name}
|
||||
</DropdownMenuLabel>
|
||||
<DropdownMenuSeparator />
|
||||
{a.domains.map((domain) => (
|
||||
<DropdownMenuItem key={domain.domainId} asChild>
|
||||
<Link
|
||||
className="space-x-4 text-xs cursor-pointer justify-between"
|
||||
target="_blank"
|
||||
href={`${domain.https ? "https" : "http"}://${domain.host}${domain.path}`}
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
<span>{domain.host}</span>
|
||||
<ExternalLink className="size-4 shrink-0" />
|
||||
</Link>
|
||||
</DropdownMenuItem>
|
||||
))}
|
||||
</DropdownMenuGroup>
|
||||
</Fragment>
|
||||
))}
|
||||
</DropdownMenuGroup>
|
||||
) : null;
|
||||
|
||||
return (
|
||||
<div key={project.projectId} className="w-full lg:max-w-md">
|
||||
<Link href={`/dashboard/project/${project.projectId}`}>
|
||||
<Card className="group relative w-full bg-transparent transition-colors hover:bg-card">
|
||||
<Button
|
||||
className="absolute -right-3 -top-3 size-9 translate-y-1 rounded-full p-0 opacity-0 transition-all duration-200 group-hover:translate-y-0 group-hover:opacity-100"
|
||||
size="sm"
|
||||
variant="default"
|
||||
>
|
||||
<ExternalLinkIcon className="size-3.5" />
|
||||
</Button>
|
||||
{flattedDomains.length > 1 ? (
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button
|
||||
className="absolute -right-3 -top-3 size-9 translate-y-1 rounded-full p-0 opacity-0 transition-all duration-200 group-hover:translate-y-0 group-hover:opacity-100"
|
||||
size="sm"
|
||||
variant="default"
|
||||
>
|
||||
<ExternalLinkIcon className="size-3.5" />
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent className="w-[200px] space-y-2">
|
||||
{renderDomainsDropdown(project.applications)}
|
||||
{renderDomainsDropdown(project.compose)}
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
) : flattedDomains[0] ? (
|
||||
<Button
|
||||
className="absolute -right-3 -top-3 size-9 translate-y-1 rounded-full p-0 opacity-0 transition-all duration-200 group-hover:translate-y-0 group-hover:opacity-100"
|
||||
size="sm"
|
||||
variant="default"
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
<Link
|
||||
href={`${flattedDomains[0].https ? "https" : "http"}://${flattedDomains[0].host}${flattedDomains[0].path}`}
|
||||
target="_blank"
|
||||
>
|
||||
<ExternalLinkIcon className="size-3.5" />
|
||||
</Link>
|
||||
</Button>
|
||||
) : null}
|
||||
|
||||
<CardHeader>
|
||||
<CardTitle className="flex items-center justify-between gap-2">
|
||||
<span className="flex flex-col gap-1.5">
|
||||
|
@ -125,6 +125,7 @@ export const projectRouter = createTRPCRouter({
|
||||
applications.applicationId,
|
||||
accesedServices,
|
||||
),
|
||||
with: { domains: true },
|
||||
},
|
||||
mariadb: {
|
||||
where: buildServiceFilter(mariadb.mariadbId, accesedServices),
|
||||
@ -143,6 +144,7 @@ export const projectRouter = createTRPCRouter({
|
||||
},
|
||||
compose: {
|
||||
where: buildServiceFilter(compose.composeId, accesedServices),
|
||||
with: { domains: true },
|
||||
},
|
||||
},
|
||||
orderBy: desc(projects.createdAt),
|
||||
@ -153,13 +155,21 @@ export const projectRouter = createTRPCRouter({
|
||||
|
||||
return await db.query.projects.findMany({
|
||||
with: {
|
||||
applications: true,
|
||||
applications: {
|
||||
with: {
|
||||
domains: true,
|
||||
},
|
||||
},
|
||||
mariadb: true,
|
||||
mongo: true,
|
||||
mysql: true,
|
||||
postgres: true,
|
||||
redis: true,
|
||||
compose: true,
|
||||
compose: {
|
||||
with: {
|
||||
domains: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
where: eq(projects.adminId, ctx.user.adminId),
|
||||
orderBy: desc(projects.createdAt),
|
||||
|
Loading…
Reference in New Issue
Block a user