diff --git a/Implementation-guide.md b/Implementation-guide.md new file mode 100644 index 00000000..1d3c9ed9 --- /dev/null +++ b/Implementation-guide.md @@ -0,0 +1,89 @@ +# Implementation Guide + +Much of the benefit of this plugin will be realized when other plugins that +enhance Jenkins offer support for it. + +## Add support in your plugin + +- Extend the DashboardPortlet class and provide a descriptor that + extends the `Descriptor` +- Create a jelly view called *portlet.jelly* +- Optionally create a jelly view called *main.jelly* to be used when the portlet + is in maximized mode (otherwise the same *portlet.jelly* view will be used) + +It is possible to define custom parameters for the DashboardPortlet. The +displayName is always required. To add new parameters: + +- create a jelly file called *config.jelly* to be used when the portlet is + configured (added to the view in 'Edit View' config page); +- modify constructor (with `@DataBoundConstructor`) to receive the new + parameters. + +Looking at the source code of this plugin will show a number of examples +of doing this. The core portlets do the same thing that your plugin +would do. + +## Sample files + +***MyPortlet.java*** + +``` +import hudson.plugins.view.dashboard.DashboardPortlet; + +class MyPortlet extends DashboardPortlet { + + @DataBoundConstructor + public MyPortlet(String name) { + super(name); + } + +// do whatever you want + + @Extension + public static class DescriptorImpl extends Descriptor { + @Override + public String getDisplayName() { + return "MyPortlet"; + } + } +}; +``` + +***portlet.jelly*** + +If you want to show a single table inside the portlet use *dp:decorate-table*. This ensures that the table is properly +rendered and really fills the complete area (The default styling of Jenkins adds rounded borders everywhere and a margin +at the bottom that make it look not so nice).
+You can pass additional classes to be set on the table, e.g. to make it sortable.
+``` + + + + + + Name + Description + + + + + + ${col.name} + ${col.description} + + + + + +``` + +To show any other kind of content use *dp:decorate-plain* +``` + + + + + + + +``` diff --git a/README.md b/README.md index f4c91dcd..c4680e3c 100644 --- a/README.md +++ b/README.md @@ -152,76 +152,7 @@ to reformat Java code in the proper style. ## Extending the Dashboard View plugin -Much of the benefit of this plugin will be realized when other plugins that -enhance Jenkins offer support for it. - -Add support in your plugin: - -- Extend the DashboardPortlet class and provide a descriptor that - extends the `Descriptor` -- Create a jelly view called portlet.jelly -- Optionally create a jelly view called main.jelly to be used when the portlet - is in maximized mode (otherwise the same portlet.jelly view will be used) - -It is possible to define custom parameters for the DashboardPortlet. The -displayName is always required. To add new parameters: - -- create a jelly file called config.jelly to be used when the portlet is - configured (added to the view in 'Edit View' config page); -- modify constructor (with `@DataBoundConstructor`) to receive the new - parameters. - -Looking at the source code of this plugin will show a number of examples -of doing this. The core portlets do the same thing that your plugin -would do. - -Please update the list below with a [pull request] against this repository. - -Sample files: - -**MyPortlet.java**: - -``` -import hudson.plugins.view.dashboard.DashboardPortlet; - -class MyPortlet extends DashboardPortlet { - - @DataBoundConstructor - public MyPortlet(String name) { - super(name); - } - -// do whatever you want - - @Extension - public static class DescriptorImpl extends Descriptor { - @Override - public String getDisplayName() { - return "MyPortlet"; - } - } -}; -``` - -**portlet.jelly**: - -``` - - - - - - -
- -
- - -
-
-``` +Read the [Implementation guide](Implementation-guide.md) if you want to write your own portlet for your plugin. ## Other plugins that support the Dashboard View @@ -273,7 +204,6 @@ This plugin is licensed under the MIT License (MIT), see [LICENSE](LICENSE). ## TODO -- Use `
` instead of `` to place portlets in the page. - Update this README with more screenshots. diff --git a/pom.xml b/pom.xml index 4fdea43a..de2bc395 100644 --- a/pom.xml +++ b/pom.xml @@ -44,7 +44,7 @@ 2999999-SNAPSHOTjenkinsci/${project.artifactId}-plugin - 2.401.3 + 2.426.2false @@ -53,7 +53,7 @@ io.jenkins.tools.bom - bom-2.401.x + bom-2.426.x 2675.v1515e14da_7a_6 pom import @@ -62,6 +62,10 @@ + + io.jenkins.plugins + ionicons-api + org.jenkins-ci.plugins junit diff --git a/src/main/java/hudson/plugins/view/dashboard/core/JobsPortlet.java b/src/main/java/hudson/plugins/view/dashboard/core/JobsPortlet.java index e666528c..7e723f54 100644 --- a/src/main/java/hudson/plugins/view/dashboard/core/JobsPortlet.java +++ b/src/main/java/hudson/plugins/view/dashboard/core/JobsPortlet.java @@ -21,6 +21,7 @@ public class JobsPortlet extends DashboardPortlet { private static final int MIN_COLUMN_COUNT = 3; private final int columnCount; + private boolean fillColumnFirst = false; @DataBoundConstructor @@ -30,13 +31,17 @@ public JobsPortlet(String name, int columnCount, boolean fillColumnFirst) { this.fillColumnFirst = fillColumnFirst; } + public boolean isFillColumnFirst() { + return fillColumnFirst; + } + public int getColumnCount() { return columnCount <= 0 ? MIN_COLUMN_COUNT : columnCount; } public List> getJobs() { List jobs = this.getDashboard().getJobs(); - Collections.sort(jobs, (p1, p2) -> p1.getDisplayName().compareToIgnoreCase(p2.getDisplayName())); + Collections.sort(jobs, (p1, p2) -> p1.getFullDisplayName().compareToIgnoreCase(p2.getFullDisplayName())); if (this.fillColumnFirst) { return transposed(jobs); diff --git a/src/main/java/hudson/plugins/view/dashboard/stats/StatJobs.java b/src/main/java/hudson/plugins/view/dashboard/stats/StatJobs.java index 3b3f8ee3..ccb2c1d9 100644 --- a/src/main/java/hudson/plugins/view/dashboard/stats/StatJobs.java +++ b/src/main/java/hudson/plugins/view/dashboard/stats/StatJobs.java @@ -2,7 +2,6 @@ import hudson.Extension; import hudson.model.Descriptor; -import hudson.model.Hudson; import hudson.model.Job; import hudson.model.TopLevelItem; import hudson.plugins.view.dashboard.DashboardPortlet; @@ -34,19 +33,22 @@ public StatJobs(String name) { */ @Deprecated public enum HealthStatus { - HEALTH_OVER_80("health-80plus.gif", Messages.Dashboard_NoRecentBuildsFailed()), - HEALTH_60_TO_79("health-60to79.gif", Messages.Dashboard_RecentBuildsFailed("20", "40")), - HEALTH_40_TO_59("health-40to59.gif", Messages.Dashboard_RecentBuildsFailed("40", "60")), - HEALTH_20_TO_39("health-20to39.gif", Messages.Dashboard_RecentBuildsFailed("60", "80")), - HEALTH_0_TO_19("health-00to19.gif", Messages.Dashboard_AllRecentBuildsFailed()), - HEALTH_UNKNOWN("empty.gif", Messages.Dashboard_UnknownStatus()); + HEALTH_OVER_80("symbol-weather-icon-health-80plus", Messages.Dashboard_NoRecentBuildsFailed(), 100), + HEALTH_60_TO_79("symbol-weather-icon-health-60to79", Messages.Dashboard_RecentBuildsFailed("20", "40"), 80), + HEALTH_40_TO_59("symbol-weather-icon-health-40to59", Messages.Dashboard_RecentBuildsFailed("40", "60"), 60), + HEALTH_20_TO_39("symbol-weather-icon-health-20to39", Messages.Dashboard_RecentBuildsFailed("60", "80"), 40), + HEALTH_0_TO_19("symbol-weather-icon-health-00to19", Messages.Dashboard_AllRecentBuildsFailed(), 20), + HEALTH_UNKNOWN("symbol-indeterminate", Messages.Dashboard_UnknownStatus(), 0); // private HealthReport healthReport; - private final String iconUrl; + private final String iconClassName; private final String description; - HealthStatus(String iconUrl, String description) { - this.iconUrl = iconUrl; + private int score; + + HealthStatus(String iconClassName, String description, int score) { + this.iconClassName = iconClassName; this.description = description; + this.score = score; } public static HealthStatus getHealthStatus(Job job) { @@ -67,18 +69,12 @@ public static HealthStatus getHealthStatus(Job job) { return job.getFirstBuild() != null ? HEALTH_OVER_80 : HEALTH_UNKNOWN; } - public String getIconUrl() { - return Hudson.RESOURCE_PATH + "/images/32x32/" + iconUrl; + public String getIconClassName() { + return iconClassName; } - public String getIconUrl(String size) { - if (iconUrl == null) { - return Hudson.RESOURCE_PATH + "/images/" + size + "/" + HEALTH_UNKNOWN.getIconUrl(); - } - if (iconUrl.startsWith("/")) { - return iconUrl.replace("/32x32/", "/" + size + "/"); - } - return Hudson.RESOURCE_PATH + "/images/" + size + "/" + iconUrl; + public int getScore() { + return score; } public String getDescription() { diff --git a/src/main/resources/hudson/plugins/view/dashboard/Dashboard/configure-entries.jelly b/src/main/resources/hudson/plugins/view/dashboard/Dashboard/configure-entries.jelly index aa0f8c1a..13199217 100644 --- a/src/main/resources/hudson/plugins/view/dashboard/Dashboard/configure-entries.jelly +++ b/src/main/resources/hudson/plugins/view/dashboard/Dashboard/configure-entries.jelly @@ -1,89 +1,91 @@ - - - - - - - - - - - ${%Show standard Jenkins list at the top of the page} - - - - ${%Full screen view - hide standard Jenkins panels} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

- - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+ + + diff --git a/src/main/resources/hudson/plugins/view/dashboard/Dashboard/main.jelly b/src/main/resources/hudson/plugins/view/dashboard/Dashboard/main.jelly index 2d5a8d4d..a0526bb2 100644 --- a/src/main/resources/hudson/plugins/view/dashboard/Dashboard/main.jelly +++ b/src/main/resources/hudson/plugins/view/dashboard/Dashboard/main.jelly @@ -45,85 +45,49 @@ - - - -

- - - - - - - - - -
- - - - -

- - -

-

- - - - - - - - - - - - - - - - -
- + + + +
+
+ + + + + +
+ + +
-

- - -

- - - -

- -

- - - - - - - - - - - - -
- - - - -

- - -

-

+

+ + + +
+ + + + +
+
+ + +
+ + + + + + +
+ diff --git a/src/main/resources/hudson/plugins/view/dashboard/builds/LatestBuilds/latestbuilds.jelly b/src/main/resources/hudson/plugins/view/dashboard/builds/LatestBuilds/latestbuilds.jelly index d0f25f89..cb0080a3 100644 --- a/src/main/resources/hudson/plugins/view/dashboard/builds/LatestBuilds/latestbuilds.jelly +++ b/src/main/resources/hudson/plugins/view/dashboard/builds/LatestBuilds/latestbuilds.jelly @@ -1,27 +1,33 @@ - - - - - - - + - - - + + + - -
${%Build name}${%Build status}${%Build time}
- - - - ${build.displayName} - - ${it.getTimestampString(build)}${%Build name}${%Build status}${%Build time}
+ + + + + +
+ +
+ + + + + ${it.getTimestampString(build)} + +
+
diff --git a/src/main/resources/hudson/plugins/view/dashboard/builds/LatestBuilds/portlet.jelly b/src/main/resources/hudson/plugins/view/dashboard/builds/LatestBuilds/portlet.jelly index e61dce16..cd9be549 100644 --- a/src/main/resources/hudson/plugins/view/dashboard/builds/LatestBuilds/portlet.jelly +++ b/src/main/resources/hudson/plugins/view/dashboard/builds/LatestBuilds/portlet.jelly @@ -1,34 +1,30 @@ - - - - - - -
- -
- -
-
\ No newline at end of file + + + + + + + + diff --git a/src/main/resources/hudson/plugins/view/dashboard/core/HudsonStdJobsPortlet/portlet.jelly b/src/main/resources/hudson/plugins/view/dashboard/core/HudsonStdJobsPortlet/portlet.jelly index 88e27c7f..58c2c51e 100644 --- a/src/main/resources/hudson/plugins/view/dashboard/core/HudsonStdJobsPortlet/portlet.jelly +++ b/src/main/resources/hudson/plugins/view/dashboard/core/HudsonStdJobsPortlet/portlet.jelly @@ -1,38 +1,34 @@ - - - - - - - - - - - - - - \ No newline at end of file + + + + + + + + + + diff --git a/src/main/resources/hudson/plugins/view/dashboard/core/IframePortlet/portlet.jelly b/src/main/resources/hudson/plugins/view/dashboard/core/IframePortlet/portlet.jelly index 6484e6dc..49a11cb6 100644 --- a/src/main/resources/hudson/plugins/view/dashboard/core/IframePortlet/portlet.jelly +++ b/src/main/resources/hudson/plugins/view/dashboard/core/IframePortlet/portlet.jelly @@ -24,29 +24,27 @@ THE SOFTWARE. - - - - -
- - - - - - - - -
-
- -
${%Display error: URL is invalid}
-
-
- -
+ + + +
+ + + + + + + + +
+
+ +
${%Display error: URL is invalid}
+
+
+
diff --git a/src/main/resources/hudson/plugins/view/dashboard/core/ImagePortlet/portlet.jelly b/src/main/resources/hudson/plugins/view/dashboard/core/ImagePortlet/portlet.jelly index 6243b23d..a8383775 100644 --- a/src/main/resources/hudson/plugins/view/dashboard/core/ImagePortlet/portlet.jelly +++ b/src/main/resources/hudson/plugins/view/dashboard/core/ImagePortlet/portlet.jelly @@ -24,18 +24,16 @@ THE SOFTWARE. - - - - - - - - -
${%Display error: Image URL is invalid}
-
-
- - -
+ + + +
+ +
+
+ +
${%Display error: Image URL is invalid}
+
+
+
diff --git a/src/main/resources/hudson/plugins/view/dashboard/core/JobsPortlet/config.jelly b/src/main/resources/hudson/plugins/view/dashboard/core/JobsPortlet/config.jelly index 252f117f..7d2027a7 100644 --- a/src/main/resources/hudson/plugins/view/dashboard/core/JobsPortlet/config.jelly +++ b/src/main/resources/hudson/plugins/view/dashboard/core/JobsPortlet/config.jelly @@ -1,38 +1,37 @@ - - - - - - - - - - - - - ${%Fill column first} - - + + + + + + + + + + + + + + diff --git a/src/main/resources/hudson/plugins/view/dashboard/core/JobsPortlet/portlet.jelly b/src/main/resources/hudson/plugins/view/dashboard/core/JobsPortlet/portlet.jelly index a5e87a19..d82ea0d6 100644 --- a/src/main/resources/hudson/plugins/view/dashboard/core/JobsPortlet/portlet.jelly +++ b/src/main/resources/hudson/plugins/view/dashboard/core/JobsPortlet/portlet.jelly @@ -7,38 +7,15 @@ SPDX-License-Identifier: MIT - + - - - - - - - - - - - - - - - - - - - - - - - + + - + diff --git a/src/main/resources/hudson/plugins/view/dashboard/core/UnstableJobsPortlet/config.jelly b/src/main/resources/hudson/plugins/view/dashboard/core/UnstableJobsPortlet/config.jelly index f398ac88..c3188570 100644 --- a/src/main/resources/hudson/plugins/view/dashboard/core/UnstableJobsPortlet/config.jelly +++ b/src/main/resources/hudson/plugins/view/dashboard/core/UnstableJobsPortlet/config.jelly @@ -27,10 +27,10 @@ THE SOFTWARE. - + - ${%Show only Failed Jobs}
+
+ - ${%Recurse within folders}
- \ No newline at end of file + diff --git a/src/main/resources/hudson/plugins/view/dashboard/core/UnstableJobsPortlet/portlet.jelly b/src/main/resources/hudson/plugins/view/dashboard/core/UnstableJobsPortlet/portlet.jelly index e38cd006..36461337 100644 --- a/src/main/resources/hudson/plugins/view/dashboard/core/UnstableJobsPortlet/portlet.jelly +++ b/src/main/resources/hudson/plugins/view/dashboard/core/UnstableJobsPortlet/portlet.jelly @@ -7,7 +7,7 @@ SPDX-License-Identifier: MIT - + @@ -21,35 +21,12 @@ SPDX-License-Identifier: MIT - - - - - - - - - - - - - - - - - - - - - - - + + - + diff --git a/src/main/resources/hudson/plugins/view/dashboard/core/UnstableJobsPortlet/portlet.properties b/src/main/resources/hudson/plugins/view/dashboard/core/UnstableJobsPortlet/portlet.properties index 2b99208b..ff3afa05 100644 --- a/src/main/resources/hudson/plugins/view/dashboard/core/UnstableJobsPortlet/portlet.properties +++ b/src/main/resources/hudson/plugins/view/dashboard/core/UnstableJobsPortlet/portlet.properties @@ -1,5 +1,3 @@ # SPDX-FileCopyrightText: \u00A9 2023 TobiX # SPDX-License-Identifier: MIT -Task_scheduled={0} scheduled -Schedule_a_task=Schedule a {1} for {0} -Schedule_a_task_with_parameters=Schedule a {1} with parameters for {0} + diff --git a/src/main/resources/hudson/plugins/view/dashboard/core/UnstableJobsPortlet/portlet_ja.properties b/src/main/resources/hudson/plugins/view/dashboard/core/UnstableJobsPortlet/portlet_ja.properties index df2f47b8..fb06d3ec 100755 --- a/src/main/resources/hudson/plugins/view/dashboard/core/UnstableJobsPortlet/portlet_ja.properties +++ b/src/main/resources/hudson/plugins/view/dashboard/core/UnstableJobsPortlet/portlet_ja.properties @@ -1,4 +1,4 @@ # SPDX-FileCopyrightText: \u00A9 2012 Seiji Sogabe # SPDX-License-Identifier: MIT No\ unstable\ jobs=\u4E0D\u5B89\u5B9A\u30D3\u30EB\u30C9\u306A\u3057 -Schedule_a_task=\u30D3\u30EB\u30C9\u5B9F\u884C + diff --git a/src/main/resources/hudson/plugins/view/dashboard/decorate-plain.jelly b/src/main/resources/hudson/plugins/view/dashboard/decorate-plain.jelly new file mode 100644 index 00000000..70485f5b --- /dev/null +++ b/src/main/resources/hudson/plugins/view/dashboard/decorate-plain.jelly @@ -0,0 +1,46 @@ + + + + + + + Portlet border decoration without a table. Use this to show other content like charts. + + The portlet being rendered + + + Unused + + +
+ +
+ +
+
+
diff --git a/src/main/resources/hudson/plugins/view/dashboard/decorate-table.jelly b/src/main/resources/hudson/plugins/view/dashboard/decorate-table.jelly new file mode 100644 index 00000000..ea3e13bb --- /dev/null +++ b/src/main/resources/hudson/plugins/view/dashboard/decorate-table.jelly @@ -0,0 +1,52 @@ + + + + + + definition here. + ]]> + + The portlet being rendered + + + Unused + + + Additional classes applied to the table + + +
+ + + +
+
+
diff --git a/src/main/resources/hudson/plugins/view/dashboard/decorate.jelly b/src/main/resources/hudson/plugins/view/dashboard/decorate.jelly index e8209c00..73bd1ebd 100644 --- a/src/main/resources/hudson/plugins/view/dashboard/decorate.jelly +++ b/src/main/resources/hudson/plugins/view/dashboard/decorate.jelly @@ -26,9 +26,11 @@ THE SOFTWARE. adds a table with header row and caller adds additional rows to body --> - + - Portlet border decoration + Deprecated. Instead use decorate-plain or decorate-table.
+ Portlet border decoration. The body is wrapper inside a table. The portlet being rendered @@ -36,26 +38,10 @@ THE SOFTWARE. Unused
-
-
- ${attrs.portlet.displayName} - - - - - -
- - -
+
+ + + +
diff --git a/src/main/resources/hudson/plugins/view/dashboard/jobCell.jelly b/src/main/resources/hudson/plugins/view/dashboard/jobCell.jelly new file mode 100644 index 00000000..0f273d0f --- /dev/null +++ b/src/main/resources/hudson/plugins/view/dashboard/jobCell.jelly @@ -0,0 +1,42 @@ + + + + Displays a link to the job with a build button, optionally followed by the job weather. + + Job object to be displayed. + + + Show job weather. + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+
diff --git a/src/main/resources/hudson/plugins/view/dashboard/core/JobsPortlet/portlet.properties b/src/main/resources/hudson/plugins/view/dashboard/jobCell.properties similarity index 100% rename from src/main/resources/hudson/plugins/view/dashboard/core/JobsPortlet/portlet.properties rename to src/main/resources/hudson/plugins/view/dashboard/jobCell.properties diff --git a/src/main/resources/hudson/plugins/view/dashboard/core/JobsPortlet/portlet_ja.properties b/src/main/resources/hudson/plugins/view/dashboard/jobCell_ja.properties similarity index 100% rename from src/main/resources/hudson/plugins/view/dashboard/core/JobsPortlet/portlet_ja.properties rename to src/main/resources/hudson/plugins/view/dashboard/jobCell_ja.properties diff --git a/src/main/resources/hudson/plugins/view/dashboard/portlet.css b/src/main/resources/hudson/plugins/view/dashboard/portlet.css new file mode 100644 index 00000000..8738df49 --- /dev/null +++ b/src/main/resources/hudson/plugins/view/dashboard/portlet.css @@ -0,0 +1,103 @@ +.dbv-container { + display: grid; + gap: 5px 10px; + min-width: fit-content; +} + +.dbv-container__top{ + grid-row: 1; + grid-column: 1 / 3; +} + +.dbv-container__middle { + grid-row: 2; + grid-column: 1 / 3; +} + +.dbv-container__left{ + grid-row: 2; + grid-column: 1; +} + +.dbv-container__right{ + grid-row: 2; + grid-column: 2; +} + +.dbv-container__bottom { + grid-row: 3; + grid-column: 1 / 3; +} + +.dbv-portlet { + margin-bottom: var(--section-padding); + border-radius: calc(var(--table-border-radius) + 2px); + border: 2px solid var(--medium-grey); + overflow: hidden; +} + +.dbv-portlet__title { + background-color: var(--medium-grey); + padding: 5px 10px; + font-weight: bold; + display: flex; +} + +.dbv-portlet__title--icons { + margin-left: auto; +} + +.dbv-portlet__table, .dbv-portlet__content #projectstatus { + margin-bottom: 0; + border-top-left-radius: 0; + border-top-right-radius: 0; +} + +.dbv-portlet__content .jenkins-icon-size { + margin-left: 5px; +} + +.dbv-portlet__table--gap { + border-spacing: 2px; +} + +.dbv-portlet__table--compact > tbody > tr > td { + height: auto; +} + +.dbv-portlet__title-button--maximize { + color: var(--text-color); +} + +.dbv-cell { + display: flex; + align-items: center; + gap: 0.4rem; +} + +.dbv-cell .jenkins-icon-adjacent { + margin-left: 0; +} + +.dbv-cell > a.model-link { + text-align: left; + width: fit-content; +} + +.dbv-cell > .jenkins-table__cell--tight { + width: fit-content; +} + +.dbv-cell svg { + min-width: 16px; +} + +.dbv-portlet__table tr > td:last-of-type, +.dbv-portlet__table tr > th:last-of-type{ + padding-right: 10px!important; +} + +.dbv-table__bottom--left { + padding-left: 1.6rem; +} + diff --git a/src/main/resources/hudson/plugins/view/dashboard/stats/StatBuilds/main.jelly b/src/main/resources/hudson/plugins/view/dashboard/stats/StatBuilds/main.jelly index 391eea30..e0df874b 100644 --- a/src/main/resources/hudson/plugins/view/dashboard/stats/StatBuilds/main.jelly +++ b/src/main/resources/hudson/plugins/view/dashboard/stats/StatBuilds/main.jelly @@ -1,34 +1,30 @@ - - - - - - -
- -
- -
-
\ No newline at end of file + + + + + + + + diff --git a/src/main/resources/hudson/plugins/view/dashboard/stats/StatBuilds/portlet.jelly b/src/main/resources/hudson/plugins/view/dashboard/stats/StatBuilds/portlet.jelly index 391eea30..c1fc31e8 100644 --- a/src/main/resources/hudson/plugins/view/dashboard/stats/StatBuilds/portlet.jelly +++ b/src/main/resources/hudson/plugins/view/dashboard/stats/StatBuilds/portlet.jelly @@ -1,34 +1,30 @@ - - - - - - -
- -
- -
-
\ No newline at end of file + + + + + + + + diff --git a/src/main/resources/hudson/plugins/view/dashboard/stats/StatBuilds/statbuilds.jelly b/src/main/resources/hudson/plugins/view/dashboard/stats/StatBuilds/statbuilds.jelly index c0d5cbd6..8bf71bb0 100644 --- a/src/main/resources/hudson/plugins/view/dashboard/stats/StatBuilds/statbuilds.jelly +++ b/src/main/resources/hudson/plugins/view/dashboard/stats/StatBuilds/statbuilds.jelly @@ -23,34 +23,36 @@ THE SOFTWARE. --> - - + - - - - - - - - - - - - - - - - - - - - - - - -
${%Status of the build}${%Description}${%Number of builds with status}${%Percentage of total builds}
${col.key.description}${col.value}${it.roundFloatDecimal((col.value/nBuilds)*100)}
${%Total builds}${%All builds}${nBuilds}
+ + + ${%S} + ${%Description} + ${%Number of builds with status} + ${%Percentage of total builds} + + + + + + + + + + ${col.key.description} + ${col.value} + ${it.roundFloatDecimal((col.value/nBuilds)*100)} + + + + + ${%Total builds} + ${nBuilds} + + +
diff --git a/src/main/resources/hudson/plugins/view/dashboard/stats/StatJobs/main.jelly b/src/main/resources/hudson/plugins/view/dashboard/stats/StatJobs/main.jelly index 483c0716..dbd52d78 100644 --- a/src/main/resources/hudson/plugins/view/dashboard/stats/StatJobs/main.jelly +++ b/src/main/resources/hudson/plugins/view/dashboard/stats/StatJobs/main.jelly @@ -1,34 +1,30 @@ - - - - - - -
- -
- -
-
\ No newline at end of file + + + + + + + + diff --git a/src/main/resources/hudson/plugins/view/dashboard/stats/StatJobs/portlet.jelly b/src/main/resources/hudson/plugins/view/dashboard/stats/StatJobs/portlet.jelly index 483c0716..67a231c2 100644 --- a/src/main/resources/hudson/plugins/view/dashboard/stats/StatJobs/portlet.jelly +++ b/src/main/resources/hudson/plugins/view/dashboard/stats/StatJobs/portlet.jelly @@ -1,34 +1,30 @@ - - - - - - -
- -
- -
-
\ No newline at end of file + + + + + + + + diff --git a/src/main/resources/hudson/plugins/view/dashboard/stats/StatJobs/statjobs.jelly b/src/main/resources/hudson/plugins/view/dashboard/stats/StatJobs/statjobs.jelly index 27b5f662..11471bd0 100644 --- a/src/main/resources/hudson/plugins/view/dashboard/stats/StatJobs/statjobs.jelly +++ b/src/main/resources/hudson/plugins/view/dashboard/stats/StatJobs/statjobs.jelly @@ -24,32 +24,36 @@ THE SOFTWARE. - - - - - - - - - - - - - - - - - - - - - - -
${%Project health}${%Description}${%Number of projects}
${col.key.description}${col.key.description}${col.value}
${%Total projects}${%All projects}${nProjects}
-
\ No newline at end of file + + + ${%W} + ${%Description} + ${%Number of projects} + + + + + + +
+ +
+ + ${col.key.description} + ${col.value} + + +
+ + + ${%Total projects} + + ${nProjects} + + + diff --git a/src/main/resources/hudson/plugins/view/dashboard/stats/StatSlaves/main.jelly b/src/main/resources/hudson/plugins/view/dashboard/stats/StatSlaves/main.jelly index 7d704017..e692f372 100644 --- a/src/main/resources/hudson/plugins/view/dashboard/stats/StatSlaves/main.jelly +++ b/src/main/resources/hudson/plugins/view/dashboard/stats/StatSlaves/main.jelly @@ -2,13 +2,7 @@ - - - -
- -
- - -
+ + +
diff --git a/src/main/resources/hudson/plugins/view/dashboard/stats/StatSlaves/poller.js b/src/main/resources/hudson/plugins/view/dashboard/stats/StatSlaves/poller.js new file mode 100644 index 00000000..12f75c6e --- /dev/null +++ b/src/main/resources/hudson/plugins/view/dashboard/stats/StatSlaves/poller.js @@ -0,0 +1,31 @@ +let err = 0; +function repeat() { + buildStat.getStats(function(t) { + let tables = document.querySelectorAll(".dbv-agents-table"); + for (let table of tables) { + let tableId = table.id; + if (t.status === 200) { + err = 0; + let stats = t.responseObject(); + document.getElementById('agents-' + tableId).innerText = stats.agents; + document.getElementById('onlineAgents-' + tableId).innerText = stats.onlineAgents; + document.getElementById('offlineAgents-' + tableId).innerText = stats.offlineAgents; + document.getElementById('disconnectedAgents-' + tableId).innerText = stats.disconnectedAgents; + document.getElementById('tasksInQueue-' + tableId).innerText = stats.tasksInQueue; + document.getElementById('runningJobs-' + tableId).innerText = stats.runningJobs; + } else if (t.status === 503 || t.status === 0) { + // Consider these recoverable and don't update error count + document.getElementById('runningJobs-' + tableId).innerText = 'ERR-' + + (t.status === 0)? 'OFFLINE' : 'PROXY'; + } else { + err++; + document.getElementById('runningJobs-' + tableId).innerText = 'ERR-' + err; + } + } + + if (err < 5) { + setTimeout('repeat()', 2500); + } + }); +} +repeat(); diff --git a/src/main/resources/hudson/plugins/view/dashboard/stats/StatSlaves/portlet.jelly b/src/main/resources/hudson/plugins/view/dashboard/stats/StatSlaves/portlet.jelly index 7d704017..d2ddfcd4 100644 --- a/src/main/resources/hudson/plugins/view/dashboard/stats/StatSlaves/portlet.jelly +++ b/src/main/resources/hudson/plugins/view/dashboard/stats/StatSlaves/portlet.jelly @@ -1,14 +1,6 @@ - - - - -
- -
- - -
+ + + + diff --git a/src/main/resources/hudson/plugins/view/dashboard/stats/StatSlaves/statagents.jelly b/src/main/resources/hudson/plugins/view/dashboard/stats/StatSlaves/statagents.jelly index 0bfb35f1..48792cbf 100644 --- a/src/main/resources/hudson/plugins/view/dashboard/stats/StatSlaves/statagents.jelly +++ b/src/main/resources/hudson/plugins/view/dashboard/stats/StatSlaves/statagents.jelly @@ -1,38 +1,10 @@ - - - + + + + @@ -40,6 +12,8 @@ + + -
${%Agents} ${%Online agents} ${%Offline agents}${%Tasks in queue} ${%Running jobs}
@@ -60,5 +34,5 @@
+
diff --git a/src/main/resources/hudson/plugins/view/dashboard/test/TestStatisticsChart/main.jelly b/src/main/resources/hudson/plugins/view/dashboard/test/TestStatisticsChart/main.jelly index 6c5b75f5..ec124787 100644 --- a/src/main/resources/hudson/plugins/view/dashboard/test/TestStatisticsChart/main.jelly +++ b/src/main/resources/hudson/plugins/view/dashboard/test/TestStatisticsChart/main.jelly @@ -1,34 +1,30 @@ - - - - - - -
- [Test Summary graph] -
- -
-
\ No newline at end of file + + + + + + [Test Summary graph] + + diff --git a/src/main/resources/hudson/plugins/view/dashboard/test/TestStatisticsChart/portlet.jelly b/src/main/resources/hudson/plugins/view/dashboard/test/TestStatisticsChart/portlet.jelly index c48f5aae..f7f16e4a 100644 --- a/src/main/resources/hudson/plugins/view/dashboard/test/TestStatisticsChart/portlet.jelly +++ b/src/main/resources/hudson/plugins/view/dashboard/test/TestStatisticsChart/portlet.jelly @@ -1,34 +1,32 @@ - - - - - - -
- [Test Summary graph] -
- -
-
\ No newline at end of file + + + + + +
+ [Test Summary graph] +
+
+
diff --git a/src/main/resources/hudson/plugins/view/dashboard/test/TestStatisticsPortlet/portlet.jelly b/src/main/resources/hudson/plugins/view/dashboard/test/TestStatisticsPortlet/portlet.jelly index 5d585ea1..ae9a13f7 100644 --- a/src/main/resources/hudson/plugins/view/dashboard/test/TestStatisticsPortlet/portlet.jelly +++ b/src/main/resources/hudson/plugins/view/dashboard/test/TestStatisticsPortlet/portlet.jelly @@ -1,34 +1,30 @@ - - - - - - -
- -
- -
-
\ No newline at end of file + + + + + + + + diff --git a/src/main/resources/hudson/plugins/view/dashboard/test/TestStatisticsPortlet/teststatistics.jelly b/src/main/resources/hudson/plugins/view/dashboard/test/TestStatisticsPortlet/teststatistics.jelly index 0a4afeca..6b0186d5 100644 --- a/src/main/resources/hudson/plugins/view/dashboard/test/TestStatisticsPortlet/teststatistics.jelly +++ b/src/main/resources/hudson/plugins/view/dashboard/test/TestStatisticsPortlet/teststatistics.jelly @@ -5,113 +5,114 @@ - - - - - - - - - - + + + + + + + + + + - - - - - - - - - - - - - - - - + + + + - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + -
${%Job}${%Success} #%${%Failed} #%${%Skipped} #%${%Total} #
${%Job}${%Success} #%${%Failed} #%${%Skipped} #%${%Total} #
- - - - - ${tr.success} - - ${it.format(format, tr.successPct)} - - ${tr.failed} - - ${it.format(format, tr.failedPct)} - - ${tr.skipped} - - ${it.format(format, tr.skippedPct)} - - ${tr.tests} -
- ${%Total} +
+
+ +
- ${summary.success} + + ${tr.success} - ${it.format(format, summary.successPct)} + + ${it.format(format, tr.successPct)} - ${summary.failed} + + ${tr.failed} - ${it.format(format, summary.failedPct)} + + ${it.format(format, tr.failedPct)} - ${summary.skipped} + + ${tr.skipped} - ${it.format(format, summary.skippedPct)} + + ${it.format(format, tr.skippedPct)} - ${summary.tests} + + ${tr.tests}
- - ${tr.success}${it.format(format, tr.successPct)}${tr.failed}${it.format(format, tr.failedPct)}${tr.skipped}${it.format(format, tr.skippedPct)}${tr.tests}
${%Total}${summary.success}${it.format(format, summary.successPct)}${summary.failed}${it.format(format, summary.failedPct)}${summary.skipped}${it.format(format, summary.skippedPct)}${summary.tests}
+ ${%Total} + + ${summary.success} + + ${it.format(format, summary.successPct)} + + ${summary.failed} + + ${it.format(format, summary.failedPct)} + + ${summary.skipped} + + ${it.format(format, summary.skippedPct)} + + ${summary.tests} +
+
+ +
+
${tr.success}${it.format(format, tr.successPct)}${tr.failed}${it.format(format, tr.failedPct)}${tr.skipped}${it.format(format, tr.skippedPct)}${tr.tests}
${%Total}${summary.success}${it.format(format, summary.successPct)}${summary.failed}${it.format(format, summary.failedPct)}${summary.skipped}${it.format(format, summary.skippedPct)}${summary.tests}
diff --git a/src/main/resources/hudson/plugins/view/dashboard/test/TestTrendChart/main.jelly b/src/main/resources/hudson/plugins/view/dashboard/test/TestTrendChart/main.jelly index 240f13d6..89e76c06 100644 --- a/src/main/resources/hudson/plugins/view/dashboard/test/TestTrendChart/main.jelly +++ b/src/main/resources/hudson/plugins/view/dashboard/test/TestTrendChart/main.jelly @@ -1,34 +1,30 @@ - - - - - - -
- [${%Test Summary graph}] -
- -
-
\ No newline at end of file + + + + + + [${%Test Summary graph}] + + diff --git a/src/main/resources/hudson/plugins/view/dashboard/test/TestTrendChart/portlet.jelly b/src/main/resources/hudson/plugins/view/dashboard/test/TestTrendChart/portlet.jelly index fb50ebe3..0e80557b 100644 --- a/src/main/resources/hudson/plugins/view/dashboard/test/TestTrendChart/portlet.jelly +++ b/src/main/resources/hudson/plugins/view/dashboard/test/TestTrendChart/portlet.jelly @@ -1,34 +1,32 @@ - - - - - - -
- [${%Test Summary graph}] -
- -
-
\ No newline at end of file + + + + + +
+ [${%Test Summary graph}] +
+
+
diff --git a/src/main/resources/hudson/plugins/view/dashboard/title.jelly b/src/main/resources/hudson/plugins/view/dashboard/title.jelly new file mode 100644 index 00000000..12da245f --- /dev/null +++ b/src/main/resources/hudson/plugins/view/dashboard/title.jelly @@ -0,0 +1,59 @@ + + + + + + + Portlet border decoration without a table. Use this when the portlet itself renders a table + + The portlet being rendered + + + +
+
+ ${attrs.portlet.displayName} +
+
+ + + + + +
+
+
diff --git a/src/main/webapp/images/go-bottom.png b/src/main/webapp/images/go-bottom.png deleted file mode 100644 index 2c5a8038..00000000 Binary files a/src/main/webapp/images/go-bottom.png and /dev/null differ diff --git a/src/main/webapp/images/go-top.png b/src/main/webapp/images/go-top.png deleted file mode 100644 index 70f2c996..00000000 Binary files a/src/main/webapp/images/go-top.png and /dev/null differ diff --git a/src/main/webapp/images/view-fullscreen.png b/src/main/webapp/images/view-fullscreen.png deleted file mode 100644 index ffdabd4e..00000000 Binary files a/src/main/webapp/images/view-fullscreen.png and /dev/null differ diff --git a/src/main/webapp/js/dashboard-view.js b/src/main/webapp/js/dashboard-view.js index c112f932..fa4ec3e5 100644 --- a/src/main/webapp/js/dashboard-view.js +++ b/src/main/webapp/js/dashboard-view.js @@ -1,70 +1,34 @@ -function getElementFromEvent(e) { - var targ; - if (e.target) - targ = e.target; - else if (e.srcElement) - targ = e.srcElement; - if (targ.nodeType == 3) // defeat Safari bug - targ = targ.parentNode; - return targ; -} - -function updateIcons(elemName, param) +function togglePortlet(portlet, show) { - var cmds = window.document.getElementsByTagName('img'); - var collapse; - var expand; - for (var cmdIndex in cmds) { - cmd = cmds[cmdIndex]; - if (cmd.id && cmd.id == ('cmdExp-'+elemName)) { - expand = cmd; - } else if (cmd.id && cmd.id == ('cmdCol-'+elemName)) { - collapse = cmd; - } + let content = portlet.querySelector(".dbv-portlet__content"); + let collapse = portlet.querySelector(".dbv-portlet__title-button--collapse"); + let expand = portlet.querySelector(".dbv-portlet__title-button--expand"); + if (show) { + content.classList.remove("jenkins-hidden"); + expand.classList.add("jenkins-hidden"); + collapse.classList.remove("jenkins-hidden"); + } else { + content.classList.add("jenkins-hidden"); + expand.classList.remove("jenkins-hidden"); + collapse.classList.add("jenkins-hidden"); } - expand.style.visibility = (param == 'e') ? 'hidden' : 'visible'; - expand.style.display = (param == 'e') ? 'none' : ''; - collapse.style.visibility = (param == 'c') ? 'hidden' : 'visible'; - collapse.style.display = (param == 'c') ? 'none' : ''; } -function myshow(e) { - if (!e) var e = window.event; - var receiver = getElementFromEvent(e); - var portletId = receiver.id.substring(7); - var elem = document.getElementById(portletId); - elem.style.visibility = 'visible'; - elem.style.display = ''; +Behaviour.specify(".dbv-portlet__title-button--maximize", "dbv-maximize", 0, function(cmd) { + cmd.classList.remove("jenkins-hidden"); +}); - updateIcons(portletId, 'e'); -} - -function myhide(e) { - if (!e) var e = window.event; - var receiver = getElementFromEvent(e); - var portletId = receiver.id.substring(7); - var elem = document.getElementById(portletId); - elem.style.visibility = 'hidden'; - elem.style.display = 'none'; - - updateIcons(portletId, 'c'); -} - -function startsWith(str, substr) { - return (str.match("^"+substr) == substr); -} +Behaviour.specify(".dbv-portlet__title-button--collapse", "dbv-collapse", 0, function(cmd) { + let portlet = cmd.closest(".dbv-portlet"); + cmd.onclick = function() { + togglePortlet(portlet, false); + } + cmd.classList.remove("jenkins-hidden") +}); -var cmds = window.document.getElementsByTagName('img'); -for (var cmdIndex in cmds) { - cmd = cmds[cmdIndex]; - if (cmd.id && startsWith(cmd.id, 'cmdExp-portlet-')) { - cmd.onclick = myshow; - } else if (cmd.id && startsWith(cmd.id, 'cmdCol-portlet-')) { - cmd.onclick = myhide; - cmd.style.visibility = 'visible'; - cmd.style.display = ''; - } else if (cmd.id && startsWith(cmd.id, 'cmdMax-portlet-')) { - cmd.style.visibility = 'visible'; - cmd.style.display = ''; - } -} +Behaviour.specify(".dbv-portlet__title-button--expand", "dbv-expand", 0, function(cmd) { + let portlet = cmd.closest(".dbv-portlet"); + cmd.onclick = function() { + togglePortlet(portlet, true); + } +}); diff --git a/src/test/java/hudson/plugins/view/dashboard/core/IFramePortletTest.java b/src/test/java/hudson/plugins/view/dashboard/core/IFramePortletTest.java index 26a96040..0b3ee1df 100644 --- a/src/test/java/hudson/plugins/view/dashboard/core/IFramePortletTest.java +++ b/src/test/java/hudson/plugins/view/dashboard/core/IFramePortletTest.java @@ -99,7 +99,7 @@ public void iframePortletSandbox() throws Exception { } private List findIFrame(HtmlPage page) { - return page.getByXPath("//table[@id='portlet-bottomPortlets-0']//iframe"); + return page.getByXPath("//div[@id='portlet-bottomPortlets-0']//iframe"); } private List findError(HtmlPage page) { diff --git a/src/test/java/hudson/plugins/view/dashboard/core/ImagePortletTest.java b/src/test/java/hudson/plugins/view/dashboard/core/ImagePortletTest.java index f44c9ff2..900a4a4d 100644 --- a/src/test/java/hudson/plugins/view/dashboard/core/ImagePortletTest.java +++ b/src/test/java/hudson/plugins/view/dashboard/core/ImagePortletTest.java @@ -50,7 +50,7 @@ public void imagePortletValidation() throws Exception { } private List findImage(HtmlPage page) { - return page.getByXPath("//table[@id='portlet-bottomPortlets-0']//img"); + return page.getByXPath("//div[@id='portlet-bottomPortlets-0']//img"); } private List findError(HtmlPage page) {