From d480ef8d53f1cf45a605846a36d0e5bb6f406842 Mon Sep 17 00:00:00 2001 From: Phillip Kruger Date: Tue, 18 Apr 2023 13:09:28 +1000 Subject: [PATCH] Dev UI Move info to menu item and format page for known items Signed-off-by: Phillip Kruger --- ...Processor.java => InfoDevUIProcessor.java} | 24 +-- .../src/main/resources/dev-ui/qwc-info.js | 149 ++++++++++++++++++ .../deployment/BuildTimeContentProcessor.java | 40 ++++- .../src/main/resources/dev-ui/qui/qui-card.js | 92 +++++++++++ 4 files changed, 288 insertions(+), 17 deletions(-) rename extensions/info/deployment/src/main/java/io/quarkus/info/deployment/{InfoDevUiProcessor.java => InfoDevUIProcessor.java} (62%) create mode 100644 extensions/info/deployment/src/main/resources/dev-ui/qwc-info.js create mode 100644 extensions/vertx-http/dev-ui-resources/src/main/resources/dev-ui/qui/qui-card.js diff --git a/extensions/info/deployment/src/main/java/io/quarkus/info/deployment/InfoDevUiProcessor.java b/extensions/info/deployment/src/main/java/io/quarkus/info/deployment/InfoDevUIProcessor.java similarity index 62% rename from extensions/info/deployment/src/main/java/io/quarkus/info/deployment/InfoDevUiProcessor.java rename to extensions/info/deployment/src/main/java/io/quarkus/info/deployment/InfoDevUIProcessor.java index a8c4e6362386f..8c1e87051ea77 100644 --- a/extensions/info/deployment/src/main/java/io/quarkus/info/deployment/InfoDevUiProcessor.java +++ b/extensions/info/deployment/src/main/java/io/quarkus/info/deployment/InfoDevUIProcessor.java @@ -2,34 +2,36 @@ import io.quarkus.deployment.IsDevelopment; import io.quarkus.deployment.annotations.BuildStep; -import io.quarkus.deployment.annotations.ExecutionTime; -import io.quarkus.deployment.annotations.Record; import io.quarkus.deployment.builditem.LaunchModeBuildItem; -import io.quarkus.devui.spi.page.CardPageBuildItem; +import io.quarkus.devui.spi.page.MenuPageBuildItem; import io.quarkus.devui.spi.page.Page; -import io.quarkus.info.runtime.InfoRecorder; import io.quarkus.vertx.http.deployment.NonApplicationRootPathBuildItem; import io.quarkus.vertx.http.runtime.management.ManagementInterfaceBuildTimeConfig; /** * This processor is responsible for the dev ui widget. */ -public class InfoDevUiProcessor { +public class InfoDevUIProcessor { @BuildStep(onlyIf = IsDevelopment.class) - @Record(ExecutionTime.STATIC_INIT) - CardPageBuildItem create(NonApplicationRootPathBuildItem nonApplicationRootPathBuildItem, + MenuPageBuildItem create(NonApplicationRootPathBuildItem nonApplicationRootPathBuildItem, InfoBuildTimeConfig config, ManagementInterfaceBuildTimeConfig managementInterfaceBuildTimeConfig, - LaunchModeBuildItem launchModeBuildItem, - InfoRecorder unused) { - CardPageBuildItem pageBuildItem = new CardPageBuildItem(); + LaunchModeBuildItem launchModeBuildItem) { + MenuPageBuildItem pageBuildItem = new MenuPageBuildItem(); var path = nonApplicationRootPathBuildItem.resolveManagementPath(config.path(), managementInterfaceBuildTimeConfig, launchModeBuildItem); - pageBuildItem.addPage(Page.externalPageBuilder("App Information") + + pageBuildItem.addBuildTimeData("infoUrl", path); + + pageBuildItem.addPage(Page.webComponentPageBuilder() + .title("Information") .icon("font-awesome-solid:circle-info") + .componentLink("qwc-info.js")); + pageBuildItem.addPage(Page.externalPageBuilder("Raw") .url(path) + .icon("font-awesome-solid:circle-info") .isJsonContent()); return pageBuildItem; diff --git a/extensions/info/deployment/src/main/resources/dev-ui/qwc-info.js b/extensions/info/deployment/src/main/resources/dev-ui/qwc-info.js new file mode 100644 index 0000000000000..3cd1f9e32c2d2 --- /dev/null +++ b/extensions/info/deployment/src/main/resources/dev-ui/qwc-info.js @@ -0,0 +1,149 @@ +import { LitElement, html, css} from 'lit'; +import { columnBodyRenderer } from '@vaadin/grid/lit.js'; +import { infoUrl } from 'build-time-data'; +import '@vaadin/progress-bar'; +import 'qui-card'; +import '@vaadin/icon'; + +/** + * This component shows the Info Screen + */ +export class QwcInfo extends LitElement { + + static styles = css` + :host { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(450px, 1fr)); + gap: 1em; + padding: 10px; + } + qui-card { + display: flex; + } + .cardContent { + display: flex; + align-items: center; + padding: 10px; + gap: 10px; + } + vaadin-icon { + font-size: xx-large; + } + `; + + static properties = { + _infoUrl: {state: false}, + _info: {state: true}, + }; + + constructor() { + super(); + this._infoUrl = infoUrl; + this._info = null; + } + + async connectedCallback() { + super.connectedCallback(); + await this.load(); + } + + async load() { + const response = await fetch(this._infoUrl) + const data = await response.json(); + this._info = data; + } + + render() { + if (this._info) { + return html` + ${this._renderOsInfo(this._info)} + ${this._renderJavaInfo(this._info)} + ${this._renderGitInfo(this._info)} + ${this._renderBuildInfo(this._info)} + `; + }else{ + return html` +
+
Fetching infomation...
+ +
+ `; + } + } + + _renderOsInfo(info){ + if(info.os){ + let os = info.os; + return html` +
+ ${this._renderOsIcon(os.name)} + + + + +
Name${os.name}
Version${os.version}
Arch${os.arch}
+
+
`; + } + } + + _renderJavaInfo(info){ + if(info.java){ + let java = info.java; + return html` +
+ + + +
Version${java.version}
+
+
`; + } + } + + _renderOsIcon(osname){ + + if(osname){ + if(osname.toLowerCase().startsWith("linux")){ + return html``; + }else if(osname.toLowerCase().startsWith("mac") || osname.toLowerCase().startsWith("darwin")){ + return html``; + }else if(osname.toLowerCase().startsWith("win")){ + return html``; + } + } + } + + _renderGitInfo(info){ + if(info.git){ + let git = info.git; + return html` +
+ + + + + +
Branch${git.branch}
Commit${git.commit.id}
Time${git.commit.time}
+
+
`; + } + } + + _renderBuildInfo(info){ + if(info.build){ + let build = info.build; + return html` +
+ + + + + +
Group${build.group}
Artifact${build.artifact}
Version${build.version}
Time${build.time}
+
+
`; + } + } +} +customElements.define('qwc-info', QwcInfo); \ No newline at end of file diff --git a/extensions/vertx-http/deployment/src/main/java/io/quarkus/devui/deployment/BuildTimeContentProcessor.java b/extensions/vertx-http/deployment/src/main/java/io/quarkus/devui/deployment/BuildTimeContentProcessor.java index 8c86ff8afb119..d7c38fc12410f 100644 --- a/extensions/vertx-http/deployment/src/main/java/io/quarkus/devui/deployment/BuildTimeContentProcessor.java +++ b/extensions/vertx-http/deployment/src/main/java/io/quarkus/devui/deployment/BuildTimeContentProcessor.java @@ -32,7 +32,10 @@ import io.quarkus.devui.spi.DevUIContent; import io.quarkus.devui.spi.buildtime.QuteTemplateBuildItem; import io.quarkus.devui.spi.buildtime.StaticContentBuildItem; +import io.quarkus.devui.spi.page.AbstractPageBuildItem; import io.quarkus.devui.spi.page.CardPageBuildItem; +import io.quarkus.devui.spi.page.FooterPageBuildItem; +import io.quarkus.devui.spi.page.MenuPageBuildItem; import io.quarkus.devui.spi.page.Page; import io.quarkus.devui.spi.page.PageBuilder; import io.quarkus.vertx.http.deployment.NonApplicationRootPathBuildItem; @@ -67,6 +70,8 @@ InternalImportMapBuildItem createKnownInternalImportMap(NonApplicationRootPathBu internalImportMapBuildItem.add("qwc-server-log", contextRoot + "qwc/qwc-server-log.js"); // Quarkus UI internalImportMapBuildItem.add("qui/", contextRoot + "qui/"); + internalImportMapBuildItem.add("qui-card", contextRoot + "qui/qui-card.js"); + internalImportMapBuildItem.add("qui-badge", contextRoot + "qui/qui-badge.js"); internalImportMapBuildItem.add("qui-alert", contextRoot + "qui/qui-alert.js"); // Echarts @@ -101,13 +106,31 @@ InternalImportMapBuildItem createKnownInternalImportMap(NonApplicationRootPathBu * @param buildTimeConstProducer */ @BuildStep(onlyIf = IsDevelopment.class) - void mapPageBuildTimeData(List pageBuildItems, + void mapPageBuildTimeData(List cards, + List menus, + List footers, CurateOutcomeBuildItem curateOutcomeBuildItem, BuildProducer buildTimeConstProducer) { - for (CardPageBuildItem pageBuildItem : pageBuildItems) { - String extensionPathName = pageBuildItem.getExtensionPathName(curateOutcomeBuildItem); - Map buildTimeData = getBuildTimeData(curateOutcomeBuildItem, pageBuildItem); + for (CardPageBuildItem card : cards) { + String extensionPathName = card.getExtensionPathName(curateOutcomeBuildItem); + Map buildTimeData = getBuildTimeDataForCard(curateOutcomeBuildItem, card); + if (!buildTimeData.isEmpty()) { + buildTimeConstProducer.produce( + new BuildTimeConstBuildItem(extensionPathName, buildTimeData)); + } + } + for (MenuPageBuildItem menu : menus) { + String extensionPathName = menu.getExtensionPathName(curateOutcomeBuildItem); + Map buildTimeData = getBuildTimeDataForPage(menu); + if (!buildTimeData.isEmpty()) { + buildTimeConstProducer.produce( + new BuildTimeConstBuildItem(extensionPathName, buildTimeData)); + } + } + for (FooterPageBuildItem footer : footers) { + String extensionPathName = footer.getExtensionPathName(curateOutcomeBuildItem); + Map buildTimeData = getBuildTimeDataForPage(footer); if (!buildTimeData.isEmpty()) { buildTimeConstProducer.produce( new BuildTimeConstBuildItem(extensionPathName, buildTimeData)); @@ -115,12 +138,17 @@ void mapPageBuildTimeData(List pageBuildItems, } } - private Map getBuildTimeData(CurateOutcomeBuildItem curateOutcomeBuildItem, - CardPageBuildItem pageBuildItem) { + private Map getBuildTimeDataForPage(AbstractPageBuildItem pageBuildItem) { Map m = new HashMap<>(); if (pageBuildItem.hasBuildTimeData()) { m.putAll(pageBuildItem.getBuildTimeData()); } + return m; + } + + private Map getBuildTimeDataForCard(CurateOutcomeBuildItem curateOutcomeBuildItem, + CardPageBuildItem pageBuildItem) { + Map m = getBuildTimeDataForPage(pageBuildItem); if (pageBuildItem.getOptionalCard().isPresent()) { // Make the pages available for the custom card diff --git a/extensions/vertx-http/dev-ui-resources/src/main/resources/dev-ui/qui/qui-card.js b/extensions/vertx-http/dev-ui-resources/src/main/resources/dev-ui/qui/qui-card.js new file mode 100644 index 0000000000000..2ea714978cdc1 --- /dev/null +++ b/extensions/vertx-http/dev-ui-resources/src/main/resources/dev-ui/qui/qui-card.js @@ -0,0 +1,92 @@ +import { LitElement, html, css} from 'lit'; + +/** + * Card UI Component + */ +export class QuiCard extends LitElement { + + static styles = css` + .card { + display: flex; + flex-direction: column; + justify-content: space-between; + border: 1px solid var(--lumo-contrast-10pct); + border-radius: 4px; + filter: brightness(90%); + + } + + .card-header { + font-size: var(--lumo-font-size-l); + line-height: 1; + height: 25px; + display: flex; + flex-direction: row; + justify-content: space-between; + align-items: center; + padding: 10px 10px; + background-color: var(--lumo-contrast-5pct); + border-bottom: 1px solid var(--lumo-contrast-10pct); + } + + .card-footer { + height: 20px; + padding: 10px 10px; + color: var(--lumo-contrast-50pct); + display: flex; + flex-direction: row; + justify-content: space-between; + visibility:hidden; + }`; + + static properties = { + title: {type: String}, + width: {state: true}, + _hasFooter: {state: true}, + }; + + constructor(){ + super(); + this.width = "100%"; + this._hasFooter = false; + } + + connectedCallback() { + super.connectedCallback() + } + + render() { + return html`
+ ${this._headerTemplate()} + + ${this._footerTemplate()} +
`; + } + + firstUpdated(){ + const footerSlot = this.shadowRoot.querySelector("#footer"); + if (footerSlot && footerSlot.assignedNodes().length>0){ + console.log('No content is available') + this._hasFooter = true; + } + } + + _headerTemplate() { + return html`
+
${this.title}
+
+ `; + } + + _footerTemplate() { + if(this._hasFooter){ + return html` + + `; + } + } + +} +customElements.define('qui-card', QuiCard); \ No newline at end of file