diff --git a/extensions/oidc/deployment/src/main/java/io/quarkus/oidc/deployment/devservices/keycloak/KeycloakDevConsoleProcessor.java b/extensions/oidc/deployment/src/main/java/io/quarkus/oidc/deployment/devservices/keycloak/KeycloakDevConsoleProcessor.java index df812885e00d1..3aa2515cb9a4f 100644 --- a/extensions/oidc/deployment/src/main/java/io/quarkus/oidc/deployment/devservices/keycloak/KeycloakDevConsoleProcessor.java +++ b/extensions/oidc/deployment/src/main/java/io/quarkus/oidc/deployment/devservices/keycloak/KeycloakDevConsoleProcessor.java @@ -19,6 +19,7 @@ import io.quarkus.devconsole.spi.DevConsoleTemplateInfoBuildItem; import io.quarkus.devui.spi.JsonRPCProvidersBuildItem; import io.quarkus.devui.spi.page.CardPageBuildItem; +import io.quarkus.devui.spi.page.Page; import io.quarkus.oidc.deployment.OidcBuildTimeConfig; import io.quarkus.oidc.deployment.devservices.AbstractDevConsoleProcessor; import io.quarkus.oidc.deployment.devservices.OidcAuthorizationCodePostHandler; @@ -81,7 +82,9 @@ void produceProviderComponent(Optional confi @SuppressWarnings("unchecked") Map users = (Map) configProps.get().getProperties().get("oidc.users"); - var cardPage = createProviderWebComponent( + String keycloakAdminUrl = configProps.get().getConfig().get("keycloak.url"); + + CardPageBuildItem cardPageBuildItem = createProviderWebComponent( recorder, capabilities, "Keycloak", @@ -97,11 +100,17 @@ void produceProviderComponent(Optional confi oidcConfig.devui.grantOptions, nonApplicationRootPathBuildItem, configurationBuildItem, - configProps.get().getConfig().get("keycloak.url"), + keycloakAdminUrl, users, configProps.get().getProperties().get("keycloak.realms"), configProps.get().isContainerRestarted()); - cardPageProducer.produce(cardPage); + + // Also add Admin page + cardPageBuildItem.addPage(Page.externalPageBuilder("Keycloak Admin") + .icon("font-awesome-solid:key") + .doNotEmbed(true) + .url(keycloakAdminUrl)); + cardPageProducer.produce(cardPageBuildItem); } } diff --git a/extensions/oidc/deployment/src/main/resources/dev-ui/qwc-oidc-provider.js b/extensions/oidc/deployment/src/main/resources/dev-ui/qwc-oidc-provider.js index 6b34773c2071c..96ef5fb13f2d4 100644 --- a/extensions/oidc/deployment/src/main/resources/dev-ui/qwc-oidc-provider.js +++ b/extensions/oidc/deployment/src/main/resources/dev-ui/qwc-oidc-provider.js @@ -351,27 +351,6 @@ export class QwcOidcProvider extends QwcHotReloadElement { } _renderProvider() { - const content = this._content(); - if (propertiesState.keycloakAdminUrl) { - return html ` - - ${content} - QwcOidcProvider._goToKeycloakUrl()}> - - Keycloak Admin - - - `; - } - - return content; - } - - _content() { if (QwcOidcProvider._isServiceOrHybridApp()) { switch (propertiesState.oidcGrantType) { case 'password': @@ -933,10 +912,6 @@ export class QwcOidcProvider extends QwcHotReloadElement { return result; } - static _goToKeycloakUrl() { - window.open(propertiesState.keycloakAdminUrl, '_blank').focus(); - } - static _areTokensInUrl() { return QwcOidcProvider._getHashQueryStringParam('id_token') && QwcOidcProvider._getHashQueryStringParam('access_token'); diff --git a/extensions/vertx-http/dev-ui-resources/src/main/resources/dev-ui/controller/router-controller.js b/extensions/vertx-http/dev-ui-resources/src/main/resources/dev-ui/controller/router-controller.js index 7b609d8b56270..d2a85ae23bd3e 100644 --- a/extensions/vertx-http/dev-ui-resources/src/main/resources/dev-ui/controller/router-controller.js +++ b/extensions/vertx-http/dev-ui-resources/src/main/resources/dev-ui/controller/router-controller.js @@ -122,6 +122,22 @@ export class RouterController { return false; } + addExternalLink(page){ + let path = this.getPageUrlFor(page); + if (!this.isExistingPath(path)) { + RouterController.pageMap.set(path, page); + if(RouterController.namespaceMap.has(page.namespace)){ + // Existing + RouterController.namespaceMap.get(page.namespace).push(page); + }else{ + // New + let namespacePages = []; + namespacePages.push(page); + RouterController.namespaceMap.set(page.namespace, namespacePages); + } + } + } + addRouteForMenu(page, defaultSelection){ this.addRoute(page.id, page.componentName, page.title, page, defaultSelection); } diff --git a/extensions/vertx-http/dev-ui-resources/src/main/resources/dev-ui/qwc/qwc-extension-link.js b/extensions/vertx-http/dev-ui-resources/src/main/resources/dev-ui/qwc/qwc-extension-link.js index c5d670deb9e5e..c514dfd82b43e 100644 --- a/extensions/vertx-http/dev-ui-resources/src/main/resources/dev-ui/qwc/qwc-extension-link.js +++ b/extensions/vertx-http/dev-ui-resources/src/main/resources/dev-ui/qwc/qwc-extension-link.js @@ -195,8 +195,8 @@ export class QwcExtensionLink extends QwcHotReloadElement { ${this.displayName} - ${this._renderBadge()} + ${this._renderBadge()} `; }else{ return html` @@ -204,8 +204,7 @@ export class QwcExtensionLink extends QwcHotReloadElement { loading ... - ${this._renderBadge()} - `; + ${this._renderBadge()}`; } } diff --git a/extensions/vertx-http/dev-ui-resources/src/main/resources/dev-ui/qwc/qwc-extensions.js b/extensions/vertx-http/dev-ui-resources/src/main/resources/dev-ui/qwc/qwc-extensions.js index 6b845302c3c86..7c97fa002e869 100644 --- a/extensions/vertx-http/dev-ui-resources/src/main/resources/dev-ui/qwc/qwc-extensions.js +++ b/extensions/vertx-http/dev-ui-resources/src/main/resources/dev-ui/qwc/qwc-extensions.js @@ -58,6 +58,8 @@ export class QwcExtensions extends observeState(LitElement) { if(page.embed){ // we need to register with the router import(page.componentRef); this.routerController.addRouteForExtension(page); + }else if(page.includeInSubMenu){ // we need to add the link to the submenu + this.routerController.addExternalLink(page); } }); diff --git a/extensions/vertx-http/dev-ui-spi/src/main/java/io/quarkus/devui/spi/page/ExternalPageBuilder.java b/extensions/vertx-http/dev-ui-spi/src/main/java/io/quarkus/devui/spi/page/ExternalPageBuilder.java index 5736a46757260..aad52ee93d1cb 100644 --- a/extensions/vertx-http/dev-ui-spi/src/main/java/io/quarkus/devui/spi/page/ExternalPageBuilder.java +++ b/extensions/vertx-http/dev-ui-spi/src/main/java/io/quarkus/devui/spi/page/ExternalPageBuilder.java @@ -65,7 +65,13 @@ public ExternalPageBuilder mimeType(String mimeType) { } public ExternalPageBuilder doNotEmbed() { + return doNotEmbed(false); + } + + public ExternalPageBuilder doNotEmbed(boolean includeInSubMenu) { super.embed = false; + super.includeInSubMenu = includeInSubMenu; return this; } + } \ No newline at end of file diff --git a/extensions/vertx-http/dev-ui-spi/src/main/java/io/quarkus/devui/spi/page/Page.java b/extensions/vertx-http/dev-ui-spi/src/main/java/io/quarkus/devui/spi/page/Page.java index d80b959c6a287..f088c06773dfe 100644 --- a/extensions/vertx-http/dev-ui-spi/src/main/java/io/quarkus/devui/spi/page/Page.java +++ b/extensions/vertx-http/dev-ui-spi/src/main/java/io/quarkus/devui/spi/page/Page.java @@ -21,6 +21,7 @@ public class Page { private final Map metadata; // Key value Metadata private final boolean embed; // if the component is embedded in the page. true in all cases except maybe external pages + private final boolean includeInSubMenu; // if this link should be added to the submenu. true in all cases except maybe external pages private final boolean internalComponent; // True if this component is provided by dev-ui (usually provided by the extension) private String namespace = null; // The namespace can be the extension path or, if internal, qwc @@ -36,6 +37,7 @@ protected Page(String icon, String componentLink, Map metadata, boolean embed, + boolean includeInSubMenu, boolean internalComponent, String namespace, String namespaceLabel, @@ -50,6 +52,7 @@ protected Page(String icon, this.componentLink = componentLink; this.metadata = metadata; this.embed = embed; + this.includeInSubMenu = includeInSubMenu; this.internalComponent = internalComponent; this.namespace = namespace; this.namespaceLabel = namespaceLabel; @@ -125,6 +128,10 @@ public boolean isEmbed() { return embed; } + public boolean isIncludeInSubMenu() { + return includeInSubMenu; + } + public boolean isInternal() { return this.internalComponent && this.extensionId == null; } @@ -149,7 +156,8 @@ public String toString() { + ", \n\tnamespaceLabel=" + namespaceLabel + ", \n\tcomponentName=" + componentName + ", \n\tcomponentLink=" + componentLink - + ", \n\tembed=" + embed + "\n}"; + + ", \n\tembed=" + embed + + ", \n\tincludeInSubMenu=" + includeInSubMenu + "\n}"; } /** diff --git a/extensions/vertx-http/dev-ui-spi/src/main/java/io/quarkus/devui/spi/page/PageBuilder.java b/extensions/vertx-http/dev-ui-spi/src/main/java/io/quarkus/devui/spi/page/PageBuilder.java index add47ae44c884..1a0acf35d278a 100644 --- a/extensions/vertx-http/dev-ui-spi/src/main/java/io/quarkus/devui/spi/page/PageBuilder.java +++ b/extensions/vertx-http/dev-ui-spi/src/main/java/io/quarkus/devui/spi/page/PageBuilder.java @@ -21,6 +21,7 @@ public abstract class PageBuilder { protected String componentLink; protected Map metadata = new HashMap<>(); protected boolean embed = true; // default + protected boolean includeInSubMenu = true; // default protected boolean internalComponent = false; // default protected String namespace = null; protected String namespaceLabel = null; @@ -128,6 +129,7 @@ public Page build() { componentLink, metadata, embed, + includeInSubMenu, internalComponent, namespace, namespaceLabel,