Azure DevOps 插件: Field Unique Control
https://github.com/smallidea/azure-devops-extension-custom-control-sample
- 一. 概述
- 二. 快速開始
- 三. 目錄結構
- 四. 使用
vss-web-extension-sdk- API
- 核心代碼
- 五. 用于打包、發布的命令
一. 概述
驗證欄位值的唯一性,如果相同型別的作業項使用了該值,將報錯,當前作業項不能保存,
-
如何開發自定義控制元件
-
如果使用web技術開發一個插件
二. 快速開始
- 克隆git庫,并進入目錄
git clone https://github.com/smallidea/azure-devops-extension-custom-control-sample.git
cd azure-devops-extension-custom-control-sample
- 運行
npm install安裝專案所需要的npm包 - 運行
npm run publish,里面的tfs地址和token需要根據具體專案進行修改 - 在瀏覽器中訪問你的tfs站點,
http://YourTFSInstance:8080/tfs.
建議使用chrome 70版本以上
- 手動安裝并啟用插件
- 集合設定 > 擴展 > 瀏覽本地插件 > 管理本地擴展 > 上傳擴展 > 瀏覽本地檔案上傳插件
- 點擊進入插件詳情 > 免費獲取 > 選擇集合,點擊啟用
- 手動更新插件
- 集合設定 > 擴展 > 瀏覽本地插件 > 管理本地擴展
- 找到需要更新的插件,點擊名稱后的三個點 > 選擇更新 > 瀏覽本地檔案上傳插件
三. 目錄結構
├── CHANGELOG.md 更新歷史
├── README.md
├── details.md 詳細描述
├── images 一些公用的圖片
├── src 源檔案
│ ├── common 公共庫
│ │ ├── apiHelper.ts 通過azure devops的api讀取相關資訊
│ │ └── errorView.ts 錯誤顯示界面
│ ├── static 公用的資源檔案
│ │ ├── css
│ │ └── images
│ └── uniqueField 主檔案夾,單獨放置的目的是方便一個工程發布多個插件
│ ├── app.ts 主檔案
│ ├── control.ts
│ ├── index.html 入口
│ ├── model.ts
│ ├── tsconfig.json typescript的組態檔
│ └── view.ts
├── package.json 包的組態檔,npm包、自定義npm run命令
├── tsconfig.json 外層放置一個是避免除錯的時候報錯,因為tsconfig里面申明了vss-web-extension-sdk是一個types
└── vss-extension-uniqueField.json 插件的組態檔
在bash下面使用tree命令獲取目錄還不錯: tree -L 3 -I 'node_module|out|dist|package-lock.json|.png|.css|license'
四. 使用vss-web-extension-sdk
使用 Microsoft VSS Web 擴展 SDK 包,vss-web-extension-sdk 英文全稱 Visual Studio Services Web Extension SDK
,此 SDK 包括一個 JavaScript 庫,該庫提供與嵌入你的擴展插件的頁面進行通信所需的 Api,
import * as VSSService from "VSS/Service";
import * as WitService from "TFS/WorkItemTracking/Services";
import * as ExtensionContracts from "TFS/WorkItemTracking/ExtensionContracts";
import * as Q from "q";
API
| API | 函式 | 用途 |
|---|---|---|
| VSSService | VSS.getConfiguration() | 可以獲取到相應的配置 |
| WitService | getService() | 回傳一個服務器實體 |
| getFieldValue() | 獲取當前作業項欄位的值值 | |
| setFieldValue() | 設定當前作業項欄位的值 | |
| getAllowedFieldValues() | 獲取欄位的允許的值,即在配作業項模版配置時的下拉框中的選項串列 |
核心代碼
- 獲取允許的值
WitService.WorkItemFormService.getservice().then(
(service) => {
service.getAllowedFieldValues(this._fieldName), (allowedValues: string[]) => {
// do something
}
}
)
- 使用Q來處理回呼, 當有多個回呼時,可以使用Q.spread
WitService.WorkItemFormService.getService().then(
(service) => {
Q.spread<any, any>(
[service.getAllowedFieldValues(this._fieldName), service.getFieldValue(this._fieldName)],
(allowedValues: string[], currentValue: (string | number)) => {
//do something
}
)
}
)
- 拋出錯誤,阻止保存 service.setError; 清除錯誤 service.clearError,
WitService.WorkItemFormService.getService().then(
(service) => {
// 驗證唯一性
this._validUniq(this._workItemId, value).then(isValid => {
if (isValid == false) {
service.setError(`${value} 已經在當前團隊專案中被使用,請使用其他!`);
} else {
service.clearError();
service.setFieldValue(this._fieldName, value).then(
() => {
this._update(value);
}, this._handleError);
}
});
},
this._handleError
);
- 呼叫wiql
import VSS_Service = require("VSS/Service");
import TFS_Wit_Client = require("TFS/WorkItemTracking/RestClient");
import TFS_Wit_Services = require("TFS/WorkItemTracking/Services");
import TFS_Core_WebApi = require("TFS/Core/RestClient");
var witClient = VSS_Service.getCollectionClient(TFS_Wit_Client.WorkItemTrackingHttpClient);
const query = {
query: `SELECT [System.Id]
FROM WorkItemLinks
WHERE ([System.Links.LinkType] = 'System.LinkTypes.Hierarchy-Forward')
AND (Target.[System.TeamProject] = @project
) mode(Recursive, ReturnMatchingChildren)`
};
let workItemQueryResult = await witClient.queryByWiql(query, project.name, null);
五. 用于打包、發布的命令
clean洗掉運行程序中生成的檔案precompiled:uniqueField預編譯,執行clean、tscpackage:prod:uniqueField打包成vsix檔案,手動發布到tfs,通常這種比較適合生產環境publish:test:uniqueField直接發布到tfs,通常適用于測驗環境
六. 除錯
TODO
歡迎在評論區留下你寶貴的意見,不論好壞都是我前進的動力!
如果喜歡,記得點贊、推薦、關注、收藏、轉發 ... ;)
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/539563.html
標籤:其他
