feat: Add i18n support for command palette
- Add commandPalette translation section with 22 keys to all 4 languages - Update CommandPalette component to use i18n for all UI text - Translate search placeholder, group headings, menu items, and shortcut hints - Support multilingual command palette interface
This commit is contained in:
@@ -1571,5 +1571,28 @@
|
|||||||
"cpu": "CPU",
|
"cpu": "CPU",
|
||||||
"ram": "RAM",
|
"ram": "RAM",
|
||||||
"notAvailable": "Nicht verfügbar"
|
"notAvailable": "Nicht verfügbar"
|
||||||
|
},
|
||||||
|
"commandPalette": {
|
||||||
|
"searchPlaceholder": "Nach Hosts oder Schnellaktionen suchen...",
|
||||||
|
"recentActivity": "Kürzliche Aktivität",
|
||||||
|
"navigation": "Navigation",
|
||||||
|
"addHost": "Host hinzufügen",
|
||||||
|
"addCredential": "Anmeldedaten hinzufügen",
|
||||||
|
"adminSettings": "Admin-Einstellungen",
|
||||||
|
"userProfile": "Benutzerprofil",
|
||||||
|
"updateLog": "Aktualisierungsprotokoll",
|
||||||
|
"hosts": "Hosts",
|
||||||
|
"openServerDetails": "Serverdetails öffnen",
|
||||||
|
"openFileManager": "Dateimanager öffnen",
|
||||||
|
"edit": "Bearbeiten",
|
||||||
|
"links": "Links",
|
||||||
|
"github": "GitHub",
|
||||||
|
"support": "Support",
|
||||||
|
"discord": "Discord",
|
||||||
|
"donate": "Spenden",
|
||||||
|
"press": "Drücken Sie",
|
||||||
|
"toToggle": "zum Umschalten",
|
||||||
|
"close": "Schließen",
|
||||||
|
"hostManager": "Host-Manager"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1689,5 +1689,28 @@
|
|||||||
"cpu": "CPU",
|
"cpu": "CPU",
|
||||||
"ram": "RAM",
|
"ram": "RAM",
|
||||||
"notAvailable": "N/A"
|
"notAvailable": "N/A"
|
||||||
|
},
|
||||||
|
"commandPalette": {
|
||||||
|
"searchPlaceholder": "Search for hosts or quick actions...",
|
||||||
|
"recentActivity": "Recent Activity",
|
||||||
|
"navigation": "Navigation",
|
||||||
|
"addHost": "Add Host",
|
||||||
|
"addCredential": "Add Credential",
|
||||||
|
"adminSettings": "Admin Settings",
|
||||||
|
"userProfile": "User Profile",
|
||||||
|
"updateLog": "Update Log",
|
||||||
|
"hosts": "Hosts",
|
||||||
|
"openServerDetails": "Open Server Details",
|
||||||
|
"openFileManager": "Open File Manager",
|
||||||
|
"edit": "Edit",
|
||||||
|
"links": "Links",
|
||||||
|
"github": "GitHub",
|
||||||
|
"support": "Support",
|
||||||
|
"discord": "Discord",
|
||||||
|
"donate": "Donate",
|
||||||
|
"press": "Press",
|
||||||
|
"toToggle": "to toggle",
|
||||||
|
"close": "Close",
|
||||||
|
"hostManager": "Host Manager"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1657,5 +1657,28 @@
|
|||||||
"cpu": "CPU",
|
"cpu": "CPU",
|
||||||
"ram": "RAM",
|
"ram": "RAM",
|
||||||
"notAvailable": "N/A"
|
"notAvailable": "N/A"
|
||||||
|
},
|
||||||
|
"commandPalette": {
|
||||||
|
"searchPlaceholder": "Поиск хостов или быстрых действий...",
|
||||||
|
"recentActivity": "Недавняя активность",
|
||||||
|
"navigation": "Навигация",
|
||||||
|
"addHost": "Добавить хост",
|
||||||
|
"addCredential": "Добавить учетные данные",
|
||||||
|
"adminSettings": "Настройки администратора",
|
||||||
|
"userProfile": "Профиль пользователя",
|
||||||
|
"updateLog": "Журнал обновлений",
|
||||||
|
"hosts": "Хосты",
|
||||||
|
"openServerDetails": "Открыть детали сервера",
|
||||||
|
"openFileManager": "Открыть файловый менеджер",
|
||||||
|
"edit": "Редактировать",
|
||||||
|
"links": "Ссылки",
|
||||||
|
"github": "GitHub",
|
||||||
|
"support": "Поддержка",
|
||||||
|
"discord": "Discord",
|
||||||
|
"donate": "Пожертвовать",
|
||||||
|
"press": "Нажмите",
|
||||||
|
"toToggle": "для переключения",
|
||||||
|
"close": "Закрыть",
|
||||||
|
"hostManager": "Менеджер хостов"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1582,5 +1582,28 @@
|
|||||||
"cpu": "CPU",
|
"cpu": "CPU",
|
||||||
"ram": "内存",
|
"ram": "内存",
|
||||||
"notAvailable": "不可用"
|
"notAvailable": "不可用"
|
||||||
|
},
|
||||||
|
"commandPalette": {
|
||||||
|
"searchPlaceholder": "搜索主机或快速操作...",
|
||||||
|
"recentActivity": "最近活动",
|
||||||
|
"navigation": "导航",
|
||||||
|
"addHost": "添加主机",
|
||||||
|
"addCredential": "添加凭据",
|
||||||
|
"adminSettings": "管理员设置",
|
||||||
|
"userProfile": "用户资料",
|
||||||
|
"updateLog": "更新日志",
|
||||||
|
"hosts": "主机",
|
||||||
|
"openServerDetails": "打开服务器详情",
|
||||||
|
"openFileManager": "打开文件管理器",
|
||||||
|
"edit": "编辑",
|
||||||
|
"links": "链接",
|
||||||
|
"github": "GitHub",
|
||||||
|
"support": "支持",
|
||||||
|
"discord": "Discord",
|
||||||
|
"donate": "捐赠",
|
||||||
|
"press": "按下",
|
||||||
|
"toToggle": "来切换",
|
||||||
|
"close": "关闭",
|
||||||
|
"hostManager": "主机管理器"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import {
|
|||||||
Pencil,
|
Pencil,
|
||||||
EllipsisVertical,
|
EllipsisVertical,
|
||||||
} from "lucide-react";
|
} from "lucide-react";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
import { BiMoney, BiSupport } from "react-icons/bi";
|
import { BiMoney, BiSupport } from "react-icons/bi";
|
||||||
import { BsDiscord } from "react-icons/bs";
|
import { BsDiscord } from "react-icons/bs";
|
||||||
import { GrUpdate } from "react-icons/gr";
|
import { GrUpdate } from "react-icons/gr";
|
||||||
@@ -64,6 +65,7 @@ export function CommandPalette({
|
|||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
setIsOpen: (isOpen: boolean) => void;
|
setIsOpen: (isOpen: boolean) => void;
|
||||||
}) {
|
}) {
|
||||||
|
const { t } = useTranslation();
|
||||||
const inputRef = useRef<HTMLInputElement>(null);
|
const inputRef = useRef<HTMLInputElement>(null);
|
||||||
const { addTab, setCurrentTab, tabs: tabList, updateTab } = useTabs();
|
const { addTab, setCurrentTab, tabs: tabList, updateTab } = useTabs();
|
||||||
const [recentActivity, setRecentActivity] = useState<RecentActivityItem[]>(
|
const [recentActivity, setRecentActivity] = useState<RecentActivityItem[]>(
|
||||||
@@ -91,7 +93,7 @@ export function CommandPalette({
|
|||||||
} else {
|
} else {
|
||||||
const id = addTab({
|
const id = addTab({
|
||||||
type: "ssh_manager",
|
type: "ssh_manager",
|
||||||
title: "Host Manager",
|
title: t("commandPalette.hostManager"),
|
||||||
initialTab: "add_host",
|
initialTab: "add_host",
|
||||||
});
|
});
|
||||||
setCurrentTab(id);
|
setCurrentTab(id);
|
||||||
@@ -107,7 +109,7 @@ export function CommandPalette({
|
|||||||
} else {
|
} else {
|
||||||
const id = addTab({
|
const id = addTab({
|
||||||
type: "ssh_manager",
|
type: "ssh_manager",
|
||||||
title: "Host Manager",
|
title: t("commandPalette.hostManager"),
|
||||||
initialTab: "add_credential",
|
initialTab: "add_credential",
|
||||||
});
|
});
|
||||||
setCurrentTab(id);
|
setCurrentTab(id);
|
||||||
@@ -120,7 +122,7 @@ export function CommandPalette({
|
|||||||
if (adminTab) {
|
if (adminTab) {
|
||||||
setCurrentTab(adminTab.id);
|
setCurrentTab(adminTab.id);
|
||||||
} else {
|
} else {
|
||||||
const id = addTab({ type: "admin", title: "Admin Settings" });
|
const id = addTab({ type: "admin", title: t("commandPalette.adminSettings") });
|
||||||
setCurrentTab(id);
|
setCurrentTab(id);
|
||||||
}
|
}
|
||||||
setIsOpen(false);
|
setIsOpen(false);
|
||||||
@@ -131,7 +133,7 @@ export function CommandPalette({
|
|||||||
if (userProfileTab) {
|
if (userProfileTab) {
|
||||||
setCurrentTab(userProfileTab.id);
|
setCurrentTab(userProfileTab.id);
|
||||||
} else {
|
} else {
|
||||||
const id = addTab({ type: "user_profile", title: "User Profile" });
|
const id = addTab({ type: "user_profile", title: t("commandPalette.userProfile") });
|
||||||
setCurrentTab(id);
|
setCurrentTab(id);
|
||||||
}
|
}
|
||||||
setIsOpen(false);
|
setIsOpen(false);
|
||||||
@@ -214,7 +216,7 @@ export function CommandPalette({
|
|||||||
: `${host.username}@${host.ip}:${host.port}`;
|
: `${host.username}@${host.ip}:${host.port}`;
|
||||||
addTab({
|
addTab({
|
||||||
type: "ssh_manager",
|
type: "ssh_manager",
|
||||||
title: "Host Manager",
|
title: t("commandPalette.hostManager"),
|
||||||
hostConfig: host,
|
hostConfig: host,
|
||||||
initialTab: "add_host",
|
initialTab: "add_host",
|
||||||
});
|
});
|
||||||
@@ -235,7 +237,7 @@ export function CommandPalette({
|
|||||||
>
|
>
|
||||||
<CommandInput
|
<CommandInput
|
||||||
ref={inputRef}
|
ref={inputRef}
|
||||||
placeholder="Search for hosts or quick actions..."
|
placeholder={t("commandPalette.searchPlaceholder")}
|
||||||
/>
|
/>
|
||||||
<CommandList
|
<CommandList
|
||||||
key={recentActivity.length}
|
key={recentActivity.length}
|
||||||
@@ -244,7 +246,7 @@ export function CommandPalette({
|
|||||||
>
|
>
|
||||||
{recentActivity.length > 0 && (
|
{recentActivity.length > 0 && (
|
||||||
<>
|
<>
|
||||||
<CommandGroup heading="Recent Activity">
|
<CommandGroup heading={t("commandPalette.recentActivity")}>
|
||||||
{recentActivity.map((item, index) => (
|
{recentActivity.map((item, index) => (
|
||||||
<CommandItem
|
<CommandItem
|
||||||
key={`recent-activity-${index}-${item.type}-${item.hostId}-${item.timestamp}`}
|
key={`recent-activity-${index}-${item.type}-${item.hostId}-${item.timestamp}`}
|
||||||
@@ -259,30 +261,30 @@ export function CommandPalette({
|
|||||||
<CommandSeparator />
|
<CommandSeparator />
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
<CommandGroup heading="Navigation">
|
<CommandGroup heading={t("commandPalette.navigation")}>
|
||||||
<CommandItem onSelect={handleAddHost}>
|
<CommandItem onSelect={handleAddHost}>
|
||||||
<Server />
|
<Server />
|
||||||
<span>Add Host</span>
|
<span>{t("commandPalette.addHost")}</span>
|
||||||
</CommandItem>
|
</CommandItem>
|
||||||
<CommandItem onSelect={handleAddCredential}>
|
<CommandItem onSelect={handleAddCredential}>
|
||||||
<Key />
|
<Key />
|
||||||
<span>Add Credential</span>
|
<span>{t("commandPalette.addCredential")}</span>
|
||||||
</CommandItem>
|
</CommandItem>
|
||||||
<CommandItem onSelect={handleOpenAdminSettings}>
|
<CommandItem onSelect={handleOpenAdminSettings}>
|
||||||
<Settings />
|
<Settings />
|
||||||
<span>Admin Settings</span>
|
<span>{t("commandPalette.adminSettings")}</span>
|
||||||
</CommandItem>
|
</CommandItem>
|
||||||
<CommandItem onSelect={handleOpenUserProfile}>
|
<CommandItem onSelect={handleOpenUserProfile}>
|
||||||
<User />
|
<User />
|
||||||
<span>User Profile</span>
|
<span>{t("commandPalette.userProfile")}</span>
|
||||||
</CommandItem>
|
</CommandItem>
|
||||||
<CommandItem onSelect={handleOpenUpdateLog}>
|
<CommandItem onSelect={handleOpenUpdateLog}>
|
||||||
<GrUpdate />
|
<GrUpdate />
|
||||||
<span>Update Log</span>
|
<span>{t("commandPalette.updateLog")}</span>
|
||||||
</CommandItem>
|
</CommandItem>
|
||||||
</CommandGroup>
|
</CommandGroup>
|
||||||
<CommandSeparator />
|
<CommandSeparator />
|
||||||
<CommandGroup heading="Hosts">
|
<CommandGroup heading={t("commandPalette.hosts")}>
|
||||||
{hosts.map((host, index) => {
|
{hosts.map((host, index) => {
|
||||||
const title = host.name?.trim()
|
const title = host.name?.trim()
|
||||||
? host.name
|
? host.name
|
||||||
@@ -329,7 +331,7 @@ export function CommandPalette({
|
|||||||
className="flex items-center gap-2 cursor-pointer px-3 py-2 hover:bg-dark-hover text-gray-300"
|
className="flex items-center gap-2 cursor-pointer px-3 py-2 hover:bg-dark-hover text-gray-300"
|
||||||
>
|
>
|
||||||
<Server className="h-4 w-4" />
|
<Server className="h-4 w-4" />
|
||||||
<span className="flex-1">Open Server Details</span>
|
<span className="flex-1">{t("commandPalette.openServerDetails")}</span>
|
||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
<DropdownMenuItem
|
<DropdownMenuItem
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
@@ -339,7 +341,7 @@ export function CommandPalette({
|
|||||||
className="flex items-center gap-2 cursor-pointer px-3 py-2 hover:bg-dark-hover text-gray-300"
|
className="flex items-center gap-2 cursor-pointer px-3 py-2 hover:bg-dark-hover text-gray-300"
|
||||||
>
|
>
|
||||||
<FolderOpen className="h-4 w-4" />
|
<FolderOpen className="h-4 w-4" />
|
||||||
<span className="flex-1">Open File Manager</span>
|
<span className="flex-1">{t("commandPalette.openFileManager")}</span>
|
||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
<DropdownMenuItem
|
<DropdownMenuItem
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
@@ -349,7 +351,7 @@ export function CommandPalette({
|
|||||||
className="flex items-center gap-2 cursor-pointer px-3 py-2 hover:bg-dark-hover text-gray-300"
|
className="flex items-center gap-2 cursor-pointer px-3 py-2 hover:bg-dark-hover text-gray-300"
|
||||||
>
|
>
|
||||||
<Pencil className="h-4 w-4" />
|
<Pencil className="h-4 w-4" />
|
||||||
<span className="flex-1">Edit</span>
|
<span className="flex-1">{t("commandPalette.edit")}</span>
|
||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
</DropdownMenuContent>
|
</DropdownMenuContent>
|
||||||
</DropdownMenu>
|
</DropdownMenu>
|
||||||
@@ -359,36 +361,36 @@ export function CommandPalette({
|
|||||||
})}
|
})}
|
||||||
</CommandGroup>
|
</CommandGroup>
|
||||||
<CommandSeparator />
|
<CommandSeparator />
|
||||||
<CommandGroup heading="Links">
|
<CommandGroup heading={t("commandPalette.links")}>
|
||||||
<CommandItem onSelect={handleGitHub}>
|
<CommandItem onSelect={handleGitHub}>
|
||||||
<Github />
|
<Github />
|
||||||
<span>GitHub</span>
|
<span>{t("commandPalette.github")}</span>
|
||||||
</CommandItem>
|
</CommandItem>
|
||||||
<CommandItem onSelect={handleSupport}>
|
<CommandItem onSelect={handleSupport}>
|
||||||
<BiSupport />
|
<BiSupport />
|
||||||
<span>Support</span>
|
<span>{t("commandPalette.support")}</span>
|
||||||
</CommandItem>
|
</CommandItem>
|
||||||
<CommandItem onSelect={handleDiscord}>
|
<CommandItem onSelect={handleDiscord}>
|
||||||
<BsDiscord />
|
<BsDiscord />
|
||||||
<span>Discord</span>
|
<span>{t("commandPalette.discord")}</span>
|
||||||
</CommandItem>
|
</CommandItem>
|
||||||
<CommandItem onSelect={handleDonate}>
|
<CommandItem onSelect={handleDonate}>
|
||||||
<BiMoney />
|
<BiMoney />
|
||||||
<span>Donate</span>
|
<span>{t("commandPalette.donate")}</span>
|
||||||
</CommandItem>
|
</CommandItem>
|
||||||
</CommandGroup>
|
</CommandGroup>
|
||||||
</CommandList>
|
</CommandList>
|
||||||
<div className="border-t border-dark-border px-4 py-2 bg-dark-hover/50 flex items-center justify-between text-xs text-muted-foreground">
|
<div className="border-t border-dark-border px-4 py-2 bg-dark-hover/50 flex items-center justify-between text-xs text-muted-foreground">
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<span>Press</span>
|
<span>{t("commandPalette.press")}</span>
|
||||||
<KbdGroup>
|
<KbdGroup>
|
||||||
<Kbd>Shift</Kbd>
|
<Kbd>Shift</Kbd>
|
||||||
<Kbd>Shift</Kbd>
|
<Kbd>Shift</Kbd>
|
||||||
</KbdGroup>
|
</KbdGroup>
|
||||||
<span>to toggle</span>
|
<span>{t("commandPalette.toToggle")}</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<span>Close</span>
|
<span>{t("commandPalette.close")}</span>
|
||||||
<Kbd>Esc</Kbd>
|
<Kbd>Esc</Kbd>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user