ONOS-2074 - GUI -- Refactor Application view to use directives. WIP.
Change-Id: If886b5af1313ef350e041dc9f9a21ba150edcd79
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 c2d61cc..2b84e83 100644
--- a/web/gui/src/main/webapp/app/view/app/app.css
+++ b/web/gui/src/main/webapp/app/view/app/app.css
@@ -31,3 +31,8 @@
width: 24px;
border: none;
}
+
+#ov-app form#inputFileForm,
+#ov-app input#uploadFile {
+ display: none;
+}
diff --git a/web/gui/src/main/webapp/app/view/app/app.html b/web/gui/src/main/webapp/app/view/app/app.html
index 3b78853..0243b5a 100644
--- a/web/gui/src/main/webapp/app/view/app/app.html
+++ b/web/gui/src/main/webapp/app/view/app/app.html
@@ -7,31 +7,28 @@
icon icon-size="36" icon-id="refresh"
ng-click="toggleRefresh()"></div>
<div class="separator"></div>
- <div id="app-install"
- icon icon-size="36" icon-id="plus"
- class="active">
+
+ <form id="inputFileForm">
+ <input id="uploadFile"
+ type="file" size="50" accept=".oar"
+ file-model="appFile">
+ </form>
+ <div icon icon-size="36" icon-id="plus"
+ class="active" trigger-form>
</div>
- <div id="app-activate"
- icon icon-size="36" icon-id="play"
+ <div icon icon-size="36" icon-id="play"
+ ng-click="appAction('activate')"
ng-class="{active: ctrlBtnState.installed}">
</div>
- <div id="app-deactivate"
- icon icon-size="36" icon-id="stop"
+ <div icon icon-size="36" icon-id="stop"
+ ng-click="appAction('deactivate')"
ng-class="{active: ctrlBtnState.active}">
</div>
- <div id="app-uninstall"
- icon icon-size="36" icon-id="garbage"
+ <div icon icon-size="36" icon-id="garbage"
+ ng-click="appAction('uninstall')"
ng-class="{active: ctrlBtnState.selection}">
</div>
</div>
-
- <form id="app-form" method="POST" action="rs/applications/upload"
- target="app-form-response" enctype="multipart/form-data" style="display:none">
- <input type="file" name="file" id="file" size="50" accept=".oar">
- <button type="submit" id="app-upload">Upload</button>
- </form>
- <iframe id="app-form-response" name="app-form-response"
- src="" width="0" height="0" style="visibility:hidden;display:none"></iframe>
</div>
<div class="summary-list" onos-fixed-header>
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 29cc9b6..1918f3a 100644
--- a/web/gui/src/main/webapp/app/view/app/app.js
+++ b/web/gui/src/main/webapp/app/view/app/app.js
@@ -21,74 +21,115 @@
(function () {
'use strict';
- var selectionObj;
+ // constants
+ var INSTALLED = 'INSTALLED',
+ ACTIVE = 'ACTIVE',
+ APP_MGMENT_REQ = 'appManagementRequest',
+ FILE_UPLOAD_URL = 'applications/upload';
angular.module('ovApp', [])
.controller('OvAppCtrl',
- ['$log', '$scope', 'FnService', 'TableBuilderService', 'WebSocketService',
+ ['$log', '$scope', '$http',
+ 'FnService', 'TableBuilderService', 'WebSocketService', 'UrlFnService',
- function ($log, $scope, fs, tbs, wss) {
+ function ($log, $scope, $http, fs, tbs, wss, ufs) {
+ var refreshCtrls;
$scope.ctrlBtnState = {};
- // TODO: clean up view
- // all DOM manipulation (adding styles, getting elements and doing stuff
- // with them) should be done in directives
function selCb($event, row) {
+ // selId comes from tableBuilder
$scope.ctrlBtnState.selection = !!$scope.selId;
- selectionObj = row;
$log.debug('Got a click on:', row);
- if ($scope.ctrlBtnState.selection) {
- $scope.ctrlBtnState.installed = row.state === 'INSTALLED';
- $scope.ctrlBtnState.active = row.state === 'ACTIVE';
- } else {
- $scope.ctrlBtnState.installed = false;
- $scope.ctrlBtnState.active = false;
- }
+ refreshCtrls = function () {
+ if ($scope.ctrlBtnState.selection) {
+ $scope.ctrlBtnState.installed = row.state === INSTALLED;
+ $scope.ctrlBtnState.active = row.state === ACTIVE;
+ } else {
+ $scope.ctrlBtnState.installed = false;
+ $scope.ctrlBtnState.active = false;
+ }
+ };
+
+ refreshCtrls();
+ }
+
+ function respCb() {
+ refreshCtrls && refreshCtrls();
}
tbs.buildTable({
scope: $scope,
tag: 'app',
- selCb: selCb
+ selCb: selCb,
+ respCb: respCb
});
- // TODO: use d3 click events -- move to directive
- d3.select('#app-install').on('click', function () {
- $log.debug('Initiating install');
- var evt = document.createEvent("HTMLEvents");
- evt.initEvent("click", true, true);
- document.getElementById('file').dispatchEvent(evt);
- });
-
- // TODO: use d3 to select elements -- move to directive
- document.getElementById('app-form-response').onload = function () {
- document.getElementById('app-form').reset();
- $scope.$apply();
- //$scope.sortCallback($scope.sortParams);
+ $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
+ });
+ }
};
- function appAction(action) {
- if ($scope.ctrlBtnState.selection) {
- $log.debug('Initiating ' + action + ' of', selectionObj);
- wss.sendEvent('appManagementRequest', {action: action, name: selectionObj.id});
+ $scope.$on('FileChanged', function () {
+ var formData = new FormData();
+ if ($scope.appFile) {
+ formData.append('file', $scope.appFile);
+ $http.post(ufs.rsUrl(FILE_UPLOAD_URL), formData, {
+ transformRequest: angular.identity,
+ headers: {
+ 'Content-Type': undefined
+ }
+ })
+ // TODO: look for finally function to combine lines
+ // TODO: reexamine reset input value
+ .success(function () {
+ $scope.sortCallback($scope.sortParams);
+ document.getElementById('inputFileForm').reset();
+ })
+ .error(function () {
+ $scope.sortCallback($scope.sortParams);
+ });
}
- }
-
- // TODO: use d3 to select elements -- move to directive
- d3.select('#file').on('change', function () {
- var file = document.getElementById('file').value.replace('C:\\fakepath\\', '');
- $log.info('Handling file', file);
- var evt = document.createEvent("HTMLEvents");
- evt.initEvent("click", true, true);
- document.getElementById('app-upload').dispatchEvent(evt);
});
- // TODO: move to directive
- d3.select('#app-uninstall').on('click', function () { appAction('uninstall'); });
- d3.select('#app-activate').on('click', function () { appAction('activate'); });
- d3.select('#app-deactivate').on('click', function () { appAction('deactivate'); });
-
$log.log('OvAppCtrl has been created');
+ }])
+
+ // triggers the input form to appear when button is clicked
+ .directive('triggerForm', function () {
+ return {
+ restrict: 'A',
+ link: function (scope, elem) {
+ elem.bind('click', function () {
+ document.getElementById('uploadFile')
+ .dispatchEvent(new Event('click'));
+ });
+ }
+ };
+ })
+
+ // binds the model file to the scope in scope.appFile
+ // sends upload request to the server
+ .directive('fileModel', ['$parse',
+ function ($parse) {
+ return {
+ restrict: 'A',
+ link: function (scope, elem, attrs) {
+ var model = $parse(attrs.fileModel),
+ modelSetter = model.assign;
+
+ elem.bind('change', function () {
+ scope.$apply(function () {
+ modelSetter(scope, elem[0].files[0]);
+ });
+ scope.$emit('FileChanged');
+ });
+ }
+ };
}]);
}());
diff --git a/web/gui/src/main/webapp/app/view/port/port.html b/web/gui/src/main/webapp/app/view/port/port.html
index 5683ca2..3e93eb3 100644
--- a/web/gui/src/main/webapp/app/view/port/port.html
+++ b/web/gui/src/main/webapp/app/view/port/port.html
@@ -18,8 +18,8 @@
<div id="ov-port">
<div class="tabular-header">
<h2>
- Ports for Device {{devId || "(No device selected)"}}
- ({{tableData.length}} total)
+ Port Statistics for Device {{devId || "(No device selected)"}}
+ ({{tableData.length}} Ports total)
</h2>
<div class="ctrl-btns">
<div class="refresh" ng-class="{active: autoRefresh}"