mirror of
https://github.com/langbot-app/LangBot.git
synced 2026-06-22 13:34:24 +00:00
fix(web): stop spurious page refresh on account menu open; plugin log auto-refresh as switch
Two unrelated frontend fixes: - LanguageSelector mounts each time the sidebar account dropdown opens and unconditionally called i18n.changeLanguage() on mount, emitting a languageChanged event even when the language was unchanged. That handed every useTranslation() consumer a fresh `t` reference, re-running effects keyed on `t` (e.g. the plugins page system-status fetch) and surfacing as a page "refresh". Guard the call so it only fires on an actual change. - Plugin logs auto-refresh control changed from a toggle Button to a Switch + Label; the on/off button i18n keys are replaced by a single static logsAutoRefresh label across all 8 locales.
This commit is contained in:
@@ -3,6 +3,8 @@ import { httpClient } from '@/app/infra/http/HttpClient';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { PluginLogEntry } from '@/app/infra/entities/plugin';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Switch } from '@/components/ui/switch';
|
||||
import { Label } from '@/components/ui/label';
|
||||
import {
|
||||
Select,
|
||||
SelectContent,
|
||||
@@ -116,17 +118,19 @@ export default function PluginLogs({
|
||||
/>
|
||||
{t('plugins.logsRefresh')}
|
||||
</Button>
|
||||
<Button
|
||||
type="button"
|
||||
variant={autoRefresh ? 'default' : 'outline'}
|
||||
size="sm"
|
||||
className="h-8"
|
||||
onClick={() => setAutoRefresh((v) => !v)}
|
||||
>
|
||||
{autoRefresh
|
||||
? t('plugins.logsAutoRefreshOn')
|
||||
: t('plugins.logsAutoRefreshOff')}
|
||||
</Button>
|
||||
<div className="flex items-center gap-2">
|
||||
<Switch
|
||||
id="plugin-logs-auto-refresh"
|
||||
checked={autoRefresh}
|
||||
onCheckedChange={setAutoRefresh}
|
||||
/>
|
||||
<Label
|
||||
htmlFor="plugin-logs-auto-refresh"
|
||||
className="cursor-pointer text-sm font-normal text-muted-foreground"
|
||||
>
|
||||
{t('plugins.logsAutoRefresh')}
|
||||
</Label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
|
||||
@@ -56,7 +56,16 @@ export function LanguageSelector({
|
||||
|
||||
const savedLanguage = localStorage.getItem('langbot_language');
|
||||
if (savedLanguage) {
|
||||
i18n.changeLanguage(savedLanguage);
|
||||
// Only switch when the active language actually differs. Calling
|
||||
// i18n.changeLanguage() unconditionally on every mount emits a
|
||||
// `languageChanged` event even when nothing changed, which hands every
|
||||
// useTranslation() consumer a fresh `t` reference and re-runs effects
|
||||
// that depend on `t` (e.g. data refetches). Since this selector mounts
|
||||
// each time the account dropdown opens, that surfaced as a spurious
|
||||
// page "refresh". Guard the call to keep mounts side-effect-free.
|
||||
if (i18n.language !== savedLanguage) {
|
||||
i18n.changeLanguage(savedLanguage);
|
||||
}
|
||||
setCurrentLanguage(savedLanguage);
|
||||
} else {
|
||||
const browserLanguage = navigator.language;
|
||||
|
||||
@@ -593,8 +593,7 @@ const enUS = {
|
||||
tabLogs: 'Logs',
|
||||
logsLevelAll: 'All levels',
|
||||
logsRefresh: 'Refresh',
|
||||
logsAutoRefreshOn: 'Auto-refresh: On',
|
||||
logsAutoRefreshOff: 'Auto-refresh: Off',
|
||||
logsAutoRefresh: 'Auto-refresh',
|
||||
logsEmpty:
|
||||
'No logs yet. Logs printed by the plugin via logger will appear here.',
|
||||
fileUpload: {
|
||||
|
||||
@@ -605,8 +605,7 @@ const esES = {
|
||||
tabLogs: 'Registros',
|
||||
logsLevelAll: 'Todos los niveles',
|
||||
logsRefresh: 'Actualizar',
|
||||
logsAutoRefreshOn: 'Auto-actualizar: Activado',
|
||||
logsAutoRefreshOff: 'Auto-actualizar: Desactivado',
|
||||
logsAutoRefresh: 'Auto-actualizar',
|
||||
logsEmpty:
|
||||
'Aún no hay registros. Los registros que el plugin imprima mediante logger aparecerán aquí.',
|
||||
fileUpload: {
|
||||
|
||||
@@ -598,8 +598,7 @@ const jaJP = {
|
||||
tabLogs: 'ログ',
|
||||
logsLevelAll: 'すべてのレベル',
|
||||
logsRefresh: '更新',
|
||||
logsAutoRefreshOn: '自動更新:オン',
|
||||
logsAutoRefreshOff: '自動更新:オフ',
|
||||
logsAutoRefresh: '自動更新',
|
||||
logsEmpty:
|
||||
'ログはまだありません。プラグインが logger で出力したログがここに表示されます。',
|
||||
fileUpload: {
|
||||
|
||||
@@ -604,8 +604,7 @@ const ruRU = {
|
||||
tabLogs: 'Журналы',
|
||||
logsLevelAll: 'Все уровни',
|
||||
logsRefresh: 'Обновить',
|
||||
logsAutoRefreshOn: 'Автообновление: вкл.',
|
||||
logsAutoRefreshOff: 'Автообновление: выкл.',
|
||||
logsAutoRefresh: 'Автообновление',
|
||||
logsEmpty:
|
||||
'Журналов пока нет. Здесь появятся логи, выводимые плагином через logger.',
|
||||
fileUpload: {
|
||||
|
||||
@@ -585,8 +585,7 @@ const thTH = {
|
||||
tabLogs: 'บันทึก',
|
||||
logsLevelAll: 'ทุกระดับ',
|
||||
logsRefresh: 'รีเฟรช',
|
||||
logsAutoRefreshOn: 'รีเฟรชอัตโนมัติ: เปิด',
|
||||
logsAutoRefreshOff: 'รีเฟรชอัตโนมัติ: ปิด',
|
||||
logsAutoRefresh: 'รีเฟรชอัตโนมัติ',
|
||||
logsEmpty: 'ยังไม่มีบันทึก บันทึกที่ปลั๊กอินพิมพ์ผ่าน logger จะแสดงที่นี่',
|
||||
fileUpload: {
|
||||
tooLarge: 'ขนาดไฟล์เกินขีดจำกัด 10MB',
|
||||
|
||||
@@ -599,8 +599,7 @@ const viVN = {
|
||||
tabLogs: 'Nhật ký',
|
||||
logsLevelAll: 'Tất cả cấp độ',
|
||||
logsRefresh: 'Làm mới',
|
||||
logsAutoRefreshOn: 'Tự động làm mới: Bật',
|
||||
logsAutoRefreshOff: 'Tự động làm mới: Tắt',
|
||||
logsAutoRefresh: 'Tự động làm mới',
|
||||
logsEmpty:
|
||||
'Chưa có nhật ký. Nhật ký do plugin in qua logger sẽ hiển thị ở đây.',
|
||||
fileUpload: {
|
||||
|
||||
@@ -566,8 +566,7 @@ const zhHans = {
|
||||
tabLogs: '日志',
|
||||
logsLevelAll: '全部级别',
|
||||
logsRefresh: '刷新',
|
||||
logsAutoRefreshOn: '自动刷新:开',
|
||||
logsAutoRefreshOff: '自动刷新:关',
|
||||
logsAutoRefresh: '自动刷新',
|
||||
logsEmpty: '暂无日志。插件通过 logger 打印的日志会显示在这里。',
|
||||
fileUpload: {
|
||||
tooLarge: '文件大小超过 10MB 限制',
|
||||
|
||||
@@ -566,8 +566,7 @@ const zhHant = {
|
||||
tabLogs: '日誌',
|
||||
logsLevelAll: '全部級別',
|
||||
logsRefresh: '重新整理',
|
||||
logsAutoRefreshOn: '自動重新整理:開',
|
||||
logsAutoRefreshOff: '自動重新整理:關',
|
||||
logsAutoRefresh: '自動重新整理',
|
||||
logsEmpty: '暫無日誌。外掛透過 logger 列印的日誌會顯示在這裡。',
|
||||
fileUpload: {
|
||||
tooLarge: '檔案大小超過 10MB 限制',
|
||||
|
||||
Reference in New Issue
Block a user