mirror of
https://github.com/andwati/dokploy.git
synced 2026-11-12 06:55:19 +00:00
Revert "feat(i18n): update zh-Hans translation"
This commit is contained in:
@@ -86,7 +86,6 @@ import { Logo } from "../shared/logo";
|
||||
import { Button } from "../ui/button";
|
||||
import { UpdateServerButton } from "./update-server";
|
||||
import { UserNav } from "./user-nav";
|
||||
import { useTranslation } from "next-i18next";
|
||||
|
||||
// The types of the queries we are going to use
|
||||
type AuthQueryOutput = inferRouterOutputs<AppRouter>["user"]["get"];
|
||||
@@ -94,7 +93,6 @@ type AuthQueryOutput = inferRouterOutputs<AppRouter>["user"]["get"];
|
||||
type SingleNavItem = {
|
||||
isSingle?: true;
|
||||
title: string;
|
||||
titleKey: string;
|
||||
url: string;
|
||||
icon?: LucideIcon;
|
||||
isEnabled?: (opts: {
|
||||
@@ -112,7 +110,6 @@ type NavItem =
|
||||
| {
|
||||
isSingle: false;
|
||||
title: string;
|
||||
titleKey: string;
|
||||
icon: LucideIcon;
|
||||
items: SingleNavItem[];
|
||||
isEnabled?: (opts: {
|
||||
@@ -125,7 +122,6 @@ type NavItem =
|
||||
// Represents an external link item (used for the help section)
|
||||
type ExternalLink = {
|
||||
name: string;
|
||||
nameKey: string;
|
||||
url: string;
|
||||
icon: React.ComponentType<{ className?: string }>;
|
||||
isEnabled?: (opts: {
|
||||
@@ -151,14 +147,12 @@ const MENU: Menu = {
|
||||
{
|
||||
isSingle: true,
|
||||
title: "Projects",
|
||||
titleKey: "common.side.projects",
|
||||
url: "/dashboard/projects",
|
||||
icon: Folder,
|
||||
},
|
||||
{
|
||||
isSingle: true,
|
||||
title: "Monitoring",
|
||||
titleKey: "common.side.monitoring",
|
||||
url: "/dashboard/monitoring",
|
||||
icon: BarChartHorizontalBigIcon,
|
||||
// Only enabled in non-cloud environments
|
||||
@@ -167,7 +161,6 @@ const MENU: Menu = {
|
||||
{
|
||||
isSingle: true,
|
||||
title: "Traefik File System",
|
||||
titleKey: "common.side.traefik",
|
||||
url: "/dashboard/traefik",
|
||||
icon: GalleryVerticalEnd,
|
||||
// Only enabled for admins and users with access to Traefik files in non-cloud environments
|
||||
@@ -180,7 +173,6 @@ const MENU: Menu = {
|
||||
{
|
||||
isSingle: true,
|
||||
title: "Docker",
|
||||
titleKey: "common.side.docker",
|
||||
url: "/dashboard/docker",
|
||||
icon: BlocksIcon,
|
||||
// Only enabled for admins and users with access to Docker in non-cloud environments
|
||||
@@ -190,7 +182,6 @@ const MENU: Menu = {
|
||||
{
|
||||
isSingle: true,
|
||||
title: "Swarm",
|
||||
titleKey: "common.side.swarm",
|
||||
url: "/dashboard/swarm",
|
||||
icon: PieChart,
|
||||
// Only enabled for admins and users with access to Docker in non-cloud environments
|
||||
@@ -200,7 +191,6 @@ const MENU: Menu = {
|
||||
{
|
||||
isSingle: true,
|
||||
title: "Requests",
|
||||
titleKey: "common.side.requests",
|
||||
url: "/dashboard/requests",
|
||||
icon: Forward,
|
||||
// Only enabled for admins and users with access to Docker in non-cloud environments
|
||||
@@ -269,7 +259,6 @@ const MENU: Menu = {
|
||||
{
|
||||
isSingle: true,
|
||||
title: "Web Server",
|
||||
titleKey: "common.side.web-server",
|
||||
url: "/dashboard/settings/server",
|
||||
icon: Activity,
|
||||
// Only enabled for admins in non-cloud environments
|
||||
@@ -278,14 +267,12 @@ const MENU: Menu = {
|
||||
{
|
||||
isSingle: true,
|
||||
title: "Profile",
|
||||
titleKey: "common.side.profile",
|
||||
url: "/dashboard/settings/profile",
|
||||
icon: User,
|
||||
},
|
||||
{
|
||||
isSingle: true,
|
||||
title: "Remote Servers",
|
||||
titleKey: "common.side.remote-servers",
|
||||
url: "/dashboard/settings/servers",
|
||||
icon: Server,
|
||||
// Only enabled for admins
|
||||
@@ -294,7 +281,6 @@ const MENU: Menu = {
|
||||
{
|
||||
isSingle: true,
|
||||
title: "Users",
|
||||
titleKey: "common.side.users",
|
||||
icon: Users,
|
||||
url: "/dashboard/settings/users",
|
||||
// Only enabled for admins
|
||||
@@ -303,7 +289,6 @@ const MENU: Menu = {
|
||||
{
|
||||
isSingle: true,
|
||||
title: "SSH Keys",
|
||||
titleKey: "common.side.ssh-keys",
|
||||
icon: KeyRound,
|
||||
url: "/dashboard/settings/ssh-keys",
|
||||
// Only enabled for admins and users with access to SSH keys
|
||||
@@ -312,7 +297,6 @@ const MENU: Menu = {
|
||||
},
|
||||
{
|
||||
title: "AI",
|
||||
titleKey: "common.side.ai",
|
||||
icon: BotIcon,
|
||||
url: "/dashboard/settings/ai",
|
||||
isSingle: true,
|
||||
@@ -321,7 +305,6 @@ const MENU: Menu = {
|
||||
{
|
||||
isSingle: true,
|
||||
title: "Git",
|
||||
titleKey: "common.side.git",
|
||||
url: "/dashboard/settings/git-providers",
|
||||
icon: GitBranch,
|
||||
// Only enabled for admins and users with access to Git providers
|
||||
@@ -331,7 +314,6 @@ const MENU: Menu = {
|
||||
{
|
||||
isSingle: true,
|
||||
title: "Registry",
|
||||
titleKey: "common.side.registry",
|
||||
url: "/dashboard/settings/registry",
|
||||
icon: Package,
|
||||
// Only enabled for admins
|
||||
@@ -340,7 +322,6 @@ const MENU: Menu = {
|
||||
{
|
||||
isSingle: true,
|
||||
title: "S3 Destinations",
|
||||
titleKey: "common.side.s3-destinations",
|
||||
url: "/dashboard/settings/destinations",
|
||||
icon: Database,
|
||||
// Only enabled for admins
|
||||
@@ -350,7 +331,6 @@ const MENU: Menu = {
|
||||
{
|
||||
isSingle: true,
|
||||
title: "Certificates",
|
||||
titleKey: "common.side.certificates",
|
||||
url: "/dashboard/settings/certificates",
|
||||
icon: ShieldCheck,
|
||||
// Only enabled for admins
|
||||
@@ -359,7 +339,6 @@ const MENU: Menu = {
|
||||
{
|
||||
isSingle: true,
|
||||
title: "Cluster",
|
||||
titleKey: "common.side.cluster",
|
||||
url: "/dashboard/settings/cluster",
|
||||
icon: Boxes,
|
||||
// Only enabled for admins in non-cloud environments
|
||||
@@ -368,7 +347,6 @@ const MENU: Menu = {
|
||||
{
|
||||
isSingle: true,
|
||||
title: "Notifications",
|
||||
titleKey: "common.side.notifications",
|
||||
url: "/dashboard/settings/notifications",
|
||||
icon: Bell,
|
||||
// Only enabled for admins
|
||||
@@ -377,7 +355,6 @@ const MENU: Menu = {
|
||||
{
|
||||
isSingle: true,
|
||||
title: "Billing",
|
||||
titleKey: "common.side.billing",
|
||||
url: "/dashboard/settings/billing",
|
||||
icon: CreditCard,
|
||||
// Only enabled for admins in cloud environments
|
||||
@@ -388,19 +365,16 @@ const MENU: Menu = {
|
||||
help: [
|
||||
{
|
||||
name: "Documentation",
|
||||
nameKey: "common.side.documentation",
|
||||
url: "https://docs.dokploy.com/docs/core",
|
||||
icon: BookIcon,
|
||||
},
|
||||
{
|
||||
name: "Support",
|
||||
nameKey: "common.side.support",
|
||||
url: "https://discord.gg/2tBnJ3jDJc",
|
||||
icon: CircleHelp,
|
||||
},
|
||||
{
|
||||
name: "Sponsor",
|
||||
nameKey: "common.side.sponsor",
|
||||
url: "https://opencollective.com/dokploy",
|
||||
icon: ({ className }) => (
|
||||
<HeartIcon
|
||||
@@ -519,7 +493,6 @@ function LogoWrapper() {
|
||||
}
|
||||
|
||||
function SidebarLogo() {
|
||||
const { t } = useTranslation();
|
||||
const { state } = useSidebar();
|
||||
const { data: isCloud } = api.settings.isCloud.useQuery();
|
||||
const { data: user } = api.user.get.useQuery();
|
||||
@@ -603,8 +576,7 @@ function SidebarLogo() {
|
||||
)}
|
||||
>
|
||||
<p className="text-sm font-medium leading-none">
|
||||
{activeOrganization?.name ??
|
||||
t("common.side.organizations.select-organization")}
|
||||
{activeOrganization?.name ?? "Select Organization"}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -620,7 +592,7 @@ function SidebarLogo() {
|
||||
sideOffset={4}
|
||||
>
|
||||
<DropdownMenuLabel className="text-xs text-muted-foreground">
|
||||
{t("common.side.organizations")}
|
||||
Organizations
|
||||
</DropdownMenuLabel>
|
||||
{organizations?.map((org) => (
|
||||
<div className="flex flex-row justify-between" key={org.name}>
|
||||
@@ -648,12 +620,8 @@ function SidebarLogo() {
|
||||
<div className="flex items-center gap-2">
|
||||
<AddOrganization organizationId={org.id} />
|
||||
<DialogAction
|
||||
title={t(
|
||||
"common.side.organizations.delete-organization",
|
||||
)}
|
||||
description={t(
|
||||
"common.side.organizations.confirm-delete-organization",
|
||||
)}
|
||||
title="Delete Organization"
|
||||
description="Are you sure you want to delete this organization?"
|
||||
type="destructive"
|
||||
onClick={async () => {
|
||||
await deleteOrganization({
|
||||
@@ -662,17 +630,13 @@ function SidebarLogo() {
|
||||
.then(() => {
|
||||
refetch();
|
||||
toast.success(
|
||||
t(
|
||||
"common.side.organizations.organization-deleted",
|
||||
),
|
||||
"Organization deleted successfully",
|
||||
);
|
||||
})
|
||||
.catch((error) => {
|
||||
toast.error(
|
||||
error?.message ||
|
||||
t(
|
||||
"common.side.organizations.error-deleting-organization",
|
||||
),
|
||||
"Error deleting organization",
|
||||
);
|
||||
});
|
||||
}}
|
||||
@@ -725,9 +689,7 @@ function SidebarLogo() {
|
||||
side={"right"}
|
||||
className="w-80"
|
||||
>
|
||||
<DropdownMenuLabel>
|
||||
{t("common.side.invitations.pending-invitations")}
|
||||
</DropdownMenuLabel>
|
||||
<DropdownMenuLabel>Pending Invitations</DropdownMenuLabel>
|
||||
<div className="flex flex-col gap-2">
|
||||
{invitations && invitations.length > 0 ? (
|
||||
invitations.map((invitation) => (
|
||||
@@ -740,23 +702,16 @@ function SidebarLogo() {
|
||||
{invitation?.organization?.name}
|
||||
</div>
|
||||
<div className="text-xs text-muted-foreground">
|
||||
{t("common.side.invitations.expires", {
|
||||
expireDate: new Date(
|
||||
invitation.expiresAt,
|
||||
).toLocaleString(),
|
||||
})}
|
||||
Expires:{" "}
|
||||
{new Date(invitation.expiresAt).toLocaleString()}
|
||||
</div>
|
||||
<div className="text-xs text-muted-foreground">
|
||||
{t("common.side.invitations.role", {
|
||||
role: invitation.role,
|
||||
})}
|
||||
Role: {invitation.role}
|
||||
</div>
|
||||
</DropdownMenuItem>
|
||||
<DialogAction
|
||||
title={t("common.side.invitations.accept-invitation")}
|
||||
description={t(
|
||||
"common.side.invitations.confirm-accept-invitation",
|
||||
)}
|
||||
title="Accept Invitation"
|
||||
description="Are you sure you want to accept this invitation?"
|
||||
type="default"
|
||||
onClick={async () => {
|
||||
const { error } =
|
||||
@@ -766,31 +721,24 @@ function SidebarLogo() {
|
||||
|
||||
if (error) {
|
||||
toast.error(
|
||||
error.message ||
|
||||
t(
|
||||
"common.side.invitations.error-accepting-invitation",
|
||||
),
|
||||
error.message || "Error accepting invitation",
|
||||
);
|
||||
} else {
|
||||
toast.success(
|
||||
t(
|
||||
"common.side.invitations.invitation-accepted",
|
||||
),
|
||||
);
|
||||
toast.success("Invitation accepted successfully");
|
||||
await refetchInvitations();
|
||||
await refetch();
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Button size="sm" variant="secondary">
|
||||
{t("common.side.invitations.accept-invitation")}
|
||||
Accept Invitation
|
||||
</Button>
|
||||
</DialogAction>
|
||||
</div>
|
||||
))
|
||||
) : (
|
||||
<DropdownMenuItem disabled>
|
||||
{t("common.side.invitations.no-pending-invitations")}
|
||||
No pending invitations
|
||||
</DropdownMenuItem>
|
||||
)}
|
||||
</div>
|
||||
@@ -804,8 +752,6 @@ function SidebarLogo() {
|
||||
}
|
||||
|
||||
export default function Page({ children }: Props) {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const [defaultOpen, setDefaultOpen] = useState<boolean | undefined>(
|
||||
undefined,
|
||||
);
|
||||
@@ -872,7 +818,7 @@ export default function Page({ children }: Props) {
|
||||
</SidebarHeader>
|
||||
<SidebarContent>
|
||||
<SidebarGroup>
|
||||
<SidebarGroupLabel>{t("common.side.home")}</SidebarGroupLabel>
|
||||
<SidebarGroupLabel>Home</SidebarGroupLabel>
|
||||
<SidebarMenu>
|
||||
{filteredHome.map((item) => {
|
||||
const isSingle = item.isSingle !== false;
|
||||
@@ -893,7 +839,7 @@ export default function Page({ children }: Props) {
|
||||
{isSingle ? (
|
||||
<SidebarMenuButton
|
||||
asChild
|
||||
tooltip={t(item.titleKey)}
|
||||
tooltip={item.title}
|
||||
className={cn(isActive && "bg-border")}
|
||||
>
|
||||
<Link
|
||||
@@ -905,14 +851,14 @@ export default function Page({ children }: Props) {
|
||||
className={cn(isActive && "text-primary")}
|
||||
/>
|
||||
)}
|
||||
<span>{t(item.titleKey)}</span>
|
||||
<span>{item.title}</span>
|
||||
</Link>
|
||||
</SidebarMenuButton>
|
||||
) : (
|
||||
<>
|
||||
<CollapsibleTrigger asChild>
|
||||
<SidebarMenuButton
|
||||
tooltip={t(item.titleKey)}
|
||||
tooltip={item.title}
|
||||
isActive={isActive}
|
||||
>
|
||||
{item.icon && <item.icon />}
|
||||
@@ -961,7 +907,7 @@ export default function Page({ children }: Props) {
|
||||
</SidebarMenu>
|
||||
</SidebarGroup>
|
||||
<SidebarGroup>
|
||||
<SidebarGroupLabel>{t("common.side.settings")}</SidebarGroupLabel>
|
||||
<SidebarGroupLabel>Settings</SidebarGroupLabel>
|
||||
<SidebarMenu className="gap-2">
|
||||
{filteredSettings.map((item) => {
|
||||
const isSingle = item.isSingle !== false;
|
||||
@@ -982,7 +928,7 @@ export default function Page({ children }: Props) {
|
||||
{isSingle ? (
|
||||
<SidebarMenuButton
|
||||
asChild
|
||||
tooltip={t(item.titleKey)}
|
||||
tooltip={item.title}
|
||||
className={cn(isActive && "bg-border")}
|
||||
>
|
||||
<Link
|
||||
@@ -994,19 +940,19 @@ export default function Page({ children }: Props) {
|
||||
className={cn(isActive && "text-primary")}
|
||||
/>
|
||||
)}
|
||||
<span>{t(item.titleKey)}</span>
|
||||
<span>{item.title}</span>
|
||||
</Link>
|
||||
</SidebarMenuButton>
|
||||
) : (
|
||||
<>
|
||||
<CollapsibleTrigger asChild>
|
||||
<SidebarMenuButton
|
||||
tooltip={t(item.titleKey)}
|
||||
tooltip={item.title}
|
||||
isActive={isActive}
|
||||
>
|
||||
{item.icon && <item.icon />}
|
||||
|
||||
<span>{t(item.titleKey)}</span>
|
||||
<span>{item.title}</span>
|
||||
{item.items?.length && (
|
||||
<ChevronRight className="ml-auto transition-transform duration-200 group-data-[state=open]/collapsible:rotate-90" />
|
||||
)}
|
||||
@@ -1050,7 +996,7 @@ export default function Page({ children }: Props) {
|
||||
</SidebarMenu>
|
||||
</SidebarGroup>
|
||||
<SidebarGroup className="group-data-[collapsible=icon]:hidden">
|
||||
<SidebarGroupLabel>{t("common.side.extra")}</SidebarGroupLabel>
|
||||
<SidebarGroupLabel>Extra</SidebarGroupLabel>
|
||||
<SidebarMenu>
|
||||
{help.map((item: ExternalLink) => (
|
||||
<SidebarMenuItem key={item.name}>
|
||||
@@ -1064,7 +1010,7 @@ export default function Page({ children }: Props) {
|
||||
<span className="mr-2">
|
||||
<item.icon className="h-4 w-4" />
|
||||
</span>
|
||||
<span>{t(item.nameKey)}</span>
|
||||
<span>{item.name}</span>
|
||||
</a>
|
||||
</SidebarMenuButton>
|
||||
</SidebarMenuItem>
|
||||
@@ -1111,7 +1057,7 @@ export default function Page({ children }: Props) {
|
||||
href={activeItem?.url || "/"}
|
||||
className="flex items-center gap-1.5"
|
||||
>
|
||||
{activeItem?.titleKey ? t(activeItem.titleKey) : ""}
|
||||
{activeItem?.title}
|
||||
</Link>
|
||||
</BreadcrumbLink>
|
||||
</BreadcrumbItem>
|
||||
|
||||
Reference in New Issue
Block a user