Добавление мини-приложения панели мониторинга
Azure DevOps Services | Azure DevOps Server 2022 — Azure DevOps Server 2019
Мини-приложения на панели мониторинга реализуются в виде вкладов в платформу расширений. Одно расширение может иметь несколько вкладов. Узнайте, как создать расширение с несколькими мини-приложениями в качестве вкладов.
Эта статья разделена на три части, каждая сборка предыдущего — начиная с простого мини-приложения и заканчивая комплексным мини-приложением.
Совет
Ознакомьтесь с нашей новой документацией по разработке расширений с помощью пакета SDK для расширений Azure DevOps.
Необходимые компоненты
- Знание. Некоторые знания о JavaScript, HTML, CSS требуются для разработки мини-приложений.
- Организация в Azure DevOps.
- Текстовый редактор. Для многих учебников мы используем Visual Studio Code.
- Последняя версия узла.
- Кроссплатформенный интерфейс командной строки для Azure DevOps (tfx-cli) для упаковки расширений.
- tfx-cli можно установить с помощью
npm
компонента Node.js, выполнив командуnpm i -g tfx-cli
- tfx-cli можно установить с помощью
- Домашний каталог для проекта. Этот каталог называется
home
на протяжении всего учебника.
Структура файла расширения:
|--- README.md
|--- sdk
|--- node_modules
|--- scripts
|--- VSS.SDK.min.js
|--- img
|--- logo.png
|--- scripts
|--- hello-world.html // html page to be used for your widget
|--- vss-extension.json // extension's manifest
В этом учебнике рассматриваются следующие темы:
- Часть 1. Показывает, как создать новое мини-приложение, которое выводит простое сообщение Hello World.
- Часть 2. Создание первой части путем добавления вызова в REST API Azure DevOps.
- Часть 3. Описание добавления конфигурации в мини-приложение.
Примечание.
Если вы спешите и хотите сразу получить свои руки по коду, вы можете скачать примеры.
После скачивания перейдите в widgets
папку, а затем следуйте шагу 6 и шагу 7 непосредственно, чтобы опубликовать пример расширения, в котором три примера мини-приложений различных сложностей.
Начало работы с некоторыми основными стилями мини-приложений , которые мы предоставляем вне поля и некоторые рекомендации по структуре мини-приложений.
Часть 1. Hello World
Часть 1 представляет мини-приложение, которое печатает "Hello World" с помощью JavaScript.
Шаг 1. Получение клиентского пакета SDK — VSS.SDK.min.js
Основной скрипт VSS.SDK.min.js
ПАКЕТА SDK позволяет веб-расширениям взаимодействовать с узлом кадром Azure DevOps. Скрипт выполняет такие операции, как инициализация, загрузка расширения уведомления или получение контекста текущей страницы.
Получите файл пакета SDK VSS.SDK.min.js
клиента и добавьте его в веб-приложение. Поместите его в папку home/sdk/scripts
.
Чтобы получить пакет SDK, используйте команду npm install:
npm install vss-web-extension-sdk
Дополнительные сведения см. на странице GitHub пакета SDK для клиента.
Шаг 2. Настройка HTML-страницы — hello-world.html
Html-страница — это клей, который содержит макет вместе и содержит ссылки на CSS и JavaScript. Вы можете присвоить этому файлу любое имя. Обновите все ссылки на hello-world
имя, используемое вами.
Мини-приложение основано на HTML и размещается в iframe.
Добавьте следующий HTML-код в hello-world.html
. Мы добавим обязательную ссылку на VSS.SDK.min.js
файл и добавим h2
элемент, который обновляется строкой Hello World в предстоящем шаге.
<!DOCTYPE html>
<html>
<head>
<script src="sdk/scripts/VSS.SDK.min.js"></script>
</head>
<body>
<div class="widget">
<h2 class="title"></h2>
</div>
</body>
</html>
Несмотря на то, что мы используем HTML-файл, большинство элементов головы HTML, отличных от скрипта и ссылки, игнорируются платформой.
Шаг 3. Обновление JavaScript
Мы используем JavaScript для отображения содержимого в мини-приложении. В этой статье мы упаковаем весь код JavaScript внутри <script>
элемента в HTML-файле. Этот код можно выбрать в отдельном файле JavaScript и ссылаться на него в HTML-файле.
Код отрисовывает содержимое. Этот код JavaScript также инициализирует пакет SDK VSS, сопоставляет код мини-приложения с именем мини-приложения и уведомляет платформу расширений об успешном выполнении или сбоях мини-приложения.
В нашем случае следующий код выводит "Hello World" в мини-приложении. Добавьте этот script
элемент в head
HTML.
<script type="text/javascript">
VSS.init({
explicitNotifyLoaded: true,
usePlatformStyles: true
});
VSS.require("TFS/Dashboards/WidgetHelpers", function (WidgetHelpers) {
WidgetHelpers.IncludeWidgetStyles();
VSS.register("HelloWorldWidget", function () {
return {
load: function (widgetSettings) {
var $title = $('h2.title');
$title.text('Hello World');
return WidgetHelpers.WidgetStatusHelper.Success();
}
};
});
VSS.notifyLoadSucceeded();
});
</script>
VSS.init
инициализирует подтверждение между iframe, в котором размещен мини-приложение и кадр узла.- Мы передаем
explicitNotifyLoaded: true
, чтобы мини-приложение было явно уведомлять узел о завершении загрузки. Этот элемент управления позволяет уведомлять о завершении загрузки после того, как будут загружены зависимые модули. Мы передаемusePlatformStyles: true
, чтобы мини-приложение пользовалось основными стилями Azure DevOps для элементов HTML (например, body, div и т. д.). Если мини-приложение предпочитает не использовать эти стили, они могут передаватьсяusePlatformStyles: false
. VSS.require
используется для загрузки необходимых библиотек скриптов VSS. Вызов этого метода автоматически загружает общие библиотеки, такие как JQuery и JQueryUI. В нашем случае мы зависят от библиотеки WidgetHelpers, которая используется для обмена данными о состоянии мини-приложения с платформой мини-приложений. Таким образом, мы передаем соответствующее имяTFS/Dashboards/WidgetHelpers
модуля и обратныйVSS.require
вызов. Обратный вызов вызывается после загрузки модуля. Обратный вызов содержит остальную часть кода JavaScript, необходимого для мини-приложения. В конце обратного вызова мы вызываемVSS.notifyLoadSucceeded
уведомление о завершении загрузки.WidgetHelpers.IncludeWidgetStyles
содержит таблицу стилей с некоторыми базовыми css для начала работы. Чтобы использовать эти стили, заключите содержимое в элемент HTML с классомwidget
.VSS.register
используется для сопоставления функции в JavaScript, которая однозначно определяет мини-приложение среди различных вкладов в расширение. Имя должно совпадатьid
с именем, определяющим ваш вклад, как описано на шаге 5. Для мини-приложений функция, передаваемая дляVSS.register
возврата объекта, удовлетворяющегоIWidget
контракту, например, возвращаемый объект должен иметь свойство load, значение которого является другой функцией, которая имеет основную логику для отрисовки мини-приложения. В нашем случае это обновление текстаh2
элемента на "Hello World". Это эта функция, которая вызывается, когда платформа мини-приложений создает экземпляр мини-приложения. Мы используемWidgetStatusHelper
приложение WidgetHelpers для возврата в качестве успешногоWidgetStatus
.
Предупреждение
Если имя, используемое для регистрации мини-приложения, не соответствует идентификатору для вклада в манифест, то мини-приложение будет неожиданно работать.
vss-extension.json
всегда должен находиться в корне папки (в этом руководстве).HelloWorld
Для всех остальных файлов их можно поместить в любую структуру в папке, просто обновите ссылки соответствующим образом в HTML-файлах и манифестеvss-extension.json
.
Шаг 4. Обновление логотипа расширения: logo.png
Логотип отображается в Marketplace и в каталоге мини-приложений после установки расширения.
Вам нужен значок каталога 98 пикселей x 98-px. Выберите изображение, назовите его logo.png
и поместите его в папку img
.
Вы можете присвоить этим изображениям имя, если манифест расширения на следующем шаге обновляется с именами, которые вы используете.
Шаг 5. Создание манифеста расширения: vss-extension.json
У каждого расширения должен быть файл манифеста расширения.
- Ознакомьтесь со ссылкой на манифест расширения.
- Узнайте больше о точках вклада в точках расширяемости.
- Создайте json-файл (
vss-extension.json
например, в каталогеhome
со следующим содержимым):
{
"manifestVersion": 1,
"id": "azure-devops-extensions-myExtensions",
"version": "1.0.0",
"name": "My First Set of Widgets",
"description": "Samples containing different widgets extending dashboards",
"publisher": "fabrikam",
"categories": ["Azure Boards"],
"targets": [
{
"id": "Microsoft.VisualStudio.Services"
}
],
"icons": {
"default": "img/logo.png"
},
"contributions": [
{
"id": "HelloWorldWidget",
"type": "ms.vss-dashboards-web.widget",
"targets": [
"ms.vss-dashboards-web.widget-catalog"
],
"properties": {
"name": "Hello World Widget",
"description": "My first widget",
"catalogIconUrl": "img/CatalogIcon.png",
"previewImageUrl": "img/preview.png",
"uri": "hello-world.html",
"supportedSizes": [
{
"rowSpan": 1,
"columnSpan": 2
}
],
"supportedScopes": ["project_team"]
}
}
],
"files": [
{
"path": "hello-world.html",
"addressable": true
},
{
"path": "sdk/scripts",
"addressable": true
},
{
"path": "img",
"addressable": true
}
]
}
Дополнительные сведения о обязательных атрибутах см. в справочнике по манифесту расширения.
Примечание.
Измените имя издателя на имя издателя. Сведения о создании издателя см. в разделе "Package/Publish/Install".
Значки
Значки стэнза указывают путь к значку расширения в манифесте.
Участие в проекте
Каждая запись вклада определяет свойства.
- Идентификатор для идентификации вашего вклада. Этот идентификатор должен быть уникальным в пределах расширения. Этот идентификатор должен совпадать с именем, используемым на шаге 3 для регистрации мини-приложения.
- Тип вклада. Для всех мини-приложений тип должен быть
ms.vss-dashboards-web.widget
. - Массив целевых объектов , в которые вносится вклад. Для всех мини-приложений целевой объект должен быть
[ms.vss-dashboards-web.widget-catalog]
. - Свойства — это объекты, включающие свойства для типа вклада. Для мини-приложений обязательны следующие свойства.
Свойство | Описание |
---|---|
name | Имя мини-приложения, отображаемое в каталоге мини-приложений. |
описание | Описание мини-приложения, отображаемого в каталоге мини-приложений. |
catalogIconUrl | Относительный путь к значку каталога, добавленного на шаге 4 для отображения в каталоге мини-приложений. Изображение должно быть 98 пикселей x 98 пикселей. Если вы использовали другую структуру папок или другое имя файла, укажите соответствующий относительный путь здесь. |
previewImageUrl | Относительный путь к изображению предварительного просмотра, добавленного на шаге 4 , для отображения в каталоге мини-приложений. Изображение должно быть 330 пикселей x 160 пикселей. Если вы использовали другую структуру папок или другое имя файла, укажите соответствующий относительный путь здесь. |
uri | Относительный путь к HTML-файлу, добавленного на шаге 1. Если вы использовали другую структуру папок или другое имя файла, укажите соответствующий относительный путь здесь. |
поддерживаемыеSizes | Массив размеров, поддерживаемых мини-приложением. Если мини-приложение поддерживает несколько размеров, первый размер в массиве — это размер мини-приложения по умолчанию. Указан widget size для строк и столбцов, занятых мини-приложением в сетке панели мониторинга. Одна строка или столбец соответствует 160 пикселей. Любое измерение, превышающее 1x1, получает дополнительные 10 пикселей, которые представляют заготовку между мини-приложениями. Например, мини-приложение 3x2 имеет ширину 160*3+10*2 и 160*2+10*1 высоту. Максимальный поддерживаемый размер 4x4 . |
поддерживаемыеScopes | В настоящее время поддерживаются только панели мониторинга группы. Значение должно быть project_team . Будущие обновления могут включать дополнительные параметры для областей панели мониторинга. |
Файлы
Файлы стэнза содержат файлы, которые необходимо включить в пакет — HTML-страницу, скрипты, скрипты пакета SDK и логотип.
Установите значение addressable
true
, если вы не включаете другие файлы, которые не должны быть url-адресируемыми.
Примечание.
Дополнительные сведения о файле манифеста расширения, например его свойствах и возможностях, ознакомьтесь со ссылкой на манифест расширения.
Шаг 6. Упаковка, публикация и общий доступ
После того как вы напишете расширение, следующий шаг к его получению в Marketplace заключается в том, чтобы упаковать все файлы вместе. Все расширения упаковываются в виде совместимых vsix-файлов VSIX 2.0. Корпорация Майкрософт предоставляет кроссплатформенный интерфейс командной строки (CLI) для упаковки расширения.
Получение средства упаковки
Вы можете установить или обновить кроссплатформенный интерфейс командной строки для Azure DevOps (tfx-cli) с помощью npm
компонента Node.js из командной строки.
npm i -g tfx-cli
Упаковка расширения
Упаковка расширения в VSIX-файл без усилий после того, как у вас есть tfx-cli. Перейдите в домашний каталог расширения и выполните следующую команду.
tfx extension create --manifest-globs vss-extension.json
Примечание.
При каждом обновлении необходимо увеличить версию расширения или интеграции.
При обновлении существующего расширения обновите версию манифеста или передайте переключатель командной --rev-version
строки. Это увеличивает номер версии исправления расширения и сохраняет новую версию в манифесте.
После упаковки расширения в VSIX-файле вы будете готовы опубликовать расширение в Marketplace.
Создание издателя для расширения
Все расширения, включая расширения от Корпорации Майкрософт, определяются как предоставляемые издателем. Если вы еще не являетесь членом существующего издателя, создайте его.
- Вход на портал публикации Visual Studio Marketplace
- Если вы еще не являетесь членом существующего издателя, необходимо создать издателя. Если у вас уже есть издатель, прокрутите страницу и выберите пункт "Опубликовать расширения " в разделе "Связанные сайты".
- Укажите идентификатор издателя, например:
mycompany-myteam
- Идентификатор используется в качестве значения атрибута
publisher
в файле манифеста расширений.
- Идентификатор используется в качестве значения атрибута
- Укажите отображаемое имя издателя, например:
My Team
- Укажите идентификатор издателя, например:
- Просмотрите соглашение издателя Marketplace и нажмите кнопку "Создать".
Теперь издатель определен. В будущем выпуске можно предоставить разрешения для просмотра расширений издателя и управления ими.
Расширения публикации в общем издателе упрощают процесс для команд и организаций, предлагая более безопасный подход. Этот метод устраняет необходимость распространять один набор учетных данных среди нескольких пользователей, повышая безопасность и
Обновите файл манифеста в примерах, чтобы заменить фиктивный vss-extension.json
идентификатор fabrikam
издателя идентификатором издателя.
Публикация и предоставление общего доступа к расширению
Теперь вы можете отправить расширение в Marketplace.
Выберите " Отправить новое расширение", перейдите в упакованный VSIX-файл и нажмите кнопку "Отправить".
Вы также можете отправить расширение через командную строку с помощью tfx extension publish
команды, а не tfx extension create
для упаковки и публикации расширения на одном шаге.
Вы также можете использовать --share-with
для совместного использования расширения с одной или несколькими учетными записями после публикации.
Вам также нужен личный маркер доступа.
tfx extension publish --manifest-globs your-manifest.json --share-with yourOrganization
Шаг 7. Добавление мини-приложения из каталога
Войдите в проект.
http://dev.azure.com/{Your_Organization}/{Your_Project}
Выберите панели мониторинга обзора>.
Выберите Добавить мини-приложение.
Выделите мини-приложение и нажмите кнопку "Добавить".
Мини-приложение отображается на панели мониторинга.
Часть 2. Hello World с REST API Azure DevOps
Мини-приложения могут вызывать любой из интерфейсов REST API в Azure DevOps для взаимодействия с ресурсами Azure DevOps. В следующем примере мы используем REST API для WorkItemTracking для получения сведений о существующем запросе и отображения некоторых сведений о запросе в мини-приложении в текстовом тексте Hello World.
Шаг 1. Добавление HTML-файла
Скопируйте файл hello-world.html
из предыдущего примера и переименуйте копию hello-world2.html
в . Теперь папка выглядит следующим образом:
|--- README.md |--- node_modules
|--- SDK
Скрипты |--- |--- VSS. SDK.min.js |--- img |--- logo.png |--- скрипты
|--- hello-world.html //html-страница, используемая для мини-приложения |--- hello-world2.html // переименованная копия манифеста hello-world.html |--- vss-extension.json // расширения
Чтобы сохранить сведения о запросе, добавьте новый div
элемент в элемент h2
.
Обновите имя мини-приложения из HelloWorldWidget
HelloWorldWidget2
строки, в которой вы вызываете VSS.register
.
Это действие позволяет платформе однозначно идентифицировать мини-приложение в расширении.
<!DOCTYPE html>
<html>
<head>
<script src="sdk/scripts/VSS.SDK.min.js"></script>
<script type="text/javascript">
VSS.init({
explicitNotifyLoaded: true,
usePlatformStyles: true
});
VSS.require("TFS/Dashboards/WidgetHelpers", function (WidgetHelpers) {
WidgetHelpers.IncludeWidgetStyles();
VSS.register("HelloWorldWidget2", function () {
return {
load: function (widgetSettings) {
var $title = $('h2.title');
$title.text('Hello World');
return WidgetHelpers.WidgetStatusHelper.Success();
}
}
});
VSS.notifyLoadSucceeded();
});
</script>
</head>
<body>
<div class="widget">
<h2 class="title"></h2>
<div id="query-info-container"></div>
</div>
</body>
</html>
Шаг 2. Доступ к ресурсам Azure DevOps
Чтобы включить доступ к ресурсам Azure DevOps, в манифесте расширения необходимо указать области . Мы добавим vso.work
область в наш манифест.
Эта область указывает, что мини-приложение должно иметь доступ только для чтения к запросам и рабочим элементам. Ознакомьтесь со всеми доступными областями.
Добавьте следующий код в конце манифеста расширения.
{
"scopes":[
"vso.work"
]
}
Чтобы включить другие свойства, необходимо явно перечислить их, например:
{
"name": "example-widget",
"publisher": "example-publisher",
"version": "1.0.0",
"scopes": [
"vso.work"
]
}
Предупреждение
Добавление или изменение областей после публикации расширения в настоящее время не поддерживается. Если вы уже добавили расширение, удалите его из Marketplace. Перейдите на портал публикации Visual Studio Marketplace, щелкните правой кнопкой мыши расширение и нажмите кнопку "Удалить".
Шаг 3. Вызов REST API
Существует множество клиентских библиотек, к которым можно получить доступ через пакет SDK для выполнения вызовов REST API в Azure DevOps. Эти библиотеки называются клиентами REST и являются оболочками JavaScript вокруг вызовов Ajax для всех доступных конечных точек на стороне сервера. Вы можете использовать методы, предоставляемые этими клиентами, вместо написания вызовов Ajax самостоятельно. Эти методы сопоставляют ответы API с объектами, которые может использовать код.
На этом шаге VSS.require
мы обновим вызов загрузки AzureDevOps/WorkItemTracking/RestClient
, который предоставляет клиент REST WorkItemTracking.
Этот клиент REST можно использовать для получения сведений о запросе, вызываемом Feedback
в папке Shared Queries
.
Внутри передаваемой VSS.register
функции мы создадим переменную для хранения текущего идентификатора проекта. Нам нужна эта переменная, чтобы получить запрос.
Мы также создадим новый метод getQueryInfo
для использования клиента REST. Этот метод, который затем вызывается из метода load.
Этот метод getClient
предоставляет экземпляр необходимого клиента REST.
Метод getQuery
возвращает запрос, упакованный в обещание.
Обновленная версия VSS.require
выглядит следующим образом:
VSS.require(["AzureDevOps/Dashboards/WidgetHelpers", "AzureDevOps/WorkItemTracking/RestClient"],
function (WidgetHelpers, TFS_Wit_WebApi) {
WidgetHelpers.IncludeWidgetStyles();
VSS.register("HelloWorldWidget2", function () {
var projectId = VSS.getWebContext().project.id;
var getQueryInfo = function (widgetSettings) {
// Get a WIT client to make REST calls to Azure DevOps Services
return TFS_Wit_WebApi.getClient().getQuery(projectId, "Shared Queries/Feedback")
.then(function (query) {
// Do something with the query
return WidgetHelpers.WidgetStatusHelper.Success();
}, function (error) {
return WidgetHelpers.WidgetStatusHelper.Failure(error.message);
});
}
return {
load: function (widgetSettings) {
// Set your title
var $title = $('h2.title');
$title.text('Hello World');
return getQueryInfo(widgetSettings);
}
}
});
VSS.notifyLoadSucceeded();
});
Обратите внимание на использование метода Failure из WidgetStatusHelper
.
Он позволяет указать платформу мини-приложений, что произошла ошибка и воспользоваться стандартным интерфейсом ошибок, предоставляемым всем мини-приложениям.
Если у вас нет Feedback
запроса в Shared Queries
папке, замените Shared Queries\Feedback
код путем запроса, существующего в проекте.
Шаг 4. Отображение ответа
Последний шаг — отрисовка сведений запроса внутри мини-приложения.
Функция getQuery
возвращает объект типа Contracts.QueryHierarchyItem
внутри обещания.
В этом примере отображается идентификатор запроса, имя запроса и имя создателя запроса в текстовом тексте Hello World.
Замените комментарий // Do something with the query
следующим фрагментом кода:
// Create a list with query details
var $list = $('<ul>');
$list.append($('<li>').text("Query Id: " + query.id));
$list.append($('<li>').text("Query Name: " + query.name));
$list.append($('<li>').text("Created By: " + (query.createdBy ? query.createdBy.displayName : "<unknown>")));
// Append the list to the query-info-container
var $container = $('#query-info-container');
$container.empty();
$container.append($list);
Ваш окончательный hello-world2.html
пример выглядит следующим образом:
<!DOCTYPE html>
<html>
<head>
<script src="sdk/scripts/VSS.SDK.min.js"></script>
<script type="text/javascript">
VSS.init({
explicitNotifyLoaded: true,
usePlatformStyles: true
});
VSS.require(["AzureDevOps/Dashboards/WidgetHelpers", "AzureDevOps/WorkItemTracking/RestClient"],
function (WidgetHelpers, TFS_Wit_WebApi) {
WidgetHelpers.IncludeWidgetStyles();
VSS.register("HelloWorldWidget2", function () {
var projectId = VSS.getWebContext().project.id;
var getQueryInfo = function (widgetSettings) {
// Get a WIT client to make REST calls to Azure DevOps Services
return TFS_Wit_WebApi.getClient().getQuery(projectId, "Shared Queries/Feedback")
.then(function (query) {
// Create a list with query details
var $list = $('<ul>');
$list.append($('<li>').text("Query ID: " + query.id));
$list.append($('<li>').text("Query Name: " + query.name));
$list.append($('<li>').text("Created By: " + (query.createdBy ? query.createdBy.displayName : "<unknown>")));
// Append the list to the query-info-container
var $container = $('#query-info-container');
$container.empty();
$container.append($list);
// Use the widget helper and return success as Widget Status
return WidgetHelpers.WidgetStatusHelper.Success();
}, function (error) {
// Use the widget helper and return failure as Widget Status
return WidgetHelpers.WidgetStatusHelper.Failure(error.message);
});
}
return {
load: function (widgetSettings) {
// Set your title
var $title = $('h2.title');
$title.text('Hello World');
return getQueryInfo(widgetSettings);
}
}
});
VSS.notifyLoadSucceeded();
});
</script>
</head>
<body>
<div class="widget">
<h2 class="title"></h2>
<div id="query-info-container"></div>
</div>
</body>
</html>
Шаг 5. Обновление манифеста расширения
На этом шаге мы обновим манифест расширения, чтобы включить запись для второго мини-приложения.
Добавьте новый вклад в массив в contributions
свойстве и добавьте новый файл hello-world2.html
в массив в свойстве файлов.
Для второго мини-приложения требуется еще один предварительный просмотр. Назовите его preview2.png
и поместите его в папку img
.
{
...,
"contributions": [
...,
{
"id": "HelloWorldWidget2",
"type": "ms.vss-dashboards-web.widget",
"targets": [
"ms.vss-dashboards-web.widget-catalog"
],
"properties": {
"name": "Hello World Widget 2 (with API)",
"description": "My second widget",
"previewImageUrl": "img/preview2.png",
"uri": "hello-world2.html",
"supportedSizes": [
{
"rowSpan": 1,
"columnSpan": 2
}
],
"supportedScopes": ["project_team"]
}
}
],
"files": [
{
"path": "hello-world.html",
"addressable": true
},
{
"path": "hello-world2.html",
"addressable": true
},
{
"path": "sdk/scripts",
"addressable": true
},
{
"path": "img",
"addressable": true
}
],
"scopes": [
"vso.work"
]
}
Шаг 6. Упаковка, публикация и общий доступ
Упаковка, публикация и предоставление общего доступа к расширению. Если вы уже опубликовали расширение, вы можете перепаковать расширение и напрямую обновить его в Marketplace.
Шаг 7. Добавление мини-приложения из каталога
Теперь перейдите на панель мониторинга https:\//dev.azure.com/{Your_Organization}/{Your_Project}
команды. Если эта страница уже открыта, обновите ее.
Наведите указатель мыши на правку и нажмите кнопку "Добавить". Откроется каталог мини-приложений, где вы нашли установленное мини-приложение.
Чтобы добавить его на панель мониторинга, выберите мини-приложение и нажмите кнопку "Добавить".
Часть 3. Настройка Hello World
В части 2 этого руководства вы узнали, как создать мини-приложение, отображающее сведения о запросах для жестко закодированного запроса. В этой части мы добавим возможность настроить запрос, который будет использоваться вместо жестко закодированного. При использовании режима конфигурации пользователь получает просмотр динамического предварительного просмотра мини-приложения на основе их изменений. Эти изменения сохраняются в мини-приложении на панели мониторинга при нажатии кнопки "Сохранить".
Шаг 1. Добавление HTML-файла
Реализация конфигураций мини-приложений и мини-приложений очень похожа. Оба реализованы в платформе расширений в качестве вкладов. Оба используют один и тот же файл ПАКЕТА SDK. VSS.SDK.min.js
Оба они основаны на HTML, JavaScript и CSS.
Скопируйте файл html-world2.html
из предыдущего примера и переименуйте копию hello-world3.html
в . Добавьте другой HTML-файл с именем configuration.html
.
Теперь папка выглядит следующим образом:
|--- README.md
|--- sdk
|--- node_modules
|--- scripts
|--- VSS.SDK.min.js
|--- img
|--- logo.png
|--- scripts
|--- configuration.html
|--- hello-world.html // html page to be used for your widget
|--- hello-world2.html // renamed copy of hello-world.html
|--- hello-world3.html // renamed copy of hello-world2.html
|--- vss-extension.json // extension's manifest
Добавьте следующий HTML-код в configuration.html
. В основном мы добавим обязательную ссылку на VSS.SDK.min.js
файл и select
элемент раскрывающегося списка, чтобы выбрать запрос из предустановленного списка.
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script src="sdk/scripts/VSS.SDK.min.js"></script>
</head>
<body>
<div class="container">
<fieldset>
<label class="label">Query: </label>
<select id="query-path-dropdown" style="margin-top:10px">
<option value="" selected disabled hidden>Please select a query</option>
<option value="Shared Queries/Feedback">Shared Queries/Feedback</option>
<option value="Shared Queries/My Bugs">Shared Queries/My Bugs</option>
<option value="Shared Queries/My Tasks">Shared Queries/My Tasks</option>
</select>
</fieldset>
</div>
</body>
</html>
Шаг 2. Настройка JavaScript
Используйте JavaScript для отображения содержимого в конфигурации мини-приложения так же, как и для мини-приложения на шаге 3 части 1 в этом руководстве.
Этот код JavaScript отображает содержимое, инициализирует пакет SDK VSS, сопоставляет код конфигурации мини-приложения с именем конфигурации и передает параметры конфигурации в платформу. В нашем случае следующий код загружает конфигурацию мини-приложения.
Откройте файл configuration.html
и следующий <script>
элемент <head>
.
<script type="text/javascript">
VSS.init({
explicitNotifyLoaded: true,
usePlatformStyles: true
});
VSS.require(["AzureDevOps/Dashboards/WidgetHelpers"], function (WidgetHelpers) {
VSS.register("HelloWorldWidget.Configuration", function () {
var $queryDropdown = $("#query-path-dropdown");
return {
load: function (widgetSettings, widgetConfigurationContext) {
var settings = JSON.parse(widgetSettings.customSettings.data);
if (settings && settings.queryPath) {
$queryDropdown.val(settings.queryPath);
}
return WidgetHelpers.WidgetStatusHelper.Success();
},
onSave: function() {
var customSettings = {
data: JSON.stringify({
queryPath: $queryDropdown.val()
})
};
return WidgetHelpers.WidgetConfigurationSave.Valid(customSettings);
}
}
});
VSS.notifyLoadSucceeded();
});
</script>
VSS.init
,VSS.require
иVSS.register
играть ту же роль, что они играли для мини-приложения, как описано в части 1. Единственное различие заключается в том, что для конфигураций мини-приложений функция, передаваемая дляVSS.register
возврата объекта, удовлетворяющего контрактуIWidgetConfiguration
.- Свойство
load
IWidgetConfiguration
контракта должно иметь функцию в качестве значения. Эта функция содержит набор шагов для отрисовки конфигурации мини-приложения. В нашем случае необходимо обновить выбранное значение раскрывающегося элемента с существующими параметрами, если таковые имеются. Эта функция вызывается при создании экземпляра платформыwidget configuration
- Свойство
onSave
IWidgetConfiguration
контракта должно иметь функцию в качестве значения. Эта функция вызывается платформой, когда пользователь выбирает "Сохранить " в области конфигурации. Если входные данные пользователя готовы к сохранению, сериализируйте его в строку, создайтеcustom settings
объект и сохранитеWidgetConfigurationSave.Valid()
входные данные пользователя.
В этом руководстве мы используем JSON для сериализации входных данных пользователя в строку. Вы можете выбрать любой другой способ сериализации входных данных пользователя в строку.
Он доступен для мини-приложения с помощью свойства WidgetSettings
customSettings объекта.
Мини-приложение требует десериализации, которое рассматривается на шаге 4.
Шаг 3. JavaScript — включение динамической предварительной версии
Чтобы включить динамическое обновление предварительной версии при выборе запроса из раскрывающегося списка, мы присоединяем обработчик событий изменения к кнопке. Этот обработчик уведомляет платформу об изменении конфигурации.
Он также передает используемый customSettings
для обновления предварительной версии. Чтобы уведомить платформу, notify
метод необходимо widgetConfigurationContext
вызвать. Он принимает два параметра, имя события, которое в данном случае — WidgetHelpers.WidgetEvent.ConfigurationChange
и EventArgs
объект для события, созданного с customSettings
помощью вспомогательного WidgetEvent.Args
метода.
Добавьте следующий код в функцию, назначенную свойству load
.
$queryDropdown.on("change", function () {
var customSettings = {
data: JSON.stringify({
queryPath: $queryDropdown.val()
})
};
var eventName = WidgetHelpers.WidgetEvent.ConfigurationChange;
var eventArgs = WidgetHelpers.WidgetEvent.Args(customSettings);
widgetConfigurationContext.notify(eventName, eventArgs);
});
Изменено. Убедитесь, что платформа уведомляется об изменении конфигурации по крайней мере один раз, чтобы включить кнопку "Сохранить ".
В конце configuration.html
вы выглядите следующим образом:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script src="sdk/scripts/VSS.SDK.min.js"></script>
<script type="text/javascript">
VSS.init({
explicitNotifyLoaded: true,
usePlatformStyles: true
});
VSS.require(["AzureDevOps/Dashboards/WidgetHelpers"], function (WidgetHelpers) {
VSS.register("HelloWorldWidget.Configuration", function () {
var $queryDropdown = $("#query-path-dropdown");
return {
load: function (widgetSettings, widgetConfigurationContext) {
var settings = JSON.parse(widgetSettings.customSettings.data);
if (settings && settings.queryPath) {
$queryDropdown.val(settings.queryPath);
}
$queryDropdown.on("change", function () {
var customSettings = {data: JSON.stringify({queryPath: $queryDropdown.val()})};
var eventName = WidgetHelpers.WidgetEvent.ConfigurationChange;
var eventArgs = WidgetHelpers.WidgetEvent.Args(customSettings);
widgetConfigurationContext.notify(eventName, eventArgs);
});
return WidgetHelpers.WidgetStatusHelper.Success();
},
onSave: function() {
var customSettings = {data: JSON.stringify({queryPath: $queryDropdown.val()})};
return WidgetHelpers.WidgetConfigurationSave.Valid(customSettings);
}
}
});
VSS.notifyLoadSucceeded();
});
</script>
</head>
<body>
<div class="container">
<fieldset>
<label class="label">Query: </label>
<select id="query-path-dropdown" style="margin-top:10px">
<option value="" selected disabled hidden>Please select a query</option>
<option value="Shared Queries/Feedback">Shared Queries/Feedback</option>
<option value="Shared Queries/My Bugs">Shared Queries/My Bugs</option>
<option value="Shared Queries/My Tasks">Shared Queries/My Tasks</option>
</select>
</fieldset>
</div>
</body>
</html>
Шаг 4. Реализация перезагрузки в мини-приложении — JavaScript
Мы настроили конфигурацию мини-приложения для хранения пути запроса, выбранного пользователем.
Теперь необходимо обновить код в мини-приложении, чтобы использовать эту хранимую конфигурацию вместо жестко закодированного Shared Queries/Feedback
из предыдущего примера.
Откройте файл hello-world3.html
и обновите имя мини-приложения в HelloWorldWidget2
HelloWorldWidget3
строку, в которой вы вызываете VSS.register
.
Это действие позволяет платформе однозначно идентифицировать мини-приложение в расширении.
Функция, сопоставленная с HelloWorldWidget3
текущей VSS.register
, возвращает объект, удовлетворяющий контракту IWidget
.
Так как наше мини-приложение теперь нуждается в настройке, эта функция должна быть обновлена, чтобы вернуть объект, удовлетворяющий контракту IConfigurableWidget
.
Для этого обновите оператор return, чтобы включить свойство, которое называется перезагрузкой в следующем коде. Значение этого свойства — это функция, которая вызывает getQueryInfo
метод еще раз.
Этот метод перезагрузки вызывается платформой каждый раз, когда пользователь изменяет входные данные для отображения динамической предварительной версии. Этот метод перезагрузки также вызывается при сохранении конфигурации.
return {
load: function (widgetSettings) {
// Set your title
var $title = $('h2.title');
$title.text('Hello World');
return getQueryInfo(widgetSettings);
},
reload: function (widgetSettings) {
return getQueryInfo(widgetSettings);
}
}
Путь к жестко закодированному запросу должен быть заменен настроенным путем getQueryInfo
запроса, который можно извлечь из параметра widgetSettings
, переданного методу.
Добавьте следующий код в самом начале getQueryInfo
метода и замените жестко закодированный путь settings.queryPath
запроса на .
var settings = JSON.parse(widgetSettings.customSettings.data);
if (!settings || !settings.queryPath) {
var $container = $('#query-info-container');
$container.empty();
$container.text("Sorry nothing to show, please configure a query path.");
return WidgetHelpers.WidgetStatusHelper.Success();
}
На этом этапе мини-приложение готово к отображению с настроенными параметрами.
load
reload
Оба свойства имеют аналогичную функцию. Это касается большинства простых мини-приложений.
Для сложных мини-приложений будут выполняться определенные операции, которые нужно выполнять только один раз, независимо от того, сколько раз изменяется конфигурация.
Или могут быть некоторые операции с большим весом, которые не должны выполняться более одного раза. Такие операции будут частью функции, соответствующей load
свойству, а не свойству reload
.
Шаг 5. Обновление манифеста расширения
vss-extension.json
Откройте файл, чтобы включить две новые записи в массив в contributions
свойство. Один для HelloWorldWidget3
мини-приложения и другой для его конфигурации.
Вам нужен еще один предварительный просмотр образа для третьего мини-приложения. Назовите его preview3.png
и поместите его в папку img
.
Обновите массив в свойстве files
, чтобы включить два новых HTML-файла, которые мы добавили в этом примере.
{
...
"contributions": [
... ,
{
"id": "HelloWorldWidget3",
"type": "ms.vss-dashboards-web.widget",
"targets": [
"ms.vss-dashboards-web.widget-catalog",
"fabrikam.azuredevops-extensions-myExtensions.HelloWorldWidget.Configuration"
],
"properties": {
"name": "Hello World Widget 3 (with config)",
"description": "My third widget",
"previewImageUrl": "img/preview3.png",
"uri": "hello-world3.html",
"supportedSizes": [
{
"rowSpan": 1,
"columnSpan": 2
}
],
"supportedScopes": ["project_team"]
}
},
{
"id": "HelloWorldWidget.Configuration",
"type": "ms.vss-dashboards-web.widget-configuration",
"targets": [ "ms.vss-dashboards-web.widget-configuration" ],
"properties": {
"name": "HelloWorldWidget Configuration",
"description": "Configures HelloWorldWidget",
"uri": "configuration.html"
}
}
],
"files": [
{
"path": "hello-world.html", "addressable": true
},
{
"path": "hello-world2.html", "addressable": true
},
{
"path": "hello-world3.html", "addressable": true
},
{
"path": "configuration.html", "addressable": true
},
{
"path": "sdk/scripts", "addressable": true
},
{
"path": "img", "addressable": true
}
],
...
}
Вклад в конфигурацию мини-приложения следует немного отличается от модели самого мини-приложения. Запись вклада для конфигурации мини-приложения имеет:
- Идентификатор для идентификации вашего вклада. Идентификатор должен быть уникальным в пределах расширения.
- Тип вклада. Для всех конфигураций мини-приложений оно должно быть
ms.vss-dashboards-web.widget-configuration
- Массив целевых объектов , в которые вносится вклад. Для всех конфигураций мини-приложений она имеет одну запись:
ms.vss-dashboards-web.widget-configuration
- Свойства, содержащие набор свойств, включающих имя, описание и URI HTML-файла, используемого для настройки.
Для поддержки конфигурации необходимо также изменить вклад мини-приложения. Массив целевых объектов для мини-приложения необходимо обновить, чтобы включить идентификатор конфигурации в форму <publisher
>.>id for the extension
<,<id for the configuration contribution
> что в данном случае .fabrikam.vsts-extensions-myExtensions.HelloWorldWidget.Configuration
Предупреждение
Если запись вклада для настраиваемого мини-приложения не нацелена на конфигурацию с использованием правильного издателя и имени расширения, как описано ранее, кнопка настройки не отображается для мини-приложения.
В конце этой части файл манифеста должен содержать три мини-приложения и одну конфигурацию. Полный манифест можно получить из примера здесь.
Шаг 6. Упаковка, публикация и общий доступ
Если расширение не опубликовано, см . этот раздел. Если вы уже опубликовали расширение, вы можете перепаковать расширение и напрямую обновить его в Marketplace.
Шаг 7. Добавление мини-приложения из каталога
Теперь перейдите на панель мониторинга группы в https://dev.azure.com/{Your_Organization}/{Your_Project}. Если эта страница уже открыта, обновите ее. Наведите указатель мыши на правку и нажмите кнопку "Добавить". Это действие должно открыть каталог мини-приложений, где вы нашли установленное мини-приложение. Чтобы добавить мини-приложение на панель мониторинга, выберите мини-приложение и нажмите кнопку "Добавить".
Сообщение, аналогичное приведенному ниже, запрашивает настройку мини-приложения.
Существует два способа настройки мини-приложений. Один из них — навести указатель мыши на мини-приложение, выбрать многоточие, которое отображается в правом верхнем углу, а затем нажмите кнопку "Настроить". Другой — выбрать кнопку "Изменить" в правом нижнем углу панели мониторинга, а затем нажать кнопку настройки, которая отображается в правом верхнем углу мини-приложения. Откроется интерфейс конфигурации справа и предварительная версия мини-приложения в центре. Перейдите к запросу в раскрывающемся списке. В динамической предварительной версии отображаются обновленные результаты. Выберите "Сохранить " и мини-приложение отображает обновленные результаты.
Шаг 8. Настройка дополнительных (необязательных)
Вы можете добавить столько элементов формы HTML, сколько требуется для configuration.html
получения дополнительной конфигурации.
Доступны две настраиваемые функции: имя мини-приложения и размер мини-приложения.
По умолчанию имя, указанное для мини-приложения в манифесте расширения, хранится в качестве имени мини-приложения для каждого экземпляра мини-приложения, который когда-либо добавляется на панель мониторинга.
Вы можете разрешить пользователям настраивать, чтобы они могли добавлять любое имя, которое они хотят, в свой экземпляр мини-приложения.
Чтобы разрешить такую конфигурацию, добавьте isNameConfigurable:true
в раздел свойств мини-приложения в манифесте расширения.
Если вы предоставляете несколько записей для мини-приложения в массиве supportedSizes
в манифесте расширения, пользователи также могут настроить размер мини-приложения.
Манифест расширения для третьего примера в этом руководстве будет выглядеть следующим образом, если включить конфигурацию имени мини-приложения и размера:
{
...
"contributions": [
... ,
{
"id": "HelloWorldWidget3",
"type": "ms.vss-dashboards-web.widget",
"targets": [
"ms.vss-dashboards-web.widget-catalog",
"fabrikam.azuredevops-extensions-myExtensions.HelloWorldWidget.Configuration"
],
"properties": {
"name": "Hello World Widget 3 (with config)",
"description": "My third widget",
"previewImageUrl": "img/preview3.png",
"uri": "hello-world3.html",
"isNameConfigurable": true,
"supportedSizes": [
{
"rowSpan": 1,
"columnSpan": 2
},
{
"rowSpan": 2,
"columnSpan": 2
}
],
"supportedScopes": ["project_team"]
}
},
...
]
}
При предыдущем изменении перепакуйте и обновите расширение. Обновите панель мониторинга с этим мини-приложением (Hello World Widget 3 (с конфигурацией)). Откройте режим конфигурации для мини-приложения, теперь вы сможете просмотреть параметр для изменения имени и размера мини-приложения.
Выберите другой размер в раскрывающемся списке. Отображается изменение размера динамического предварительного просмотра. Сохраните изменения и мини-приложение на панели мониторинга также изменяется.
Изменение имени мини-приложения не приводит к каким-либо видимым изменениям в мини-приложении, так как наши примеры мини-приложений не отображают имя мини-приложения в любом месте. Давайте изменим пример кода, чтобы отобразить имя мини-приложения вместо жестко закодированного текста Hello World.
Для этого замените жестко закодированный текст Hello World widgetSettings.name
на строку, в которой мы задали текст h2
элемента.
Это действие гарантирует, что имя мини-приложения отображается каждый раз, когда мини-приложение загружается на обновление страницы.
Так как мы хотим, чтобы динамический просмотр обновлялся каждый раз при изменении конфигурации, мы должны добавить тот же код в reload
часть нашего кода.
Последняя инструкция hello-world3.html
возврата приведена следующим образом:
return {
load: function (widgetSettings) {
// Set your title
var $title = $('h2.title');
$title.text(widgetSettings.name);
return getQueryInfo(widgetSettings);
},
reload: function (widgetSettings) {
// Set your title
var $title = $('h2.title');
$title.text(widgetSettings.name);
return getQueryInfo(widgetSettings);
}
}
Перепакуйте и обновите расширение еще раз. Обновите панель мониторинга с этим мини-приложением.
Все изменения имени мини-приложения в режиме конфигурации теперь обновите название мини-приложения.