mirror of
https://github.com/qingchencloud/clawpanel.git
synced 2026-05-29 20:30:00 +08:00
把 raw error toast 升级为 humanizeError,让用户看到分类友好的错误提示
(自动加 action button 如「打开设置」「重试」「查看文档」)。
## sessions.js (5 处)
- 加载会话失败 → humanizeError(err, t('engine.sessionsLoadFailed'))
- 详情加载失败 → humanizeError(err, t('engine.sessionsDetailLoadFailed'))
- 切换会话失败 → humanizeError(err, t('engine.sessionsSwitchFailed'))
- 删除失败 → humanizeError(err, t('engine.chatDeleteFailed'))
- 导出失败 → humanizeError(err, t('engine.sessionsExportFailed'))
## extensions.js (5 处)
- dashboard 打开失败 (probe / start) - 2 处
- 主题保存失败 → humanizeError(err, t('engine.extensionsThemeSaveFailed'))
- 加载扩展失败 → humanizeError(err, t('engine.extensionsLoadFailed'))
- 重新扫描失败 → humanizeError(err, t('engine.extensionsRescanFailed'))
## env-editor.js (4 处)
- reveal / save / delete / load 错误 → humanizeError
- 文案保留 inline 中文(页面尚未 i18n 化)
## usage.js (1 bug + 1 升级)
- **修真 bug**: catch (_) {...} 内部却用了 err 引用 → 改为 catch (err) {...}
- 失败时 humanizeError(err, t('engine.usageLoadFailed'))
## lazy-deps.js (1 处)
- features API 失败显示 humanizeError + escapeHtml
## config.js (2 处)
- 加载配置失败 → humanizeError(err, t('engine.hermesConfigLoadFailed'))
- 保存配置失败 → humanizeError(err, t('engine.hermesConfigSaveFailed'))
## hermes.css 修 lint
- .hm-kanban-task-summary 加 line-clamp 标准属性(不只是 -webkit-line-clamp)
## i18n 新增 8 键
- sessionsLoadFailed / sessionsSwitchFailed / usageLoadFailed
- extensionsThemeSaveFailed / extensionsLoadFailed / extensionsRescanFailed
- hermesConfigLoadFailed / hermesConfigSaveFailed
- 全部 × 3 语言
## 累计影响
- 6 个 hermes 页面(sessions/extensions/env-editor/usage/lazy-deps/config)统一错误处理
- 修 usage.js 1 个真 bug(catch 参数名错配)
- 8 个新 i18n × 3 语言
- 1 个 CSS lint 警告修复
- npm build ✓
94 lines
3.3 KiB
JavaScript
94 lines
3.3 KiB
JavaScript
/**
|
|
* Hermes Agent 配置编辑
|
|
*/
|
|
import { t } from '../../../lib/i18n.js'
|
|
import { api } from '../../../lib/tauri-api.js'
|
|
import { toast } from '../../../components/toast.js'
|
|
import { humanizeError } from '../../../lib/humanize-error.js'
|
|
|
|
export function render() {
|
|
const el = document.createElement('div')
|
|
el.className = 'page'
|
|
el.dataset.engine = 'hermes'
|
|
let yaml = ''
|
|
let loading = true
|
|
let saving = false
|
|
let error = ''
|
|
|
|
function esc(value) {
|
|
return String(value || '')
|
|
.replace(/&/g, '&')
|
|
.replace(/</g, '<')
|
|
.replace(/>/g, '>')
|
|
.replace(/"/g, '"')
|
|
}
|
|
|
|
function draw() {
|
|
el.innerHTML = `
|
|
<div class="hm-hero">
|
|
<div class="hm-hero-title">
|
|
<div class="hm-hero-eyebrow">${t('engine.hermesConfigEyebrow')}</div>
|
|
<h1 class="hm-hero-h1">${t('engine.hermesConfigTitle')}</h1>
|
|
<div class="hm-hero-sub">~/.hermes/config.yaml</div>
|
|
</div>
|
|
<div class="hm-hero-actions">
|
|
<button class="hm-btn hm-btn--ghost hm-btn--sm" id="hm-config-reload" ${loading || saving ? 'disabled' : ''}>${t('engine.hermesConfigReload')}</button>
|
|
<button class="hm-btn hm-btn--cta hm-btn--sm" id="hm-config-save" ${loading || saving ? 'disabled' : ''}>${t('engine.hermesConfigSave')}</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="hm-panel">
|
|
<div class="hm-panel-header">
|
|
<div class="hm-panel-title">config.yaml</div>
|
|
<div class="hm-panel-actions">
|
|
<span class="hm-muted">${saving ? t('engine.hermesConfigStatusSaving') : loading ? t('engine.hermesConfigStatusLoading') : t('engine.hermesConfigStatusReady')}</span>
|
|
</div>
|
|
</div>
|
|
<div class="hm-panel-body" style="padding:0">
|
|
${error ? `<div style="margin:16px 18px;padding:10px 14px;border-radius:var(--hm-radius-sm);background:var(--hm-error-soft);color:var(--hm-error);font-family:var(--hm-font-mono);font-size:12px">${esc(error)}</div>` : ''}
|
|
<textarea id="hm-config-yaml" class="hm-input" spellcheck="false" ${loading || saving ? 'disabled' : ''} style="width:100%;min-height:560px;border:0;border-radius:0;background:var(--hm-surface-0);font-family:var(--hm-font-mono);font-size:12px;line-height:1.7;padding:18px 20px;resize:vertical">${esc(yaml)}</textarea>
|
|
</div>
|
|
</div>
|
|
`
|
|
el.querySelector('#hm-config-reload')?.addEventListener('click', load)
|
|
el.querySelector('#hm-config-save')?.addEventListener('click', save)
|
|
}
|
|
|
|
async function load() {
|
|
loading = true
|
|
error = ''
|
|
draw()
|
|
try {
|
|
const data = await api.hermesConfigRawRead()
|
|
yaml = data?.yaml || ''
|
|
} catch (err) {
|
|
error = humanizeError(err, t('engine.hermesConfigLoadFailed') || 'Load config failed')
|
|
} finally {
|
|
loading = false
|
|
draw()
|
|
}
|
|
}
|
|
|
|
async function save() {
|
|
const textarea = el.querySelector('#hm-config-yaml')
|
|
yaml = textarea?.value || ''
|
|
saving = true
|
|
error = ''
|
|
draw()
|
|
try {
|
|
await api.hermesConfigRawWrite(yaml)
|
|
toast(t('engine.hermesConfigSaveSuccess'), 'success')
|
|
} catch (err) {
|
|
error = humanizeError(err, t('engine.hermesConfigSaveFailed') || 'Save failed')
|
|
toast(error, 'error')
|
|
} finally {
|
|
saving = false
|
|
draw()
|
|
}
|
|
}
|
|
|
|
draw()
|
|
load()
|
|
return el
|
|
}
|