diff --git a/extensions/resteasy-reactive/rest-client-reactive/deployment/src/main/java/io/quarkus/rest/client/reactive/deployment/devconsole/RestClientReactiveDevConsoleProcessor.java b/extensions/resteasy-reactive/rest-client-reactive/deployment/src/main/java/io/quarkus/rest/client/reactive/deployment/devconsole/RestClientReactiveDevConsoleProcessor.java
index f311ef7f3de1b..88cf63330f0da 100644
--- a/extensions/resteasy-reactive/rest-client-reactive/deployment/src/main/java/io/quarkus/rest/client/reactive/deployment/devconsole/RestClientReactiveDevConsoleProcessor.java
+++ b/extensions/resteasy-reactive/rest-client-reactive/deployment/src/main/java/io/quarkus/rest/client/reactive/deployment/devconsole/RestClientReactiveDevConsoleProcessor.java
@@ -6,7 +6,11 @@
import io.quarkus.deployment.annotations.BuildStep;
import io.quarkus.deployment.pkg.builditem.CurateOutcomeBuildItem;
import io.quarkus.devconsole.spi.DevConsoleRuntimeTemplateInfoBuildItem;
+import io.quarkus.devui.spi.JsonRPCProvidersBuildItem;
+import io.quarkus.devui.spi.page.CardPageBuildItem;
+import io.quarkus.devui.spi.page.Page;
import io.quarkus.rest.client.reactive.runtime.devconsole.RestClientsContainer;
+import io.quarkus.rest.client.reactive.runtime.devconsole.RestClientsJsonRPCService;
public class RestClientReactiveDevConsoleProcessor {
@@ -20,4 +24,20 @@ public DevConsoleRuntimeTemplateInfoBuildItem devConsoleInfo(CurateOutcomeBuildI
public AdditionalBeanBuildItem beans() {
return AdditionalBeanBuildItem.unremovableOf(RestClientsContainer.class);
}
+
+ @BuildStep(onlyIf = IsDevelopment.class)
+ CardPageBuildItem create() {
+ CardPageBuildItem pageBuildItem = new CardPageBuildItem();
+ pageBuildItem.addPage(Page.webComponentPageBuilder()
+ .title("REST Clients")
+ .componentLink("qwc-rest-client-clients.js")
+ .icon("font-awesome-solid:server"));
+
+ return pageBuildItem;
+ }
+
+ @BuildStep(onlyIf = IsDevelopment.class)
+ JsonRPCProvidersBuildItem createJsonRPCServiceForCache() {
+ return new JsonRPCProvidersBuildItem(RestClientsJsonRPCService.class);
+ }
}
diff --git a/extensions/resteasy-reactive/rest-client-reactive/deployment/src/main/resources/dev-ui/qwc-rest-client-clients.js b/extensions/resteasy-reactive/rest-client-reactive/deployment/src/main/resources/dev-ui/qwc-rest-client-clients.js
new file mode 100644
index 0000000000000..5e914d2a2be3a
--- /dev/null
+++ b/extensions/resteasy-reactive/rest-client-reactive/deployment/src/main/resources/dev-ui/qwc-rest-client-clients.js
@@ -0,0 +1,99 @@
+import { LitElement, html, css} from 'lit';
+import { JsonRpc } from 'jsonrpc';
+import '@vaadin/icon';
+import '@vaadin/progress-bar';
+import '@vaadin/checkbox';
+import { until } from 'lit/directives/until.js';
+import '@vaadin/grid';
+import { columnBodyRenderer } from '@vaadin/grid/lit.js';
+import '@vaadin/grid/vaadin-grid-sort-column.js';
+
+export class QwcRestClientClients extends LitElement {
+
+ jsonRpc = new JsonRpc(this);
+
+ // Component style
+ static styles = css`
+ code {
+ font-size: 85%;
+ }`;
+
+ // Component properties
+ static properties = {
+ _clients: {state: true}
+ }
+
+ constructor() {
+ super();
+ this._clients = null;
+ }
+
+ // Components callbacks
+
+ /**
+ * Called when displayed
+ */
+ connectedCallback() {
+ super.connectedCallback();
+ this.jsonRpc.getAll().then(jsonRpcResponse => {
+ this._clients = jsonRpcResponse.result;
+ });
+ }
+
+ /**
+ * Called when it needs to render the components
+ * @returns {*}
+ */
+ render() {
+ return html`${until(this._renderClientsTable(), html`Loading REST Clients...`)}`;
+ }
+
+ // View / Templates
+
+ _renderClientsTable() {
+ if (this._clients) {
+ return html`
+
+
+
+
+
+
+
+
+
+ `;
+ }
+ }
+
+ _clientInterfaceRenderer(client){
+ return html`
+ ${client.clientInterface}
+ `;
+ }
+
+ _configKeyRenderer(client){
+ return html`
+ ${client.configKey}
+ `;
+ }
+
+ _isBeanRenderer(client){
+ if(client.isBean !== false){
+ return html`
+
+ `;
+ }
+ }
+
+}
+customElements.define('qwc-rest-client-clients', QwcRestClientClients);
diff --git a/extensions/resteasy-reactive/rest-client-reactive/runtime/src/main/java/io/quarkus/rest/client/reactive/runtime/devconsole/RestClientsJsonRPCService.java b/extensions/resteasy-reactive/rest-client-reactive/runtime/src/main/java/io/quarkus/rest/client/reactive/runtime/devconsole/RestClientsJsonRPCService.java
new file mode 100644
index 0000000000000..0406f82a046f1
--- /dev/null
+++ b/extensions/resteasy-reactive/rest-client-reactive/runtime/src/main/java/io/quarkus/rest/client/reactive/runtime/devconsole/RestClientsJsonRPCService.java
@@ -0,0 +1,35 @@
+package io.quarkus.rest.client.reactive.runtime.devconsole;
+
+import java.util.Comparator;
+
+import jakarta.inject.Singleton;
+
+import io.smallrye.common.annotation.NonBlocking;
+import io.vertx.core.json.JsonArray;
+import io.vertx.core.json.JsonObject;
+
+@Singleton
+public class RestClientsJsonRPCService {
+
+ private final RestClientsContainer restClientsContainer;
+
+ public RestClientsJsonRPCService(RestClientsContainer restClientsContainer) {
+ this.restClientsContainer = restClientsContainer;
+ }
+
+ @NonBlocking
+ public JsonArray getAll() {
+ var allClients = restClientsContainer.getClientData().clients;
+ allClients.sort(Comparator.comparing(rci -> rci.interfaceClass));
+
+ var result = new JsonArray();
+ for (RestClientsContainer.RestClientInfo rci : allClients) {
+ result.add(new JsonObject()
+ .put("clientInterface", rci.interfaceClass)
+ .put("isBean", rci.isBean)
+ .put("configKey", rci.configKey));
+ }
+ return result;
+ }
+
+}