asd
This commit is contained in:
@@ -10,6 +10,14 @@
|
|||||||
const adminInput = form.querySelector('input[name="admin_only"]');
|
const adminInput = form.querySelector('input[name="admin_only"]');
|
||||||
const submitBtn = form.querySelector('[data-command-submit]');
|
const submitBtn = form.querySelector('[data-command-submit]');
|
||||||
const cancelBtn = form.querySelector('[data-command-cancel]');
|
const cancelBtn = form.querySelector('[data-command-cancel]');
|
||||||
|
const modal = document.querySelector('[data-command-modal]');
|
||||||
|
const modalTitle = document.querySelector('[data-command-modal-title]');
|
||||||
|
const closeBtn = document.querySelector('[data-command-close]');
|
||||||
|
const newBtn = document.querySelector('[data-command-new]');
|
||||||
|
const unsavedBar = document.querySelector('[data-command-unsaved]');
|
||||||
|
const discardBtn = document.querySelector('[data-command-discard]');
|
||||||
|
|
||||||
|
let initialSnapshot = '';
|
||||||
|
|
||||||
const resetForm = () => {
|
const resetForm = () => {
|
||||||
if (idInput) idInput.value = '';
|
if (idInput) idInput.value = '';
|
||||||
@@ -18,6 +26,37 @@
|
|||||||
if (timeoutInput) timeoutInput.value = '';
|
if (timeoutInput) timeoutInput.value = '';
|
||||||
if (adminInput) adminInput.checked = false;
|
if (adminInput) adminInput.checked = false;
|
||||||
if (submitBtn) submitBtn.textContent = 'Speichern';
|
if (submitBtn) submitBtn.textContent = 'Speichern';
|
||||||
|
if (unsavedBar) unsavedBar.style.display = 'none';
|
||||||
|
};
|
||||||
|
|
||||||
|
const snapshot = () => {
|
||||||
|
return JSON.stringify({
|
||||||
|
id: idInput ? idInput.value : '',
|
||||||
|
label: labelInput ? labelInput.value : '',
|
||||||
|
command: commandInput ? commandInput.value : '',
|
||||||
|
timeout: timeoutInput ? timeoutInput.value : '',
|
||||||
|
admin: adminInput ? adminInput.checked : false,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const isDirty = () => snapshot() !== initialSnapshot;
|
||||||
|
|
||||||
|
const openModal = () => {
|
||||||
|
if (!modal) return;
|
||||||
|
modal.classList.add('is-open');
|
||||||
|
modal.setAttribute('aria-hidden', 'false');
|
||||||
|
initialSnapshot = snapshot();
|
||||||
|
};
|
||||||
|
|
||||||
|
const closeModal = (force = false) => {
|
||||||
|
if (!modal) return;
|
||||||
|
if (!force && isDirty()) {
|
||||||
|
if (unsavedBar) unsavedBar.style.display = 'flex';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
modal.classList.remove('is-open');
|
||||||
|
modal.setAttribute('aria-hidden', 'true');
|
||||||
|
if (unsavedBar) unsavedBar.style.display = 'none';
|
||||||
};
|
};
|
||||||
|
|
||||||
document.querySelectorAll('[data-command-edit]').forEach((btn) => {
|
document.querySelectorAll('[data-command-edit]').forEach((btn) => {
|
||||||
@@ -30,9 +69,10 @@
|
|||||||
if (timeoutInput) timeoutInput.value = item.dataset.timeout || '';
|
if (timeoutInput) timeoutInput.value = item.dataset.timeout || '';
|
||||||
if (adminInput) adminInput.checked = item.dataset.admin === '1';
|
if (adminInput) adminInput.checked = item.dataset.admin === '1';
|
||||||
if (submitBtn) submitBtn.textContent = 'Aktualisieren';
|
if (submitBtn) submitBtn.textContent = 'Aktualisieren';
|
||||||
|
if (modalTitle) modalTitle.textContent = 'Befehl bearbeiten';
|
||||||
const details = btn.closest('details');
|
const details = btn.closest('details');
|
||||||
if (details) details.removeAttribute('open');
|
if (details) details.removeAttribute('open');
|
||||||
form.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
openModal();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -43,6 +83,31 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (newBtn) {
|
||||||
|
newBtn.addEventListener('click', () => {
|
||||||
|
resetForm();
|
||||||
|
if (modalTitle) modalTitle.textContent = 'Neuer Befehl';
|
||||||
|
openModal();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (closeBtn) {
|
||||||
|
closeBtn.addEventListener('click', () => closeModal(false));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (discardBtn) {
|
||||||
|
discardBtn.addEventListener('click', () => {
|
||||||
|
resetForm();
|
||||||
|
closeModal(true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
form.addEventListener('input', () => {
|
||||||
|
if (unsavedBar && isDirty()) {
|
||||||
|
unsavedBar.style.display = 'flex';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
if (!list) return;
|
if (!list) return;
|
||||||
|
|
||||||
let dragging = null;
|
let dragging = null;
|
||||||
|
|||||||
@@ -86,6 +86,8 @@
|
|||||||
display: grid;
|
display: grid;
|
||||||
grid-template-rows: 120px 1fr;
|
grid-template-rows: 120px 1fr;
|
||||||
box-shadow: var(--shadow);
|
box-shadow: var(--shadow);
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
}
|
}
|
||||||
.host-card-image {
|
.host-card-image {
|
||||||
background: linear-gradient(135deg, #2b3a67 0%, #3b2f5c 45%, #1c2b3f 100%);
|
background: linear-gradient(135deg, #2b3a67 0%, #3b2f5c 45%, #1c2b3f 100%);
|
||||||
@@ -150,7 +152,7 @@
|
|||||||
min-width: 160px;
|
min-width: 160px;
|
||||||
display: grid;
|
display: grid;
|
||||||
gap: 4px;
|
gap: 4px;
|
||||||
z-index: 30;
|
z-index: 200;
|
||||||
box-shadow: var(--shadow);
|
box-shadow: var(--shadow);
|
||||||
}
|
}
|
||||||
.action-menu-panel form { margin: 0; }
|
.action-menu-panel form { margin: 0; }
|
||||||
|
|||||||
@@ -81,7 +81,10 @@ $commands = $pdo->query('SELECT * FROM ' . $table('commands') . ' ORDER BY COALE
|
|||||||
?>
|
?>
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="pill">Pi Control</div>
|
<div class="pill">Pi Control</div>
|
||||||
<h1 style="margin-top:.75rem;">Befehle</h1>
|
<div style="display:flex; align-items:center; justify-content:space-between; gap:12px; flex-wrap:wrap; margin-top:.75rem;">
|
||||||
|
<h1 style="margin:0;">Befehle</h1>
|
||||||
|
<button class="cta-button" type="button" data-command-new>+ Neuer Befehl</button>
|
||||||
|
</div>
|
||||||
<p class="muted">Verwalte vordefinierte SSH-Befehle.</p>
|
<p class="muted">Verwalte vordefinierte SSH-Befehle.</p>
|
||||||
|
|
||||||
<?php if ($error): ?>
|
<?php if ($error): ?>
|
||||||
@@ -95,24 +98,6 @@ $commands = $pdo->query('SELECT * FROM ' . $table('commands') . ' ORDER BY COALE
|
|||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
|
||||||
<div class="grid" style="margin-top:1rem;">
|
<div class="grid" style="margin-top:1rem;">
|
||||||
<div class="card" style="background:var(--panel-2);">
|
|
||||||
<strong>Neuer Befehl</strong>
|
|
||||||
<form method="post" class="form-grid" style="margin-top:.75rem;" data-command-form>
|
|
||||||
<input type="hidden" name="id" value="">
|
|
||||||
<input type="text" name="label" placeholder="Label" required>
|
|
||||||
<textarea name="command" rows="4" placeholder="Command" required></textarea>
|
|
||||||
<input type="number" name="timeout_sec" placeholder="Timeout (Sek., optional)">
|
|
||||||
<label class="muted" style="display:flex; gap:8px; align-items:center;">
|
|
||||||
<input type="checkbox" name="admin_only" value="1">
|
|
||||||
Nur Admin
|
|
||||||
</label>
|
|
||||||
<div style="display:flex; gap:10px; flex-wrap:wrap;">
|
|
||||||
<button class="cta-button" type="submit" data-command-submit>Speichern</button>
|
|
||||||
<button class="nav-link" type="button" data-command-cancel>Zurücksetzen</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="card" style="background:var(--panel-2);">
|
<div class="card" style="background:var(--panel-2);">
|
||||||
<strong>Vorhandene Befehle</strong>
|
<strong>Vorhandene Befehle</strong>
|
||||||
<?php if (!$commands): ?>
|
<?php if (!$commands): ?>
|
||||||
@@ -159,3 +144,33 @@ $commands = $pdo->query('SELECT * FROM ' . $table('commands') . ' ORDER BY COALE
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="modal" data-command-modal aria-hidden="true">
|
||||||
|
<div class="modal-card">
|
||||||
|
<div class="modal-header">
|
||||||
|
<strong data-command-modal-title>Neuer Befehl</strong>
|
||||||
|
<button class="icon-button" type="button" data-command-close>×</button>
|
||||||
|
</div>
|
||||||
|
<form method="post" class="form-grid" style="margin-top:.75rem;" data-command-form>
|
||||||
|
<input type="hidden" name="id" value="">
|
||||||
|
<input type="text" name="label" placeholder="Label" required>
|
||||||
|
<textarea name="command" rows="4" placeholder="Command" required></textarea>
|
||||||
|
<input type="number" name="timeout_sec" placeholder="Timeout (Sek., optional)">
|
||||||
|
<label class="muted" style="display:flex; gap:8px; align-items:center;">
|
||||||
|
<input type="checkbox" name="admin_only" value="1">
|
||||||
|
Nur Admin
|
||||||
|
</label>
|
||||||
|
<div class="host-unsaved" data-command-unsaved style="display:none;">
|
||||||
|
<span class="muted">Änderungen nicht gespeichert.</span>
|
||||||
|
<div style="display:flex; gap:10px; flex-wrap:wrap;">
|
||||||
|
<button class="cta-button" type="submit" data-command-submit>Speichern</button>
|
||||||
|
<button class="nav-link" type="button" data-command-discard>Änderungen verwerfen</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div style="display:flex; gap:10px; flex-wrap:wrap;">
|
||||||
|
<button class="cta-button" type="submit" data-command-submit>Speichern</button>
|
||||||
|
<button class="nav-link" type="button" data-command-cancel>Zurücksetzen</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user