├── .gitattributes ├── .github ├── release-drafter.yml ├── CODEOWNERS ├── create-view.png ├── configure-view.png ├── dependabot.yml └── workflows │ ├── cd.yaml │ └── jenkins-security-scan.yml ├── src ├── main │ ├── resources │ │ ├── hudson │ │ │ └── plugins │ │ │ │ └── view │ │ │ │ └── dashboard │ │ │ │ ├── taglib │ │ │ │ ├── Dashboard │ │ │ │ ├── newViewDetail.jelly │ │ │ │ ├── newViewDetail.properties │ │ │ │ ├── newViewDetail_ja.properties │ │ │ │ ├── newViewDetail_fr.properties │ │ │ │ ├── newViewDetail_ko.properties │ │ │ │ ├── configure-entries_fr.properties │ │ │ │ ├── configure-entries_it.properties │ │ │ │ ├── configure-entries_ja.properties │ │ │ │ ├── main.jelly │ │ │ │ └── configure-entries.jelly │ │ │ │ ├── core │ │ │ │ ├── ImagePortlet │ │ │ │ │ ├── portlet_de.properties │ │ │ │ │ ├── config_ja.properties │ │ │ │ │ ├── config.jelly │ │ │ │ │ └── portlet.jelly │ │ │ │ ├── UnstableJobsPortlet │ │ │ │ │ ├── portlet.properties │ │ │ │ │ ├── portlet_ja.properties │ │ │ │ │ ├── portlet.jelly │ │ │ │ │ ├── portlet_fr.properties │ │ │ │ │ ├── portlet_el.properties │ │ │ │ │ └── config.jelly │ │ │ │ ├── JobsPortlet │ │ │ │ │ ├── config_ja.properties │ │ │ │ │ ├── portlet.jelly │ │ │ │ │ └── config.jelly │ │ │ │ ├── buildbutton.js │ │ │ │ ├── HudsonStdJobsPortlet │ │ │ │ │ └── portlet.jelly │ │ │ │ └── IframePortlet │ │ │ │ │ ├── config.jelly │ │ │ │ │ └── portlet.jelly │ │ │ │ ├── builds │ │ │ │ └── LatestBuilds │ │ │ │ │ ├── config_ja.properties │ │ │ │ │ ├── latestbuilds_nl.properties │ │ │ │ │ ├── latestbuilds_it.properties │ │ │ │ │ ├── latestbuilds.properties │ │ │ │ │ ├── latestbuilds_ja.properties │ │ │ │ │ ├── latestbuilds_el.properties │ │ │ │ │ ├── latestbuilds.jelly │ │ │ │ │ ├── portlet.jelly │ │ │ │ │ └── config.jelly │ │ │ │ ├── jobCell_ja.properties │ │ │ │ ├── test │ │ │ │ ├── TestStatisticsPortlet │ │ │ │ │ ├── teststatistics_ja.properties │ │ │ │ │ ├── portlet_nl.properties │ │ │ │ │ ├── portlet_sv_SE.properties │ │ │ │ │ ├── portlet_fr.properties │ │ │ │ │ ├── portlet_ja.properties │ │ │ │ │ ├── config_ja.properties │ │ │ │ │ ├── portlet.jelly │ │ │ │ │ ├── config.jelly │ │ │ │ │ └── teststatistics.jelly │ │ │ │ ├── TestTrendChart │ │ │ │ │ ├── main_ja.properties │ │ │ │ │ ├── portlet_ja.properties │ │ │ │ │ ├── config.properties │ │ │ │ │ ├── main.jelly │ │ │ │ │ ├── config_ja.properties │ │ │ │ │ ├── portlet.jelly │ │ │ │ │ └── config.jelly │ │ │ │ └── TestStatisticsChart │ │ │ │ │ ├── main.jelly │ │ │ │ │ └── portlet.jelly │ │ │ │ ├── DashboardPortlet │ │ │ │ ├── main.jelly │ │ │ │ ├── index.jelly │ │ │ │ ├── config_fr.properties │ │ │ │ ├── config_it.properties │ │ │ │ ├── config_ja.properties │ │ │ │ └── config.jelly │ │ │ │ ├── jobCell.properties │ │ │ │ ├── stats │ │ │ │ ├── StatSlaves │ │ │ │ │ ├── portlet.jelly │ │ │ │ │ ├── main.jelly │ │ │ │ │ ├── statagents.jelly │ │ │ │ │ ├── poller.js │ │ │ │ │ └── statagents_ja.properties │ │ │ │ ├── StatBuilds │ │ │ │ │ ├── statbuilds_fr.properties │ │ │ │ │ ├── statbuilds.properties │ │ │ │ │ ├── statbuilds_el.properties │ │ │ │ │ ├── main.jelly │ │ │ │ │ ├── statbuilds_ja.properties │ │ │ │ │ ├── portlet.jelly │ │ │ │ │ └── statbuilds.jelly │ │ │ │ └── StatJobs │ │ │ │ │ ├── statjobs_fr.properties │ │ │ │ │ ├── statjobs.properties │ │ │ │ │ ├── statjobs_ja.properties │ │ │ │ │ ├── main.jelly │ │ │ │ │ ├── portlet.jelly │ │ │ │ │ └── statjobs.jelly │ │ │ │ ├── jobLink.jelly │ │ │ │ ├── Messages.properties │ │ │ │ ├── Messages_ja.properties │ │ │ │ ├── decorate_ja.properties │ │ │ │ ├── decorate-plain.jelly │ │ │ │ ├── decorate.jelly │ │ │ │ ├── portlet.css │ │ │ │ ├── jobCell.jelly │ │ │ │ ├── decorate-table.jelly │ │ │ │ └── title.jelly │ │ └── index.jelly │ ├── webapp │ │ ├── help │ │ │ ├── help-configPortletWidth_ja.html │ │ │ ├── help-configPortletWidth.html │ │ │ ├── help-configDivStyle.html │ │ │ ├── help-configTestTrendDateshift.html │ │ │ └── help-configUrl.html │ │ ├── css │ │ │ └── full_screen.css │ │ └── js │ │ │ └── dashboard-view.js │ └── java │ │ └── hudson │ │ └── plugins │ │ └── view │ │ └── dashboard │ │ ├── test │ │ ├── TestResultSummary.java │ │ ├── TestResult.java │ │ ├── LocalDateLabel.java │ │ ├── TestUtil.java │ │ └── TestStatisticsChart.java │ │ ├── core │ │ ├── HudsonStdJobsPortlet.java │ │ ├── JobsPortlet.java │ │ ├── ImagePortlet.java │ │ └── UnstableJobsPortlet.java │ │ ├── DashboardLog.java │ │ ├── DashboardPortlet.java │ │ ├── stats │ │ ├── StatBuilds.java │ │ ├── StatSlaves.java │ │ └── StatJobs.java │ │ └── builds │ │ └── LatestBuilds.java └── test │ ├── resources │ └── hudson │ │ └── plugins │ │ └── view │ │ └── dashboard │ │ ├── test │ │ └── maven-unit-failure.zip │ │ ├── casc_image_backcompat_export.yml │ │ ├── test_failure.xml │ │ ├── casc_image_backcompat_import.yml │ │ ├── casc-export.yml │ │ └── casc.yml │ └── java │ └── hudson │ └── plugins │ └── view │ └── dashboard │ ├── test │ ├── TestSummaryForMavenJobs.java │ ├── TestSummaryForMatrixJobs.java │ └── TestTrendChartTest.java │ ├── stats │ └── StatBuildsTest.java │ ├── core │ └── ImagePortletTest.java │ ├── DashboardViewTest.java │ ├── builds │ └── LatestBuildsTest.java │ └── ConfigurationAsCodeBackCompatTest.java ├── .git-blame-ignore-revs ├── .gitignore ├── .mvn ├── maven.config └── extensions.xml ├── .editorconfig ├── Jenkinsfile ├── LICENSE └── Implementation-guide.md /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | -------------------------------------------------------------------------------- /.github/release-drafter.yml: -------------------------------------------------------------------------------- 1 | --- 2 | _extends: .github 3 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/taglib: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @jenkinsci/dashboard-view-plugin-developers 2 | -------------------------------------------------------------------------------- /.git-blame-ignore-revs: -------------------------------------------------------------------------------- 1 | # Initial spotless reformat 2 | 32d3ce165740f80f9623486d006b99eb2eb6763f 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /*.iml 2 | /.classpath 3 | /.idea/ 4 | /.project 5 | /.settings/ 6 | /target/ 7 | /work/ 8 | -------------------------------------------------------------------------------- /.mvn/maven.config: -------------------------------------------------------------------------------- 1 | -Pconsume-incrementals 2 | -Pmight-produce-incrementals 3 | -Dchangelist.format=%d.v%s 4 | -------------------------------------------------------------------------------- /.github/create-view.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/dashboard-view-plugin/HEAD/.github/create-view.png -------------------------------------------------------------------------------- /src/main/webapp/help/help-configPortletWidth_ja.html: -------------------------------------------------------------------------------- 1 |
2 | 単位(50%, 300pxなど)を含むCSS属性を用いて幅を指定してください。 3 |
4 | -------------------------------------------------------------------------------- /.github/configure-view.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/dashboard-view-plugin/HEAD/.github/configure-view.png -------------------------------------------------------------------------------- /src/main/webapp/help/help-configPortletWidth.html: -------------------------------------------------------------------------------- 1 |
2 | Specify the width as the CSS attribute, including the unit (50%, 300px) 3 |
4 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/Dashboard/newViewDetail.jelly: -------------------------------------------------------------------------------- 1 | 2 |
3 | ${%blurb} 4 |
-------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/core/ImagePortlet/portlet_de.properties: -------------------------------------------------------------------------------- 1 | Display\ error\:\ Image\ URL\ is\ invalid=Anzeigefehler: Die Bild-URL ist ung\u00FCltig 2 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/Dashboard/newViewDetail.properties: -------------------------------------------------------------------------------- 1 | blurb=\ 2 | Customizable view that contains various portlets containing information about your job(s) -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/core/UnstableJobsPortlet/portlet.properties: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: \u00A9 2023 TobiX 2 | # SPDX-License-Identifier: MIT 3 | 4 | -------------------------------------------------------------------------------- /src/main/webapp/css/full_screen.css: -------------------------------------------------------------------------------- 1 | #side-panel, #top-panel, #footer, #top-nav, #view-message, #viewList { 2 | display: none; 3 | } 4 | 5 | #main-panel { 6 | margin-left: 0 !important; 7 | } 8 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/builds/LatestBuilds/config_ja.properties: -------------------------------------------------------------------------------- 1 | Display\ name=\u540d\u79f0 2 | Number\ of\ builds\ to\ use=\u4f7f\u7528\u3059\u308b\u30d3\u30eb\u30c9\u306e\u6570 3 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/jobCell_ja.properties: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: \u00A9 2012 Seiji Sogabe 2 | # SPDX-License-Identifier: MIT 3 | Schedule_a_task=\u30D3\u30EB\u30C9\u5B9F\u884C 4 | -------------------------------------------------------------------------------- /src/test/resources/hudson/plugins/view/dashboard/test/maven-unit-failure.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/dashboard-view-plugin/HEAD/src/test/resources/hudson/plugins/view/dashboard/test/maven-unit-failure.zip -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/test/TestStatisticsPortlet/teststatistics_ja.properties: -------------------------------------------------------------------------------- 1 | Job=\u30b8\u30e7\u30d6 2 | Success=\u6210\u529f 3 | Failed=\u5931\u6557 4 | Skipped=\u30b9\u30ad\u30c3\u30d7 5 | Total=\u5408\u8a08 6 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/core/JobsPortlet/config_ja.properties: -------------------------------------------------------------------------------- 1 | Display\ name=\u540d\u79f0 2 | Number\ of\ columns=\u30ab\u30e9\u30e0\u6570 3 | Fill\ column\ first=\u5217\u304b\u3089\u30b8\u30e7\u30d6\u3092\u8868\u793a 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/core/UnstableJobsPortlet/portlet_ja.properties: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: \u00A9 2012 Seiji Sogabe 2 | # SPDX-License-Identifier: MIT 3 | No\ unstable\ jobs=\u4E0D\u5B89\u5B9A\u30D3\u30EB\u30C9\u306A\u3057 4 | 5 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # See https://EditorConfig.org 2 | root = true 3 | 4 | [*] 5 | end_of_line = lf 6 | insert_final_newline = true 7 | trim_trailing_whitespace = true 8 | charset = utf-8 9 | 10 | [*.{html,java,jelly,xml}] 11 | indent_style = space 12 | indent_size = 2 13 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "maven" 4 | directory: "/" 5 | schedule: 6 | interval: "weekly" 7 | - package-ecosystem: "github-actions" 8 | directory: "/" 9 | schedule: 10 | interval: "weekly" 11 | -------------------------------------------------------------------------------- /src/main/webapp/help/help-configDivStyle.html: -------------------------------------------------------------------------------- 1 | Value form this field will be used as a style attribute of the <div> element 2 | surrounding iframe. The main purpose of this field is to adjust size of the <div> 3 | (embedded iframe will autoadjust to the <div> size). -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/DashboardPortlet/main.jelly: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/jobCell.properties: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: \u00A9 2023 TobiX 2 | # SPDX-License-Identifier: MIT 3 | Task_scheduled={0} scheduled 4 | Schedule_a_task=Schedule a {1} for {0} 5 | Schedule_a_task_with_parameters=Schedule a {1} with parameters for {0} 6 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/Dashboard/newViewDetail_ja.properties: -------------------------------------------------------------------------------- 1 | blurb=\ 2 | \u30b8\u30e7\u30d6\u306e\u60c5\u5831\u3092\u542b\u3080\u69d8\u3005\u306a\u30dd\u30fc\u30c8\u30ec\u30c3\u30c8\u3092\u30ab\u30b9\u30bf\u30de\u30a4\u30ba\u3057\u3066\u914d\u7f6e\u3067\u304d\u308b\u30d3\u30e5\u30fc\u3067\u3059\u3002 3 | -------------------------------------------------------------------------------- /src/main/resources/index.jelly: -------------------------------------------------------------------------------- 1 | 6 | 7 |
8 | Customizable dashboard that can present various views of job information. 9 |
-------------------------------------------------------------------------------- /src/main/webapp/help/help-configTestTrendDateshift.html: -------------------------------------------------------------------------------- 1 | Value of this field will be used to shift the UTC-Timestamp of the corresponding jobs in minutes:
2 | value = 0: no shift (default)
3 | value > 0: all jobs will be seemed to happened value minutes earlier (shift on the day before)
4 | value < 0: all jobs analogous seemed to happened later (shift on the next day) -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/stats/StatSlaves/portlet.jelly: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/main/webapp/help/help-configUrl.html: -------------------------------------------------------------------------------- 1 | Value form this field will be used as a src attribute of the <iframe> element. 2 | Contents from that url will be presented inside portlet.
3 | In this field you can use the following placeholders:
4 | ${viewName} - will be replaced by the name of the view
5 | ${jobsList} - will be replaced by comma-delimited list of the jobs' names from the view -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/stats/StatSlaves/main.jelly: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.mvn/extensions.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | io.jenkins.tools.incrementals 4 | git-changelist-maven-extension 5 | 1.13 6 | 7 | 8 | -------------------------------------------------------------------------------- /.github/workflows/cd.yaml: -------------------------------------------------------------------------------- 1 | # Note: additional setup is required, see https://www.jenkins.io/redirect/continuous-delivery-of-plugins 2 | 3 | name: cd 4 | on: 5 | workflow_dispatch: 6 | check_run: 7 | types: 8 | - completed 9 | 10 | jobs: 11 | maven-cd: 12 | uses: jenkins-infra/github-reusable-workflows/.github/workflows/maven-cd.yml@v1 13 | secrets: 14 | MAVEN_USERNAME: ${{ secrets.MAVEN_USERNAME }} 15 | MAVEN_TOKEN: ${{ secrets.MAVEN_TOKEN }} 16 | -------------------------------------------------------------------------------- /Jenkinsfile: -------------------------------------------------------------------------------- 1 | /* 2 | See the documentation for more options: 3 | https://github.com/jenkins-infra/pipeline-library/ 4 | */ 5 | buildPlugin( 6 | forkCount: '1C', // run this number of tests in parallel for faster feedback. If the number terminates with a 'C', the value will be multiplied by the number of available CPU cores 7 | useContainerAgent: true, // Set to `false` if you need to use Docker for containerized tests 8 | configurations: [ 9 | [platform: 'linux', jdk: 25], 10 | [platform: 'windows', jdk: 21], 11 | ]) 12 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/DashboardPortlet/index.jelly: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/core/buildbutton.js: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: © 2023 TobiX 2 | // SPDX-License-Identifier: MIT 3 | 4 | Behaviour.specify( 5 | ".dashboard-view-job-portlet-build-button", 6 | "build-button", 7 | 0, 8 | function (e) { 9 | var url = e.getAttribute("href"); 10 | var message = e.getAttribute("data-notification"); 11 | 12 | e.onclick = function () { 13 | fetch(url, { 14 | method: "post", 15 | headers: crumb.wrap({}), 16 | }); 17 | hoverNotification(message, this, -100); 18 | return false; 19 | }; 20 | } 21 | ); 22 | -------------------------------------------------------------------------------- /src/test/resources/hudson/plugins/view/dashboard/casc_image_backcompat_export.yml: -------------------------------------------------------------------------------- 1 | dashboard: 2 | columns: 3 | - "status" 4 | - "weather" 5 | - "jobName" 6 | - "lastSuccess" 7 | - "lastFailure" 8 | - "lastDuration" 9 | - "buildButton" 10 | hideJenkinsPanels: true 11 | includeRegex: ".*" 12 | includeStdJobList: true 13 | leftPortlets: 14 | - imagePortlet: 15 | imageUrl: "test-backcompat" 16 | name: "Image" 17 | name: "test" 18 | recurse: true 19 | topPortlets: 20 | - statSlaves: 21 | name: "Agent statistics" 22 | - statBuilds: 23 | name: "Build statistics" 24 | - latestBuilds: 25 | name: "Latest builds" 26 | numBuilds: 10 27 | useCssStyle: true 28 | -------------------------------------------------------------------------------- /.github/workflows/jenkins-security-scan.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: Jenkins Security Scan 3 | 4 | on: 5 | push: 6 | branches: 7 | - main 8 | pull_request: 9 | types: [ opened, synchronize, reopened ] 10 | workflow_dispatch: 11 | 12 | permissions: 13 | security-events: write 14 | contents: read 15 | actions: read 16 | 17 | jobs: 18 | security-scan: 19 | uses: jenkins-infra/jenkins-security-scan/.github/workflows/jenkins-security-scan.yaml@v2 20 | with: 21 | java-cache: 'maven' # Optionally enable use of a build dependency cache. Specify 'maven' or 'gradle' as appropriate. 22 | # java-version: 21 # Optionally specify what version of Java to set up for the build, or remove to use a recent default. 23 | -------------------------------------------------------------------------------- /src/test/resources/hudson/plugins/view/dashboard/test_failure.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | detail message 9 | 10 | 11 | 12 | 14 | 16 | 17 | -------------------------------------------------------------------------------- /src/main/java/hudson/plugins/view/dashboard/test/TestResultSummary.java: -------------------------------------------------------------------------------- 1 | package hudson.plugins.view.dashboard.test; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class TestResultSummary extends TestResult { 7 | 8 | private final List testResults = new ArrayList<>(); 9 | 10 | public TestResultSummary() { 11 | super(null, 0, 0, 0); 12 | } 13 | 14 | public TestResultSummary addTestResult(TestResult testResult) { 15 | testResults.add(testResult); 16 | 17 | tests += testResult.getTests(); 18 | success += testResult.getSuccess(); 19 | failed += testResult.getFailed(); 20 | skipped += testResult.getSkipped(); 21 | 22 | return this; 23 | } 24 | 25 | public List getTestResults() { 26 | return testResults; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/core/JobsPortlet/portlet.jelly: -------------------------------------------------------------------------------- 1 | 7 | 8 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/main/java/hudson/plugins/view/dashboard/core/HudsonStdJobsPortlet.java: -------------------------------------------------------------------------------- 1 | package hudson.plugins.view.dashboard.core; 2 | 3 | import hudson.Extension; 4 | import hudson.model.Descriptor; 5 | import hudson.plugins.view.dashboard.DashboardPortlet; 6 | import hudson.plugins.view.dashboard.Messages; 7 | import org.kohsuke.stapler.DataBoundConstructor; 8 | 9 | /** 10 | * Portlet displays standard Jenkins job list 11 | * 12 | * @author marco.ambu 13 | */ 14 | public class HudsonStdJobsPortlet extends DashboardPortlet { 15 | 16 | @DataBoundConstructor 17 | public HudsonStdJobsPortlet(String name) { 18 | super(name); 19 | } 20 | 21 | @Extension 22 | public static class DescriptorImpl extends Descriptor { 23 | 24 | @Override 25 | public String getDisplayName() { 26 | return Messages.Dashboard_JenkinsJobsList(); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/jobLink.jelly: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Deprecated. Use lib/hudson/jobLink instead. 5 | 6 | Job object to be displayed. 7 | 8 | 9 | 10 | 12 | ${job.iconColor.description} 15 | ${job.buildHealth.description} 18 | 19 | ${job.fullDisplayName} 20 | 21 | -------------------------------------------------------------------------------- /src/test/resources/hudson/plugins/view/dashboard/casc_image_backcompat_import.yml: -------------------------------------------------------------------------------- 1 | --- 2 | configuration-as-code: 3 | deprecated: warn 4 | jenkins: 5 | views: 6 | - dashboard: 7 | name: "test" 8 | columns: 9 | - "status" 10 | - "weather" 11 | - "jobName" 12 | - "lastSuccess" 13 | - "lastFailure" 14 | - "lastDuration" 15 | - "buildButton" 16 | recurse: true 17 | includeRegex: ".*" 18 | includeStdJobList: true 19 | hideJenkinsPanels: true 20 | useCssStyle: true 21 | leftPortletWidth: "50%" 22 | rightPortletWidth: "50%" 23 | topPortlets: 24 | - statSlaves: 25 | name: "Agent statistics" 26 | - statBuilds: 27 | name: "Build statistics" 28 | - latestBuilds: 29 | name: "Latest builds" 30 | numBuilds: 10 31 | leftPortlets: 32 | - imagePortlet: 33 | name: "Image" 34 | url: "test-backcompat" 35 | -------------------------------------------------------------------------------- /src/main/java/hudson/plugins/view/dashboard/DashboardLog.java: -------------------------------------------------------------------------------- 1 | package hudson.plugins.view.dashboard; 2 | 3 | import java.util.logging.Level; 4 | import java.util.logging.Logger; 5 | 6 | /** 7 | * 8 | * @author Marco Ambu 9 | */ 10 | public class DashboardLog { 11 | 12 | private static String loggerName = "DashboardView"; 13 | 14 | public static void debug(String component, String msg) { 15 | Logger l = Logger.getLogger(loggerName); 16 | l.log(Level.FINEST, "[" + component + "] " + msg); 17 | } 18 | 19 | public static void info(String component, String msg) { 20 | Logger l = Logger.getLogger(loggerName); 21 | l.log(Level.INFO, "[" + component + "] " + msg); 22 | } 23 | 24 | public static void warning(String component, String msg) { 25 | Logger l = Logger.getLogger(loggerName); 26 | l.log(Level.WARNING, "[" + component + "] " + msg); 27 | } 28 | 29 | public static void error(String component, String msg) { 30 | Logger l = Logger.getLogger(loggerName); 31 | l.log(Level.SEVERE, "[" + component + "] " + msg); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2009-2010 Peter Hayes 2 | Copyright (c) 2010-2016 Marco Ambu 3 | Copyright (c) 2018-2024 TobiX 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 9 | of the Software, and to permit persons to whom the Software is furnished to do 10 | so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/core/UnstableJobsPortlet/portlet.jelly: -------------------------------------------------------------------------------- 1 | 7 | 8 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | ${%No unstable jobs} 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/stats/StatSlaves/statagents.jelly: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | ${%Agents} 9 | ${%Online agents} 10 | ${%Offline agents} 11 | ${%Disconnected agents} 12 | ${%Tasks in queue} 13 | ${%Running jobs} 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 |
23 | 24 | 25 |
26 | 27 | 28 |
29 | 30 | 31 |
32 | 33 | 34 |
35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/core/ImagePortlet/config_ja.properties: -------------------------------------------------------------------------------- 1 | # The MIT License 2 | # 3 | # Copyright (c) 2012, Seiji Sogabe 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in 13 | # all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | # THE SOFTWARE. 22 | 23 | Display\ name=\u540d\u79f0 -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/DashboardPortlet/config_fr.properties: -------------------------------------------------------------------------------- 1 | # The MIT License 2 | # 3 | # Copyright (c) 2004-2010, Sun Microsystems, Inc. 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in 13 | # all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | # THE SOFTWARE. 22 | 23 | Display\ name=Nom 24 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/DashboardPortlet/config_it.properties: -------------------------------------------------------------------------------- 1 | # The MIT License 2 | # 3 | # Copyright (c) 2004-2010, Sun Microsystems, Inc. 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in 13 | # all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | # THE SOFTWARE. 22 | 23 | Display\ name=Nome visualizzato 24 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/DashboardPortlet/config_ja.properties: -------------------------------------------------------------------------------- 1 | # The MIT License 2 | # 3 | # Copyright (c) 2004-2010, Sun Microsystems, Inc. 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in 13 | # all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | # THE SOFTWARE. 22 | 23 | Display\ name=\u540d\u79f0 24 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/core/UnstableJobsPortlet/portlet_fr.properties: -------------------------------------------------------------------------------- 1 | # The MIT License 2 | # 3 | # Copyright (c) 2004-2010, Sun Microsystems, Inc. 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in 13 | # all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | # THE SOFTWARE. 22 | 23 | No\ unstable\ jobs=Pas de jobs instables 24 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/test/TestTrendChart/main_ja.properties: -------------------------------------------------------------------------------- 1 | #MIT License 2 | # 3 | # Copyright (c) 2012, Seiji Sogabe 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in 13 | # all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | # THE SOFTWARE. 22 | 23 | Test\ Summary\ graph=\u30c6\u30b9\u30c8\u63a8\u79fb\u30b0\u30e9\u30d5 24 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/test/TestTrendChart/portlet_ja.properties: -------------------------------------------------------------------------------- 1 | #MIT License 2 | # 3 | # Copyright (c) 2012, Seiji Sogabe 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in 13 | # all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | # THE SOFTWARE. 22 | 23 | Test\ Summary\ graph=\u30c6\u30b9\u30c8\u63a8\u79fb\u30b0\u30e9\u30d5 24 | -------------------------------------------------------------------------------- /src/main/webapp/js/dashboard-view.js: -------------------------------------------------------------------------------- 1 | function togglePortlet(portlet, show) 2 | { 3 | let content = portlet.querySelector(".dbv-portlet__content"); 4 | let collapse = portlet.querySelector(".dbv-portlet__title-button--collapse"); 5 | let expand = portlet.querySelector(".dbv-portlet__title-button--expand"); 6 | if (show) { 7 | content.classList.remove("jenkins-hidden"); 8 | expand.classList.add("jenkins-hidden"); 9 | collapse.classList.remove("jenkins-hidden"); 10 | } else { 11 | content.classList.add("jenkins-hidden"); 12 | expand.classList.remove("jenkins-hidden"); 13 | collapse.classList.add("jenkins-hidden"); 14 | } 15 | } 16 | 17 | Behaviour.specify(".dbv-portlet__title-button--maximize", "dbv-maximize", 0, function(cmd) { 18 | cmd.classList.remove("jenkins-hidden"); 19 | }); 20 | 21 | Behaviour.specify(".dbv-portlet__title-button--collapse", "dbv-collapse", 0, function(cmd) { 22 | let portlet = cmd.closest(".dbv-portlet"); 23 | cmd.onclick = function() { 24 | togglePortlet(portlet, false); 25 | } 26 | cmd.classList.remove("jenkins-hidden") 27 | }); 28 | 29 | Behaviour.specify(".dbv-portlet__title-button--expand", "dbv-expand", 0, function(cmd) { 30 | let portlet = cmd.closest(".dbv-portlet"); 31 | cmd.onclick = function() { 32 | togglePortlet(portlet, true); 33 | } 34 | }); 35 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/builds/LatestBuilds/latestbuilds_nl.properties: -------------------------------------------------------------------------------- 1 | # The MIT License 2 | # 3 | # Copyright (c) 2004-2010, Sun Microsystems, Inc. 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in 13 | # all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | # THE SOFTWARE. 22 | 23 | Build\ name=Job 24 | Build\ status=Bouwpoging 25 | Build\ time=Tijd 26 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/Messages.properties: -------------------------------------------------------------------------------- 1 | Dashboard.JobStatistics=Job statistics 2 | Dashboard.BuildStatistics=Build statistics 3 | Dashboard.Success=success 4 | Dashboard.Skipped=skipped 5 | Dashboard.Failed=failed 6 | Dashboard.NoDataAvailable=No data available 7 | Dashboard.TestStatisticsChart=Test Statistics Chart 8 | Dashboard.DisplayName=Dashboard 9 | Dashboard.LatestBuilds=Latest builds 10 | Dashboard.JenkinsJobsList=Jenkins jobs list 11 | Dashboard.JobsGrid=Jobs Grid 12 | Dashboard.UnstableJobs=Unstable Jobs 13 | Dashboard.NoRecentBuildsFailed=No recent builds failed 14 | Dashboard.RecentBuildsFailed={0}-{1}% of recent builds failed 15 | Dashboard.AllRecentBuildsFailed=All recent builds failed 16 | Dashboard.UnknownStatus=Unknown status 17 | Dashboard.TestStatisticsGrid=Test Statistics Grid 18 | Dashboard.TestTrendChart=Test Trend Chart 19 | Dashboard.Total=total 20 | Dashboard.Date=date 21 | Dashboard.Count=count 22 | Dashboard.AgentStatistics=Agent statistics 23 | Dashboard.Image=Image 24 | Dashboard.ImageUrlEmpty=Image URL should not be empty. 25 | Dashboard.ImageUrlInvalid=Image URL is invalid: {0} 26 | Dashboard.ImageUrlHttp=Image URL must be http or https. 27 | Dashboard.IframePortlet=Iframe Portlet 28 | Dashboard.UrlEmpty=URL should not be empty. 29 | Dashboard.UrlInvalid=URL is invalid: {0} 30 | Dashboard.UrlHttp=URL must be http or https. 31 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/builds/LatestBuilds/latestbuilds_it.properties: -------------------------------------------------------------------------------- 1 | # The MIT License 2 | # 3 | # Copyright (c) 2004-2010, Sun Microsystems, Inc. 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in 13 | # all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | # THE SOFTWARE. 22 | 23 | Build\ name=Job 24 | Build\ status=Stato del build 25 | Build\ time=Data e ora 26 | -------------------------------------------------------------------------------- /src/main/java/hudson/plugins/view/dashboard/test/TestResult.java: -------------------------------------------------------------------------------- 1 | package hudson.plugins.view.dashboard.test; 2 | 3 | import hudson.model.Job; 4 | 5 | public class TestResult { 6 | 7 | private final Job job; 8 | protected int tests; 9 | protected int success; 10 | protected int failed; 11 | protected int skipped; 12 | 13 | public TestResult(Job job, int tests, int failed, int skipped) { 14 | super(); 15 | this.job = job; 16 | this.tests = tests; 17 | this.failed = failed; 18 | this.skipped = skipped; 19 | 20 | this.success = tests - failed - skipped; 21 | } 22 | 23 | public Job getJob() { 24 | return job; 25 | } 26 | 27 | public int getTests() { 28 | return tests; 29 | } 30 | 31 | public int getSuccess() { 32 | return success; 33 | } 34 | 35 | public double getSuccessPct() { 36 | return tests != 0 ? ((double) success / tests) : 0d; 37 | } 38 | 39 | public int getFailed() { 40 | return failed; 41 | } 42 | 43 | public double getFailedPct() { 44 | return tests != 0 ? ((double) failed / tests) : 0d; 45 | } 46 | 47 | public int getSkipped() { 48 | return skipped; 49 | } 50 | 51 | public double getSkippedPct() { 52 | return tests != 0 ? ((double) skipped / tests) : 0d; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/test/TestTrendChart/config.properties: -------------------------------------------------------------------------------- 1 | # The MIT License 2 | # 3 | # Copyright (c) 2004-2010, Sun Microsystems, Inc. 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in 13 | # all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | # THE SOFTWARE. 22 | 23 | Number\ of\ latest\ days\ to\ display=Number of (latest) days to display 24 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/test/TestStatisticsPortlet/portlet_nl.properties: -------------------------------------------------------------------------------- 1 | # The MIT License 2 | # 3 | # Copyright (c) 2004-2010, Sun Microsystems, Inc. 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in 13 | # all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | # THE SOFTWARE. 22 | 23 | Failed=Gefaald 24 | Job=Job 25 | Skipped=Overgeslagen 26 | Success=Succes 27 | Total=Totaal 28 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/builds/LatestBuilds/latestbuilds.properties: -------------------------------------------------------------------------------- 1 | # The MIT License 2 | # 3 | # Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Seiji Sogabe 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in 13 | # all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | # THE SOFTWARE. 22 | 23 | Build\ name=Job 24 | Build\ status=Build 25 | Build\ time=Time 26 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/stats/StatBuilds/statbuilds_fr.properties: -------------------------------------------------------------------------------- 1 | # The MIT License 2 | # 3 | # Copyright (c) 2004-2010, Sun Microsystems, Inc. 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in 13 | # all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | # THE SOFTWARE. 22 | 23 | All\ builds=Tous les builds 24 | Status=\u00C9tats 25 | Status\ of\ the\ build=\u00C9tat de la build 26 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/test/TestStatisticsPortlet/portlet_sv_SE.properties: -------------------------------------------------------------------------------- 1 | # The MIT License 2 | # 3 | # Copyright (c) 2004-2010, Sun Microsystems, Inc. 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in 13 | # all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | # THE SOFTWARE. 22 | 23 | Failed=Misslyckade 24 | Job=Jobb 25 | Skipped=\u00D6verhoppade 26 | Success=Lyckades 27 | Total=Totalt 28 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/test/TestStatisticsPortlet/portlet_fr.properties: -------------------------------------------------------------------------------- 1 | # The MIT License 2 | # 3 | # Copyright (c) 2004-2010, Sun Microsystems, Inc. 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in 13 | # all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | # THE SOFTWARE. 22 | 23 | Failed=\u00C9chou\u00E9s 24 | Job=Job 25 | Skipped=Non lanc\u00E9s 26 | Success=R\u00E9ussis 27 | Total=Total 28 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/Dashboard/newViewDetail_fr.properties: -------------------------------------------------------------------------------- 1 | # The MIT License 2 | # 3 | # Copyright (c) 2004-2010, Sun Microsystems, Inc. 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in 13 | # all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | # THE SOFTWARE. 22 | 23 | blurb=Vue personnalisable qui peut afficher une vari\u00E9t\u00E9 de Portlets offrant diff\u00E9rentes informations sur vos travaux. 24 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/core/UnstableJobsPortlet/portlet_el.properties: -------------------------------------------------------------------------------- 1 | # The MIT License 2 | # 3 | # Copyright (c) 2004-2010, Sun Microsystems, Inc. 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in 13 | # all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | # THE SOFTWARE. 22 | 23 | No\ unstable\ jobs=\u0394\u03B5\u03BD \u03C5\u03C0\u03AC\u03C1\u03C7\u03BF\u03C5\u03BD "\u03C3\u03C0\u03B1\u03C3\u03BC\u03AD\u03BD\u03B1" builds 24 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/builds/LatestBuilds/latestbuilds_ja.properties: -------------------------------------------------------------------------------- 1 | # The MIT License 2 | # 3 | # Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Seiji Sogabe 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in 13 | # all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | # THE SOFTWARE. 22 | 23 | Build\ name=\u30b8\u30e7\u30d6 24 | Build\ status=\u30d3\u30eb\u30c9 25 | Build\ time=\u6642\u523b 26 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/stats/StatJobs/statjobs_fr.properties: -------------------------------------------------------------------------------- 1 | # The MIT License 2 | # 3 | # Copyright (c) 2004-2010, Sun Microsystems, Inc. 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in 13 | # all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | # THE SOFTWARE. 22 | 23 | All\ projects=Tous les jobs 24 | Description=Description 25 | Number\ of\ projects=Nombre de jobs 26 | Project\ health=Sant\u00E9 des jobs 27 | Total\ projects=Total des jobs 28 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/test/TestStatisticsPortlet/portlet_ja.properties: -------------------------------------------------------------------------------- 1 | # The MIT License 2 | # 3 | # Copyright (c) 2004-2010, Sun Microsystems, Inc. 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in 13 | # all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | # THE SOFTWARE. 22 | 23 | Failed=\u5931\u6557 24 | Success=\u6210\u529f 25 | Total=\u7dcf\u8a08 26 | Job=\u30b8\u30e7\u30d6 27 | Skipped=\u30b9\u30ad\u30c3\u30d7 28 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/stats/StatSlaves/poller.js: -------------------------------------------------------------------------------- 1 | let err = 0; 2 | function repeat() { 3 | buildStat.getStats(function(t) { 4 | let tables = document.querySelectorAll(".dbv-agents-table"); 5 | for (let table of tables) { 6 | let tableId = table.id; 7 | if (t.status === 200) { 8 | err = 0; 9 | let stats = t.responseObject(); 10 | document.getElementById('agents-' + tableId).innerText = stats.agents; 11 | document.getElementById('onlineAgents-' + tableId).innerText = stats.onlineAgents; 12 | document.getElementById('offlineAgents-' + tableId).innerText = stats.offlineAgents; 13 | document.getElementById('disconnectedAgents-' + tableId).innerText = stats.disconnectedAgents; 14 | document.getElementById('tasksInQueue-' + tableId).innerText = stats.tasksInQueue; 15 | document.getElementById('runningJobs-' + tableId).innerText = stats.runningJobs; 16 | } else if (t.status === 503 || t.status === 0) { 17 | // Consider these recoverable and don't update error count 18 | document.getElementById('runningJobs-' + tableId).innerText = 'ERR-' + 19 | (t.status === 0)? 'OFFLINE' : 'PROXY'; 20 | } else { 21 | err++; 22 | document.getElementById('runningJobs-' + tableId).innerText = 'ERR-' + err; 23 | } 24 | } 25 | 26 | if (err < 5) { 27 | setTimeout(repeat, 2500); 28 | } 29 | }); 30 | } 31 | repeat(); 32 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/Dashboard/newViewDetail_ko.properties: -------------------------------------------------------------------------------- 1 | # The MIT License 2 | # 3 | # Copyright (c) 2004-2010, Sun Microsystems, Inc. 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in 13 | # all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | # THE SOFTWARE. 22 | 23 | blurb=\uC8FC\uBB38\uC81C\uC791 \uB41C \uC870\uD68C\uB294 \uC791\uC5C5\uC5D0 \uB300\uD55C \uC815\uBCF4\uB97C \uD3EC\uD568\uD55C \uB9CE\uC740 \uD3EC\uD2C0\uB9BF\uB4E4\uC744 \uD3EC\uD568. 24 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/builds/LatestBuilds/latestbuilds_el.properties: -------------------------------------------------------------------------------- 1 | # The MIT License 2 | # 3 | # Copyright (c) 2004-2010, Sun Microsystems, Inc. 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in 13 | # all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | # THE SOFTWARE. 22 | 23 | Build\ name=Project / \u0395\u03C1\u03B3\u03B1\u03C3\u03AF\u03B1 24 | Build\ status=Build 25 | Build\ time=\u0397\u03BC\u03B5\u03C1\u03BF\u03BC\u03B7\u03BD\u03AF\u03B1 & \u038F\u03C1\u03B1 26 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/stats/StatJobs/statjobs.properties: -------------------------------------------------------------------------------- 1 | # The MIT License 2 | # 3 | # Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Seiji Sogabe 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in 13 | # all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | # THE SOFTWARE. 22 | 23 | ProjectStat=Job Statistics 24 | Project\ health=Job health 25 | Description=Description 26 | Number\ of\ projects=Number of jobs 27 | Total\ projects=Total jobs 28 | All\ projects=All jobs 29 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/builds/LatestBuilds/latestbuilds.jelly: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | ${%Build name} 7 | ${%Build status} 8 | ${%Build time} 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 |
18 | 19 | 20 | 28 | 29 | ${it.getTimestampString(build)} 30 | 31 |
32 | 33 |
34 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/stats/StatBuilds/statbuilds.properties: -------------------------------------------------------------------------------- 1 | # The MIT License 2 | # 3 | # Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Seiji Sogabe 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in 13 | # all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | # THE SOFTWARE. 22 | 23 | BuildStat=Build Statistics 24 | Status\ of\ the\ build=Status of the build 25 | Number\ of\ builds\ with\ status=Number of builds 26 | Total\ builds = Total builds 27 | All\ builds=All builds 28 | 29 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/test/TestStatisticsPortlet/config_ja.properties: -------------------------------------------------------------------------------- 1 | # The MIT License 2 | # 3 | # Copyright (c) 2012, Seiji Sogabe 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in 13 | # all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | # THE SOFTWARE. 22 | 23 | Display\ name=\u540d\u79f0 24 | Background\ Colors=\u80cc\u666f\u8272 25 | Success\ Color=\u6210\u529f\u306e\u8272 26 | Failure\ Color=\u5931\u6557\u306e\u8272 27 | Skipped\ Color=\u30b9\u30ad\u30c3\u30d7\u306e\u8272 28 | in\ hex=16\u9032\u6570 29 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/Messages_ja.properties: -------------------------------------------------------------------------------- 1 | Dashboard.JobStatistics=\u30b8\u30e7\u30d6\u306e\u7d71\u8a08\u60c5\u5831 2 | Dashboard.BuildStatistics=\u30d3\u30eb\u30c9\u306e\u7d71\u8a08\u60c5\u5831 3 | Dashboard.Success=\u6210\u529f 4 | Dashboard.Skipped=\u30b9\u30ad\u30c3\u30d7 5 | Dashboard.Failed=\u5931\u6557 6 | Dashboard.NoDataAvailable=\u30c7\u30fc\u30bf\u306a\u3057 7 | Dashboard.TestStatisticsChart=\u30c6\u30b9\u30c8\u306e\u7d71\u8a08\u60c5\u5831(\u30b0\u30e9\u30d5) 8 | Dashboard.DisplayName=\u30c0\u30c3\u30b7\u30e5\u30dc\u30fc\u30c9 9 | Dashboard.LatestBuilds=\u6700\u65b0\u306e\u30d3\u30eb\u30c9 10 | Dashboard.JenkinsJobsList=Jenkins\u30b8\u30e7\u30d6\u30ea\u30b9\u30c8 11 | Dashboard.JobsGrid=\u30b8\u30e7\u30d6\u30b0\u30ea\u30c3\u30c9 12 | Dashboard.UnstableJobs=\u4e0d\u5b89\u5b9a\u30d3\u30eb\u30c9 13 | Dashboard.NoRecentBuildsFailed=\u6700\u8fd1\u306e\u5931\u6557\u30d3\u30eb\u30c9\u306a\u3057 14 | Dashboard.RecentBuildsFailed={0}-{1}%\u306e\u30d3\u30eb\u30c9\u304c\u5931\u6557 15 | Dashboard.AllRecentBuildsFailed=\u3059\u3079\u3066\u306e\u30d3\u30eb\u30c9\u304c\u5931\u6557 16 | Dashboard.UnknownStatus=\u30b9\u30c6\u30fc\u30bf\u30b9\u4e0d\u660e 17 | Dashboard.TestStatisticsGrid=\u30c6\u30b9\u30c8\u306e\u7d71\u8a08\u60c5\u5831(\u30b0\u30ea\u30c3\u30c9) 18 | Dashboard.TestTrendChart=\u30c6\u30b9\u30c8\u306e\u63a8\u79fb\u30b0\u30e9\u30d5 19 | Dashboard.Total=\u7dcf\u8a08 20 | Dashboard.Date=\u65e5\u4ed8 21 | Dashboard.Count=\u4ef6\u6570 22 | Dashboard.AgentStatistics=\u30b9\u30ec\u30fc\u30d6\u306e\u7d71\u8a08 23 | Dashboard.Image=\u753b\u50cf 24 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/stats/StatBuilds/statbuilds_el.properties: -------------------------------------------------------------------------------- 1 | # The MIT License 2 | # 3 | # Copyright (c) 2004-2010, Sun Microsystems, Inc. 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in 13 | # all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | # THE SOFTWARE. 22 | 23 | All\ builds=\u038C\u03BB\u03B1 \u03C4\u03B1 Builds 24 | Status=\u039A\u03B1\u03C3\u03C4\u03AC\u03C3\u03C4\u03B1\u03C3\u03B7 25 | Status\ of\ the\ build=\u039A\u03B1\u03C3\u03C4\u03AC\u03C3\u03C4\u03B1\u03C3\u03B7 Build 26 | Total\ builds=\u03A3\u03CD\u03BD\u03BF\u03BB\u03BF Builds 27 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/stats/StatSlaves/statagents_ja.properties: -------------------------------------------------------------------------------- 1 | # The MIT License 2 | # 3 | # Copyright (c) 2012, Seiji Sogabe 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in 13 | # all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | # THE SOFTWARE. 22 | 23 | Agents=\u30b9\u30ec\u30fc\u30d6 24 | Online\ agents=\u30aa\u30f3\u30e9\u30a4\u30f3 25 | Offline\ agents=\u30aa\u30d5\u30e9\u30a4\u30f3 26 | Disconnected\ agents=\u5207\u65ad\u4e2d 27 | Tasks\ in\ queue=\u30ad\u30e5\u30fc\u30a4\u30f3\u30b0\u4e2d 28 | Running\ jobs=\u30b8\u30e7\u30d6\u3092\u5b9f\u884c\u4e2d 29 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/stats/StatJobs/statjobs_ja.properties: -------------------------------------------------------------------------------- 1 | # The MIT License 2 | # 3 | # Copyright (c) 2004-2010, Sun Microsystems, Inc. 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in 13 | # all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | # THE SOFTWARE. 22 | 23 | All\ projects=\u5168\u30d7\u30ed\u30b8\u30a7\u30af\u30c8 24 | Description=\u8aac\u660e 25 | Number\ of\ projects=\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u6570 26 | Project\ health=\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u306e\u72b6\u614b 27 | Total\ projects=\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u306e\u7dcf\u6570 28 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/stats/StatJobs/main.jelly: -------------------------------------------------------------------------------- 1 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/decorate_ja.properties: -------------------------------------------------------------------------------- 1 | # The MIT License 2 | # 3 | # Copyright (c) 2004-2012, Sun Microsystems, Inc., Seiji Sogabe 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in 13 | # all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | # THE SOFTWARE. 22 | 23 | Click\ to\ collapse\ portlet=\u30dd\u30fc\u30c8\u30ec\u30c3\u30c8\u3092\u9589\u3058\u308b 24 | Click\ to\ expand\ portlet=\u30dd\u30fc\u30c8\u30ec\u30c3\u30c8\u3092\u958b\u304f 25 | Click\ to\ show\ full-screen\ portlet=\u30dd\u30fc\u30c8\u30ec\u30c3\u30c8\u3092\u30d5\u30eb\u30b9\u30af\u30ea\u30fc\u30f3\u3067\u8868\u793a 26 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/stats/StatBuilds/main.jelly: -------------------------------------------------------------------------------- 1 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/stats/StatBuilds/statbuilds_ja.properties: -------------------------------------------------------------------------------- 1 | # The MIT License 2 | # 3 | # Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Seiji Sogabe 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in 13 | # all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | # THE SOFTWARE. 22 | 23 | Status\ of\ the\ build=\u30d3\u30eb\u30c9\u30b9\u30c6\u30fc\u30bf\u30b9 24 | Number\ of\ builds\ with\ status=\u4ef6\u6570 25 | All\ builds=\u5168\u30d3\u30eb\u30c9 26 | Status=\u30b9\u30c6\u30fc\u30bf\u30b9 27 | Total\ builds=\u7dcf\u30d3\u30eb\u30c9\u6570 28 | Description=\u8aac\u660e 29 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/DashboardPortlet/config.jelly: -------------------------------------------------------------------------------- 1 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/stats/StatBuilds/portlet.jelly: -------------------------------------------------------------------------------- 1 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/stats/StatJobs/portlet.jelly: -------------------------------------------------------------------------------- 1 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/builds/LatestBuilds/portlet.jelly: -------------------------------------------------------------------------------- 1 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/test/TestStatisticsPortlet/portlet.jelly: -------------------------------------------------------------------------------- 1 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /src/test/resources/hudson/plugins/view/dashboard/casc-export.yml: -------------------------------------------------------------------------------- 1 | dashboard: 2 | bottomPortlets: 3 | - testStatisticsChart: 4 | name: "Test Statistics Chart" 5 | - testStatisticsPortlet: 6 | failureColor: "E86850" 7 | hideZeroTestProjects: false 8 | name: "Test Statistics Grid" 9 | skippedColor: "FDB813" 10 | successColor: "71E66D" 11 | useBackgroundColors: false 12 | - testTrendChart: 13 | dateRange: 0 14 | dateShift: 0 15 | displayStatus: ALL 16 | graphHeight: 220 17 | graphWidth: 300 18 | name: "Test Trend Chart" 19 | columns: 20 | - "status" 21 | - "weather" 22 | - "jobName" 23 | - "lastSuccess" 24 | - "lastFailure" 25 | - "lastDuration" 26 | - "buildButton" 27 | hideJenkinsPanels: true 28 | includeRegex: ".*" 29 | includeStdJobList: true 30 | leftPortlets: 31 | - iframePortlet: 32 | divStyle: "width:100%;height:1000px;" 33 | iframeSource: "test" 34 | name: "Iframe Portlet" 35 | - imagePortlet: 36 | imageUrl: "test" 37 | name: "Image" 38 | name: "test" 39 | recurse: true 40 | rightPortlets: 41 | - hudsonStdJobsPortlet: 42 | name: "Jenkins jobs list" 43 | - statJobs: 44 | name: "Job statistics" 45 | - jobsPortlet: 46 | columnCount: 3 47 | fillColumnFirst: false 48 | name: "Jobs Grid" 49 | - unstableJobsPortlet: 50 | name: "Unstable Jobs" 51 | recurse: false 52 | showOnlyFailedJobs: false 53 | topPortlets: 54 | - statSlaves: 55 | name: "Agent statistics" 56 | - statBuilds: 57 | name: "Build statistics" 58 | - latestBuilds: 59 | name: "Latest builds" 60 | numBuilds: 10 61 | useCssStyle: true 62 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/test/TestTrendChart/main.jelly: -------------------------------------------------------------------------------- 1 | 24 | 25 | 26 | 27 | 28 | [${%Test Summary graph}] 29 | 30 | 31 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/core/ImagePortlet/config.jelly: -------------------------------------------------------------------------------- 1 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/test/TestStatisticsChart/main.jelly: -------------------------------------------------------------------------------- 1 | 24 | 25 | 26 | 27 | 28 | [Test Summary graph] 29 | 30 | 31 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/test/TestStatisticsChart/portlet.jelly: -------------------------------------------------------------------------------- 1 | 24 | 25 | 26 | 27 | 28 |
29 | [Test Summary graph] 30 |
31 |
32 |
33 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/core/JobsPortlet/config.jelly: -------------------------------------------------------------------------------- 1 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/builds/LatestBuilds/config.jelly: -------------------------------------------------------------------------------- 1 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/core/ImagePortlet/portlet.jelly: -------------------------------------------------------------------------------- 1 | 24 | 25 | 26 | 27 | 28 | 29 | 30 |
31 | 32 |
33 |
34 | 35 |
${%Display error: Image URL is invalid}
36 |
37 |
38 |
39 |
40 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/test/TestTrendChart/config_ja.properties: -------------------------------------------------------------------------------- 1 | # The MIT License 2 | # 3 | # Copyright (c) 2004-2012, Sun Microsystems, Inc., Seiji Sogabe 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in 13 | # all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | # THE SOFTWARE. 22 | 23 | Graph\ width=\u5e45 24 | Graph\ height=\u9ad8\u3055 25 | Display\ name=\u540d\u79f0 26 | Number\ of\ latest\ days\ to\ display=\u8868\u793a\u65e5\u6570 27 | All\ tests=\u5168\u30c6\u30b9\u30c8 28 | Only\ successful\ tests=\u6210\u529f\u3057\u305f\u30c6\u30b9\u30c8\u306e\u307f 29 | Only\ failed\ tests=\u5931\u6557\u3057\u305f\u30c6\u30b9\u30c8\u306e\u307f 30 | Only\ skipped\ tests=\u30b9\u30ad\u30c3\u30d7\u3057\u305f\u30c6\u30b9\u30c8\u306e\u307f 31 | Display=\u8868\u793a\u5bfe\u8c61 -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/test/TestTrendChart/portlet.jelly: -------------------------------------------------------------------------------- 1 | 24 | 25 | 26 | 27 | 28 |
29 | [${%Test Summary graph}] 30 |
31 |
32 |
33 | -------------------------------------------------------------------------------- /src/main/java/hudson/plugins/view/dashboard/test/LocalDateLabel.java: -------------------------------------------------------------------------------- 1 | package hudson.plugins.view.dashboard.test; 2 | 3 | import java.time.LocalDate; 4 | import java.time.format.DateTimeFormatter; 5 | 6 | /** 7 | * Graph label showing the build date. 8 | * 9 | * @author Ulli Hafner 10 | */ 11 | public class LocalDateLabel implements Comparable { 12 | 13 | private static final DateTimeFormatter format = DateTimeFormatter.ofPattern("MM-dd"); 14 | 15 | private final LocalDate date; 16 | 17 | /** 18 | * Creates a new instance of {@link LocalDateLabel}. 19 | * 20 | * @param date 21 | * the date of the build 22 | */ 23 | public LocalDateLabel(final LocalDate date) { 24 | this.date = date; 25 | } 26 | 27 | /** {@inheritDoc} */ 28 | @Override 29 | public int compareTo(final LocalDateLabel o) { 30 | return date.compareTo(o.date); 31 | } 32 | 33 | /** {@inheritDoc} */ 34 | @Override 35 | public String toString() { 36 | return format.format(date); 37 | } 38 | 39 | /** {@inheritDoc} */ 40 | @Override 41 | public int hashCode() { 42 | int prime = 31; 43 | int result = 1; 44 | result = prime * result + ((date == null) ? 0 : date.hashCode()); 45 | return result; 46 | } 47 | 48 | /** {@inheritDoc} */ 49 | @Override 50 | public boolean equals(final Object obj) { 51 | if (this == obj) { 52 | return true; 53 | } 54 | if (obj == null) { 55 | return false; 56 | } 57 | if (getClass() != obj.getClass()) { 58 | return false; 59 | } 60 | LocalDateLabel other = (LocalDateLabel) obj; 61 | if (date == null) { 62 | return other.date == null; 63 | } else { 64 | return date.equals(other.date); 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/core/UnstableJobsPortlet/config.jelly: -------------------------------------------------------------------------------- 1 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/core/HudsonStdJobsPortlet/portlet.jelly: -------------------------------------------------------------------------------- 1 | 24 | 25 | 26 | 27 | 28 | 30 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /src/test/java/hudson/plugins/view/dashboard/test/TestSummaryForMavenJobs.java: -------------------------------------------------------------------------------- 1 | package hudson.plugins.view.dashboard.test; 2 | 3 | import static org.hamcrest.CoreMatchers.is; 4 | import static org.hamcrest.MatcherAssert.assertThat; 5 | 6 | import hudson.Functions; 7 | import hudson.maven.MavenModuleSet; 8 | import hudson.maven.MavenModuleSetBuild; 9 | import hudson.model.Result; 10 | import java.util.Collections; 11 | import org.junit.jupiter.api.BeforeEach; 12 | import org.junit.jupiter.api.Test; 13 | import org.jvnet.hudson.test.ExtractResourceSCM; 14 | import org.jvnet.hudson.test.JenkinsRule; 15 | import org.jvnet.hudson.test.ToolInstallations; 16 | import org.jvnet.hudson.test.junit.jupiter.WithJenkins; 17 | 18 | @WithJenkins 19 | class TestSummaryForMavenJobs { 20 | 21 | private JenkinsRule j; 22 | 23 | @BeforeEach 24 | void setUp(JenkinsRule rule) { 25 | j = rule; 26 | } 27 | 28 | @Test 29 | void summaryIncludesMavenJob() throws Exception { 30 | ToolInstallations.configureMaven35(); 31 | 32 | MavenModuleSet project = j.jenkins.createProject(MavenModuleSet.class, "maven"); 33 | project.setGoals("test"); 34 | project.setScm(new ExtractResourceSCM(getClass().getResource("maven-unit-failure.zip"))); 35 | MavenModuleSetBuild build = 36 | j.assertBuildStatus(Result.UNSTABLE, project.scheduleBuild2(0).get()); 37 | 38 | if (Functions.isWindows()) { 39 | // Allow some time for files to close, reduce test failures 40 | Thread.sleep(3307); 41 | } 42 | 43 | TestResultSummary testSummary = TestUtil.getTestResultSummary(Collections.singleton(project), false); 44 | assertThat(testSummary.getFailed(), is(2)); 45 | assertThat(testSummary.getSuccess(), is(2)); 46 | 47 | if (Functions.isWindows()) { 48 | // Allow some time for files to close, reduce test failures 49 | Thread.sleep(3307); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/core/IframePortlet/config.jelly: -------------------------------------------------------------------------------- 1 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /src/test/java/hudson/plugins/view/dashboard/stats/StatBuildsTest.java: -------------------------------------------------------------------------------- 1 | package hudson.plugins.view.dashboard.stats; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertEquals; 4 | 5 | import hudson.model.BallColor; 6 | import hudson.model.FreeStyleProject; 7 | import java.util.Collections; 8 | import java.util.Map; 9 | import org.junit.jupiter.api.BeforeEach; 10 | import org.junit.jupiter.api.Test; 11 | import org.jvnet.hudson.test.JenkinsRule; 12 | import org.jvnet.hudson.test.RunLoadCounter; 13 | import org.jvnet.hudson.test.junit.jupiter.WithJenkins; 14 | 15 | @WithJenkins 16 | class StatBuildsTest { 17 | 18 | private JenkinsRule j; 19 | 20 | @BeforeEach 21 | void setUp(JenkinsRule rule) { 22 | j = rule; 23 | } 24 | 25 | @Test 26 | void avoidEagerLoading() throws Exception { 27 | final FreeStyleProject p = j.createFreeStyleProject(); 28 | RunLoadCounter.prepare(p); 29 | for (int i = 0; i < 25; i++) { 30 | j.assertBuildStatusSuccess(p.scheduleBuild2(0)); 31 | } 32 | final StatBuilds stats = new StatBuilds("-"); 33 | assertEquals( 34 | StatBuilds.MAX_BUILDS, 35 | RunLoadCounter.assertMaxLoads( 36 | p, 37 | StatBuilds.MAX_BUILDS + /* margin for AbstractLazyLoadRunMap.headMap */ 2, 38 | () -> stats.getBuildStat(Collections.singletonList(p)) 39 | .get(BallColor.BLUE)) 40 | .intValue()); 41 | } 42 | 43 | @Test 44 | void testGettingBuildStatsWithZeroBuild() throws Exception { 45 | final FreeStyleProject project = j.createFreeStyleProject(); 46 | RunLoadCounter.prepare(project); 47 | final StatBuilds stats = new StatBuilds("-"); 48 | final Map buildStats = stats.getBuildStat(Collections.singletonList(project)); 49 | for (BallColor color : BallColor.values()) { 50 | assertEquals((Integer) 0, buildStats.get(color.noAnime())); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/decorate-plain.jelly: -------------------------------------------------------------------------------- 1 | 24 | 25 | 28 | 29 | 31 | 32 | Portlet border decoration without a table. Use this to show other content like charts. 33 | 34 | The portlet being rendered 35 | 36 | 37 | Unused 38 | 39 | 40 |
41 | 42 |
43 | 44 |
45 |
46 |
47 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/decorate.jelly: -------------------------------------------------------------------------------- 1 | 24 | 25 | 28 | 29 | 31 | 32 | Deprecated. Instead use decorate-plain or decorate-table.
33 | Portlet border decoration. The body is wrapper inside a table. 34 | 35 | The portlet being rendered 36 | 37 | 38 | Unused 39 | 40 |
41 |
42 | 43 | 44 | 45 |
46 |
47 |
48 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/portlet.css: -------------------------------------------------------------------------------- 1 | .dbv-container { 2 | display: grid; 3 | gap: 5px 10px; 4 | min-width: fit-content; 5 | } 6 | 7 | .dbv-container__top{ 8 | grid-row: 1; 9 | grid-column: 1 / 3; 10 | } 11 | 12 | .dbv-container__middle { 13 | grid-row: 2; 14 | grid-column: 1 / 3; 15 | } 16 | 17 | .dbv-container__left{ 18 | grid-row: 2; 19 | grid-column: 1; 20 | } 21 | 22 | .dbv-container__right{ 23 | grid-row: 2; 24 | grid-column: 2; 25 | } 26 | 27 | .dbv-container__bottom { 28 | grid-row: 3; 29 | grid-column: 1 / 3; 30 | } 31 | 32 | .dbv-portlet { 33 | margin-bottom: var(--section-padding); 34 | border-radius: calc(var(--table-border-radius) + 2px); 35 | border: 2px solid var(--medium-grey); 36 | overflow: hidden; 37 | } 38 | 39 | .dbv-portlet__title { 40 | background-color: var(--medium-grey); 41 | padding: 5px 10px; 42 | font-weight: bold; 43 | display: flex; 44 | } 45 | 46 | .dbv-portlet__title--icons { 47 | margin-left: auto; 48 | } 49 | 50 | .dbv-portlet__table, .dbv-portlet__content #projectstatus { 51 | margin-bottom: 0; 52 | border-top-left-radius: 0; 53 | border-top-right-radius: 0; 54 | } 55 | 56 | .dbv-portlet__content .jenkins-icon-size { 57 | margin-left: 5px; 58 | } 59 | 60 | .dbv-portlet__table--gap { 61 | border-spacing: 2px; 62 | } 63 | 64 | .dbv-portlet__table--compact > tbody > tr > td { 65 | height: auto; 66 | } 67 | 68 | .dbv-portlet__title-button--maximize { 69 | color: var(--text-color); 70 | } 71 | 72 | .dbv-cell { 73 | display: flex; 74 | align-items: center; 75 | gap: 0.4rem; 76 | } 77 | 78 | .dbv-cell .jenkins-icon-adjacent { 79 | margin-left: 0; 80 | } 81 | 82 | .dbv-cell > a.model-link { 83 | text-align: left; 84 | width: fit-content; 85 | } 86 | 87 | .dbv-cell > .jenkins-table__cell--tight { 88 | width: fit-content; 89 | } 90 | 91 | .dbv-cell svg { 92 | min-width: 16px; 93 | } 94 | 95 | .dbv-portlet__table tr > td:last-of-type, 96 | .dbv-portlet__table tr > th:last-of-type{ 97 | padding-right: 10px!important; 98 | } 99 | 100 | .dbv-table__bottom--left { 101 | padding-left: 1.6rem; 102 | } 103 | 104 | -------------------------------------------------------------------------------- /src/test/resources/hudson/plugins/view/dashboard/casc.yml: -------------------------------------------------------------------------------- 1 | --- 2 | jenkins: 3 | views: 4 | - dashboard: 5 | name: "test" 6 | columns: 7 | - "status" 8 | - "weather" 9 | - "jobName" 10 | - "lastSuccess" 11 | - "lastFailure" 12 | - "lastDuration" 13 | - "buildButton" 14 | recurse: true 15 | includeRegex: ".*" 16 | includeStdJobList: true 17 | hideJenkinsPanels: true 18 | useCssStyle: true 19 | leftPortletWidth: "50%" 20 | rightPortletWidth: "50%" 21 | topPortlets: 22 | - statSlaves: 23 | name: "Agent statistics" 24 | - statBuilds: 25 | name: "Build statistics" 26 | - latestBuilds: 27 | name: "Latest builds" 28 | numBuilds: 10 29 | leftPortlets: 30 | - iframePortlet: 31 | divStyle: "width:100%;height:1000px;" 32 | iframeSource: "test" 33 | name: "Iframe Portlet" 34 | - imagePortlet: 35 | name: "Image" 36 | imageUrl: "test" 37 | rightPortlets: 38 | - hudsonStdJobsPortlet: 39 | name: "Jenkins jobs list" 40 | - statJobs: 41 | name: "Job statistics" 42 | - jobsPortlet: 43 | columnCount: 3 44 | fillColumnFirst: false 45 | name: "Jobs Grid" 46 | - unstableJobsPortlet: 47 | name: "Unstable Jobs" 48 | recurse: false 49 | showOnlyFailedJobs: false 50 | bottomPortlets: 51 | - testStatisticsChart: 52 | name: "Test Statistics Chart" 53 | - testStatisticsPortlet: 54 | failureColor: "E86850" 55 | hideZeroTestProjects: false 56 | name: "Test Statistics Grid" 57 | skippedColor: "FDB813" 58 | successColor: "71E66D" 59 | useBackgroundColors: false 60 | - testTrendChart: 61 | dateRange: 0 62 | dateShift: 0 63 | displayStatus: ALL 64 | graphHeight: 220 65 | graphWidth: 300 66 | name: "Test Trend Chart" 67 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/jobCell.jelly: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | Displays a link to the job with a build button, optionally followed by the job weather. 6 | 7 | Job object to be displayed. 8 | 9 | 10 | Show job weather. 11 | 12 | 13 |
14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 |
42 |
43 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/Dashboard/configure-entries_fr.properties: -------------------------------------------------------------------------------- 1 | # The MIT License 2 | # 3 | # Copyright (c) 2004-2010, Sun Microsystems, Inc. 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in 13 | # all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | # THE SOFTWARE. 22 | 23 | Add\ Dashboard\ Portlet\ to\ bottom\ of\ the\ view=Ajouter un Portlet en bas de la vue 24 | Add\ Dashboard\ Portlet\ to\ left\ column=Ajouter la Portlet Dashboard \u00E0 la colonne de gauche 25 | Add\ Dashboard\ Portlet\ to\ right\ column=Ajouter la Portlet Dashboard \u00E0 la colonne de droite 26 | Add\ Dashboard\ Portlet\ to\ the\ top\ of\ the\ view=Ajouter un Portlets en haut de la vue 27 | Portlets\ at\ the\ bottom\ of\ the\ page=Portlets du bas 28 | Dashboard\ Portlets=Dashboard Portlets 29 | Exclude\ disabled\ jobs=Ex\u00E9cuter les travaux d\u00E9sactiv\u00E9s 30 | Jobs=Travaux 31 | Portlets\ in\ the\ left\ column=Colonne de gauche 32 | Regular\ expression=Expression r\u00E9guli\u00E8re 33 | Portlets\ in\ the\ right\ column=Colonne de droite 34 | Show\ standard\ Jenkins\ list\ at\ the\ top\ of\ the\ page=Montrer la liste Jenkins standard en haut de la page 35 | Portlets\ at\ the\ top\ of\ the\ page=Portels Hautes 36 | Use\ a\ regular\ expression\ to\ include\ jobs\ into\ the\ view=Utiliser une expression r\u00E9guli\u00E8re pour inclure les travaux dans la vue 37 | -------------------------------------------------------------------------------- /src/main/java/hudson/plugins/view/dashboard/DashboardPortlet.java: -------------------------------------------------------------------------------- 1 | package hudson.plugins.view.dashboard; 2 | 3 | import hudson.DescriptorExtensionList; 4 | import hudson.ExtensionPoint; 5 | import hudson.model.Describable; 6 | import hudson.model.Descriptor; 7 | import hudson.model.ModelObject; 8 | import hudson.model.TopLevelItem; 9 | import java.util.Comparator; 10 | import jenkins.model.Jenkins; 11 | import org.kohsuke.stapler.Stapler; 12 | import org.kohsuke.stapler.StaplerRequest2; 13 | 14 | /** 15 | * Report that can summarize project data across multiple projects and display the resulting data. 16 | * 17 | * @author Peter Hayes 18 | */ 19 | public abstract class DashboardPortlet implements ModelObject, Describable, ExtensionPoint { 20 | 21 | private final String name; 22 | 23 | public DashboardPortlet(String name) { 24 | this.name = name; 25 | } 26 | 27 | public String getId() { 28 | return "portlet-" + getDashboard().getPortletUrl(this).replace('/', '-'); 29 | } 30 | 31 | public String getName() { 32 | return name; 33 | } 34 | 35 | public Dashboard getDashboard() { 36 | // TODO Can the dashboard instance be a field on this class -- parent? 37 | StaplerRequest2 req = Stapler.getCurrentRequest2(); 38 | return req != null ? req.findAncestorObject(Dashboard.class) : null; 39 | } 40 | 41 | @Override 42 | public String getDisplayName() { 43 | return getName(); 44 | } 45 | 46 | public String getUrl() { 47 | return getDashboard().getPortletUrl(this) + '/'; 48 | } 49 | 50 | /** Support accessing jobs available via view through portlets */ 51 | public TopLevelItem getJob(String name) { 52 | return getDashboard().getJob(name); 53 | } 54 | 55 | @Override 56 | public Descriptor getDescriptor() { 57 | return (Descriptor) Jenkins.get().getDescriptor(getClass()); 58 | } 59 | 60 | /** Returns all the registered {@link DashboardPortlet} descriptors. */ 61 | public static DescriptorExtensionList> all() { 62 | return Jenkins.get().getDescriptorList(DashboardPortlet.class); 63 | } 64 | 65 | public static Comparator getComparator() { 66 | return (Comparator) (p1, p2) -> p1.getDescription().compareTo(p2.getDescription()); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/decorate-table.jelly: -------------------------------------------------------------------------------- 1 | 24 | 25 | 28 | 29 | 31 | definition here. 35 | ]]> 36 | 37 | The portlet being rendered 38 | 39 | 40 | Unused 41 | 42 | 43 | Additional classes applied to the table 44 | 45 | 46 |
47 | 48 | 49 | 50 |
51 |
52 |
53 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/core/IframePortlet/portlet.jelly: -------------------------------------------------------------------------------- 1 | 24 | 25 | 26 | 27 | 28 | 29 | 30 |
31 | 32 | 33 | 36 | 37 | 38 | 41 | 42 | 43 |
44 |
45 | 46 |
${%Display error: URL is invalid}
47 |
48 |
49 |
50 |
51 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/Dashboard/configure-entries_it.properties: -------------------------------------------------------------------------------- 1 | # The MIT License 2 | # 3 | # Copyright (c) 2004-2010, Sun Microsystems, Inc. 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in 13 | # all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | # THE SOFTWARE. 22 | 23 | Add\ Dashboard\ Portlet\ to\ bottom\ of\ the\ view=Aggiungi un portlet alla fine della pagina 24 | Add\ Dashboard\ Portlet\ to\ left\ column=Aggiungi un portlet alla sinistra della pagina 25 | Add\ Dashboard\ Portlet\ to\ right\ column=Aggiungi un portlet alla destra della pagina 26 | Add\ Dashboard\ Portlet\ to\ the\ top\ of\ the\ view=Aggiungi un portlet all''inizio della pagina 27 | Portlets\ at\ the\ bottom\ of\ the\ page=Portlet alla fine pagina 28 | Dashboard\ Portlets=Dashboard Portlets 29 | Exclude\ disabled\ jobs=Escludi job disabilitati 30 | Jobs=Job 31 | Portlets\ in\ the\ left\ column=Portlet alla sinistra della pagina 32 | Regular\ expression=Espressione regolare 33 | Portlets\ in\ the\ right\ column=Portlet alla destra della pagina 34 | Show\ standard\ Jenkins\ list\ at\ the\ top\ of\ the\ page=Mostra la lista standard dei Job all''inizio della pagina 35 | Portlets\ at\ the\ top\ of\ the\ page=Portlet all''inizio della pagina 36 | Use\ a\ regular\ expression\ to\ include\ jobs\ into\ the\ view=Usa una espressione regolare per includere i Job nella view 37 | Left\ portlet\ width=Larghezza colonna sinistra 38 | Right\ portlet\ width=Larghezza colonna destra 39 | Set\ CSS\ custom\ parameters=Imposta parametri CSS avanzati 40 | -------------------------------------------------------------------------------- /src/main/java/hudson/plugins/view/dashboard/stats/StatBuilds.java: -------------------------------------------------------------------------------- 1 | package hudson.plugins.view.dashboard.stats; 2 | 3 | import hudson.Extension; 4 | import hudson.model.BallColor; 5 | import hudson.model.Descriptor; 6 | import hudson.model.Job; 7 | import hudson.model.Run; 8 | import hudson.model.TopLevelItem; 9 | import hudson.plugins.view.dashboard.DashboardPortlet; 10 | import hudson.plugins.view.dashboard.Messages; 11 | import java.util.List; 12 | import java.util.Map; 13 | import java.util.SortedMap; 14 | import java.util.TreeMap; 15 | import org.kohsuke.stapler.DataBoundConstructor; 16 | 17 | /** 18 | * Build statistics - number of builds with given build status 19 | * 20 | * @author Vojtech Juranek 21 | */ 22 | public class StatBuilds extends DashboardPortlet { 23 | 24 | /** The most builds we will try to examine. */ 25 | static final int MAX_BUILDS = Integer.getInteger(StatBuilds.class.getName() + ".maxBuilds", 10); 26 | 27 | @DataBoundConstructor 28 | public StatBuilds(String name) { 29 | super(name); 30 | } 31 | 32 | public Map getBuildStat(List jobs) { 33 | SortedMap colStatBuilds = new TreeMap<>(); 34 | for (BallColor color : BallColor.values()) { 35 | colStatBuilds.put(color.noAnime(), 0); 36 | } 37 | // loop over jobs 38 | for (TopLevelItem job : jobs) { 39 | if (job instanceof Job) { 40 | // Build statistics 41 | List builds = ((Job) job).getBuilds().limit(MAX_BUILDS); 42 | // loop over builds 43 | for (Run build : builds) { 44 | BallColor bColor = build.getIconColor(); 45 | if (bColor != null && bColor.noAnime() != null && colStatBuilds.get(bColor) != null) { 46 | colStatBuilds.put(bColor.noAnime(), colStatBuilds.get(bColor) + 1); 47 | } 48 | } 49 | } 50 | } 51 | return colStatBuilds; 52 | } 53 | 54 | public float roundFloatDecimal(float input) { 55 | float rounded = (float) Math.round(input * 100f); 56 | rounded = rounded / 100f; 57 | return rounded; 58 | } 59 | 60 | @Extension 61 | public static class DescriptorImpl extends Descriptor { 62 | 63 | @Override 64 | public String getDisplayName() { 65 | return Messages.Dashboard_BuildStatistics(); 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/test/TestStatisticsPortlet/config.jelly: -------------------------------------------------------------------------------- 1 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/test/TestTrendChart/config.jelly: -------------------------------------------------------------------------------- 1 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /src/test/java/hudson/plugins/view/dashboard/test/TestSummaryForMatrixJobs.java: -------------------------------------------------------------------------------- 1 | package hudson.plugins.view.dashboard.test; 2 | 3 | import static org.hamcrest.CoreMatchers.is; 4 | import static org.hamcrest.MatcherAssert.assertThat; 5 | 6 | import hudson.Launcher; 7 | import hudson.matrix.MatrixBuild; 8 | import hudson.matrix.MatrixProject; 9 | import hudson.matrix.TextAxis; 10 | import hudson.model.AbstractBuild; 11 | import hudson.model.BuildListener; 12 | import hudson.model.Result; 13 | import hudson.tasks.junit.JUnitResultArchiver; 14 | import java.io.IOException; 15 | import java.util.Collections; 16 | import org.junit.jupiter.api.AfterEach; 17 | import org.junit.jupiter.api.BeforeEach; 18 | import org.junit.jupiter.api.Test; 19 | import org.jvnet.hudson.test.JenkinsRule; 20 | import org.jvnet.hudson.test.TestBuilder; 21 | import org.jvnet.hudson.test.junit.jupiter.WithJenkins; 22 | 23 | @WithJenkins 24 | class TestSummaryForMatrixJobs { 25 | 26 | private JenkinsRule j; 27 | 28 | private MatrixProject matrixProject; 29 | 30 | @BeforeEach 31 | void setUp(JenkinsRule rule) throws Exception { 32 | j = rule; 33 | 34 | matrixProject = j.jenkins.createProject(MatrixProject.class, "top"); 35 | matrixProject.getAxes().add(new TextAxis("param", "one", "two")); 36 | matrixProject.getBuildersList().add(new TestBuilder() { 37 | @Override 38 | public boolean perform(AbstractBuild build, Launcher launcher, BuildListener listener) 39 | throws InterruptedException, IOException { 40 | build.getWorkspace() 41 | .child("testresult.xml") 42 | .copyFrom(TestSummaryForMatrixJobs.class.getResource( 43 | "/hudson/plugins/view/dashboard/test_failure.xml")); 44 | return true; 45 | } 46 | }); 47 | matrixProject.getPublishersList().add(new JUnitResultArchiver("testresult.xml")); 48 | } 49 | 50 | @Test 51 | void summaryIncludesMatrixJobs() throws Exception { 52 | MatrixBuild result = matrixProject.scheduleBuild2(0).get(); 53 | j.assertBuildStatus(Result.UNSTABLE, result); 54 | 55 | TestResultSummary testSummary = TestUtil.getTestResultSummary(Collections.singleton(matrixProject), false); 56 | assertThat(testSummary.getFailed(), is((2))); 57 | assertThat(testSummary.getSuccess(), is((2))); 58 | } 59 | 60 | @AfterEach 61 | void cleanupMatrixJob() throws Exception { 62 | matrixProject.delete(); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/hudson/plugins/view/dashboard/core/JobsPortlet.java: -------------------------------------------------------------------------------- 1 | package hudson.plugins.view.dashboard.core; 2 | 3 | import com.google.common.collect.Lists; 4 | import hudson.Extension; 5 | import hudson.model.Descriptor; 6 | import hudson.model.Job; 7 | import hudson.plugins.view.dashboard.DashboardPortlet; 8 | import hudson.plugins.view.dashboard.Messages; 9 | import java.util.ArrayList; 10 | import java.util.Collections; 11 | import java.util.List; 12 | import org.kohsuke.stapler.DataBoundConstructor; 13 | 14 | /** 15 | * Portlet displays a grid of job names with status and links to jobs. 16 | * 17 | * @author Peter Hayes 18 | */ 19 | public class JobsPortlet extends DashboardPortlet { 20 | 21 | private static final int MIN_COLUMN_COUNT = 3; 22 | 23 | private final int columnCount; 24 | 25 | private boolean fillColumnFirst = false; 26 | 27 | @DataBoundConstructor 28 | public JobsPortlet(String name, int columnCount, boolean fillColumnFirst) { 29 | super(name); 30 | this.columnCount = columnCount; 31 | this.fillColumnFirst = fillColumnFirst; 32 | } 33 | 34 | public boolean isFillColumnFirst() { 35 | return fillColumnFirst; 36 | } 37 | 38 | public int getColumnCount() { 39 | return columnCount <= 0 ? MIN_COLUMN_COUNT : columnCount; 40 | } 41 | 42 | public List> getJobs() { 43 | List jobs = this.getDashboard().getJobs(); 44 | Collections.sort(jobs, (p1, p2) -> p1.getFullDisplayName().compareToIgnoreCase(p2.getFullDisplayName())); 45 | 46 | if (this.fillColumnFirst) { 47 | return transposed(jobs); 48 | } else { 49 | return Lists.partition(jobs, this.getColumnCount()); 50 | } 51 | } 52 | 53 | private List> transposed(List jobs) { 54 | int rowCount = (jobs.size() + 1) / this.getColumnCount(); 55 | List> result = new ArrayList<>(rowCount); 56 | for (int i = 0; i < rowCount; i++) { 57 | result.add(new ArrayList<>(this.getColumnCount())); 58 | } 59 | int c = 0; 60 | for (Job job : jobs) { 61 | result.get(c).add(job); 62 | c = (c + 1) % rowCount; 63 | } 64 | return result; 65 | } 66 | 67 | @Extension 68 | public static class DescriptorImpl extends Descriptor { 69 | 70 | public int getDefaultColumnCount() { 71 | return MIN_COLUMN_COUNT; 72 | } 73 | 74 | @Override 75 | public String getDisplayName() { 76 | return Messages.Dashboard_JobsGrid(); 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/test/java/hudson/plugins/view/dashboard/core/ImagePortletTest.java: -------------------------------------------------------------------------------- 1 | package hudson.plugins.view.dashboard.core; 2 | 3 | import static org.hamcrest.MatcherAssert.assertThat; 4 | import static org.hamcrest.Matchers.emptyIterable; 5 | import static org.hamcrest.Matchers.hasSize; 6 | import static org.hamcrest.Matchers.is; 7 | 8 | import hudson.plugins.view.dashboard.Dashboard; 9 | import java.util.Arrays; 10 | import java.util.List; 11 | import org.htmlunit.html.DomNode; 12 | import org.htmlunit.html.HtmlPage; 13 | import org.junit.jupiter.api.BeforeEach; 14 | import org.junit.jupiter.api.Test; 15 | import org.jvnet.hudson.test.Issue; 16 | import org.jvnet.hudson.test.JenkinsRule; 17 | import org.jvnet.hudson.test.junit.jupiter.WithJenkins; 18 | 19 | @WithJenkins 20 | class ImagePortletTest { 21 | 22 | private JenkinsRule j; 23 | 24 | @BeforeEach 25 | void setUp(JenkinsRule rule) { 26 | j = rule; 27 | } 28 | 29 | @Test 30 | @Issue("SECURITY-2233") 31 | void imagePortletValidation() throws Exception { 32 | j.createFreeStyleProject("p1"); 33 | 34 | Dashboard dashboard = new Dashboard("dash1"); 35 | dashboard.setIncludeRegex(".*"); 36 | j.jenkins.addView(dashboard); 37 | 38 | for (String invalid : Arrays.asList("", "", "ftp://example.com")) { 39 | ImagePortlet imagePortlet = new ImagePortlet("bar", invalid); 40 | dashboard.getBottomPortlets().clear(); 41 | dashboard.getBottomPortlets().add(imagePortlet); 42 | assertThat(imagePortlet.isUrlValid(), is(false)); 43 | HtmlPage page = j.createWebClient().goTo("view/dash1/"); 44 | assertThat(findError(page), hasSize(1)); 45 | assertThat(findImage(page), is(emptyIterable())); 46 | } 47 | 48 | for (String valid : Arrays.asList("http://example.com/img.png", "//example.com/img.png", "/some/img.png")) { 49 | ImagePortlet imagePortlet = new ImagePortlet("bar", valid); 50 | dashboard.getBottomPortlets().clear(); 51 | dashboard.getBottomPortlets().add(imagePortlet); 52 | assertThat(imagePortlet.isUrlValid(), is(true)); 53 | HtmlPage page = j.createWebClient().goTo("view/dash1/"); 54 | assertThat(findError(page), is(emptyIterable())); 55 | assertThat(findImage(page), hasSize(1)); 56 | } 57 | } 58 | 59 | private List findImage(HtmlPage page) { 60 | return page.getByXPath("//div[@id='portlet-bottomPortlets-0']//img"); 61 | } 62 | 63 | private List findError(HtmlPage page) { 64 | return page.getByXPath("//div[@class='error']"); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/test/java/hudson/plugins/view/dashboard/DashboardViewTest.java: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: MIT 2 | * Copyright (c) 2020, Tobias Gruetzmacher 3 | */ 4 | package hudson.plugins.view.dashboard; 5 | 6 | import static org.hamcrest.MatcherAssert.assertThat; 7 | import static org.hamcrest.Matchers.equalTo; 8 | import static org.hamcrest.Matchers.is; 9 | 10 | import hudson.model.FreeStyleProject; 11 | import java.util.function.Predicate; 12 | import org.htmlunit.html.HtmlAnchor; 13 | import org.htmlunit.html.HtmlPage; 14 | import org.junit.jupiter.api.BeforeAll; 15 | import org.junit.jupiter.api.Test; 16 | import org.jvnet.hudson.test.JenkinsRule; 17 | import org.jvnet.hudson.test.MockFolder; 18 | import org.jvnet.hudson.test.junit.jupiter.WithJenkins; 19 | 20 | @WithJenkins 21 | class DashboardViewTest { 22 | 23 | private static JenkinsRule j; 24 | 25 | private static FreeStyleProject p1; 26 | private static FreeStyleProject p2; 27 | 28 | @BeforeAll 29 | static void setUp(JenkinsRule rule) throws Exception { 30 | j = rule; 31 | 32 | p1 = j.createFreeStyleProject("p1"); 33 | j.assertBuildStatusSuccess(p1.scheduleBuild2(0)); 34 | MockFolder f = j.createFolder("f1"); 35 | p2 = f.createProject(FreeStyleProject.class, "p2"); 36 | j.assertBuildStatusSuccess(p2.scheduleBuild2(0)); 37 | 38 | for (int i = 0; i < 2; i++) { 39 | Dashboard dashboard = new Dashboard("foo" + i); 40 | dashboard.setIncludeRegex(".*"); 41 | dashboard.setRecurse(true); 42 | dashboard.setIncludeStdJobList(true); 43 | if (i % 2 == 0) { 44 | j.jenkins.addView(dashboard); 45 | } else { 46 | f.addView(dashboard); 47 | } 48 | } 49 | } 50 | 51 | @Test 52 | void verifyDisplayNameInFolders() throws Exception { 53 | HtmlPage page = j.createWebClient().goTo("view/foo0/"); 54 | HtmlAnchor p1Link = findLink(page, a -> a.getHrefAttribute().equals("job/p1/")); 55 | assertThat(p1Link.getTextContent(), is(equalTo("p1"))); 56 | HtmlAnchor p2Link = findLink(page, a -> a.getHrefAttribute().endsWith("/job/p2/")); 57 | assertThat(p2Link.getTextContent(), is(equalTo(p2.getFullDisplayName()))); 58 | 59 | page = j.createWebClient().goTo("job/f1/view/foo1/"); 60 | p2Link = findLink(page, a -> a.getHrefAttribute().equals("job/p2/")); 61 | assertThat(p2Link.getTextContent(), is(equalTo("p2"))); 62 | } 63 | 64 | private static HtmlAnchor findLink(HtmlPage page, Predicate condition) { 65 | return page.getAnchors().stream().filter(condition).findAny().orElseThrow(IllegalStateException::new); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/test/java/hudson/plugins/view/dashboard/test/TestTrendChartTest.java: -------------------------------------------------------------------------------- 1 | package hudson.plugins.view.dashboard.test; 2 | 3 | import static org.hamcrest.MatcherAssert.assertThat; 4 | import static org.hamcrest.Matchers.equalTo; 5 | import static org.hamcrest.Matchers.is; 6 | import static org.mockito.Mockito.doReturn; 7 | import static org.mockito.Mockito.spy; 8 | import static org.mockito.Mockito.when; 9 | 10 | import hudson.maven.MavenModuleSet; 11 | import hudson.model.Result; 12 | import hudson.plugins.view.dashboard.Dashboard; 13 | import java.time.LocalDate; 14 | import java.util.Collection; 15 | import java.util.Collections; 16 | import java.util.Map; 17 | import org.hamcrest.Matchers; 18 | import org.junit.jupiter.api.BeforeEach; 19 | import org.junit.jupiter.api.Test; 20 | import org.junit.jupiter.api.extension.ExtendWith; 21 | import org.jvnet.hudson.test.ExtractResourceSCM; 22 | import org.jvnet.hudson.test.JenkinsRule; 23 | import org.jvnet.hudson.test.ToolInstallations; 24 | import org.jvnet.hudson.test.junit.jupiter.WithJenkins; 25 | import org.mockito.Mock; 26 | import org.mockito.junit.jupiter.MockitoExtension; 27 | 28 | @WithJenkins 29 | @ExtendWith(MockitoExtension.class) 30 | class TestTrendChartTest { 31 | 32 | private JenkinsRule j; 33 | 34 | @Mock 35 | private Dashboard dashboard; 36 | 37 | @BeforeEach 38 | void setUp(JenkinsRule rule) { 39 | j = rule; 40 | } 41 | 42 | // TODO: It would be nice to actually have some "history", but that would involve faking builds on 43 | // different days 44 | 45 | @Test 46 | void summaryIncludesMavenJob() throws Exception { 47 | ToolInstallations.configureMaven35(); 48 | 49 | MavenModuleSet project = j.jenkins.createProject(MavenModuleSet.class, "maven"); 50 | project.setGoals("test"); 51 | project.setScm(new ExtractResourceSCM(getClass().getResource("maven-unit-failure.zip"))); 52 | j.assertBuildStatus(Result.UNSTABLE, project.scheduleBuild2(0).get()); 53 | j.assertBuildStatus(Result.UNSTABLE, project.scheduleBuild2(0).get()); 54 | 55 | when(dashboard.getJobs()).thenReturn(Collections.singletonList(project)); 56 | TestTrendChart chart = new TestTrendChart("tests", 320, 240, TestTrendChart.DisplayStatus.ALL, 30, 0); 57 | chart = spy(chart); 58 | doReturn(dashboard).when(chart).getDashboard(); 59 | 60 | Map chartData = chart.collectData(); 61 | Collection values = chartData.values(); 62 | assertThat(values, Matchers.hasSize(1)); 63 | TestResultSummary today = values.iterator().next(); 64 | assertThat(today.getFailed(), is(equalTo(2))); 65 | assertThat(today.getSuccess(), is(equalTo(2))); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/stats/StatJobs/statjobs.jelly: -------------------------------------------------------------------------------- 1 | 24 | 25 | 26 | 27 | 29 | 30 | 31 | 32 | 33 | ${%W} 34 | ${%Description} 35 | ${%Number of projects} 36 | 37 | 38 | 39 | 40 | 41 | 42 |
43 | 45 |
46 | 47 | ${col.key.description} 48 | ${col.value} 49 | 50 | 51 |
52 | 53 | 54 | ${%Total projects} 55 | 56 | ${nProjects} 57 | 58 | 59 |
60 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/stats/StatBuilds/statbuilds.jelly: -------------------------------------------------------------------------------- 1 | 24 | 25 | 26 | 28 | 29 | 30 | 31 | 32 | 33 | ${%S} 34 | ${%Description} 35 | ${%Number of builds with status} 36 | ${%Percentage of total builds} 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | ${col.key.description} 47 | ${col.value} 48 | ${it.roundFloatDecimal((col.value/nBuilds)*100)} 49 | 50 | 51 | 52 | 53 | ${%Total builds} 54 | ${nBuilds} 55 | 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /src/test/java/hudson/plugins/view/dashboard/builds/LatestBuildsTest.java: -------------------------------------------------------------------------------- 1 | package hudson.plugins.view.dashboard.builds; 2 | 3 | import static org.hamcrest.MatcherAssert.assertThat; 4 | import static org.hamcrest.Matchers.containsString; 5 | import static org.hamcrest.Matchers.not; 6 | import static org.hamcrest.Matchers.startsWith; 7 | 8 | import hudson.model.FreeStyleBuild; 9 | import hudson.model.FreeStyleProject; 10 | import hudson.model.Job; 11 | import hudson.plugins.view.dashboard.Dashboard; 12 | import java.util.Collections; 13 | import java.util.List; 14 | import org.htmlunit.html.HtmlAnchor; 15 | import org.htmlunit.html.HtmlPage; 16 | import org.junit.jupiter.api.BeforeAll; 17 | import org.junit.jupiter.api.Test; 18 | import org.jvnet.hudson.test.Issue; 19 | import org.jvnet.hudson.test.JenkinsRule; 20 | import org.jvnet.hudson.test.RunLoadCounter; 21 | import org.jvnet.hudson.test.junit.jupiter.WithJenkins; 22 | 23 | @WithJenkins 24 | class LatestBuildsTest { 25 | 26 | private static JenkinsRule j; 27 | 28 | private static FreeStyleProject p; 29 | 30 | @BeforeAll 31 | static void setUp(JenkinsRule rule) throws Exception { 32 | j = rule; 33 | 34 | p = j.createFreeStyleProject(); 35 | for (int i = 0; i < 5; i++) { 36 | j.assertBuildStatusSuccess(p.scheduleBuild2(0)); 37 | } 38 | } 39 | 40 | @Test 41 | void testAvoidEagerLoading() throws Exception { 42 | RunLoadCounter.prepare(p); 43 | 44 | int numbuilds = 3; 45 | final LatestBuilds latest = new LatestBuilds("-", numbuilds) { 46 | 47 | @Override 48 | protected List getDashboardJobs() { 49 | return Collections.singletonList(p); 50 | } 51 | }; 52 | 53 | RunLoadCounter.assertMaxLoads(p, numbuilds, latest::getFinishedBuilds); 54 | } 55 | 56 | @Test 57 | @Issue("SECURITY-1489") 58 | void testTooltipIsEscaped() throws Exception { 59 | FreeStyleBuild lastBuild = p.getLastBuild(); 60 | lastBuild.setDescription("test"); 61 | Dashboard dashboard = new Dashboard("foo"); 62 | dashboard.setIncludeRegex(".*"); 63 | dashboard.getLeftPortlets().add(new LatestBuilds("foo", 10)); 64 | j.jenkins.addView(dashboard); 65 | HtmlPage page = j.createWebClient().goTo("view/foo/"); 66 | HtmlAnchor link = page.getAnchors().stream() 67 | .filter(a -> a.getHrefAttribute().endsWith("/" + lastBuild.number)) 68 | .findAny() 69 | .orElseThrow(IllegalStateException::new); 70 | String tooltip = link.getAttribute("tooltip"); 71 | // The default formatter just escapes all HTML 72 | assertThat(tooltip, not(containsString("<"))); 73 | assertThat(tooltip, startsWith("<")); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/main/java/hudson/plugins/view/dashboard/builds/LatestBuilds.java: -------------------------------------------------------------------------------- 1 | package hudson.plugins.view.dashboard.builds; 2 | 3 | import hudson.Extension; 4 | import hudson.model.Descriptor; 5 | import hudson.model.Job; 6 | import hudson.model.Run; 7 | import hudson.plugins.view.dashboard.DashboardPortlet; 8 | import hudson.plugins.view.dashboard.Messages; 9 | import java.text.DateFormat; 10 | import java.util.ArrayList; 11 | import java.util.Date; 12 | import java.util.List; 13 | import java.util.PriorityQueue; 14 | import org.kohsuke.stapler.DataBoundConstructor; 15 | 16 | public class LatestBuilds extends DashboardPortlet { 17 | 18 | /** 19 | * Number of latest builds which will be displayed on the screen 20 | */ 21 | private int numBuilds = 10; 22 | 23 | @DataBoundConstructor 24 | public LatestBuilds(String name, int numBuilds) { 25 | super(name); 26 | this.numBuilds = numBuilds; 27 | } 28 | 29 | public int getNumBuilds() { 30 | return numBuilds <= 0 ? 10 : numBuilds; 31 | } 32 | 33 | public String getTimestampSortData(Run run) { 34 | return String.valueOf(run.getTimeInMillis()); 35 | } 36 | 37 | public String getTimestampString(Run run) { 38 | return DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM) 39 | .format(new Date(run.getTimeInMillis())); 40 | } 41 | 42 | /** 43 | * Last N_LATEST_BUILDS builds 44 | * 45 | */ 46 | public List getFinishedBuilds() { 47 | List jobs = getDashboardJobs(); 48 | 49 | PriorityQueue queue = new PriorityQueue<>(numBuilds, Run.ORDER_BY_DATE); 50 | for (Job job : jobs) { 51 | Run lb = job.getLastBuild(); 52 | if (lb != null) { 53 | queue.add(lb); 54 | } 55 | } 56 | 57 | List recentBuilds = new ArrayList<>(numBuilds); 58 | Run build; 59 | while ((build = queue.poll()) != null) { 60 | recentBuilds.add(build); 61 | if (recentBuilds.size() == numBuilds) { 62 | break; 63 | } 64 | Run pb = build.getPreviousBuild(); 65 | if (pb != null) { 66 | queue.add(pb); 67 | } 68 | } 69 | 70 | return recentBuilds; 71 | } 72 | 73 | /** 74 | * for unit test 75 | */ 76 | protected List getDashboardJobs() { 77 | return getDashboard().getJobs(); 78 | } 79 | 80 | public String getBuildColumnSortData(Run build) { 81 | return String.valueOf(build.getNumber()); 82 | } 83 | 84 | @Extension 85 | public static class DescriptorImpl extends Descriptor { 86 | 87 | @Override 88 | public String getDisplayName() { 89 | return Messages.Dashboard_LatestBuilds(); 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/main/java/hudson/plugins/view/dashboard/core/ImagePortlet.java: -------------------------------------------------------------------------------- 1 | package hudson.plugins.view.dashboard.core; 2 | 3 | import edu.umd.cs.findbugs.annotations.CheckForNull; 4 | import hudson.Extension; 5 | import hudson.model.Descriptor; 6 | import hudson.plugins.view.dashboard.DashboardPortlet; 7 | import hudson.plugins.view.dashboard.Messages; 8 | import hudson.util.FormValidation; 9 | import java.net.URI; 10 | import java.net.URISyntaxException; 11 | import org.kohsuke.stapler.DataBoundConstructor; 12 | import org.kohsuke.stapler.DataBoundSetter; 13 | import org.kohsuke.stapler.QueryParameter; 14 | 15 | /** 16 | * Portlet displays image fetched from specified URL 17 | * 18 | * @author rmihael@gmail.com 19 | */ 20 | public class ImagePortlet extends DashboardPortlet { 21 | 22 | private String url; 23 | 24 | @DataBoundConstructor 25 | public ImagePortlet(String name) { 26 | super(name); 27 | } 28 | 29 | @Deprecated 30 | public ImagePortlet(String name, String url) { 31 | super(name); 32 | this.url = url; 33 | } 34 | 35 | public String getImageUrl() { 36 | return this.url; 37 | } 38 | 39 | @DataBoundSetter 40 | public void setImageUrl(final String url) { 41 | this.url = url; 42 | } 43 | 44 | @Deprecated 45 | @DataBoundSetter 46 | public void setUrl(final String url) { 47 | this.url = url; 48 | } 49 | 50 | public boolean isUrlValid() { 51 | return getUrlError(url) == null; 52 | } 53 | 54 | @Extension 55 | public static class DescriptorImpl extends Descriptor { 56 | 57 | @Override 58 | public String getDisplayName() { 59 | return Messages.Dashboard_Image(); 60 | } 61 | 62 | public FormValidation doCheckImageUrl(@QueryParameter String value) { 63 | String error = getUrlError(value); 64 | if (error != null) { 65 | return FormValidation.error(error); 66 | } 67 | return FormValidation.ok(); 68 | } 69 | } 70 | 71 | /** 72 | * Checks if the passed string is a valid HTTP or relative URL. 73 | * 74 | * @return Localized error message or null if URL is valid. 75 | */ 76 | @CheckForNull 77 | private static final String getUrlError(String url) { 78 | if (url == null || url.isBlank()) { 79 | return Messages.Dashboard_ImageUrlEmpty(); 80 | } 81 | try { 82 | final URI allowedUrl = new URI(url); 83 | final String protocol = allowedUrl.getScheme(); 84 | if (!allowedUrl.isAbsolute() || protocol.equals("http") || protocol.equals("https")) { 85 | return null; 86 | } else { 87 | return Messages.Dashboard_ImageUrlHttp(); 88 | } 89 | } catch (URISyntaxException e) { 90 | return Messages.Dashboard_ImageUrlInvalid(e.getMessage()); 91 | } 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/title.jelly: -------------------------------------------------------------------------------- 1 | 24 | 25 | 28 | 29 | 31 | 32 | Portlet border decoration without a table. Use this when the portlet itself renders a table 33 | 34 | The portlet being rendered 35 | 36 | 37 | 38 |
39 |
40 | ${attrs.portlet.displayName} 41 |
42 |
43 | 47 | 51 | 52 | 56 | 57 |
58 |
59 |
60 | -------------------------------------------------------------------------------- /src/main/java/hudson/plugins/view/dashboard/stats/StatSlaves.java: -------------------------------------------------------------------------------- 1 | package hudson.plugins.view.dashboard.stats; 2 | 3 | import hudson.Extension; 4 | import hudson.model.Computer; 5 | import hudson.model.Descriptor; 6 | import hudson.model.Job; 7 | import hudson.plugins.view.dashboard.DashboardPortlet; 8 | import hudson.plugins.view.dashboard.Messages; 9 | import hudson.security.ACL; 10 | import hudson.security.ACLContext; 11 | import jenkins.model.Jenkins; 12 | import org.kohsuke.stapler.DataBoundConstructor; 13 | import org.kohsuke.stapler.bind.JavaScriptMethod; 14 | import org.kohsuke.stapler.export.Exported; 15 | import org.kohsuke.stapler.export.ExportedBean; 16 | 17 | /** @author Lucie Votypkova */ 18 | public class StatSlaves extends DashboardPortlet { 19 | 20 | @DataBoundConstructor 21 | public StatSlaves(String name) { 22 | super(name); 23 | } 24 | 25 | @ExportedBean 26 | public static final class AgentStats { 27 | @Exported 28 | public final int agents; 29 | 30 | @Exported 31 | public int onlineAgents = 0; 32 | 33 | @Exported 34 | public int offlineAgents = 0; 35 | 36 | @Exported 37 | public int disconnectedAgents = 0; 38 | 39 | @Exported 40 | public final int tasksInQueue; 41 | 42 | @Exported 43 | public final int runningJobs; 44 | 45 | AgentStats(Jenkins j) { 46 | agents = j.getNodes().size(); 47 | countAgents(j.getComputers()); 48 | tasksInQueue = j.getQueue().getItems().length; 49 | runningJobs = countRunningJobs(j); 50 | } 51 | 52 | private void countAgents(Computer[] computers) { 53 | for (Computer computer : computers) { 54 | if (computer.isOnline()) { 55 | onlineAgents++; 56 | } else if (computer.getConnectTime() != 0) { 57 | offlineAgents++; 58 | } else { 59 | disconnectedAgents++; 60 | } 61 | } 62 | onlineAgents--; 63 | } 64 | 65 | private int countRunningJobs(Jenkins j) { 66 | // TODO: Might be a faster way to get this info from the computers 67 | int countRunningJobs = 0; 68 | // We don't really care about security here as all this returns is a count 69 | try (ACLContext ctx = ACL.as(ACL.SYSTEM)) { 70 | for (Job job : j.allItems(Job.class)) { 71 | if (job.isBuilding()) { 72 | countRunningJobs++; 73 | } 74 | } 75 | } 76 | return countRunningJobs; 77 | } 78 | } 79 | 80 | @JavaScriptMethod 81 | public AgentStats getStats() { 82 | return new AgentStats(Jenkins.get()); 83 | } 84 | 85 | @Extension 86 | public static class DescriptorImpl extends Descriptor { 87 | 88 | @Override 89 | public String getDisplayName() { 90 | return Messages.Dashboard_AgentStatistics(); 91 | } 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /src/main/java/hudson/plugins/view/dashboard/test/TestUtil.java: -------------------------------------------------------------------------------- 1 | package hudson.plugins.view.dashboard.test; 2 | 3 | import hudson.matrix.MatrixProject; 4 | import hudson.model.Job; 5 | import hudson.model.Run; 6 | import hudson.model.TopLevelItem; 7 | import hudson.tasks.test.AbstractTestResultAction; 8 | import hudson.tasks.test.TestResultProjectAction; 9 | import java.util.Collection; 10 | 11 | public class TestUtil { 12 | /** "Cache" if matrix plugin is installed, so exception handling is only triggered once. */ 13 | private static boolean matrixPluginInstalled = true; 14 | 15 | /** 16 | * Summarize the last test results from the passed set of jobs. If a job doesn't include any 17 | * tests, add a 0 summary. 18 | */ 19 | public static TestResultSummary getTestResultSummary(Collection jobs, boolean hideZeroTestProjects) { 20 | TestResultSummary summary = new TestResultSummary(); 21 | 22 | for (TopLevelItem item : jobs) { 23 | if (isMatrixJob(item)) { 24 | MatrixProject mp = (MatrixProject) item; 25 | 26 | for (Job configuration : mp.getActiveConfigurations()) { 27 | summarizeJob(configuration, summary, hideZeroTestProjects); 28 | } 29 | } else if (item instanceof Job) { 30 | Job job = (Job) item; 31 | summarizeJob(job, summary, hideZeroTestProjects); 32 | } 33 | } 34 | 35 | return summary; 36 | } 37 | 38 | private static void summarizeJob(Job job, TestResultSummary summary, boolean hideZeroTestProjects) { 39 | boolean addBlank = true; 40 | TestResultProjectAction testResults = job.getAction(TestResultProjectAction.class); 41 | 42 | if (testResults != null) { 43 | AbstractTestResultAction tra = testResults.getLastTestResultAction(); 44 | 45 | if (tra != null) { 46 | addBlank = false; 47 | if (tra.getTotalCount() > 0 || !hideZeroTestProjects) { 48 | summary.addTestResult( 49 | new TestResult(job, tra.getTotalCount(), tra.getFailCount(), tra.getSkipCount())); 50 | } 51 | } 52 | } 53 | 54 | if (addBlank && !hideZeroTestProjects) { 55 | summary.addTestResult(new TestResult(job, 0, 0, 0)); 56 | } 57 | } 58 | 59 | public static TestResult getTestResult(Run run) { 60 | AbstractTestResultAction tra = run.getAction(AbstractTestResultAction.class); 61 | if (tra != null) { 62 | return new TestResult(run.getParent(), tra.getTotalCount(), tra.getFailCount(), tra.getSkipCount()); 63 | } 64 | 65 | return new TestResult(run.getParent(), 0, 0, 0); 66 | } 67 | 68 | private static final boolean isMatrixJob(TopLevelItem item) { 69 | if (!matrixPluginInstalled) { 70 | return false; 71 | } 72 | try { 73 | return item instanceof MatrixProject; 74 | } catch (NoClassDefFoundError x) { 75 | matrixPluginInstalled = false; 76 | } 77 | return false; 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /Implementation-guide.md: -------------------------------------------------------------------------------- 1 | # Implementation Guide 2 | 3 | Much of the benefit of this plugin will be realized when other plugins that 4 | enhance Jenkins offer support for it. 5 | 6 | ## Add support in your plugin 7 | 8 | - Extend the DashboardPortlet class and provide a descriptor that 9 | extends the `Descriptor` 10 | - Create a jelly view called *portlet.jelly* 11 | - Optionally create a jelly view called *main.jelly* to be used when the portlet 12 | is in maximized mode (otherwise the same *portlet.jelly* view will be used) 13 | 14 | It is possible to define custom parameters for the DashboardPortlet. The 15 | displayName is always required. To add new parameters: 16 | 17 | - create a jelly file called *config.jelly* to be used when the portlet is 18 | configured (added to the view in 'Edit View' config page); 19 | - modify constructor (with `@DataBoundConstructor`) to receive the new 20 | parameters. 21 | 22 | Looking at the source code of this plugin will show a number of examples 23 | of doing this. The core portlets do the same thing that your plugin 24 | would do. 25 | 26 | ## Sample files 27 | 28 | ***MyPortlet.java*** 29 | 30 | ``` 31 | import hudson.plugins.view.dashboard.DashboardPortlet; 32 | 33 | class MyPortlet extends DashboardPortlet { 34 | 35 | @DataBoundConstructor 36 | public MyPortlet(String name) { 37 | super(name); 38 | } 39 | 40 | // do whatever you want 41 | 42 | @Extension 43 | public static class DescriptorImpl extends Descriptor { 44 | @Override 45 | public String getDisplayName() { 46 | return "MyPortlet"; 47 | } 48 | } 49 | }; 50 | ``` 51 | 52 | ***portlet.jelly*** 53 | 54 | If you want to show a single table inside the portlet use *dp:decorate-table*. This ensures that the table is properly 55 | rendered and really fills the complete area (The default styling of Jenkins adds rounded borders everywhere and a margin 56 | at the bottom that make it look not so nice).
57 | You can pass additional classes to be set on the table, e.g. to make it sortable.
58 | ``` 59 | 60 | 61 | 62 | 63 | 64 | Name 65 | Description 66 | 67 | 68 | 69 | 70 | 71 | ${col.name} 72 | ${col.description} 73 | 74 | 75 | 76 | 77 | 78 | ``` 79 | 80 | To show any other kind of content use *dp:decorate-plain* 81 | ``` 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | ``` 90 | -------------------------------------------------------------------------------- /src/main/java/hudson/plugins/view/dashboard/core/UnstableJobsPortlet.java: -------------------------------------------------------------------------------- 1 | package hudson.plugins.view.dashboard.core; 2 | 3 | import hudson.Extension; 4 | import hudson.model.*; 5 | import hudson.plugins.view.dashboard.DashboardPortlet; 6 | import hudson.plugins.view.dashboard.Messages; 7 | import hudson.views.JobColumn; 8 | import hudson.views.ListViewColumn; 9 | import hudson.views.StatusColumn; 10 | import hudson.views.WeatherColumn; 11 | import java.util.ArrayList; 12 | import java.util.Arrays; 13 | import java.util.Collection; 14 | import java.util.IdentityHashMap; 15 | import java.util.Iterator; 16 | import org.kohsuke.stapler.DataBoundConstructor; 17 | 18 | /** 19 | * Portlet display a list of unstable (or worse) jobs in a simple tabular format. 20 | * 21 | * @author Peter Hayes 22 | */ 23 | public class UnstableJobsPortlet extends DashboardPortlet { 24 | 25 | private static final Collection COLUMNS = 26 | Arrays.asList(new StatusColumn(), new WeatherColumn(), new JobColumn()); 27 | private boolean showOnlyFailedJobs = false; 28 | private final boolean recurse; 29 | 30 | @DataBoundConstructor 31 | public UnstableJobsPortlet(String name, boolean showOnlyFailedJobs, boolean recurse) { 32 | super(name); 33 | this.showOnlyFailedJobs = showOnlyFailedJobs; 34 | this.recurse = recurse; 35 | } 36 | 37 | /** Given a list of all jobs, return just those that are unstable or worse. */ 38 | public Collection getUnstableJobs(Collection allJobs) { 39 | ArrayList unstableJobs = new ArrayList<>(); 40 | Result expected = this.showOnlyFailedJobs ? Result.FAILURE : Result.UNSTABLE; 41 | 42 | for (Item item : allJobs) { 43 | if (!(item instanceof TopLevelItem)) { 44 | continue; 45 | } 46 | if (recurse && item instanceof ItemGroup) { 47 | unstableJobs.addAll(getUnstableJobs(((ItemGroup) item).getItems())); 48 | } 49 | if (item instanceof Job) { 50 | Job job = (Job) item; 51 | Run run = job.getLastCompletedBuild(); 52 | 53 | if (run != null) { 54 | Result result = run.getResult(); 55 | if (result != null && expected.isBetterOrEqualTo(result)) { 56 | unstableJobs.add(job); 57 | } 58 | } 59 | } 60 | } 61 | if (recurse) { 62 | IdentityHashMap duplicates = new IdentityHashMap<>(unstableJobs.size()); 63 | for (Iterator iterator = unstableJobs.iterator(); iterator.hasNext(); ) { 64 | Job j = iterator.next(); 65 | if (duplicates.containsKey(j)) { 66 | iterator.remove(); 67 | } else { 68 | duplicates.put(j, null); 69 | } 70 | } 71 | } 72 | 73 | return unstableJobs; 74 | } 75 | 76 | public Collection getColumns() { 77 | return COLUMNS; 78 | } 79 | 80 | public boolean isShowOnlyFailedJobs() { 81 | return this.showOnlyFailedJobs; 82 | } 83 | 84 | public boolean isRecurse() { 85 | return recurse; 86 | } 87 | 88 | @Extension 89 | public static class DescriptorImpl extends Descriptor { 90 | 91 | @Override 92 | public String getDisplayName() { 93 | return Messages.Dashboard_UnstableJobs(); 94 | } 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/Dashboard/configure-entries_ja.properties: -------------------------------------------------------------------------------- 1 | # The MIT License 2 | # 3 | # Copyright (c) 2004-2010, Sun Microsystems, Inc. 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in 13 | # all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | # THE SOFTWARE. 22 | 23 | Add\ Dashboard\ Portlet\ to\ bottom\ of\ the\ view=\u30d3\u30e5\u30fc\u306e\u4e0b\u90e8\u306b\u30dd\u30fc\u30c8\u30ec\u30c3\u30c8\u3092\u8ffd\u52a0 24 | Add\ Dashboard\ Portlet\ to\ left\ column=\u30d3\u30e5\u30fc\u306e\u5de6\u90e8\u306b\u30dd\u30fc\u30c8\u30ec\u30c3\u30c8\u3092\u8ffd\u52a0 25 | Add\ Dashboard\ Portlet\ to\ right\ column=\u30d3\u30e5\u30fc\u306e\u53f3\u90e8\u306b\u30dd\u30fc\u30c8\u30ec\u30c3\u30c8\u3092\u8ffd\u52a0 26 | Add\ Dashboard\ Portlet\ to\ the\ top\ of\ the\ view=\u30d3\u30e5\u30fc\u306e\u4e0a\u90e8\u306b\u30dd\u30fc\u30c8\u30ec\u30c3\u30c8\u3092\u8ffd\u52a0 27 | Portlets\ at\ the\ bottom\ of\ the\ page=\u30da\u30fc\u30b8\u306e\u4e0b\u90e8\u306b\u914d\u7f6e\u3059\u308b\u30dd\u30fc\u30c8\u30ec\u30c3\u30c8 28 | Dashboard\ Portlets=\u30c0\u30c3\u30b7\u30e5\u30dc\u30fc\u30c9\u30dd\u30fc\u30c8\u30ec\u30c3\u30c8 29 | Jobs=\u30b8\u30e7\u30d6 30 | Portlets\ in\ the\ left\ column=\u30da\u30fc\u30b8\u306e\u5de6\u90e8\u306b\u914d\u7f6e\u3059\u308b\u30dd\u30fc\u30c8\u30ec\u30c3\u30c8 31 | Regular\ expression=\u6b63\u898f\u8868\u73fe 32 | Portlets\ in\ the\ right\ column=\u30da\u30fc\u30b8\u306e\u53f3\u90e8\u306b\u914d\u7f6e\u3059\u308b\u30dd\u30fc\u30c8\u30ec\u30c3\u30c8 33 | Show\ standard\ Jenkins\ list\ at\ the\ top\ of\ the\ page=\u30da\u30fc\u30b8\u4e0a\u90e8\u306b\u6a19\u6e96\u306eJenkins\u30ea\u30b9\u30c8\u3092\u8868\u793a 34 | Portlets\ at\ the\ top\ of\ the\ page=\u30da\u30fc\u30b8\u306e\u4e0a\u90e8\u306b\u914d\u7f6e\u3059\u308b\u30dd\u30fc\u30c8\u30ec\u30c3\u30c8 35 | Use\ a\ regular\ expression\ to\ include\ jobs\ into\ the\ view=\u30d3\u30e5\u30fc\u306b\u542b\u3081\u308b\u30b8\u30e7\u30d6\u3092\u6b63\u898f\u8868\u73fe\u3067\u6307\u5b9a 36 | Left\ portlet\ width=\u5de6\u30dd\u30fc\u30c8\u30ec\u30c3\u30c8\u306e\u5e45 37 | Right\ portlet\ width=\u53f3\u30dd\u30fc\u30c8\u30ec\u30c3\u30c8\u306e\u5e45 38 | Set\ CSS\ custom\ parameters=CSS\u30ab\u30b9\u30bf\u30e0\u30d1\u30e9\u30e1\u30fc\u30bf\u3092\u8a2d\u5b9a 39 | Status\ Filter=\u30b9\u30c6\u30fc\u30bf\u30b9\u30d5\u30a3\u30eb\u30bf\u30fc 40 | Add\ column=\u30ab\u30e9\u30e0\u3092\u8ffd\u52a0 41 | Enabled\ jobs\ only=\u6709\u52b9\u306a\u30b8\u30e7\u30d6\u306e\u307f 42 | All\ selected\ jobs=\u9078\u629e\u6e08\u307f\u30b8\u30e7\u30d6\u3092\u3059\u3079\u3066 43 | Add\ Job\ Filter=\u30b8\u30e7\u30d6\u30d5\u30a3\u30eb\u30bf\u3092\u8ffd\u52a0 44 | Job\ Filters=\u30b8\u30e7\u30d6\u30d5\u30a3\u30eb\u30bf\u30fc 45 | Columns=\u30ab\u30e9\u30e0 46 | Disabled\ jobs\ only=\u7121\u52b9\u306a\u30b8\u30e7\u30d6\u306e\u307f 47 | -------------------------------------------------------------------------------- /src/test/java/hudson/plugins/view/dashboard/ConfigurationAsCodeBackCompatTest.java: -------------------------------------------------------------------------------- 1 | package hudson.plugins.view.dashboard; 2 | 3 | import static io.jenkins.plugins.casc.misc.Util.getJenkinsRoot; 4 | import static org.hamcrest.MatcherAssert.assertThat; 5 | import static org.hamcrest.Matchers.containsInAnyOrder; 6 | import static org.hamcrest.Matchers.containsString; 7 | import static org.hamcrest.Matchers.equalTo; 8 | import static org.hamcrest.Matchers.hasProperty; 9 | import static org.hamcrest.Matchers.instanceOf; 10 | import static org.hamcrest.Matchers.is; 11 | import static org.hamcrest.Matchers.notNullValue; 12 | import static org.hamcrest.core.AllOf.allOf; 13 | 14 | import hudson.plugins.view.dashboard.core.ImagePortlet; 15 | import io.jenkins.plugins.casc.ConfigurationContext; 16 | import io.jenkins.plugins.casc.ConfiguratorRegistry; 17 | import io.jenkins.plugins.casc.ObsoleteConfigurationMonitor; 18 | import io.jenkins.plugins.casc.misc.ConfiguredWithCode; 19 | import io.jenkins.plugins.casc.misc.JenkinsConfiguredWithCodeRule; 20 | import io.jenkins.plugins.casc.misc.Util; 21 | import io.jenkins.plugins.casc.misc.junit.jupiter.WithJenkinsConfiguredWithCode; 22 | import io.jenkins.plugins.casc.model.CNode; 23 | import java.util.List; 24 | import org.hamcrest.Description; 25 | import org.hamcrest.Matcher; 26 | import org.hamcrest.TypeSafeDiagnosingMatcher; 27 | import org.junit.jupiter.api.Test; 28 | import org.jvnet.hudson.test.Issue; 29 | 30 | @WithJenkinsConfiguredWithCode 31 | class ConfigurationAsCodeBackCompatTest { 32 | 33 | @Test 34 | @Issue("SECURITY-2233") 35 | @ConfiguredWithCode("casc_image_backcompat_import.yml") 36 | void testOldImagePortletUrl(JenkinsConfiguredWithCodeRule j) throws Exception { 37 | Dashboard.DescriptorImpl descriptor = j.jenkins.getDescriptorByType(Dashboard.DescriptorImpl.class); 38 | assertThat(descriptor, notNullValue()); 39 | 40 | Dashboard dashboard = (Dashboard) j.jenkins.getView("test"); 41 | assertThat(dashboard.getViewName(), is("test")); 42 | List leftPortlets = dashboard.getLeftPortlets(); 43 | assertThat( 44 | leftPortlets.get(0), 45 | allOf( 46 | instanceOf(ImagePortlet.class), 47 | hasProperty("name", equalTo("Image")), 48 | hasProperty("imageUrl", equalTo("test-backcompat")))); 49 | 50 | final List errors = 51 | ObsoleteConfigurationMonitor.get().getErrors(); 52 | assertThat(errors, containsInAnyOrder(new ErrorMatcher(containsString("'url' is deprecated")))); 53 | 54 | final ConfiguratorRegistry registry = ConfiguratorRegistry.get(); 55 | final ConfigurationContext context = new ConfigurationContext(registry); 56 | CNode node = getJenkinsRoot(context).get("views").asSequence().get(0).asMapping(); 57 | 58 | final String exported = Util.toYamlString(node); 59 | final String expected = Util.toStringFromYamlFile(this, "casc_image_backcompat_export.yml"); 60 | 61 | assertThat(exported, is(expected)); 62 | } 63 | 64 | static class ErrorMatcher extends TypeSafeDiagnosingMatcher { 65 | final Matcher messageMatcher; 66 | 67 | public ErrorMatcher(final Matcher messageMatcher) { 68 | this.messageMatcher = messageMatcher; 69 | } 70 | 71 | @Override 72 | protected boolean matchesSafely( 73 | final ObsoleteConfigurationMonitor.Error item, final Description mismatchDescription) { 74 | return messageMatcher.matches(item.message); 75 | } 76 | 77 | @Override 78 | public void describeTo(final Description description) { 79 | description.appendDescriptionOf(messageMatcher); 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/main/java/hudson/plugins/view/dashboard/test/TestStatisticsChart.java: -------------------------------------------------------------------------------- 1 | package hudson.plugins.view.dashboard.test; 2 | 3 | import hudson.Extension; 4 | import hudson.model.Descriptor; 5 | import hudson.plugins.view.dashboard.DashboardPortlet; 6 | import hudson.plugins.view.dashboard.Messages; 7 | import hudson.util.ColorPalette; 8 | import hudson.util.Graph; 9 | import java.awt.Color; 10 | import java.awt.Paint; 11 | import java.text.NumberFormat; 12 | import java.util.ArrayList; 13 | import java.util.List; 14 | import org.jfree.chart.ChartFactory; 15 | import org.jfree.chart.JFreeChart; 16 | import org.jfree.chart.labels.StandardPieSectionLabelGenerator; 17 | import org.jfree.chart.plot.DefaultDrawingSupplier; 18 | import org.jfree.chart.plot.PiePlot; 19 | import org.jfree.data.general.DefaultPieDataset; 20 | import org.kohsuke.stapler.DataBoundConstructor; 21 | 22 | public class TestStatisticsChart extends DashboardPortlet { 23 | 24 | @DataBoundConstructor 25 | public TestStatisticsChart(String name) { 26 | super(name); 27 | } 28 | 29 | /** 30 | * Graph of duration of tests over time. 31 | */ 32 | public Graph getSummaryGraph() { 33 | final TestResultSummary summary = 34 | TestUtil.getTestResultSummary(getDashboard().getItems(), false); 35 | 36 | return new Graph(-1, 300, 220) { 37 | 38 | @Override 39 | protected JFreeChart createGraph() { 40 | DefaultPieDataset dataset = new DefaultPieDataset(); 41 | dataset.setValue(Messages.Dashboard_Success(), summary.getSuccess()); 42 | dataset.setValue(Messages.Dashboard_Skipped(), summary.getSkipped()); 43 | dataset.setValue(Messages.Dashboard_Failed(), summary.getFailed()); 44 | JFreeChart chart = ChartFactory.createPieChart(null, dataset, false, false, false); 45 | 46 | chart.setBackgroundPaint(Color.white); 47 | 48 | final PiePlot plot = (PiePlot) chart.getPlot(); 49 | 50 | // plot.setAxisOffset(new Spacer(Spacer.ABSOLUTE, 5.0, 5.0, 5.0, 5.0)); 51 | plot.setBackgroundPaint(Color.WHITE); 52 | plot.setOutlinePaint(null); 53 | plot.setForegroundAlpha(0.8f); 54 | 55 | // create arraylist of paint color, adding only color if related stat is > 0 56 | List paints = new ArrayList(); 57 | if (summary.getSuccess() > 0) { 58 | paints.add(ColorPalette.BLUE); 59 | } 60 | if (summary.getSkipped() > 0) { 61 | paints.add(ColorPalette.YELLOW); 62 | } 63 | if (summary.getFailed() > 0) { 64 | paints.add(ColorPalette.RED); 65 | } 66 | 67 | DefaultDrawingSupplier ds = new DefaultDrawingSupplier( 68 | paints.toArray(new Paint[0]), 69 | DefaultDrawingSupplier.DEFAULT_OUTLINE_PAINT_SEQUENCE, 70 | DefaultDrawingSupplier.DEFAULT_STROKE_SEQUENCE, 71 | DefaultDrawingSupplier.DEFAULT_OUTLINE_STROKE_SEQUENCE, 72 | DefaultDrawingSupplier.DEFAULT_SHAPE_SEQUENCE); 73 | plot.setDrawingSupplier(ds); 74 | 75 | plot.setLabelGenerator(new StandardPieSectionLabelGenerator( 76 | "{0} = {1} ({2})", NumberFormat.getNumberInstance(), NumberFormat.getPercentInstance())); 77 | plot.setNoDataMessage(Messages.Dashboard_NoDataAvailable()); 78 | 79 | return chart; 80 | } 81 | }; 82 | } 83 | 84 | @Extension 85 | public static class DescriptorImpl extends Descriptor { 86 | 87 | @Override 88 | public String getDisplayName() { 89 | return Messages.Dashboard_TestStatisticsChart(); 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/Dashboard/main.jelly: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 8 |
9 | 11 |
12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 50 | 51 | 52 | 53 | 54 |
55 |
56 | 57 | 58 | 59 | 60 | 61 |
62 | 63 | 64 |
65 | 66 | 67 | 68 | 69 |
70 |
71 | 72 | 73 |
74 | 75 | 76 | 77 | 78 |
79 |
80 | 81 | 82 |
83 | 84 | 85 | 86 | 87 | 88 | 89 |
90 |
91 | 92 | 94 | 95 |
96 |
97 |
98 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/Dashboard/configure-entries.jelly: -------------------------------------------------------------------------------- 1 | 24 | 25 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 59 | 60 | 61 | 62 | 63 | 67 | 68 | 69 | 70 | 71 | 75 | 76 | 77 | 78 | 79 | 83 | 84 |

85 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /src/main/java/hudson/plugins/view/dashboard/stats/StatJobs.java: -------------------------------------------------------------------------------- 1 | package hudson.plugins.view.dashboard.stats; 2 | 3 | import hudson.Extension; 4 | import hudson.model.Descriptor; 5 | import hudson.model.Job; 6 | import hudson.model.TopLevelItem; 7 | import hudson.plugins.view.dashboard.DashboardPortlet; 8 | import hudson.plugins.view.dashboard.Messages; 9 | import java.util.List; 10 | import java.util.Map; 11 | import java.util.SortedMap; 12 | import java.util.TreeMap; 13 | import org.kohsuke.stapler.DataBoundConstructor; 14 | 15 | /** 16 | * Job statistics - number of jobs with given health status 17 | * 18 | * @author Vojtech Juranek 19 | */ 20 | public class StatJobs extends DashboardPortlet { 21 | 22 | @DataBoundConstructor 23 | public StatJobs(String name) { 24 | super(name); 25 | } 26 | 27 | /** 28 | * Heath status of the builds (use enum not class for it) 29 | * 30 | * FIXME: Should be refactored to not duplicate logic from Jenkins core. 31 | * 32 | * @deprecated Should be replaced with {@link hudson.model.HealthReport} 33 | */ 34 | @Deprecated 35 | public enum HealthStatus { 36 | HEALTH_OVER_80("symbol-weather-icon-health-80plus", Messages.Dashboard_NoRecentBuildsFailed(), 100), 37 | HEALTH_60_TO_79("symbol-weather-icon-health-60to79", Messages.Dashboard_RecentBuildsFailed("20", "40"), 80), 38 | HEALTH_40_TO_59("symbol-weather-icon-health-40to59", Messages.Dashboard_RecentBuildsFailed("40", "60"), 60), 39 | HEALTH_20_TO_39("symbol-weather-icon-health-20to39", Messages.Dashboard_RecentBuildsFailed("60", "80"), 40), 40 | HEALTH_0_TO_19("symbol-weather-icon-health-00to19", Messages.Dashboard_AllRecentBuildsFailed(), 20), 41 | HEALTH_UNKNOWN("symbol-indeterminate", Messages.Dashboard_UnknownStatus(), 0); 42 | // private HealthReport healthReport; 43 | private final String iconClassName; 44 | private final String description; 45 | 46 | private int score; 47 | 48 | HealthStatus(String iconClassName, String description, int score) { 49 | this.iconClassName = iconClassName; 50 | this.description = description; 51 | this.score = score; 52 | } 53 | 54 | public static HealthStatus getHealthStatus(Job job) { 55 | int score = job.getBuildHealth().getScore(); 56 | if (score <= 20) { 57 | return HEALTH_0_TO_19; 58 | } 59 | if (score <= 40) { 60 | return HEALTH_20_TO_39; 61 | } 62 | if (score <= 60) { 63 | return HEALTH_40_TO_59; 64 | } 65 | if (score <= 80) { 66 | return HEALTH_60_TO_79; 67 | } 68 | 69 | return job.getFirstBuild() != null ? HEALTH_OVER_80 : HEALTH_UNKNOWN; 70 | } 71 | 72 | public String getIconClassName() { 73 | return iconClassName; 74 | } 75 | 76 | public int getScore() { 77 | return score; 78 | } 79 | 80 | public String getDescription() { 81 | return description; 82 | } 83 | } 84 | 85 | /** 86 | * Project statistics - number of projects with given health status 87 | */ 88 | public Map getJobStat(List jobs) { 89 | SortedMap colStatJobs = new TreeMap(); 90 | for (HealthStatus status : HealthStatus.values()) { 91 | colStatJobs.put(status, 0); 92 | } 93 | // Job and build statistics 94 | for (TopLevelItem job : jobs) { 95 | if (job instanceof Job) { 96 | HealthStatus status = HealthStatus.getHealthStatus(((Job) job)); 97 | colStatJobs.put(status, colStatJobs.get(status) + 1); 98 | } 99 | } 100 | return colStatJobs; 101 | } 102 | 103 | @Extension 104 | public static class DescriptorImpl extends Descriptor { 105 | 106 | @Override 107 | public String getDisplayName() { 108 | return Messages.Dashboard_JobStatistics(); 109 | } 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /src/main/resources/hudson/plugins/view/dashboard/test/TestStatisticsPortlet/teststatistics.jelly: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | ${%Job} 11 | ${%Success} # 12 | % 13 | ${%Failed} # 14 | % 15 | ${%Skipped} # 16 | % 17 | ${%Total} # 18 | 19 | 20 | 21 | 22 | 23 | 25 |

26 | 27 |
28 | 29 | 30 | ${tr.success} 31 | 32 | 33 | ${it.format(format, tr.successPct)} 34 | 35 | 36 | ${tr.failed} 37 | 38 | 39 | ${it.format(format, tr.failedPct)} 40 | 41 | 42 | ${tr.skipped} 43 | 44 | 45 | ${it.format(format, tr.skippedPct)} 46 | 47 | 48 | ${tr.tests} 49 | 50 | 51 | 52 | 53 | 54 | 56 | ${%Total} 57 | 58 | 60 | ${summary.success} 61 | 62 | 64 | ${it.format(format, summary.successPct)} 65 | 66 | 68 | ${summary.failed} 69 | 70 | 72 | ${it.format(format, summary.failedPct)} 73 | 74 | 76 | ${summary.skipped} 77 | 78 | 80 | ${it.format(format, summary.skippedPct)} 81 | 82 | 84 | ${summary.tests} 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 |
93 | 94 |
95 | 96 | ${tr.success} 97 | ${it.format(format, tr.successPct)} 98 | ${tr.failed} 99 | ${it.format(format, tr.failedPct)} 100 | ${tr.skipped} 101 | ${it.format(format, tr.skippedPct)} 102 | ${tr.tests} 103 | 104 |
105 | 106 | 107 | ${%Total} 108 | ${summary.success} 109 | ${it.format(format, summary.successPct)} 110 | ${summary.failed} 111 | ${it.format(format, summary.failedPct)} 112 | ${summary.skipped} 113 | ${it.format(format, summary.skippedPct)} 114 | ${summary.tests} 115 | 116 |
117 | 118 |
119 | --------------------------------------------------------------------------------