diff --git a/app/_assets/entrypoints/hub.js b/app/_assets/entrypoints/hub.js new file mode 100644 index 00000000..390511ae --- /dev/null +++ b/app/_assets/entrypoints/hub.js @@ -0,0 +1,83 @@ +class Hub { + constructor() { + this.filters = document.getElementById("filters"); + this.plugins = document.querySelectorAll("[data-card='plugin']"); + + this.deploymentTopologies = this.filters.querySelectorAll( + 'input[name="deployment-topology"]' + ); + this.categories = this.filters.querySelectorAll('input[name="category"]'); + + this.deploymentValues = []; + this.categoryValues = []; + + this.addEventListeners(); + } + + addEventListeners() { + const checkboxes = [...this.deploymentTopologies, ...this.categories]; + checkboxes.forEach((checkbox) => { + checkbox.addEventListener("change", () => this.onChange()); + }); + } + + onChange() { + this.deploymentValues = this.getValues(this.deploymentTopologies); + this.categoryValues = this.getValues(this.categories); + + this.filterPlugins(); + } + + getValues(filterGroup) { + return Array.from(filterGroup) + .filter((checkbox) => checkbox.checked) + .map((checkbox) => checkbox.value); + } + + filterPlugins() { + this.plugins.forEach((plugin) => { + const matchesDeploymentTopology = this.filterBy( + plugin, + this.deploymentTopologies, + "deploymentTopology" + ); + const matchesCategory = this.filterBy( + plugin, + this.categories, + "category" + ); + + const showPlugin = matchesDeploymentTopology && matchesCategory; + + plugin.classList.toggle("hidden", !showPlugin); + }); + + this.toggleCategoriesIfEmpty(); + } + + toggleCategoriesIfEmpty() { + this.categories.forEach((cat) => { + const category = document.getElementById(cat.value); + const showCategory = category.querySelectorAll( + '[data-card="plugin"]:not(.hidden)' + ).length; + + category.classList.toggle("hidden", !showCategory); + }); + } + + filterBy(plugin, filterGroup, dataAttribute) { + const checkedValues = Array.from(filterGroup) + .filter((checkbox) => checkbox.checked) + .map((checkbox) => checkbox.value); + + const dataValues = plugin.dataset[dataAttribute]?.split(",") || []; + return ( + checkedValues.length === 0 || + checkedValues.some((value) => dataValues.includes(value)) + ); + } +} + +// Initialize the Hub once the DOM is fully loaded +document.addEventListener("DOMContentLoaded", () => new Hub()); diff --git a/app/_data/plugin_categories.yml b/app/_data/plugin_categories.yml index 533ad18b..6afce132 100644 --- a/app/_data/plugin_categories.yml +++ b/app/_data/plugin_categories.yml @@ -1,24 +1,24 @@ -- name: AI +- text: AI slug: ai desc: Govern, secure, and control AI traffic with multi-LLM AI Gateway plugins -- name: Authentication +- text: Authentication slug: authentication desc: Protect your services with an authentication layer -- name: Security +- text: Security slug: security desc: Protect your services with additional security layer -- name: Traffic Control +- text: Traffic Control slug: traffic-control desc: Manage, throttle and restrict inbound and outbound API traffic -- name: Serverless +- text: Serverless slug: serverless desc: Invoke serverless functions in combination with other plugins -- name: Analytics & Monitoring +- text: Analytics & Monitoring slug: analytics-monitoring desc: Visualize, inspect and monitor APIs and microservices traffic -- name: Transformations +- text: Transformations slug: transformations desc: Transform request and responses on the fly on Kong -- name: Logging +- text: Logging slug: logging desc: Log request and response data using the best transport for your infrastructure \ No newline at end of file diff --git a/app/_includes/cards/plugin.html b/app/_includes/cards/plugin.html index 704cffd2..f1217fb9 100644 --- a/app/_includes/cards/plugin.html +++ b/app/_includes/cards/plugin.html @@ -1,6 +1,12 @@ {% assign plugin = include.plugin %} -