Skip to content

Commit 064b1d2

Browse files
authored
Merge pull request #633 from melloware/devui-card
Fix #627: Dev UI Card
2 parents c113a3a + e7fa51f commit 064b1d2

File tree

12 files changed

+257
-89
lines changed

12 files changed

+257
-89
lines changed

deployment/pom.xml

Lines changed: 14 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,25 @@
4848
<groupId>io.quarkus</groupId>
4949
<artifactId>quarkus-smallrye-jwt-build-deployment</artifactId>
5050
</dependency>
51+
<dependency>
52+
<groupId>io.quarkus</groupId>
53+
<artifactId>quarkus-vertx-http-deployment</artifactId>
54+
</dependency>
55+
<dependency>
56+
<groupId>io.quarkus</groupId>
57+
<artifactId>quarkus-vertx-http-dev-ui-spi</artifactId>
58+
<optional>true</optional>
59+
</dependency>
5160
<dependency>
5261
<groupId>io.quarkiverse.githubapp</groupId>
5362
<artifactId>quarkus-github-app</artifactId>
5463
<version>${project.version}</version>
5564
</dependency>
65+
<dependency>
66+
<groupId>io.quarkiverse.githubapp</groupId>
67+
<artifactId>quarkus-github-app-ui</artifactId>
68+
<version>${project.version}</version>
69+
</dependency>
5670
<dependency>
5771
<groupId>io.quarkus</groupId>
5872
<artifactId>quarkus-junit5-internal</artifactId>
@@ -90,87 +104,6 @@
90104
</annotationProcessorPaths>
91105
</configuration>
92106
</plugin>
93-
<plugin>
94-
<groupId>org.apache.maven.plugins</groupId>
95-
<artifactId>maven-dependency-plugin</artifactId>
96-
<executions>
97-
<execution>
98-
<id>install-ui</id>
99-
<phase>generate-sources</phase>
100-
<goals>
101-
<goal>unpack</goal>
102-
</goals>
103-
<configuration>
104-
<artifactItems>
105-
<!-- Fomantic UI -->
106-
<artifactItem>
107-
<groupId>org.webjars.npm</groupId>
108-
<artifactId>fomantic-ui-css</artifactId>
109-
<version>${webjar.fomantic-ui.version}</version>
110-
<type>jar</type>
111-
<overWrite>true</overWrite>
112-
<outputDirectory>${project.build.directory}/classes/META-INF/resources/replay-ui/css/</outputDirectory>
113-
<includes>META-INF/resources/webjars/fomantic-ui-css/${webjar.fomantic-ui.version}/semantic.min.css,META-INF/resources/webjars/fomantic-ui-css/${webjar.fomantic-ui.version}/themes/default/**</includes>
114-
<fileMappers>
115-
<org.codehaus.plexus.components.io.filemappers.RegExpFileMapper>
116-
<pattern>^META-INF/resources/webjars/fomantic-ui-css/${webjar.fomantic-ui.version}/</pattern>
117-
<replacement>./</replacement>
118-
</org.codehaus.plexus.components.io.filemappers.RegExpFileMapper>
119-
</fileMappers>
120-
</artifactItem>
121-
<artifactItem>
122-
<groupId>org.webjars.npm</groupId>
123-
<artifactId>fomantic-ui-css</artifactId>
124-
<version>${webjar.fomantic-ui.version}</version>
125-
<type>jar</type>
126-
<overWrite>true</overWrite>
127-
<outputDirectory>${project.build.directory}/classes/META-INF/resources/replay-ui/js/</outputDirectory>
128-
<includes>META-INF/resources/webjars/fomantic-ui-css/${webjar.fomantic-ui.version}/semantic.min.js</includes>
129-
<fileMappers>
130-
<org.codehaus.plexus.components.io.filemappers.RegExpFileMapper>
131-
<pattern>^META-INF/resources/webjars/fomantic-ui-css/${webjar.fomantic-ui.version}/</pattern>
132-
<replacement>./</replacement>
133-
</org.codehaus.plexus.components.io.filemappers.RegExpFileMapper>
134-
</fileMappers>
135-
</artifactItem>
136-
<!-- Vue.js -->
137-
<artifactItem>
138-
<groupId>org.webjars.npm</groupId>
139-
<artifactId>vue</artifactId>
140-
<version>${webjar.vue.version}</version>
141-
<type>jar</type>
142-
<overWrite>true</overWrite>
143-
<outputDirectory>${project.build.directory}/classes/META-INF/resources/replay-ui/js/</outputDirectory>
144-
<includes>META-INF/resources/webjars/vue/${webjar.vue.version}/dist/vue.min.js</includes>
145-
<fileMappers>
146-
<org.codehaus.plexus.components.io.filemappers.RegExpFileMapper>
147-
<pattern>^META-INF/resources/webjars/vue/${webjar.vue.version}/dist/</pattern>
148-
<replacement>./</replacement>
149-
</org.codehaus.plexus.components.io.filemappers.RegExpFileMapper>
150-
</fileMappers>
151-
</artifactItem>
152-
<!-- jQuery -->
153-
<artifactItem>
154-
<groupId>org.webjars.npm</groupId>
155-
<artifactId>jquery</artifactId>
156-
<version>${webjar.jquery.version}</version>
157-
<type>jar</type>
158-
<overWrite>true</overWrite>
159-
<outputDirectory>${project.build.directory}/classes/META-INF/resources/replay-ui/js/</outputDirectory>
160-
<includes>META-INF/resources/webjars/jquery/${webjar.jquery.version}/dist/jquery.min.js</includes>
161-
<fileMappers>
162-
<org.codehaus.plexus.components.io.filemappers.RegExpFileMapper>
163-
<pattern>^META-INF/resources/webjars/jquery/${webjar.jquery.version}/dist/</pattern>
164-
<replacement>./</replacement>
165-
</org.codehaus.plexus.components.io.filemappers.RegExpFileMapper>
166-
</fileMappers>
167-
</artifactItem>
168-
<!-- favico.js is a version coming from the master branch of https://github.com/ejci/favico.js/ -->
169-
</artifactItems>
170-
</configuration>
171-
</execution>
172-
</executions>
173-
</plugin>
174107
</plugins>
175108
</build>
176109

deployment/src/main/java/io/quarkiverse/githubapp/deployment/GitHubAppProcessor.java

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,6 @@
123123
import io.quarkus.runtime.util.HashUtil;
124124
import io.quarkus.vertx.http.deployment.HttpRootPathBuildItem;
125125
import io.quarkus.vertx.http.deployment.RouteBuildItem;
126-
import io.quarkus.vertx.http.deployment.devmode.NotFoundPageDisplayableEndpointBuildItem;
127126
import io.quarkus.vertx.http.deployment.webjar.WebJarBuildItem;
128127
import io.quarkus.vertx.http.deployment.webjar.WebJarResultsBuildItem;
129128
import io.smallrye.graphql.client.dynamic.api.DynamicGraphQLClient;
@@ -153,9 +152,9 @@ class GitHubAppProcessor {
153152
.createSimple("com.infradna.tool.bridge_method_injector.WithBridgeMethods");
154153

155154
private static final GACT QUARKIVERSE_GITHUB_APP_GACT = new GACT("io.quarkiverse.githubapp",
156-
"quarkus-github-app-deployment", null, "jar");
155+
"quarkus-github-app-ui", null, "jar");
157156
private static final String REPLAY_UI_RESOURCES_PREFIX = "META-INF/resources/replay-ui/";
158-
private static final String REPLAY_UI_PATH = "/replay";
157+
private static final String REPLAY_UI_PATH = "replay";
159158

160159
@BuildStep
161160
FeatureBuildItem feature() {
@@ -328,8 +327,7 @@ void replayUi(GitHubAppRecorder recorder,
328327
WebJarResultsBuildItem webJarResults,
329328
HttpRootPathBuildItem httpRootPath,
330329
ShutdownContextBuildItem shutdownContext,
331-
BuildProducer<RouteBuildItem> routes,
332-
BuildProducer<NotFoundPageDisplayableEndpointBuildItem> displayableEndpoints) throws IOException {
330+
BuildProducer<RouteBuildItem> routes) throws IOException {
333331
if (launchMode.getLaunchMode() != LaunchMode.DEVELOPMENT) {
334332
return;
335333
}
@@ -339,12 +337,17 @@ void replayUi(GitHubAppRecorder recorder,
339337
return;
340338
}
341339

342-
Handler<RoutingContext> handler = recorder.replayUiHandler(webJarResult.getFinalDestination(), REPLAY_UI_PATH,
340+
String replayUiPath = httpRootPath.resolvePath(REPLAY_UI_PATH);
341+
342+
Handler<RoutingContext> handler = recorder.replayUiHandler(webJarResult.getFinalDestination(), replayUiPath,
343343
webJarResult.getWebRootConfigurations(), shutdownContext);
344-
routes.produce(httpRootPath.routeBuilder().route(REPLAY_UI_PATH).handler(handler).build());
344+
routes.produce(httpRootPath.routeBuilder()
345+
.route(REPLAY_UI_PATH)
346+
.handler(handler)
347+
.displayOnNotFoundPage("Replay UI")
348+
.build());
345349
routes.produce(httpRootPath.routeBuilder().route(REPLAY_UI_PATH + "/*").handler(handler).build());
346350

347-
displayableEndpoints.produce(new NotFoundPageDisplayableEndpointBuildItem(REPLAY_UI_PATH + "/", "Replay UI"));
348351
}
349352

350353
private static Collection<EventDefinition> getAllEventDefinitions(IndexView index) {
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package io.quarkiverse.githubapp.deployment.devui;
2+
3+
import io.quarkus.deployment.IsDevelopment;
4+
import io.quarkus.deployment.annotations.BuildProducer;
5+
import io.quarkus.deployment.annotations.BuildStep;
6+
import io.quarkus.deployment.builditem.LaunchModeBuildItem;
7+
import io.quarkus.devui.spi.page.CardPageBuildItem;
8+
import io.quarkus.devui.spi.page.ExternalPageBuilder;
9+
import io.quarkus.devui.spi.page.Page;
10+
import io.quarkus.vertx.http.deployment.HttpRootPathBuildItem;
11+
import io.quarkus.vertx.http.runtime.management.ManagementInterfaceBuildTimeConfig;
12+
13+
/**
14+
* Dev UI card for displaying important details such as the GitHub App Replay UI.
15+
*/
16+
public class GitHubAppDevUIProcessor {
17+
18+
@BuildStep(onlyIf = IsDevelopment.class)
19+
void createDevCard(BuildProducer<CardPageBuildItem> cardPageBuildItemBuildProducer,
20+
HttpRootPathBuildItem httpRootPathBuildItem,
21+
ManagementInterfaceBuildTimeConfig managementInterfaceBuildTimeConfig,
22+
LaunchModeBuildItem launchModeBuildItem) {
23+
final CardPageBuildItem card = new CardPageBuildItem();
24+
25+
String uiPath = httpRootPathBuildItem.resolvePath("replay");
26+
27+
final ExternalPageBuilder versionPage = Page.externalPageBuilder("Replay UI")
28+
.icon("font-awesome-solid:play")
29+
.url(uiPath, uiPath)
30+
.doNotEmbed();
31+
card.addPage(versionPage);
32+
33+
card.setCustomCard("qwc-github-app-card.js");
34+
35+
cardPageBuildItemBuildProducer.produce(card);
36+
}
37+
}
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
import { LitElement, html, css} from 'lit';
2+
import { pages } from 'build-time-data';
3+
import 'qwc/qwc-extension-link.js';
4+
5+
export class QwcGitHubAppCard extends LitElement {
6+
7+
static styles = css`
8+
.identity {
9+
display: flex;
10+
justify-content: flex-start;
11+
}
12+
13+
.description {
14+
padding-bottom: 10px;
15+
}
16+
17+
.logo {
18+
padding-bottom: 10px;
19+
margin-right: 5px;
20+
}
21+
22+
.card-content {
23+
color: var(--lumo-contrast-90pct);
24+
display: flex;
25+
flex-direction: column;
26+
justify-content: flex-start;
27+
padding: 2px 2px;
28+
height: 100%;
29+
}
30+
31+
.card-content slot {
32+
display: flex;
33+
flex-flow: column wrap;
34+
padding-top: 5px;
35+
}
36+
`;
37+
38+
static properties = {
39+
extensionName: {attribute: true},
40+
description: {attribute: true},
41+
guide: {attribute: true},
42+
namespace: {attribute: true},
43+
};
44+
45+
46+
constructor() {
47+
super();
48+
}
49+
50+
connectedCallback() {
51+
super.connectedCallback();
52+
}
53+
54+
render() {
55+
return html`<div class="card-content" slot="content">
56+
<div class="identity">
57+
<div class="logo">
58+
<img src="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iOTgiIGhlaWdodD0iOTYiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik00OC44NTQgMEMyMS44MzkgMCAwIDIyIDAgNDkuMjE3YzAgMjEuNzU2IDEzLjk5MyA0MC4xNzIgMzMuNDA1IDQ2LjY5IDIuNDI3LjQ5IDMuMzE2LTEuMDU5IDMuMzE2LTIuMzYyIDAtMS4xNDEtLjA4LTUuMDUyLS4wOC05LjEyNy0xMy41OSAyLjkzNC0xNi40Mi01Ljg2Ny0xNi40Mi01Ljg2Ny0yLjE4NC01LjcwNC01LjQyLTcuMTctNS40Mi03LjE3LTQuNDQ4LTMuMDE1LjMyNC0zLjAxNS4zMjQtMy4wMTUgNC45MzQuMzI2IDcuNTIzIDUuMDUyIDcuNTIzIDUuMDUyIDQuMzY3IDcuNDk2IDExLjQwNCA1LjM3OCAxNC4yMzUgNC4wNzQuNDA0LTMuMTc4IDEuNjk5LTUuMzc4IDMuMDc0LTYuNi0xMC44MzktMS4xNDEtMjIuMjQzLTUuMzc4LTIyLjI0My0yNC4yODMgMC01LjM3OCAxLjk0LTkuNzc4IDUuMDE0LTEzLjItLjQ4NS0xLjIyMi0yLjE4NC02LjI3NS40ODYtMTMuMDM4IDAgMCA0LjEyNS0xLjMwNCAxMy40MjYgNS4wNTJhNDYuOTcgNDYuOTcgMCAwIDEgMTIuMjE0LTEuNjNjNC4xMjUgMCA4LjMzLjU3MSAxMi4yMTMgMS42MyA5LjMwMi02LjM1NiAxMy40MjctNS4wNTIgMTMuNDI3LTUuMDUyIDIuNjcgNi43NjMuOTcgMTEuODE2LjQ4NSAxMy4wMzggMy4xNTUgMy40MjIgNS4wMTUgNy44MjIgNS4wMTUgMTMuMiAwIDE4LjkwNS0xMS40MDQgMjMuMDYtMjIuMzI0IDI0LjI4MyAxLjc4IDEuNTQ4IDMuMzE2IDQuNDgxIDMuMzE2IDkuMTI2IDAgNi42LS4wOCAxMS44OTctLjA4IDEzLjUyNiAwIDEuMzA0Ljg5IDIuODUzIDMuMzE2IDIuMzY0IDE5LjQxMi02LjUyIDMzLjQwNS0yNC45MzUgMzMuNDA1LTQ2LjY5MUM5Ny43MDcgMjIgNzUuNzg4IDAgNDguODU0IDB6IiBmaWxsPSIjZmZmIi8+PC9zdmc+"
59+
alt="${this.extensionName}"
60+
title="${this.extensionName}"
61+
width="32"
62+
height="32">
63+
</div>
64+
<div class="description">${this.description}</div>
65+
</div>
66+
${this._renderCardLinks()}
67+
</div>
68+
`;
69+
}
70+
71+
_renderCardLinks(){
72+
return html`${pages.map(page => html`
73+
<qwc-extension-link slot="link"
74+
namespace="${this.namespace}"
75+
extensionName="${this.extensionName}"
76+
iconName="${page.icon}"
77+
displayName="${page.title}"
78+
staticLabel="${page.staticLabel}"
79+
dynamicLabel="${page.dynamicLabel}"
80+
streamingLabel="${page.streamingLabel}"
81+
path="${page.id}"
82+
?embed=${page.embed}
83+
externalUrl="${page.metadata.externalUrl}"
84+
webcomponent="${page.componentLink}" >
85+
</qwc-extension-link>
86+
`)}`;
87+
}
88+
89+
}
90+
customElements.define('qwc-github-app-card', QwcGitHubAppCard);

pom.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939

4040
<modules>
4141
<module>events</module>
42+
<module>ui</module>
4243
<module>deployment</module>
4344
<module>runtime</module>
4445
<module>command-airline</module>

runtime/pom.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,10 @@
5454
<groupId>io.quarkus</groupId>
5555
<artifactId>quarkus-smallrye-jwt-build</artifactId>
5656
</dependency>
57+
<dependency>
58+
<groupId>io.quarkus</groupId>
59+
<artifactId>quarkus-vertx-http</artifactId>
60+
</dependency>
5761
<dependency>
5862
<groupId>com.fasterxml.jackson.dataformat</groupId>
5963
<artifactId>jackson-dataformat-yaml</artifactId>

0 commit comments

Comments
 (0)