diff --git a/assets/sass/content.sass b/assets/sass/content.sass index 3ae27f5d8bd..26a0b8b6d6c 100644 --- a/assets/sass/content.sass +++ b/assets/sass/content.sass @@ -30,5 +30,5 @@ width: 100% @media screen and (min-width: 769px) - .is-search-result > .column + .is-search-result > .column, .is-external-search-result > .column width: 50% diff --git a/layouts/partials/javascript.html b/layouts/partials/javascript.html index 06bed679249..e5f24348bab 100644 --- a/layouts/partials/javascript.html +++ b/layouts/partials/javascript.html @@ -39,22 +39,25 @@ const builtInScalers = document.querySelectorAll("#built-in-scalers"); const externalScalers = document.getElementById("external-scalers"); const btnFocusOnMount = document.getElementById("btn-focus-on-mount"); - const searchResultCount = document.querySelector(".results"); - + const builtInSearchResultCount = document.querySelector(".results"); + const externalSearchResultCount = document.querySelector(".external-results"); let btns = document.getElementsByClassName("filterBtn"); + for (let i = 0; i < btns.length; i++) { btns[i].addEventListener("click", function () { let filterValue = btns[i].value.toLowerCase(); if (filterValue === "built-in-scalers") { builtInScalers.forEach((node) => (node.style.display = "flex")); externalScalers.style.display = "none"; - searchResultCount.style.display = "block"; + builtInSearchResultCount.style.display = "block"; + externalSearchResultCount.style.display = "none"; } else if (filterValue === "external-scalers") { // remove focus when changed btnFocusOnMount.classList.remove("is-focused"); builtInScalers.forEach((node) => (node.style.display = "none")); externalScalers.style.display = "inline"; - searchResultCount.style.display = "none"; + builtInSearchResultCount.style.display = "none"; + externalSearchResultCount.style.display = "block"; } }); } @@ -75,20 +78,27 @@ const form = document.getElementById("search"); const input = document.getElementById("search-input"); const target = document.querySelector(".is-search-result"); + const externalTarget = document.querySelector( + ".is-external-search-result" + ); const searchResultCount = document.querySelector(".results"); + const externalSearchResultCount = + document.querySelector(".external-results"); const template = document.getElementById("is-search-template"); const isExternalScalers = document.getElementById("external-scalers"); const isBuiltInScalers = document.getElementById("built-in-scalers"); + const externalBanner = document.getElementById("external-banner"); const groups = document.getElementsByClassName( "artifacthub-widget-group" ); - const interval = 300; + const interval = 500; let query = input.value.trim(); let parse = {}; // fetch all scalers on inital load if (!query) { initSearchIndex(); + externalScalersIndex(); } input.addEventListener( @@ -109,10 +119,14 @@ } query = keywords; - - if (isExternalScalers) { + if (isExternalScalers.style.display === "inline") { + // hide banner during scaler search + externalBanner.style.display = "none"; + if (query === "") { + externalBanner.style.display = "block"; + } let externalSearchUrl = new URL( - "https://artifacthub.io/packages/search" + "https://artifacthub.io/api/v1/packages/search" ); externalSearchUrl.search = new URLSearchParams({ kind: "8", @@ -121,13 +135,21 @@ }); debounceTimer = setTimeout(() => { groups[0].dataset.url = externalSearchUrl; + externalScalersIndex(); }, interval); - } - if (isBuiltInScalers) { - debounceTimer = setTimeout(initSearchIndex, interval); + // clear out all the scaler item card when external scalers are being searched + while (externalTarget.firstChild.nextSibling) { + externalTarget.removeChild( + externalTarget.firstChild.nextSibling.nextSibling + .nextElementSibling + ); + } + return; } + debounceTimer = setTimeout(initSearchIndex, interval); + // clear out all the scaler item card when in-built scalers are being searched while (target.firstChild.nextSibling) { target.removeChild(template.nextSibling.nextElementSibling); @@ -136,6 +158,57 @@ false ); + async function externalScalersIndex() { + const externalScalerUrl = groups[0].dataset.url; + const results = await fetch(externalScalerUrl) + .then((response) => response.json()) + .then((data) => { + return data.packages; + }) + .catch((err) => console.error("error:", err)); + + if ("content" in template) { + // show result count + const title = document.createElement("h3"); + title.id = "external-search-results"; + title.className = "subtitle is-size-3 external-search-results"; + + if (results.length == 0) + title.textContent = `No results found for "${query}"`; + else if (results.length == 1) + title.textContent = `Found one result for "${query}"`; + else if (results.length > 1 && query === "") + title.textContent = `${results.length} scalers available`; + else + title.textContent = `Found ${results.length} results for "${query}"`; + externalSearchResultCount.replaceChildren(title); + + // show the matched result + results.forEach(function (result) { + const element = template.content.cloneNode(true); + element.querySelector(".scaler-title").textContent = + result.display_name; + element + .querySelector(".scaler-title") + .setAttribute("href", result.repository.url); + result.description && + (element.querySelector(".description").textContent = + result.description); + result.repository.organization_name && + (element.querySelector(".maintainer").textContent = + result.repository.organization_name); + result.repository.user_alias && + (element.querySelector(".maintainer").textContent = + result.repository.user_alias); + result.version && + (element.querySelector( + ".availability" + ).textContent = `v${result.version}`); + externalTarget.appendChild(element); + }, this); + } + } + async function initSearchIndex() { const scalers = await fetch("/index.json", { method: "GET" }) .then((response) => response.json()) diff --git a/layouts/partials/scaler-layout.html b/layouts/partials/scaler-layout.html index 09049472bfb..de982e42377 100644 --- a/layouts/partials/scaler-layout.html +++ b/layouts/partials/scaler-layout.html @@ -25,6 +25,7 @@

Currently available scalers for KEDA

+
Currently available scalers for KEDA {{ partial "scaler-template" . }}