Skip to content

Commit

Permalink
Merge branch 'canary' into canary
Browse files Browse the repository at this point in the history
  • Loading branch information
Siumauricio authored Jan 26, 2025
2 parents 8769714 + 074e3b6 commit b961032
Show file tree
Hide file tree
Showing 11 changed files with 284 additions and 19 deletions.
2 changes: 1 addition & 1 deletion apps/dokploy/components/dashboard/project/add-template.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,7 @@ export const AddTemplate = ({ projectId }: Props) => {
{/* Create Button */}
<div
className={cn(
"flex-none px-6 pb-6 pt-3 mt-auto",
"flex-none px-6 py-3 mt-auto",
viewMode === "detailed"
? "flex items-center justify-between bg-muted/30 border-t"
: "flex justify-center",
Expand Down
100 changes: 91 additions & 9 deletions apps/dokploy/components/dashboard/projects/show.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,10 @@ import {
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuGroup,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { Input } from "@/components/ui/input";
Expand Down Expand Up @@ -149,14 +151,91 @@ export const ShowProjects = () => {
href={`/dashboard/project/${project.projectId}`}
>
<Card className="group relative w-full h-full bg-transparent transition-colors hover:bg-border">
<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>

{project.applications.length > 0 ||
project.compose.length > 0 ? (
<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 overflow-y-auto max-h-[400px]"
onClick={(e) => e.stopPropagation()}
>
{project.applications.length > 0 && (
<DropdownMenuGroup>
<DropdownMenuLabel>
Applications
</DropdownMenuLabel>
{project.applications.map((app) => (
<div key={app.applicationId}>
<DropdownMenuSeparator />
<DropdownMenuGroup>
<DropdownMenuLabel className="font-normal capitalize text-xs">
{app.name}
</DropdownMenuLabel>
<DropdownMenuSeparator />
{app.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}`}
>
<span>{domain.host}</span>
<ExternalLinkIcon className="size-4 shrink-0" />
</Link>
</DropdownMenuItem>
))}
</DropdownMenuGroup>
</div>
))}
</DropdownMenuGroup>
)}
{project.compose.length > 0 && (
<DropdownMenuGroup>
<DropdownMenuLabel>
Compose
</DropdownMenuLabel>
{project.compose.map((comp) => (
<div key={comp.composeId}>
<DropdownMenuSeparator />
<DropdownMenuGroup>
<DropdownMenuLabel className="font-normal capitalize text-xs">
{comp.name}
</DropdownMenuLabel>
<DropdownMenuSeparator />
{comp.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}`}
>
<span>{domain.host}</span>
<ExternalLinkIcon className="size-4 shrink-0" />
</Link>
</DropdownMenuItem>
))}
</DropdownMenuGroup>
</div>
))}
</DropdownMenuGroup>
)}
</DropdownMenuContent>
</DropdownMenu>
) : null}
<CardHeader>
<CardTitle className="flex items-center justify-between gap-2">
<span className="flex flex-col gap-1.5">
Expand All @@ -182,7 +261,10 @@ export const ShowProjects = () => {
<MoreHorizontalIcon className="size-5" />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent className="w-[200px] space-y-2">
<DropdownMenuContent
className="w-[200px] space-y-2 overflow-y-auto max-h-[280px]"
onClick={(e) => e.stopPropagation()}
>
<DropdownMenuLabel className="font-normal">
Actions
</DropdownMenuLabel>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import { Textarea } from "@/components/ui/textarea";
import { sshKeyCreate, type sshKeyType } from "@/server/db/validations";
import { api } from "@/utils/api";
import { zodResolver } from "@hookform/resolvers/zod";
import { PenBoxIcon, PlusIcon } from "lucide-react";
import { DownloadIcon, PenBoxIcon, PlusIcon } from "lucide-react";
import { useEffect, useState } from "react";
import { useForm } from "react-hook-form";
import { toast } from "sonner";
Expand Down Expand Up @@ -111,6 +111,26 @@ export const HandleSSHKeys = ({ sshKeyId }: Props) => {
toast.error("Error generating the SSH Key");
});

const downloadKey = (
content: string,
defaultFilename: string,
keyType: "private" | "public",
) => {
const keyName = form.watch("name");
const filename = keyName
? `${keyName}${sshKeyId ? `_${sshKeyId}` : ""}_${keyType}_${defaultFilename}`
: `${keyType}_${defaultFilename}`;
const blob = new Blob([content], { type: "text/plain" });
const url = window.URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = filename;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
window.URL.revokeObjectURL(url);
};

return (
<Dialog open={isOpen} onOpenChange={setIsOpen}>
<DialogTrigger className="" asChild>
Expand Down Expand Up @@ -245,7 +265,41 @@ export const HandleSSHKeys = ({ sshKeyId }: Props) => {
</FormItem>
)}
/>
<DialogFooter>
<DialogFooter className="flex items-center justify-between">
<div className="flex items-center gap-4">
{form.watch("privateKey") && (
<Button
type="button"
variant="outline"
size="default"
onClick={() =>
downloadKey(form.watch("privateKey"), "id_rsa", "private")
}
className="flex items-center gap-2"
>
<DownloadIcon className="h-4 w-4" />
Private Key
</Button>
)}
{form.watch("publicKey") && (
<Button
type="button"
variant="outline"
size="default"
onClick={() =>
downloadKey(
form.watch("publicKey"),
"id_rsa.pub",
"public",
)
}
className="flex items-center gap-2"
>
<DownloadIcon className="h-4 w-4" />
Public Key
</Button>
)}
</div>
<Button isLoading={isLoading} type="submit">
{sshKeyId ? "Update" : "Create"}
</Button>
Expand Down
24 changes: 19 additions & 5 deletions apps/dokploy/public/locales/ru/settings.json
Original file line number Diff line number Diff line change
@@ -1,24 +1,33 @@
{
"settings.common.save": "Сохранить",
"settings.common.enterTerminal": "Открыть терминал",
"settings.server.domain.title": "Домен сервера",
"settings.server.domain.description": "Установите домен для вашего серверного приложения Dokploy.",
"settings.server.domain.form.domain": "Домен",
"settings.server.domain.form.letsEncryptEmail": "Email для Let's Encrypt",
"settings.server.domain.form.certificate.label": "Сертификат",
"settings.server.domain.form.certificate.placeholder": "Выберите сертификат",
"settings.server.domain.form.certificateOptions.none": "Нет",
"settings.server.domain.form.certificateOptions.letsencrypt": "Let's Encrypt (По умолчанию)",
"settings.server.domain.form.certificateOptions.letsencrypt": "Let's Encrypt",

"settings.server.webServer.title": "Веб-сервер",
"settings.server.webServer.description": "Перезагрузка или очистка веб-сервера.",
"settings.server.webServer.server.label": "Сервер",
"settings.server.webServer.traefik.label": "Traefik",
"settings.server.webServer.storage.label": "Дисковое пространство",
"settings.server.webServer.actions": "Действия",
"settings.server.webServer.reload": "Перезагрузить",
"settings.server.webServer.watchLogs": "Просмотр логов",
"settings.server.webServer.updateServerIp": "Изменить IP адрес",
"settings.server.webServer.server.label": "Сервер",
"settings.server.webServer.traefik.label": "Traefik",
"settings.server.webServer.traefik.modifyEnv": "Изменить переменные окружения",
"settings.server.webServer.traefik.managePorts": "Назначение портов",
"settings.server.webServer.traefik.managePortsDescription": "Добавить или удалить дополнительные порты для Traefik",
"settings.server.webServer.traefik.targetPort": "Внутренний порт",
"settings.server.webServer.traefik.publishedPort": "Внешний порт",
"settings.server.webServer.traefik.addPort": "Добавить порт",
"settings.server.webServer.traefik.portsUpdated": "Порты успешно обновлены",
"settings.server.webServer.traefik.portsUpdateError": "Не удалось обновить порты",
"settings.server.webServer.traefik.publishMode": "Режим сопоставления",
"settings.server.webServer.storage.label": "Дисковое пространство",
"settings.server.webServer.storage.cleanUnusedImages": "Очистить неиспользуемые образы",
"settings.server.webServer.storage.cleanUnusedVolumes": "Очистить неиспользуемые тома",
"settings.server.webServer.storage.cleanStoppedContainers": "Очистить остановленные контейнеры",
Expand All @@ -40,5 +49,10 @@
"settings.appearance.themes.dark": "Темная",
"settings.appearance.themes.system": "Системная",
"settings.appearance.language": "Язык",
"settings.appearance.languageDescription": "Select a language for your dashboard"
"settings.appearance.languageDescription": "Выберите язык для панели управления",

"settings.terminal.connectionSettings": "Настройки подключения",
"settings.terminal.ipAddress": "IP адрес",
"settings.terminal.port": "Порт",
"settings.terminal.username": "Имя пользователя"
}
10 changes: 10 additions & 0 deletions apps/dokploy/public/templates/alist.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added apps/dokploy/public/templates/spacedrive.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
14 changes: 14 additions & 0 deletions apps/dokploy/templates/alist/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
version: '3.3'
services:
alist:
image: xhofe/alist:v3.41.0
volumes:
- alist-data:/opt/alist/data
environment:
- PUID=0
- PGID=0
- UMASK=022
restart: unless-stopped

volumes:
alist-data:
22 changes: 22 additions & 0 deletions apps/dokploy/templates/alist/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import {
type DomainSchema,
type Schema,
type Template,
generateRandomDomain,
} from "../utils";

export function generate(schema: Schema): Template {
const mainDomain = generateRandomDomain(schema);

const domains: DomainSchema[] = [
{
host: mainDomain,
port: 5244,
serviceName: "alist",
},
];

return {
domains,
};
}
9 changes: 9 additions & 0 deletions apps/dokploy/templates/spacedrive/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
services:
server:
image: ghcr.io/spacedriveapp/spacedrive/server:latest
ports:
- 8080
environment:
- SD_AUTH=${SD_USERNAME}:${SD_PASSWORD}
volumes:
- /var/spacedrive:/var/spacedrive
31 changes: 31 additions & 0 deletions apps/dokploy/templates/spacedrive/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import {
type DomainSchema,
type Schema,
type Template,
generateRandomDomain,
generatePassword,
} from "../utils";

export function generate(schema: Schema): Template {
const randomDomain = generateRandomDomain(schema);
const secretKey = generatePassword();
const randomUsername = "admin"; // Default username

const domains: DomainSchema[] = [
{
host: randomDomain,
port: 8080,
serviceName: "server",
},
];

const envs = [
`SD_USERNAME=${randomUsername}`,
`SD_PASSWORD=${secretKey}`,
];

return {
envs,
domains,
};
}
Loading

0 comments on commit b961032

Please sign in to comment.