Windows Azure Pack Management Portal Client-Side Extension JavaScript

 

Applies To: Windows Azure Pack

Hello World Sample Visual Studio Project Paths: Microsoft.WAP.Samples.HelloWorld.TenantExtension\Content\*.js and Microsoft.WAP.Samples.HelloWorld.AdminExtension\Content\*.js

JavaScript required by a Windows Azure Pack management portal extension should be put into templates and defined in the manifest. This will load the JavaScript into the browser when the Windows Azure Pack portal loads. As with style sheets, there is no isolation for scripts—all scripts are loaded together. It is therefore highly recommended that JavaScript isolation techniques such as namespaces are used.

Layout

You can have as few or as many JavaScript files as your extension requires. However, it is suggested you follow a file layout and separation similar to the Hello World sample:

Microsoft.WAP.Samples.HelloWorld.TenantExtension (or Microsoft.WAP.Samples.HelloWorld.AdminExtension)
  \Styles
  \Templates
  extensions.data.js
  [ExtensionName]Extension.js (e.g. DomainTenantExtension.js)
  \Scripts
    (Individual scripts per tab or dialog)

The principal points of this layout are:

  • There are two JavaScript files outside of the \Scripts directory—these contain the initialization code for the browser part of the client-side of the extension.

  • All other JavaScript files are in the \Scripts directory. Each major user interface view of the extension, such as tabs or dialogs, has its own file. The code within is in one namespace for the extension.

Initialization Java Script

The initialization JavaScript files are:

  • Microsoft.WAP.Samples.HelloWorld.TenantExtension\extensions.data.js

  • Microsoft.WAP.Samples.HelloWorld.TenantExtension\HelloWorldTenant Extension.js

  • Microsoft.WAP.Samples.HelloWorld.AdminExtension\extensions.data.js

  • Microsoft.WAP.Samples.HelloWorld.AdminExtension\HelloWorldAdminExtension.js

Initialization of the JavaScript part of the client-side extension is in two parts. The first declares the extension to the framework, the second part fills in behavior and major user interface components such as tabs and command bar buttons. The reason for this split is that it allows an extension to check if it needs to display. For example, a user may not have subscribed to a plan that includes your resources, in which case display wouldn’t be needed. This is demonstrated by the function HelloWorldTenantExtensionActivationInit in Microsoft.WAP.Samples.HelloWorld.TenantExtension\Content\HelloWorldTenantExtension.js:

HelloWorldTenantExtensionActivationInit = function () {
     var subs = Exp.Rdfe.getSubscriptionList(),
         subscriptionRegisteredToService = global.Exp.Rdfe.getSubscriptionsRegisteredToService("helloworld"),
         helloWorldExtension = $.extend(this, global.HelloWorldTenantExtension);

     // Don't activate the extension if user doesn't have a plan that includes the service.
     if (subscriptionRegisteredToService.length === 0) {
         return false; // Don't want to activate? Just bail
     }

     //var quickCreateViewModel = new global.HelloWorldTenantExtension.ViewModels.QuickCreateViewModel();

     $.extend(helloWorldExtension, {
         viewModelUris: [helloWorldExtension.Controller.userInfoUrl],
         displayName: "Hello World",
         navigationalViewModelUri: {
             uri: helloWorldExtension.Controller.listFileSharesUrl,
             ajaxData: function () {
                 return global.Exp.Rdfe.getSubscriptionIdsRegisteredToService(serviceName);
             }
         },
         displayStatus: global.waz.interaction.statusIconHelper(global.HelloWorldTenantExtension.FileSharesTab.statusIcons, "Status"),
         menuItems: [
             {
                 name: "FileShares",
                 displayName: "Hello World",
                 url: "#Workspaces/HelloWorldTenantExtension",
                 preview: "createPreview",
                 subMenu: [
                     {
                         name: "Create",
                         displayName: "Create File Share",
                         description: "Quickly Create File Share on a File Server",
                         template: "CreateFileShare",
                         label: "Create",
                         subMenu: [
                             {
                                 name: "QuickCreate",
                                 displayName: "FileFile",
                                 template: "CreateFileShare"                                    
                             }
                         ]//,
                         //data: quickCreateViewModel,
                         //open: global.HelloWorldTenantExtension.ViewModels.onOpened,
                         //ok: global.HelloWorldTenantExtension.ViewModels.onOk

                         //execute: global.HelloWorldTenantExtension.CreateWizard.showCreateWizard
                     }
                 ]
             }
         ],
         getResources: function () {
             return resources;
         }
     });

     // TODO: (fx-isolation) Refactor navigation
     helloWorldExtension.onNavigateAway = onNavigateAway;
     helloWorldExtension.navigation = navigation;

     Shell.UI.Pivots.registerExtension(helloWorldExtension, function () {
         Exp.Navigation.initializePivots(this, this.navigation);
     });

     // Finally activate and give "the" helloWorldExtension the activated extension since a good bit of code depends on it
     $.extend(global.HelloWorldTenantExtension, Shell.Extensions.activate(helloWorldExtension));
 };

Like any other JavaScript required for your extension, it should be declared in the manifest for your extension.The first part of extension declaration, if using the suggested file layout from earlier, takes place in the extensions.data.js file. The Hello World sample has this in Microsoft.WAP.Samples.HelloWorld.TenantExtension\Content\extensions.data.js :

(function (global, undefined) {
    "use strict";

    var extensions = [{
        name: "HelloWorldTenantExtension",
        displayName: "Hello World",
        iconUri: "/Content/HelloWorldTenant/HelloWorldTenant.png",
        iconShowCount: false,
        iconTextOffset: 11,
        iconInvertTextColor: true,
        displayOrderHint: 2 // Display it right after WebSites extension (order 1)
    }];

    global.Shell.Internal.ExtensionProviders.addLocal(extensions);
})(this);

Property

Description

displayName

Text displayed in the left navigation for the extension.

iconUri

Site-absolute path to the image used as the icon for the extension.

iconShowCount

Toggles displaying a count of the items in an extension on the extension’s icon.

iconTextOffset, iconInvertTextColor

Fine-grained control over the display of the extension’s entry in the left navigation.

displayOrderHint

Position in the list of extensions in the left navigation. A lower number equates to closer to the top of the left navigation pane.

The second part of extension declaration, if using the suggested file layout in Implementing a Windows Azure Pack Management Portal Client-Side Extension, takes place in the [ExtensionName]Extension.js file (where [ExtensionName] is the name of the extension). Content in this file is generally extension-wide in scope. Examples of what is usually performed in this file include:

  • Setting up the JavaScript namespace for the extension’s code.

  • Declaring any tabs the extension will have.

  • Declaring any Add New menu items the extension will contribute.

  • Defining any extension-global behaviors. For example, what to do when the extension is opened for the first time.

Tab or Dialog JavaScript Files

If you use the suggested script splitting and file layout, each tab or dialog will have its own JavaScript file in the \Scripts directory. Every script file must be declared in the manifest for your extension if it is to be loaded.It is recommended that your JavaScript code exists within a namespace in order not to interfere with code from other extensions. If the same namespace is used between all your files, you should be able to refer to functions from other files, meaning you could have the initialization JavaScript refer to a function in your wizard JavaScript which creates a wizard, instead of having the wizard creation function be part of the initialization JavaScript.

For more information about performing actions in the user interface, see Performing Common Tasks in a Windows Azure Pack Management Portal Extension.

See Also

Windows Azure Pack Management Portal User Interface Extensions