License Management

../../../../_images/step-project1.png ../../../../_images/step-meta1.png ../../../../_images/step-provision1.png ../../../../_images/step-presentation-b.png ../../../../_images/step-deploy1.png ../../../../_images/step-provisioning1.png

This document directs you through the process of creating the landing page for managing licenses in the provider control panel.

../../../../_images/step-presentation-licenses-b.png ../../../../_images/step-presentation-license-new.png ../../../../_images/step-presentation-license-edit.png ../../../../_images/step-presentation-services.png

In this document:

Overview

When managing a list of objects created from an APS type, you normally need a landing page that presents this list and enables the user to launch some management operations with the objects individually or in a bunch.

In APS applications, use the aps/Grid container consisting of toolbars and a table with specified columns for this purpose.

Development

Extend the ui/licenses.html file you have created from the project template with the following JavaScript code:

  1. Ensure the require list contains all JavaScript modules that the main callback function will need:

    require([
          "dojo/when",
          "dijit/registry",
          "aps/ResourceStore",
          "aps/load",
          "./displayError.js",
          "aps/ready!"
       ], function (when, registry, Store, load, displayError) {
       // .. To be continued in the next steps ..
    
    });
    
  2. Start the definition of the main callback function with the declaration of license store that will interact with the APS controller:

    /* Define data source */
    var licenseStore = new Store({
       target: "/aps/2/resources/" + aps.context.vars.app.aps.id + "/licenses"
    });
    
  3. Define the widget processing structure that consists of widget loading method followed by the widget processing logic:

    /* Define and load the widgets */
    load(["aps/PageContainer", { id: "page" }, [
        /* ...Define widgets here */
    
    ]])
    .then(function() {
       /* ...Define button processing here */
    
    });
    
  4. In the load method, define the aps/Grid container that will show a list of licenses from the license store and provide the buttons to manage the licenses:

    load(["aps/PageContainer", { id: "page" }, [
    /* ...Define widgets here */
       ["aps/Grid", {
             id:                "licenses_grid",
             selectionMode:     "multiple",
             apsResourceViewId: "license-edit",
             store: licenseStore,
             columns: [{
                name: "License",
                field: "name",
                type: "resourceName",
                filter: true
                }, {
                name: "Security scopes",
                renderCell: function (row) {
                return row.scopes.toString();
                }
             }]
          }, [
          ["aps/Toolbar", { id: "licenses_toolbar" }, [
             ["aps/ToolbarButton", {
                id: "licenses_new",
                iconClass: "sb-add-new",
                label:  "New"
             }],
             ["aps/ToolbarButton", {
                id: "licenses_delete",
                iconClass: "sb-delete",
                label: "Delete",
                requireItems: true
             }],
             ["aps/ToolbarButton", {
                id: "licenses_refresh",
                iconClass: "sb-refresh",
                label: "Refresh",
                autoBusy: false
             }]
          ]]
       ]]
    ]])
    

    Key:

    • selectionMode:"multiple" allows a user to select multiple rows. This will be needed to delete several rows.

    • apsResourceViewId:"license-edit" specifies a view (by its ID declared in metadata) to be opened when a user clicks on a row. In our case, that view will be the license editor.

    • The above code declares two columns: the first one represents the license name as defined by the license APS type and the second one builds its contents dynamically transferring an array of scopes to a string.

    • type:"resourceName" in the first column makes that column clickable.

    • Three buttons declared in the gird will be used to create, delete and refresh a list of licenses as defined by the respective handlers in the next steps.

  5. In function then(), define the following button handlers:

    .then(function() {
    /* ...Define button processing here */
       // The "New" button:
       registry.byId("licenses_new").on("click", function() {
           aps.apsc.gotoView("license-new");
       });
    
       // The "Refresh" button:
       registry.byId("licenses_refresh").on("click", function() {
           registry.byId("licenses_grid").refresh();
       });
    
       // The "Delete" button:
       registry.byId("licenses_delete").on("click", function() {
           var self = this;
           if (!confirm("Are you sure you want delete licenses?")) {
              self.cancel();
              return;
           }
           var grid    = registry.byId("licenses_grid"),
               sel     = grid.get("selectionArray"),
               counter = sel.length;
    
           registry.byId("page").get("messageList").removeAll();
    
           sel.forEach(function(licenseId){ /* Get a License from the selected list */
              console.log("I'm trying to delete license with id = [" + licenseId + "]");
    
              /* Remove the License from the APS database */
              when(licenseStore.remove(licenseId),
                  /* If success, process the next License until the list is empty */
                 function(){
                    console.log("license with id = [" + licenseId + "] removed");
                    sel.splice(sel.indexOf(licenseId),1); /* Remove the License from the view */
                    grid.refresh();
                    if(--counter === 0) {
                       self.cancel(); /* Make the button available again */
                    }
                 },
                  /* If failure, call the error handler */
                 function(e){
                    displayError(e);
                    if(--counter === 0) {
                       self.cancel();
                    }
                 }
              );
           });
       });
    

    Key:

    • The handler of the “New” button will open the license creation editor by its ID: “license-new”.

    • The handler of the “Refresh” button will call the grid built-in refresh function to sync the grid with the updated contents of the license store.

    • The handler of the “Delete” button will scan the list of selected rows and send a request for deletion of a license one by one. On completion of this process, the handler calls the built-in cancel method to make the button available for further operations with it.

Conclusion

This completes the development of the view presenting the landing page for managing licenses. From this page, the provider will be able to open the other view for their specific operations.

The project file you have created should be similar to the sample licenses.html file:

<!DOCTYPE html>
<html>
<head>
<script src="/aps/2/ui/runtime/client/aps/aps.js"></script>
<script>
require([
       "dojo/when",
       "dijit/registry",
       "aps/ResourceStore",
       "aps/load",
       "./displayError.js",
       "aps/ready!"
	], function (when, registry, Store, load, displayError) {
       /* Define data source */
       var licenseStore = new Store({
          target: "/aps/2/resources/" + aps.context.vars.app.aps.id + "/licenses"
       });

        load(["aps/PageContainer", { id: "page" }, [
          /* ...Define widgets here */
          ["aps/Grid", {
             id:                "licenses_grid",
             selectionMode:     "multiple",
             apsResourceViewId: "license-edit",
             store: licenseStore,
             columns: [{
                name: "License",
                field: "name",
                type: "resourceName",
                filter: true
             }, {
                name: "Security scopes",
                renderCell: function (row) {
                   return row.scopes.toString();
                }
             }]
          }, [
             ["aps/Toolbar", { id: "licenses_toolbar" }, [
                ["aps/ToolbarButton", {
                   id: "licenses_new",
                   iconClass: "sb-add-new",
                   label:  "New"
                }],
                ["aps/ToolbarButton", {
                   id: "licenses_delete",
                   iconClass: "sb-delete",
                   label: "Delete",
                   requireItems: true
                }],
                ["aps/ToolbarButton", {
                   id: "licenses_refresh",
                   iconClass: "sb-refresh",
                   label: "Refresh",
                   autoBusy: false
                }]
             ]]
          ]]
        ]]).then(function() {
        /* ...Define button processing here */
          // The "New" button:
          registry.byId("licenses_new").on("click", function() {
             aps.apsc.gotoView("license-new");
          });

          // The "Refresh" button:
          registry.byId("licenses_refresh").on("click", function() {
             registry.byId("licenses_grid").refresh();
          });

          // The "Delete" button:
          registry.byId("licenses_delete").on("click", function() {
             var self = this;
             if (!confirm("Are you sure you want delete licenses?")) {
                self.cancel();
                return;
             }
             var grid    = registry.byId("licenses_grid"),
                sel     = grid.get("selectionArray"),
                counter = sel.length;

             registry.byId("page").get("messageList").removeAll();

             sel.forEach(function(licenseId){ /* Get a License from the selected list */
                console.log("I'm trying to delete license with id = [" + licenseId + "]");

                /* Remove the License from the APS database */
                when(licenseStore.remove(licenseId),
                   /* If success, process the next License until the list is empty */
                   function(){
                      console.log("license with id = [" + licenseId + "] removed");
                      sel.splice(sel.indexOf(licenseId),1); /* Remove the License from the view */
                      grid.refresh();
                      if(--counter === 0) {
                         self.cancel(); /* Make the button available again */
                      }
                   },
                   /* If failure, call the error handler */
                   function(e){
                      displayError(e);
                      if(--counter === 0) {
                         self.cancel();
                      }
                   }
                );
             });
          });
        });
});
</script>
</head>
<body>
</body>
</html>