ONOS-2849: Refactored topo dialog to general DialogService. Implemented confirmation dialog in App view.

Change-Id: Ib20e98253b2d13f7d7debef2dea5a530b61ced99
diff --git a/web/gui/src/main/webapp/app/view/app/app.css b/web/gui/src/main/webapp/app/view/app/app.css
index 9413369..528c622 100644
--- a/web/gui/src/main/webapp/app/view/app/app.css
+++ b/web/gui/src/main/webapp/app/view/app/app.css
@@ -30,3 +30,8 @@
 #ov-app input#uploadFile {
     display: none;
 }
+
+#app-dialog p {
+    color: darkred;
+    font-size: 12pt;
+}
diff --git a/web/gui/src/main/webapp/app/view/app/app.js b/web/gui/src/main/webapp/app/view/app/app.js
index 7cc081c..3b27c38 100644
--- a/web/gui/src/main/webapp/app/view/app/app.js
+++ b/web/gui/src/main/webapp/app/view/app/app.js
@@ -24,16 +24,20 @@
     // constants
     var INSTALLED = 'INSTALLED',
         ACTIVE = 'ACTIVE',
-        APP_MGMENT_REQ = 'appManagementRequest',
-        FILE_UPLOAD_URL = 'applications/upload';
+        appMgmtReq = 'appManagementRequest',
+        fileUploadUrl = 'applications/upload',
+        dialogId = 'app-dialog',
+        dialogOpts = {
+            edge: 'right'
+        };
 
     angular.module('ovApp', [])
     .controller('OvAppCtrl',
         ['$log', '$scope', '$http',
         'FnService', 'TableBuilderService', 'WebSocketService', 'UrlFnService',
-        'KeyService',
+        'KeyService', 'DialogService',
 
-    function ($log, $scope, $http, fs, tbs, wss, ufs, ks) {
+    function ($log, $scope, $http, fs, tbs, wss, ufs, ks, ds) {
         $scope.ctrlBtnState = {};
         $scope.uploadTip = 'Upload an application (.oar file)';
         $scope.activateTip = 'Activate selected application';
@@ -77,15 +81,41 @@
             ['scroll down', 'See more apps']
         ]);
 
+
+        function createConfirmationText(action, sid) {
+            var content = ds.createDiv();
+            content.append('p').text(action + ' ' + sid);
+            return content;
+        }
+
+        function confirmAction(action) {
+            var sid = $scope.selId,
+                spar = $scope.sortParams;
+
+            function dOk() {
+                $log.debug('Initiating', action, 'of', sid);
+                wss.sendEvent(appMgmtReq, {
+                    action: action,
+                    name: sid,
+                    sortCol: spar.sortCol,
+                    sortDir: spar.sortDir
+                });
+            }
+
+            function dCancel() {
+                $log.debug('Canceling', action, 'of', sid);
+            }
+
+            ds.openDialog(dialogId, dialogOpts)
+                .setTitle('Confirm Action')
+                .addContent(createConfirmationText(action, sid))
+                .addButton('OK', dOk)
+                .addButton('Cancel', dCancel);
+        }
+
         $scope.appAction = function (action) {
             if ($scope.ctrlBtnState.selection) {
-                $log.debug('Initiating ' + action + ' of ' + $scope.selId);
-                wss.sendEvent(APP_MGMENT_REQ, {
-                    action: action,
-                    name: $scope.selId,
-                    sortCol: $scope.sortParams.sortCol,
-                    sortDir: $scope.sortParams.sortDir
-                });
+                confirmAction(action);
             }
         };
 
@@ -93,7 +123,7 @@
             var formData = new FormData();
             if ($scope.appFile) {
                 formData.append('file', $scope.appFile);
-                $http.post(ufs.rsUrl(FILE_UPLOAD_URL), formData, {
+                $http.post(ufs.rsUrl(fileUploadUrl), formData, {
                     transformRequest: angular.identity,
                     headers: {
                         'Content-Type': undefined
diff --git a/web/gui/src/main/webapp/app/view/topo/topo.css b/web/gui/src/main/webapp/app/view/topo/topo.css
index 0319b9b..69f500f 100644
--- a/web/gui/src/main/webapp/app/view/topo/topo.css
+++ b/web/gui/src/main/webapp/app/view/topo/topo.css
@@ -96,23 +96,6 @@
     height: 30px;
 }
 
-/* --- Topo Dialog Panel --- */
-
-#topo-p-dialog .dialog-button {
-    display: inline-block;
-    cursor: pointer;
-    height: 20px;
-    padding: 2px 6px;
-    margin: 4px;
-    float: right;
-}
-
-.light #topo-p-dialog .dialog-button {
-    background-color: #fec;
-}
-.dark #topo-p-dialog .dialog-button {
-    background-color: #369;
-}
 
 /* --- general topo-panel styling --- */
 
diff --git a/web/gui/src/main/webapp/app/view/topo/topoDialog.js b/web/gui/src/main/webapp/app/view/topo/topoDialog.js
index 0c47511..c5e89dd 100644
--- a/web/gui/src/main/webapp/app/view/topo/topoDialog.js
+++ b/web/gui/src/main/webapp/app/view/topo/topoDialog.js
@@ -16,175 +16,29 @@
 
 /*
  ONOS GUI -- Topology Dialog Module.
- Defines functions for manipulating a dialog box.
+ Creates a dialog box for the topology view.
  */
 
 (function () {
     'use strict';
 
-    // injected refs
-    var $log, $window, $rootScope, fs, ps, bns;
-
     // constants
-    var pCls = 'topo-p dialog',
-        idDialog = 'topo-p-dialog',
-        panelOpts = {
-            width: 300,
-            edge: 'left'
+    var idDialog = 'topo-p-dialog',
+        opts = {
+            cssCls: 'topo-p'
         };
 
-    // internal state
-    var pApi, panel, dApi;
-
-    // TODO: ESC key invokes Cancel callback
-    // TODO: Enter invokes OK callback
-
-    // create the dialog; return its API
-    function createDialog() {
-        var header, body, footer,
-            p = ps.createPanel(idDialog, panelOpts);
-        p.classed(pCls, true);
-        panel = p;
-
-        function reset() {
-            p.empty();
-            p.append('div').classed('header', true);
-            p.append('div').classed('body', true);
-            p.append('div').classed('footer', true);
-
-            header = p.el().select('.header');
-            body = p.el().select('.body');
-            footer = p.el().select('.footer');
-        }
-
-        function hAppend(x) {
-            if (typeof x === 'string') {
-                return header.append(x);
-            }
-            header.node().appendChild(x.node());
-            return header;
-        }
-
-        function bAppend(x) {
-            if (typeof x === 'string') {
-                return body.append(x);
-            }
-            body.node().appendChild(x.node());
-            return body;
-        }
-
-        function fAppend(x) {
-            if (typeof x === 'string') {
-                return footer.append(x);
-            }
-            footer.node().appendChild(x.node());
-            return footer;
-        }
-
-        function destroy() {
-            ps.destroyPanel(idDialog);
-        }
-
-        return {
-            reset: reset,
-            appendHeader: hAppend,
-            appendBody: bAppend,
-            appendFooter: fAppend,
-            destroy: destroy
-        };
-    }
-
-    function makeButton(text, callback) {
-        var cb = fs.isF(callback);
-
-        function invoke() {
-            cb && cb();
-            panel.hide();
-        }
-        return createDiv('dialog-button')
-            .text(text)
-            .on('click', invoke);
-    }
-
-    function setTitle(title) {
-        if (pApi) {
-            pApi.appendHeader('h2').text(title);
-        }
-        return dApi;
-    }
-
-    function addContent(content) {
-        if (pApi) {
-            pApi.appendBody(content);
-        }
-        return dApi;
-    }
-
-    function addButton(text, cb) {
-        if (pApi) {
-            pApi.appendFooter(makeButton(text, cb));
-        }
-        return dApi;
-    }
-
-    // opens the dialog (creates if necessary)
-    function openDialog() {
-        $log.debug('Open DIALOG');
-        if (!pApi) {
-            pApi = createDialog();
-        }
-        pApi.reset();
-        panel.show();
-
-        // return the dialog object API
-        dApi = {
-            setTitle: setTitle,
-            addContent: addContent,
-            addButton: addButton
-        };
-        return dApi;
-    }
-
-    // closes the dialog (destroying panel)
-    function closeDialog() {
-        $log.debug('Close DIALOG');
-        if (pApi) {
-            panel.hide();
-            pApi.destroy();
-            pApi = null;
-            dApi = null;
-        }
-    }
-
-    // creates a detached div, returning D3 selection
-    // optional CSS class may be provided
-    function createDiv(cls) {
-        var div = d3.select(document.createElement('div'));
-        if (cls) {
-            div.classed(cls, true);
-        }
-        return div;
-    }
-
     // ==========================
 
     angular.module('ovTopo')
     .factory('TopoDialogService',
-        ['$log', '$window', '$rootScope', 'FnService', 'PanelService', 'ButtonService',
+        ['DialogService',
 
-        function (_$log_, _$window_, _$rootScope_,
-                  _fs_, _ps_, _bns_) {
-            $log = _$log_;
-            $window = _$window_;
-            $rootScope = _$rootScope_;
-            fs = _fs_;
-            ps = _ps_;
-            bns = _bns_;
-
+        function (ds) {
             return {
-                openDialog: openDialog,
-                closeDialog: closeDialog,
-                createDiv: createDiv
+                openDialog: function () { return ds.openDialog(idDialog, opts); },
+                closeDialog: ds.closeDialog,
+                createDiv: ds.createDiv
             };
         }]);
 }());