動(dòng)手實(shí)踐:美化 Jenkins 報(bào)告插件的用戶界面

本文首發(fā)于: Jenkins 中文社區(qū)

原文鏈接 作者:Ullrich Hafner

譯者:wenjunzhangp

動(dòng)手實(shí)踐:美化 Jenkins 報(bào)告插件的用戶界面

進(jìn)來看看呢诬,關(guān)于 Jenkins 新的 UI 插件介紹以及他們的教程搂鲫、用法都在這里了

封面圖

對于 Jenkins 而言型奥,可以使用大量插件來可視化各種構(gòu)建步驟的結(jié)果组砚。有一些插件可用于呈現(xiàn)測試結(jié)果、代碼覆蓋率、靜態(tài)分析等屉凯。所有這些插件通常都會(huì)獲取給定構(gòu)建步驟的構(gòu)建結(jié)果父虑,并在用戶界面中顯示它們母赵。為了呈現(xiàn)這些細(xì)節(jié)逸爵,大多數(shù)插件使用靜態(tài) HTML 頁面,因?yàn)檫@種類型的用戶界面是 Jenkins 自 2007 年成立以來的標(biāo)準(zhǔn)可視化凹嘲。

為了改善這些插件的外觀和用戶體驗(yàn)痊银,有必要向前發(fā)展并合并一些現(xiàn)代 Java Script 庫和組件。由于 Blue Ocean 的開發(fā)已經(jīng)停止(請參閱Jenkins mailing list post)施绎,因此插件作者需要自己決定溯革,哪些 UI 技術(shù)可幫助完成該任務(wù)。但是谷醉,現(xiàn)代 UI 組件的種類繁多致稀,以至于只挑選一小部分被證明是有用的并且與 Jenkins 基礎(chǔ) Web 技術(shù)兼容的組件是有意義的。而且俱尼,合并這樣一個(gè)新組件的初始設(shè)置相當(dāng)大抖单,因此如果該工作僅需要執(zhí)行一次,將會(huì)有很大的幫助遇八。

本指南介紹了一些 UI 組件矛绘,以后所有插件作者都可以使用這些 UI 組件,從而為 Jenkins 中的報(bào)告提供豐富的用戶界面刃永。為了簡化這些庫在 Jenkins 作為基于 Java 的 Web 應(yīng)用程序的上下文中的使用货矮,這些 Java Script 庫和組件已打包為普通的 Jenkins 插件。

在以下各小節(jié)中斯够,將逐步介紹這些新組件囚玫。為了了解如何使用這些組件的插件,我將演示新功能读规,同時(shí)使用新的用戶界面增強(qiáng)現(xiàn)有的Forensics Plugin抓督。由于 Warnings Next Generation 插件也使用這些新組件,因此您可以在warnings 插件的文檔中或在我們的公共ci.jenkins.io 實(shí)例中看到其他示例束亏,這些示例已經(jīng)在 warnings 插件的詳細(xì)信息視圖中使用了這些組件铃在。

新的用戶界面插件

新的 Jenkins 插件提供了以下 UI 組件:

  • jquery3-api-plugin:為 Jenkins 插件提供jQuery 3。如其首頁所述碍遍,jQuery 是一個(gè)快速定铜、小型且功能豐富的 JavaScript 庫。借助易于使用的 API(可在多種瀏覽器中使用)雀久,使 HTML 文檔的遍歷和操作宿稀、事件處理趁舀、動(dòng)畫和 Ajax 等事情變得更加簡單赖捌。兼具多功能性和可擴(kuò)展性,jQuery 改變了數(shù)百萬人編寫 JavaScript 的方式。
  • bootstrap4-api-plugin:為 Jenkins 插件提供Bootstrap 4越庇。Bootstrap 自稱是世界上最流行的前端組件庫罩锐,用于在 Web 上構(gòu)建響應(yīng)式,移動(dòng)優(yōu)先的項(xiàng)目卤唉。它是一個(gè)用于使用 HTML涩惑、CSS 和 JS 開發(fā)的開源工具包。開發(fā)人員可以使用他們的 Sass 變量和 mixins桑驱、響應(yīng)式柵格系統(tǒng)竭恬、大量的預(yù)構(gòu)建組件以及基于 jQuery 構(gòu)建的強(qiáng)大插件,快速構(gòu)建其思想原型或整個(gè)應(yīng)用程序熬的。
  • data-tables-api-plugin:提供 Jenkins 插件的數(shù)據(jù)表格痊硕。DataTables 是 jQuery Javascript 庫的插件。這是一個(gè)高度靈活的工具押框,建立在逐步增強(qiáng)的基礎(chǔ)上岔绸,可將所有這些高級(jí)功能添加到任何 HTML 表中:
    • 上一頁,下一頁和頁面導(dǎo)航
    • 通過文本搜索過濾結(jié)果
    • 一次按多列對數(shù)據(jù)排序
    • DOM橡伞、Javascript盒揉、Ajax、服務(wù)器端處理
    • 簡單主題化
    • 手機(jī)端兼容友好
  • echarts-api-plugin:為 Jenkins 插件提供ECharts兑徘。ECharts 是一種開放源代碼的 JavaScript 可視化工具刚盈,用于創(chuàng)建直觀、交互式和高度可定制的圖表挂脑。它可以在 PC 和移動(dòng)設(shè)備上流暢運(yùn)行航攒,并且與大多數(shù)現(xiàn)代 Web 瀏覽器兼容施禾。
  • font-awesome-api-plugin:為 Jenkins 插件提供Font Awesome。Font Awesome 具有矢量圖標(biāo)和社交徽標(biāo),號(hào)稱是網(wǎng)絡(luò)上最受歡迎的圖標(biāo)集和工具包掰盘。目前,它包含 1,500 多個(gè)免費(fèi)圖標(biāo)帐姻。
  • popper-api-plugin:為 Jenkins 插件提供Popper.js酒觅。Popper 只需一行代碼即可輕松定位工具提示,彈出窗口或其他任何內(nèi)容薄翅。
  • plugin-util-api-plugin:這個(gè)小插件提供了一些幫助程序和基類沙兰,以簡化 Jenkins 中報(bào)告程序的創(chuàng)建。該插件還提供了一組體系結(jié)構(gòu)規(guī)則翘魄,這些規(guī)則可以包含在插件的體系結(jié)構(gòu)測試套件中鼎天。

POM 文件必要的改變

為了使用這些插件,您需要將它們作為依賴項(xiàng)添加到插件 pom 中暑竟。您可以使用以下代碼段將其全部添加:

pom.xml
<project>

 [...]

  <properties>
    <plugin-util-api.version>1.0.2</plugin-util-api.version>
    <font-awesome-api.version>5.12.0-7</font-awesome-api.version>
    <bootstrap4-api.version>4.4.1-10</bootstrap4-api.version>
    <echarts-api.version>4.6.0-8</echarts-api.version>
    <data-tables-api.version>1.10.20-13</data-tables-api.version>
    [...]
  </properties>

  <dependencies>
    <dependency>
      <groupId>io.jenkins.plugins</groupId>
      <artifactId>plugin-util-api</artifactId>
      <version>${plugin-util-api.version}</version>
    </dependency>
    <dependency>
      <groupId>io.jenkins.plugins</groupId>
      <artifactId>font-awesome-api</artifactId>
      <version>${font-awesome-api.version}</version>
    </dependency>
    <dependency>
      <groupId>io.jenkins.plugins</groupId>
      <artifactId>bootstrap4-api</artifactId>
      <version>${bootstrap4-api.version}</version>
    </dependency>
    <dependency>
      <groupId>io.jenkins.plugins</groupId>
      <artifactId>echarts-api</artifactId>
      <version>${echarts-api.version}</version>
    </dependency>
    <dependency>
      <groupId>io.jenkins.plugins</groupId>
      <artifactId>data-tables-api</artifactId>
      <version>${data-tables-api.version}</version>
    </dependency>
    [...]
  </dependencies>

  [...]

</project>

或者斋射,您可以查看Warnings Next Generation 插件Forensics API 插件的 POM 文件,它們已經(jīng)使用了這些插件。

報(bào)告的總體結(jié)構(gòu)

在本節(jié)中罗岖,我將解釋 Jenkins 設(shè)計(jì)的一些基礎(chǔ)知識(shí)涧至,即 Java 模型和相關(guān)的用戶界面元素。如果您已經(jīng)熟悉如何實(shí)現(xiàn)報(bào)告插件的相應(yīng)擴(kuò)展點(diǎn)(請參閱 Jenkins 開發(fā)人員指南中的可擴(kuò)展性部分)桑包,則可以跳過本節(jié)南蓬,直接進(jìn)入第3.1節(jié)。

Jenkins 使用圖 1所示的靜態(tài)對象模型結(jié)構(gòu)來組織項(xiàng)目哑了。

jenkins-design

Jenkins 用戶界面中的頂級(jí)項(xiàng)目是工作(至少是我們感興趣的頂級(jí)項(xiàng)目)赘方。Jenkins 包含多個(gè)不同類型的任務(wù)(自由式任務(wù)、Maven任務(wù)弱左、流水線等)蒜焊。

這些任務(wù)中的每一個(gè)都包含任意數(shù)量的構(gòu)建(或更確切地說,是運(yùn)行)科贬。每個(gè)版本均由其唯一的版本號(hào)標(biāo)識(shí)泳梆。Jenkins 插件可以將結(jié)果附加到這些版本中,例如生成工件榜掌、測試結(jié)果优妙、分析報(bào)告等。為了附加這樣的結(jié)果憎账,插件在技術(shù)上需要實(shí)現(xiàn)并創(chuàng)建存儲(chǔ)這些結(jié)果的操作套硼。

這些 Java 對象在幾種不同的視圖中可視化,以下各節(jié)將對其進(jìn)行詳細(xì)描述胞皱。顯示所有可用任務(wù)的頂級(jí)視圖如圖 2所示邪意。

jobs

插件還可以在這些視圖中提供 UI 元素,但這超出了本指南的范圍反砌。

每個(gè)任務(wù)都有一個(gè)詳細(xì)視圖雾鬼,插件可以在其中擴(kuò)展相應(yīng)的擴(kuò)展點(diǎn)并提供摘要框和趨勢圖。通常宴树,在工作級(jí)別上不需要報(bào)告者摘要框策菜,因此我僅更詳細(xì)地描述趨勢圖,請參見第5.5.2節(jié)酒贬。

job

每個(gè)版本也都有一個(gè)詳細(xì)視圖又憨。在這里,插件可以提供類似于“工作詳細(xì)信息”視圖的框的摘要框锭吨。通常蠢莺,插件在這里僅顯示簡短摘要,并提供指向詳細(xì)結(jié)果的鏈接零如,有關(guān)示例躏将,請參見圖 4锄弱。

build

視圖層次結(jié)構(gòu)中的最后一個(gè)元素實(shí)際上是一個(gè)專用視圖,它顯示特定插件的結(jié)果耸携。例如棵癣,有些視圖可顯示測試結(jié)果辕翰,分析結(jié)果等夺衍。完全由給定的插件決定應(yīng)在此處顯示哪些元素。在接下來的幾節(jié)中喜命,我將介紹一些新的 UI 組件沟沙,這些組件可用于以愉悅的方式顯示相應(yīng)的結(jié)果。

擴(kuò)展 Jenkins 對象模型

由于報(bào)告程序通常以類似的方式構(gòu)成壁榕,因此我用一些其他元素?cái)U(kuò)展了 Jenkins 的原始對象模型(參見圖 1)矛紫,因此創(chuàng)建或?qū)崿F(xiàn)新的報(bào)告程序插件將更加簡單。這個(gè)新模型如圖 5所示牌里。中心元素是構(gòu)建操作颊咬,它將存儲(chǔ)插件報(bào)告程序的結(jié)果。此操作將附加到每個(gè)內(nèi)部版本牡辽,并將為報(bào)告者保存(并保留)結(jié)果喳篇。每個(gè)動(dòng)作的詳細(xì)數(shù)據(jù)將自動(dòng)存儲(chǔ)在其他文件中,因此态辛,如果用戶從不要求提供詳細(xì)信息麸澜,則 Jenkins 的內(nèi)存占用空間可以保持較小。另外奏黑,該動(dòng)作還用于簡化項(xiàng)目動(dòng)作和趨勢圖的創(chuàng)建炊邦,請參見第5.5.2節(jié)。

Git Forensics 插件

本教程中的元素將全部在新的Forensics API 插件中使用(實(shí)際上熟史,該插件不是新的馁害,它是Warnings Next Generation插件的依賴項(xiàng))。您可以下載插件內(nèi)容蹂匹,并詳細(xì)了解如何在實(shí)踐中使用這些新組件蜗细。或者怒详,您可以更改此插件炉媒,只是為了了解如何對這些新組件進(jìn)行參數(shù)設(shè)置。

如果您將 Git 用作源代碼管理系統(tǒng)昆烁,則此插件將以犯罪現(xiàn)場代碼的樣式(Adam Tornhill吊骤,2013 年 11 月)挖掘存儲(chǔ)庫,以確定所包含源代碼文件的統(tǒng)計(jì)信息:

  • 提交總數(shù)
  • 不同作者總數(shù)
  • 創(chuàng)建時(shí)間
  • 最后一次編輯時(shí)間

該插件提供了一個(gè)新的步驟(或發(fā)布后的發(fā)布者)該步驟開始了存儲(chǔ)庫挖掘并將收集的信息存儲(chǔ)在 Jenkins 操作中(請參見圖 5)静尼。然后白粉,您將獲得一個(gè)新的構(gòu)建摘要传泊,該摘要顯示掃描文件的總數(shù)(趨勢和構(gòu)建結(jié)果)。從這里鸭巴,您可以導(dǎo)航到詳細(xì)信息視圖眷细,該視圖在可以簡單排序和過濾的表中顯示掃描的文件。您還將獲得一些餅圖鹃祖,這些餅圖顯示提交歷史記錄的重要方面溪椎。

請注意,插件的此功能仍是概念證明:此步驟的性能在很大程度上取決于 Git 存儲(chǔ)庫的大小和提交次數(shù)恬口。當(dāng)前校读,它會(huì)掃描每個(gè)版本中的整個(gè)存儲(chǔ)庫。在不久的將來祖能,我希望找到一個(gè)有志于用增量掃描儀替代這種愚蠢算法的志愿者歉秫。

引入新的 UI 組件

第 3 節(jié)所述,詳細(xì)信息視圖特定于插件养铸。顯示的內(nèi)容以及這些元素的顯示方式取決于各個(gè)插件作者雁芙。因此,在接下來的部分中钞螟,我將提供一些示例和新概念兔甘,插件可以將這些示例和新概念用作其自身內(nèi)容的構(gòu)建塊。

現(xiàn)代化圖標(biāo)

Jenkins 插件通常不經(jīng)常使用圖標(biāo)筛圆。大多數(shù)插件都提供了操作圖標(biāo)裂明,僅此而已。如果您打算在其他地方使用圖標(biāo)太援,那么插件作者將自己留著:推薦的 Tango 圖標(biāo)集已有 10 多年的歷史了闽晦,如今太有限了。有幾個(gè)選項(xiàng)可用提岔,但最受歡迎的是Font Awesome Icon Set仙蛉。它提供超過 1500 個(gè)遵循相同設(shè)計(jì)準(zhǔn)則的免費(fèi)圖標(biāo):

font-awesome

為了在插件中使用 Font Awesome 圖標(biāo),您只需要依賴于相應(yīng)的font-awesome-api-plugin即可碱蒙。然后荠瘪,您可以在果凍視圖中使用新標(biāo)簽svg-icon來使用任何實(shí)心圖標(biāo):

index.jelly
1 <j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:l="/lib/layout" xmlns:fa="/font-awesome">
2
3 [...]
4 <fa:svg-icon name="check-double" class="no-issues-banner"/>
5 [...]
6
7 </j:jelly>

如果要使用 Java 代碼生成視圖,則也可以使用SvgTag類為此類圖標(biāo)生成 HTML 標(biāo)記赛惩。

柵格布局

目前哀墓,Jenkins 在所有視圖中都包含 Boostrap 柵格系統(tǒng)的舊版本和補(bǔ)丁版本(24 列)。該版本與 Boostrap4 或任何依賴 Bootstrap4 的 JS 庫不兼容喷兼。為了使用 Bootstrap4 功能篮绰,我們需要用補(bǔ)丁版本替換 Jenkins 提供的layout.jelly文件,該文件不會(huì)加載損壞的柵格系統(tǒng)季惯。我打算創(chuàng)建一個(gè)PR吠各,以修復(fù) Jenkins 核心中的柵格臀突,但這將需要一些時(shí)間。在此之前贾漏,您將需要使用 Boostrap4 插件提供的layout.jelly候学,請參見下文。

首先要確定的是纵散,哪些元素應(yīng)顯示在插件頁面上以及每個(gè)元素應(yīng)占用多少空間梳码。通常,所有可見組件都使用簡單的柵格映射到可用空間上困食。在 Jenkins 視圖中边翁,我們具有固定的頁眉和頁腳以及左側(cè)的導(dǎo)航欄(水平空間的20%)翎承。屏幕的其余部分可由詳細(xì)信息視圖使用硕盹。為了簡化剩余空間中元素的分布,我們使用Bootstrap 的柵格系統(tǒng)叨咖。

grid

這意味著瘩例,一個(gè)視圖被分為 12 列和任意數(shù)量的行。此柵格系統(tǒng)易于使用(但足夠復(fù)雜甸各,還可以支持精美的屏幕布局)-我在這里不做詳細(xì)介紹垛贤,請參考Bootstrap 文檔

對于取證詳細(xì)視圖趣倾,我們使用兩行兩列的簡單柵格聘惦。由于列數(shù)始終為 12,因此我們需要?jiǎng)?chuàng)建兩個(gè)寬列以填充 6 個(gè)標(biāo)準(zhǔn)列儒恋。為了在我們的插件中創(chuàng)建這樣的視圖善绎,我們需要?jiǎng)?chuàng)建一個(gè)以果凍文件和相應(yīng)的 Java 視圖模型對象形式給出的視圖。以下代碼段顯示了具有這種布局的視圖:

index.jelly
1 <?jelly escape-by-default='true'?>
2 <j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:l="/lib/layout" xmlns:bs="/bootstrap">
3
4   <bs:layout title="${it.displayName}" norefresh="true"> 
5       <st:include it="${it.owner}" page="sidepanel.jelly"/>
6       <l:main-panel>
7           <st:adjunct includes="io.jenkins.plugins.bootstrap4"/> 
8           <div class="fluid-container"> 
9
10              <div class="row py-3"> 
11                  <div class="col-6">
12                      Content of column 1 in row 1
13                  </div>
14                  <div class="col-6"> 
15                      Content of column 2 in row 1
16                  </div>
17              </div>
18          
19              <div class="row py-3"> 
20                  <div class="col">
21                      Content of row 2
22                  </div>
23              </div>
24
25          </div>
26      </l:main-panel>
27  </bs:layout>
28 </j:jelly>

  1. 使用基于 Bootstrap 的自定義布局:由于 Jenkins 核心包含舊版本的 Bootstrap诫尽,因此我們需要替換標(biāo)準(zhǔn)的 layout.jelly 文件禀酱。
  2. 導(dǎo)入 Bootstrap4:使用輔助概念完成 JS 和 CSS 組件的導(dǎo)入,這是在 Jenkins 的 Stapler Web 框架中引用靜態(tài)資源的首選方式牧嫉。
  3. 整個(gè)視圖將被放入一個(gè)充滿整個(gè)屏幕(寬度為100%)的流體容器中剂跟。
  4. 視圖的新行由類row指定。附加類py-3定義了用于此行的填充酣藻,有關(guān)更多詳細(xì)信息曹洽,請參見Bootstrap Spacing
  5. 由于 Bootstrap 會(huì)自動(dòng)將一行分成 12 個(gè)相等大小的列辽剧,因此我們在此定義第一列應(yīng)占據(jù)這 12 列中的 6 列送淆。您也可以省略詳細(xì)編號(hào),然后 Bootstrap 將自動(dòng)在可用空間中分發(fā)內(nèi)容抖仅。請注意坊夫,在大多數(shù)情況下這不是您想要的砖第。
  6. 第二列使用剩余空間,即 12 列中的 6 列环凿。
  7. 第二行使用與第一行相同的布局梧兼。
  8. 第 1 行只有一列,它將填滿整個(gè)可用空間智听。

您還可以根據(jù)屏幕的實(shí)際可見大小為一行指定不同的列布局羽杰。這有助于改善大屏幕的布局。在警告插件中到推,您將找到一個(gè)示例:在小型設(shè)備上考赛,有一張可見的卡片可以在輪播中顯示一張餅圖。 如果要在較大的設(shè)備上打開同一頁面莉测,則會(huì)并排顯示兩個(gè)餅圖颜骤,并且輪播會(huì)被隱藏。

卡片

當(dāng)將插件信息顯示為一個(gè)塊時(shí)捣卤,通常會(huì)顯示純文本元素忍抽。通常,這將導(dǎo)致某些無關(guān)緊要的網(wǎng)頁董朝。為了創(chuàng)建一個(gè)更具吸引力的界面鸠项,在具有邊框、標(biāo)題子姜、圖標(biāo)等的卡片中顯示此類信息是有意義的祟绊。為了創(chuàng)建這樣的Bootstrap 卡片,新的Bootstrap 插件提供了一個(gè)小的果凍標(biāo)簽哥捕,該標(biāo)簽簡化了插件的此任務(wù)牧抽。可以通過以下方式在果凍視圖中輕松創(chuàng)建此類卡片:

1 <bs:card title="${%Card Title}" fontAwesomeIcon="icon-name">
2 Content of the card
3 </bs:card>

圖 8中顯示了此類卡的示例扭弧。上排的卡片包含餅圖阎姥,這些餅圖顯示了整個(gè)存儲(chǔ)庫中作者和提交數(shù)量的分布。底部的卡在數(shù)據(jù)表中顯示詳細(xì)信息鸽捻『舭停可視化不僅限于圖表或表格,您可以在其中顯示任何類型的 HTML 內(nèi)容御蒲。您可以在這些卡中顯示插件的任何圖標(biāo)衣赶,但是建議使用現(xiàn)有的Font Awesome圖標(biāo)之一,以在 Jenkins 的插件生態(tài)系統(tǒng)中獲得一致的外觀厚满。

card

注意府瞄,卡片的大小由網(wǎng)格配置決定,請參見第 5.2 節(jié)

表格

用于顯示插件詳細(xì)信息的常見 UI 元素是表格控件遵馆。大多數(shù)插件(和 Jenkins 核心)通常使用純 HTML 表格鲸郊。但是,如果表格應(yīng)顯示大量行货邓,則使用像DataTables這樣的更復(fù)雜的控件更有意義秆撮。使用此基于 JS 的表控件可免費(fèi)提供其他功能:

  • 通過文本搜索過濾結(jié)果
  • 提供結(jié)果集的分頁
  • 一次按多列排序數(shù)據(jù)
  • 使用 Ajax 調(diào)用獲取表行
  • 根據(jù)屏幕分辨率顯示和隱藏列

為了在視圖中使用DataTables,有兩個(gè)選項(xiàng)换况,您可以裝飾現(xiàn)有的靜態(tài) HTML 表(請參見第 5.4.1 節(jié))或使用 Ajax 填充表內(nèi)容(請參見第 5.4.2 節(jié))职辨。

靜態(tài) HTML 內(nèi)容的表格

使用 DataTables 的最簡單方法是創(chuàng)建一個(gè)靜態(tài) HTML 表格,只需調(diào)用 datatable 的構(gòu)造函數(shù)即可對其進(jìn)行修飾戈二。這種方法在 Java 和 Jelly 方面不涉及任何特殊處理舒裤,因此我認(rèn)為只需遵循 DataTables 文檔中的示例即可。只需確保在您的 Jelly 文件中構(gòu)建了表之后觉吭,您需要使用以下代碼裝飾表:

<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" >

  <st:adjunct includes="io.jenkins.plugins.jquery3"/>
  <st:adjunct includes="io.jenkins.plugins.data-tables"/>

  [...]

    <div class="table-responsive">
        <table class="table table-hover table-striped display" id="id">
            [...]
        </table>
    </div>

  [...]
  <script>
     $('#id').DataTable(); 
  </script>

</j:jelly>

  1. 用您的 HTML 表格元素的 ID 替換上面代碼中的 ID

到目前為止腾供,在 Forensics 插件中還沒有使用過此類靜態(tài)表格,但是您可以查看警告插件中顯示固定警告的表亏栈,以了解如何裝飾此類表台腥。

具有基于動(dòng)態(tài)模型內(nèi)容的表

盡管靜態(tài) HTML 表格易于實(shí)現(xiàn)宏赘,但它們有一些限制绒北。因此,遵循更復(fù)雜的方法是有意義的察署。通常闷游,用戶界面中的表是通過使用相應(yīng)的表(和行)模型定義的。自 Java 成立以來贴汪,Java Swing 成功地提供了這樣的表模型概念脐往。我也為 Jenkins 和 DataTables 修改了這些概念。為了在 Jenkins 視圖中創(chuàng)建表扳埂,插件需要提供一個(gè)表模型類业簿,該類提供以下信息:

  • 表的 ID(因?yàn)橐晥D中可能有多個(gè)表)
  • 列的模型(即列的編號(hào),類型和標(biāo)題標(biāo)簽)
  • 表格的內(nèi)容(即各個(gè)行對象)

您可以在 Forensics 插件中找到此類表格的示例:此處的表格列出了 Git 存儲(chǔ)庫中的文件以及相應(yīng)的提交統(tǒng)計(jì)信息(作者數(shù)量阳懂、提交數(shù)量梅尤、最后修改、首次提交)岩调。該表的屏幕截圖如圖 9所示巷燥。

table

為了在 Jenkins 中創(chuàng)建這樣的表,您需要?jiǎng)?chuàng)建一個(gè)從TableModel派生的表模型類号枕。在圖 10中缰揪,顯示了取證插件中相應(yīng)類的圖。

table-model

表格欄模型

表格模型類定義的第一件事是通過創(chuàng)建相應(yīng)的TableColumn實(shí)例來創(chuàng)建可用列的模型葱淳。對于每一列钝腺,您需要指定標(biāo)題標(biāo)簽和應(yīng)在相應(yīng)列中顯示的 bean 屬性的名稱(行元素實(shí)際上是 Java bean:每一列將顯示此類 bean 的一個(gè)獨(dú)特屬性抛姑,請參閱下一節(jié))。您可以通過簡單地提供基于StringInteger的列來使用任何受支持的列類型艳狐。

表格行內(nèi)容

此外途戒,表模型類提供行的內(nèi)容。此getRows()方法將使用 Ajax 調(diào)用異步調(diào)用僵驰。通常喷斋,此方法僅返回 Java Bean 實(shí)例的列表,該列表提供每一列的屬性(請參見上一節(jié))蒜茴。這些對象將自動(dòng)轉(zhuǎn)換為 JSON 對象數(shù)組星爪,這是 DataTables API 所需的基本數(shù)據(jù)結(jié)構(gòu)。您可以在ForensicsTableModel類的取證插件的 Git 存儲(chǔ)庫中找到一個(gè)可以正常工作的示例表模型實(shí)現(xiàn)粉私。

為了在插件視圖中使用這樣的表顽腾,您需要使用新的table標(biāo)簽在關(guān)聯(lián)的 Jelly 文件中創(chuàng)建表:

index.jelly
<j:jelly xmlns:j="jelly:core" xmlns:dt="/data-tables" >
    [...]
    <st:adjunct includes="io.jenkins.plugins.data-tables"/>

    <dt:table model="${it.getTableModel('id')}"/> 
    [...]
</j:jelly>

  1. 用自己的 ID 替換上面代碼的 ID

您需要為表提供的唯一參數(shù)是 model,它通常是對應(yīng)的 Jenkins 視圖模型類的一部分(此對象在視圖中用${it}引用)诺核。為了將對應(yīng)的 Jenkins 視圖模型類與表連接抄肖,視圖模型類需要實(shí)現(xiàn)AsyncTableContentProvider接口。甚至更簡單窖杀,讓您的視圖模型類派生自DefaultAsyncTableContentProvider漓摩。此關(guān)系是必需的,以便 Jenkins 可以自動(dòng)創(chuàng)建和綁定 Ajax 調(diào)用的代理入客,該代理將在創(chuàng)建 HTML 頁面后自動(dòng)填充表內(nèi)容管毙。

如果將所有這些部分放在一起,則需要定義一個(gè)類似于 Forensics 插件的模型的模型桌硫,如圖 11所示夭咬。

forensics-view-model

如在圖 5中已經(jīng)描述的,插件需要將BuildAction附加到每個(gè)構(gòu)建铆隘。Forensics 插件將ForensicBuildAction附加到構(gòu)建卓舵。該操作存儲(chǔ)一個(gè)RepositoryStatistics實(shí)例,該實(shí)例包含給定構(gòu)建的存儲(chǔ)庫結(jié)果膀钠。該操作將所有 Stapler 請求委派給新的Stapler 代理實(shí)例掏湾,因此我們可以使該操作清除用戶界面代碼。然后托修,此ForensicsViewModel類充當(dāng)視圖模型忘巧,為文件index.jelly給出的相應(yīng) Jelly 視圖提供服務(wù)器端模型。

雖然這種方法在第一眼看上去很復(fù)雜睦刃,但是您會(huì)看到實(shí)際的實(shí)現(xiàn)部分很小砚嘴。基本類已經(jīng)提供了大多數(shù)樣板代碼,您只需要實(shí)現(xiàn)一些方法即可际长。使用此概念還提供了一些其他功能耸采,這些功能是 DataTables 插件的一部分:

  • 列的順序會(huì)自動(dòng)保存在瀏覽器本地存儲(chǔ)中。
  • 分頁大小會(huì)自動(dòng)保存在瀏覽器本地存儲(chǔ)中工育。
  • 僅當(dāng)表格可見時(shí)才實(shí)際調(diào)用 Ajax 調(diào)用虾宇。因此,如果選項(xiàng)卡中隱藏了幾個(gè)表如绸,則僅按需加載內(nèi)容嘱朽,從而減少了要傳輸?shù)臄?shù)據(jù)量。
  • 有一個(gè)選項(xiàng)可用于提供其他詳細(xì)信息行怔接,該行可以用 + 符號(hào)擴(kuò)展搪泳,有關(guān)詳細(xì)信息,請參閱warnings plugin table扼脐。

圖表

插件報(bào)告程序通常還會(huì)報(bào)告從構(gòu)建到構(gòu)建的某種趨勢岸军。到目前為止,Jenkins 核心僅提供了一個(gè)非常有限的概念來呈現(xiàn)諸如趨勢圖之類的趨勢瓦侮。Jenkins 核心提供的JFreeChart框架是服務(wù)器端渲染引擎艰赞,可將圖表創(chuàng)建為靜態(tài) PNG 圖像,并將其包含在任務(wù)和詳細(xì)信息頁面中肚吏。如今方妖,有幾個(gè)功能強(qiáng)大的基于 JS 的圖表庫可供使用,它們在客戶端完成相同的工作(實(shí)際上甚至做得更好)须喂。這樣做的好處是可以在每個(gè)客戶端上自定義這些圖表吁断,而不會(huì)影響服務(wù)器性能。此外坞生,您還可以免費(fèi)獲得許多其他功能(例如縮放,動(dòng)畫等)掷伙。此外是己,這些圖表庫不僅支持典型的構(gòu)建趨勢圖,而且還支持許多其他圖表類型任柜,可用于改善插件的用戶體驗(yàn)卒废。這些圖表庫之一是ECharts:該庫具有強(qiáng)大的 API,并且實(shí)際上支持一個(gè)人可以想象的每種圖表類型宙地。您可以在庫的示例頁面上獲得一些功能印象摔认。

為了使用這些圖表,可以通過導(dǎo)入相應(yīng)的 JS 文件并在相應(yīng)的 Jelly 文件中定義圖表來嵌入使用該庫的圖表宅粥。盡管這已經(jīng)很好地工作了参袱,但是從詹金斯的構(gòu)建結(jié)果中為這些圖表提供相應(yīng)的模型仍然有些麻煩。因此,我添加了功能強(qiáng)大的 Java API抹蚀,可幫助在 Java 端為這些圖表創(chuàng)建模型剿牺。該 API 提供以下功能:

  • 根據(jù)構(gòu)建結(jié)果的集合創(chuàng)建趨勢圖。
  • 將圖表類型與聚合分開环壤,以簡化圖表模型的單元測試晒来。
  • 在內(nèi)部版本號(hào)或內(nèi)部版本日期之間切換 X 軸的類型(自動(dòng)匯總當(dāng)天記錄的結(jié)果)。
  • 將 Java 模型自動(dòng)轉(zhuǎn)換為 JS 端所需的 JSON 模型郑现。
  • 支持餅圖和折線圖(更多內(nèi)容即將推出)湃崩。

這些圖表可以在項(xiàng)目頁面中用作趨勢圖(請參見圖 3),也可以在插件的詳細(xì)信息視圖中用作信息圖(請參見第 5 節(jié))接箫。

餅狀圖

一個(gè)簡單但仍然有用的圖表是一個(gè)餅圖竹习,它說明了插件數(shù)據(jù)的數(shù)字比例。在 Forensics 插件中列牺,我使用此圖表來顯示 Git 存儲(chǔ)庫中源代碼文件的作者或提交數(shù)量的數(shù)字比例(請參見圖 8)整陌。在警告插件中,我使用此圖表顯示新警告瞎领,突出警告或固定警告的數(shù)字比例泌辫,請參見圖 12

pie

為了在您的詳細(xì)信息視圖中包括這樣的圖表九默,您可以使用提供的pie-chart標(biāo)簽震放。在以下代碼片段中,您可以看到此標(biāo)簽的使用情況(嵌入在 Bootstrap 卡片中驼修,請參見第 5.3 節(jié)):

index.jelly
1 <?jelly escape-by-default='true'?>
2   <j:jelly xmlns:j="jelly:core"  xmlns:c="/charts" xmlns:bs="/bootstrap">
3
4   [...]
5   <bs:card title="${%Number of authors}" fontAwesomeIcon="users">
6       <c:pie-chart id="authors" model="${it.authorsModel}" height="256" />
7   </bs:card>
8   [...]
9
10 </j:jelly>

您需要為此圖表提供唯一的 ID 和相應(yīng)的模型值殿遂。該模型必須是對應(yīng)的PieChartModel實(shí)例的 JSON 表示形式∫腋鳎可以使用以下幾行來創(chuàng)建這樣的模型:

ViewModel.java
1 [...]
2 PieChartModel model = new PieChartModel("Title");
3
4 model.add(new PieData("Segment 1 name", 10), Palette.RED);
5 model.add(new PieData("Segment 2 name", 15), Palette.GREEN);
6 model.add(new PieData("Segment 3 name", 20), Palette.YELLOW);
7
8 String json = new JacksonFacade().toJson(model);
9 [...]  

任務(wù)級(jí)別視圖上的趨勢圖

為了顯示在任務(wù)頁面上呈現(xiàn)折線圖的趨勢(請參見圖 3)墨礁,您需要提供一個(gè)所謂的浮動(dòng)框(存儲(chǔ)在任務(wù)操作的floatBox.jelly文件中(請參見第 3 節(jié)))。該文件的內(nèi)容非常簡單耳峦,僅包含一個(gè)trend-chart標(biāo)簽:

floatingBox.jelly
1 <?jelly escape-by-default='true'?>
2 <j:jelly xmlns:j="jelly:core" xmlns:c="/charts">
3
4   <c:trend-chart it="${from}" title="${%SCM Files Count Trend}" enableLinks="true"/>
5
6 </j:jelly>

在 Java 方面恩静,需要在JobAction的相應(yīng)子類(浮動(dòng)框的所有者)中提供圖表的模型。由于趨勢圖的計(jì)算在服務(wù)器端也非常昂貴(需要從磁盤讀取多個(gè)構(gòu)建蹲坷,并且需要計(jì)算有趣的數(shù)據(jù)點(diǎn))驶乾,因此該過程已放入單獨(dú)的后臺(tái)任務(wù)中。一旦計(jì)算完成循签,將通過 Ajax 調(diào)用顯示結(jié)果级乐。為了為插件作者隱藏這些詳細(xì)信息,您應(yīng)該簡單地從相應(yīng)的AsyncTrendJobAction類派生JobAction類县匠,該類已經(jīng)包含樣板代碼风科。因此撒轮,您的靜態(tài)插件對象模型實(shí)際上會(huì)變得有些復(fù)雜:

chart-model

基本上,您需要實(shí)現(xiàn)LinesChartModel 方法 createChartModel()來創(chuàng)建折線圖丐重。該方法的實(shí)現(xiàn)非常簡單腔召,因?yàn)榇蠖鄶?shù)艱苦的工作都是由庫提供的:從最新的構(gòu)建開始,您將使用構(gòu)建動(dòng)作的迭代器進(jìn)行調(diào)用扮惦。迭代器從一個(gè)版本開始構(gòu)建臀蛛,直到?jīng)]有更多可用結(jié)果為止(或已達(dá)到要考慮的最大構(gòu)建數(shù)量)。在插件中實(shí)現(xiàn)的最重要的事情是如何為給定的BuildAction計(jì)算數(shù)據(jù)點(diǎn)崖蜜。這是取證插件中此類SeriesBuilder實(shí)現(xiàn)的示例:

FilesCountSeriesBuilder.java
1 package io.jenkins.plugins.forensics.miner;
2
3 import java.util.HashMap;
4 import java.util.Map;
5
6 import edu.hm.hafner.echarts.SeriesBuilder;
7
8 /**
9  * Builds one x-axis point for the series of a line chart showing the number of files in the repository.
10 *
11 * @author Ullrich Hafner
12 */
13 public class FilesCountSeriesBuilder extends SeriesBuilder<ForensicsBuildAction> {
14      static final String TOTALS_KEY = "total";
15
16      @Override
17      protected Map<String, Integer> computeSeries(final ForensicsBuildAction current) {
18          Map<String, Integer> series = new HashMap<>();
19          series.put(TOTALS_KEY, current.getNumberOfFiles());
20          return series;
21      }
22 }

您不僅限于單個(gè)折線圖浊仆。您可以在一個(gè)圖表中顯示多條線,可以顯示堆疊的值豫领,甚至可以顯示某些值之間的差異抡柿。您也可以查看charts of the warnings plugin,以詳細(xì)了解其中一些功能等恐。

trend-lines
trend-stacked

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末洲劣,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子课蔬,更是在濱河造成了極大的恐慌囱稽,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,451評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件二跋,死亡現(xiàn)場離奇詭異蛾扇,居然都是意外死亡烂瘫,警方通過查閱死者的電腦和手機(jī)舆声,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,172評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門供置,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人谚鄙,你說我怎么就攤上這事各拷。” “怎么了襟锐?”我有些...
    開封第一講書人閱讀 164,782評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵撤逢,是天一觀的道長。 經(jīng)常有香客問我粮坞,道長,這世上最難降的妖魔是什么初狰? 我笑而不...
    開封第一講書人閱讀 58,709評(píng)論 1 294
  • 正文 為了忘掉前任莫杈,我火速辦了婚禮,結(jié)果婚禮上奢入,老公的妹妹穿的比我還像新娘筝闹。我一直安慰自己媳叨,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,733評(píng)論 6 392
  • 文/花漫 我一把揭開白布关顷。 她就那樣靜靜地躺著糊秆,像睡著了一般。 火紅的嫁衣襯著肌膚如雪议双。 梳的紋絲不亂的頭發(fā)上痘番,一...
    開封第一講書人閱讀 51,578評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音平痰,去河邊找鬼汞舱。 笑死,一個(gè)胖子當(dāng)著我的面吹牛宗雇,可吹牛的內(nèi)容都是我干的昂芜。 我是一名探鬼主播,決...
    沈念sama閱讀 40,320評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼赔蒲,長吁一口氣:“原來是場噩夢啊……” “哼泌神!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起舞虱,我...
    開封第一講書人閱讀 39,241評(píng)論 0 276
  • 序言:老撾萬榮一對情侶失蹤欢际,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后砾嫉,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體幼苛,經(jīng)...
    沈念sama閱讀 45,686評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,878評(píng)論 3 336
  • 正文 我和宋清朗相戀三年焕刮,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了舶沿。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,992評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡配并,死狀恐怖括荡,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情溉旋,我是刑警寧澤畸冲,帶...
    沈念sama閱讀 35,715評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站观腊,受9級(jí)特大地震影響邑闲,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜梧油,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,336評(píng)論 3 330
  • 文/蒙蒙 一苫耸、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧儡陨,春花似錦褪子、人聲如沸量淌。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,912評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽呀枢。三九已至,卻和暖如春笼痛,著一層夾襖步出監(jiān)牢的瞬間裙秋,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,040評(píng)論 1 270
  • 我被黑心中介騙來泰國打工晃痴, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留残吩,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,173評(píng)論 3 370
  • 正文 我出身青樓倘核,卻偏偏與公主長得像泣侮,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子紧唱,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,947評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容