feat(ui): translate channels views and update terminology
- Keep 'Token' and 'Skills' in English per user preference - Add i18n to channels.ts, channels.shared.ts, channels.whatsapp.ts - Add WhatsApp-specific translations (linked, authAge, showQr, etc.) - Update nav.tabs.skills to 'Skills' - Update config.sections.skills to 'Skills'
This commit is contained in:
parent
edeb35dbcc
commit
e1066b0a42
@ -186,10 +186,13 @@ export const enUS = {
|
||||
connected: "Connected",
|
||||
},
|
||||
|
||||
// General
|
||||
accounts: "Accounts",
|
||||
|
||||
// WhatsApp
|
||||
whatsapp: {
|
||||
title: "WhatsApp",
|
||||
desc: "WhatsApp via Baileys (multi-device).",
|
||||
desc: "Link WhatsApp Web and monitor connection health.",
|
||||
start: "Start",
|
||||
relink: "Relink",
|
||||
logout: "Logout",
|
||||
@ -197,6 +200,12 @@ export const enUS = {
|
||||
linking: "Linking…",
|
||||
waitingForQr: "Waiting for QR code…",
|
||||
notConfigured: "Not configured.",
|
||||
linked: "Linked",
|
||||
lastConnect: "Last connect",
|
||||
authAge: "Auth age",
|
||||
showQr: "Show QR",
|
||||
waitForScan: "Wait for scan",
|
||||
working: "Working…",
|
||||
},
|
||||
|
||||
// Telegram
|
||||
|
||||
@ -78,7 +78,7 @@ export const zhTW = {
|
||||
instances: "實例",
|
||||
sessions: "工作階段",
|
||||
cron: "排程任務",
|
||||
skills: "技能",
|
||||
skills: "Skills",
|
||||
nodes: "節點",
|
||||
chat: "對話",
|
||||
config: "組態",
|
||||
@ -91,7 +91,7 @@ export const zhTW = {
|
||||
instances: "來自已連線用戶端與節點的存在訊號。",
|
||||
sessions: "檢視進行中的工作階段並調整個別設定。",
|
||||
cron: "排程喚醒與週期性代理執行。",
|
||||
skills: "管理技能的啟用狀態與 API 金鑰。",
|
||||
skills: "管理 Skills 的啟用狀態與 API 金鑰。",
|
||||
nodes: "已配對的裝置、功能與指令權限。",
|
||||
chat: "直接與閘道器對話,進行快速操作。",
|
||||
config: "安全地編輯 ~/.clawdbot/moltbot.json 設定檔。",
|
||||
@ -107,7 +107,7 @@ export const zhTW = {
|
||||
gatewayAccess: "閘道器連線",
|
||||
gatewayAccessDesc: "控制台連線位置與認證方式。",
|
||||
websocketUrl: "WebSocket 網址",
|
||||
gatewayToken: "閘道器 Token",
|
||||
gatewayToken: "Gateway Token",
|
||||
password: "密碼(不會儲存)",
|
||||
passwordPlaceholder: "系統或共用密碼",
|
||||
defaultSessionKey: "預設工作階段金鑰",
|
||||
@ -193,10 +193,13 @@ export const zhTW = {
|
||||
connected: "已連線",
|
||||
},
|
||||
|
||||
// 一般
|
||||
accounts: "帳號",
|
||||
|
||||
// WhatsApp
|
||||
whatsapp: {
|
||||
title: "WhatsApp",
|
||||
desc: "透過 Baileys 連接 WhatsApp(多裝置)。",
|
||||
desc: "連結 WhatsApp Web 並監控連線狀態。",
|
||||
start: "開始",
|
||||
relink: "重新連結",
|
||||
logout: "登出",
|
||||
@ -204,6 +207,12 @@ export const zhTW = {
|
||||
linking: "連結中…",
|
||||
waitingForQr: "等待 QR Code…",
|
||||
notConfigured: "尚未設定。",
|
||||
linked: "已連結",
|
||||
lastConnect: "上次連線",
|
||||
authAge: "認證時長",
|
||||
showQr: "顯示 QR",
|
||||
waitForScan: "等待掃描",
|
||||
working: "處理中…",
|
||||
},
|
||||
|
||||
// Telegram
|
||||
@ -388,12 +397,12 @@ export const zhTW = {
|
||||
},
|
||||
},
|
||||
|
||||
// 技能頁面
|
||||
// Skills 頁面
|
||||
skills: {
|
||||
title: "技能",
|
||||
desc: "管理內建與已安裝的技能。",
|
||||
noSkills: "找不到技能。",
|
||||
filter: "篩選技能",
|
||||
title: "Skills",
|
||||
desc: "管理內建與已安裝的 Skills。",
|
||||
noSkills: "找不到 Skills。",
|
||||
filter: "篩選 Skills",
|
||||
shown: "個顯示中",
|
||||
apiKey: "API 金鑰",
|
||||
saveKey: "儲存金鑰",
|
||||
@ -417,7 +426,7 @@ export const zhTW = {
|
||||
desc: "已配對的裝置與即時連結。",
|
||||
noNodes: "找不到節點。",
|
||||
devices: "裝置",
|
||||
devicesDesc: "配對請求與角色權杖。",
|
||||
devicesDesc: "配對請求與角色 Token。",
|
||||
noDevices: "沒有已配對的裝置。",
|
||||
approve: "核准",
|
||||
reject: "拒絕",
|
||||
@ -427,8 +436,8 @@ export const zhTW = {
|
||||
paired: "已配對",
|
||||
approved: "已核准",
|
||||
offline: "離線",
|
||||
tokens: "權杖",
|
||||
tokensNone: "權杖:無",
|
||||
tokens: "Token",
|
||||
tokensNone: "Token:無",
|
||||
role: "角色",
|
||||
requested: "請求於",
|
||||
repair: "修復",
|
||||
@ -530,7 +539,7 @@ export const zhTW = {
|
||||
messages: "訊息",
|
||||
commands: "指令",
|
||||
hooks: "鉤子",
|
||||
skills: "技能",
|
||||
skills: "Skills",
|
||||
tools: "工具",
|
||||
gateway: "閘道器",
|
||||
wizard: "設定精靈",
|
||||
|
||||
@ -1,10 +1,11 @@
|
||||
import { html, nothing } from "lit";
|
||||
|
||||
import { t } from "../../i18n";
|
||||
import type { ChannelAccountSnapshot } from "../types";
|
||||
import type { ChannelKey, ChannelsProps } from "./channels.types";
|
||||
|
||||
export function formatDuration(ms?: number | null) {
|
||||
if (!ms && ms !== 0) return "n/a";
|
||||
if (!ms && ms !== 0) return t("common.na");
|
||||
const sec = Math.round(ms / 1000);
|
||||
if (sec < 60) return `${sec}s`;
|
||||
const min = Math.round(sec / 60);
|
||||
@ -41,5 +42,5 @@ export function renderChannelAccountCount(
|
||||
) {
|
||||
const count = getChannelAccountCount(key, channelAccounts);
|
||||
if (count < 2) return nothing;
|
||||
return html`<div class="account-count">Accounts (${count})</div>`;
|
||||
return html`<div class="account-count">${t("channels.accounts")} (${count})</div>`;
|
||||
}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import { html, nothing } from "lit";
|
||||
|
||||
import { t } from "../../i18n";
|
||||
import { formatAgo } from "../format";
|
||||
import type {
|
||||
ChannelAccountSnapshot,
|
||||
@ -77,10 +78,10 @@ export function renderChannels(props: ChannelsProps) {
|
||||
<section class="card" style="margin-top: 18px;">
|
||||
<div class="row" style="justify-content: space-between;">
|
||||
<div>
|
||||
<div class="card-title">Channel health</div>
|
||||
<div class="card-sub">Channel status snapshots from the gateway.</div>
|
||||
<div class="card-title">${t("channels.health")}</div>
|
||||
<div class="card-sub">${t("channels.healthDesc")}</div>
|
||||
</div>
|
||||
<div class="muted">${props.lastSuccessAt ? formatAgo(props.lastSuccessAt) : "n/a"}</div>
|
||||
<div class="muted">${props.lastSuccessAt ? formatAgo(props.lastSuccessAt) : t("common.na")}</div>
|
||||
</div>
|
||||
${props.lastError
|
||||
? html`<div class="callout danger" style="margin-top: 12px;">
|
||||
@ -88,7 +89,7 @@ export function renderChannels(props: ChannelsProps) {
|
||||
</div>`
|
||||
: nothing}
|
||||
<pre class="code-block" style="margin-top: 12px;">
|
||||
${props.snapshot ? JSON.stringify(props.snapshot, null, 2) : "No snapshot yet."}
|
||||
${props.snapshot ? JSON.stringify(props.snapshot, null, 2) : t("channels.noSnapshot")}
|
||||
</pre>
|
||||
</section>
|
||||
`;
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import { html, nothing } from "lit";
|
||||
|
||||
import { t } from "../../i18n";
|
||||
import { formatAgo } from "../format";
|
||||
import type { WhatsAppStatus } from "../types";
|
||||
import type { ChannelsProps } from "./channels.types";
|
||||
@ -16,46 +17,46 @@ export function renderWhatsAppCard(params: {
|
||||
return html`
|
||||
<div class="card">
|
||||
<div class="card-title">WhatsApp</div>
|
||||
<div class="card-sub">Link WhatsApp Web and monitor connection health.</div>
|
||||
<div class="card-sub">${t("channels.whatsapp.desc")}</div>
|
||||
${accountCountLabel}
|
||||
|
||||
<div class="status-list" style="margin-top: 16px;">
|
||||
<div>
|
||||
<span class="label">Configured</span>
|
||||
<span>${whatsapp?.configured ? "Yes" : "No"}</span>
|
||||
<span class="label">${t("channels.labels.configured")}</span>
|
||||
<span>${whatsapp?.configured ? t("common.yes") : t("common.no")}</span>
|
||||
</div>
|
||||
<div>
|
||||
<span class="label">Linked</span>
|
||||
<span>${whatsapp?.linked ? "Yes" : "No"}</span>
|
||||
<span class="label">${t("channels.whatsapp.linked")}</span>
|
||||
<span>${whatsapp?.linked ? t("common.yes") : t("common.no")}</span>
|
||||
</div>
|
||||
<div>
|
||||
<span class="label">Running</span>
|
||||
<span>${whatsapp?.running ? "Yes" : "No"}</span>
|
||||
<span class="label">${t("channels.labels.running")}</span>
|
||||
<span>${whatsapp?.running ? t("common.yes") : t("common.no")}</span>
|
||||
</div>
|
||||
<div>
|
||||
<span class="label">Connected</span>
|
||||
<span>${whatsapp?.connected ? "Yes" : "No"}</span>
|
||||
<span class="label">${t("channels.labels.connected")}</span>
|
||||
<span>${whatsapp?.connected ? t("common.yes") : t("common.no")}</span>
|
||||
</div>
|
||||
<div>
|
||||
<span class="label">Last connect</span>
|
||||
<span class="label">${t("channels.whatsapp.lastConnect")}</span>
|
||||
<span>
|
||||
${whatsapp?.lastConnectedAt
|
||||
? formatAgo(whatsapp.lastConnectedAt)
|
||||
: "n/a"}
|
||||
: t("common.na")}
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
<span class="label">Last message</span>
|
||||
<span class="label">${t("channels.lastInbound")}</span>
|
||||
<span>
|
||||
${whatsapp?.lastMessageAt ? formatAgo(whatsapp.lastMessageAt) : "n/a"}
|
||||
${whatsapp?.lastMessageAt ? formatAgo(whatsapp.lastMessageAt) : t("common.na")}
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
<span class="label">Auth age</span>
|
||||
<span class="label">${t("channels.whatsapp.authAge")}</span>
|
||||
<span>
|
||||
${whatsapp?.authAgeMs != null
|
||||
? formatDuration(whatsapp.authAgeMs)
|
||||
: "n/a"}
|
||||
: t("common.na")}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
@ -84,31 +85,31 @@ export function renderWhatsAppCard(params: {
|
||||
?disabled=${props.whatsappBusy}
|
||||
@click=${() => props.onWhatsAppStart(false)}
|
||||
>
|
||||
${props.whatsappBusy ? "Working…" : "Show QR"}
|
||||
${props.whatsappBusy ? t("channels.whatsapp.working") : t("channels.whatsapp.showQr")}
|
||||
</button>
|
||||
<button
|
||||
class="btn"
|
||||
?disabled=${props.whatsappBusy}
|
||||
@click=${() => props.onWhatsAppStart(true)}
|
||||
>
|
||||
Relink
|
||||
${t("channels.whatsapp.relink")}
|
||||
</button>
|
||||
<button
|
||||
class="btn"
|
||||
?disabled=${props.whatsappBusy}
|
||||
@click=${() => props.onWhatsAppWait()}
|
||||
>
|
||||
Wait for scan
|
||||
${t("channels.whatsapp.waitForScan")}
|
||||
</button>
|
||||
<button
|
||||
class="btn danger"
|
||||
?disabled=${props.whatsappBusy}
|
||||
@click=${() => props.onWhatsAppLogout()}
|
||||
>
|
||||
Logout
|
||||
${t("channels.whatsapp.logout")}
|
||||
</button>
|
||||
<button class="btn" @click=${() => props.onRefresh(true)}>
|
||||
Refresh
|
||||
${t("common.refresh")}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user