Skip to content

Commit 85cfd62

Browse files
authored
feat: localize session management group & interval method texts (#6471)
* fix(ui): localize session management group texts Replace hardcoded Chinese strings in SessionManagementPage with i18n lookups for group management labels, dialogs, and action feedback. Add and align translation keys in en-US, ru-RU, and zh-CN for group management and batch operation messages to ensure consistent multilingual UI behavior. * fix(ui): localize interval method hint text
1 parent 1c7c2ee commit 85cfd62

File tree

5 files changed

+126
-55
lines changed

5 files changed

+126
-55
lines changed

dashboard/src/i18n/locales/en-US/features/config-metadata.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -851,7 +851,7 @@
851851
},
852852
"interval_method": {
853853
"description": "Interval Method",
854-
"hint": "random 为随机时间,log 为根据消息长度计算,$y=log_<log_base>(x)$,x为字数,y的单位为秒。"
854+
"hint": "random uses a random delay. log calculates delay by message length: $y=log_{log\\_base}(x)$, where x is word count and y is in seconds."
855855
},
856856
"interval": {
857857
"description": "Random Interval Time",

dashboard/src/i18n/locales/en-US/features/session-management.json

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -93,24 +93,6 @@
9393
"batchDeleteConfirm": {
9494
"title": "Confirm Batch Delete",
9595
"message": "Are you sure you want to delete {count} selected rules? Global settings will be used after deletion."
96-
},
97-
"batchOperations": {
98-
"title": "Batch Operations",
99-
"hint": "Quick batch modify session settings",
100-
"scope": "Apply to",
101-
"scopeSelected": "Selected sessions",
102-
"scopeAll": "All sessions",
103-
"scopeGroup": "All groups",
104-
"scopePrivate": "All private chats",
105-
"llmStatus": "LLM Status",
106-
"ttsStatus": "TTS Status",
107-
"chatProvider": "Chat Model",
108-
"ttsProvider": "TTS Model",
109-
"apply": "Apply Changes"
110-
},
111-
"status": {
112-
"enabled": "Enabled",
113-
"disabled": "Disabled"
11496
},
11597
"batchOperations": {
11698
"title": "Batch Operations",
@@ -126,6 +108,25 @@
126108
"ttsProvider": "TTS Model",
127109
"apply": "Apply Changes"
128110
},
111+
"groups": {
112+
"title": "Group Management",
113+
"count": "{count} groups",
114+
"addToGroup": "Add to Group",
115+
"create": "Create Group",
116+
"edit": "Edit Group",
117+
"name": "Group Name",
118+
"sessionsCount": "{count} sessions",
119+
"empty": "No groups yet. Click 'Create Group' to create one.",
120+
"availableSessions": "Available Sessions ({count})",
121+
"selectedSessions": "Selected Sessions ({count})",
122+
"searchPlaceholder": "Search...",
123+
"noMatch": "No matches",
124+
"noMembers": "No members",
125+
"customGroupDivider": "── Custom Groups ──",
126+
"customGroupOption": "📁 {name} ({count})",
127+
"groupOption": "{name} ({count} sessions)",
128+
"deleteConfirm": "Are you sure you want to delete group \"{name}\"?"
129+
},
129130
"status": {
130131
"enabled": "Enabled",
131132
"disabled": "Disabled"
@@ -142,7 +143,16 @@
142143
"noChanges": "No changes to save",
143144
"batchDeleteSuccess": "Batch delete successful",
144145
"batchDeleteError": "Batch delete failed",
146+
"selectSessionsFirst": "Please select sessions first",
147+
"selectAtLeastOneConfig": "Please select at least one setting to modify",
148+
"batchUpdateSuccess": "Batch update successful",
149+
"partialUpdateFailed": "Some updates failed",
145150
"batchUpdateError": "Batch update failed",
146-
"batchUpdateSuccess": "Batch update success"
151+
"groupNameRequired": "Group name cannot be empty",
152+
"saveGroupError": "Failed to save group",
153+
"deleteGroupError": "Failed to delete group",
154+
"selectSessionsToAddFirst": "Please select sessions to add first",
155+
"addToGroupSuccess": "Added {count} sessions to the group",
156+
"addToGroupError": "Failed to add to group"
147157
}
148158
}

dashboard/src/i18n/locales/ru-RU/features/session-management.json

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,25 @@
108108
"ttsProvider": "TTS-модель",
109109
"apply": "Применить"
110110
},
111+
"groups": {
112+
"title": "Управление группами",
113+
"count": "групп: {count}",
114+
"addToGroup": "Добавить в группу",
115+
"create": "Создать группу",
116+
"edit": "Изменить группу",
117+
"name": "Имя группы",
118+
"sessionsCount": "сессий: {count}",
119+
"empty": "Пока нет групп. Нажмите «Создать группу», чтобы добавить.",
120+
"availableSessions": "Доступные сессии ({count})",
121+
"selectedSessions": "Выбранные сессии ({count})",
122+
"searchPlaceholder": "Поиск...",
123+
"noMatch": "Нет совпадений",
124+
"noMembers": "Нет участников",
125+
"customGroupDivider": "── Пользовательские группы ──",
126+
"customGroupOption": "📁 {name} ({count})",
127+
"groupOption": "{name} (сессий: {count})",
128+
"deleteConfirm": "Вы уверены, что хотите удалить группу \"{name}\"?"
129+
},
111130
"status": {
112131
"enabled": "Включено",
113132
"disabled": "Выключено"
@@ -124,7 +143,16 @@
124143
"noChanges": "Изменений не обнаружено",
125144
"batchDeleteSuccess": "Массовое удаление выполнено",
126145
"batchDeleteError": "Ошибка массового удаления",
146+
"selectSessionsFirst": "Пожалуйста, сначала выберите сессии",
147+
"selectAtLeastOneConfig": "Пожалуйста, выберите хотя бы одну настройку для изменения",
148+
"batchUpdateSuccess": "Пакетное обновление успешно выполнено",
149+
"partialUpdateFailed": "Некоторые обновления не выполнены",
127150
"batchUpdateError": "Ошибка пакетного обновления",
128-
"batchUpdateSuccess": "Пакетное обновление успешно выполнено"
151+
"groupNameRequired": "Имя группы не может быть пустым",
152+
"saveGroupError": "Ошибка сохранения группы",
153+
"deleteGroupError": "Ошибка удаления группы",
154+
"selectSessionsToAddFirst": "Пожалуйста, сначала выберите сессии для добавления",
155+
"addToGroupSuccess": "Добавлено сессий в группу: {count}",
156+
"addToGroupError": "Ошибка добавления в группу"
129157
}
130-
}
158+
}

dashboard/src/i18n/locales/zh-CN/features/session-management.json

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,25 @@
108108
"ttsProvider": "TTS 模型",
109109
"apply": "应用更改"
110110
},
111+
"groups": {
112+
"title": "分组管理",
113+
"count": "{count} 个分组",
114+
"addToGroup": "添加到分组",
115+
"create": "新建分组",
116+
"edit": "编辑分组",
117+
"name": "分组名称",
118+
"sessionsCount": "{count} 个会话",
119+
"empty": "暂无分组,点击「新建分组」创建",
120+
"availableSessions": "可选会话 ({count})",
121+
"selectedSessions": "已选会话 ({count})",
122+
"searchPlaceholder": "搜索...",
123+
"noMatch": "无匹配项",
124+
"noMembers": "暂无成员",
125+
"customGroupDivider": "── 自定义分组 ──",
126+
"customGroupOption": "📁 {name} ({count})",
127+
"groupOption": "{name} ({count} 个会话)",
128+
"deleteConfirm": "确定要删除分组 \"{name}\" 吗?"
129+
},
111130
"status": {
112131
"enabled": "启用",
113132
"disabled": "禁用"
@@ -123,6 +142,17 @@
123142
"deleteError": "删除失败",
124143
"noChanges": "没有需要保存的更改",
125144
"batchDeleteSuccess": "批量删除成功",
126-
"batchDeleteError": "批量删除失败"
145+
"batchDeleteError": "批量删除失败",
146+
"selectSessionsFirst": "请先选择要操作的会话",
147+
"selectAtLeastOneConfig": "请至少选择一项要修改的配置",
148+
"batchUpdateSuccess": "批量更新成功",
149+
"partialUpdateFailed": "部分更新失败",
150+
"batchUpdateError": "批量更新失败",
151+
"groupNameRequired": "分组名称不能为空",
152+
"saveGroupError": "保存分组失败",
153+
"deleteGroupError": "删除分组失败",
154+
"selectSessionsToAddFirst": "请先选择要添加的会话",
155+
"addToGroupSuccess": "已添加 {count} 个会话到分组",
156+
"addToGroupError": "添加失败"
127157
}
128158
}

dashboard/src/views/SessionManagementPage.vue

Lines changed: 35 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -156,24 +156,24 @@
156156
<!-- 分组管理面板 -->
157157
<v-card flat class="mt-4">
158158
<v-card-title class="d-flex align-center py-3 px-4">
159-
<span class="text-h6">分组管理</span>
159+
<span class="text-h6">{{ tm('groups.title') }}</span>
160160
<v-chip size="small" class="ml-2" color="secondary" variant="outlined">
161-
{{ groups.length }} 个分组
161+
{{ tm('groups.count', { count: groups.length }) }}
162162
</v-chip>
163163
<v-spacer></v-spacer>
164164
<v-btn v-if="selectedItems.length > 0 && groups.length > 0" color="info" variant="tonal" size="small" class="mr-2">
165165
<v-icon start>mdi-folder-plus</v-icon>
166-
添加到分组
166+
{{ tm('groups.addToGroup') }}
167167
<v-menu activator="parent">
168168
<v-list density="compact">
169169
<v-list-item v-for="g in groups" :key="g.id" @click="addSelectedToGroup(g.id)">
170-
<v-list-item-title>{{ g.name }} ({{ g.umo_count }})</v-list-item-title>
170+
<v-list-item-title>{{ tm('groups.customGroupOption', { name: g.name, count: g.umo_count }) }}</v-list-item-title>
171171
</v-list-item>
172172
</v-list>
173173
</v-menu>
174174
</v-btn>
175175
<v-btn color="success" variant="tonal" size="small" @click="openCreateGroupDialog" prepend-icon="mdi-folder-plus">
176-
新建分组
176+
{{ tm('groups.create') }}
177177
</v-btn>
178178
</v-card-title>
179179
<v-card-text v-if="groups.length > 0">
@@ -183,7 +183,7 @@
183183
<div class="d-flex align-center justify-space-between">
184184
<div>
185185
<div class="font-weight-bold">{{ group.name }}</div>
186-
<div class="text-caption text-grey">{{ group.umo_count }} 个会话</div>
186+
<div class="text-caption text-grey">{{ tm('groups.sessionsCount', { count: group.umo_count }) }}</div>
187187
</div>
188188
<div>
189189
<v-btn icon size="small" variant="text" @click="openEditGroupDialog(group)">
@@ -199,23 +199,23 @@
199199
</v-row>
200200
</v-card-text>
201201
<v-card-text v-else class="text-center text-grey py-6">
202-
暂无分组,点击「新建分组」创建
202+
{{ tm('groups.empty') }}
203203
</v-card-text>
204204
</v-card>
205205

206206
<!-- 分组编辑对话框 -->
207207
<v-dialog v-model="groupDialog" max-width="800" @after-enter="loadAvailableUmos">
208208
<v-card>
209209
<v-card-title class="py-3 px-4">
210-
{{ groupDialogMode === 'create' ? '新建分组' : '编辑分组' }}
210+
{{ groupDialogMode === 'create' ? tm('groups.create') : tm('groups.edit') }}
211211
</v-card-title>
212212
<v-card-text>
213-
<v-text-field v-model="editingGroup.name" label="分组名称" variant="outlined" hide-details class="mb-4"></v-text-field>
213+
<v-text-field v-model="editingGroup.name" :label="tm('groups.name')" variant="outlined" hide-details class="mb-4"></v-text-field>
214214
<v-row dense>
215215
<!-- 左侧:可选会话 -->
216216
<v-col cols="5">
217-
<div class="text-subtitle-2 mb-2">可选会话 ({{ unselectedUmos.length }})</div>
218-
<v-text-field v-model="groupMemberSearch" placeholder="搜索..." variant="outlined" density="compact" hide-details class="mb-2" clearable prepend-inner-icon="mdi-magnify"></v-text-field>
217+
<div class="text-subtitle-2 mb-2">{{ tm('groups.availableSessions', { count: unselectedUmos.length }) }}</div>
218+
<v-text-field v-model="groupMemberSearch" :placeholder="tm('groups.searchPlaceholder')" variant="outlined" density="compact" hide-details class="mb-2" clearable prepend-inner-icon="mdi-magnify"></v-text-field>
219219
<v-list density="compact" class="transfer-list" lines="one">
220220
<v-list-item v-for="umo in filteredUnselectedUmos" :key="umo" @click="addToGroup(umo)" class="transfer-item">
221221
<template v-slot:prepend>
@@ -224,7 +224,7 @@
224224
<v-list-item-title class="text-caption">{{ formatUmoShort(umo) }}</v-list-item-title>
225225
</v-list-item>
226226
<v-list-item v-if="filteredUnselectedUmos.length === 0 && !loadingUmos">
227-
<v-list-item-title class="text-caption text-grey text-center">无匹配项</v-list-item-title>
227+
<v-list-item-title class="text-caption text-grey text-center">{{ tm('groups.noMatch') }}</v-list-item-title>
228228
</v-list-item>
229229
<v-list-item v-if="loadingUmos">
230230
<v-list-item-title class="text-center"><v-progress-circular indeterminate size="20"></v-progress-circular></v-list-item-title>
@@ -242,8 +242,8 @@
242242
</v-col>
243243
<!-- 右侧:已选会话 -->
244244
<v-col cols="5">
245-
<div class="text-subtitle-2 mb-2">已选会话 ({{ editingGroup.umos.length }})</div>
246-
<v-text-field v-model="groupSelectedSearch" placeholder="搜索..." variant="outlined" density="compact" hide-details class="mb-2" clearable prepend-inner-icon="mdi-magnify"></v-text-field>
245+
<div class="text-subtitle-2 mb-2">{{ tm('groups.selectedSessions', { count: editingGroup.umos.length }) }}</div>
246+
<v-text-field v-model="groupSelectedSearch" :placeholder="tm('groups.searchPlaceholder')" variant="outlined" density="compact" hide-details class="mb-2" clearable prepend-inner-icon="mdi-magnify"></v-text-field>
247247
<v-list density="compact" class="transfer-list" lines="one">
248248
<v-list-item v-for="umo in filteredSelectedUmos" :key="umo" @click="removeFromGroup(umo)" class="transfer-item">
249249
<template v-slot:prepend>
@@ -252,16 +252,16 @@
252252
<v-list-item-title class="text-caption">{{ formatUmoShort(umo) }}</v-list-item-title>
253253
</v-list-item>
254254
<v-list-item v-if="editingGroup.umos.length === 0">
255-
<v-list-item-title class="text-caption text-grey text-center">暂无成员</v-list-item-title>
255+
<v-list-item-title class="text-caption text-grey text-center">{{ tm('groups.noMembers') }}</v-list-item-title>
256256
</v-list-item>
257257
</v-list>
258258
</v-col>
259259
</v-row>
260260
</v-card-text>
261261
<v-card-actions class="px-4 pb-4">
262262
<v-spacer></v-spacer>
263-
<v-btn variant="text" @click="groupDialog = false">取消</v-btn>
264-
<v-btn color="primary" variant="tonal" @click="saveGroup">保存</v-btn>
263+
<v-btn variant="text" @click="groupDialog = false">{{ tm('buttons.cancel') }}</v-btn>
264+
<v-btn color="primary" variant="tonal" @click="saveGroup">{{ tm('buttons.save') }}</v-btn>
265265
</v-card-actions>
266266
</v-card>
267267
</v-dialog>
@@ -721,17 +721,20 @@ export default {
721721
]
722722
// 添加自定义分组选项
723723
if (this.groups.length > 0) {
724-
options.push({ label: '── 自定义分组 ──', value: '_divider', disabled: true })
724+
options.push({ label: this.tm('groups.customGroupDivider'), value: '_divider', disabled: true })
725725
this.groups.forEach(g => {
726-
options.push({ label: `📁 ${g.name} (${g.umo_count})`, value: `custom_group:${g.id}` })
726+
options.push({
727+
label: this.tm('groups.customGroupOption', { name: g.name, count: g.umo_count }),
728+
value: `custom_group:${g.id}`
729+
})
727730
})
728731
}
729732
return options
730733
},
731734
732735
groupOptions() {
733736
return this.groups.map(g => ({
734-
label: `${g.name} (${g.umo_count} 个会话)`,
737+
label: this.tm('groups.groupOption', { name: g.name, count: g.umo_count }),
735738
value: g.id
736739
}))
737740
},
@@ -1331,7 +1334,7 @@ export default {
13311334
if (scope === 'selected') {
13321335
umos = this.selectedItems.map(item => item.umo)
13331336
if (umos.length === 0) {
1334-
this.showError('请先选择要操作的会话')
1337+
this.showError(this.tm('messages.selectSessionsFirst'))
13351338
this.batchUpdating = false
13361339
return
13371340
}
@@ -1371,7 +1374,7 @@ export default {
13711374
}
13721375
13731376
if (tasks.length === 0) {
1374-
this.showError('请至少选择一项要修改的配置')
1377+
this.showError(this.tm('messages.selectAtLeastOneConfig'))
13751378
this.batchUpdating = false
13761379
return
13771380
}
@@ -1380,17 +1383,17 @@ export default {
13801383
const allOk = results.every(r => r.data.status === 'ok')
13811384
13821385
if (allOk) {
1383-
this.showSuccess('批量更新成功')
1386+
this.showSuccess(this.tm('messages.batchUpdateSuccess'))
13841387
this.batchLlmStatus = null
13851388
this.batchTtsStatus = null
13861389
this.batchChatProvider = null
13871390
this.batchTtsProvider = null
13881391
await this.loadData()
13891392
} else {
1390-
this.showError('部分更新失败')
1393+
this.showError(this.tm('messages.partialUpdateFailed'))
13911394
}
13921395
} catch (error) {
1393-
this.showError(error.response?.data?.message || '批量更新失败')
1396+
this.showError(error.response?.data?.message || this.tm('messages.batchUpdateError'))
13941397
}
13951398
this.batchUpdating = false
13961399
},
@@ -1477,7 +1480,7 @@ export default {
14771480
14781481
async saveGroup() {
14791482
if (!this.editingGroup.name.trim()) {
1480-
this.showError('分组名称不能为空')
1483+
this.showError(this.tm('messages.groupNameRequired'))
14811484
return
14821485
}
14831486
@@ -1504,12 +1507,12 @@ export default {
15041507
this.showError(response.data.message)
15051508
}
15061509
} catch (error) {
1507-
this.showError(error.response?.data?.message || '保存分组失败')
1510+
this.showError(error.response?.data?.message || this.tm('messages.saveGroupError'))
15081511
}
15091512
},
15101513
15111514
async deleteGroup(group) {
1512-
const message = `确定要删除分组 "${group.name}" 吗?`
1515+
const message = this.tm('groups.deleteConfirm', { name: group.name })
15131516
if (!(await askForConfirmationDialog(message, this.confirmDialog))) return
15141517
15151518
try {
@@ -1521,7 +1524,7 @@ export default {
15211524
this.showError(response.data.message)
15221525
}
15231526
} catch (error) {
1524-
this.showError(error.response?.data?.message || '删除分组失败')
1527+
this.showError(error.response?.data?.message || this.tm('messages.deleteGroupError'))
15251528
}
15261529
},
15271530
@@ -1532,7 +1535,7 @@ export default {
15321535
15331536
async addSelectedToGroup(groupId) {
15341537
if (this.selectedItems.length === 0) {
1535-
this.showError('请先选择要添加的会话')
1538+
this.showError(this.tm('messages.selectSessionsToAddFirst'))
15361539
return
15371540
}
15381541
@@ -1542,13 +1545,13 @@ export default {
15421545
add_umos: this.selectedItems.map(item => item.umo)
15431546
})
15441547
if (response.data.status === 'ok') {
1545-
this.showSuccess(`已添加 ${this.selectedItems.length} 个会话到分组`)
1548+
this.showSuccess(this.tm('messages.addToGroupSuccess', { count: this.selectedItems.length }))
15461549
await this.loadGroups()
15471550
} else {
15481551
this.showError(response.data.message)
15491552
}
15501553
} catch (error) {
1551-
this.showError(error.response?.data?.message || '添加失败')
1554+
this.showError(error.response?.data?.message || this.tm('messages.addToGroupError'))
15521555
}
15531556
},
15541557
},

0 commit comments

Comments
 (0)