Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dev UI - First version of build steps and build items pages #32270

Merged
merged 8 commits into from
Apr 4, 2023
Original file line number Diff line number Diff line change
Expand Up @@ -365,18 +365,15 @@ void createBuildTimeData(BuildProducer<BuildTimeConstBuildItem> buildTimeConstPr
.title("Build Steps")
phillip-kruger marked this conversation as resolved.
Show resolved Hide resolved
.icon("font-awesome-solid:hammer")
.componentLink("qwc-build-steps.js").build();
internalBuildTimeData.addBuildTimeData("buildSteps", "TODO: Build Steps");

Page buildItems = Page.webComponentPageBuilder().internal()
.namespace("devui-build-information")
.title("Build Items")
.icon("font-awesome-solid:trowel")
.componentLink("qwc-build-items.js").build();
internalBuildTimeData.addBuildTimeData("buildItems", "TODO: Build Items");

// Add default menu items
@SuppressWarnings("unchecked")
List<Page> sectionMenu = new ArrayList(
List<Page> sectionMenu = new ArrayList<>(
List.of(extensions, configuration, configurationSourceEditor, continuousTesting, devServices,
buildSteps, buildItems));

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package io.quarkus.devui.deployment.build;

import static io.quarkus.deployment.annotations.ExecutionTime.RUNTIME_INIT;

import io.quarkus.arc.deployment.AdditionalBeanBuildItem;
import io.quarkus.arc.processor.DotNames;
import io.quarkus.deployment.IsDevelopment;
import io.quarkus.deployment.annotations.BuildStep;
import io.quarkus.deployment.annotations.BuildSteps;
import io.quarkus.deployment.annotations.Record;
import io.quarkus.deployment.pkg.builditem.BuildSystemTargetBuildItem;
import io.quarkus.devui.runtime.build.BuildMetricsDevUIRecorder;
import io.quarkus.devui.runtime.build.BuildMetricsJsonRPCService;
import io.quarkus.devui.spi.JsonRPCProvidersBuildItem;

@BuildSteps(onlyIf = { IsDevelopment.class })
public class BuildMetricsDevUIProcessor {

@BuildStep
@Record(RUNTIME_INIT)
public void create(BuildMetricsDevUIRecorder recorder,
BuildSystemTargetBuildItem buildSystemTarget) {
recorder.setBuildMetricsPath(buildSystemTarget.getOutputDirectory().resolve("build-metrics.json").toString());
}

@BuildStep
AdditionalBeanBuildItem additionalBeans() {
return AdditionalBeanBuildItem
.builder()
.addBeanClass(BuildMetricsJsonRPCService.class)
.setUnremovable()
.setDefaultScope(DotNames.APPLICATION_SCOPED)
.build();
}

@BuildStep
JsonRPCProvidersBuildItem createJsonRPCService() {
return new JsonRPCProvidersBuildItem("build-metrics", BuildMetricsJsonRPCService.class);
phillip-kruger marked this conversation as resolved.
Show resolved Hide resolved
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import io.vertx.core.json.JsonArray;
import io.vertx.core.json.JsonObject;

@Deprecated(forRemoval = true)
public class BuildMetricsDevConsoleProcessor {

private static final Logger LOG = Logger.getLogger(BuildMetricsDevConsoleProcessor.class.getName());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
import io.quarkus.devconsole.runtime.spi.DevConsolePostHandler;
import io.quarkus.devconsole.spi.DevConsoleRouteBuildItem;
import io.quarkus.devconsole.spi.DevConsoleRuntimeTemplateInfoBuildItem;
import io.quarkus.devui.runtime.config.ConfigJsonRpcService;
import io.quarkus.devui.runtime.config.ConfigJsonRPCService;
import io.quarkus.devui.spi.JsonRPCProvidersBuildItem;
import io.quarkus.vertx.http.runtime.devmode.ConfigDescription;
import io.quarkus.vertx.http.runtime.devmode.ConfigDescriptionsManager;
Expand Down Expand Up @@ -161,7 +161,7 @@ JsonRPCProvidersBuildItem registerJsonRpcService() {
updateConfig(values);
return null;
});
return new JsonRPCProvidersBuildItem("configuration", ConfigJsonRpcService.class);
return new JsonRPCProvidersBuildItem("configuration", ConfigJsonRPCService.class);
}

private Map<String, String> filterAndApplyProfile(Map<String, String> autoconfig, List<String> configFilter,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ export class JsonRpc {

_extensionName;
_logTraffic;

/**
*
* @param {type} host the component using this.
Expand All @@ -96,7 +96,7 @@ export class JsonRpc {
* Again serviceIdentifier can allow multiple backends
* In the case of cards or logs, the namespace will be passed in as an attribute (as this component is not registered with the router)
* Again serviceIdentifier can allow multiple backends
* @param {type} logTraffic - if traffic should be logged in the Dev UI Log (json-prc log)
* @param {type} logTraffic - if traffic should be logged in the Dev UI Log (json-rpc log)
* @param {type} serviceIdentifier - if needed, a backend service identifier
* @returns {Proxy}
*/
Expand Down Expand Up @@ -205,7 +205,7 @@ export class JsonRpc {

_setExtensionName(discoveredNamespace, serviceIdentifier){
if(serviceIdentifier){
this._extensionName = discoveredNamespace + "-" + serviceIdentifier;
this._extensionName = serviceIdentifier;
phillip-kruger marked this conversation as resolved.
Show resolved Hide resolved
}else {
this._extensionName = discoveredNamespace;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,29 +1,113 @@
import { LitElement, html, css} from 'lit';
import { buildItems } from 'devui-data';
import { LitElement, html, css } from 'lit';

import { JsonRpc } from 'jsonrpc';
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';
import '@vaadin/icon';
import '@vaadin/text-field';
import '@vaadin/vertical-layout';
import '@vaadin/horizontal-layout';

/**
* This component shows the Build Items
*/
export class QwcBuildItems extends LitElement {

jsonRpc = new JsonRpc(this, true, 'build-metrics');
phillip-kruger marked this conversation as resolved.
Show resolved Hide resolved

static styles = css`
.todo {
padding-left: 10px;
height: 100%;
}`;
.build-items {
height: 100%;
display: flex;
flex-direction: column;
overflow: hidden;
}

vaadin-grid {
height: 100%;
}

vaadin-grid-cell-content {
vertical-align: top;
width: 100%;
}

.summary {
margin-bottom: 15px;
}`;

static properties = {
_items: {state: true}
_buildStepsMetrics: { state: true },
_filtered: {state: true, type: Array}
};

constructor() {
super();
this._items = buildItems;
this.jsonRpc.getBuildStepsMetrics().then(e => {
this._buildStepsMetrics = e.result;
this._filtered = this._buildStepsMetrics.items;
});
}

render() {
if(this._items){
return html`<div class="todo">${this._items}</div>`;
return html`${until(this._render(), html`<span>Loading build items...</span>`)}`;
}

_match(value, term) {
if (!value) {
return false;
}
return value.toLowerCase().includes(term.toLowerCase());
}

_filter(e) {
const searchTerm = (e.detail.value || '').trim();
if (searchTerm === '') {
this._filtered = this._buildStepsMetrics.items;
return;
}

this._filtered = this._buildStepsMetrics.items.filter((item) => {
return this._match(item.class, searchTerm);
});
}

_render() {
if (this._buildStepsMetrics && this._filtered) {
return html`<div class="build-items">
<div class="summary">Produced <strong>${this._buildStepsMetrics.itemsCount}</strong> build items.</div>
<vaadin-text-field
placeholder="Filter"
style="width: 100%;"
@value-changed="${(e) => this._filter(e)}">
<vaadin-icon slot="prefix" icon="font-awesome-solid:filter"></vaadin-icon>
</vaadin-text-field>
<vaadin-grid .items="${this._filtered}" style="width: 100%;" class="datatable" theme="row-stripes">
<vaadin-grid-sort-column auto-width resizable flex-grow="0"
header="Build item"
path="class"
class="cell"
${columnBodyRenderer(this._classRenderer, [])}>
</vaadin-grid-sort-column>

<vaadin-grid-sort-column auto-width resizable flex-grow="0"
header="Count"
path="count"
class="cell"
${columnBodyRenderer(this._countRenderer, [])}>
</vaadin-grid-sort-column>
</vaadin-grid></div>`;
}
}

_classRenderer(item) {
return html`<code>${item.class}</code>`;
}

_countRenderer(item) {
return html`${item.count}`;
}
}
customElements.define('qwc-build-items', QwcBuildItems);
Original file line number Diff line number Diff line change
@@ -1,29 +1,135 @@
import { LitElement, html, css} from 'lit';
import { buildSteps } from 'devui-data';
import { LitElement, html, css } from 'lit';

import { JsonRpc } from 'jsonrpc';
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';
import '@vaadin/icon';
import '@vaadin/text-field';
import '@vaadin/vertical-layout';
import '@vaadin/horizontal-layout';

/**
* This component shows the Build Steps
*/
export class QwcBuildSteps extends LitElement {

jsonRpc = new JsonRpc(this, true, 'build-metrics');
phillip-kruger marked this conversation as resolved.
Show resolved Hide resolved

static styles = css`
.todo {
padding-left: 10px;
height: 100%;
}`;
.build-steps {
height: 100%;
display: flex;
flex-direction: column;
overflow: hidden;
}

vaadin-grid {
height: 100%;
}

vaadin-grid-cell-content {
vertical-align: top;
width: 100%;
}

.summary {
margin-bottom: 15px;
}`;

static properties = {
_steps: {state: true}
_buildStepsMetrics: { state: true },
_filtered: {state: true, type: Array}
};

constructor() {
super();
this._steps = buildSteps;
this.jsonRpc.getBuildStepsMetrics().then(e => {
this._buildStepsMetrics = e.result;
this._filtered = this._buildStepsMetrics.records;
});
}

render() {
if(this._steps){
return html`<div class="todo">${this._steps}</div>`;
return html`${until(this._render(), html`<span>Loading build steps...</span>`)}`;
phillip-kruger marked this conversation as resolved.
Show resolved Hide resolved
}

_match(value, term) {
if (!value) {
return false;
}
return value.toLowerCase().includes(term.toLowerCase());
}

_filter(e) {
const searchTerm = (e.detail.value || '').trim();
if (searchTerm === '') {
this._filtered = this._buildStepsMetrics.records;
return;
}

this._filtered = this._buildStepsMetrics.records.filter((record) => {
return this._match(record.stepId, searchTerm);
});
}

_render() {
if (this._buildStepsMetrics && this._filtered) {
return html`<div class="build-steps">
<div class="summary">Executed <strong>${this._buildStepsMetrics.records.length}</strong> build steps on <strong>${Object.keys(this._buildStepsMetrics.threadSlotRecords).length}</strong> threads in <strong>${this._buildStepsMetrics.duration} ms</strong>.</div>
<vaadin-text-field
placeholder="Filter"
style="width: 100%;"
@value-changed="${(e) => this._filter(e)}">
<vaadin-icon slot="prefix" icon="font-awesome-solid:filter"></vaadin-icon>
</vaadin-text-field>
<vaadin-grid .items="${this._filtered}" style="width: 100%;" class="datatable" theme="row-stripes">
<vaadin-grid-sort-column auto-width resizable flex-grow="0"
header="Build step"
path="stepId"
class="cell"
${columnBodyRenderer(this._stepIdRenderer, [])}>
</vaadin-grid-sort-column>

<vaadin-grid-sort-column auto-width resizable flex-grow="0"
header="Started"
path="started"
class="cell"
${columnBodyRenderer(this._startedRenderer, [])}>
</vaadin-grid-sort-column>

<vaadin-grid-sort-column auto-width resizable flex-grow="0"
header="Duration (ms)"
path="duration"
class="cell"
${columnBodyRenderer(this._durationRenderer, [])}>
</vaadin-grid-sort-column>

<vaadin-grid-column auto-width resizable flex-grow="0"
header="Thread"
path="thread"
class="cell"
${columnBodyRenderer(this._threadRenderer, [])}>
</vaadin-grid-column>
</vaadin-grid></div>`;
}
}

_stepIdRenderer(record) {
return html`<code>${record.stepId}</code>`;
}

_startedRenderer(record) {
return html`${record.started}`;
}

_durationRenderer(record) {
return html`${record.duration}`;
}

_threadRenderer(record) {
return html`${record.thread}`;
}
}
customElements.define('qwc-build-steps', QwcBuildSteps);
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ export class QwcDevServices extends LitElement {
return html`${items}`;
} else {
return html`<p class="no-dev-services">
<span>You do not have any Dev Services running</span>
<span>You do not have any Dev Services running.</span>
<a href="https://quarkus.io/guides/dev-services" target="_blank">Read more about Dev Services</a>
</p>
`
Expand Down
Loading