Implement search functionality for services and add info button for connection details
This commit is contained in:
58
index.html
58
index.html
@@ -10,6 +10,9 @@
|
|||||||
<header>
|
<header>
|
||||||
<h1>My Services</h1>
|
<h1>My Services</h1>
|
||||||
<p class="subtitle">Quick links to the commonly used containers on this host</p>
|
<p class="subtitle">Quick links to the commonly used containers on this host</p>
|
||||||
|
<div class="search-container">
|
||||||
|
<input type="text" id="search-input" placeholder="🔍 Search services..." />
|
||||||
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<main>
|
<main>
|
||||||
@@ -33,7 +36,10 @@
|
|||||||
// Fetch services.xml and render the service cards with logos.
|
// Fetch services.xml and render the service cards with logos.
|
||||||
(async function(){
|
(async function(){
|
||||||
const grid = document.getElementById('services-grid');
|
const grid = document.getElementById('services-grid');
|
||||||
|
const searchInput = document.getElementById('search-input');
|
||||||
const host = window.location.hostname;
|
const host = window.location.hostname;
|
||||||
|
let allServices = []; // Store all service elements for filtering
|
||||||
|
|
||||||
try{
|
try{
|
||||||
const res = await fetch('/services.xml', {cache: 'no-cache'});
|
const res = await fetch('/services.xml', {cache: 'no-cache'});
|
||||||
if(!res.ok){ throw new Error('Failed to load services.xml'); }
|
if(!res.ok){ throw new Error('Failed to load services.xml'); }
|
||||||
@@ -81,6 +87,7 @@
|
|||||||
a.href = href;
|
a.href = href;
|
||||||
a.target = '_blank';
|
a.target = '_blank';
|
||||||
a.rel = 'noreferrer';
|
a.rel = 'noreferrer';
|
||||||
|
a.dataset.serviceName = name.toLowerCase(); // For search filtering
|
||||||
|
|
||||||
const img = document.createElement('img');
|
const img = document.createElement('img');
|
||||||
img.className = 'logo';
|
img.className = 'logo';
|
||||||
@@ -93,8 +100,59 @@
|
|||||||
|
|
||||||
a.appendChild(img);
|
a.appendChild(img);
|
||||||
a.appendChild(span);
|
a.appendChild(span);
|
||||||
|
|
||||||
|
// Add info button if both hostname and port are available
|
||||||
|
if((hostAttr || host) && port){
|
||||||
|
const infoBtn = document.createElement('button');
|
||||||
|
infoBtn.className = 'info-btn';
|
||||||
|
infoBtn.title = 'Connection details';
|
||||||
|
infoBtn.innerHTML = 'ⓘ';
|
||||||
|
infoBtn.onclick = (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
const displayHost = hostAttr || host;
|
||||||
|
const details = `Service: ${name}\nHost: ${displayHost}\nPort: ${port}\nProtocol: ${proto}`;
|
||||||
|
alert(details);
|
||||||
|
};
|
||||||
|
a.appendChild(infoBtn);
|
||||||
|
}
|
||||||
|
|
||||||
grid.appendChild(a);
|
grid.appendChild(a);
|
||||||
|
allServices.push(a);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Search functionality
|
||||||
|
searchInput.addEventListener('input', (e) => {
|
||||||
|
const searchTerm = e.target.value.toLowerCase().trim();
|
||||||
|
let visibleCount = 0;
|
||||||
|
allServices.forEach(card => {
|
||||||
|
const serviceName = card.dataset.serviceName;
|
||||||
|
if(serviceName.includes(searchTerm)){
|
||||||
|
card.style.display = '';
|
||||||
|
visibleCount++;
|
||||||
|
} else {
|
||||||
|
card.style.display = 'none';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// Show message if no results
|
||||||
|
const existingMsg = grid.querySelector('.no-results');
|
||||||
|
if(existingMsg) existingMsg.remove();
|
||||||
|
if(visibleCount === 0 && searchTerm !== ''){
|
||||||
|
const msg = document.createElement('p');
|
||||||
|
msg.className = 'notes no-results';
|
||||||
|
msg.textContent = `No services found matching "${e.target.value}"`;
|
||||||
|
grid.appendChild(msg);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Focus search on '/' key
|
||||||
|
document.addEventListener('keydown', (e) => {
|
||||||
|
if(e.key === '/' && document.activeElement !== searchInput){
|
||||||
|
e.preventDefault();
|
||||||
|
searchInput.focus();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
}catch(err){
|
}catch(err){
|
||||||
console.error(err);
|
console.error(err);
|
||||||
grid.innerHTML = '<p class="notes">Error loading services.xml — see console for details.</p>';
|
grid.innerHTML = '<p class="notes">Error loading services.xml — see console for details.</p>';
|
||||||
|
|||||||
Reference in New Issue
Block a user