대시보드 위젯 추가

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

대시보드의 위젯은 확장 프레임워크에서 기여 구현됩니다. 단일 확장에는 여러 기여 있을 수 있습니다. 여러 위젯을 기여 사용하여 확장을 만드는 방법을 알아봅니다.

이 문서는 간단한 위젯에서 시작하여 포괄적인 위젯으로 끝나는 이전의 각 건물인 세 부분으로 나뉩니다.

Azure DevOps 확장 SDK사용하여 확장 개발에 대한 최신 설명서를 확인하세요.

이 자습서의 준비 및 필수 설정

Azure DevOps 또는 TFS에 대한 확장을 만들려면 필요한 몇 가지 필수 구성 요소 소프트웨어 및 도구가 있습니다.

지식: 위젯 개발에 JavaScript, HTML, CSS에 대한 지식이 필요합니다.

  • 위젯을 설치하고 테스트하기 위한 Azure DevOps의 조직에서 자세한 내용은 여기를 참조하세요.
  • 텍스트 편집기입니다. 많은 자습서에서 여기서 다운로드할 수 있는 사용 Visual Studio Code했습니다 .
  • 여기에서 다운로드할 수 있는 최신 버전의 노드
  • 확장을 패키지하는 Azure DevOps(tfx-cli) 용 플랫폼 간 CLI입니다.
    • 실행하여 Node.js의 구성 요소인 tfx-cli 를 사용하여 npm설치할 수 있습니다. npm i -g 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. 이 가이드의 첫 번째 부분에서는 간단한 "헬로 월드" 메시지를 출력하는 새 위젯을 만드는 방법을 보여 줍니다.
  2. 두 번째 부분은 Azure DevOps REST API에 대한 호출을 추가하여 첫 번째 파트 를 기반으로 합니다.
  3. 세 번째 부분에서위젯에 구성을 추가하는 방법을 설명합니다.

참고 항목

서둘러 코드를 바로 사용하려는 경우 여기에서 샘플을 다운로드할 수 있습니다. 다운로드한 후 폴더로 widgets 이동한 다음 6단계와 7단계를 직접 수행하여 다양한 복잡성의 세 가지 샘플 위젯이 있는 샘플 확장을 게시합니다.

기본적으로 제공되는 위젯에 대한 몇 가지 기본 스타일과 위젯 구조에 대한 몇 가지 지침을 시작합니다.

1부: 헬로 월드

이 부분에서는 JavaScript를 사용하여 "헬로 월드"을 인쇄하는 위젯을 제공합니다.

Overview dashboard with a sample widget

1단계: 클라이언트 SDK 가져오기 - VSS.SDK.min.js

핵심 SDK 스크립트 VSS.SDK.min.js를 사용하면 웹 확장이 호스트 Azure DevOps 프레임과 통신할 수 있습니다. 스크립트는 초기화, 확장 프로그램 알림 로드 또는 현재 페이지에 대한 컨텍스트 가져오기와 같은 작업을 수행합니다. 클라이언트 SDK VSS.SDK.min.js 파일을 가져와서 웹앱에 추가합니다. 폴더에 배치합니다 home/sdk/scripts .

'npm install' 명령을 사용하여 SDK를 검색합니다.

npm install vss-web-extension-sdk

SDK에 대한 자세한 내용은 클라이언트 SDK GitHub 페이지를 방문 하세요.

2단계: HTML 페이지 - hello-world.html

HTML 페이지는 레이아웃을 함께 포함하고 CSS 및 JavaScript에 대한 참조를 포함하는 붙이기입니다. 이 파일의 이름을 무엇이든 지정할 수 있습니다. 모든 참조를 hello-world 사용하는 이름으로 업데이트하기만 하면 됩니다.

위젯은 HTML 기반이며 iframe에서 호스트됩니다. 에 아래 HTML을 추가합니다 hello-world.html. 파일에 대한 필수 참조를 VSS.SDK.min.js 추가하고 다음 단계에서 문자열 헬로 월드 업데이트되는 요소를 포함합니다h2.

    <!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를 사용하여 위젯에서 콘텐츠를 렌더링합니다. 이 문서에서는 HTML 파일의 요소 내에 &lt;script&gt; 모든 JavaScript 코드를 래핑합니다. 이 코드를 별도의 JavaScript 파일에 저장하고 HTML 파일에서 참조하도록 선택할 수 있습니다. 코드는 콘텐츠를 렌더링합니다. 또한 이 JavaScript 코드는 VSS SDK를 초기화하고, 위젯의 코드를 위젯 이름에 매핑하고, 위젯 성공 또는 실패의 확장 프레임워크에 알깁니다. 이 경우 위젯에 "헬로 월드"을 인쇄하는 코드는 다음과 같습니다. HTML에서 headscript 요소를 추가합니다.

    <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 합니다. 이 컨트롤을 사용하면 종속 모듈이 로드되는지 확인한 후 부하 완료를 알릴 수 있습니다. 위젯에서 html 요소(예: 본문, div 등)에 대한 Azure DevOps 핵심 스타일을 사용할 수 있도록 전달 usePlatformStyles: true 합니다. 위젯에서 이러한 스타일을 사용하지 않으려는 경우 전달할 usePlatformStyles: false수 있습니다.

VSS.require 는 필요한 VSS 스크립트 라이브러리를 로드하는 데 사용됩니다. 이 메서드를 호출하면 JQuery 및 JQueryUI같은 일반 라이브러리가 자동으로 로드됩니다. 이 경우 위젯 프레임워크에 위젯 상태 통신하는 데 사용되는 WidgetHelpers 라이브러리에 의존합니다. 따라서 해당 모듈 이름 TFS/Dashboards/WidgetHelpers 및 콜백을 .에 전달합니다 VSS.require. 모듈이 로드되면 콜백이 호출됩니다. 콜백에는 위젯에 필요한 나머지 JavaScript 코드가 있습니다. 콜백이 끝나면 로드 완료를 알리기 위해 호출 VSS.notifyLoadSucceeded 합니다.

WidgetHelpers.IncludeWidgetStyles 에는 시작하기 위한 몇 가지 기본 css 가 포함된 스타일시트가 포함되어 있습니다. 이러한 스타일을 사용하려면 HTML 요소 내에 콘텐츠를 클래스 widget 로 래핑해야 합니다.

VSS.register는 확장의 여러 기여 간에 위젯을 고유하게 식별하는 JavaScript의 함수를 매핑하는 데 사용됩니다. 이름은 5단계에서 id설명한 대로 기여를 식별하는 이름과 일치해야 합니다. 위젯의 경우 전달되는 VSS.register 함수는 계약을 충족 IWidget 하는 개체를 반환해야 합니다. 예를 들어 반환된 개체에는 위젯을 렌더링하는 핵심 논리가 있는 다른 함수 값이 있는 부하 속성이 있어야 합니다. 이 경우 요소의 텍스트를 h2 "헬로 월드"로 업데이트합니다. 위젯 프레임워크가 위젯을 인스턴스화할 때 호출되는 함수입니다. WidgetHelpers를 사용하여 WidgetStatusHelper 성공으로 반환합니다 WidgetStatus .

Warning

위젯을 등록하는 데 사용되는 이름이 매니페스트의 기여에 대한 ID와 일치하지 않으면 위젯이 예기치 않게 작동합니다.

항상 vss-extension.json 폴더의 루트에 있어야 합니다(이 가이드 HelloWorld에서는). 다른 모든 파일의 경우 폴더 내에 원하는 구조로 배치할 수 있으며 HTML 파일 및 vss-extension.json 매니페스트에서 참조를 적절하게 업데이트해야 합니다.

4단계: 확장의 로고: logo.png

사용자가 확장을 설치하면 Marketplace 및 위젯 카탈로그에 로고가 표시됩니다.

98px x 98px 카탈로그 아이콘이 필요합니다. 이미지를 선택하고 이름을 지정 logo.png한 다음 폴더에 배치합니다 img .

TFS 2015 업데이트 3을 지원하려면 330px x 160px인 추가 이미지가 필요합니다. 이 미리 보기 이미지는 이 카탈로그에 표시됩니다. 이미지를 선택하고 이름을 지정 preview.png한 다음 이전과 같이 폴더에 img 배치합니다.

그러나 다음 단계의 확장 매니페스트가 사용하는 이름으로 업데이트되는 한 원하는 이미지의 이름을 지정할 수 있습니다.

5단계: 확장 매니페스트: vss-extension.json

다음 내용을 사용하여 디렉터리에 json 파일(vss-extension.json예: home )을 만듭니다.

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

필요한 특성에 대한 자세한 내용은 확장 매니페스트 참조를 참조하세요.

참고 항목

여기서 게시자는 게시자 이름으로 변경해야 합니다. 지금 게시자를 만들려면 패키지/게시/설치를 방문 하세요.

아이콘

아이콘 stanza매니페스트에서 확장 아이콘의 경로를 지정합니다.

참여

각 기여 항목은 속성을 정의합니다.

  • 기여를 식별할 ID입니다. 이 ID는 확장 내에서 고유해야 합니다. 이 ID는 위젯을 등록하기 위해 3단계에서 사용한 이름과 일치해야 합니다.
  • 기여 유형입니다. 모든 위젯의 경우 형식은 .이어야 ms.vss-dashboards-web.widget합니다.
  • 기여가 기여하는 대상의 배열입니다. 모든 위젯의 경우 대상은 .이어야 [ms.vss-dashboards-web.widget-catalog]합니다.
  • 속성기여 유형에 대한 속성을 포함하는 개체입니다. 위젯의 경우 다음 속성은 필수입니다.
속성 설명
name 위젯 카탈로그에 표시할 위젯의 이름입니다.
description 위젯 카탈로그에 표시할 위젯에 대한 설명입니다.
catalogIconUrl 위젯 카탈로그에 표시하기 위해 4단계에서 추가한 카탈로그 아이콘의 상대 경로입니다. 이미지는 98px x 98px여야 합니다. 다른 폴더 구조 또는 다른 파일 이름을 사용한 경우 여기에 적절한 상대 경로를 지정합니다.
previewImageUrl TFS 2015 업데이트 3에 대해서만 위젯 카탈로그에 표시하기 위해 4 단계에서 추가한 미리 보기 이미지의 상대 경로입니다. 이미지는 330px x 160px여야 합니다. 다른 폴더 구조 또는 다른 파일 이름을 사용한 경우 여기에 적절한 상대 경로를 지정합니다.
uri 1단계에서 추가한 HTML 파일의 상대 경로입니다. 다른 폴더 구조 또는 다른 파일 이름을 사용한 경우 여기에 적절한 상대 경로를 지정합니다.
supportedSizes 위젯에서 지원하는 크기의 배열입니다. 위젯이 여러 크기를 지원하는 경우 배열의 첫 번째 크기는 위젯의 기본 크기입니다. 대시보드 widget size 그리드에서 위젯이 차지하는 행 및 열에 대해 지정됩니다. 하나의 행/열은 160px에 해당합니다. 1x1을 초과하는 차원은 위젯 사이의 여백을 나타내는 10px를 추가로 가져옵니다. 예를 들어 3x2 위젯은 160*3+10*2 넓고 160*2+10*1 키가 깁니다. 지원되는 최대 크기는 .입니다 4x4.
supportedScopes 현재 팀 대시보드만 지원합니다. 값은 .이어야 합니다 project_team. 나중에 다른 대시보드 범위를 지원할 때 여기에서 선택할 수 있는 더 많은 옵션이 있을 것입니다.

Files

파일HTML 페이지, 스크립트, SDK 스크립트 및 로고 등 패키지에 포함하려는 파일을 표시합니다. true URL 주소를 지정할 필요가 없는 다른 파일을 포함하지 않는 한 설정 addressable 됩니다.

참고 항목

확장명 매니페스트 파일에 대한 자세한 내용(예: 해당 속성 및 해당 파일의 기능)은 확장 매니페스트 참조검사.

6단계: 패키지, 게시 및 공유

확장을 작성한 후에는 Marketplace에 확장을 가져오는 다음 단계는 모든 파일을 함께 패키지하는 것입니다. 모든 확장은 VSIX 2.0 호환 .vsix 파일로 패키지됩니다. Microsoft는 확장을 패키지하는 플랫폼 간 CLI(명령줄 인터페이스)를 제공합니다.

패키징 도구 가져오기

명령줄에서 Node.js구성 요소인 Azure DevOps(tfx-cli)npm용 플랫폼 간 CLI를 설치하거나 업데이트할 수 있습니다.

npm i -g tfx-cli

확장 패키지

tfx-cli가 있으면 확장 프로그램을 .vsix 파일로 패키징하는 것은 간편합니다. 확장의 홈 디렉터리로 이동하여 다음 명령을 실행합니다.

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

참고 항목

확장/통합의 버전은 모든 업데이트에서 증가해야 합니다.
기존 확장을 업데이트할 때 매니페스트에서 버전을 업데이트하거나 명령줄 스위치를 --rev-version 전달합니다. 이렇게 하면 확장의 패치 버전 번호가 증가하고 새 버전이 매니페스트에 저장됩니다.

.vsix 파일에 패키지 확장명이 있으면 확장명이 Marketplace에 게시될 준비가 된 것입니다.

확장에 대한 게시자 만들기

Microsoft의 확장을 포함한 모든 확장은 게시자가 제공하는 것으로 식별됩니다. 기존 게시자의 구성원이 아닌 경우 새로 만듭니다.

  1. Visual Studio Marketplace 게시 포털에 로그인
  2. 기존 게시자의 구성원이 아닌 경우 게시자를 만들라는 메시지가 표시됩니다. 게시자를 만들라는 메시지가 표시되지 않으면 페이지 아래쪽으로 스크롤하여 관련 사이트 아래에서 확장 게시를 선택합니다.
    • 게시자에 대한 식별자를 지정합니다. 예를 들면 다음과 같습니다. mycompany-myteam
      • 식별자는 확장명 매니페스트 파일의 publisher 특성 값으로 사용됩니다.
    • 게시자의 표시 이름을 지정합니다. 예를 들면 다음과 같습니다. My Team
  3. Marketplace 게시자 계약 검토 및 만들기 선택

이제 게시자가 정의됩니다. 이후 릴리스에서는 게시자의 확장을 보고 관리할 수 있는 권한을 부여할 수 있습니다. 팀과 조직이 공통 게시자에서 확장을 게시하는 것은 쉽고 안전하지만 사용자 집합 간에 자격 증명 집합을 공유할 필요는 없습니다.

vss-extension.json 더미 게시자 ID를 게시자 ID fabrikam 로 바꾸도록 샘플의 매니페스트 파일을 업데이트합니다.

확장 게시 및 공유

게시자를 만든 후 이제 Marketplace에 확장을 업로드할 수 있습니다.

  1. 새 확장 업로드 단추를 찾아 패키지된 .vsix 파일로 이동한 다음 업로드를 선택합니다.

한 단계에서 확장을 패키지하고 게시하는 대신 tfx extension create 명령을 사용하여 tfx extension publish 명령줄을 통해 확장을 업로드할 수도 있습니다. 필요에 따라 게시 후 하나 이상의 계정과 확장을 공유하는 데 사용할 --share-with 수 있습니다. 개인용 액세스 토큰도 필요합니다.

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

7단계: 카탈로그에서 위젯 추가

  1. Azure DevOps에서 프로젝트로 이동 http://dev.azure.com/{yourOrganization}/{yourProject}

  2. 개요를 선택한 다음 대시보드를 선택합니다.

  3. 위젯 추가를 선택합니다.

  4. 위젯을 강조 표시한 다음 추가를 선택합니다.

    위젯이 대시보드에 나타납니다.

2부: Azure DevOps REST API를 사용하여 헬로 월드

위젯은 Azure DevOps의 REST API 를 호출하여 Azure DevOps 리소스와 상호 작용할 수 있습니다. 이 예제에서는 WorkItemTracking용 REST API를 사용하여 기존 쿼리에 대한 정보를 가져오고 "헬로 월드" 텍스트 바로 아래 위젯에 일부 쿼리 정보를 표시합니다.

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

1단계: HTML

이전 예제에서 파일을 hello-world.html 복사하고 복사본 hello-world2.html이름을 .로 바꿉니다. 이제 폴더는 다음과 같습니다.

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

'h2' 바로 아래에 새 'div' 요소를 추가하여 쿼리 정보를 저장합니다. 'VSS.register'를 호출하는 줄에서 위젯의 이름을 'HelloWorldWidget'에서 'HelloWorldWidget2'로 업데이트합니다. 이렇게 하면 프레임워크가 확장 내에서 위젯을 고유하게 식별할 수 있습니다.
<!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"
    ]
}

Warning

확장을 게시한 후 범위를 추가하거나 변경하는 것은 현재 지원되지 않습니다. 확장을 이미 업로드한 경우 Marketplace에서 제거합니다. 으로 이동하여 Visual Studio Marketplace Publishing Portal확장을 마우스 오른쪽 단추로 클릭하고 "제거"를 선택합니다.

3단계: REST API 호출

Azure DevOps에서 REST API를 호출하기 위해 SDK를 통해 액세스할 수 있는 많은 클라이언트 쪽 라이브러리가 있습니다. 이러한 라이브러리를 REST 클라이언트라고 하며 사용 가능한 모든 서버 쪽 엔드포인트에 대한 Ajax 호출을 중심으로 하는 JavaScript 래퍼입니다. Ajax 호출을 직접 작성하는 대신 이러한 클라이언트에서 제공하는 메서드를 사용할 수 있습니다. 이러한 메서드는 코드에서 사용할 수 있는 개체에 API 응답을 매핑합니다.

이 단계에서는 WorkItemTracking REST 클라이언트를 제공하는 로드 TFS/WorkItemTracking/RestClient호출을 업데이트 VSS.require 합니다. 이 REST 클라이언트를 사용하여 폴더 Shared Queries아래에 호출 Feedback 된 쿼리에 대한 정보를 가져올 수 있습니다.

전달하는 VSS.register함수 내에서 현재 프로젝트 ID를 보유하는 변수를 만듭니다. 쿼리를 가져오려면 이 변수가 필요합니다. 또한 REST 클라이언트를 사용하는 새 메서드 getQueryInfo 를 만듭니다. 그런 다음, 로드 메서드에서 호출되는 이 메서드입니다.

이 메서드 getClient 는 필요한 REST 클라이언트의 인스턴스를 제공합니다. 이 메서드 getQuery 는 프라미스로 래핑된 쿼리를 반환합니다. 업데이트 VSS.require 된 내용은 다음과 같습니다.

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

에서 Failure 메서드 WidgetStatusHelper를 사용하는지 확인합니다. 위젯 프레임워크에 오류가 발생했음을 나타내고 모든 위젯에 제공된 표준 오류 환경을 활용할 수 있습니다.

폴더 아래에 Shared Queries 쿼리가 Feedback 없는 경우 코드에서 프로젝트에 있는 쿼리의 경로로 바꿉 Shared Queries\Feedback 니다.

4단계: 응답 표시

마지막 단계는 위젯 내에서 쿼리 정보를 렌더링하는 것입니다. 이 함수는 getQuery 프라미스 내에 있는 형식 Contracts.QueryHierarchyItem 의 개체를 반환합니다. 이 예제에서는 "헬로 월드" 텍스트 아래에 쿼리 ID, 쿼리 이름 및 쿼리 작성자의 이름을 표시합니다. 주석을 // Do something with the 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);

결승전 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(["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>

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/{yourOrganization}/{yourProject}팀 대시보드로 이동합니다. 이 페이지가 이미 열려 있는 경우 새로 고칩니다. 오른쪽 아래에 있는 편집 단추를 마우스로 가리키고 추가 단추를 선택합니다. 설치한 위젯을 찾을 수 있는 위젯 카탈로그가 열립니다. 위젯을 선택하고 '추가' 단추를 선택하여 대시보드에 추가합니다.

3부: 구성을 사용하여 헬로 월드

이 가이드의 2부에서는 하드 코딩된 쿼리에 대한 쿼리 정보를 표시하는 위젯을 만드는 방법을 알아보았습니다. 이 부분에서는 하드 코딩된 쿼리 대신 사용할 쿼리를 구성하는 기능을 추가합니다. 구성 모드에서 사용자는 변경 내용에 따라 위젯의 라이브 미리 보기를 볼 수 있습니다. 사용자가 저장을 선택하면 이러한 변경 내용이 대시보드의 위젯에 저장됩니다.

Overview dashboard live preview of the widget based on changes.

1단계: HTML

위젯 및 위젯 구성의 구현은 매우 유사합니다. 둘 다 확장 프레임워크에서 기여 구현됩니다. 둘 다 동일한 SDK 파일을 VSS.SDK.min.js사용합니다. 둘 다 HTML, JavaScript 및 CSS를 기반으로 합니다.

이전 예제에서 파일을 html-world2.html 복사하고 복사본 이름을 .로 hello-world3.html바꿉니다. 라는 configuration.html다른 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 - 구성

이 가이드의 1부 3단계에서 위젯에 대해 수행한 것처럼 JavaScript를 사용하여 위젯 구성에서 콘텐츠를 렌더링합니다. 이 JavaScript 코드는 콘텐츠를 렌더링하고, VSS SDK를 초기화하고, 위젯 구성의 코드를 구성 이름에 매핑하고, 구성 설정을 프레임워크에 전달합니다. 이 경우 위젯 구성을 로드하는 코드는 다음과 같습니다. 파일 configuration.html 및 아래 <script> 요소를 <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.initVSS.requireVSS.register 1부에 설명된 대로 위젯에 대해 연주한 것과 동일한 역할을 합니다. 유일한 차이점은 위젯 구성의 경우 전달되는 VSS.register 함수가 계약을 충족 IWidgetConfiguration 하는 개체를 반환해야 한다는 것입니다.

계약의 속성에는 loadIWidgetConfiguration 해당 값으로 함수가 있어야 합니다. 이 함수에는 위젯 구성을 렌더링하는 단계 집합이 있습니다. 이 경우 드롭다운 요소의 선택한 값을 기존 설정(있는 경우)으로 업데이트합니다. 프레임워크에서 인스턴스화할 때 이 함수가 호출됩니다. widget configuration

계약의 속성에는 onSaveIWidgetConfiguration 해당 값으로 함수가 있어야 합니다. 이 함수는 사용자가 구성 창에서 저장선택하면 프레임워크에서 호출됩니다. 사용자 입력을 저장할 준비가 되면 문자열로 serialize하고 개체를 custom settings 형성하여 사용자 입력을 저장하는 데 사용합니다 WidgetConfigurationSave.Valid() .

이 가이드에서는 JSON을 사용하여 사용자 입력을 문자열로 직렬화합니다. 사용자 입력을 문자열로 직렬화하는 다른 방법을 선택할 수 있습니다. 개체의 custom설정 속성을 통해 위젯에 WidgetSettings 액세스할 수 있습니다. 위젯은 4단계에서 다루는 이 값을 역직렬화해야 합니다.

3단계: JavaScript - 라이브 미리 보기 사용

사용자가 드롭다운에서 쿼리를 선택할 때 라이브 미리 보기 업데이트를 사용하도록 설정하려면 변경 이벤트 처리기를 단추에 연결합니다. 이 처리기는 구성이 변경되었음을 프레임워크에 알깁니다. 또한 미리 보기를 업데이트하는 데 사용할 대상을 전달 customSettings 합니다. 프레임워크에 알리려면 메서드를 notifywidgetConfigurationContext 호출해야 합니다. 이 매개 변수는 두 개의 매개 변수를 사용합니다. 이 경우는 이벤트의 이름과 도우미 메서드를 사용하여 만든 customSettings 이벤트에 대한 개체입니다.WidgetHelpers.WidgetEvent.ConfigurationChangeEventArgsWidgetEvent.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("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>

4단계: JavaScript - 위젯에서 다시 로드 구현

사용자가 선택한 쿼리 경로를 저장하도록 위젯 구성을 설정했습니다. 이제 위젯의 코드를 업데이트하여 이전 예제에서 하드 코딩된 Shared Queries/Feedback 대신 이 저장된 구성을 사용해야 합니다.

파일을 hello-world3.html 열고 호출VSS.register하는 줄에서 HelloWorldWidget2 위젯의 이름을 업데이트합니다HelloWorldWidget3. 이렇게 하면 프레임워크가 확장 내에서 위젯을 고유하게 식별할 수 있습니다.

현재 통해 매핑된 HelloWorldWidget3VSS.register 함수는 계약을 충족하는 개체를 IWidget 반환합니다. 이제 위젯에 구성이 필요하므로 계약을 충족하는 개체를 반환하려면 이 함수를 IConfigurableWidget 업데이트해야 합니다. 이렇게 하려면 아래와 같이 reload라는 속성을 포함하도록 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'의 하드 코딩된 쿼리 경로는 구성된 쿼리 경로로 바꿔야 합니다. 이 경로는 메서드에 전달되는 매개 변수 '위젯설정'에서 추출할 수 있습니다. '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단계: 확장 매니페스트 업데이트

속성을 배열 contributionsvss-extension.json 두 개의 새 항목을 포함하도록 파일을 엽니다. 하나는 위젯용 HelloWorldWidget3 이고 다른 하나는 해당 구성에 대한 것입니다. 세 번째 위젯에 대한 또 다른 미리 보기 이미지가 필요합니다. 이 preview3.png 이름을 지정하고 폴더에 배치합니다 img . 이 예제에서 추가한 files 두 개의 새 HTML 파일을 포함하도록 속성의 배열을 업데이트합니다.

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

위젯 구성에 대한 기여도는 위젯 자체와 약간 다른 모델을 따릅니다. 위젯 구성에 대한 기여 항목은 다음과 같습니다.
  • 기여를 식별할 ID입니다. 확장 내에서 고유해야 합니다.
  • 기여 유형입니다. 모든 위젯 구성의 경우 다음을 수행해야 합니다. ms.vss-dashboards-web.widget-configuration
  • 기여가 기여하는 대상의 배열입니다. 모든 위젯 구성의 경우 다음과 같은 단일 항목 ms.vss-dashboards-web.widget-configuration이 있습니다.
  • 구성에 사용되는 HTML 파일의 이름, 설명 및 URI를 포함하는 속성 집합을 포함하는 속성입니다.

구성을 지원하려면 위젯 기여도 변경해야 합니다. 위젯에 대한 대상의 배열을 업데이트하여 구성publisher>< ID를 .><id for the extension.id for the configuration contribution<> 이 경우 .fabrikam.vsts-extensions-myExtensions.HelloWorldWidget.Configuration

Warning

구성 가능한 위젯에 대한 기여 항목이 앞에서 설명한 대로 올바른 게시자 및 확장 이름을 사용하여 구성을 대상으로 하지 않는 경우 위젯에 대한 구성 단추가 표시되지 않습니다.

이 부분의 끝에서 매니페스트 파일에는 위젯 3개와 구성 1개가 포함되어야 합니다. 여기에서 샘플 에서 전체 매니페스트를 가져올 수 있습니다.

6단계: 패키지, 게시 및 공유

확장을 아직 게시하지 않은 경우 이 섹션을 읽어 확장을 패키지, 게시 및 공유합니다. 이 시점 이전에 확장을 이미 게시한 경우 확장을 다시 패키지하고 Marketplace로 직접 업데이트할 수 있습니다.

7단계: 카탈로그에서 위젯 추가

이제 팀 대시보드로 이동합니다. https://dev.azure.com/{yourOrganization}/{yourProject}. 이 페이지가 이미 열려 있는 경우 새로 고칩니다. 오른쪽 아래에 있는 편집 단추를 마우스로 가리키고 추가 단추를 선택합니다. 설치한 위젯을 찾을 위젯 카탈로그가 열립니다. 위젯을 선택하고 '추가' 단추를 선택하여 대시보드에 추가합니다.

위젯을 구성하라는 메시지가 표시됩니다.

Overview dashboard with a sample widget from the catalog.

위젯을 구성하는 방법에는 두 가지가 있습니다. 하나는 위젯을 마우스로 가리키고 오른쪽 위 모서리에 표시되는 줄임표를 선택한 다음 구성을 선택하는 것입니다. 다른 하나는 대시보드의 오른쪽 아래에 있는 편집 단추를 선택한 다음 위젯의 오른쪽 위 모서리에 표시되는 구성 단추를 선택하는 것입니다. 오른쪽에 구성 환경이 열리고 가운데에 위젯 미리 보기가 열립니다. 계속 진행하여 드롭다운에서 쿼리를 선택합니다. 라이브 미리 보기에는 업데이트된 결과가 표시됩니다. "저장"을 선택하면 위젯에 업데이트된 결과가 표시됩니다.

8단계: 추가 구성(선택 사항)

추가 구성에 필요한 configuration.html 만큼 HTML 양식 요소를 추가할 수 있습니다. 위젯 이름 및 위젯 크기라는 두 가지 구성 가능한 기능이 있습니다.

기본적으로 확장 매니페스트에서 위젯에 제공하는 이름은 대시보드에 추가되는 위젯의 모든 인스턴스에 대한 위젯 이름으로 저장됩니다. 사용자가 위젯 인스턴스에 원하는 이름을 추가할 수 있도록 이 구성을 허용할 수 있습니다. 이러한 구성을 허용하려면 확장 매니페스트에서 위젯의 속성 섹션에 추가 isNameConfigurable:true 합니다.

확장 매니페스트의 배열에서 supportedSizes 위젯에 대해 둘 이상의 항목을 제공하는 경우 사용자는 위젯의 크기도 구성할 수 있습니다.

위젯 이름 및 크기 구성을 사용하도록 설정하면 이 가이드의 세 번째 샘플에 대한 확장 매니페스트는 아래와 같습니다.

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

이전 변경 내용으로 확장을 다시 패키키지 하고 업데이트 합니다. 이 위젯이 있는 대시보드를 새로 고칩니다(헬로 월드 위젯 3(구성 포함). 위젯에 대한 구성 모드를 열면 이제 위젯 이름 및 크기를 변경하는 옵션을 볼 수 있습니다.

Widget where name and size can be configured

드롭다운에서 다른 크기를 선택합니다. 라이브 미리 보기의 크기가 조정되는 것을 볼 수 있습니다. 변경 내용 저장 및 대시보드의 위젯 크기도 조정됩니다.

Warning

이미 지원되는 크기를 제거하면 위젯이 제대로 로드되지 않습니다. 향후 릴리스에 대한 수정 작업을 진행 중입니다.

위젯의 이름을 변경해도 위젯이 표시되지 않습니다. 이는 샘플 위젯이 위젯 이름을 어디에도 표시하지 않기 때문입니다. 하드 코딩된 텍스트 "헬로 월드" 대신 위젯 이름을 표시하도록 샘플 코드를 수정해 보겠습니다.

이렇게 하려면 하드 코딩된 텍스트 "헬로 월드"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);
    }
}

확장을 다시 패키지 하고 업데이트 합니다. 이 위젯이 있는 대시보드를 새로 고칩니다. 구성 모드에서 위젯 이름을 변경하면 이제 위젯 제목을 업데이트합니다.