Fix automation badge overflow, dashboard crosslinks, compact numbers, icon grids, OpenRGB brightness
UI fixes: - Automation card badge moved to flex layout — title truncates, badge stays visible - Automation condition pills max-width increased to 280px - Dashboard crosslinks fixed: pass correct sub-tab key (led-targets not led) - navigateToCard only skips data load when tab already has cards in DOM - Badge gets white-space:nowrap + flex-shrink:0 to prevent wrapping New features: - formatCompact() for large frame/error counters (1.2M, 45.2K) with hover title - Log filter and log level selects replaced with IconSelect grids - OpenRGB devices now support software brightness control OpenRGB improvements: - Added brightness_control capability (uses software brightness fallback) - Change-threshold dedup compares raw pixels before brightness scaling Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -8,6 +8,7 @@ import { Modal } from '../core/modal.js';
|
||||
import { showToast, showConfirm } from '../core/ui.js';
|
||||
import { t } from '../core/i18n.js';
|
||||
import { ICON_UNDO, ICON_DOWNLOAD } from '../core/icons.js';
|
||||
import { IconSelect } from '../core/icon-select.js';
|
||||
|
||||
// ─── Log Viewer ────────────────────────────────────────────
|
||||
|
||||
@@ -130,9 +131,53 @@ export function applyLogFilter() {
|
||||
// Simple modal (no form / no dirty check needed)
|
||||
const settingsModal = new Modal('settings-modal');
|
||||
|
||||
let _logFilterIconSelect = null;
|
||||
let _logLevelIconSelect = null;
|
||||
|
||||
const _LOG_LEVEL_ITEMS = [
|
||||
{ value: 'DEBUG', icon: '<span style="color:#9e9e9e;font-weight:700">D</span>', label: 'DEBUG', desc: t('settings.log_level.desc.debug') },
|
||||
{ value: 'INFO', icon: '<span style="color:#4fc3f7;font-weight:700">I</span>', label: 'INFO', desc: t('settings.log_level.desc.info') },
|
||||
{ value: 'WARNING', icon: '<span style="color:#ffb74d;font-weight:700">W</span>', label: 'WARNING', desc: t('settings.log_level.desc.warning') },
|
||||
{ value: 'ERROR', icon: '<span style="color:#ef5350;font-weight:700">E</span>', label: 'ERROR', desc: t('settings.log_level.desc.error') },
|
||||
{ value: 'CRITICAL', icon: '<span style="color:#ff1744;font-weight:700">!</span>', label: 'CRITICAL', desc: t('settings.log_level.desc.critical') },
|
||||
];
|
||||
|
||||
const _LOG_FILTER_ITEMS = [
|
||||
{ value: 'all', icon: '<span style="color:#9e9e9e;font-weight:700">*</span>', label: t('settings.logs.filter.all'), desc: t('settings.logs.filter.all_desc') },
|
||||
{ value: 'INFO', icon: '<span style="color:#4fc3f7;font-weight:700">I</span>', label: t('settings.logs.filter.info'), desc: t('settings.logs.filter.info_desc') },
|
||||
{ value: 'WARNING', icon: '<span style="color:#ffb74d;font-weight:700">W</span>', label: t('settings.logs.filter.warning'), desc: t('settings.logs.filter.warning_desc') },
|
||||
{ value: 'ERROR', icon: '<span style="color:#ef5350;font-weight:700">E</span>', label: t('settings.logs.filter.error'), desc: t('settings.logs.filter.error_desc') },
|
||||
];
|
||||
|
||||
export function openSettingsModal() {
|
||||
document.getElementById('settings-error').style.display = 'none';
|
||||
settingsModal.open();
|
||||
|
||||
// Initialize log filter icon select
|
||||
if (!_logFilterIconSelect) {
|
||||
const filterSel = document.getElementById('log-viewer-filter');
|
||||
if (filterSel) {
|
||||
_logFilterIconSelect = new IconSelect({
|
||||
target: filterSel,
|
||||
items: _LOG_FILTER_ITEMS,
|
||||
columns: 2,
|
||||
onChange: () => applyLogFilter(),
|
||||
});
|
||||
}
|
||||
}
|
||||
// Initialize log level icon select
|
||||
if (!_logLevelIconSelect) {
|
||||
const levelSel = document.getElementById('settings-log-level');
|
||||
if (levelSel) {
|
||||
_logLevelIconSelect = new IconSelect({
|
||||
target: levelSel,
|
||||
items: _LOG_LEVEL_ITEMS,
|
||||
columns: 3,
|
||||
onChange: () => setLogLevel(),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
loadApiKeysList();
|
||||
loadAutoBackupSettings();
|
||||
loadBackupList();
|
||||
@@ -559,8 +604,12 @@ export async function loadLogLevel() {
|
||||
const resp = await fetchWithAuth('/system/log-level');
|
||||
if (!resp.ok) return;
|
||||
const data = await resp.json();
|
||||
const select = document.getElementById('settings-log-level');
|
||||
if (select) select.value = data.level;
|
||||
if (_logLevelIconSelect) {
|
||||
_logLevelIconSelect.setValue(data.level);
|
||||
} else {
|
||||
const select = document.getElementById('settings-log-level');
|
||||
if (select) select.value = data.level;
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Failed to load log level:', err);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user