mirror of
https://github.com/Dokploy/dokploy
synced 2025-06-26 18:27:59 +00:00
feat(i18n): add translation for server tab
This commit is contained in:
@@ -235,7 +235,7 @@ export function generate(schema: Schema): Template {
|
|||||||
|
|
||||||
5. Add the logo or image of the template to `public/templates/plausible.svg`
|
5. Add the logo or image of the template to `public/templates/plausible.svg`
|
||||||
|
|
||||||
### Recomendations
|
### Recommendations
|
||||||
|
|
||||||
- Use the same name of the folder as the id of the template.
|
- Use the same name of the folder as the id of the template.
|
||||||
- The logo should be in the public folder.
|
- The logo should be in the public folder.
|
||||||
|
|||||||
@@ -11,10 +11,12 @@ import {
|
|||||||
DropdownMenuTrigger,
|
DropdownMenuTrigger,
|
||||||
} from "@/components/ui/dropdown-menu";
|
} from "@/components/ui/dropdown-menu";
|
||||||
import { api } from "@/utils/api";
|
import { api } from "@/utils/api";
|
||||||
|
import { useTranslation } from "next-i18next";
|
||||||
import { toast } from "sonner";
|
import { toast } from "sonner";
|
||||||
import { ShowModalLogs } from "../../web-server/show-modal-logs";
|
import { ShowModalLogs } from "../../web-server/show-modal-logs";
|
||||||
|
|
||||||
export const ShowDokployActions = () => {
|
export const ShowDokployActions = () => {
|
||||||
|
const { t } = useTranslation("settings");
|
||||||
const { mutateAsync: reloadServer, isLoading } =
|
const { mutateAsync: reloadServer, isLoading } =
|
||||||
api.settings.reloadServer.useMutation();
|
api.settings.reloadServer.useMutation();
|
||||||
|
|
||||||
@@ -22,11 +24,13 @@ export const ShowDokployActions = () => {
|
|||||||
<DropdownMenu>
|
<DropdownMenu>
|
||||||
<DropdownMenuTrigger asChild disabled={isLoading}>
|
<DropdownMenuTrigger asChild disabled={isLoading}>
|
||||||
<Button isLoading={isLoading} variant="outline">
|
<Button isLoading={isLoading} variant="outline">
|
||||||
Server
|
{t("settings.server.webServer.server.label")}
|
||||||
</Button>
|
</Button>
|
||||||
</DropdownMenuTrigger>
|
</DropdownMenuTrigger>
|
||||||
<DropdownMenuContent className="w-56" align="start">
|
<DropdownMenuContent className="w-56" align="start">
|
||||||
<DropdownMenuLabel>Actions</DropdownMenuLabel>
|
<DropdownMenuLabel>
|
||||||
|
{t("settings.server.webServer.actions")}
|
||||||
|
</DropdownMenuLabel>
|
||||||
<DropdownMenuSeparator />
|
<DropdownMenuSeparator />
|
||||||
<DropdownMenuGroup>
|
<DropdownMenuGroup>
|
||||||
<DropdownMenuItem
|
<DropdownMenuItem
|
||||||
@@ -40,10 +44,10 @@ export const ShowDokployActions = () => {
|
|||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<span>Reload</span>
|
<span>{t("settings.server.webServer.reload")}</span>
|
||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
<ShowModalLogs appName="dokploy">
|
<ShowModalLogs appName="dokploy">
|
||||||
<span>Watch logs</span>
|
<span>{t("settings.server.webServer.watchLogs")}</span>
|
||||||
</ShowModalLogs>
|
</ShowModalLogs>
|
||||||
</DropdownMenuGroup>
|
</DropdownMenuGroup>
|
||||||
</DropdownMenuContent>
|
</DropdownMenuContent>
|
||||||
|
|||||||
@@ -11,12 +11,14 @@ import {
|
|||||||
DropdownMenuTrigger,
|
DropdownMenuTrigger,
|
||||||
} from "@/components/ui/dropdown-menu";
|
} from "@/components/ui/dropdown-menu";
|
||||||
import { api } from "@/utils/api";
|
import { api } from "@/utils/api";
|
||||||
|
import { useTranslation } from "next-i18next";
|
||||||
import { toast } from "sonner";
|
import { toast } from "sonner";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
serverId?: string;
|
serverId?: string;
|
||||||
}
|
}
|
||||||
export const ShowStorageActions = ({ serverId }: Props) => {
|
export const ShowStorageActions = ({ serverId }: Props) => {
|
||||||
|
const { t } = useTranslation("settings");
|
||||||
const { mutateAsync: cleanAll, isLoading: cleanAllIsLoading } =
|
const { mutateAsync: cleanAll, isLoading: cleanAllIsLoading } =
|
||||||
api.settings.cleanAll.useMutation();
|
api.settings.cleanAll.useMutation();
|
||||||
|
|
||||||
@@ -64,11 +66,13 @@ export const ShowStorageActions = ({ serverId }: Props) => {
|
|||||||
}
|
}
|
||||||
variant="outline"
|
variant="outline"
|
||||||
>
|
>
|
||||||
Space
|
{t("settings.server.webServer.storage.label")}
|
||||||
</Button>
|
</Button>
|
||||||
</DropdownMenuTrigger>
|
</DropdownMenuTrigger>
|
||||||
<DropdownMenuContent className="w-64" align="start">
|
<DropdownMenuContent className="w-64" align="start">
|
||||||
<DropdownMenuLabel>Actions</DropdownMenuLabel>
|
<DropdownMenuLabel>
|
||||||
|
{t("settings.server.webServer.actions")}
|
||||||
|
</DropdownMenuLabel>
|
||||||
<DropdownMenuSeparator />
|
<DropdownMenuSeparator />
|
||||||
<DropdownMenuGroup>
|
<DropdownMenuGroup>
|
||||||
<DropdownMenuItem
|
<DropdownMenuItem
|
||||||
@@ -85,7 +89,9 @@ export const ShowStorageActions = ({ serverId }: Props) => {
|
|||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<span>Clean unused images</span>
|
<span>
|
||||||
|
{t("settings.server.webServer.storage.cleanUnusedImages")}
|
||||||
|
</span>
|
||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
<DropdownMenuItem
|
<DropdownMenuItem
|
||||||
className="w-full cursor-pointer"
|
className="w-full cursor-pointer"
|
||||||
@@ -101,7 +107,9 @@ export const ShowStorageActions = ({ serverId }: Props) => {
|
|||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<span>Clean unused volumes</span>
|
<span>
|
||||||
|
{t("settings.server.webServer.storage.cleanUnusedVolumes")}
|
||||||
|
</span>
|
||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
|
|
||||||
<DropdownMenuItem
|
<DropdownMenuItem
|
||||||
@@ -118,7 +126,9 @@ export const ShowStorageActions = ({ serverId }: Props) => {
|
|||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<span>Clean stopped containers</span>
|
<span>
|
||||||
|
{t("settings.server.webServer.storage.cleanStoppedContainers")}
|
||||||
|
</span>
|
||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
|
|
||||||
<DropdownMenuItem
|
<DropdownMenuItem
|
||||||
@@ -135,7 +145,9 @@ export const ShowStorageActions = ({ serverId }: Props) => {
|
|||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<span>Clean Docker Builder & System</span>
|
<span>
|
||||||
|
{t("settings.server.webServer.storage.cleanDockerBuilder")}
|
||||||
|
</span>
|
||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
{!serverId && (
|
{!serverId && (
|
||||||
<DropdownMenuItem
|
<DropdownMenuItem
|
||||||
@@ -150,7 +162,9 @@ export const ShowStorageActions = ({ serverId }: Props) => {
|
|||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<span>Clean Monitoring </span>
|
<span>
|
||||||
|
{t("settings.server.webServer.storage.cleanMonitoring")}
|
||||||
|
</span>
|
||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
@@ -168,7 +182,7 @@ export const ShowStorageActions = ({ serverId }: Props) => {
|
|||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<span>Clean all</span>
|
<span>{t("settings.server.webServer.storage.cleanAll")}</span>
|
||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
</DropdownMenuGroup>
|
</DropdownMenuGroup>
|
||||||
</DropdownMenuContent>
|
</DropdownMenuContent>
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import { api } from "@/utils/api";
|
|||||||
import { toast } from "sonner";
|
import { toast } from "sonner";
|
||||||
|
|
||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
|
import { useTranslation } from "next-i18next";
|
||||||
import { EditTraefikEnv } from "../../web-server/edit-traefik-env";
|
import { EditTraefikEnv } from "../../web-server/edit-traefik-env";
|
||||||
import { ShowModalLogs } from "../../web-server/show-modal-logs";
|
import { ShowModalLogs } from "../../web-server/show-modal-logs";
|
||||||
|
|
||||||
@@ -30,6 +31,7 @@ interface Props {
|
|||||||
serverId?: string;
|
serverId?: string;
|
||||||
}
|
}
|
||||||
export const ShowTraefikActions = ({ serverId }: Props) => {
|
export const ShowTraefikActions = ({ serverId }: Props) => {
|
||||||
|
const { t } = useTranslation("settings");
|
||||||
const { mutateAsync: reloadTraefik, isLoading: reloadTraefikIsLoading } =
|
const { mutateAsync: reloadTraefik, isLoading: reloadTraefikIsLoading } =
|
||||||
api.settings.reloadTraefik.useMutation();
|
api.settings.reloadTraefik.useMutation();
|
||||||
|
|
||||||
@@ -51,11 +53,13 @@ export const ShowTraefikActions = ({ serverId }: Props) => {
|
|||||||
isLoading={reloadTraefikIsLoading || toggleDashboardIsLoading}
|
isLoading={reloadTraefikIsLoading || toggleDashboardIsLoading}
|
||||||
variant="outline"
|
variant="outline"
|
||||||
>
|
>
|
||||||
Traefik
|
{t("settings.server.webServer.traefik.label")}
|
||||||
</Button>
|
</Button>
|
||||||
</DropdownMenuTrigger>
|
</DropdownMenuTrigger>
|
||||||
<DropdownMenuContent className="w-56" align="start">
|
<DropdownMenuContent className="w-56" align="start">
|
||||||
<DropdownMenuLabel>Actions</DropdownMenuLabel>
|
<DropdownMenuLabel>
|
||||||
|
{t("settings.server.webServer.actions")}
|
||||||
|
</DropdownMenuLabel>
|
||||||
<DropdownMenuSeparator />
|
<DropdownMenuSeparator />
|
||||||
<DropdownMenuGroup>
|
<DropdownMenuGroup>
|
||||||
<DropdownMenuItem
|
<DropdownMenuItem
|
||||||
@@ -71,17 +75,17 @@ export const ShowTraefikActions = ({ serverId }: Props) => {
|
|||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<span>Reload</span>
|
<span>{t("settings.server.webServer.reload")}</span>
|
||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
<ShowModalLogs appName="dokploy-traefik" serverId={serverId}>
|
<ShowModalLogs appName="dokploy-traefik" serverId={serverId}>
|
||||||
<span>Watch logs</span>
|
<span>{t("settings.server.webServer.watchLogs")}</span>
|
||||||
</ShowModalLogs>
|
</ShowModalLogs>
|
||||||
<EditTraefikEnv serverId={serverId}>
|
<EditTraefikEnv serverId={serverId}>
|
||||||
<DropdownMenuItem
|
<DropdownMenuItem
|
||||||
onSelect={(e) => e.preventDefault()}
|
onSelect={(e) => e.preventDefault()}
|
||||||
className="w-full cursor-pointer space-x-3"
|
className="w-full cursor-pointer space-x-3"
|
||||||
>
|
>
|
||||||
<span>Modify Env</span>
|
<span>{t("settings.server.webServer.traefik.modifyEnv")}</span>
|
||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
</EditTraefikEnv>
|
</EditTraefikEnv>
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import {
|
|||||||
} from "@/components/ui/select";
|
} from "@/components/ui/select";
|
||||||
import { api } from "@/utils/api";
|
import { api } from "@/utils/api";
|
||||||
import { zodResolver } from "@hookform/resolvers/zod";
|
import { zodResolver } from "@hookform/resolvers/zod";
|
||||||
|
import { useTranslation } from "next-i18next";
|
||||||
import { useEffect } from "react";
|
import { useEffect } from "react";
|
||||||
import { useForm } from "react-hook-form";
|
import { useForm } from "react-hook-form";
|
||||||
import { toast } from "sonner";
|
import { toast } from "sonner";
|
||||||
@@ -49,6 +50,7 @@ const addServerDomain = z
|
|||||||
type AddServerDomain = z.infer<typeof addServerDomain>;
|
type AddServerDomain = z.infer<typeof addServerDomain>;
|
||||||
|
|
||||||
export const WebDomain = () => {
|
export const WebDomain = () => {
|
||||||
|
const { t } = useTranslation("settings");
|
||||||
const { data: user, refetch } = api.admin.one.useQuery();
|
const { data: user, refetch } = api.admin.one.useQuery();
|
||||||
const { mutateAsync, isLoading } =
|
const { mutateAsync, isLoading } =
|
||||||
api.settings.assignDomainServer.useMutation();
|
api.settings.assignDomainServer.useMutation();
|
||||||
@@ -89,9 +91,11 @@ export const WebDomain = () => {
|
|||||||
<div className="w-full">
|
<div className="w-full">
|
||||||
<Card className="bg-transparent">
|
<Card className="bg-transparent">
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<CardTitle className="text-xl">Server Domain</CardTitle>
|
<CardTitle className="text-xl">
|
||||||
|
{t("settings.server.domain.title")}
|
||||||
|
</CardTitle>
|
||||||
<CardDescription>
|
<CardDescription>
|
||||||
Add a domain to your server application.
|
{t("settings.server.domain.description")}
|
||||||
</CardDescription>
|
</CardDescription>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent className="flex w-full flex-col gap-4">
|
<CardContent className="flex w-full flex-col gap-4">
|
||||||
@@ -106,7 +110,9 @@ export const WebDomain = () => {
|
|||||||
render={({ field }) => {
|
render={({ field }) => {
|
||||||
return (
|
return (
|
||||||
<FormItem>
|
<FormItem>
|
||||||
<FormLabel>Domain</FormLabel>
|
<FormLabel>
|
||||||
|
{t("settings.server.domain.form.domain")}
|
||||||
|
</FormLabel>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<Input
|
<Input
|
||||||
className="w-full"
|
className="w-full"
|
||||||
@@ -126,7 +132,9 @@ export const WebDomain = () => {
|
|||||||
render={({ field }) => {
|
render={({ field }) => {
|
||||||
return (
|
return (
|
||||||
<FormItem>
|
<FormItem>
|
||||||
<FormLabel>Letsencrypt Email</FormLabel>
|
<FormLabel>
|
||||||
|
{t("settings.server.domain.form.letsEncryptEmail")}
|
||||||
|
</FormLabel>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<Input
|
<Input
|
||||||
className="w-full"
|
className="w-full"
|
||||||
@@ -145,20 +153,32 @@ export const WebDomain = () => {
|
|||||||
render={({ field }) => {
|
render={({ field }) => {
|
||||||
return (
|
return (
|
||||||
<FormItem className="md:col-span-2">
|
<FormItem className="md:col-span-2">
|
||||||
<FormLabel>Certificate</FormLabel>
|
<FormLabel>
|
||||||
|
{t("settings.server.domain.form.certificate.label")}
|
||||||
|
</FormLabel>
|
||||||
<Select
|
<Select
|
||||||
onValueChange={field.onChange}
|
onValueChange={field.onChange}
|
||||||
value={field.value}
|
value={field.value}
|
||||||
>
|
>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<SelectTrigger>
|
<SelectTrigger>
|
||||||
<SelectValue placeholder="Select a certificate" />
|
<SelectValue
|
||||||
|
placeholder={t(
|
||||||
|
"settings.server.domain.form.certificate.placeholder",
|
||||||
|
)}
|
||||||
|
/>
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
<SelectContent>
|
<SelectContent>
|
||||||
<SelectItem value={"none"}>None</SelectItem>
|
<SelectItem value={"none"}>
|
||||||
|
{t(
|
||||||
|
"settings.server.domain.form.certificateOptions.none",
|
||||||
|
)}
|
||||||
|
</SelectItem>
|
||||||
<SelectItem value={"letsencrypt"}>
|
<SelectItem value={"letsencrypt"}>
|
||||||
Letsencrypt (Default)
|
{t(
|
||||||
|
"settings.server.domain.form.certificateOptions.letsencrypt",
|
||||||
|
)}
|
||||||
</SelectItem>
|
</SelectItem>
|
||||||
</SelectContent>
|
</SelectContent>
|
||||||
</Select>
|
</Select>
|
||||||
@@ -169,7 +189,7 @@ export const WebDomain = () => {
|
|||||||
/>
|
/>
|
||||||
<div>
|
<div>
|
||||||
<Button isLoading={isLoading} type="submit">
|
<Button isLoading={isLoading} type="submit">
|
||||||
Save
|
{t("settings.common.save")}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import {
|
|||||||
} from "@/components/ui/card";
|
} from "@/components/ui/card";
|
||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
import { api } from "@/utils/api";
|
import { api } from "@/utils/api";
|
||||||
|
import { useTranslation } from "next-i18next";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { ShowDokployActions } from "./servers/actions/show-dokploy-actions";
|
import { ShowDokployActions } from "./servers/actions/show-dokploy-actions";
|
||||||
import { ShowStorageActions } from "./servers/actions/show-storage-actions";
|
import { ShowStorageActions } from "./servers/actions/show-storage-actions";
|
||||||
@@ -18,6 +19,7 @@ interface Props {
|
|||||||
className?: string;
|
className?: string;
|
||||||
}
|
}
|
||||||
export const WebServer = ({ className }: Props) => {
|
export const WebServer = ({ className }: Props) => {
|
||||||
|
const { t } = useTranslation("settings");
|
||||||
const { data } = api.admin.one.useQuery();
|
const { data } = api.admin.one.useQuery();
|
||||||
|
|
||||||
const { data: dokployVersion } = api.settings.getDokployVersion.useQuery();
|
const { data: dokployVersion } = api.settings.getDokployVersion.useQuery();
|
||||||
@@ -25,8 +27,12 @@ export const WebServer = ({ className }: Props) => {
|
|||||||
return (
|
return (
|
||||||
<Card className={cn("rounded-lg w-full bg-transparent p-0", className)}>
|
<Card className={cn("rounded-lg w-full bg-transparent p-0", className)}>
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<CardTitle className="text-xl">Web server settings</CardTitle>
|
<CardTitle className="text-xl">
|
||||||
<CardDescription>Reload or clean the web server.</CardDescription>
|
{t("settings.server.webServer.title")}
|
||||||
|
</CardTitle>
|
||||||
|
<CardDescription>
|
||||||
|
{t("settings.server.webServer.description")}
|
||||||
|
</CardDescription>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent className="flex flex-col gap-4 ">
|
<CardContent className="flex flex-col gap-4 ">
|
||||||
<div className="grid md:grid-cols-2 gap-4">
|
<div className="grid md:grid-cols-2 gap-4">
|
||||||
|
|||||||
@@ -3,9 +3,11 @@ import { WebServer } from "@/components/dashboard/settings/web-server";
|
|||||||
import { DashboardLayout } from "@/components/layouts/dashboard-layout";
|
import { DashboardLayout } from "@/components/layouts/dashboard-layout";
|
||||||
import { SettingsLayout } from "@/components/layouts/settings-layout";
|
import { SettingsLayout } from "@/components/layouts/settings-layout";
|
||||||
import { appRouter } from "@/server/api/root";
|
import { appRouter } from "@/server/api/root";
|
||||||
|
import { getLocale } from "@/utils/i18n";
|
||||||
import { IS_CLOUD, validateRequest } from "@dokploy/server";
|
import { IS_CLOUD, validateRequest } from "@dokploy/server";
|
||||||
import { createServerSideHelpers } from "@trpc/react-query/server";
|
import { createServerSideHelpers } from "@trpc/react-query/server";
|
||||||
import type { GetServerSidePropsContext } from "next";
|
import type { GetServerSidePropsContext } from "next";
|
||||||
|
import { serverSideTranslations } from "next-i18next/serverSideTranslations";
|
||||||
import React, { type ReactElement } from "react";
|
import React, { type ReactElement } from "react";
|
||||||
import superjson from "superjson";
|
import superjson from "superjson";
|
||||||
|
|
||||||
@@ -31,6 +33,7 @@ export async function getServerSideProps(
|
|||||||
ctx: GetServerSidePropsContext<{ serviceId: string }>,
|
ctx: GetServerSidePropsContext<{ serviceId: string }>,
|
||||||
) {
|
) {
|
||||||
const { req, res } = ctx;
|
const { req, res } = ctx;
|
||||||
|
const locale = await getLocale(req.cookies);
|
||||||
if (IS_CLOUD) {
|
if (IS_CLOUD) {
|
||||||
return {
|
return {
|
||||||
redirect: {
|
redirect: {
|
||||||
@@ -73,6 +76,7 @@ export async function getServerSideProps(
|
|||||||
return {
|
return {
|
||||||
props: {
|
props: {
|
||||||
trpcState: helpers.dehydrate(),
|
trpcState: helpers.dehydrate(),
|
||||||
|
...(await serverSideTranslations(locale, ["settings"])),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,47 @@
|
|||||||
"common": {
|
"common": {
|
||||||
"save": "Save"
|
"save": "Save"
|
||||||
},
|
},
|
||||||
|
"server": {
|
||||||
|
"domain": {
|
||||||
|
"title": "Server Domain",
|
||||||
|
"description": "Add a domain to your server application.",
|
||||||
|
"form": {
|
||||||
|
"domain": "Domain",
|
||||||
|
"letsEncryptEmail": "Let's Encrypt Email",
|
||||||
|
"certificate": {
|
||||||
|
"label": "Certificate",
|
||||||
|
"placeholder": "Select a certificate"
|
||||||
|
},
|
||||||
|
"certificateOptions": {
|
||||||
|
"none": "None",
|
||||||
|
"letsencrypt": "Let's Encrypt (Default)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"webServer": {
|
||||||
|
"title": "Web Server",
|
||||||
|
"description": "Reload or clean the web server.",
|
||||||
|
"actions": "Actions",
|
||||||
|
"reload": "Reload",
|
||||||
|
"watchLogs": "Watch logs",
|
||||||
|
"server": {
|
||||||
|
"label": "Server"
|
||||||
|
},
|
||||||
|
"traefik": {
|
||||||
|
"label": "Traefik",
|
||||||
|
"modifyEnv": "Modify Env"
|
||||||
|
},
|
||||||
|
"storage": {
|
||||||
|
"label": "Space",
|
||||||
|
"cleanUnusedImages": "Clean unused images",
|
||||||
|
"cleanUnusedVolumes": "Clean unused volumes",
|
||||||
|
"cleanStoppedContainers": "Clean stopped containers",
|
||||||
|
"cleanDockerBuilder": "Clean Docker Builder & System",
|
||||||
|
"cleanMonitoring": "Clean Monitoring",
|
||||||
|
"cleanAll": "Clean all"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"profile": {
|
"profile": {
|
||||||
"title": "Account",
|
"title": "Account",
|
||||||
"description": "Change the details of your profile here.",
|
"description": "Change the details of your profile here.",
|
||||||
|
|||||||
@@ -3,6 +3,47 @@
|
|||||||
"common": {
|
"common": {
|
||||||
"save": "保存"
|
"save": "保存"
|
||||||
},
|
},
|
||||||
|
"server": {
|
||||||
|
"domain": {
|
||||||
|
"title": "服务器域名",
|
||||||
|
"description": "添加一个域名到您的服务器。",
|
||||||
|
"form": {
|
||||||
|
"domain": "域名",
|
||||||
|
"letsEncryptEmail": "Let's Encrypt 邮箱",
|
||||||
|
"certificate": {
|
||||||
|
"label": "证书",
|
||||||
|
"placeholder": "选择一个证书"
|
||||||
|
},
|
||||||
|
"certificateOptions": {
|
||||||
|
"none": "无",
|
||||||
|
"letsencrypt": "Let's Encrypt (默认)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"webServer": {
|
||||||
|
"title": "Web 服务器",
|
||||||
|
"description": "管理 Web 服务器。",
|
||||||
|
"actions": "操作",
|
||||||
|
"reload": "重新加载",
|
||||||
|
"watchLogs": "查看日志",
|
||||||
|
"server": {
|
||||||
|
"label": "服务器"
|
||||||
|
},
|
||||||
|
"traefik": {
|
||||||
|
"label": "Traefik",
|
||||||
|
"modifyEnv": "修改环境变量"
|
||||||
|
},
|
||||||
|
"storage": {
|
||||||
|
"label": "磁盘空间",
|
||||||
|
"cleanUnusedImages": "清理未使用的镜像",
|
||||||
|
"cleanUnusedVolumes": "清理未使用的卷",
|
||||||
|
"cleanStoppedContainers": "清理停止的容器",
|
||||||
|
"cleanDockerBuilder": "清理 Docker Builder 和系统缓存",
|
||||||
|
"cleanMonitoring": "Clean Monitoring",
|
||||||
|
"cleanAll": "清理所有"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"profile": {
|
"profile": {
|
||||||
"title": "账户偏好",
|
"title": "账户偏好",
|
||||||
"description": "更改您的个人资料详情。",
|
"description": "更改您的个人资料详情。",
|
||||||
|
|||||||
Reference in New Issue
Block a user