Skip to content

Commit eebfaf2

Browse files
virtual server (IBM#940)
* The search option on the virtual server page is not working properly Signed-off-by: NAYANAR <[email protected]> * Fixed line breaks and indentation for long function calls Signed-off-by: NAYANAR <[email protected]> * Fixed the remaining indentation errors by removing the extra spaces that prettier was complaining abou Signed-off-by: NAYANAR <[email protected]> --------- Signed-off-by: NAYANAR <[email protected]> Co-authored-by: NAYANAR <[email protected]>
1 parent 7341b61 commit eebfaf2

File tree

2 files changed

+120
-41
lines changed

2 files changed

+120
-41
lines changed

mcpgateway/static/admin.js

Lines changed: 104 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8166,53 +8166,143 @@ function setupSelectorSearch() {
81668166
const searchTools = safeGetElement("searchTools", true);
81678167
if (searchTools) {
81688168
searchTools.addEventListener("input", function () {
8169-
filterItems(this.value, ".tool-item", ["span"]);
8169+
filterSelectorItems(
8170+
this.value,
8171+
"#associatedTools",
8172+
".tool-item",
8173+
"noToolsMessage",
8174+
"searchQuery",
8175+
);
81708176
});
81718177
}
81728178

81738179
// Resources search
81748180
const searchResources = safeGetElement("searchResources", true);
81758181
if (searchResources) {
81768182
searchResources.addEventListener("input", function () {
8177-
filterItems(this.value, ".resource-item", ["span", ".text-xs"]);
8183+
filterSelectorItems(
8184+
this.value,
8185+
"#associatedResources",
8186+
".resource-item",
8187+
"noResourcesMessage",
8188+
"searchResourcesQuery",
8189+
);
81788190
});
81798191
}
81808192

81818193
// Prompts search
81828194
const searchPrompts = safeGetElement("searchPrompts", true);
81838195
if (searchPrompts) {
81848196
searchPrompts.addEventListener("input", function () {
8185-
filterItems(this.value, ".prompt-item", ["span", ".text-xs"]);
8197+
filterSelectorItems(
8198+
this.value,
8199+
"#associatedPrompts",
8200+
".prompt-item",
8201+
"noPromptsMessage",
8202+
"searchPromptsQuery",
8203+
);
81868204
});
81878205
}
81888206
}
81898207

81908208
/**
8191-
* Generic function to filter items in multi-select dropdowns
8209+
* Generic function to filter items in multi-select dropdowns with no results message
81928210
*/
8193-
function filterItems(searchText, itemSelector, textSelectors) {
8194-
const items = document.querySelectorAll(itemSelector);
8195-
const search = searchText.toLowerCase();
8211+
function filterSelectorItems(
8212+
searchText,
8213+
containerSelector,
8214+
itemSelector,
8215+
noResultsId,
8216+
searchQueryId,
8217+
) {
8218+
const container = document.querySelector(containerSelector);
8219+
if (!container) {
8220+
return;
8221+
}
8222+
8223+
const items = container.querySelectorAll(itemSelector);
8224+
const search = searchText.toLowerCase().trim();
8225+
let hasVisibleItems = false;
81968226

81978227
items.forEach((item) => {
81988228
let textContent = "";
81998229

8200-
// Collect text from all specified selectors within the item
8201-
textSelectors.forEach((selector) => {
8202-
const elements = item.querySelectorAll(selector);
8203-
elements.forEach((el) => {
8204-
textContent += " " + el.textContent;
8205-
});
8230+
// Get text from all text nodes within the item
8231+
const textElements = item.querySelectorAll(
8232+
"span, .text-xs, .font-medium",
8233+
);
8234+
textElements.forEach((el) => {
8235+
textContent += " " + el.textContent;
82068236
});
82078237

8208-
if (textContent.toLowerCase().includes(search)) {
8238+
// Also get direct text content
8239+
textContent += " " + item.textContent;
8240+
8241+
if (search === "" || textContent.toLowerCase().includes(search)) {
82098242
item.style.display = "";
8243+
hasVisibleItems = true;
82108244
} else {
82118245
item.style.display = "none";
82128246
}
82138247
});
8248+
8249+
// Handle no results message
8250+
const noResultsMessage = safeGetElement(noResultsId, true);
8251+
const searchQuerySpan = safeGetElement(searchQueryId, true);
8252+
8253+
if (search !== "" && !hasVisibleItems) {
8254+
if (noResultsMessage) {
8255+
noResultsMessage.style.display = "block";
8256+
}
8257+
if (searchQuerySpan) {
8258+
searchQuerySpan.textContent = searchText;
8259+
}
8260+
} else {
8261+
if (noResultsMessage) {
8262+
noResultsMessage.style.display = "none";
8263+
}
8264+
}
82148265
}
82158266

8267+
/**
8268+
* Filter server table rows based on search text
8269+
*/
8270+
function filterServerTable(searchText) {
8271+
try {
8272+
const tbody = document.querySelector(
8273+
'tbody[data-testid="server-list"]',
8274+
);
8275+
if (!tbody) {
8276+
console.warn("Server table not found");
8277+
return;
8278+
}
8279+
8280+
const rows = tbody.querySelectorAll('tr[data-testid="server-item"]');
8281+
const search = searchText.toLowerCase().trim();
8282+
8283+
rows.forEach((row) => {
8284+
let textContent = "";
8285+
8286+
// Get text from all cells in the row
8287+
const cells = row.querySelectorAll("td");
8288+
cells.forEach((cell) => {
8289+
textContent += " " + cell.textContent;
8290+
});
8291+
8292+
if (search === "" || textContent.toLowerCase().includes(search)) {
8293+
row.style.display = "";
8294+
} else {
8295+
row.style.display = "none";
8296+
}
8297+
});
8298+
} catch (error) {
8299+
console.error("Error filtering server table:", error);
8300+
}
8301+
}
8302+
8303+
// Make server search function available globally
8304+
window.filterServerTable = filterServerTable;
8305+
82168306
function handleAuthTypeChange() {
82178307
const authType = this.value;
82188308
const basicFields = safeGetElement("auth-basic-fields-gw");

mcpgateway/templates/admin.html

Lines changed: 16 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1081,9 +1081,11 @@ <h2 class="text-2xl font-bold dark:text-gray-200">
10811081
<div class="flex items-center space-x-4">
10821082
<input
10831083
type="text"
1084+
id="search-servers"
10841085
data-testid="search-input"
10851086
placeholder="Search servers..."
10861087
class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 dark:bg-gray-900 dark:placeholder-gray-300 dark:text-gray-300"
1088+
oninput="filterServerTable(this.value)"
10871089
/>
10881090
<div class="flex items-center">
10891091
<input
@@ -1584,6 +1586,13 @@ <h3 class="text-lg font-bold mb-4 dark:text-gray-200">
15841586
</div>
15851587
</label>
15861588
{% endfor %}
1589+
<p
1590+
id="noResourcesMessage"
1591+
class="text-gray-700 dark:text-gray-300"
1592+
style="display: none"
1593+
>
1594+
No resource found containing "<span id="searchResourcesQuery"></span>"
1595+
</p>
15871596
</div>
15881597
<div class="flex justify-end gap-3 mt-3">
15891598
<button
@@ -1643,6 +1652,13 @@ <h3 class="text-lg font-bold mb-4 dark:text-gray-200">
16431652
</div>
16441653
</label>
16451654
{% endfor %}
1655+
<p
1656+
id="noPromptsMessage"
1657+
class="text-gray-700 dark:text-gray-300"
1658+
style="display: none"
1659+
>
1660+
No prompt found containing "<span id="searchPromptsQuery"></span>"
1661+
</p>
16461662
</div>
16471663
<div class="flex justify-end gap-3 mt-3">
16481664
<button
@@ -7904,34 +7920,7 @@ <h4>Breakdown by Type:</h4>
79047920
});
79057921

79067922
// Add search functionality for filtering tools
7907-
document.addEventListener('DOMContentLoaded', function() {
7908-
const searchBox = document.getElementById('searchTools');
7909-
const toolItems = document.querySelectorAll('#associatedTools .tool-item');
7910-
const noToolsMessage = document.getElementById('noToolsMessage');
7911-
const searchQuerySpan = document.getElementById('searchQuery');
7912-
7913-
searchBox.addEventListener('input', function() {
7914-
const filter = this.value.toLowerCase();
7915-
let hasVisibleItems = false;
7916-
7917-
toolItems.forEach(function(toolItem) {
7918-
const toolName = toolItem.querySelector('span').textContent.toLowerCase();
7919-
if (toolName.includes(filter)) {
7920-
toolItem.style.display = '';
7921-
hasVisibleItems = true;
7922-
} else {
7923-
toolItem.style.display = 'none';
7924-
}
7925-
});
79267923

7927-
if (hasVisibleItems) {
7928-
noToolsMessage.style.display = 'none';
7929-
} else {
7930-
searchQuerySpan.textContent = filter;
7931-
noToolsMessage.style.display = 'block';
7932-
}
7933-
});
7934-
});
79357924
</script>
79367925
<script>
79377926
function handleEditIntegrationTypeChange() {

0 commit comments

Comments
 (0)