扩展“工作项”窗体

Azure DevOps Services | Azure DevOps Server 2022 - Azure DevOps Server 2019

了解如何通过通过扩展做出的贡献自定义工作项表单向用户呈现的方式。

有关完整源,请参阅 GitHub 上的 Azure DevOps 扩展示例中的 UI 示例

添加组

工作项窗体中的工具栏项。

若要将组添加到主页,请为扩展清单添加贡献。 此贡献的类型应为ms.vss-work-web.work-item-form-group,应面向贡献。ms.vss-work-web.work-item-form

"contributions": [
   {  
       "id": "sample-work-item-form-group",
       "type": "ms.vss-work-web.work-item-form-group",
       "description": "Custom work item form group",
       "targets": [
           "ms.vss-work-web.work-item-form"
       ],
       "properties": {
           "name": "My Group",
           "uri": "workItemGroup.html",
           "height": 600
       }
   }
]

属性

属性 说明
name 显示在组上的文本
uri 承载工作项窗体及其脚本上显示的 html 的页面的 URI
height (可选)定义组的高度。 省略时,为 100%

JavaScript 示例

此示例演示如何注册一个对象,该对象在可能影响参与组的工作项窗体上发生事件时调用。 有关更多示例,请参阅 WorkItemFormGroup 示例

import { IWorkItemFormService, WorkItemTrackingServiceIds } from "azure-devops-extension-api/WorkItemTracking";
import * as SDK from "azure-devops-extension-sdk";

// Get the WorkItemFormService.  This service allows you to get/set fields/links on the 'active' work item (the work item
// that currently is displayed in the UI).
async function getWorkItemFormService()
{
    const workItemFormService = await SDK.getService<IWorkItemFormService>(WorkItemTrackingServiceIds.WorkItemFormService);
    return workItemFormService;
}

// Register a listener for the work item group contribution after initializing the SDK.
SDK.register(SDK.getContributionId(), function () {
    return {
        // Called when the active work item is modified
        onFieldChanged: function(args) {
            $(".events").append($("<div/>").text("onFieldChanged - " + JSON.stringify(args)));
        },
        
        // Called when a new work item is being loaded in the UI
        onLoaded: function (args) {

            getWorkItemFormService().then(function(service) {            
                // Get the current values for a few of the common fields
                service.getFieldValues(["System.Id", "System.Title", "System.State", "System.CreatedDate"]).then(
                    function (value) {
                        $(".events").append($("<div/>").text("onLoaded - " + JSON.stringify(value)));
                    });
            });
        },
        
        // Called when the active work item is being unloaded in the UI
        onUnloaded: function (args) {
            $(".events").empty();
            $(".events").append($("<div/>").text("onUnloaded - " + JSON.stringify(args)));
        },
        
        // Called after the work item has been saved
        onSaved: function (args) {
            $(".events").append($("<div/>").text("onSaved - " + JSON.stringify(args)));
        },
        
        // Called when the work item is reset to its unmodified state (undo)
        onReset: function (args) {
            $(".events").append($("<div/>").text("onReset - " + JSON.stringify(args)));
        },
        
        // Called when the work item has been refreshed from the server
        onRefreshed: function (args) {
            $(".events").append($("<div/>").text("onRefreshed - " + JSON.stringify(args)));
        }
    }
});

事件

事件 事件说明 参数 参数说明
onFieldChanged 在字段发生更改后触发。 如果字段更改运行规则更新了其他字段,则所有这些更改都是单个事件的一部分。 ID 工作项的 ID。
changedFields 包含所有已更改字段的引用名称的数组。 ID 工作项的 ID。
onLoaded 在工作项窗体中加载数据、用户打开工作项或用户导航到会审视图中的另一个工作项时触发。 ID 工作项的 ID。
onReset 在用户撤消对工作项的更改后触发。 ID 工作项的 ID。
onRefreshed 在用户手动刷新工作项后触发。 ID 工作项的 ID。
onSaved 保存工作项后触发。 对于对话中的工作项,应以“ms.vss-work-web.work-item-notifications”类型为目标,以确保事件发生,因为对话关闭后,将卸载此贡献类型。 有关详细信息,请参阅 “侦听事件”。 ID 工作项的 ID。
onUnloaded 在用户关闭对话框之前触发,或者在用户移动到会审视图中的另一个工作项之前触发。 ID 工作项的 ID。

添加页面

新页面呈现为工作项窗体上的选项卡。 新页面显示在“详细信息”选项卡旁边。

新页面作为工作项窗体上的选项卡。

若要向工作项窗体添加页面,请为扩展清单添加贡献。 此贡献的类型应为ms.vss-work-web.work-item-form-page,应面向贡献。ms.vss-work-web.work-item-form

"contributions": [
    {  
        "id": "sample-work-item-form-page",
        "type": "ms.vss-work-web.work-item-form-page",
        "description": "Custom work item form page",
        "targets": [
            "ms.vss-work-web.work-item-form"
        ],
        "properties": {
            "name": "My Page",
            "uri": "workItemPage.html"
        } 
    }
]

属性

属性 说明
name 显示在选项卡页上的文本。
uri 承载工作项窗体及其脚本上显示的 html 的页面的 URI。

JavaScript 示例

请参阅窗体组部分中的 JavaScript 示例。 已注册对象的名称应与贡献的名称匹配 id

事件

事件 事件说明 参数 参数说明
onFieldChanged 在字段发生更改后触发。 如果字段更改运行规则更新了其他字段,则所有这些更改都是单个事件的一部分。 ID 工作项的 ID。
changedFields 包含所有已更改字段的引用名称的数组。 ID 工作项的 ID。
onLoaded 在工作项窗体中加载数据、用户打开工作项或用户导航到会审视图中的另一个工作项时触发。 ID 工作项的 ID。
onReset 在用户撤消对工作项的更改后触发。 ID 工作项的 ID。
onRefreshed 在用户手动刷新工作项后触发。 ID 工作项的 ID。
onSaved 保存工作项后触发。 对于对话中的工作项,应以“ms.vss-work-web.work-item-notifications”类型为目标,以确保事件发生,因为对话关闭后,将卸载此贡献类型。 有关详细信息,请参阅 “侦听事件”。 ID 工作项的 ID。
onUnloaded 在用户关闭对话框之前触发,或者在用户移动到会审视图中的另一个工作项之前触发。 ID 工作项的 ID。

在工作项窗体中配置贡献

在 Azure DevOps Services 中,默认情况下,组扩展显示在窗体的第二列末尾,页面贡献显示在所有工作项窗体页作为选项卡之后。默认情况下,控件贡献不会显示在窗体中,因此用户必须手动将其添加到窗体。 在 Azure DevOps Server 中,若要在工作项窗体中显示/隐藏或移动控件、组和页面贡献,请参阅 “配置工作项”窗体扩展

添加菜单操作

将项添加到工作项工具栏。

若要将项添加到工作项工具栏,请将此贡献添加到扩展清单。 该项显示在 ... 中工作项窗体右上角的下拉列表。

"contributions": [
   {  
      "id": "sample-work-item-menu",  
      "type": "ms.vss-web.action",  
      "description": "Sample toolbar item which updates the title of a work item",  
      "targets": [  
          "ms.vss-work-web.work-item-context-menu"  
      ],  
      "properties": {  
          "text": "Try me!",  
          "title": "Updates the title of the work item from the extension",  
          "toolbarText": "Try me!",  
          "icon": "images/show-properties.png",  
          "uri": "menu-workItemToolbarButton.html"  
      }  
   }
]

属性

属性 说明
text 显示在工具栏项上的文本。
title 显示在菜单项上的工具提示文本。
toolbarText 当项悬停在上方时显示的文本。
uri 注册工具栏操作处理程序的页面的 URI。
图标 显示在菜单项上的图标的 URL。 使用 baseUri 解析相对 URL。
group 确定菜单项的显示位置,与其他项相关。 具有相同组名称的工具栏项分组并除以与其余项的分隔符。
registeredObjectId (可选)已注册菜单操作处理程序的名称。 默认为贡献 ID。

侦听事件

若要向侦听工作项事件的工作项添加观察程序,请将此贡献添加到扩展清单。 工作项窗体上的观察程序没有可视化效果。 这是在Saved 事件上侦听工作项窗体的最佳方式,因为观察者位于窗体外部,当窗体关闭时不会销毁,该窗体在保存后可能会发生。

"contributions": [
   {  
       "id": "sample-work-item-form-observer",
       "type": "ms.vss-work-web.work-item-notifications",
       "description": "Gets events about the current work item form for the 'Try Me!' toolbar button",
       "targets": [
           "ms.vss-work-web.work-item-form"
       ],
       "properties": {
           "uri": "myformobserver.html"
       }
   }
]

属性

属性 说明
uri 承载侦听事件的脚本的页面的 URI

事件

事件 事件说明 参数 参数说明
onFieldChanged 在字段发生更改后触发。 如果字段更改运行规则更新了其他字段,则所有这些更改都是单个事件的一部分。 ID 工作项的 ID。
changedFields 包含所有已更改字段的引用名称的数组。 ID 工作项的 ID。
onLoaded 在工作项窗体中加载数据、用户打开工作项或用户导航到会审视图中的另一个工作项时触发。 ID 工作项的 ID。
onReset 在用户撤消对工作项的更改后触发。 ID 工作项的 ID。
onRefreshed 在用户手动刷新工作项后触发。 ID 工作项的 ID。
onSaved 保存工作项后触发。 对于对话中的工作项,应以“ms.vss-work-web.work-item-notifications”类型为目标,以确保事件发生,因为对话关闭后,将卸载此贡献类型。 有关详细信息,请参阅 “侦听事件”。 ID 工作项的 ID。
onUnloaded 在用户关闭对话框之前触发,或者在用户移动到会审视图中的另一个工作项之前触发。 ID 工作项的 ID。

HTML/JavaScript 示例

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Work item extension page sample</title>
</head>

<body>
    <script src="sdk/scripts/SDK.js"></script>

    <script>
        SDK.init({
            usePlatformScripts: true
        });
        
        SDK.ready(function () {
             // Register a listener for the work item page contribution.
            SDK.register(SDK.getContributionId(), function () {
                return {
                    // Called when the active work item is modified
                    onFieldChanged: function(args) {
                        
                    },
                    
                    // Called when a new work item is being loaded in the UI
                    onLoaded: function (args) {
            
                    },
                    
                    // Called when the active work item is being unloaded in the UI
                    onUnloaded: function (args) {
            
                    },
                    
                    // Called after the work item has been saved
                    onSaved: function (args) {
            
                    },
                    
                    // Called when the work item is reset to its unmodified state (undo)
                    onReset: function (args) {
            
                    },
                    
                    // Called when the work item has been refreshed from the server
                    onRefreshed: function (args) {
            
                    }
                }
            });    
        });
     </script>
</body>
</html>