fix(web): i18n fixes for sidebar and dropdown labels

- Add missing translation keys: skills.resultCount, skills.toolsetLabel
- Replace hardcoded "result(s)" and "toolset" with translated strings
- Fix stale useMemo in SkillsPage allCategories (missing `t` dependency)
  causing sidebar category names to stay in English after language switch

Made-with: Cursor
This commit is contained in:
Austin Pickett 2026-04-14 10:32:51 -04:00
parent e88aa8a58c
commit 4ffaac542b
4 changed files with 9 additions and 3 deletions

View file

@ -170,8 +170,10 @@ export const en: Translations = {
noSkills: "No skills found. Skills are loaded from ~/.hermes/skills/", noSkills: "No skills found. Skills are loaded from ~/.hermes/skills/",
noSkillsMatch: "No skills match your search or filter.", noSkillsMatch: "No skills match your search or filter.",
skillCount: "{count} skill{s}", skillCount: "{count} skill{s}",
resultCount: "{count} result{s}",
noDescription: "No description available.", noDescription: "No description available.",
toolsets: "Toolsets", toolsets: "Toolsets",
toolsetLabel: "{name} toolset",
noToolsetsMatch: "No toolsets match the search.", noToolsetsMatch: "No toolsets match the search.",
setupNeeded: "Setup needed", setupNeeded: "Setup needed",
disabledForCli: "Disabled for CLI", disabledForCli: "Disabled for CLI",

View file

@ -178,8 +178,10 @@ export interface Translations {
noSkills: string; noSkills: string;
noSkillsMatch: string; noSkillsMatch: string;
skillCount: string; skillCount: string;
resultCount: string;
noDescription: string; noDescription: string;
toolsets: string; toolsets: string;
toolsetLabel: string;
noToolsetsMatch: string; noToolsetsMatch: string;
setupNeeded: string; setupNeeded: string;
disabledForCli: string; disabledForCli: string;

View file

@ -170,8 +170,10 @@ export const zh: Translations = {
noSkills: "未找到技能。技能从 ~/.hermes/skills/ 加载", noSkills: "未找到技能。技能从 ~/.hermes/skills/ 加载",
noSkillsMatch: "没有匹配的技能。", noSkillsMatch: "没有匹配的技能。",
skillCount: "{count} 个技能", skillCount: "{count} 个技能",
resultCount: "{count} 个结果",
noDescription: "暂无描述。", noDescription: "暂无描述。",
toolsets: "工具集", toolsets: "工具集",
toolsetLabel: "{name} 工具集",
noToolsetsMatch: "没有匹配的工具集。", noToolsetsMatch: "没有匹配的工具集。",
setupNeeded: "需要配置", setupNeeded: "需要配置",
disabledForCli: "CLI 已禁用", disabledForCli: "CLI 已禁用",

View file

@ -162,7 +162,7 @@ export default function SkillsPage() {
return a[0].localeCompare(b[0]); return a[0].localeCompare(b[0]);
}) })
.map(([key, count]) => ({ key, name: prettyCategory(key === "__none__" ? null : key, t.common.general), count })); .map(([key, count]) => ({ key, name: prettyCategory(key === "__none__" ? null : key, t.common.general), count }));
}, [skills]); }, [skills, t]);
const enabledCount = skills.filter((s) => s.enabled).length; const enabledCount = skills.filter((s) => s.enabled).length;
@ -292,7 +292,7 @@ export default function SkillsPage() {
{t.skills.title} {t.skills.title}
</CardTitle> </CardTitle>
<Badge variant="secondary" className="text-[10px]"> <Badge variant="secondary" className="text-[10px]">
{searchMatchedSkills.length} result{searchMatchedSkills.length !== 1 ? "s" : ""} {t.skills.resultCount.replace("{count}", String(searchMatchedSkills.length)).replace("{s}", searchMatchedSkills.length !== 1 ? "s" : "")}
</Badge> </Badge>
</div> </div>
</CardHeader> </CardHeader>
@ -405,7 +405,7 @@ export default function SkillsPage() {
)} )}
{ts.tools.length === 0 && ( {ts.tools.length === 0 && (
<span className="text-[10px] text-muted-foreground/60"> <span className="text-[10px] text-muted-foreground/60">
{ts.enabled ? `${ts.name} toolset` : t.skills.disabledForCli} {ts.enabled ? t.skills.toolsetLabel.replace("{name}", ts.name) : t.skills.disabledForCli}
</span> </span>
)} )}
</div> </div>