diff --git a/frontend/app.js b/frontend/app.js
index cdc1d23..14725db 100644
--- a/frontend/app.js
+++ b/frontend/app.js
@@ -11,6 +11,8 @@ document.addEventListener('DOMContentLoaded', () => {
const actionOutput = document.getElementById('action-output');
let currentData = [];
+ let currentPage = 1;
+ const pageSize = 10;
function saveSession() {
sessionStorage.setItem('k8s_context', contextSelect.value);
@@ -73,6 +75,7 @@ document.addEventListener('DOMContentLoaded', () => {
const ctx = contextSelect.value || null;
resourceTitle.textContent = resType.charAt(0).toUpperCase() + resType.slice(1);
resourceList.innerHTML = '
Loading...';
+ currentPage = 1;
try {
let url;
if (resType === 'pods') {
@@ -115,26 +118,61 @@ document.addEventListener('DOMContentLoaded', () => {
function renderList() {
const filter = searchInput.value.toLowerCase();
- resourceList.innerHTML = '';
const filtered = currentData.filter(item => item.name.toLowerCase().includes(filter));
- if (filtered.length === 0) {
+ const totalPages = Math.max(1, Math.ceil(filtered.length / pageSize));
+ if (currentPage > totalPages) currentPage = totalPages;
+ if (currentPage < 1) currentPage = 1;
+
+ const start = (currentPage - 1) * pageSize;
+ const pageItems = filtered.slice(start, start + pageSize);
+
+ resourceList.innerHTML = '';
+ if (pageItems.length === 0) {
resourceList.innerHTML = 'No results';
- return;
+ } else {
+ pageItems.forEach(item => {
+ const li = document.createElement('li');
+ li.style.cursor = 'pointer';
+ li.innerHTML = `${item.name} (${item.namespace})`;
+ li.addEventListener('click', () => {
+ actionName.value = item.name;
+ Array.from(resourceList.children).forEach(child => {
+ child.classList.remove('selected');
+ child.style.background = '';
+ });
+ li.classList.add('selected');
+ li.style.background = '#ebf8ff';
+ });
+ resourceList.appendChild(li);
+ });
}
- filtered.forEach(item => {
- const li = document.createElement('li');
- li.innerHTML = `${item.name} (${item.namespace})`;
- resourceList.appendChild(li);
- });
+
+ const pageInfo = document.getElementById('page-info');
+ if (pageInfo) pageInfo.textContent = `Page ${currentPage} of ${totalPages} (${filtered.length} total)`;
+
+ const prevBtn = document.getElementById('prev-page');
+ const nextBtn = document.getElementById('next-page');
+ if (prevBtn) prevBtn.disabled = currentPage <= 1;
+ if (nextBtn) nextBtn.disabled = currentPage >= totalPages;
}
contextSelect.addEventListener('change', () => { saveSession(); loadNamespaces(); });
namespaceSelect.addEventListener('change', () => { saveSession(); loadResources(); });
resourceSelect.addEventListener('change', () => { saveSession(); loadResources(); });
- searchBtn.addEventListener('click', renderList);
- searchInput.addEventListener('input', renderList);
+ searchBtn.addEventListener('click', () => { currentPage = 1; renderList(); });
+ searchInput.addEventListener('input', () => { currentPage = 1; renderList(); });
setDefaultBtn.addEventListener('click', () => { saveSession(); alert('Defaults saved for session'); });
+ document.getElementById('prev-page').addEventListener('click', () => {
+ if (currentPage > 1) { currentPage--; renderList(); }
+ });
+ document.getElementById('next-page').addEventListener('click', () => {
+ const filter = searchInput.value.toLowerCase();
+ const filtered = currentData.filter(item => item.name.toLowerCase().includes(filter));
+ const totalPages = Math.max(1, Math.ceil(filtered.length / pageSize));
+ if (currentPage < totalPages) { currentPage++; renderList(); }
+ });
+
document.getElementById('btn-describe').addEventListener('click', async () => {
const name = actionName.value.trim();
if (!name) return;
diff --git a/frontend/index.html b/frontend/index.html
index 094d465..855f7bd 100644
--- a/frontend/index.html
+++ b/frontend/index.html
@@ -36,6 +36,11 @@
diff --git a/frontend/style.css b/frontend/style.css
index f420233..d16c382 100644
--- a/frontend/style.css
+++ b/frontend/style.css
@@ -78,6 +78,11 @@ button.danger:hover {
background: #c53030;
}
+button:disabled {
+ opacity: 0.5;
+ cursor: not-allowed;
+}
+
#search {
display: flex;
gap: 0.5rem;
@@ -107,12 +112,29 @@ button.danger:hover {
display: flex;
justify-content: space-between;
align-items: center;
+ transition: background 0.1s ease;
+}
+
+#resource-list li:hover {
+ background: #f7fafc;
+}
+
+#resource-list li.selected {
+ background: #ebf8ff;
+ border-left: 3px solid #3182ce;
}
#resource-list li:last-child {
border-bottom: none;
}
+#pagination {
+ margin-top: 1rem;
+ display: flex;
+ gap: 0.5rem;
+ align-items: center;
+}
+
#actions pre {
background: #1a202c;
color: #e2e8f0;