v1.8.4: единая стилистика — замена confirm/alert/prompt на кастомные модалки, SERVICE_STYLE_GUIDE.md, обновлен AGENTS.md
Tests / test (push) Has been cancelled
Tests / test-max-bot (push) Has been cancelled

This commit is contained in:
2026-06-02 20:40:24 +03:00
parent df34048e2a
commit e184e5fe79
23 changed files with 777 additions and 70 deletions
+67 -3
View File
@@ -1,5 +1,17 @@
{% extends "page.html" %}
{% block page_content %}
<style>
.modal-overlay { display:none; position:fixed; top:0; left:0; right:0; bottom:0; background:rgba(0,0,0,0.5); z-index:1000; align-items:center; justify-content:center; }
.modal-overlay.open { display:flex; }
.modal { background:var(--bg-card); border:1px solid var(--border); border-radius:12px; padding:24px; width:420px; max-width:90vw; }
.modal h2 { color:var(--text-primary); }
.modal p { color:var(--text-secondary); }
.modal-actions { display:flex; gap:10px; }
.btn-danger { background:var(--danger, #dc3545); color:#fff; border:none; padding:8px 16px; border-radius:6px; cursor:pointer; font-weight:600; }
.btn-primary { background:var(--accent, #00ADEF); color:#fff; border:none; padding:8px 16px; border-radius:6px; cursor:pointer; font-weight:600; }
.btn { background:var(--bg-input); color:var(--text-primary); border:1px solid var(--border); padding:8px 16px; border-radius:6px; cursor:pointer; }
.form-group { margin-bottom:0; }
</style>
<div class="card">
<div class="card-header"><h2>Графики и диаграммы</h2></div>
<div class="filter-bar" style="flex-wrap:wrap;gap:8px;">
@@ -41,10 +53,38 @@
</div>
</div>
<div class="modal-overlay" id="chart-name-modal">
<div class="modal" style="max-width:420px;">
<h2 style="font-size:16px;margin-bottom:8px;">Название графика</h2>
<div class="form-group">
<input type="text" id="chart-name-input" placeholder="Введите название..." style="width:100%;padding:8px 12px;border:1px solid var(--border);border-radius:6px;font-size:14px;background:var(--bg-card);color:var(--text);box-sizing:border-box;">
</div>
<div class="modal-actions" style="justify-content:flex-end;margin-top:16px;">
<button type="button" class="btn btn-primary" onclick="confirmSaveChart()">Сохранить</button>
<button type="button" class="btn" onclick="closeChartNameModal()">Отмена</button>
</div>
</div>
</div>
<div class="modal-overlay" id="confirm-delete-chart">
<div class="modal" style="max-width:420px;">
<h2 style="font-size:16px;margin-bottom:8px;">Удалить график?</h2>
<p style="color:var(--text-secondary);font-size:14px;margin-bottom:20px;">
<strong id="delete-chart-name"></strong> будет удалён навсегда.
Это действие нельзя отменить.
</p>
<div class="modal-actions" style="justify-content:flex-end;">
<button type="button" class="btn btn-danger" onclick="confirmDeleteChart()">Удалить</button>
<button type="button" class="btn" onclick="closeConfirmDeleteChart()">Отмена</button>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.7/dist/chart.umd.min.js"></script>
<script>
var chartInstance = null;
var currentChartConfig = null;
var pendingDeleteChartName = null;
function loadChart(){
var metric = document.getElementById('metric-select').value;
@@ -107,8 +147,19 @@ function exportChart(){
function saveCustomChart(){
if(!currentChartConfig) return;
var name = prompt('Название графика:');
if(!name) return;
document.getElementById('chart-name-input').value = '';
document.getElementById('chart-name-modal').classList.add('open');
document.getElementById('chart-name-input').focus();
}
function closeChartNameModal(){
document.getElementById('chart-name-modal').classList.remove('open');
}
function confirmSaveChart(){
var name = document.getElementById('chart-name-input').value.trim();
if(!name){ return; }
closeChartNameModal();
var saved = JSON.parse(localStorage.getItem('custom_charts') || '[]');
saved.push({ name: name, config: currentChartConfig });
localStorage.setItem('custom_charts', JSON.stringify(saved));
@@ -131,7 +182,20 @@ function deleteCustomChart(){
var sel = document.getElementById('custom-chart-select');
var name = sel.value;
if(!name) return;
if(!confirm('Удалить "' + name + '"?')) return;
pendingDeleteChartName = name;
document.getElementById('delete-chart-name').textContent = name;
document.getElementById('confirm-delete-chart').classList.add('open');
}
function closeConfirmDeleteChart(){
document.getElementById('confirm-delete-chart').classList.remove('open');
pendingDeleteChartName = null;
}
function confirmDeleteChart(){
var name = pendingDeleteChartName;
closeConfirmDeleteChart();
var sel = document.getElementById('custom-chart-select');
var saved = JSON.parse(localStorage.getItem('custom_charts') || '[]');
saved = saved.filter(function(c){ return c.name !== name; });
localStorage.setItem('custom_charts', JSON.stringify(saved));