Skip to content

Commit f05d169

Browse files
authored
Merge pull request #43 from open-webui/main
0.4.1
2 parents 9f5b03a + 8d59ed6 commit f05d169

17 files changed

Lines changed: 741 additions & 148 deletions

File tree

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,14 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [0.4.1] - 2026-06-13
9+
10+
### Changed
11+
12+
- 🌍 **i18n for tool servers, browser, and web settings.** Replaced all remaining hardcoded English strings in the Tool Servers, Web/Browser, and admin panels with translation keys. Added ~60 new keys per locale across all 10 languages (de, en, es, fr, ja, ko, pt-BR, ru, zh-CN, zh-TW).
13+
- 🎨 **General settings layout refactor.** Reorganised the General settings panel into a scrollable layout with grouped sections (Notifications, Updates, Message Queue). Webhook URL input is now full-width with a hint instead of an inline save button. The save button now shows a loading/saving state.
14+
- 🖱️ **Scrollbar-on-hover utility.** Added a `.scrollbar-hover` CSS class that hides scrollbar thumbs until the user hovers, reducing visual clutter in scrollable panels.
15+
816
## [0.4.0] - 2026-06-13
917

1018
### Added

cptr/frontend/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "frontend",
33
"private": true,
4-
"version": "0.4.0",
4+
"version": "0.4.1",
55
"type": "module",
66
"scripts": {
77
"dev": "vite dev",

cptr/frontend/src/app.css

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,13 @@
9090
display: none;
9191
}
9292

93+
.scrollbar-hover::-webkit-scrollbar-thumb {
94+
visibility: hidden;
95+
}
96+
.scrollbar-hover:hover::-webkit-scrollbar-thumb {
97+
visibility: visible;
98+
}
99+
93100
/* CodeMirror - match Open WebUI */
94101
.cm-editor {
95102
height: 100%;

cptr/frontend/src/lib/components/Admin/ToolServers.svelte

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -156,9 +156,9 @@
156156
try {
157157
verifyResult = await verifyToolServer(editServer.id);
158158
if (verifyResult.ok) toast.success($t('toolServers.connected'));
159-
else toast.error(verifyResult.message || 'Connection failed');
159+
else toast.error(verifyResult.message || $t('toolServers.connectionFailed'));
160160
} catch (e: any) {
161-
verifyResult = { ok: false, message: e?.message || 'Connection failed' };
161+
verifyResult = { ok: false, message: e?.message || $t('toolServers.connectionFailed') };
162162
toast.error(verifyResult.message!);
163163
} finally {
164164
verifying = false;
@@ -269,7 +269,7 @@
269269
>
270270
<input
271271
type="text"
272-
placeholder="my_server"
272+
placeholder={$t('toolServers.idPlaceholder')}
273273
bind:value={formId}
274274
autofocus
275275
autocomplete="off"
@@ -286,8 +286,8 @@
286286
bind:value={formType}
287287
class="block w-full bg-transparent text-[13px] text-gray-700 dark:text-gray-300 outline-none py-0.5 cursor-pointer"
288288
>
289-
<option value="openapi">OpenAPI</option>
290-
<option value="mcp">MCP</option>
289+
<option value="openapi">{$t('toolServers.typeOpenAPI')}</option>
290+
<option value="mcp">{$t('toolServers.typeMCP')}</option>
291291
</select>
292292
</div>
293293
</div>
@@ -298,7 +298,7 @@
298298
>
299299
<input
300300
type="text"
301-
placeholder="Optional display name"
301+
placeholder={$t('toolServers.namePlaceholder')}
302302
bind:value={formName}
303303
autocomplete="off"
304304
spellcheck="false"
@@ -356,7 +356,7 @@
356356
>
357357
<input
358358
type="password"
359-
placeholder={editServer ? '•••••••• (leave blank to keep)' : 'sk-...'}
359+
placeholder={editServer ? $t('toolServers.apiKeyKeep') : 'sk-...'}
360360
bind:value={formKey}
361361
autocomplete="new-password"
362362
class="block w-full bg-transparent text-[13px] text-gray-700 dark:text-gray-300 placeholder:text-gray-300 dark:placeholder:text-gray-700 outline-none py-0.5 font-mono"

cptr/frontend/src/lib/components/Admin/Web.svelte

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@
122122
<div class="flex justify-center py-8"><Spinner size={16} /></div>
123123
{:else}
124124
<!-- Search -->
125-
<h3 class="text-xs text-gray-400 dark:text-gray-600 mb-2">Search</h3>
125+
<h3 class="text-xs text-gray-400 dark:text-gray-600 mb-2">{$t('admin.webSearch')}</h3>
126126

127127
<div class="flex flex-col gap-2.5">
128128
<label class="flex items-center justify-between cursor-pointer">
@@ -207,58 +207,58 @@
207207
</div>
208208

209209
<!-- Browser -->
210-
<h3 class="text-xs text-gray-400 dark:text-gray-600 mb-2 mt-5">Browser</h3>
210+
<h3 class="text-xs text-gray-400 dark:text-gray-600 mb-2 mt-5">{$t('admin.browser')}</h3>
211211

212212
<div class="flex flex-col gap-2.5">
213213
<label class="flex items-center justify-between cursor-pointer">
214-
<span class="text-xs text-gray-600 dark:text-gray-400">Browser tools</span>
214+
<span class="text-xs text-gray-600 dark:text-gray-400">{$t('admin.browserTools')}</span>
215215
<ToggleSwitch value={browserEnabled} onchange={(v) => { browserEnabled = v; }} />
216216
</label>
217217
<p class="text-[11px] text-gray-400 dark:text-gray-600 -mt-1">
218-
Give the AI access to a web browser for navigating pages, clicking elements, and taking screenshots.
218+
{$t('admin.browserHint')}
219219
</p>
220220

221221
{#if browserEnabled}
222222
<div class="flex items-center justify-between">
223-
<span class="text-xs text-gray-600 dark:text-gray-400">Provider</span>
223+
<span class="text-xs text-gray-600 dark:text-gray-400">{$t('admin.browserProvider')}</span>
224224
<select
225225
bind:value={browserProvider}
226226
class="bg-transparent text-xs text-gray-600 dark:text-gray-400 outline-none cursor-pointer"
227227
>
228-
<option value="local">Local CDP</option>
229-
<option value="firecrawl">Firecrawl</option>
230-
<option value="browser_use">Browser-Use</option>
228+
<option value="local">{$t('admin.browserLocalCdp')}</option>
229+
<option value="firecrawl">{$t('admin.browserFirecrawl')}</option>
230+
<option value="browser_use">{$t('admin.browserBrowserUse')}</option>
231231
</select>
232232
</div>
233233
<p class="text-[11px] text-gray-400 dark:text-gray-600 -mt-1">
234234
{#if browserProvider === 'local'}
235-
Connects to Chrome via DevTools Protocol. Full interactive browsing with clicking, typing, and screenshots.
235+
{$t('admin.browserLocalHint')}
236236
{:else if browserProvider === 'firecrawl'}
237-
Cloud API that converts web pages to markdown. Fast extraction, no interactive browsing.
237+
{$t('admin.browserFirecrawlHint')}
238238
{:else}
239-
Cloud API for LLM-driven browser tasks. Describe what you need in natural language.
239+
{$t('admin.browserBrowserUseHint')}
240240
{/if}
241241
</p>
242242

243243
{#if browserProvider === 'local'}
244244
<label class="flex items-center justify-between cursor-pointer">
245245
<div>
246-
<span class="text-xs text-gray-600 dark:text-gray-400">Auto-launch Chrome</span>
247-
<p class="text-[10px] text-gray-400 dark:text-gray-600">Start a headless Chrome if none is running</p>
246+
<span class="text-xs text-gray-600 dark:text-gray-400">{$t('admin.browserAutoLaunch')}</span>
247+
<p class="text-[10px] text-gray-400 dark:text-gray-600">{$t('admin.browserAutoLaunchHint')}</p>
248248
</div>
249249
<ToggleSwitch value={autoLaunch} onchange={(v) => { autoLaunch = v; }} />
250250
</label>
251251

252252
<div>
253-
<label class="text-xs text-gray-600 dark:text-gray-400" for="cdp-url">CDP URL</label>
253+
<label class="text-xs text-gray-600 dark:text-gray-400" for="cdp-url">{$t('admin.browserCdpUrl')}</label>
254254
<div class="flex gap-1.5 mt-1">
255255
<input id="cdp-url" type="text" bind:value={cdpUrl} placeholder="http://localhost:9222"
256256
class="flex-1 h-7 px-2 rounded-lg text-xs bg-gray-100 dark:bg-white/6 text-gray-700 dark:text-gray-300 border border-gray-200 dark:border-white/8 outline-none focus:border-blue-400 dark:focus:border-blue-500 transition-colors" />
257257
<button
258258
class="h-7 px-2.5 rounded-lg text-xs bg-gray-200/50 dark:bg-white/8 text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-white transition-colors disabled:opacity-50"
259259
onclick={() => testConnection()}
260260
disabled={testing}
261-
>{testing ? '...' : 'Test'}</button>
261+
>{testing ? '...' : $t('admin.browserTest')}</button>
262262
</div>
263263
{#if testResult}
264264
<p class="text-[11px] mt-1 {testResult.ok ? 'text-emerald-600 dark:text-emerald-400' : 'text-red-500'}">
@@ -268,33 +268,33 @@
268268
</div>
269269

270270
<div>
271-
<label class="text-xs text-gray-600 dark:text-gray-400" for="session-timeout">Session timeout</label>
271+
<label class="text-xs text-gray-600 dark:text-gray-400" for="session-timeout">{$t('admin.browserSessionTimeout')}</label>
272272
<div class="flex items-center gap-1.5 mt-1">
273273
<input id="session-timeout" type="number" bind:value={sessionTimeout} min="1" max="120"
274274
class="w-16 h-7 px-2 rounded-lg text-xs bg-gray-100 dark:bg-white/6 text-gray-700 dark:text-gray-300 border border-gray-200 dark:border-white/8 outline-none focus:border-blue-400 dark:focus:border-blue-500 transition-colors" />
275-
<span class="text-[11px] text-gray-400 dark:text-gray-600">minutes</span>
275+
<span class="text-[11px] text-gray-400 dark:text-gray-600">{$t('admin.browserMinutes')}</span>
276276
</div>
277277
</div>
278278
{:else if browserProvider === 'firecrawl'}
279279
<div>
280-
<label class="text-xs text-gray-600 dark:text-gray-400" for="fc-key">API Key</label>
280+
<label class="text-xs text-gray-600 dark:text-gray-400" for="fc-key">{$t('admin.browserApiKey')}</label>
281281
<input id="fc-key" type="password" bind:value={firecrawlApiKey} placeholder="fc-..."
282282
class="w-full mt-1 h-7 px-2 rounded-lg text-xs bg-gray-100 dark:bg-white/6 text-gray-700 dark:text-gray-300 border border-gray-200 dark:border-white/8 outline-none focus:border-blue-400 dark:focus:border-blue-500 transition-colors" />
283283
</div>
284284
<div>
285-
<label class="text-xs text-gray-600 dark:text-gray-400" for="fc-url">Base URL</label>
285+
<label class="text-xs text-gray-600 dark:text-gray-400" for="fc-url">{$t('admin.browserBaseUrl')}</label>
286286
<input id="fc-url" type="text" bind:value={firecrawlBaseUrl} placeholder="https://api.firecrawl.dev"
287287
class="w-full mt-1 h-7 px-2 rounded-lg text-xs bg-gray-100 dark:bg-white/6 text-gray-700 dark:text-gray-300 border border-gray-200 dark:border-white/8 outline-none focus:border-blue-400 dark:focus:border-blue-500 transition-colors" />
288-
<p class="text-[11px] text-gray-400 dark:text-gray-600 mt-0.5">Change for self-hosted Firecrawl instances</p>
288+
<p class="text-[11px] text-gray-400 dark:text-gray-600 mt-0.5">{$t('admin.browserFirecrawlBaseUrlHint')}</p>
289289
</div>
290290
{:else if browserProvider === 'browser_use'}
291291
<div>
292-
<label class="text-xs text-gray-600 dark:text-gray-400" for="bu-key">API Key</label>
292+
<label class="text-xs text-gray-600 dark:text-gray-400" for="bu-key">{$t('admin.browserApiKey')}</label>
293293
<input id="bu-key" type="password" bind:value={browserUseApiKey} placeholder="bu-..."
294294
class="w-full mt-1 h-7 px-2 rounded-lg text-xs bg-gray-100 dark:bg-white/6 text-gray-700 dark:text-gray-300 border border-gray-200 dark:border-white/8 outline-none focus:border-blue-400 dark:focus:border-blue-500 transition-colors" />
295295
</div>
296296
<div>
297-
<label class="text-xs text-gray-600 dark:text-gray-400" for="bu-url">Base URL</label>
297+
<label class="text-xs text-gray-600 dark:text-gray-400" for="bu-url">{$t('admin.browserBaseUrl')}</label>
298298
<input id="bu-url" type="text" bind:value={browserUseBaseUrl} placeholder="https://api.browser-use.com"
299299
class="w-full mt-1 h-7 px-2 rounded-lg text-xs bg-gray-100 dark:bg-white/6 text-gray-700 dark:text-gray-300 border border-gray-200 dark:border-white/8 outline-none focus:border-blue-400 dark:focus:border-blue-500 transition-colors" />
300300
</div>

0 commit comments

Comments
 (0)