setValue(e.target.value)}
@@ -58,17 +134,20 @@ export function SettingInput({ setting, onUpdate, disabled }: SettingInputProps)
if (e.key === 'Escape') handleCancel()
}}
autoFocus
- className="bg-dark-700 border border-accent-500 rounded-lg px-3 py-1.5 text-sm text-dark-100 focus:outline-none w-32"
+ placeholder="Введите значение..."
+ className="bg-dark-700 border border-accent-500 rounded-lg px-3 py-2 text-sm text-dark-100 focus:outline-none focus:ring-2 focus:ring-accent-500/30 w-48 sm:w-56"
/>
@@ -76,14 +155,38 @@ export function SettingInput({ setting, onUpdate, disabled }: SettingInputProps)
)
}
- // Display mode
+ // Display mode - Long value preview
+ if (needsTextarea) {
+ const displayValue = currentValue || '-'
+ const previewValue = displayValue.length > 60 ? displayValue.slice(0, 60) + '...' : displayValue
+
+ return (
+
+ )
+ }
+
+ // Display mode - Short value
return (
)
}
diff --git a/src/components/admin/SettingRow.tsx b/src/components/admin/SettingRow.tsx
index a607f81..d2cbe7d 100644
--- a/src/components/admin/SettingRow.tsx
+++ b/src/components/admin/SettingRow.tsx
@@ -30,75 +30,137 @@ export function SettingRow({
const displayName = t(`admin.settings.settingNames.${formattedKey}`, formattedKey)
const description = setting.hint?.description ? stripHtml(setting.hint.description) : null
+ // Check if this is a long/complex value
+ const isLongValue = (() => {
+ const val = String(setting.current ?? '')
+ const key = setting.key.toLowerCase()
+ return (
+ val.length > 50 ||
+ val.includes('\n') ||
+ val.startsWith('[') ||
+ val.startsWith('{') ||
+ key.includes('_items') ||
+ key.includes('_config') ||
+ key.includes('_keywords') ||
+ key.includes('_template') ||
+ key.includes('_packages')
+ )
+ })()
+
return (
-
- {/* Top row - name and badge */}
-
+
+ {/* Header row - name, badges, favorite */}
+
- {displayName}
+
{displayName}
{setting.has_override && (
-
+
{t('admin.settings.modified')}
)}
+ {setting.read_only && (
+
+
+ {t('admin.settings.readOnly')}
+
+ )}
{description && (
-
{description}
+
{description}
)}
{/* Favorite button */}
- {/* Bottom row - control */}
-
-
{setting.key}
+ {/* Setting key (muted) */}
+
+
+ {setting.key}
+
+
-
- {/* Setting control */}
- {setting.read_only ? (
-
-
-
{String(setting.current ?? '-')}
+ {/* Control section */}
+
+ {setting.read_only ? (
+ // Read-only display
+
+ {String(setting.current ?? '-')}
+
+ ) : setting.type === 'bool' ? (
+ // Boolean toggle
+
+
+ {setting.current === true || setting.current === 'true' ? 'Включено' : 'Выключено'}
+
+
+ onUpdate(setting.current === true || setting.current === 'true' ? 'false' : 'true')}
+ disabled={isUpdating}
+ />
+ {/* Reset button for boolean */}
+ {setting.has_override && (
+
+ )}
- ) : setting.type === 'bool' ? (
-
onUpdate(setting.current === true || setting.current === 'true' ? 'false' : 'true')}
- disabled={isUpdating}
- />
- ) : (
+
+ ) : (
+ // Input field
+
- )}
-
- {/* Reset button */}
- {setting.has_override && !setting.read_only && (
-
- )}
-
+ {/* Reset button for non-long values */}
+ {!isLongValue && setting.has_override && (
+
+ )}
+
+ )}
+
+ {/* Reset button for long values - shown below */}
+ {isLongValue && setting.has_override && !setting.read_only && setting.type !== 'bool' && (
+
+
+
+ )}
)
}
diff --git a/src/components/admin/SettingsTab.tsx b/src/components/admin/SettingsTab.tsx
index 44d74ee..29ef0e4 100644
--- a/src/components/admin/SettingsTab.tsx
+++ b/src/components/admin/SettingsTab.tsx
@@ -66,7 +66,7 @@ export function SettingsTab({
{t('admin.settings.noSettings')}
) : (
-
+
{filteredSettings.map((setting) => (
-
+
{cat.settings.map((setting) => (
(
)
+
+export const EditIcon = () => (
+
+)
diff --git a/src/locales/ru.json b/src/locales/ru.json
index a0f9ea3..a4a08fa 100644
--- a/src/locales/ru.json
+++ b/src/locales/ru.json
@@ -1191,7 +1191,7 @@
"POSTGRES": "PostgreSQL",
"SQLITE": "SQLite",
"REDIS": "Redis",
- "CORE": "Ядро",
+ "CORE": "Бот",
"REMNAWAVE": "RemnaWave",
"SERVER_STATUS": "Статус сервера",
"MONITORING": "Мониторинг",