Add CPU/GPU names on perf charts, reusable color picker, and header toolbar redesign

- Show CPU and GPU model names as overlays on performance chart cards
- Add cpu_name field to performance API with cross-platform detection
- Extract reusable color-picker popover module (9 presets + custom picker)
- Per-chart color customization for CPU/RAM/GPU performance charts
- Redesign header: compact toolbar container with icon-only buttons
- Compact language dropdown (EN/RU/ZH), icon-only login/logout
- Use accent color for FPS charts, range slider accent, dashboard icons

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-27 21:12:13 +03:00
parent 2bca119ad4
commit 6a7ba3d0b7
13 changed files with 361 additions and 127 deletions

View File

@@ -86,9 +86,14 @@ function _destroyFpsCharts() {
_fpsCharts = {};
}
function _getAccentColor() {
return getComputedStyle(document.documentElement).getPropertyValue('--primary-color').trim() || '#4CAF50';
}
function _createFpsChart(canvasId, actualHistory, currentHistory, fpsTarget) {
const canvas = document.getElementById(canvasId);
if (!canvas) return null;
const accent = _getAccentColor();
return new Chart(canvas, {
type: 'line',
data: {
@@ -96,8 +101,8 @@ function _createFpsChart(canvasId, actualHistory, currentHistory, fpsTarget) {
datasets: [
{
data: [...actualHistory],
borderColor: '#2196F3',
backgroundColor: 'rgba(33,150,243,0.12)',
borderColor: accent,
backgroundColor: accent + '1f',
borderWidth: 1.5,
tension: 0.3,
fill: true,
@@ -105,7 +110,7 @@ function _createFpsChart(canvasId, actualHistory, currentHistory, fpsTarget) {
},
{
data: [...currentHistory],
borderColor: '#4CAF50',
borderColor: accent + '80',
borderWidth: 1.5,
tension: 0.3,
fill: false,
@@ -490,7 +495,7 @@ export async function loadDashboard(forceFullRender = false) {
if (running.length > 0) {
runningIds = running.map(t => t.id);
const stopAllBtn = `<button class="btn btn-sm btn-danger dashboard-stop-all" onclick="event.stopPropagation(); dashboardStopAll()" title="${t('dashboard.stop_all')}">${ICON_STOP} ${t('dashboard.stop_all')}</button>`;
const stopAllBtn = `<button class="btn btn-sm btn-primary dashboard-stop-all" onclick="event.stopPropagation(); dashboardStopAll()" title="${t('dashboard.stop_all')}">${ICON_STOP} ${t('dashboard.stop_all')}</button>`;
const runningItems = running.map(target => renderDashboardTarget(target, true, devicesMap, cssSourceMap)).join('');
targetsInner += `<div class="dashboard-subsection">