Přidání widgetu řídicího panelu
Azure DevOps Services | Azure DevOps Server 2022 – Azure DevOps Server 2019
Widgety na řídicím panelu se implementují jako příspěvky v rámci rozšíření. Jedno rozšíření může mít více příspěvků. Zjistěte, jak vytvořit rozšíření s více widgety jako příspěvky.
Tento článek je rozdělený na tři části, z nichž každá vychází z předchozího – počínaje jednoduchým widgetem a končící komplexním widgetem.
Tip
Projděte si nejnovější dokumentaci k vývoji rozšíření pomocí sady SDK rozšíření Azure DevOps.
Požadavky
- Znalost: Některé znalosti JavaScriptu, HTML, CSS jsou vyžadovány pro vývoj widgetů.
- Organizace v Azure DevOps.
- Textový editor. Pro mnoho kurzů používáme Visual Studio Code.
- Nejnovější verze uzlu.
- Multiplatformní rozhraní příkazového řádku pro Azure DevOps (tfx-cli) pro zabalení rozšíření
- tfx-cli lze nainstalovat pomocí
npm
komponenty Node.js spuštěním příkazunpm i -g tfx-cli
- tfx-cli lze nainstalovat pomocí
- Domovský adresář projektu. Tento adresář se označuje jako
home
v průběhu kurzu.
Struktura souborů přípony:
|--- 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
V tomto kurzu
- Část 1: Ukazuje, jak vytvořit nový widget, který vytiskne jednoduchou zprávu "Hello World".
- Část 2: Vychází z první části přidáním volání do rozhraní REST API Azure DevOps.
- Část 3: Vysvětluje, jak do widgetu přidat konfiguraci.
Poznámka:
Pokud jste ve spěchu a chcete si rovnou stáhnout kód, můžete si ukázky stáhnout.
Po stažení přejděte do widgets
složky a pak postupujte podle kroku 6 a kroku 7 přímo a publikujte ukázkové rozšíření, které obsahuje tři ukázkové widgety s různými složitostmi.
Začněte s některými základními styly widgetů , které poskytujeme od začátku a pokyny ke struktuře widgetů.
Část 1: Hello World
Část 1 představuje widget, který vytiskne "Hello World" pomocí JavaScriptu.
Krok 1: Získání klientské sady SDK – VSS.SDK.min.js
Základní skript VSS.SDK.min.js
sady SDK umožňuje webovým rozšířením komunikovat s hostitelským rámcem Azure DevOps. Skript provádí operace, jako je inicializace, upozorňování rozšíření, načtení rozšíření nebo získání kontextu o aktuální stránce.
Získejte soubor klientské sady SDK VSS.SDK.min.js
a přidejte ho do webové aplikace. Umístěte ho do home/sdk/scripts
složky.
K načtení sady SDK použijte příkaz npm install:
npm install vss-web-extension-sdk
Další informace najdete na stránce GitHub klientské sady SDK.
Krok 2: Nastavení stránky HTML – hello-world.html
Stránka HTML je připevnění, které obsahuje rozložení společně a obsahuje odkazy na šablony stylů CSS a JavaScript. Tento soubor můžete pojmenovat cokoli. Aktualizujte všechny odkazy na název, který hello-world
používáte.
Váš widget je založený na HTML a je hostovaný v prvku iframe.
hello-world.html
Do souboru . Do souboru přidáme povinný odkaz VSS.SDK.min.js
a zahrneme prvek h2
, který se aktualizuje řetězcem Hello World v nadcházejícím kroku.
<!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>
I když používáme soubor HTML, většina hlavních prvků HTML než skript a odkaz jsou ignorovány architekturou.
Krok 3: Aktualizace JavaScriptu
K vykreslení obsahu ve widgetu používáme JavaScript. V tomto článku zabalíme veškerý kód JavaScriptu do <script>
elementu v souboru HTML. Tento kód můžete mít v samostatném javascriptovém souboru a odkazovat ho v souboru HTML.
Kód vykreslí obsah. Tento javascriptový kód také inicializuje sadu SDK sady VSS, mapuje kód widgetu na název widgetu a upozorní architekturu rozšíření úspěšných nebo neúspěšných widgetů.
V našem případě následující kód ve widgetu vytiskne text "Hello World". Přidejte tento script
prvek do 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
inicializuje metodu handshake mezi elementem iframe, který je hostitelem widgetu a rámcem hostitele.- Předáme
explicitNotifyLoaded: true
, aby widget mohl hostitele explicitně upozornit, až se načítá. Tento ovládací prvek nám umožňuje oznámit dokončení načtení po zajištění načtení závislých modulů. ProjdemeusePlatformStyles: true
, aby widget mohl používat základní styly Azure DevOps pro elementy HTML (například tělo, div atd.). Pokud widget dává přednost tomu, aby tyto styly nepoužívali, mohou předatusePlatformStyles: false
. VSS.require
slouží k načtení požadovaných knihoven skriptů VSS. Volání této metody automaticky načte obecné knihovny, jako jsou JQuery a JQueryUI. V našem případě závisíme na knihovně WidgetHelpers, která slouží ke komunikaci stavu widgetu s architekturou widgetů. Proto předáme odpovídající názevTFS/Dashboards/WidgetHelpers
modulu a zpětné volání .VSS.require
Zpětné volání se volá po načtení modulu. Zpětné volání obsahuje zbytek kódu JavaScriptu potřebného pro widget. Na konci zpětného volání volámeVSS.notifyLoadSucceeded
, abychom oznámili dokončení načítání.WidgetHelpers.IncludeWidgetStyles
obsahuje šablonu stylů s některými základními šablonami stylů CSS , které vám pomůžou začít. Chcete-li použít tyto styly, zabalte obsah uvnitř html elementu třídywidget
.VSS.register
slouží k mapování funkce v JavaScriptu, která jednoznačně identifikuje widget mezi různými příspěvky ve vašem rozšíření. Název by měl odpovídat vašemu příspěvkuid
, jak je popsáno v kroku 5. U widgetů by funkce, která je předánaVSS.register
, měla vrátit objekt, který splňujeIWidget
kontrakt, například vrácený objekt by měl mít vlastnost načtení, jejíž hodnota je další funkce, která má základní logiku k vykreslení widgetu. V našem případě je třeba aktualizovat texth2
prvku na "Hello World". Je to tato funkce, která se volá, když architektura widgetu vytvoří instanci widgetu. PomocíWidgetStatusHelper
widgetHelperů vrátímeWidgetStatus
úspěch.
Upozorňující
Pokud název použitý k registraci widgetu neodpovídá ID příspěvku v manifestu, funkce widgetu neočekávaně funguje.
vss-extension.json
by měl být vždy v kořenovém adresáři složky (v této příručce,HelloWorld
). U všech ostatních souborů je můžete umístit do libovolné struktury, kterou chcete ve složce, stačí, abyste odkazy správně aktualizovali v souborech HTML a v manifestuvss-extension.json
.
Krok 4: Aktualizace loga rozšíření: logo.png
Logo se zobrazí na Marketplace a v katalogu widgetů, jakmile uživatel nainstaluje vaše rozšíření.
Potřebujete ikonu katalogu 98 px x 98-px. Zvolte obrázek, pojmenujte ho logo.png
a umístěte ho do img
složky.
Tyto image ale můžete pojmenovat, pokud se manifest rozšíření v dalším kroku aktualizuje o názvy, které používáte.
Krok 5: Vytvoření manifestu rozšíření: vss-extension.json
Každá přípona musí mít soubor manifestu přípony.
- Přečtěte si referenční informace k manifestu rozšíření.
- Přečtěte si další informace o bodech příspěvku v bodech rozšiřitelnosti.
- V adresáři vytvořte soubor JSON (
vss-extension.json
například)home
s následujícím obsahem:
{
"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
}
]
}
Další informace o požadovaných atributech najdete v referenčních informacích k manifestu rozšíření.
Poznámka:
Změňte vydavatele na název vydavatele. Pokud chcete vytvořit vydavatele, přečtěte si téma Balíček/ Publikování/Instalace.
Ikony
Ikony stanza určuje cestu k ikoně rozšíření v manifestu.
Příspěvky
Každá položka příspěvku definuje vlastnosti.
- ID pro identifikaci vašeho příspěvku Toto ID by mělo být jedinečné v rámci rozšíření. Toto ID by se mělo shodovat s názvem, který jste použili v kroku 3 k registraci widgetu.
- Typ příspěvku. Pro všechny widgety by měl být
ms.vss-dashboards-web.widget
typ . - Pole cílů , ke kterým přispívá příspěvek. Pro všechny widgety by měl být
[ms.vss-dashboards-web.widget-catalog]
cíl . - Vlastnosti jsou objekty, které zahrnují vlastnosti pro typ příspěvku. Pro widgety jsou povinné následující vlastnosti.
Vlastnost | Popis |
---|---|
name | Název widgetu, který se má zobrazit v katalogu widgetů |
description | Popis widgetu, který se má zobrazit v katalogu widgetů |
catalogIconUrl | Relativní cesta ikony katalogu, kterou jste přidali v kroku 4 pro zobrazení v katalogu widgetů. Obrázek by měl být 98 px x 98 px. Pokud jste použili jinou strukturu složek nebo jiný název souboru, zadejte zde odpovídající relativní cestu. |
previewImageUrl | Relativní cesta k obrázku náhledu, který jste přidali v kroku 4 , aby se zobrazil v katalogu widgetů. Obrázek by měl být 330 px x 160 px. Pokud jste použili jinou strukturu složek nebo jiný název souboru, zadejte zde odpovídající relativní cestu. |
uri | Relativní cesta k souboru HTML, který jste přidali v kroku 1. Pokud jste použili jinou strukturu složek nebo jiný název souboru, zadejte zde odpovídající relativní cestu. |
supportedSizes | Pole velikostí podporovaných widgetem Pokud widget podporuje více velikostí, první velikost v poli je výchozí velikost widgetu. Určuje se widget size pro řádky a sloupce obsazené widgetem v mřížce řídicího panelu. Jeden řádek/sloupec odpovídá 160 px. Jakákoli dimenze větší než 1x1 získá extra 10 pixelů, které představují hřbet mezi widgety. Například widget 3x2 je 160*3+10*2 široký a 160*2+10*1 vysoký. Maximální podporovaná velikost je 4x4 . |
supportedScopes | V současné době se podporují jenom týmové řídicí panely. Hodnota musí být project_team . Budoucí aktualizace můžou obsahovat další možnosti pro obory řídicích panelů. |
Soubory
Soubory stanza uvádí soubory, které chcete zahrnout do balíčku – stránku HTML, skripty, skripty sady SDK a logo.
true
Pokud addressable
nezahrnete jiné soubory, které nemusí být adresovatelné adresou URL.
Poznámka:
Další informace o souboru manifestu přípony, jako jsou jeho vlastnosti a co dělají, najdete v referenčních informacích k manifestu rozšíření.
Krok 6: Balení, publikování a sdílení
Až budete mít napsané rozšíření, dalším krokem, jak ho dostat do Marketplace, je zabalit všechny soubory dohromady. Všechna rozšíření jsou zabalená jako soubory .vsix kompatibilní s VSIX 2.0 – Microsoft poskytuje rozhraní příkazového řádku (CLI) pro více platforem pro zabalení rozšíření.
Získání nástroje pro balení
Rozhraní příkazového řádku pro azure DevOps (tfx-cli) můžete nainstalovat nebo aktualizovat pomocí npm
komponenty Node.js z příkazového řádku.
npm i -g tfx-cli
Zabalení rozšíření
Zabalení rozšíření do souboru .vsix je snadné, jakmile máte tfx-cli. Přejděte do domovského adresáře rozšíření a spusťte následující příkaz.
tfx extension create --manifest-globs vss-extension.json
Poznámka:
Při každé aktualizaci se musí zvýšit verze rozšíření nebo integrace.
Při aktualizaci existujícího rozšíření buď aktualizujte verzi v manifestu, nebo předejte přepínač příkazového --rev-version
řádku. Tím se zvýší číslo verze opravy vašeho rozšíření a uloží se nová verze do manifestu.
Jakmile rozšíření zabalíte do souboru .vsix, můžete rozšíření publikovat na Marketplace.
Vytvoření vydavatele pro rozšíření
Všechna rozšíření, včetně rozšíření od Microsoftu, jsou identifikována jako poskytovaná vydavatelem. Pokud ještě nejste členem existujícího vydavatele, vytvořte ho.
- Přihlášení k portálu publikování na Webu Visual Studio Marketplace
- Pokud ještě nejste členem existujícího vydavatele, musíte vytvořit vydavatele. Pokud již máte vydavatele, posuňte se a vyberte Možnost Publikovat rozšíření v části Související weby.
- Zadejte identifikátor vydavatele, například:
mycompany-myteam
- Identifikátor se používá jako hodnota atributu v souboru manifestu
publisher
rozšíření.
- Identifikátor se používá jako hodnota atributu v souboru manifestu
- Zadejte zobrazovaný název vydavatele, například:
My Team
- Zadejte identifikátor vydavatele, například:
- Zkontrolujte smlouvu vydavatele Marketplace a vyberte Vytvořit.
Teď je váš vydavatel definovaný. V budoucí verzi můžete udělit oprávnění k zobrazení a správě rozšíření vydavatele.
Publikování rozšíření v rámci běžného vydavatele zjednodušuje proces pro týmy a organizace a nabízí bezpečnější přístup. Tato metoda eliminuje potřebu distribuovat jednu sadu přihlašovacích údajů mezi více uživatelů, což zvyšuje zabezpečení a
Aktualizujte soubor manifestu vss-extension.json
v ukázkách a nahraďte fiktivní ID fabrikam
vydavatele vaším ID vydavatele.
Publikování a sdílení rozšíření
Teď můžete svoje rozšíření nahrát na Marketplace.
Vyberte Nahrát nové rozšíření, přejděte do zabaleného souboru .vsix a vyberte Nahrát.
Rozšíření můžete nahrát také pomocí příkazového řádku, tfx extension publish
a ne tfx extension create
zabalit a publikovat rozšíření v jednom kroku.
Volitelně můžete rozšíření po publikování sdílet --share-with
s jedním nebo více účty.
Potřebujete také osobní přístupový token.
tfx extension publish --manifest-globs your-manifest.json --share-with yourOrganization
Krok 7: Přidání widgetu z katalogu
Přihlaste se ke svému projektu.
http://dev.azure.com/{Your_Organization}/{Your_Project}
Vyberte řídicí panely přehledu>.
Vyberte možnost Přidejte pomůcku.
Zvýrazněte widget a pak vyberte Přidat.
Widget se zobrazí na řídicím panelu.
Část 2: Hello World s využitím azure DevOps REST API
Widgety můžou volat libovolná rozhraní REST API v Azure DevOps pro interakci s prostředky Azure DevOps. V následujícím příkladu použijeme rozhraní REST API pro WorkItemTracking k načtení informací o existujícím dotazu a zobrazení některých informací o dotazu ve widgetu pod textem Hello World.
Krok 1: Přidání souboru HTML
Zkopírujte soubor hello-world.html
z předchozího příkladu a přejmenujte kopii na hello-world2.html
. Vaše složka teď vypadá jako v následujícím příkladu:
|--- README.md |--- node_modules
|--- SDK
|--- skripty |--- VSS. SDK.min.js |--- img |--- logo.png |--- skripty
|--- hello-world.html // html stránku, která se má použít pro widget |--- hello-world2.html // přejmenovaná kopie manifestu rozšíření hello-world.html |--- vss-extension.json ///
Chcete-li uchovávat informace o dotazu, přidejte nový div
prvek pod .h2
Aktualizujte název widgetu z HelloWorldWidget
řádku HelloWorldWidget2
, do kterého voláte VSS.register
.
Tato akce umožňuje rozhraní jednoznačně identifikovat widget v rámci rozšíření.
<!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>
Krok 2: Přístup k prostředkům Azure DevOps
Pokud chcete povolit přístup k prostředkům Azure DevOps, musí se obory zadat v manifestu rozšíření. Do manifestu vso.work
přidáme obor.
Tento obor označuje, že widget potřebuje přístup jen pro čtení k dotazům a pracovním položkám. Tady najdete všechny dostupné obory.
Na konec manifestu rozšíření přidejte následující kód.
{
"scopes":[
"vso.work"
]
}
Pokud chcete zahrnout další vlastnosti, měli byste je uvést explicitně, například:
{
"name": "example-widget",
"publisher": "example-publisher",
"version": "1.0.0",
"scopes": [
"vso.work"
]
}
Upozorňující
Přidání nebo změna oborů po publikování rozšíření se v současné době nepodporuje. Pokud jste rozšíření už nahráli, odeberte ho z Marketplace. Přejděte na portál publikování na Webu Visual Studio Marketplace, vyberte rozšíření pravým tlačítkem a vyberte Odebrat.
Krok 3: Volání rozhraní REST API
Existuje mnoho knihoven na straně klienta, ke kterým je možné přistupovat prostřednictvím sady SDK, aby bylo možné provádět volání rozhraní REST API v Azure DevOps. Tyto knihovny se nazývají klienti REST a představují obálky JavaScriptu kolem volání Ajaxu pro všechny dostupné koncové body na straně serveru. Metody poskytované těmito klienty můžete použít místo psaní volání Ajax sami. Tyto metody mapují odpovědi rozhraní API na objekty, které může váš kód využívat.
V tomto kroku aktualizujeme VSS.require
volání pro načtení AzureDevOps/WorkItemTracking/RestClient
, které poskytuje klienta REST WorkItemTracking.
Tento klient REST můžeme použít k získání informací o dotazu volaný Feedback
pod složkou Shared Queries
.
Uvnitř funkce, do VSS.register
které předáváme , vytvoříme proměnnou, která bude obsahovat aktuální ID projektu. K načtení dotazu potřebujeme tuto proměnnou.
Vytvoříme také novou metodu getQueryInfo
pro použití klienta REST. Tato metoda, která se pak volá z metody načítání.
Metoda getClient
poskytuje instanci klienta REST, který potřebujeme.
Metoda getQuery
vrátí dotaz zabalený do příslibu.
VSS.require
Aktualizace vypadá takto:
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();
});
Všimněte si použití metody Failure z WidgetStatusHelper
.
Umožňuje indikovat rozhraní widgetů, že došlo k chybě, a využít standardní chybové prostředí poskytované všem widgetům.
Pokud dotaz ve složce nemáte Feedback
Shared Queries
, nahraďte Shared Queries\Feedback
v kódu cestu dotazu, který v projektu existuje.
Krok 4: Zobrazení odpovědi
Posledním krokem je vykreslení informací o dotazu uvnitř widgetu.
Funkce getQuery
vrátí objekt typu Contracts.QueryHierarchyItem
uvnitř příslibu.
V tomto příkladu zobrazíme ID dotazu, název dotazu a název tvůrce dotazu pod textem Hello World.
Nahraďte komentář // Do something with the query
následujícím kódem:
// 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);
Vaše konečné hello-world2.html
je jako v následujícím příkladu:
<!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>
Krok 5: Aktualizace manifestu rozšíření
V tomto kroku aktualizujeme manifest rozšíření tak, aby zahrnoval položku pro náš druhý widget.
Přidejte nový příspěvek do pole ve contributions
vlastnosti a přidejte nový soubor hello-world2.html
do pole ve vlastnosti soubory.
Pro druhý widget potřebujete další obrázek náhledu. preview2.png
Pojmenujte ho a umístěte ho do img
složky.
{
...,
"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"
]
}
Krok 6: Balení, publikování a sdílení
Zabalte, publikujte a sdílejte rozšíření. Pokud jste rozšíření už publikovali, můžete rozšíření znovu zabalit a přímo ho aktualizovat na Marketplace.
Krok 7: Přidání widgetu z katalogu
Teď přejděte na řídicí panel týmu na adrese https:\//dev.azure.com/{Your_Organization}/{Your_Project}
. Pokud je tato stránka už otevřená, aktualizujte ji.
Najetím myší na Upravit a vyberte Přidat. Otevře se katalog widgetů, kde najdete widget, který jste nainstalovali.
Pokud ho chcete přidat na řídicí panel, zvolte widget a vyberte Přidat.
Část 3: Konfigurace Hello World
V části 2 tohoto průvodce jste viděli, jak vytvořit widget, který zobrazuje informace o dotazu pro pevně zakódovaný dotaz. V této části přidáme možnost nakonfigurovat dotaz tak, aby se používal místo pevně zakódovaného dotazu. Když je v režimu konfigurace, uživatel se na základě změn dostane k živému náhledu widgetu. Tyto změny se uloží do widgetu na řídicím panelu, když uživatel vybere Možnost Uložit.
Krok 1: Přidání souboru HTML
Implementace widgetů a konfigurací widgetů jsou hodně podobné. Obě jsou implementovány v rámci rozšíření jako příspěvky. Oba používají stejný soubor SDK, VSS.SDK.min.js
. Obě jsou založené na HTML, JavaScriptu a CSS.
Zkopírujte soubor html-world2.html
z předchozího příkladu a přejmenujte kopii na hello-world3.html
. Přidejte další soubor HTML s názvem configuration.html
.
Vaše složka teď vypadá jako v následujícím příkladu:
|--- 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
configuration.html
Do souboru . V podstatě přidáme povinný odkaz na VSS.SDK.min.js
soubor a select
prvek rozevíracího seznamu pro výběr dotazu z přednastaveného seznamu.
<!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>
Krok 2: Konfigurace JavaScriptu
Pomocí JavaScriptu můžete vykreslit obsah v konfiguraci widgetu stejně jako u widgetu v kroku 3 části 1 v této příručce.
Tento kód JavaScriptu vykreslí obsah, inicializuje sadu SDK sady VSS, mapuje kód konfigurace widgetu na název konfigurace a předá nastavení konfigurace do architektury. V našem případě následující kód načte konfiguraci widgetu.
Otevřete soubor configuration.html
a následující <script>
prvek do souboru <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
aVSS.register
hrají stejnou roli, jakou hráli pro widget, jak je popsáno v části 1. Jediným rozdílem je, že pro konfigurace widgetu by funkce, která je předánaVSS.register
, měla vrátit objekt, který splňujeIWidgetConfiguration
kontrakt.- Vlastnost
load
kontraktuIWidgetConfiguration
by měla mít funkci jako její hodnotu. Tato funkce obsahuje sadu kroků pro vykreslení konfigurace widgetu. V našem případě je potřeba aktualizovat vybranou hodnotu prvku rozevíracího seznamu s existujícím nastavením, pokud existuje. Tato funkce se zavolá, když architektura vytvoří instanci vaší instance.widget configuration
- Vlastnost
onSave
kontraktuIWidgetConfiguration
by měla mít funkci jako její hodnotu. Tato funkce se volá podle architektury, když uživatel vybere Možnost Uložit v podokně konfigurace. Pokud je uživatelský vstup připravený k uložení, serializujte ho do řetězce, vytvořtecustom settings
objekt a použijteWidgetConfigurationSave.Valid()
k uložení vstupu uživatele.
V této příručce použijeme JSON k serializaci vstupu uživatele do řetězce. Můžete zvolit jakýkoli jiný způsob serializace uživatelského vstupu do řetězce.
Widget je přístupný prostřednictvím vlastnosti customSettings objektu WidgetSettings
.
Widget musí deserializovat, což je popsáno v kroku 4.
Krok 3: JavaScript – povolení živého náhledu
Pokud chcete povolit aktualizaci živého náhledu, když uživatel vybere dotaz z rozevíracího seznamu, připojíme k tlačítku obslužnou rutinu události změny. Tato obslužná rutina upozorní architekturu, že se konfigurace změnila.
Také předá customSettings
, aby se použila k aktualizaci verze Preview. Aby bylo možné architekturu upozornit, notify
je potřeba volat metodu widgetConfigurationContext
. Přebírá dva parametry, název události, což je WidgetHelpers.WidgetEvent.ConfigurationChange
v tomto případě a EventArgs
objekt pro událost vytvořený z customSettings
pomocné WidgetEvent.Args
metody.
Do funkce přiřazené k load
vlastnosti přidejte následující kód.
$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);
});
Revidované: Ujistěte se, že architektura bude upozorněna na změnu konfigurace aspoň jednou, aby se povolilo tlačítko Uložit .
Na konci vypadá váš configuration.html
příklad jako v následujícím příkladu:
<!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>
Krok 4: Implementace opětovného načtení do widgetu – JavaScript
Nastavili jsme konfiguraci widgetu pro uložení cesty dotazu vybrané uživatelem.
Teď musíme aktualizovat kód ve widgetu tak, aby místo pevně zakódované Shared Queries/Feedback
konfigurace používal tuto uloženou konfiguraci z předchozího příkladu.
Otevřete soubor hello-world3.html
a aktualizujte název widgetu z HelloWorldWidget2
řádku HelloWorldWidget3
, kam voláte VSS.register
.
Tato akce umožňuje rozhraní jednoznačně identifikovat widget v rámci rozšíření.
Funkce namapovaná na HelloWorldWidget3
prostřednictvím VSS.register
aktuálně vrací objekt, který splňuje IWidget
kontrakt.
Vzhledem k tomu, že náš widget teď potřebuje konfiguraci, musí být tato funkce aktualizována, aby vrátila objekt, který splňuje IConfigurableWidget
kontrakt.
Chcete-li to provést, aktualizujte návratový příkaz tak, aby zahrnoval vlastnost s názvem znovu načíst podle následujícího kódu. Hodnota této vlastnosti je funkce, která volá metodu getQueryInfo
ještě jednou.
Tato metoda opětovného načtení se volá podle architektury pokaždé, když se uživatelský vstup změní tak, aby zobrazoval dynamický náhled. Tato metoda opětovného načtení se také volá při uložení konfigurace.
return {
load: function (widgetSettings) {
// Set your title
var $title = $('h2.title');
$title.text('Hello World');
return getQueryInfo(widgetSettings);
},
reload: function (widgetSettings) {
return getQueryInfo(widgetSettings);
}
}
Pevně zakódovaná cesta getQueryInfo
dotazu by měla být nahrazena nakonfigurovanou cestou dotazu, která se dá extrahovat z parametru widgetSettings
předávaného metodě.
Na začátek getQueryInfo
metody přidejte následující kód a nahraďte pevně zakódovanou cestu settings.queryPath
dotazu .
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();
}
V tuto chvíli je widget připravený k vykreslení s nakonfigurovaným nastavením.
Obě load
reload
vlastnosti mají podobnou funkci. Toto je případ pro většinu jednoduchých widgetů.
U složitých widgetů by existovaly určité operace, které byste chtěli spustit jen jednou bez ohledu na to, kolikrát se konfigurace změní.
Nebo může existovat několik náročných operací, které nemusí běžet více než jednou. Takové operace by byly součástí funkce odpovídající load
vlastnosti, nikoli vlastnosti reload
.
Krok 5: Aktualizace manifestu rozšíření
Otevřete soubor, vss-extension.json
který bude obsahovat dvě nové položky do pole ve contributions
vlastnosti. Jeden pro HelloWorldWidget3
widget a druhý pro jeho konfiguraci.
Pro třetí widget potřebujete ještě další obrázek náhledu. preview3.png
Pojmenujte ho a umístěte ho do img
složky.
Aktualizujte pole ve files
vlastnosti tak, aby zahrnovalo dva nové soubory HTML, které jsme přidali v tomto příkladu.
{
...
"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
}
],
...
}
Příspěvek pro konfiguraci widgetu se řídí trochu jiným modelem než samotný widget. Položka příspěvku pro konfiguraci widgetu obsahuje:
- ID pro identifikaci vašeho příspěvku ID by mělo být jedinečné v rámci rozšíření.
- Typ příspěvku. U všech konfigurací widgetů by měla být
ms.vss-dashboards-web.widget-configuration
- Pole cílů , ke kterým přispívá příspěvek. Pro všechny konfigurace widgetu má jednu položku:
ms.vss-dashboards-web.widget-configuration
. - Vlastnosti obsahující sadu vlastností, které obsahují název, popis a identifikátor URI souboru HTML použitého pro konfiguraci.
Aby bylo možné podporovat konfiguraci, je potřeba také změnit příspěvek widgetu. Pole cílů widgetu musí být aktualizováno tak, aby zahrnovalo ID konfigurace ve formuláři <publisher
>.>id for the extension
<.<id for the configuration contribution
> V tomto případě je fabrikam.vsts-extensions-myExtensions.HelloWorldWidget.Configuration
to .
Upozorňující
Pokud položka příspěvku pro konfigurovatelný widget nebude cílit na konfiguraci pomocí správného vydavatele a názvu rozšíření, jak je popsáno výše, tlačítko konfigurace se pro widget nezobrazí.
Na konci této části by soubor manifestu měl obsahovat tři widgety a jednu konfiguraci. Tady můžete získat úplný manifest z ukázky.
Krok 6: Balení, publikování a sdílení
Pokud vaše rozšíření není publikované, přečtěte si tuto část. Pokud jste rozšíření už publikovali, můžete rozšíření znovu zabalit a přímo ho aktualizovat na Marketplace.
Krok 7: Přidání widgetu z katalogu
Teď přejděte na řídicí panel týmu na adrese https://dev.azure.com/{Your_Organization}/{Your_Project}. Pokud je tato stránka už otevřená, aktualizujte ji. Najetím myší na Upravit a vyberte Přidat. Tato akce by měla otevřít katalog widgetů, kde najdete widget, který jste nainstalovali. Pokud chcete widget přidat na řídicí panel, zvolte widget a vyberte Přidat.
Zpráva podobná následující po vás požádá o konfiguraci widgetu.
Existují dva způsoby konfigurace widgetů. Jedním z nich je najetí myší na widget, vybrat tři tečky, které se zobrazí v pravém horním rohu, a pak vyberte Konfigurovat. Druhým je vybrat tlačítko Upravit v pravém dolním rohu řídicího panelu a pak vybrat tlačítko konfigurovat, které se zobrazí v pravém horním rohu widgetu. Na pravé straně se otevře prostředí konfigurace a uprostřed se zobrazí náhled widgetu. Pokračujte a v rozevíracím seznamu zvolte dotaz. V živém náhledu se zobrazují aktualizované výsledky. Vyberte Uložit a widget zobrazí aktualizované výsledky.
Krok 8: Konfigurace dalších (volitelné)
Do další konfigurace můžete přidat tolik elementů formuláře HTML, kolik potřebujete configuration.html
.
K dispozici jsou dvě konfigurovatelné funkce: název widgetu a velikost widgetu.
Ve výchozím nastavení se název, který zadáte pro widget v manifestu rozšíření, uloží jako název widgetu pro každou instanci widgetu, která se někdy přidá na řídicí panel.
Uživatelům můžete povolit konfiguraci, aby mohli do své instance widgetu přidat libovolný název.
Pokud chcete takovou konfiguraci povolit, přidejte isNameConfigurable:true
do oddílu vlastností widgetu v manifestu rozšíření.
Pokud do pole v manifestu supportedSizes
rozšíření zadáte více než jednu položku widgetu, můžou uživatelé také nakonfigurovat velikost widgetu.
Manifest rozšíření třetí ukázky v této příručce by vypadal jako v následujícím příkladu, pokud povolíme konfiguraci názvu a velikosti widgetu:
{
...
"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"]
}
},
...
]
}
S předchozí změnou znovu zabalte a aktualizujte rozšíření. Aktualizujte řídicí panel s tímto widgetem (Hello World Widget 3 (s konfigurací)). Otevřete režim konfigurace widgetu. Teď byste měli být schopni zobrazit možnost změnit název a velikost widgetu.
V rozevíracím seznamu vyberte jinou velikost. Zobrazí se změna velikosti živého náhledu. Uložte změnu a widget na řídicím panelu se změní také.
Změna názvu widgetu nemá za následek žádnou viditelnou změnu widgetu, protože naše ukázkové widgety nikde nezobrazují název widgetu. Upravme vzorový kód tak, aby zobrazoval název widgetu místo pevně zakódovaného textu "Hello World".
Uděláte to tak, že nahradíte pevně zakódovaný text "Hello World" widgetSettings.name
na řádku, na kterém nastavíme text h2
prvku.
Tato akce zajistí, že se název widgetu zobrazí při každém načtení widgetu při aktualizaci stránky.
Vzhledem k tomu, že chceme, aby se živá verze Preview aktualizovala při každé změně konfigurace, měli bychom do části našeho kódu také přidat stejný kód reload
.
Poslední návratový příkaz hello-world3.html
je následující:
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);
}
}
Znovu zabalte a aktualizujte rozšíření znovu. Aktualizujte řídicí panel s tímto widgetem.
Všechny změny názvu widgetu v režimu konfigurace teď aktualizují název widgetu.