Menambahkan widget dasbor

Layanan Azure DevOps | Azure DevOps Server 2022 - Azure DevOps Server 2019

Widget di dasbor diimplementasikan sebagai kontribusi dalam kerangka kerja ekstensi. Satu ekstensi dapat memiliki beberapa kontribusi. Pelajari cara membuat ekstensi dengan beberapa widget sebagai kontribusi.

Artikel ini dibagi menjadi tiga bagian, masing-masing bangunan pada sebelumnya - dimulai dengan widget sederhana dan diakhir dengan widget komprehensif.

Tip

Lihat dokumentasi terbaru kami tentang pengembangan ekstensi menggunakan Azure DevOps Extension SDK.

Persiapan dan penyiapan yang diperlukan untuk tutorial ini

Untuk membuat ekstensi untuk Azure DevOps atau TFS, ada beberapa perangkat lunak dan alat prasyarat yang Anda perlukan:

Pengetahuan: Beberapa pengetahuan tentang JavaScript, HTML, CSS diperlukan untuk pengembangan widget.

  • Organisasi di Azure DevOps untuk menginstal dan menguji widget Anda, informasi selengkapnya dapat ditemukan di sini
  • Editor teks. Untuk banyak tutorial, kami menggunakan Visual Studio Code, yang dapat diunduh di sini
  • Versi node terbaru, yang dapat diunduh di sini
  • CLI lintas platform untuk Azure DevOps (tfx-cli) untuk mengemas ekstensi Anda.
    • tfx-cli dapat diinstal menggunakan npm, komponen Node.js dengan menjalankan npm i -g tfx-cli
  • Direktori rumah untuk proyek Anda. Direktori ini disebut sebagai home sepanjang tutorial.

Struktur file ekstensi:

|--- 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

Apa yang akan Anda temukan dalam tutorial

  1. Bagian pertama dari panduan ini menunjukkan kepada Anda cara membuat widget baru, yang mencetak pesan "Halo Dunia" sederhana.
  2. Bagian kedua dibangun pada bagian pertama dengan menambahkan panggilan ke REST API Azure DevOps.
  3. Bagian ketiga menjelaskan cara menambahkan konfigurasi ke widget Anda.

Catatan

Jika Anda terburu-buru dan ingin segera mendapatkan kode, Anda dapat mengunduh sampel di sini. Setelah diunduh, buka widgets folder, lalu ikuti Langkah 6 dan Langkah 7 secara langsung untuk menerbitkan ekstensi sampel yang memiliki tiga widget sampel dari berbagai kompleksitas.

Mulailah dengan beberapa gaya dasar untuk widget yang kami sediakan di luar kotak untuk Anda dan beberapa panduan tentang struktur widget.

Bagian 1: Halo Dunia

Bagian ini menyajikan widget yang mencetak "Halo Dunia" menggunakan JavaScript.

Overview dashboard with a sample widget

Langkah 1: Dapatkan SDK klien - VSS.SDK.min.js

Skrip SDK inti, VSS.SDK.min.js, memungkinkan ekstensi web untuk berkomunikasi ke bingkai Azure DevOps host. Skrip melakukan operasi seperti menginisialisasi, memberi tahu ekstensi dimuat, atau mendapatkan konteks tentang halaman saat ini. Dapatkan file SDK VSS.SDK.min.js Klien dan tambahkan ke aplikasi web Anda. Tempatkan di home/sdk/scripts folder .

Gunakan perintah 'npm install' untuk mengambil SDK:

npm install vss-web-extension-sdk

Untuk mempelajari lebih lanjut tentang SDK, kunjungi Halaman GitHub SDK Klien.

Langkah 2: Halaman HTML Anda - hello-world.html

Halaman HTML Anda adalah lem yang menyimpan tata letak Anda bersama-sama dan menyertakan referensi ke CSS dan JavaScript. Anda dapat memberi nama file ini apa pun, pastikan untuk memperbarui semua referensi dengan hello-world nama yang Anda gunakan.

Widget Anda berbasis HTML dan dihosting dalam iframe. Tambahkan HTML di bawah ini di hello-world.html. Kami menambahkan referensi wajib ke VSS.SDK.min.js file dan menyertakan h2 elemen dalam , yang diperbarui dengan string Halo Dunia pada langkah mendatang.

    <!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>

Meskipun kita menggunakan file HTML, sebagian besar elemen kepala HTML selain skrip dan tautan diabaikan oleh kerangka kerja.

Langkah 3: JavaScript Anda

Kami menggunakan JavaScript untuk merender konten di widget. Dalam artikel ini, kami membungkus semua kode JavaScript kami di dalam &lt;script&gt; elemen dalam file HTML. Anda dapat memilih untuk memiliki kode ini dalam file JavaScript terpisah dan merujuknya dalam file HTML. Kode merender konten. Kode JavaScript ini juga menginisialisasi VSS SDK, memetakan kode untuk widget Anda ke nama widget Anda, dan memberi tahu kerangka kerja ekstensi keberhasilan atau kegagalan widget. Dalam kasus kami, di bawah ini adalah kode yang akan mencetak "Halo Dunia" di widget. Tambahkan elemen ini script di 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 menginisialisasi jabat tangan antara iframe yang menghosting widget dan bingkai host. Kami meneruskan explicitNotifyLoaded: true sehingga widget dapat secara eksplisit memberi tahu host ketika kami selesai memuat. Kontrol ini memungkinkan kami untuk memberi tahu penyelesaian beban setelah memastikan bahwa modul dependen dimuat. Kami meneruskan usePlatformStyles: true sehingga gaya inti Azure DevOps untuk elemen html (seperti isi, div, dan sebagainya) dapat digunakan oleh Widget. Jika widget lebih suka tidak menggunakan gaya ini, mereka dapat meneruskan usePlatformStyles: false.

VSS.require digunakan untuk memuat pustaka skrip VSS yang diperlukan. Panggilan ke metode ini secara otomatis memuat pustaka umum seperti JQuery dan JQueryUI. Dalam kasus kami, kami bergantung pada pustaka WidgetHelpers, yang digunakan untuk mengkomunikasikan status widget ke kerangka kerja widget. Jadi, kami meneruskan nama TFS/Dashboards/WidgetHelpers modul yang sesuai dan panggilan balik ke VSS.require. Panggilan balik dipanggil setelah modul dimuat. Panggilan balik memiliki sisa kode JavaScript yang diperlukan untuk widget. Di akhir panggilan balik, kami memanggil VSS.notifyLoadSucceeded untuk memberi tahu penyelesaian beban.

WidgetHelpers.IncludeWidgetStyles termasuk lembar gaya dengan beberapa css dasar untuk memulai. Pastikan untuk membungkus konten Anda di dalam elemen HTML dengan kelas widget untuk menggunakan gaya ini.

VSS.register digunakan untuk memetakan fungsi di JavaScript, yang secara unik mengidentifikasi widget di antara berbagai kontribusi dalam ekstensi Anda. Nama harus cocok dengan id yang mengidentifikasi kontribusi Anda seperti yang dijelaskan di Langkah 5. Untuk widget, fungsi yang diteruskan harus VSS.register mengembalikan objek yang memenuhi IWidget kontrak, misalnya, objek yang dikembalikan harus memiliki properti beban yang nilainya adalah fungsi lain yang memiliki logika inti untuk merender widget. Dalam kasus kami, ini untuk memperbarui teks h2 elemen ke "Halo Dunia". Fungsi inilah yang dipanggil ketika kerangka kerja widget membuat instans widget Anda. Kami menggunakan WidgetStatusHelper dari WidgetHelpers untuk mengembalikan sebagai sukses WidgetStatus .

Peringatan

Jika nama yang digunakan untuk mendaftarkan widget tidak cocok dengan ID untuk kontribusi dalam manifes, maka widget berfungsi secara tidak terduga.

vss-extension.json harus selalu berada di akar folder (dalam panduan ini, HelloWorld). Untuk semua file lainnya, Anda dapat menempatkannya dalam struktur apa pun yang Anda inginkan di dalam folder, cukup pastikan untuk memperbarui referensi dengan tepat dalam file HTML dan dalam vss-extension.json manifes.

Langkah 4: Logo ekstensi Anda: logo.png

Logo Anda ditampilkan di Marketplace, dan di katalog widget setelah pengguna menginstal ekstensi Anda.

Anda memerlukan ikon katalog 98 px x 98 px. Pilih gambar, beri nama logo.png, dan letakkan img di folder .

Untuk mendukung TFS 2015 Update 3, Anda memerlukan gambar tambahan yaitu 330 px x 160 px. Gambar pratinjau ini ditampilkan dalam katalog ini. Pilih gambar, beri nama preview.png, dan letakkan img di folder seperti sebelumnya.

Anda dapat memberi nama gambar ini sesampainya selama manifes ekstensi di langkah berikutnya diperbarui dengan nama yang Anda gunakan.

Langkah 5: Manifes ekstensi Anda: vss-extension.json

Buat file json (vss-extension.json, misalnya) di home direktori dengan konten berikut:

    {
        "manifestVersion": 1,
        "id": "vsts-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
            }
        ]
    }

Untuk informasi selengkapnya tentang atribut yang diperlukan, lihat Referensi manifes ekstensi

Catatan

Penerbit di sini perlu diubah ke nama penerbit Anda. Untuk membuat penerbit sekarang, kunjungi Paket/Terbitkan/Instal.

Ikon

Ikon stanza menentukan jalur ke ikon ekstensi Anda dalam manifes Anda.

Kontribusi

Setiap entri kontribusi mendefinisikan properti.

  • ID untuk mengidentifikasi kontribusi Anda. ID ini harus unik dalam ekstensi. ID ini harus cocok dengan nama yang Anda gunakan di Langkah 3 untuk mendaftarkan widget Anda.
  • Jenis kontribusi. Untuk semua widget, jenisnya harus ms.vss-dashboards-web.widget.
  • Array target tempat kontribusi berkontribusi. Untuk semua widget, targetnya harus [ms.vss-dashboards-web.widget-catalog].
  • Properti adalah objek yang menyertakan properti untuk jenis kontribusi. Untuk widget, properti berikut wajib.
Properti Deskripsi
nama Nama widget yang akan ditampilkan di katalog widget.
description Deskripsi widget untuk ditampilkan di katalog widget.
catalogIconUrl Jalur relatif ikon katalog yang Anda tambahkan di Langkah 4 untuk ditampilkan di katalog widget. Gambar harus 98 px x 98 px. Jika Anda telah menggunakan struktur folder yang berbeda atau nama file yang berbeda, tentukan jalur relatif yang sesuai di sini.
previewImageUrl Jalur relatif gambar pratinjau yang Anda tambahkan di Langkah 4 untuk ditampilkan di katalog widget hanya untuk TFS 2015 Update 3. Gambar harus 330 px x 160 px. Jika Anda telah menggunakan struktur folder yang berbeda atau nama file yang berbeda, tentukan jalur relatif yang sesuai di sini.
uri Jalur relatif file HTML yang Anda tambahkan di Langkah 1. Jika Anda telah menggunakan struktur folder yang berbeda atau nama file yang berbeda, tentukan jalur relatif yang sesuai di sini.
supportedSizes Array ukuran yang didukung oleh widget Anda. Saat widget mendukung beberapa ukuran, ukuran pertama dalam array adalah ukuran default widget. widget size ditentukan untuk baris dan kolom yang ditempati oleh widget di kisi dasbor. Satu baris/kolom sesuai dengan 160 px. Dimensi apa pun di atas 1x1 mendapatkan tambahan 10 px yang mewakili selokan di antara widget. Misalnya, widget 160*3+10*2 3x2 lebar dan 160*2+10*1 tinggi. Ukuran maksimum yang didukung adalah 4x4.
cakupan yang didukung Saat ini, kami hanya mendukung dasbor tim. Nilainya harus project_team. Di masa mendatang, ketika kami mendukung cakupan dasbor lain, akan ada lebih banyak opsi untuk dipilih dari sini.

File

Stanza file menyatakan file yang ingin Anda sertakan dalam paket Anda - halaman HTML Anda, skrip Anda, skrip SDK, dan logo Anda. Atur addressable ke true kecuali Anda menyertakan file lain yang tidak perlu dapat diatasi URL.

Catatan

Untuk informasi selengkapnya tentang file manifes ekstensi, seperti propertinya dan apa yang mereka lakukan, lihat referensi manifes ekstensi.

Langkah 6: Mengemas, menerbitkan, dan berbagi

Setelah Anda menulis ekstensi, langkah selanjutnya untuk memasukkannya ke Marketplace adalah mengemas semua file Anda bersama-sama. Semua ekstensi dimas sebagai file .vsix yang kompatibel dengan VSIX 2.0 - Microsoft menyediakan antarmuka baris perintah lintas platform (CLI) untuk mengemas ekstensi Anda.

Mendapatkan alat pengemasan

Anda dapat menginstal atau memperbarui CLI Lintas platform untuk Azure DevOps (tfx-cli) menggunakan npm, komponen Node.js, dari baris perintah Anda.

npm i -g tfx-cli

Mengemas ekstensi Anda

Mengemas ekstensi Anda ke dalam file .vsix mudah setelah Anda memiliki tfx-cli. Buka direktori beranda ekstensi Anda dan jalankan perintah berikut.

tfx extension create --manifest-globs vss-extension.json

Catatan

Versi ekstensi/integrasi harus ditahapkan pada setiap pembaruan.
Saat memperbarui ekstensi yang ada, perbarui versi dalam manifes atau lewati --rev-version sakelar baris perintah. Ini akan menaikkan nomor versi patch ekstensi Anda dan menyimpan versi baru ke manifes Anda.

Setelah Anda memiliki ekstensi paket dalam file .vsix, Anda siap untuk menerbitkan ekstensi Anda ke Marketplace.

Membuat penerbit untuk ekstensi

Semua ekstensi, termasuk ekstensi dari Microsoft, diidentifikasi sebagai disediakan oleh penerbit. Jika Anda belum menjadi anggota penerbit yang sudah ada, Anda akan membuatnya.

  1. Masuk ke Portal Penerbitan Marketplace Visual Studio
  2. Jika Anda belum menjadi anggota penerbit yang sudah ada, Anda akan diminta untuk membuat penerbit. Jika Anda tidak diminta untuk membuat penerbit, gulir ke bawah ke bagian bawah halaman dan pilih Terbitkan Ekstensi di bawah Situs Terkait.
    • Tentukan pengidentifikasi untuk penerbit Anda, misalnya: mycompany-myteam
      • Pengidentifikasi digunakan sebagai nilai untuk publisher atribut dalam file manifes ekstensi Anda.
    • Tentukan nama tampilan untuk penerbit Anda, misalnya: My Team
  3. Tinjau Perjanjian Penerbit Marketplace dan pilih Buat

Sekarang penerbit Anda ditentukan. Dalam rilis mendatang, Anda dapat memberikan izin untuk melihat dan mengelola ekstensi penerbit Anda. Mudah dan lebih aman bagi tim dan organisasi untuk menerbitkan ekstensi di bawah penerbit umum, tetapi tanpa perlu berbagi serangkaian kredensial di sekumpulan pengguna.

vss-extension.json Perbarui file manifes dalam sampel untuk mengganti ID fabrikam penerbit dummy dengan ID penerbit Anda.

Menerbitkan dan berbagi ekstensi

Setelah membuat penerbit, Anda sekarang dapat mengunggah ekstensi Anda ke Marketplace.

  1. Temukan tombol Unggah ekstensi baru, navigasikan ke file .vsix paket Anda, dan pilih unggah.

Anda juga dapat mengunggah ekstensi melalui baris perintah dengan menggunakan tfx extension publish perintah alih-alih tfx extension create mengemas dan menerbitkan ekstensi Anda dalam satu langkah. Anda dapat secara opsional menggunakan --share-with untuk berbagi ekstensi Anda dengan satu atau beberapa akun setelah penerbitan. Anda juga memerlukan token akses pribadi.

tfx extension publish --manifest-globs your-manifest.json --share-with yourOrganization

Langkah 7: Tambahkan widget dari katalog

  1. Buka proyek Anda di Azure DevOps, http://dev.azure.com/{yourOrganization}/{yourProject}

  2. Pilih Gambaran Umum, lalu pilih Dasbor.

  3. Pilih Tambahkan widget.

  4. Sorot widget Anda, lalu pilih Tambahkan.

    Widget muncul di dasbor Anda.

Bagian 2: Halo Dunia dengan REST API Azure DevOps

Widget dapat memanggil salah satu REST API di Azure DevOps untuk berinteraksi dengan sumber daya Azure DevOps. Dalam contoh ini, kami menggunakan REST API untuk WorkItemTracking untuk mengambil informasi tentang kueri yang ada dan menampilkan beberapa info kueri di widget tepat di bawah teks "Halo Dunia".

Overview dashboard with a sample widget using the REST API for WorkItemTracking.

Langkah 1: HTML

Salin file hello-world.html dari contoh sebelumnya, dan ganti nama salinan menjadi hello-world2.html. Folder Anda sekarang terlihat seperti di bawah ini:

|--- 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  
|--- hello-world2.html              // renamed copy of hello-world.html
|--- vss-extension.json             // extension's manifest

Tambahkan elemen 'div' baru tepat di bawah 'h2' untuk menyimpan informasi kueri. Perbarui nama widget dari 'HelloWorldWidget' ke 'HelloWorldWidget2' di baris tempat Anda memanggil 'VSS.register'. Ini memungkinkan kerangka kerja untuk mengidentifikasi widget secara unik dalam ekstensi.
<!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>

Langkah 2: Mengakses sumber daya Azure DevOps

Untuk mengaktifkan akses ke sumber daya Azure DevOps, cakupan perlu ditentukan dalam manifes ekstensi. Kami menambahkan cakupan ke vso.work manifes kami.
Cakupan ini menunjukkan widget memerlukan akses baca-saja ke kueri dan item kerja. Lihat semua cakupan yang tersedia di sini. Tambahkan di bawah ini di akhir manifes ekstensi Anda.

{
    ...,
    "scopes":[
        "vso.work"
    ]
}

Peringatan

Menambahkan atau mengubah cakupan setelah menerbitkan ekstensi saat ini tidak didukung. Jika Anda telah mengunggah ekstensi, hapus ekstensi dari Marketplace. Visual Studio Marketplace Publishing PortalBuka , klik kanan ekstensi Anda dan pilih "Hapus".

Langkah 3: Lakukan Panggilan REST API

Ada banyak pustaka sisi klien yang dapat diakses melalui SDK untuk melakukan panggilan REST API di Azure DevOps. Pustaka ini disebut klien REST dan merupakan pembungkus JavaScript di sekitar panggilan Ajax untuk semua titik akhir sisi server yang tersedia. Anda dapat menggunakan metode yang disediakan oleh klien ini alih-alih menulis panggilan Ajax sendiri. Metode ini memetakan respons API ke objek yang dapat digunakan oleh kode Anda.

Dalam langkah ini, kami memperbarui VSS.require panggilan untuk memuat TFS/WorkItemTracking/RestClient, yang menyediakan klien WORKItemTracking REST. Kita dapat menggunakan klien REST ini untuk mendapatkan informasi tentang kueri yang disebut Feedback di bawah folder Shared Queries.

Di dalam fungsi yang kita teruskan ke VSS.register, kita membuat variabel untuk menahan ID proyek saat ini. Kita perlu variabel ini untuk mengambil kueri. Kami juga membuat metode getQueryInfo baru untuk menggunakan klien REST. Metode ini yang kemudian dipanggil dari metode pemuatan.

Metode getClient ini memberikan instans klien REST yang kita butuhkan. Metode getQuery mengembalikan kueri yang dibungkus dalam janji. Tampilan yang diperbarui VSS.require adalah sebagai berikut:

VSS.require(["TFS/Dashboards/WidgetHelpers", "TFS/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();
    });

Perhatikan penggunaan metode Kegagalan dari WidgetStatusHelper. Ini memungkinkan Anda untuk menunjukkan kepada kerangka kerja widget bahwa kesalahan telah terjadi dan memanfaatkan pengalaman kesalahan standar yang disediakan untuk semua widget.

Jika Anda tidak memiliki Feedback kueri di bawah Shared Queries folder, ganti Shared Queries\Feedback dalam kode dengan jalur kueri yang ada di proyek Anda.

Langkah 4: Menampilkan Respons

Langkah terakhir adalah merender informasi kueri di dalam widget. Fungsi mengembalikan getQuery objek jenis Contracts.QueryHierarchyItem di dalam janji. Dalam contoh ini, kami menampilkan ID kueri, nama kueri, dan nama pembuat kueri di bawah teks "Halo Dunia". // Do something with the query Ganti komentar dengan yang di bawah ini:

    // Create a list with query details                                
    var $list = $('<ul>');                                
    $list.append($('- ').text("Query Id: " + query.id));
    $list.append($('- ').text("Query Name: " + query.name));
    $list.append($('- ').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);

Final hello-world2.html Anda adalah sebagai berikut:

<!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", "TFS/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($('- ').text("Query ID: " + query.id));
                                $list.append($('- ').text("Query Name: " + query.name));
                                $list.append($('- ').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>

Langkah 5: Pembaruan Manifes Ekstensi

Dalam langkah ini, kami memperbarui manifes ekstensi untuk menyertakan entri untuk widget kedua kami. Tambahkan kontribusi baru ke array di contributions properti dan tambahkan file hello-world2.html baru ke array di properti file. Anda memerlukan gambar pratinjau lain untuk widget kedua. Beri nama ini preview2.png dan letakkan img di folder .

 {
     ...,
     "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"
     ]
 }

Langkah 6: Paket, Terbitkan, dan Bagikan

Paket, terbitkan, dan bagikan ekstensi Anda. Jika Anda telah menerbitkan ekstensi, Anda dapat mengemas ulang ekstensi dan langsung memperbaruinya ke Marketplace.

Langkah 7: Tambahkan Widget Dari Katalog

Sekarang, buka dasbor tim Anda di https:\//dev.azure.com/{yourOrganization}/{yourProject}. Jika halaman ini sudah terbuka, maka refresh. Arahkan mouse ke tombol Edit di kanan bawah, dan pilih tombol Tambahkan. Katalog widget terbuka di mana Anda menemukan widget yang Anda instal. Pilih widget Anda dan pilih tombol 'Tambahkan' untuk menambahkannya ke dasbor Anda.

Bagian 3: Halo Dunia dengan Konfigurasi

Di Bagian 2 panduan ini, Anda melihat cara membuat widget yang menampilkan informasi kueri untuk kueri yang dikodekan secara permanen. Di bagian ini, kami menambahkan kemampuan untuk mengonfigurasi kueri yang akan digunakan alih-alih yang dikodekan secara permanen. Saat dalam mode konfigurasi, pengguna akan melihat pratinjau langsung widget berdasarkan perubahannya. Perubahan ini disimpan ke widget di dasbor saat pengguna memilih Simpan.

Overview dashboard live preview of the widget based on changes.

Langkah 1: HTML

Implementasi Widget dan Konfigurasi Widget sangat mirip. Keduanya diimplementasikan dalam kerangka kerja ekstensi sebagai kontribusi. Keduanya menggunakan file SDK yang sama, VSS.SDK.min.js. Keduanya didasarkan pada HTML, JavaScript, dan CSS.

Salin file html-world2.html dari contoh sebelumnya dan ganti nama salinan menjadi hello-world3.html. Tambahkan file HTML lain yang disebut configuration.html. Folder Anda sekarang terlihat seperti contoh berikut:

|--- 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

Tambahkan HTML di bawah ini di 'configuration.html'. Kami pada dasarnya menambahkan referensi wajib ke 'VSS. File SDK.min.js' dan elemen 'pilih' untuk dropdown untuk memilih kueri dari daftar prasetel.
    <!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>

Langkah 2: JavaScript - Konfigurasi

Gunakan JavaScript untuk merender konten dalam konfigurasi widget seperti yang kami lakukan untuk widget di Langkah 3 Bagian 1 dalam panduan ini. Kode JavaScript ini merender konten, menginisialisasi VSS SDK, memetakan kode untuk konfigurasi widget Anda ke nama konfigurasi, dan meneruskan pengaturan konfigurasi ke kerangka kerja. Dalam kasus kami, di bawah ini adalah kode yang memuat konfigurasi widget. Buka file configuration.html dan elemen di bawah ini <script> ke <head>.

    <script type="text/javascript">
        VSS.init({                        
            explicitNotifyLoaded: true,
            usePlatformStyles: true
        });

        VSS.require("TFS/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.requiredan VSS.register memainkan peran yang sama seperti yang mereka mainkan untuk widget seperti yang dijelaskan di Bagian 1. Satu-satunya perbedaan adalah bahwa untuk konfigurasi widget, fungsi yang diteruskan ke VSS.register harus mengembalikan objek yang memenuhi IWidgetConfiguration kontrak.

Properti loadIWidgetConfiguration kontrak harus memiliki fungsi sebagai nilainya. Fungsi ini memiliki serangkaian langkah untuk merender konfigurasi widget. Dalam kasus kami, ini untuk memperbarui nilai yang dipilih dari elemen dropdown dengan pengaturan yang ada jika ada. Fungsi ini dipanggil ketika kerangka kerja membuat instans widget configuration

Properti onSaveIWidgetConfiguration kontrak harus memiliki fungsi sebagai nilainya. Fungsi ini dipanggil oleh kerangka kerja saat pengguna memilih Simpan di panel konfigurasi. Jika input pengguna siap disimpan, maka serialisasikan ke string, bentuk custom settings objek dan gunakan WidgetConfigurationSave.Valid() untuk menyimpan input pengguna.

Dalam panduan ini, kami menggunakan JSON untuk membuat serial input pengguna ke dalam string. Anda dapat memilih cara lain untuk membuat serialisasi input pengguna ke string. Ini dapat diakses oleh widget melalui properti WidgetSettings kustom Pengaturan objek. Widget harus mendeserialisasi ini, yang tercakup dalam Langkah 4.

Langkah 3: JavaScript - Aktifkan Pratinjau Langsung

Untuk mengaktifkan pembaruan pratinjau langsung saat pengguna memilih kueri dari dropdown, kami melampirkan penanganan aktivitas perubahan ke tombol . Handler ini memberi tahu kerangka kerja bahwa konfigurasi telah berubah. Ini juga meneruskan yang customSettings akan digunakan untuk memperbarui pratinjau. Untuk memberi tahu kerangka kerja, notify metode pada perlu dipanggil widgetConfigurationContext . Dibutuhkan dua parameter, nama peristiwa, yang dalam hal ini adalah WidgetHelpers.WidgetEvent.ConfigurationChange, dan EventArgs objek untuk peristiwa, dibuat dari customSettings dengan bantuan metode pembantu WidgetEvent.Args .

Tambahkan di bawah ini dalam fungsi yang ditetapkan ke load properti .

 $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);
 });

Anda perlu memberi tahu kerangka kerja perubahan konfigurasi setidaknya sekali sehingga tombol "Simpan" dapat diaktifkan.

Pada akhirnya, Anda configuration.html terlihat seperti ini:

    <!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("TFS/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>

Langkah 4: JavaScript - Terapkan muat ulang di widget

Kami telah menyiapkan konfigurasi widget untuk menyimpan jalur kueri yang dipilih oleh pengguna. Kita sekarang harus memperbarui kode di widget untuk menggunakan konfigurasi tersimpan ini alih-alih dikodekan Shared Queries/Feedback secara permanen dari contoh sebelumnya.

Buka file hello-world3.html dan perbarui nama widget dari HelloWorldWidget2 ke HelloWorldWidget3 di baris tempat Anda memanggil VSS.register. Ini memungkinkan kerangka kerja untuk mengidentifikasi widget secara unik dalam ekstensi.

Fungsi yang dipetakan melalui HelloWorldWidget3VSS.register saat ini mengembalikan objek yang memenuhi IWidget kontrak. Karena widget kami sekarang membutuhkan konfigurasi, fungsi ini perlu diperbarui untuk mengembalikan objek yang memenuhi IConfigurableWidget kontrak. Untuk melakukan ini, perbarui pernyataan pengembalian untuk menyertakan properti yang disebut muat ulang seperti di bawah ini. Nilai untuk properti ini adalah fungsi yang memanggil getQueryInfo metode sekali lagi. Metode muat ulang ini dipanggil oleh kerangka kerja setiap kali input pengguna berubah untuk menampilkan pratinjau langsung. Ini juga dipanggil ketika konfigurasi disimpan.

return {
    load: function (widgetSettings) {
        // Set your title
        var $title = $('h2.title');
        $title.text('Hello World');

        return getQueryInfo(widgetSettings);
    },
    reload: function (widgetSettings) {
        return getQueryInfo(widgetSettings);
    }
}

Jalur kueri yang dikodekan secara permanen di 'getQueryInfo' harus diganti dengan jalur kueri yang dikonfigurasi, yang dapat diekstrak dari parameter 'widget Pengaturan' yang diteruskan ke metode . Tambahkan di bawah ini di awal metode 'getQueryInfo' dan ganti querypath yang dikodekan secara permanen dengan '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();
}

Pada titik ini, widget Anda siap untuk dirender dengan pengaturan yang dikonfigurasi.

load Properti dan reload memiliki fungsi yang sama. Ini adalah kasus untuk widget yang paling sederhana. Untuk widget yang kompleks, akan ada operasi tertentu yang ingin Anda jalankan hanya sekali tidak peduli berapa kali konfigurasi berubah. Atau mungkin ada beberapa operasi berat yang tidak perlu berjalan lebih dari sekali. Operasi tersebut akan menjadi bagian dari fungsi yang sesuai dengan load properti dan bukan reload properti .

Langkah 5: Pembaruan Manifes Ekstensi

vss-extension.json Buka file untuk menyertakan dua entri baru ke array dalam contributions properti . Satu untuk HelloWorldWidget3 widget dan yang lain untuk konfigurasinya. Anda memerlukan gambar pratinjau lain untuk widget ketiga. Beri nama ini preview3.png dan letakkan img di folder . Perbarui array dalam files properti untuk menyertakan dua file HTML baru yang telah kami tambahkan dalam contoh ini.

{
    ...
    "contributions": [
        ... , 
        {
             "id": "HelloWorldWidget3",
             "type": "ms.vss-dashboards-web.widget",
             "targets": [
                 "ms.vss-dashboards-web.widget-catalog",
                 "fabrikam.vsts-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
            }
        ],
        ...     
}

Perhatikan kontribusi untuk konfigurasi widget mengikuti model yang sedikit berbeda dari widget itu sendiri. Entri kontribusi untuk konfigurasi widget memiliki:
  • ID untuk mengidentifikasi kontribusi Anda. Ini harus unik dalam ekstensi.
  • Jenis kontribusi. Untuk semua konfigurasi widget, ini harus ms.vss-dashboards-web.widget-configuration
  • Array target tempat kontribusi berkontribusi. Untuk semua konfigurasi widget, ini memiliki satu entri: ms.vss-dashboards-web.widget-configuration.
  • Properti yang berisi sekumpulan properti yang menyertakan nama, deskripsi, dan URI file HTML yang digunakan untuk konfigurasi.

Untuk mendukung konfigurasi, kontribusi widget juga perlu diubah. Array target untuk widget perlu diperbarui untuk menyertakan ID untuk konfigurasi dalam formulir <publisher>.>id for the extension<.<id for the configuration contribution> yang dalam hal ini adalah .fabrikam.vsts-extensions-myExtensions.HelloWorldWidget.Configuration

Peringatan

Jika entri kontribusi untuk widget yang dapat dikonfigurasi tidak menargetkan konfigurasi menggunakan penerbit dan nama ekstensi yang tepat seperti yang dijelaskan sebelumnya, tombol konfigurasi tidak muncul untuk widget.

Di akhir bagian ini, file manifes harus berisi tiga widget dan satu konfigurasi. Anda bisa mendapatkan manifes lengkap dari sampel di sini.

Langkah 6: Paket, Terbitkan, dan Bagikan

Jika Anda belum menerbitkan ekstensi, baca bagian ini untuk mengemas, menerbitkan, dan berbagi ekstensi Anda. Jika Anda telah menerbitkan ekstensi sebelum titik ini, Anda dapat mengemas ulang ekstensi dan langsung memperbaruinya ke Marketplace.

Langkah 7: Tambahkan Widget Dari Katalog

Sekarang, buka dasbor tim Anda di https://dev.azure.com/{yourOrganization}/{yourProject}. Jika halaman ini sudah terbuka, refresh. Arahkan mouse ke tombol Edit di kanan bawah, dan pilih tombol Tambahkan. Ini akan membuka katalog widget tempat Anda menemukan widget yang Anda instal. Pilih widget Anda dan pilih tombol 'Tambahkan' untuk menambahkannya ke dasbor Anda.

Anda akan melihat pesan yang meminta Anda untuk mengonfigurasi widget.

Overview dashboard with a sample widget from the catalog.

Ada dua cara untuk mengonfigurasi widget. Salah satunya adalah mengarahkan mouse ke widget, pilih elipsis yang muncul di sudut kanan atas lalu pilih Konfigurasikan. Yang lain adalah memilih tombol Edit di kanan bawah dasbor, lalu pilih tombol konfigurasi yang muncul di sudut kanan atas widget. Membuka pengalaman konfigurasi di sisi kanan, dan pratinjau widget Anda di tengah. Lanjutkan dan pilih kueri dari menu dropdown. Pratinjau langsung menunjukkan hasil yang diperbarui. Pilih "Simpan" dan widget Anda menampilkan hasil yang diperbarui.

Langkah 8: Mengonfigurasi Lainnya (opsional)

Anda dapat menambahkan elemen formulir HTML sebanyak yang configuration.html Anda butuhkan dalam untuk konfigurasi tambahan. Ada dua fitur yang dapat dikonfigurasi yang tersedia di luar kotak: nama widget dan ukuran widget.

Secara default, nama yang Anda berikan untuk widget Anda dalam manifes ekstensi disimpan sebagai nama widget untuk setiap instans widget Anda yang pernah ditambahkan ke dasbor. Anda dapat mengizinkan pengguna untuk mengonfigurasi ini, sehingga mereka dapat menambahkan nama apa pun yang mereka inginkan ke instans widget Anda. Untuk mengizinkan konfigurasi tersebut, tambahkan isNameConfigurable:true di bagian properti untuk widget Anda dalam manifes ekstensi.

Jika Anda memberikan lebih dari satu entri untuk widget Anda dalam supportedSizes array dalam manifes ekstensi, maka pengguna juga dapat mengonfigurasi ukuran widget.

Manifes ekstensi untuk sampel ketiga dalam panduan ini akan terlihat seperti di bawah ini jika kita mengaktifkan nama widget dan konfigurasi ukuran:

{
    ...
    "contributions": [
        ... , 
        {
             "id": "HelloWorldWidget3",
             "type": "ms.vss-dashboards-web.widget",
             "targets": [
                 "ms.vss-dashboards-web.widget-catalog",  "fabrikam.vsts-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"]
             }
         },
         ...
}

Dengan perubahan sebelumnya, kemas ulang dan perbarui ekstensi Anda. Refresh dasbor yang memiliki widget ini (Halo Dunia Widget 3 (dengan konfigurasi)). Buka mode konfigurasi untuk widget Anda, Anda sekarang dapat melihat opsi untuk mengubah nama dan ukuran widget.

Widget where name and size can be configured

Lanjutkan dan pilih ukuran yang berbeda dari menu drop-down. Anda melihat pratinjau langsung diubah ukurannya. Simpan perubahan dan widget di dasbor juga diubah ukurannya.

Peringatan

Jika Anda menghapus ukuran yang sudah didukung, maka widget gagal dimuat dengan benar. Kami sedang berupaya memperbaiki rilis mendatang.

Mengubah nama widget tidak mengakibatkan perubahan yang terlihat pada widget. Ini karena widget sampel kami tidak menampilkan nama widget di mana pun. Mari kita ubah kode sampel untuk menampilkan nama widget alih-alih teks "Halo Dunia" yang dikodekan secara permanen.

Untuk melakukan ini, ganti teks yang dikodekan secara permanen "Halo Dunia" dengan widgetSettings.name di baris tempat kita mengatur teks h2 elemen. Ini memastikan bahwa nama widget ditampilkan setiap kali widget dimuat pada refresh halaman. Karena kita ingin pratinjau langsung diperbarui setiap kali konfigurasi berubah, kita harus menambahkan kode yang sama di reload bagian kode kita juga. Pernyataan pengembalian akhir dalam hello-world3.html adalah sebagai berikut:

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);
    }
}

Kemas ulang dan perbarui ekstensi Anda lagi. Refresh dasbor yang memiliki widget ini. Setiap perubahan pada nama widget, dalam mode konfigurasi, perbarui judul widget sekarang.