mirror of
https://github.com/andrey271192/vps_monitoring.git
synced 2026-09-20 11:55:34 +00:00
fix(keenetic): open KeenDNS edit instead of detail modal
Card-level onclick fired even when KeenDNS was clicked. Use delegated handlers so the edit form toggles reliably and card clicks skip buttons. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -435,12 +435,36 @@ main {
|
|||||||
|
|
||||||
.keenetic-url-edit {
|
.keenetic-url-edit {
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
padding-top: 10px;
|
padding: 12px;
|
||||||
border-top: 1px solid var(--border);
|
border: 1px solid var(--border);
|
||||||
|
border-radius: 8px;
|
||||||
|
background: color-mix(in srgb, var(--accent) 8%, var(--card-bg));
|
||||||
|
}
|
||||||
|
|
||||||
|
.keenetic-url-edit.is-open {
|
||||||
|
border-color: var(--accent);
|
||||||
|
box-shadow: 0 0 0 1px color-mix(in srgb, var(--accent) 35%, transparent);
|
||||||
|
}
|
||||||
|
|
||||||
|
.keenetic-url-edit-title {
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 600;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
color: var(--accent);
|
||||||
}
|
}
|
||||||
|
|
||||||
.keenetic-url-edit .form-group input {
|
.keenetic-url-edit .form-group input {
|
||||||
font-size: 12px;
|
font-size: 13px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.server-card-actions .keenetic-url-btn.active {
|
||||||
|
border-color: var(--accent);
|
||||||
|
color: var(--accent);
|
||||||
|
}
|
||||||
|
|
||||||
|
.keenetic-card-open {
|
||||||
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.server-card-actions {
|
.server-card-actions {
|
||||||
|
|||||||
@@ -40,6 +40,28 @@ document.addEventListener('click', function(e) {
|
|||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
toggleMuteDevice(bell);
|
toggleMuteDevice(bell);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const keenDnsBtn = e.target.closest('.keenetic-url-btn');
|
||||||
|
if (keenDnsBtn) {
|
||||||
|
e.stopPropagation();
|
||||||
|
e.preventDefault();
|
||||||
|
toggleKeeneticUrlEdit(keenDnsBtn.dataset.name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const keenSaveBtn = e.target.closest('.keenetic-url-save');
|
||||||
|
if (keenSaveBtn) {
|
||||||
|
e.stopPropagation();
|
||||||
|
e.preventDefault();
|
||||||
|
saveKeeneticUrl(keenSaveBtn.dataset.name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const keenCard = e.target.closest('.server-card[data-keen]');
|
||||||
|
if (keenCard && !e.target.closest('.mute-bell, .server-card-actions, .keenetic-url-edit, .keenetic-links, a, button, input, label')) {
|
||||||
|
showKeeneticDetail(keenCard.dataset.keen);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1230,11 +1252,11 @@ function renderKeenetic() {
|
|||||||
const urlValue = escHtml(keeneticWebUrl(dev));
|
const urlValue = escHtml(keeneticWebUrl(dev));
|
||||||
|
|
||||||
return `
|
return `
|
||||||
<div class="server-card ${isOnline ? 'online' : 'offline'}" data-keen="${dev.name}" onclick="showKeeneticDetail('${dev.name}')">
|
<div class="server-card ${isOnline ? 'online' : 'offline'}" data-keen="${escHtml(dev.name)}">
|
||||||
${bellHtml('keenetic', dev.name)}
|
${bellHtml('keenetic', dev.name)}
|
||||||
<div class="server-card-header">
|
<div class="server-card-header keenetic-card-open">
|
||||||
<div>
|
<div>
|
||||||
<div class="name">📡 ${dev.name}</div>
|
<div class="name">📡 ${escHtml(dev.name)}</div>
|
||||||
<div class="host">${hostParts.join(' • ')}</div>
|
<div class="host">${hostParts.join(' • ')}</div>
|
||||||
</div>
|
</div>
|
||||||
<span class="status-badge ${isOnline ? 'online' : 'offline'}">
|
<span class="status-badge ${isOnline ? 'online' : 'offline'}">
|
||||||
@@ -1262,18 +1284,19 @@ function renderKeenetic() {
|
|||||||
${uptime ? ' • ⏱ ' + uptime : ''}
|
${uptime ? ' • ⏱ ' + uptime : ''}
|
||||||
</div>
|
</div>
|
||||||
` : `<div style="padding:20px 0;text-align:center;opacity:0.5">${error ? '⚠️ ' + error : 'Нет данных — нажмите 🔄'}</div>`}
|
` : `<div style="padding:20px 0;text-align:center;opacity:0.5">${error ? '⚠️ ' + error : 'Нет данных — нажмите 🔄'}</div>`}
|
||||||
<div id="${urlEditId}" class="keenetic-url-edit" style="display:none" onclick="event.stopPropagation()">
|
<div id="${urlEditId}" class="keenetic-url-edit" style="display:none">
|
||||||
|
<div class="keenetic-url-edit-title">✏️ Адрес KeenDNS</div>
|
||||||
<div class="form-group" style="margin-bottom:8px">
|
<div class="form-group" style="margin-bottom:8px">
|
||||||
<label>Адрес KeenDNS</label>
|
<label for="${urlEditId}-input">Адрес KeenDNS</label>
|
||||||
<input type="text" id="${urlEditId}-input" value="${urlValue}" placeholder="https://example.keenetic.pro:8443">
|
<input type="text" id="${urlEditId}-input" value="${urlValue}" placeholder="https://example.keenetic.pro:8443">
|
||||||
</div>
|
</div>
|
||||||
<button class="btn-primary" style="width:100%" onclick="saveKeeneticUrl(${JSON.stringify(dev.name)})">Сохранить</button>
|
<button type="button" class="btn-primary keenetic-url-save" style="width:100%" data-name="${escHtml(dev.name)}">Сохранить</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="server-card-actions">
|
<div class="server-card-actions">
|
||||||
<button onclick="event.stopPropagation();toggleKeeneticUrlEdit(${JSON.stringify(dev.name)})">✏️ KeenDNS</button>
|
<button type="button" class="keenetic-url-btn" data-name="${escHtml(dev.name)}">✏️ KeenDNS</button>
|
||||||
<button onclick="event.stopPropagation();refreshKeenetic('${dev.name}')">🔄 Обновить</button>
|
<button type="button" onclick="event.stopPropagation();refreshKeenetic(${JSON.stringify(dev.name)})">🔄 Обновить</button>
|
||||||
<button onclick="event.stopPropagation();rebootKeenetic('${dev.name}')">🔁 Reboot</button>
|
<button type="button" onclick="event.stopPropagation();rebootKeenetic(${JSON.stringify(dev.name)})">🔁 Reboot</button>
|
||||||
<button class="danger" onclick="event.stopPropagation();deleteKeenetic('${dev.name}')">🗑</button>
|
<button type="button" class="danger" onclick="event.stopPropagation();deleteKeenetic(${JSON.stringify(dev.name)})">🗑</button>
|
||||||
</div>
|
</div>
|
||||||
</div>`;
|
</div>`;
|
||||||
}).join('');
|
}).join('');
|
||||||
@@ -1555,11 +1578,26 @@ function keeneticUrlEditId(name) {
|
|||||||
function toggleKeeneticUrlEdit(name) {
|
function toggleKeeneticUrlEdit(name) {
|
||||||
const block = document.getElementById(keeneticUrlEditId(name));
|
const block = document.getElementById(keeneticUrlEditId(name));
|
||||||
if (!block) return;
|
if (!block) return;
|
||||||
const show = block.style.display === 'none';
|
const show = block.style.display === 'none' || !block.classList.contains('is-open');
|
||||||
block.style.display = show ? 'block' : 'none';
|
block.style.display = show ? 'block' : 'none';
|
||||||
|
block.classList.toggle('is-open', show);
|
||||||
|
const card = document.querySelector(`.server-card[data-keen="${CSS.escape(name)}"]`);
|
||||||
|
if (card) {
|
||||||
|
card.querySelectorAll('.keenetic-url-edit.is-open').forEach(el => {
|
||||||
|
if (el !== block) {
|
||||||
|
el.style.display = 'none';
|
||||||
|
el.classList.remove('is-open');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
card.querySelector('.keenetic-url-btn')?.classList.toggle('active', show);
|
||||||
|
}
|
||||||
if (show) {
|
if (show) {
|
||||||
const input = document.getElementById(keeneticUrlEditId(name) + '-input');
|
const input = document.getElementById(keeneticUrlEditId(name) + '-input');
|
||||||
if (input) input.focus();
|
if (input) {
|
||||||
|
input.focus();
|
||||||
|
input.select();
|
||||||
|
}
|
||||||
|
block.scrollIntoView({block: 'nearest', behavior: 'smooth'});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -601,6 +601,6 @@ loftliliana https://loftliliana.netcraze.pro 1020687391" style="width:100%;font-
|
|||||||
|
|
||||||
<script src="https://cdn.jsdelivr.net/npm/xterm@5.3.0/lib/xterm.min.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/xterm@5.3.0/lib/xterm.min.js"></script>
|
||||||
<script src="https://cdn.jsdelivr.net/npm/xterm-addon-fit@0.8.0/lib/xterm-addon-fit.min.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/xterm-addon-fit@0.8.0/lib/xterm-addon-fit.min.js"></script>
|
||||||
<script src="/static/js/app.js?v=20260521b"></script>
|
<script src="/static/js/app.js?v=20260522a"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
Reference in New Issue
Block a user