Skip to content

Commit cace125

Browse files
committed
style(web-ui): align OpenClaw config panel layout
1 parent 5769ed4 commit cace125

4 files changed

Lines changed: 347 additions & 159 deletions

File tree

web-ui/modules/i18n.dict.mjs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1052,6 +1052,8 @@ const DICT = Object.freeze({
10521052

10531053
// OpenClaw config panel
10541054
'openclaw.applyHint': '写入 ~/.openclaw/openclaw.json,支持 JSON5。',
1055+
'openclaw.workspace.title': 'OpenClaw 工作区',
1056+
'openclaw.configs.hint': '选择常用配置,或进入编辑器维护完整 JSON5。',
10551057
'openclaw.agents.hint': '读写 Workspace 的 AGENTS.md,默认路径 ~/.openclaw/workspace/AGENTS.md。',
10561058
'openclaw.agents.open': '打开 AGENTS.md',
10571059
'openclaw.workspaceFile': '工作区文件',
@@ -3178,6 +3180,8 @@ const DICT = Object.freeze({
31783180

31793181
// OpenClaw config panel
31803182
'openclaw.applyHint': 'Writes to ~/.openclaw/openclaw.json (JSON5 supported).',
3183+
'openclaw.workspace.title': 'OpenClaw workspace',
3184+
'openclaw.configs.hint': 'Select a saved config, or open the editor to maintain full JSON5.',
31813185
'openclaw.agents.hint': 'Read/write Workspace AGENTS.md. Default: ~/.openclaw/workspace/AGENTS.md.',
31823186
'openclaw.agents.open': 'Open AGENTS.md',
31833187
'openclaw.workspaceFile': 'Workspace file',

web-ui/partials/index/panel-config-openclaw.html

Lines changed: 83 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -10,74 +10,94 @@
1010
<button type="button" :class="['segment', { active: configMode === 'claude' }]" @click="switchConfigMode('claude')">{{ t('tab.config.claude') }}</button>
1111
<button type="button" :class="['segment', { active: configMode === 'openclaw' }]" @click="switchConfigMode('openclaw')">{{ t('tab.config.openclaw') }}</button>
1212
</div>
13-
<div class="config-template-hint">
14-
{{ t('openclaw.applyHint') }}
15-
</div>
16-
17-
<div class="selector-section">
18-
<div class="selector-header">
19-
<span class="selector-title">AGENTS.md</span>
20-
</div>
21-
<div class="config-template-hint">
22-
{{ t('openclaw.agents.hint') }}
23-
</div>
24-
<button class="btn-tool" @click="openOpenclawAgentsEditor" :disabled="loading || !!initError || agentsLoading">
25-
{{ agentsLoading ? t('config.modelLoading') : t('openclaw.agents.open') }}
26-
</button>
27-
</div>
13+
<div class="openclaw-layout">
14+
<section class="settings-card settings-card--wide openclaw-overview-card" aria-labelledby="openclaw-workspace-title">
15+
<div class="settings-card-header settings-card-header-row">
16+
<div>
17+
<div id="openclaw-workspace-title" class="settings-card-title">{{ t('openclaw.workspace.title') }}</div>
18+
<div class="settings-card-meta">{{ t('openclaw.applyHint') }}</div>
19+
</div>
20+
</div>
21+
<div class="settings-card-body">
22+
<div class="openclaw-tools-grid">
23+
<div class="openclaw-tool-card">
24+
<div class="openclaw-tool-copy">
25+
<div class="openclaw-tool-title">AGENTS.md</div>
26+
<div class="openclaw-tool-meta">{{ t('openclaw.agents.hint') }}</div>
27+
</div>
28+
<div class="openclaw-tool-actions">
29+
<button class="btn-tool btn-tool-compact" @click="openOpenclawAgentsEditor" :disabled="loading || !!initError || agentsLoading">
30+
{{ agentsLoading ? t('config.modelLoading') : t('openclaw.agents.open') }}
31+
</button>
32+
</div>
33+
</div>
2834

29-
<div class="selector-section">
30-
<div class="selector-header">
31-
<label class="selector-title" for="openclaw-workspace-file">{{ t('openclaw.workspaceFile') }}</label>
32-
</div>
33-
<input
34-
id="openclaw-workspace-file"
35-
class="form-input"
36-
v-model="openclawWorkspaceFileName"
37-
:placeholder="t('openclaw.workspace.placeholder')">
38-
<div class="config-template-hint">
39-
{{ t('openclaw.workspace.hint') }}
40-
</div>
41-
<button class="btn-tool" @click="openOpenclawWorkspaceEditor" :disabled="loading || !!initError || agentsLoading">
42-
{{ agentsLoading ? t('config.modelLoading') : t('openclaw.workspace.open') }}
43-
</button>
44-
</div>
35+
<div class="openclaw-tool-card openclaw-tool-card--workspace">
36+
<div class="openclaw-tool-copy">
37+
<label class="openclaw-tool-title" for="openclaw-workspace-file">{{ t('openclaw.workspaceFile') }}</label>
38+
<div class="openclaw-tool-meta">{{ t('openclaw.workspace.hint') }}</div>
39+
</div>
40+
<div class="openclaw-workspace-row">
41+
<input
42+
id="openclaw-workspace-file"
43+
class="form-input"
44+
v-model="openclawWorkspaceFileName"
45+
:placeholder="t('openclaw.workspace.placeholder')">
46+
<button class="btn-tool btn-tool-compact" @click="openOpenclawWorkspaceEditor" :disabled="loading || !!initError || agentsLoading">
47+
{{ agentsLoading ? t('config.modelLoading') : t('openclaw.workspace.open') }}
48+
</button>
49+
</div>
50+
</div>
51+
</div>
52+
</div>
53+
</section>
4554

46-
<div class="card-list">
47-
<div v-for="(config, name) in openclawConfigs" :key="name"
48-
:class="['card', { active: currentOpenclawConfig === name }]"
49-
@click="applyOpenclawConfig(name)"
50-
@keydown.enter.self.prevent="applyOpenclawConfig(name)"
51-
@keydown.space.self.prevent="applyOpenclawConfig(name)"
52-
tabindex="0"
53-
role="button"
54-
:aria-current="currentOpenclawConfig === name ? 'true' : null">
55-
<div class="card-leading">
56-
<div class="card-icon">{{ name.charAt(0).toUpperCase() }}</div>
57-
<div class="card-content">
58-
<div class="card-title">{{ name }}</div>
59-
<div class="card-subtitle">{{ openclawSubtitle(config) }}</div>
55+
<section class="settings-card settings-card--wide openclaw-configs-card" aria-labelledby="openclaw-configs-title">
56+
<div class="settings-card-header settings-card-header-row">
57+
<div>
58+
<div id="openclaw-configs-title" class="settings-card-title">{{ t('status.openclawConfig') }}</div>
59+
<div class="settings-card-meta">{{ t('openclaw.configs.hint') }}</div>
6060
</div>
6161
</div>
62-
<div class="card-trailing">
63-
<span :class="['pill', openclawHasContent(config) ? 'configured' : 'empty']">
64-
{{ openclawHasContent(config) ? t('openclaw.configured') : t('openclaw.notConfigured') }}
65-
</span>
66-
<div class="card-actions" @click.stop>
67-
<button class="card-action-btn" @click="openOpenclawEditModal(name)" :aria-label="t('openclaw.action.editAria', { name })" :title="t('openclaw.action.edit')">
68-
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
69-
<path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"/>
70-
<path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"/>
71-
</svg>
72-
</button>
73-
<button v-if="name !== '默认配置'" class="card-action-btn delete" @click="deleteOpenclawConfig(name)" :aria-label="t('openclaw.action.deleteAria', { name })" :title="t('openclaw.action.delete')">
74-
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
75-
<path d="M3 6h18"/>
76-
<path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/>
77-
</svg>
78-
</button>
62+
<div class="settings-card-body">
63+
<div class="card-list openclaw-card-list">
64+
<div v-for="(config, name) in openclawConfigs" :key="name"
65+
:class="['card', { active: currentOpenclawConfig === name }]"
66+
@click="applyOpenclawConfig(name)"
67+
@keydown.enter.self.prevent="applyOpenclawConfig(name)"
68+
@keydown.space.self.prevent="applyOpenclawConfig(name)"
69+
tabindex="0"
70+
role="button"
71+
:aria-current="currentOpenclawConfig === name ? 'true' : null">
72+
<div class="card-leading">
73+
<div class="card-icon">{{ name.charAt(0).toUpperCase() }}</div>
74+
<div class="card-content">
75+
<div class="card-title">{{ name }}</div>
76+
<div class="card-subtitle">{{ openclawSubtitle(config) }}</div>
77+
</div>
78+
</div>
79+
<div class="card-trailing">
80+
<span :class="['pill', openclawHasContent(config) ? 'configured' : 'empty']">
81+
{{ openclawHasContent(config) ? t('openclaw.configured') : t('openclaw.notConfigured') }}
82+
</span>
83+
<div class="card-actions" @click.stop>
84+
<button class="card-action-btn" @click="openOpenclawEditModal(name)" :aria-label="t('openclaw.action.editAria', { name })" :title="t('openclaw.action.edit')">
85+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
86+
<path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"/>
87+
<path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"/>
88+
</svg>
89+
</button>
90+
<button v-if="name !== '默认配置'" class="card-action-btn delete" @click="deleteOpenclawConfig(name)" :aria-label="t('openclaw.action.deleteAria', { name })" :title="t('openclaw.action.delete')">
91+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
92+
<path d="M3 6h18"/>
93+
<path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/>
94+
</svg>
95+
</button>
96+
</div>
97+
</div>
98+
</div>
7999
</div>
80100
</div>
81-
</div>
101+
</section>
82102
</div>
83103
</div>

0 commit comments

Comments
 (0)