feat(ui): vervang start/restart/stop knoppen door 3-dot dropdown in containers en pods
This commit is contained in:
+97
-12
@@ -122,6 +122,19 @@
|
|||||||
.btn.ok{border-color: rgba(45,212,191,.6)}
|
.btn.ok{border-color: rgba(45,212,191,.6)}
|
||||||
.btn.bad{border-color: rgba(251,113,133,.6)}
|
.btn.bad{border-color: rgba(251,113,133,.6)}
|
||||||
.btn.warn{border-color: rgba(251,191,36,.6)}
|
.btn.warn{border-color: rgba(251,191,36,.6)}
|
||||||
|
.btn.icon {
|
||||||
|
padding: 6px 7px;
|
||||||
|
min-width: 28px;
|
||||||
|
height: 28px;
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-size: 13px;
|
||||||
|
border-radius: 8px;
|
||||||
|
}
|
||||||
|
.btn.icon span {
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
.pill{
|
.pill{
|
||||||
display:inline-flex; align-items:center; gap:8px;
|
display:inline-flex; align-items:center; gap:8px;
|
||||||
padding:6px 10px;
|
padding:6px 10px;
|
||||||
@@ -233,6 +246,45 @@
|
|||||||
opacity: 0.65;
|
opacity: 0.65;
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
}
|
}
|
||||||
|
/* 3-dot dropdown actions */
|
||||||
|
.actions-menu { position: relative; display: inline-flex; }
|
||||||
|
|
||||||
|
.menuPanel{
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
top: 34px;
|
||||||
|
min-width: 140px;
|
||||||
|
background: linear-gradient(180deg, rgba(17,26,46,.98), rgba(14,23,48,.98));
|
||||||
|
border: 1px solid rgba(36,52,95,.9);
|
||||||
|
border-radius: 12px;
|
||||||
|
box-shadow: var(--shadow);
|
||||||
|
padding: 6px;
|
||||||
|
display: none;
|
||||||
|
z-index: 50;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menuPanel.open { display: block; }
|
||||||
|
|
||||||
|
.menuItem{
|
||||||
|
width: 100%;
|
||||||
|
text-align: left;
|
||||||
|
padding: 8px 10px;
|
||||||
|
border-radius: 10px;
|
||||||
|
border: 1px solid transparent;
|
||||||
|
background: transparent;
|
||||||
|
color: var(--text);
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menuItem:hover{
|
||||||
|
background: rgba(96,165,250,.10);
|
||||||
|
border-color: rgba(96,165,250,.25);
|
||||||
|
}
|
||||||
|
|
||||||
|
.menuItem.ok{ border-color: rgba(45,212,191,.35); }
|
||||||
|
.menuItem.warn{ border-color: rgba(251,191,36,.35); }
|
||||||
|
.menuItem.bad{ border-color: rgba(251,113,133,.35); }
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
@@ -516,6 +568,25 @@
|
|||||||
function hideModal() { document.getElementById('modalBack').style.display = 'none'; }
|
function hideModal() { document.getElementById('modalBack').style.display = 'none'; }
|
||||||
function closeModal(e){ if(e.target.id === 'modalBack') hideModal(); }
|
function closeModal(e){ if(e.target.id === 'modalBack') hideModal(); }
|
||||||
|
|
||||||
|
function closeAllMenus() {
|
||||||
|
document.querySelectorAll('.menuPanel.open').forEach(p => p.classList.remove('open'));
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleMenu(menuId) {
|
||||||
|
const el = document.getElementById(menuId);
|
||||||
|
if (!el) return;
|
||||||
|
const willOpen = !el.classList.contains('open');
|
||||||
|
closeAllMenus();
|
||||||
|
if (willOpen) el.classList.add('open');
|
||||||
|
}
|
||||||
|
|
||||||
|
// klik buiten menu = sluiten
|
||||||
|
document.addEventListener('click', (e) => {
|
||||||
|
// als je op een menu knop klikt, laat toggleMenu het regelen
|
||||||
|
if (e.target.closest('.actions-menu')) return;
|
||||||
|
closeAllMenus();
|
||||||
|
});
|
||||||
|
|
||||||
// ---- Tabs ----
|
// ---- Tabs ----
|
||||||
let currentTab = 'dashboard';
|
let currentTab = 'dashboard';
|
||||||
function setTab(tab) {
|
function setTab(tab) {
|
||||||
@@ -656,12 +727,28 @@
|
|||||||
localStorage.setItem('pod_group_collapsed:' + pod, v ? '1' : '0');
|
localStorage.setItem('pod_group_collapsed:' + pod, v ? '1' : '0');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function renderActionsDropdown(menuId, actionFn, targetEsc) {
|
||||||
|
// actionFn is string: "containerAction" of "podAction"
|
||||||
|
// targetEsc is al esc(...) dus veilig in onclick
|
||||||
|
return `
|
||||||
|
<span class="actions-menu">
|
||||||
|
<button class="btn icon" title="Acties" onclick="toggleMenu('${menuId}')">⋮</button>
|
||||||
|
<div class="menuPanel" id="${menuId}">
|
||||||
|
<button class="menuItem ok" onclick="${actionFn}('start','${targetEsc}'); closeAllMenus();">Start</button>
|
||||||
|
<button class="menuItem warn" onclick="${actionFn}('restart','${targetEsc}'); closeAllMenus();">Restart</button>
|
||||||
|
<button class="menuItem bad" onclick="${actionFn}('stop','${targetEsc}'); closeAllMenus();">Stop</button>
|
||||||
|
</div>
|
||||||
|
</span>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
function renderContainerRow(c) {
|
function renderContainerRow(c) {
|
||||||
const name = (c.Names && c.Names[0]) ? c.Names[0] : (c.Names || c.Name || c.name || '');
|
const name = (c.Names && c.Names[0]) ? c.Names[0] : (c.Names || c.Name || c.name || '');
|
||||||
const status = c.Status || c.State || c.state || '';
|
const status = c.Status || c.State || c.state || '';
|
||||||
const podName = c.PodName || '-';
|
const podName = c.PodName || '-';
|
||||||
const image = c.Image || c.image || '';
|
const image = c.Image || c.image || '';
|
||||||
const managed = c._dashboard_source || 'podman';
|
const managed = c._dashboard_source || 'podman';
|
||||||
|
const menuId = `menu-${cssSafeId('c:' + normalizeContainerName(name))}`;
|
||||||
const inPod = !!(c.PodName && String(c.PodName).trim());
|
const inPod = !!(c.PodName && String(c.PodName).trim());
|
||||||
const ports = inPod
|
const ports = inPod
|
||||||
? '' // verberg bij pod-containers
|
? '' // verberg bij pod-containers
|
||||||
@@ -680,11 +767,9 @@
|
|||||||
<td>${ports || '-'}</td>
|
<td>${ports || '-'}</td>
|
||||||
<td>
|
<td>
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<button class="btn small" onclick="containerInspect('${esc(name)}')">Inspect</button>
|
<button class="btn icon" title="Inspect" onclick="containerInspect('${esc(name)}')">🔍</button>
|
||||||
<button class="btn small" onclick="containerLogs('${esc(name)}')">Logs</button>
|
<button class="btn icon" title="Logs" onclick="containerLogs('${esc(name)}')">📄</button>
|
||||||
<button class="btn small ok" onclick="containerAction('start','${esc(name)}')">Start</button>
|
${renderActionsDropdown(menuId, 'containerAction', esc(name))}
|
||||||
<button class="btn small warn" onclick="containerAction('restart','${esc(name)}')">Restart</button>
|
|
||||||
<button class="btn small bad" onclick="containerAction('stop','${esc(name)}')">Stop</button>
|
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@@ -727,6 +812,7 @@
|
|||||||
const collapsed = _isCollapsed(pod);
|
const collapsed = _isCollapsed(pod);
|
||||||
const isRealPod = (pod !== '(geen pod)');
|
const isRealPod = (pod !== '(geen pod)');
|
||||||
const total = items.length;
|
const total = items.length;
|
||||||
|
const podMenuId = `menu-${cssSafeId('p:' + pod)}`;
|
||||||
|
|
||||||
let podPortsText = "-";
|
let podPortsText = "-";
|
||||||
if (isRealPod) {
|
if (isRealPod) {
|
||||||
@@ -779,14 +865,13 @@
|
|||||||
<td class="mono">${esc(podPortsText)}</td>
|
<td class="mono">${esc(podPortsText)}</td>
|
||||||
<td>
|
<td>
|
||||||
${isRealPod ? `
|
${isRealPod ? `
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<button class="btn small" disabled style="visibility:hidden;">Inspect</button>
|
<!-- placeholders voor uitlijning -->
|
||||||
<button class="btn small" disabled style="visibility:hidden;">Logs</button>
|
<button class="btn icon" disabled style="visibility:hidden;" aria-hidden="true" tabindex="-1">🔍</button>
|
||||||
|
<button class="btn icon" disabled style="visibility:hidden;" aria-hidden="true" tabindex="-1">📄</button>
|
||||||
|
|
||||||
<button class="btn small ok" onclick="podAction('start','${esc(pod)}')">Start</button>
|
${renderActionsDropdown(podMenuId, 'podAction', esc(pod))}
|
||||||
<button class="btn small warn" onclick="podAction('restart','${esc(pod)}')">Restart</button>
|
</div>
|
||||||
<button class="btn small bad" onclick="podAction('stop','${esc(pod)}')">Stop</button>
|
|
||||||
</div>
|
|
||||||
` : '<span class="muted">-</span>'}
|
` : '<span class="muted">-</span>'}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|||||||
Reference in New Issue
Block a user