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

Make trend charts configurable (with Bootstrap 5) #889

Merged
merged 34 commits into from
Jun 11, 2021
Merged
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
23dab9a
Migrate UI to Bootstrap 5.
uhafner Apr 19, 2021
0c6b0a7
Fix some other minor issues due to BS5 changes.
uhafner Apr 23, 2021
22fe52c
Bump UI dependencies to latest versions.
uhafner Apr 23, 2021
70f0485
Bump UI dependencies to latest versions.
uhafner Apr 23, 2021
9a363ed
Add configuration dialog for trend chart.
uhafner Apr 26, 2021
ef79493
Add NPM to dependabot and ignore some UI modules.
uhafner May 7, 2021
bfe2f88
Merge remote-tracking branch 'origin/master' into boostrap5
uhafner May 7, 2021
58f618a
Make tooltips compatible with BS5.
uhafner May 8, 2021
10d3c92
Enable configuration dialog for job trend charts.
uhafner May 11, 2021
fde4be8
Use new interface for configurable trend charts.
uhafner May 13, 2021
69270a4
Fix 2 new warnings.
uhafner May 13, 2021
469121c
Merge remote-tracking branch 'origin/master' into boostrap5
uhafner May 13, 2021
813a927
Use new trend setup dialog IDs.
uhafner May 16, 2021
7648aba
Use new echarts version.
uhafner May 17, 2021
7599500
Add a configuration of the build trend charts on the job view.
uhafner May 18, 2021
bcb1bfd
Bump version of echarts to 5.1.0-3-rc440.bf1a5b2177c1.
uhafner May 19, 2021
08dc2b3
Simplify JSON parsing of the `chartType` property.
uhafner May 20, 2021
0de0016
Kake parsing of configuration more robust.
uhafner May 21, 2021
590ead8
Bump version of ECharts to 5.1.0-3-rc443.de651a379c4a.
uhafner May 21, 2021
017575d
Refactor trend configuration:
uhafner May 31, 2021
5462ef4
Extract configuration of charts.
uhafner Jun 2, 2021
4c7e8b9
Extract configuration of charts.
uhafner Jun 2, 2021
d258e3c
Merge remote-tracking branch 'origin/master' into boostrap5
uhafner Jun 9, 2021
33fa53f
Remove unused global `trendDefaultStorageId`.
uhafner Jun 9, 2021
b0ac162
Fix Bootstrap 5 version.
uhafner Jun 9, 2021
1e83282
Bump version of echarts and datatables to latest.
uhafner Jun 9, 2021
195bf90
Simplify API of `LineChart`.
uhafner Jun 9, 2021
a7539f0
Use released versions of echarts and datatables.
uhafner Jun 9, 2021
668331f
Bump version of pull request monitoring to 1.7.2.
uhafner Jun 9, 2021
1777f80
Try to fix test failures.
uhafner Jun 9, 2021
4401bbb
Fix font-awesome version.
uhafner Jun 10, 2021
4f0e1d3
Bump version of Jenkins baseline to 2.263 to get all tests running.
uhafner Jun 10, 2021
4bb3269
Fix selection of tabs using the new BS5 attribute `data-bs-toggle`.
uhafner Jun 11, 2021
a50d54c
Fix some PMD warnings.
uhafner Jun 11, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ updates:
- dependency-name: org.webjars:popper.js
versions:
- ">= 2.0.0"
- dependency-name: org.webjars:bootstrap
versions:
- ">= 5.0.0"

- package-ecosystem: "github-actions"
directory: "/"
Expand Down
12 changes: 3 additions & 9 deletions plugin/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@
<plugin-util-api.version>2.2.0</plugin-util-api.version>

<data-tables-api.version>1.10.23-3</data-tables-api.version>
<echarts-api.version>5.1.0-2</echarts-api.version>
<font-awesome-api.version>5.15.3-2</font-awesome-api.version>
<echarts-api.version>5.1.0-3-rc464.d7d9d5650d0a</echarts-api.version>
<jquery3-api.version>3.6.0-1</jquery3-api.version>
<bootstrap4-api.version>4.6.0-3</bootstrap4-api.version>
<popper-api.version>1.16.1-2</popper-api.version>
Expand Down Expand Up @@ -109,11 +109,6 @@
<artifactId>script-security</artifactId>
<version>${script-security.version}</version>
</dependency>
<dependency>
<groupId>io.jenkins.plugins</groupId>
<artifactId>popper-api</artifactId>
<version>${popper-api.version}</version>
</dependency>
<dependency>
<groupId>com.google.errorprone</groupId>
<artifactId>error_prone_annotations</artifactId>
Expand Down Expand Up @@ -174,13 +169,12 @@
</dependency>
<dependency>
<groupId>io.jenkins.plugins</groupId>
<artifactId>bootstrap4-api</artifactId>
<version>${bootstrap4-api.version}</version>
<artifactId>bootstrap5-api</artifactId>
<version>${bootstrap5-api.version}</version>
</dependency>
<dependency>
<groupId>io.jenkins.plugins</groupId>
<artifactId>jquery3-api</artifactId>
<version>${jquery3-api.version}</version>
</dependency>
<dependency>
<groupId>io.jenkins.plugins</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,16 @@
import io.jenkins.plugins.analysis.core.charts.JenkinsBuild;
import io.jenkins.plugins.analysis.core.charts.ToolsTrendChart;
import io.jenkins.plugins.analysis.core.util.AnalysisBuildResult;
import io.jenkins.plugins.echarts.AsyncTrendChart;
import io.jenkins.plugins.echarts.AsyncConfigurableTrendChart;

/**
* Project action that renders a combined trend chart of all tools in the job.
*
* @author Ullrich Hafner
*/
public class AggregatedTrendAction implements Action, AsyncTrendChart {
public class AggregatedTrendAction implements Action, AsyncConfigurableTrendChart {
private static final int MIN_TOOLS = 2;
private static final String EMPTY = "{}";

private final Job<?, ?> owner;

Expand Down Expand Up @@ -75,19 +76,38 @@ private Set<AnalysisHistory> createBuildHistory() {
}
}

/**
* Returns the trend chart model that renders the aggregated build results.
*
* @return the trend chart
* @deprecated replaced {@link #getConfigurableBuildTrendModel(String)}
*/
@Deprecated
public String getBuildTrendModel() {
return getConfigurableBuildTrendModel(EMPTY);
}

/**
* Returns the trend chart model that renders the aggregated build results.
*
* @param configuration
* JSON configuration of the chart (number of builds, etc.)
*
* @return the trend chart
*/
@Override
@JavaScriptMethod
@SuppressWarnings("unused") // Called by jelly view
@Override
public String getBuildTrendModel() {
return new JacksonFacade().toJson(createChartModel());
public String getConfigurableBuildTrendModel(final String configuration) {
return new JacksonFacade().toJson(createChartModel(ChartModelConfiguration.fromJson(configuration)));
}

private LinesChartModel createChartModel() {
private LinesChartModel createChartModel(final ChartModelConfiguration configuration) {
Run<?, ?> lastBuild = owner.getLastBuild();
if (lastBuild == null) {
return new LinesChartModel();
}
return new ToolsTrendChart().create(new CompositeBuildResultsIterable(lastBuild), new ChartModelConfiguration());
return new ToolsTrendChart().create(new CompositeBuildResultsIterable(lastBuild), configuration);
}

@Override
Expand Down Expand Up @@ -115,7 +135,8 @@ private static class CompositeBuildResultsIterable implements Iterable<BuildResu
this.lastBuild = lastBuild;
}

@Override @NonNull
@Override
@NonNull
public Iterator<BuildResult<AnalysisBuildResult>> iterator() {
return new CompositeIterator(lastBuild);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,8 @@ public DomContent createAffectedFileLink(final Issue issue, final String prefix)
else if (facade.canAccessAffectedFileOf(build, issue)) {
return a().withHref(prefix + getSourceCodeUrl(issue))
.withText(getFileNameAtLine(issue))
.attr("data-toggle", "tooltip")
.attr("data-placement", "bottom")
.attr("data-bs-toggle", "tooltip")
.attr("data-bs-placement", "left")
.withTitle(issue.getFileName());
}
else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
import edu.hm.hafner.analysis.Report;
import edu.hm.hafner.analysis.Severity;
import edu.hm.hafner.echarts.ChartModelConfiguration;
import edu.hm.hafner.echarts.ChartModelConfiguration.AxisType;
import edu.hm.hafner.echarts.JacksonFacade;

import org.kohsuke.stapler.StaplerRequest;
Expand Down Expand Up @@ -48,10 +47,11 @@
*
* @author Ullrich Hafner
*/
@SuppressWarnings({"PMD.ExcessiveImports", "ClassDataAbstractionCoupling", "ClassFanOutComplexity"})
@SuppressWarnings({"PMD.ExcessiveImports", "PMD.GodClass", "ClassDataAbstractionCoupling", "ClassFanOutComplexity"})
public class IssuesDetail extends DefaultAsyncTableContentProvider implements ModelObject {
private static final ResetQualityGateCommand RESET_QUALITY_GATE_COMMAND = new ResetQualityGateCommand();
private static final JacksonFacade JACKSON_FACADE = new JacksonFacade();
private static final String DEFAULT_CONFIGURATION = "{}";

private final Run<?, ?> owner;

Expand Down Expand Up @@ -299,15 +299,25 @@ public String getTrendModel() {
* determines whether the Jenkins build number should be used on the X-axis or the date
*
* @return the UI model as JSON
* @deprecated replaced by {@link #getBuildTrend(String)}
*/
@JavaScriptMethod
@SuppressWarnings("unused") // Called by jelly view
@Deprecated @SuppressWarnings("unused")
public String getBuildTrend(final boolean isBuildOnXAxis) {
return createTrendAsJson(new SeverityTrendChart(), isBuildOnXAxis);
return createTrendAsJson(new SeverityTrendChart(), DEFAULT_CONFIGURATION);
}

private ChartModelConfiguration createChartConfiguration(final boolean isBuildOnXAxis) {
return new ChartModelConfiguration(isBuildOnXAxis ? AxisType.BUILD : AxisType.DATE);
/**
* Returns the UI model for an ECharts line chart that shows the issues stacked by severity.
*
* @param configuration
* determines whether the Jenkins build number should be used on the X-axis or the date
*
* @return the UI model as JSON
*/
@JavaScriptMethod
@SuppressWarnings("unused") // Called by jelly view
public String getBuildTrend(final String configuration) {
return createTrendAsJson(new SeverityTrendChart(), configuration);
}

/**
Expand All @@ -317,11 +327,25 @@ private ChartModelConfiguration createChartConfiguration(final boolean isBuildOn
* determines whether the Jenkins build number should be used on the X-axis or the date
*
* @return the UI model as JSON
* @deprecated replaced by {@link #getToolsTrend(String)}
*/
@Deprecated @SuppressWarnings("unused")
public String getToolsTrend(final boolean isBuildOnXAxis) {
return createTrendAsJson(new ToolsTrendChart(), DEFAULT_CONFIGURATION);
}

/**
* Returns the UI model for an ECharts line chart that shows the issues by tool.
*
* @param configuration
* determines whether the Jenkins build number should be used on the X-axis or the date
*
* @return the UI model as JSON
*/
@JavaScriptMethod
@SuppressWarnings("unused") // Called by jelly view
public String getToolsTrend(final boolean isBuildOnXAxis) {
return createTrendAsJson(new ToolsTrendChart(), isBuildOnXAxis);
public String getToolsTrend(final String configuration) {
return createTrendAsJson(new ToolsTrendChart(), configuration);
}

/**
Expand All @@ -331,11 +355,25 @@ public String getToolsTrend(final boolean isBuildOnXAxis) {
* determines whether the Jenkins build number should be used on the X-axis or the date
*
* @return the UI model as JSON
* @deprecated replaced by {@link #getNewVersusFixedTrend(String)}
*/
@Deprecated @SuppressWarnings("unused")
public String getNewVersusFixedTrend(final boolean isBuildOnXAxis) {
return createTrendAsJson(new NewVersusFixedTrendChart(), DEFAULT_CONFIGURATION);
}

/**
* Returns the UI model for an ECharts line chart that shows the new and fixed issues.
*
* @param configuration
* determines whether the Jenkins build number should be used on the X-axis or the date
*
* @return the UI model as JSON
*/
@JavaScriptMethod
@SuppressWarnings("unused") // Called by jelly view
public String getNewVersusFixedTrend(final boolean isBuildOnXAxis) {
return createTrendAsJson(new NewVersusFixedTrendChart(), isBuildOnXAxis);
public String getNewVersusFixedTrend(final String configuration) {
return createTrendAsJson(new NewVersusFixedTrendChart(), configuration);
}

/**
Expand All @@ -345,11 +383,25 @@ public String getNewVersusFixedTrend(final boolean isBuildOnXAxis) {
* determines whether the Jenkins build number should be used on the X-axis or the date
*
* @return the UI model as JSON
* @deprecated replaced by {@link #getHealthTrend(String)}
*/
@Deprecated @SuppressWarnings("unused")
public String getHealthTrend(final boolean isBuildOnXAxis) {
return createTrendAsJson(new HealthTrendChart(healthDescriptor), DEFAULT_CONFIGURATION);
}

/**
* Returns the UI model for an ECharts line chart that shows the issues by tool.
*
* @param configuration
* determines whether the Jenkins build number should be used on the X-axis or the date
*
* @return the UI model as JSON
*/
@JavaScriptMethod
@SuppressWarnings("unused") // Called by jelly view
public String getHealthTrend(final boolean isBuildOnXAxis) {
return createTrendAsJson(new HealthTrendChart(healthDescriptor), isBuildOnXAxis);
public String getHealthTrend(final String configuration) {
return createTrendAsJson(new HealthTrendChart(healthDescriptor), configuration);
}

/**
Expand All @@ -362,10 +414,10 @@ public boolean isHealthReportEnabled() {
return healthDescriptor.isEnabled();
}

private String createTrendAsJson(final TrendChart trendChart, final boolean isBuildOnXAxis) {
private String createTrendAsJson(final TrendChart trendChart, final String configuration) {
History history = new AnalysisHistory(owner, new ByIdResultSelector(result.getId()));

return new JacksonFacade().toJson(trendChart.create(history, createChartConfiguration(isBuildOnXAxis)));
return new JacksonFacade().toJson(trendChart.create(history, ChartModelConfiguration.fromJson(configuration)));
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import edu.hm.hafner.echarts.BuildResult;
import edu.hm.hafner.echarts.ChartModelConfiguration;
import edu.hm.hafner.echarts.JacksonFacade;
import edu.hm.hafner.echarts.LinesChartModel;
import edu.umd.cs.findbugs.annotations.CheckForNull;

import org.kohsuke.stapler.StaplerRequest;
Expand All @@ -17,19 +16,23 @@
import hudson.model.Run;
import jenkins.model.Jenkins;

import io.jenkins.plugins.analysis.core.charts.HealthTrendChart;
import io.jenkins.plugins.analysis.core.charts.NewVersusFixedTrendChart;
import io.jenkins.plugins.analysis.core.charts.SeverityTrendChart;
import io.jenkins.plugins.analysis.core.charts.ToolsTrendChart;
import io.jenkins.plugins.analysis.core.charts.TrendChart;
import io.jenkins.plugins.analysis.core.util.AnalysisBuildResult;
import io.jenkins.plugins.analysis.core.util.TrendChartType;
import io.jenkins.plugins.echarts.AsyncTrendChart;
import io.jenkins.plugins.echarts.AsyncConfigurableTrendChart;

/**
* A job action displays a link on the side panel of a job. This action also is responsible to render the historical
* trend via its associated 'floatingBox.jelly' view.
* trend via its associated 'charts.jelly' view.
*
* @author Ullrich Hafner
*/
public class JobAction implements Action, AsyncTrendChart {
public class JobAction implements Action, AsyncConfigurableTrendChart {
private static final JacksonFacade JACKSON_FACADE = new JacksonFacade();
private final Job<?, ?> owner;
private final StaticAnalysisLabelProvider labelProvider;
private final int numberOfTools;
Expand All @@ -42,6 +45,7 @@ public class JobAction implements Action, AsyncTrendChart {
* the job that owns this action
* @param labelProvider
* the label provider
*
* @deprecated use {@link #JobAction(Job, StaticAnalysisLabelProvider, int)}
*/
@Deprecated
Expand Down Expand Up @@ -178,18 +182,50 @@ public Optional<ResultAction> getLatestAction() {
return createBuildHistory().getBaselineAction();
}

@JavaScriptMethod
@Override
/**
* Returns the trend chart model that renders the aggregated build results.
*
* @return the trend chart
* @deprecated replaced {@link #getConfigurableBuildTrendModel(String)}
*/
@Deprecated
public String getBuildTrendModel() {
return new JacksonFacade().toJson(createChartModel());
return getConfigurableBuildTrendModel("{}");
}

/**
* Returns the trend chart model that renders the build results for a specific action.
*
* @param configuration
* JSON configuration of the chart (number of builds, etc.)
*
* @return the trend chart
*/
@Override
@JavaScriptMethod
@SuppressWarnings("unused") // Called by jelly view
public String getConfigurableBuildTrendModel(final String configuration) {
String chartType = JACKSON_FACADE.getString(configuration, "chartType", "severity");

return new JacksonFacade().toJson(selectChart(chartType).create(
createBuildHistory(), ChartModelConfiguration.fromJson(configuration)));
}

private LinesChartModel createChartModel() {
private TrendChart selectChart(final String chartType) {
if ("new".equals(chartType)) {
return new NewVersusFixedTrendChart();
}
if ("health".equals(chartType)) {
Optional<ResultAction> latestAction = getLatestAction();
if (latestAction.isPresent()) {
return new HealthTrendChart(latestAction.get().getHealthDescriptor());
}
}
if (numberOfTools > 1) {
return new ToolsTrendChart().create(createBuildHistory(), new ChartModelConfiguration());
return new ToolsTrendChart();
}
else {
return new SeverityTrendChart().create(createBuildHistory(), new ChartModelConfiguration());
return new SeverityTrendChart();
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,10 @@ public HealthReport getBuildHealth() {
getResult().getSizePerSeverity());
}

HealthDescriptor getHealthDescriptor() {
return healthDescriptor;
}

@Override
public Collection<? extends Action> getProjectActions() {
return Collections.singleton(
Expand Down
Loading