From da005bc511cc631ef878ce976319ce54f3b7ba9e Mon Sep 17 00:00:00 2001 From: Mauricio Siu <47042324+Siumauricio@users.noreply.github.com> Date: Sun, 17 Nov 2024 22:25:03 -0600 Subject: [PATCH 01/46] chore: add startupfa.me sponsor --- .github/sponsors/startupfame.png | Bin 0 -> 13206 bytes README.md | 3 ++- 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 .github/sponsors/startupfame.png diff --git a/.github/sponsors/startupfame.png b/.github/sponsors/startupfame.png new file mode 100644 index 0000000000000000000000000000000000000000..da53b40b645ca67ba9f42b3676351097778fe1c5 GIT binary patch literal 13206 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 Lightspeed.run -Lightspeed.run +Cloudblast.io +Startupfame ### Community Backers 🤝 From 1c5fe8a2836d82ab21a9e1c68c63c527d60282da Mon Sep 17 00:00:00 2001 From: JiPai Date: Mon, 18 Nov 2024 14:09:42 +0800 Subject: [PATCH 02/46] feat(Profile): support use Gravatar as avatar --- .../settings/profile/profile-form.tsx | 19 +++++++++++++++++-- apps/dokploy/lib/utils.ts | 8 ++++++++ .../pages/dashboard/settings/appearance.tsx | 1 - 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/apps/dokploy/components/dashboard/settings/profile/profile-form.tsx b/apps/dokploy/components/dashboard/settings/profile/profile-form.tsx index e90eb5e5..1d4daa53 100644 --- a/apps/dokploy/components/dashboard/settings/profile/profile-form.tsx +++ b/apps/dokploy/components/dashboard/settings/profile/profile-form.tsx @@ -16,10 +16,11 @@ import { } from "@/components/ui/form"; import { Input } from "@/components/ui/input"; import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group"; +import { generateSHA256Hash } from "@/lib/utils"; import { api } from "@/utils/api"; import { zodResolver } from "@hookform/resolvers/zod"; import { useTranslation } from "next-i18next"; -import { useEffect } from "react"; +import { useEffect, useMemo, useState } from "react"; import { useForm } from "react-hook-form"; import { toast } from "sonner"; import { z } from "zod"; @@ -53,6 +54,14 @@ export const ProfileForm = () => { const { data, refetch } = api.auth.get.useQuery(); const { mutateAsync, isLoading } = api.auth.update.useMutation(); const { t } = useTranslation("settings"); + const [gravatarHash, setGravatarHash] = useState(null); + + const availableAvatars = useMemo(() => { + if (gravatarHash === null) return randomImages; + return randomImages.concat([ + `https://www.gravatar.com/avatar/${gravatarHash}`, + ]); + }, [gravatarHash]); const form = useForm({ defaultValues: { @@ -70,6 +79,12 @@ export const ProfileForm = () => { password: "", image: data?.image || "", }); + + if (data.email) { + generateSHA256Hash(data.email).then((hash) => { + setGravatarHash(hash); + }); + } } form.reset(); }, [form, form.reset, data]); @@ -154,7 +169,7 @@ export const ProfileForm = () => { value={field.value} className="flex flex-row flex-wrap gap-2 max-xl:justify-center" > - {randomImages.map((image) => ( + {availableAvatars.map((image) => ( diff --git a/apps/dokploy/lib/utils.ts b/apps/dokploy/lib/utils.ts index ac680b30..c83f5e22 100644 --- a/apps/dokploy/lib/utils.ts +++ b/apps/dokploy/lib/utils.ts @@ -4,3 +4,11 @@ import { twMerge } from "tailwind-merge"; export function cn(...inputs: ClassValue[]) { return twMerge(clsx(inputs)); } + +export async function generateSHA256Hash(text: string) { + const encoder = new TextEncoder(); + const data = encoder.encode(text); + const hashBuffer = await crypto.subtle.digest("SHA-256", data); + const hashArray = Array.from(new Uint8Array(hashBuffer)); + return hashArray.map((b) => b.toString(16).padStart(2, "0")).join(""); +} diff --git a/apps/dokploy/pages/dashboard/settings/appearance.tsx b/apps/dokploy/pages/dashboard/settings/appearance.tsx index 209d938c..f7f49746 100644 --- a/apps/dokploy/pages/dashboard/settings/appearance.tsx +++ b/apps/dokploy/pages/dashboard/settings/appearance.tsx @@ -8,7 +8,6 @@ import { createServerSideHelpers } from "@trpc/react-query/server"; import type { GetServerSidePropsContext } from "next"; import React, { type ReactElement } from "react"; import superjson from "superjson"; -import nextI18NextConfig from "../../../next-i18next.config.cjs"; const Page = () => { return ( From 28f2c1a3c07ab9511be57fb6c110e973b7cf1779 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20T=C3=B8n=20L=C3=B8vhaug?= Date: Mon, 18 Nov 2024 09:03:48 +0100 Subject: [PATCH 03/46] fix: template pointing to wrong TLD --- apps/dokploy/templates/templates.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/dokploy/templates/templates.ts b/apps/dokploy/templates/templates.ts index 40f5e736..d0b29fc6 100644 --- a/apps/dokploy/templates/templates.ts +++ b/apps/dokploy/templates/templates.ts @@ -771,8 +771,8 @@ export const templates: TemplateData[] = [ logo: "postiz.png", links: { github: "https://github.com/gitroomhq/postiz", - website: "https://postiz.io", - docs: "https://docs.postiz.io", + website: "https://postiz.com", + docs: "https://docs.postiz.com", }, tags: ["cms", "content-management", "publishing"], load: () => import("./postiz/index").then((m) => m.generate), From cda66606ec2cca2b8fc028046f58cfb2dde16ab7 Mon Sep 17 00:00:00 2001 From: WoWnik Date: Mon, 18 Nov 2024 11:47:41 +0300 Subject: [PATCH 04/46] feat: add russian translation init --- .../dashboard/settings/appearance-form.tsx | 3 +- apps/dokploy/next-i18next.config.cjs | 2 +- apps/dokploy/pages/_app.tsx | 2 +- apps/dokploy/public/locales/ru/common.json | 1 + apps/dokploy/public/locales/ru/settings.json | 44 +++++++++++++++++++ apps/dokploy/utils/hooks/use-locale.ts | 2 +- 6 files changed, 50 insertions(+), 4 deletions(-) create mode 100644 apps/dokploy/public/locales/ru/common.json create mode 100644 apps/dokploy/public/locales/ru/settings.json diff --git a/apps/dokploy/components/dashboard/settings/appearance-form.tsx b/apps/dokploy/components/dashboard/settings/appearance-form.tsx index 9bafbeda..5d764cac 100644 --- a/apps/dokploy/components/dashboard/settings/appearance-form.tsx +++ b/apps/dokploy/components/dashboard/settings/appearance-form.tsx @@ -37,7 +37,7 @@ const appearanceFormSchema = z.object({ theme: z.enum(["light", "dark", "system"], { required_error: "Please select a theme.", }), - language: z.enum(["en", "pl", "zh-Hans"], { + language: z.enum(["en", "pl", "zh-Hans", "ru"], { required_error: "Please select a language.", }), }); @@ -176,6 +176,7 @@ export function AppearanceForm() { { label: "English", value: "en" }, { label: "Polski", value: "pl" }, { label: "简体中文", value: "zh-Hans" }, + { label: "Русский", value: "ru" }, ].map((preset) => ( {preset.label} diff --git a/apps/dokploy/next-i18next.config.cjs b/apps/dokploy/next-i18next.config.cjs index bac301cb..7a1e5b01 100644 --- a/apps/dokploy/next-i18next.config.cjs +++ b/apps/dokploy/next-i18next.config.cjs @@ -2,7 +2,7 @@ module.exports = { i18n: { defaultLocale: "en", - locales: ["en", "pl", "zh-Hans"], + locales: ["en", "pl", "zh-Hans", "ru"], localeDetection: false, }, fallbackLng: "en", diff --git a/apps/dokploy/pages/_app.tsx b/apps/dokploy/pages/_app.tsx index 18cb3e7e..b74f24aa 100644 --- a/apps/dokploy/pages/_app.tsx +++ b/apps/dokploy/pages/_app.tsx @@ -71,7 +71,7 @@ export default api.withTRPC( { i18n: { defaultLocale: "en", - locales: ["en", "pl", "zh-Hans"], + locales: ["en", "pl", "zh-Hans", "ru"], localeDetection: false, }, fallbackLng: "en", diff --git a/apps/dokploy/public/locales/ru/common.json b/apps/dokploy/public/locales/ru/common.json new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/apps/dokploy/public/locales/ru/common.json @@ -0,0 +1 @@ +{} diff --git a/apps/dokploy/public/locales/ru/settings.json b/apps/dokploy/public/locales/ru/settings.json new file mode 100644 index 00000000..55620c67 --- /dev/null +++ b/apps/dokploy/public/locales/ru/settings.json @@ -0,0 +1,44 @@ +{ + "settings.common.save": "Сохранить", + "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.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.traefik.modifyEnv": "Изменить переменные окружения", + "settings.server.webServer.storage.cleanUnusedImages": "Очистить неиспользуемые образы", + "settings.server.webServer.storage.cleanUnusedVolumes": "Очистить неиспользуемые тома", + "settings.server.webServer.storage.cleanStoppedContainers": "Очистить остановленные контейнеры", + "settings.server.webServer.storage.cleanDockerBuilder": "Очистить Docker Builder и систему", + "settings.server.webServer.storage.cleanMonitoring": "Очистить мониторинг", + "settings.server.webServer.storage.cleanAll": "Очистить всё", + + "settings.profile.title": "Аккаунт", + "settings.profile.description": "Измените данные вашего профиля.", + "settings.profile.email": "Email", + "settings.profile.password": "Пароль", + "settings.profile.avatar": "Аватар", + + "settings.appearance.title": "Внешний вид", + "settings.appearance.description": "Настройте тему Dokploy.", + "settings.appearance.theme": "Тема", + "settings.appearance.themeDescription": "Выберите тему системной панели", + "settings.appearance.themes.light": "Светлая", + "settings.appearance.themes.dark": "Тёмная", + "settings.appearance.themes.system": "Системная", + "settings.appearance.language": "Язык", + "settings.appearance.languageDescription": "Select a language for your dashboard" +} diff --git a/apps/dokploy/utils/hooks/use-locale.ts b/apps/dokploy/utils/hooks/use-locale.ts index caad152a..52b5fbf4 100644 --- a/apps/dokploy/utils/hooks/use-locale.ts +++ b/apps/dokploy/utils/hooks/use-locale.ts @@ -1,6 +1,6 @@ import Cookies from "js-cookie"; -const SUPPORTED_LOCALES = ["en", "pl", "zh-Hans"] as const; +const SUPPORTED_LOCALES = ["en", "pl", "zh-Hans", "ru"] as const; type Locale = (typeof SUPPORTED_LOCALES)[number]; From adde8126abc883c1652a2c79aa8998f2dee85ec4 Mon Sep 17 00:00:00 2001 From: mufeng Date: Mon, 18 Nov 2024 15:07:10 +0800 Subject: [PATCH 05/46] feat: add HeyForm template --- apps/dokploy/public/templates/heyform.svg | 5 ++ .../templates/heyform/docker-compose.yml | 48 +++++++++++++++++++ apps/dokploy/templates/heyform/index.ts | 32 +++++++++++++ apps/dokploy/templates/templates.ts | 15 ++++++ 4 files changed, 100 insertions(+) create mode 100644 apps/dokploy/public/templates/heyform.svg create mode 100644 apps/dokploy/templates/heyform/docker-compose.yml create mode 100644 apps/dokploy/templates/heyform/index.ts diff --git a/apps/dokploy/public/templates/heyform.svg b/apps/dokploy/public/templates/heyform.svg new file mode 100644 index 00000000..e1e34e61 --- /dev/null +++ b/apps/dokploy/public/templates/heyform.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/apps/dokploy/templates/heyform/docker-compose.yml b/apps/dokploy/templates/heyform/docker-compose.yml new file mode 100644 index 00000000..b7120737 --- /dev/null +++ b/apps/dokploy/templates/heyform/docker-compose.yml @@ -0,0 +1,48 @@ +services: + heyform: + image: heyform/community-edition:latest + restart: always + volumes: + # Persist uploaded images + - heyform-data:/app/static/upload + depends_on: + - mongo + - redis + ports: + - '9513:8000' + env_file: + - .env + environment: + MONGO_URI: 'mongodb://mongo:27017/heyform' + REDIS_HOST: redis + REDIS_PORT: 6379 + networks: + - heyform-network + + mongo: + image: percona/percona-server-mongodb:4.4 + restart: always + networks: + - heyform-network + volumes: + # Persist MongoDB data + - mongo-data:/data/db + + redis: + image: redis + restart: always + command: "redis-server --appendonly yes" + networks: + - heyform-network + volumes: + # Persist KeyDB data + - redis-data:/data + +networks: + heyform-network: + driver: bridge + +volumes: + heyform-data: + mongo-data: + redis-data: diff --git a/apps/dokploy/templates/heyform/index.ts b/apps/dokploy/templates/heyform/index.ts new file mode 100644 index 00000000..5e1a86be --- /dev/null +++ b/apps/dokploy/templates/heyform/index.ts @@ -0,0 +1,32 @@ +import { + type DomainSchema, + type Schema, + type Template, + generateBase64, + generateRandomDomain, +} from "../utils"; + +export function generate(schema: Schema): Template { + const mainDomain = generateRandomDomain(schema); + const sessionKey = generateBase64(64); + const formEncryptionKey = generateBase64(64); + + const domains: DomainSchema[] = [ + { + host: mainDomain, + port: 9513, + serviceName: "heyform", + }, + ]; + + const envs = [ + `APP_HOMEPAGE_URL=http://${mainDomain}`, + `SESSION_KEY=${sessionKey}`, + `FORM_ENCRYPTION_KEY=${formEncryptionKey}`, + ]; + + return { + envs, + domains, + }; +} diff --git a/apps/dokploy/templates/templates.ts b/apps/dokploy/templates/templates.ts index 40f5e736..26f225f0 100644 --- a/apps/dokploy/templates/templates.ts +++ b/apps/dokploy/templates/templates.ts @@ -837,4 +837,19 @@ export const templates: TemplateData[] = [ tags: ["3d", "rendering", "animation"], load: () => import("./blender/index").then((m) => m.generate), }, + { + id: "heyform", + name: "HeyForm", + version: "latest", + description: + "Allows anyone to create engaging conversational forms for surveys, questionnaires, quizzes, and polls. No coding skills required.", + logo: "heyform.svg", + links: { + github: "https://github.com/heyform/heyform", + website: "https://heyform.net", + docs: "https://docs.heyform.net", + }, + tags: ["form", "builder", "questionnaire", "quiz", "survey"], + load: () => import("./heyform/index").then((m) => m.generate), + }, ]; From 6fc1ce2fbc7e47fd6ccb01c37e430c215f8c5986 Mon Sep 17 00:00:00 2001 From: JiPai Date: Mon, 18 Nov 2024 22:25:56 +0800 Subject: [PATCH 06/46] chore(README): fix broken video thumbnail --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7886f42a..ff25f7d0 100644 --- a/README.md +++ b/README.md @@ -117,7 +117,7 @@ For detailed documentation, visit [docs.dokploy.com](https://docs.dokploy.com). ## Video Tutorial - Watch the video + Watch the video