Blueprint filter
### Expected Behavior

Displaying filters/tags : 
- A tag should not be displayed if it has no blueprints.
- When you do a search, you need to refresh the filter display.

<img width="1782" alt="Capture d’écran 2023-06-27 à 12 42 44" src="https://github.com/kestra-io/kestra/assets/125994028/c9bb39a2-8da1-4030-9689-a96c6856b73a">

Thanks


### Actual Behaviour

_No response_

### Steps To Reproduce

_No response_

### Environment Information

- Kestra Version:
- Operating System (OS / Docker / Kubernetes):
- Java Version (If not docker):


### Example flow

_No response_
ui/src/override/components/flows/blueprints/BlueprintsBrowser.vue webserver/src/main/java/io/kestra/webserver/controllers/BlueprintController.java
ui/src/override/components/flows/blueprints/BlueprintsBrowser.vue webserver/src/main/java/io/kestra/webserver/controllers/BlueprintController.java
webserver/src/test/java/io/kestra/webserver/controllers/BlueprintControllerTest.java
diff --git a/ui/src/override/components/flows/blueprints/BlueprintsBrowser.vue b/ui/src/override/components/flows/blueprints/BlueprintsBrowser.vue
index 5be2060bdd..a5b0caaa9d 100644
--- a/ui/src/override/components/flows/blueprints/BlueprintsBrowser.vue
+++ b/ui/src/override/components/flows/blueprints/BlueprintsBrowser.vue
@@ -122,8 +122,15 @@
                 }
             },
             loadTags(beforeLoadBlueprintBaseUri) {
+                const query = {}
+                if (this.$route.query.q || this.q) {
+                    query.q = this.$route.query.q || this.q;
+                }
+
                 return this.$http
-                    .get(beforeLoadBlueprintBaseUri + "/tags")
+                    .get(beforeLoadBlueprintBaseUri + "/tags", {
+                        params: query
+                    })
                     .then(response => {
                         // Handle switch tab while fetching data
                         if (this.blueprintBaseUri === beforeLoadBlueprintBaseUri) {
@@ -169,12 +176,7 @@
                 const beforeLoadBlueprintBaseUri = this.blueprintBaseUri;
 
                 Promise.all([
-                    new Promise(async (resolve) => {
-                        if (this.tags === undefined) {
-                            await this.loadTags(beforeLoadBlueprintBaseUri);
-                        }
-                        resolve();
-                    }),
+                    this.loadTags(beforeLoadBlueprintBaseUri),
                     this.loadBlueprints(beforeLoadBlueprintBaseUri)
                 ]).finally(() => {
                     // Handle switch tab while fetching data
@@ -186,7 +188,6 @@
             hardReload() {
                 this.ready = false;
                 this.selectedTag = 0;
-                this.tags = undefined;
                 this.load(this.onDataLoaded);
             }
         },
@@ -223,6 +224,11 @@
             },
             blueprintBaseUri() {
                 this.hardReload();
+            },
+            tags() {
+                if(!this.tags.hasOwnProperty(this.selectedTag)) {
+                    this.selectedTag = 0;
+                }
             }
         }
     };
diff --git a/webserver/src/main/java/io/kestra/webserver/controllers/BlueprintController.java b/webserver/src/main/java/io/kestra/webserver/controllers/BlueprintController.java
index b4bb57b6c3..fc925e8839 100644
--- a/webserver/src/main/java/io/kestra/webserver/controllers/BlueprintController.java
+++ b/webserver/src/main/java/io/kestra/webserver/controllers/BlueprintController.java
@@ -1,7 +1,6 @@
 package io.kestra.webserver.controllers;
 
 import com.fasterxml.jackson.annotation.JsonInclude;
-import io.kestra.core.models.hierarchies.FlowGraph;
 import io.kestra.webserver.responses.PagedResults;
 import io.micronaut.core.annotation.Introspected;
 import io.micronaut.core.annotation.Nullable;
@@ -85,8 +84,9 @@ public BlueprintItemWithFlow blueprint(
     @SuppressWarnings("unchecked")
     @ExecuteOn(TaskExecutors.IO)
     @Get("tags")
-    @Operation(tags = {"Blueprint Tags"}, summary = "List all blueprint tags")
+    @Operation(tags = {"Blueprint Tags"}, summary = "List blueprint tags matching the filter")
     public List<BlueprintTagItem> blueprintTags(
+        @Parameter(description = "A string filter to get tags with matching blueprints only") @Nullable @QueryValue(value = "q") Optional<String> q,
         HttpRequest<?> httpRequest
     ) throws URISyntaxException {
         return fastForwardToKestraApi(httpRequest, "/v1/blueprints/tags", Argument.of(List.class, BlueprintTagItem.class));

diff --git a/webserver/src/test/java/io/kestra/webserver/controllers/BlueprintControllerTest.java b/webserver/src/test/java/io/kestra/webserver/controllers/BlueprintControllerTest.java
index d772420214..15740e77eb 100644
--- a/webserver/src/test/java/io/kestra/webserver/controllers/BlueprintControllerTest.java
+++ b/webserver/src/test/java/io/kestra/webserver/controllers/BlueprintControllerTest.java
@@ -137,7 +137,7 @@ void blueprintTags(WireMockRuntimeInfo wmRuntimeInfo) {
         );
 
         List<BlueprintController.BlueprintTagItem> blueprintTags = client.toBlocking().retrieve(
-            HttpRequest.GET("/api/v1/blueprints/community/tags"),
+            HttpRequest.GET("/api/v1/blueprints/community/tags?q=someQuery"),
             Argument.of(List.class, BlueprintController.BlueprintTagItem.class)
         );
 
@@ -147,6 +147,6 @@ void blueprintTags(WireMockRuntimeInfo wmRuntimeInfo) {
         assertThat(blueprintTags.get(0).getPublishedAt(), is(Instant.parse("2023-06-01T08:37:10.171Z")));
 
         WireMock wireMock = wmRuntimeInfo.getWireMock();
-        wireMock.verifyThat(getRequestedFor(urlEqualTo("/v1/blueprints/tags")));
+        wireMock.verifyThat(getRequestedFor(urlEqualTo("/v1/blueprints/tags?q=someQuery")));
     }
 }
