From 599b75bce8373c77c12d0ec8b01a55627c4a472c Mon Sep 17 00:00:00 2001 From: Ulli Hafner Date: Fri, 20 May 2022 17:25:30 +0200 Subject: [PATCH 01/32] Improve the layout and design of the coverage columns. --- .../coverage/model/CoverageViewModel.java | 16 +++++------ .../dashboard/CoverageColumn/column.jelly | 27 ++++++++++--------- plugin/src/main/webapp/css/column-style.css | 9 +++++++ plugin/src/main/webapp/css/custom-style.css | 16 +++++++++++ 4 files changed, 48 insertions(+), 20 deletions(-) create mode 100644 plugin/src/main/webapp/css/column-style.css diff --git a/plugin/src/main/java/io/jenkins/plugins/coverage/model/CoverageViewModel.java b/plugin/src/main/java/io/jenkins/plugins/coverage/model/CoverageViewModel.java index 1012f4217..764ec4ca7 100644 --- a/plugin/src/main/java/io/jenkins/plugins/coverage/model/CoverageViewModel.java +++ b/plugin/src/main/java/io/jenkins/plugins/coverage/model/CoverageViewModel.java @@ -582,13 +582,13 @@ protected DetailedColumnDefinition createColoredCoverageColumn(final CoveragePer double percentage = coverage.getDoubleValue(); String sort = String.valueOf(percentage); DisplayColors colors = CoverageLevel.getDisplayColorsOfCoverageLevel(percentage, COLOR_PROVIDER); - String tag = span() - .withTitle(tooltip) - .withStyle(String.format( - "color:%s; background-image: linear-gradient(90deg, %s %f%%, transparent %f%%); display:block;", + String tag = div().withClasses("coverage-column-outer").with( + div().withClasses("coverage-column-inner") + .withStyle(String.format("color:%s; background-image: linear-gradient(90deg, %s %f%%, transparent %f%%);", colors.getLineColorAsHex(), colors.getFillColorAsHex(), percentage, percentage)) - .withText(text) + .withTitle(tooltip) + .withText(text)) .render(); return new DetailedColumnDefinition(tag, sort); } @@ -610,12 +610,12 @@ protected DetailedColumnDefinition createColoredCoverageDeltaColumn( String sort = String.valueOf(coverageValue); DisplayColors colors = CoverageChangeTendency .getDisplayColorsForTendency(coverageValue, COLOR_PROVIDER); - String tag = span() - .withClasses("badge", "badge-delta") + String tag = div().withClasses("coverage-column-outer").with( + div().withClasses("coverage-column-inner") .withStyle(String.format("color:%s;background-color:%s;", colors.getLineColorAsHex(), colors.getFillColorAsHex())) .withText(coverageText) - .withTitle(tooltip) + .withTitle(tooltip)) .render(); return new DetailedColumnDefinition(tag, sort); } diff --git a/plugin/src/main/resources/io/jenkins/plugins/coverage/model/visualization/dashboard/CoverageColumn/column.jelly b/plugin/src/main/resources/io/jenkins/plugins/coverage/model/visualization/dashboard/CoverageColumn/column.jelly index 8f63fee0f..a75d7831d 100644 --- a/plugin/src/main/resources/io/jenkins/plugins/coverage/model/visualization/dashboard/CoverageColumn/column.jelly +++ b/plugin/src/main/resources/io/jenkins/plugins/coverage/model/visualization/dashboard/CoverageColumn/column.jelly @@ -1,27 +1,30 @@ + + - - - - - ${coverageText} - - - ${coverageText} - - + +
+
+ + + ${coverageText} + + + ${coverageText} + + +
+
diff --git a/plugin/src/main/webapp/css/column-style.css b/plugin/src/main/webapp/css/column-style.css new file mode 100644 index 000000000..dd3bb8e44 --- /dev/null +++ b/plugin/src/main/webapp/css/column-style.css @@ -0,0 +1,9 @@ +.coverage-column-inner { + padding: 4px 7px; + border-radius: 10px +} + +.coverage-column-outer { + border: 1px solid var(--light-bg-color); + border-radius: 10px +} diff --git a/plugin/src/main/webapp/css/custom-style.css b/plugin/src/main/webapp/css/custom-style.css index 7ad5c734a..856234ae9 100644 --- a/plugin/src/main/webapp/css/custom-style.css +++ b/plugin/src/main/webapp/css/custom-style.css @@ -56,9 +56,25 @@ border-color: #b4b4b4; background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='white'/%3e%3c/svg%3e"); } + .form-switch .form-check-input:focus { box-shadow: none; background-color: #b4b4b4; border-color: #b4b4b4; background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='white'/%3e%3c/svg%3e"); } + +.coverage-column-outer { + border: 1px solid var(--light-bg-color); + border-radius: 10px; +} + +.coverage-column-inner { + padding: 1px 7px; + border-radius: 10px; + color:black +} + +#coverage-table td { + vertical-align: middle; +} From adfcb8a956202509aaa1974391840c30edac384f Mon Sep 17 00:00:00 2001 From: Ulli Hafner Date: Fri, 20 May 2022 22:53:42 +0200 Subject: [PATCH 02/32] Right align number cells. --- .../plugins/coverage/model/CoverageViewModel.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/plugin/src/main/java/io/jenkins/plugins/coverage/model/CoverageViewModel.java b/plugin/src/main/java/io/jenkins/plugins/coverage/model/CoverageViewModel.java index 764ec4ca7..486d597e5 100644 --- a/plugin/src/main/java/io/jenkins/plugins/coverage/model/CoverageViewModel.java +++ b/plugin/src/main/java/io/jenkins/plugins/coverage/model/CoverageViewModel.java @@ -470,23 +470,23 @@ public List getColumns() { // fileColumn.setWidth(2); columns.add(fileColumn); - TableColumn lineColumn = new TableColumn("Line", "lineCoverage", "number"); + TableColumn lineColumn = new TableColumn("Line", "lineCoverage", "number").setHeaderClass(ColumnCss.NUMBER); // lineColumn.setWidth(2); columns.add(lineColumn); - TableColumn lineColumnDelta = new TableColumn("Line Δ", "lineCoverageDelta", "number"); + TableColumn lineColumnDelta = new TableColumn("Line Δ", "lineCoverageDelta", "number").setHeaderClass(ColumnCss.NUMBER); // lineColumnDelta.setWidth(1); columns.add(lineColumnDelta); - TableColumn branchColumn = new TableColumn("Branch", "branchCoverage", "number"); + TableColumn branchColumn = new TableColumn("Branch", "branchCoverage", "number").setHeaderClass(ColumnCss.NUMBER); // branchColumn.setWidth(2); columns.add(branchColumn); - TableColumn branchColumnDelta = new TableColumn("Branch Δ", "branchCoverageDelta", "number"); + TableColumn branchColumnDelta = new TableColumn("Branch Δ", "branchCoverageDelta", "number").setHeaderClass(ColumnCss.NUMBER); // branchColumnDelta.setWidth(1); columns.add(branchColumnDelta); - TableColumn loc = new TableColumn("LOC", "loc", "number"); + TableColumn loc = new TableColumn("LOC", "loc", "number").setHeaderClass(ColumnCss.NUMBER); // loc.setWidth(1); columns.add(loc); @@ -699,7 +699,7 @@ static class IndirectCoverageChangesTable extends CoverageTableModel { private final CoverageNode changeRoot; /** - * Creates a indirect coverage changes table model. + * Creates an indirect coverage changes table model. * * @param root * The root of the origin coverage tree From ea30b5e12f98da11143416f9cf9015e7863f5a37 Mon Sep 17 00:00:00 2001 From: Ulli Hafner Date: Fri, 20 May 2022 23:17:55 +0200 Subject: [PATCH 03/32] Print n/a without rendering. --- .../coverage/model/CoverageViewModel.java | 74 ++++++++----------- 1 file changed, 30 insertions(+), 44 deletions(-) diff --git a/plugin/src/main/java/io/jenkins/plugins/coverage/model/CoverageViewModel.java b/plugin/src/main/java/io/jenkins/plugins/coverage/model/CoverageViewModel.java index 486d597e5..5b762d22d 100644 --- a/plugin/src/main/java/io/jenkins/plugins/coverage/model/CoverageViewModel.java +++ b/plugin/src/main/java/io/jenkins/plugins/coverage/model/CoverageViewModel.java @@ -510,6 +510,8 @@ protected CoverageNode getRoot() { * UI row model for the coverage details table. */ private static class CoverageRow { + private static final String COVERAGE_COLUMN_OUTER = "coverage-column-outer"; + private static final String COVERAGE_COLUMN_INNER = "coverage-column-inner"; private final CoverageNode root; private final Locale browserLocale; @@ -532,14 +534,12 @@ public String getPackageName() { public DetailedColumnDefinition getLineCoverage() { Coverage coverage = root.getCoverage(LINE_COVERAGE); - return createColoredCoverageColumn(coverage.getCoveredPercentage(), printCoverage(coverage), - "The total line coverage of the file"); + return createColoredCoverageColumn(coverage, "The total line coverage of the file"); } public DetailedColumnDefinition getBranchCoverage() { Coverage coverage = root.getCoverage(BRANCH_COVERAGE); - return createColoredCoverageColumn(coverage.getCoveredPercentage(), printCoverage(coverage), - "The total branch coverage of the file"); + return createColoredCoverageColumn(coverage, "The total branch coverage of the file"); } public DetailedColumnDefinition getLineCoverageDelta() { @@ -558,39 +558,32 @@ public DetailedColumnDefinition getLoc() { return new DetailedColumnDefinition(Messages.Coverage_Not_Available(), "0"); } - protected String printCoverage(final Coverage coverage) { - if (coverage.isSet()) { - return coverage.formatCoveredPercentage(browserLocale); - } - return Messages.Coverage_Not_Available(); - } - /** * Creates a table cell which colorizes the shown coverage dependent on the coverage percentage. * * @param coverage - * The coverage as percentage - * @param text - * The text to be shown which represents the coverage + * the coverage of the element * @param tooltip - * The tooltip which describes the value + * the tooltip which describes the value * * @return the create {@link DetailedColumnDefinition} */ - protected DetailedColumnDefinition createColoredCoverageColumn(final CoveragePercentage coverage, - final String text, final String tooltip) { - double percentage = coverage.getDoubleValue(); - String sort = String.valueOf(percentage); - DisplayColors colors = CoverageLevel.getDisplayColorsOfCoverageLevel(percentage, COLOR_PROVIDER); - String tag = div().withClasses("coverage-column-outer").with( - div().withClasses("coverage-column-inner") - .withStyle(String.format("color:%s; background-image: linear-gradient(90deg, %s %f%%, transparent %f%%);", - colors.getLineColorAsHex(), colors.getFillColorAsHex(), - percentage, percentage)) - .withTitle(tooltip) - .withText(text)) - .render(); - return new DetailedColumnDefinition(tag, sort); + protected DetailedColumnDefinition createColoredCoverageColumn(final Coverage coverage, final String tooltip) { + double percentage = coverage.getCoveredPercentage().getDoubleValue(); + if (coverage.isSet()) { + DisplayColors colors = CoverageLevel.getDisplayColorsOfCoverageLevel(percentage, COLOR_PROVIDER); + String cell = div().withClasses(COVERAGE_COLUMN_OUTER).with( + div().withClasses(COVERAGE_COLUMN_INNER) + .withStyle(String.format( + "color:%s; background-image: linear-gradient(90deg, %s %f%%, transparent %f%%);", + colors.getLineColorAsHex(), colors.getFillColorAsHex(), + percentage, percentage)) + .withTitle(tooltip) + .withText(coverage.formatCoveredPercentage(browserLocale))) + .render(); + return new DetailedColumnDefinition(cell, String.valueOf(percentage)); + } + return new DetailedColumnDefinition(Messages.Coverage_Not_Available(), "-"); } /** @@ -608,16 +601,15 @@ protected DetailedColumnDefinition createColoredCoverageDeltaColumn( double coverageValue = coveragePercentage.getDoubleValue(); String coverageText = coveragePercentage.formatDeltaPercentage(browserLocale); String sort = String.valueOf(coverageValue); - DisplayColors colors = CoverageChangeTendency - .getDisplayColorsForTendency(coverageValue, COLOR_PROVIDER); - String tag = div().withClasses("coverage-column-outer").with( - div().withClasses("coverage-column-inner") + DisplayColors colors = CoverageChangeTendency.getDisplayColorsForTendency(coverageValue, COLOR_PROVIDER); + String cell = div().withClasses(COVERAGE_COLUMN_OUTER).with( + div().withClasses(COVERAGE_COLUMN_INNER) .withStyle(String.format("color:%s;background-color:%s;", colors.getLineColorAsHex(), colors.getFillColorAsHex())) .withText(coverageText) .withTitle(tooltip)) .render(); - return new DetailedColumnDefinition(tag, sort); + return new DetailedColumnDefinition(cell, sort); } protected CoverageNode getRoot() { @@ -654,7 +646,6 @@ private DetailedColumnDefinition createColoredFileCoverageDeltaColumn(final Cove * @since 3.0.0 */ static class ChangeCoverageTable extends CoverageTableModel { - private final CoverageNode changeRoot; /** @@ -758,15 +749,13 @@ private static class ChangeCoverageRow extends CoverageRow { @Override public DetailedColumnDefinition getLineCoverage() { Coverage coverage = changedFileNode.getCoverage(LINE_COVERAGE); - return createColoredCoverageColumn(coverage.getCoveredPercentage(), printCoverage(coverage), - "The line change coverage"); + return createColoredCoverageColumn(coverage, "The line change coverage"); } @Override public DetailedColumnDefinition getBranchCoverage() { Coverage coverage = changedFileNode.getCoverage(BRANCH_COVERAGE); - return createColoredCoverageColumn(coverage.getCoveredPercentage(), printCoverage(coverage), - "The branch change coverage"); + return createColoredCoverageColumn(coverage, "The branch change coverage"); } @Override @@ -805,7 +794,6 @@ private DetailedColumnDefinition createColoredChangeCoverageDeltaColumn(final Co * @since 3.0.0 */ private static class IndirectCoverageChangesRow extends CoverageRow { - private final FileCoverageNode changedFileNode; /** @@ -827,15 +815,13 @@ private static class IndirectCoverageChangesRow extends CoverageRow { @Override public DetailedColumnDefinition getLineCoverage() { Coverage coverage = changedFileNode.getCoverage(LINE_COVERAGE); - return createColoredCoverageColumn(coverage.getCoveredPercentage(), printCoverage(coverage), - "The indirect line coverage changes"); + return createColoredCoverageColumn(coverage, "The indirect line coverage changes"); } @Override public DetailedColumnDefinition getBranchCoverage() { Coverage coverage = changedFileNode.getCoverage(BRANCH_COVERAGE); - return createColoredCoverageColumn(coverage.getCoveredPercentage(), printCoverage(coverage), - "The indirect branch coverage changes"); + return createColoredCoverageColumn(coverage, "The indirect branch coverage changes"); } @Override From d529feb19ed109a71d4e0c3f92442e7652c8fe22 Mon Sep 17 00:00:00 2001 From: Ulli Hafner Date: Fri, 20 May 2022 23:27:18 +0200 Subject: [PATCH 04/32] Use `--medium-grey` for column border. --- plugin/src/main/webapp/css/column-style.css | 2 +- plugin/src/main/webapp/css/custom-style.css | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/plugin/src/main/webapp/css/column-style.css b/plugin/src/main/webapp/css/column-style.css index dd3bb8e44..f31034495 100644 --- a/plugin/src/main/webapp/css/column-style.css +++ b/plugin/src/main/webapp/css/column-style.css @@ -4,6 +4,6 @@ } .coverage-column-outer { - border: 1px solid var(--light-bg-color); + border: 1px solid var(--medium-grey); border-radius: 10px } diff --git a/plugin/src/main/webapp/css/custom-style.css b/plugin/src/main/webapp/css/custom-style.css index 856234ae9..fb2fbdd4b 100644 --- a/plugin/src/main/webapp/css/custom-style.css +++ b/plugin/src/main/webapp/css/custom-style.css @@ -65,7 +65,7 @@ } .coverage-column-outer { - border: 1px solid var(--light-bg-color); + border: 1px solid var(--medium-grey); border-radius: 10px; } From cec7f4d2da5e51cdc3d28e46c74312df87759cd5 Mon Sep 17 00:00:00 2001 From: Ulli Hafner Date: Mon, 23 May 2022 00:47:25 +0200 Subject: [PATCH 05/32] Tweak layout for dark mode. --- .../plugins/coverage/model/CoverageViewModel.java | 9 ++++----- .../dashboard/CoverageColumn/column.jelly | 8 ++++---- plugin/src/main/webapp/css/column-style.css | 11 ++++++++--- plugin/src/main/webapp/css/custom-style.css | 5 +++-- 4 files changed, 19 insertions(+), 14 deletions(-) diff --git a/plugin/src/main/java/io/jenkins/plugins/coverage/model/CoverageViewModel.java b/plugin/src/main/java/io/jenkins/plugins/coverage/model/CoverageViewModel.java index 5b762d22d..83b232a8d 100644 --- a/plugin/src/main/java/io/jenkins/plugins/coverage/model/CoverageViewModel.java +++ b/plugin/src/main/java/io/jenkins/plugins/coverage/model/CoverageViewModel.java @@ -510,7 +510,7 @@ protected CoverageNode getRoot() { * UI row model for the coverage details table. */ private static class CoverageRow { - private static final String COVERAGE_COLUMN_OUTER = "coverage-column-outer"; + private static final String COVERAGE_COLUMN_OUTER = "coverage-column-outer float-end"; private static final String COVERAGE_COLUMN_INNER = "coverage-column-inner"; private final CoverageNode root; private final Locale browserLocale; @@ -575,8 +575,8 @@ protected DetailedColumnDefinition createColoredCoverageColumn(final Coverage co String cell = div().withClasses(COVERAGE_COLUMN_OUTER).with( div().withClasses(COVERAGE_COLUMN_INNER) .withStyle(String.format( - "color:%s; background-image: linear-gradient(90deg, %s %f%%, transparent %f%%);", - colors.getLineColorAsHex(), colors.getFillColorAsHex(), + "background-image: linear-gradient(90deg, %s %f%%, transparent %f%%);", + colors.getFillColorAsHex(), percentage, percentage)) .withTitle(tooltip) .withText(coverage.formatCoveredPercentage(browserLocale))) @@ -604,8 +604,7 @@ protected DetailedColumnDefinition createColoredCoverageDeltaColumn( DisplayColors colors = CoverageChangeTendency.getDisplayColorsForTendency(coverageValue, COLOR_PROVIDER); String cell = div().withClasses(COVERAGE_COLUMN_OUTER).with( div().withClasses(COVERAGE_COLUMN_INNER) - .withStyle(String.format("color:%s;background-color:%s;", - colors.getLineColorAsHex(), colors.getFillColorAsHex())) + .withStyle(String.format("background-color:%s;", colors.getFillColorAsHex())) .withText(coverageText) .withTitle(tooltip)) .render(); diff --git a/plugin/src/main/resources/io/jenkins/plugins/coverage/model/visualization/dashboard/CoverageColumn/column.jelly b/plugin/src/main/resources/io/jenkins/plugins/coverage/model/visualization/dashboard/CoverageColumn/column.jelly index a75d7831d..1c593f5c1 100644 --- a/plugin/src/main/resources/io/jenkins/plugins/coverage/model/visualization/dashboard/CoverageColumn/column.jelly +++ b/plugin/src/main/resources/io/jenkins/plugins/coverage/model/visualization/dashboard/CoverageColumn/column.jelly @@ -12,15 +12,15 @@ - -
+ +