diff --git a/apps/dokploy/components/dashboard/project/add-template.tsx b/apps/dokploy/components/dashboard/project/add-template.tsx index 52008d9e7..068fc984d 100644 --- a/apps/dokploy/components/dashboard/project/add-template.tsx +++ b/apps/dokploy/components/dashboard/project/add-template.tsx @@ -35,6 +35,7 @@ import { PopoverContent, PopoverTrigger, } from "@/components/ui/popover"; +import { ScrollArea } from "@/components/ui/scroll-area"; import { Select, SelectContent, @@ -52,7 +53,6 @@ import { } from "@/components/ui/tooltip"; import { cn } from "@/lib/utils"; import { api } from "@/utils/api"; -import { ScrollArea } from "@radix-ui/react-scroll-area"; import { BookText, CheckIcon, @@ -61,12 +61,15 @@ import { Github, Globe, HelpCircle, + LayoutGrid, + List, PuzzleIcon, SearchIcon, } from "lucide-react"; import Link from "next/link"; import { useState } from "react"; import { toast } from "sonner"; + interface Props { projectId: string; } @@ -74,8 +77,9 @@ interface Props { export const AddTemplate = ({ projectId }: Props) => { const [query, setQuery] = useState(""); const [open, setOpen] = useState(false); - const { data } = api.compose.templates.useQuery(); + const [viewMode, setViewMode] = useState<"detailed" | "icon">("detailed"); const [selectedTags, setSelectedTags] = useState([]); + const { data } = api.compose.templates.useQuery(); const { data: servers } = api.server.withSSHKey.useQuery(); const { data: tags, isLoading: isLoadingTags } = api.compose.getTags.useQuery(); @@ -108,279 +112,340 @@ export const AddTemplate = ({ projectId }: Props) => { Template - -
- - Create from Template - - Create an open source application from a template - - - {isError && {error?.message}} -
- setQuery(e.target.value)} - className="w-full" - value={query} - /> - - - - - - - - {isLoadingTags && ( - - Loading Tags.... - + + + + + + + {isLoadingTags && ( + + Loading Tags.... + + )} + No tags found. + + + {tags?.map((tag) => ( + { + if (selectedTags.includes(tag)) { + setSelectedTags( + selectedTags.filter((t) => t !== tag), + ); + return; + } + setSelectedTags([...selectedTags, tag]); + }} + > + {tag} + + + ))} + + + + + +
-
-
- {templates.length === 0 ? ( -
- -
- No templates found +
- ) : ( -
- {templates?.map((template, index) => ( -
-
0 && ( +
+ {selectedTags.map((tag) => ( + + setSelectedTags(selectedTags.filter((t) => t !== tag)) + } > -
+ {tag} × + + ))} +
+ )} +
+ + + +
+ {isError && {error?.message}} + + {templates.length === 0 ? ( +
+ +
+ No templates found +
+
+ ) : ( +
+ {templates?.map((template, index) => ( +
+ + {template.version} + + {/* Template Header */} +
+ {template.name}
- -
- -
-
-
-
- - {template.name} - - {template.version} -
- -
- - - - {template.links.website && ( - - - - )} - {template.links.docs && ( - - - - )} - - - -
-
+ + {template.name} + + {viewMode === "detailed" && + template.tags.length > 0 && ( +
{template.tags.map((tag) => ( - + {tag} ))}
-
- - - - - - - - - Are you absolutely sure? - - - This will create an application from the{" "} - {template.name} template and add it to your - project. - - -
- - - - - - - - If ot server is selected, the - application will be deployed on the - server where the user is logged in. - - - - - - -
-
- - Cancel - { - const promise = mutateAsync({ - projectId, - serverId: serverId || undefined, - id: template.id, - }); - toast.promise(promise, { - loading: "Setting up...", - success: (data) => { - utils.project.one.invalidate({ - projectId, - }); - setOpen(false); - return `${template.name} template created successfully`; - }, - error: (err) => { - return `An error ocurred deploying ${template.name} template`; - }, - }); - }} - > - Confirm - - -
-
-
- -

- {template.description} -

+ )}
+ + {/* Template Content */} + {viewMode === "detailed" && ( + +
+ {template.description} +
+
+ )} + + {/* Create Button */} +
+ {viewMode === "detailed" && ( +
+ + + + {template.links.website && ( + + + + )} + {template.links.docs && ( + + + + )} +
+ )} + + + + + + + + Are you absolutely sure? + + + This will create an application from the{" "} + {template.name} template and add it to your + project. + + +
+ + + + + + + + If ot server is selected, the application + will be deployed on the server where the + user is logged in. + + + + + + +
+
+ + Cancel + { + const promise = mutateAsync({ + projectId, + serverId: serverId || undefined, + id: template.id, + }); + toast.promise(promise, { + loading: "Setting up...", + success: (data) => { + utils.project.one.invalidate({ + projectId, + }); + setOpen(false); + return `${template.name} template created successfully`; + }, + error: (err) => { + return `An error ocurred deploying ${template.name} template`; + }, + }); + }} + > + Confirm + + +
+
+
-
- ))} -
- )} -
+ ))} +
+ )} +
+ );