Jimmy Yan | da878fc | 2016-09-02 16:32:01 -0700 | [diff] [blame] | 1 | // js for roadm flow table view |
| 2 | (function () { |
| 3 | 'use strict'; |
| 4 | |
| 5 | var SET_ATT_REQ = "roadmSetAttenuationRequest"; |
| 6 | var SET_ATT_RESP = "roadmSetAttenuationResponse"; |
| 7 | var DELETE_FLOW_REQ = "roadmDeleteFlowRequest"; |
| 8 | var CREATE_FLOW_REQ = "roadmCreateFlowRequest"; |
| 9 | var CREATE_FLOW_RESP = "roadmCreateFlowResponse"; |
MaoLu | 937cf42 | 2017-03-03 23:31:46 -0800 | [diff] [blame] | 10 | var SHOW_ITEMS_REQ = "roadmShowFlowItemsRequest"; |
| 11 | var SHOW_ITEMS_RESP = "roadmShowFlowItemsResponse"; |
Jimmy Yan | da878fc | 2016-09-02 16:32:01 -0700 | [diff] [blame] | 12 | |
| 13 | // injected references |
| 14 | var $log, $scope, $location, fs, tbs, wss, ns; |
| 15 | |
| 16 | // used to map id to a request call function |
| 17 | var flowCbTable = {}; |
| 18 | |
| 19 | function setAttenuation(flow, targetVal, cb) { |
| 20 | flowCbTable[flow.id] = cb; |
| 21 | wss.sendEvent(SET_ATT_REQ, |
| 22 | { |
| 23 | devId: $scope.devId, |
| 24 | flowId: flow.id, |
| 25 | attenuation: targetVal |
| 26 | }); |
| 27 | } |
| 28 | |
MaoLu | 937cf42 | 2017-03-03 23:31:46 -0800 | [diff] [blame] | 29 | function queryShowItems() { |
| 30 | wss.sendEvent(SHOW_ITEMS_REQ, |
| 31 | { |
| 32 | devId: $scope.devId, |
| 33 | }); |
| 34 | } |
| 35 | |
| 36 | function showItemsCb(data) { |
| 37 | $scope.showChannel = data.showChannel; |
| 38 | $scope.showAttenuation = data.showAttenuation; |
| 39 | $scope.$apply(); |
| 40 | } |
| 41 | |
Jimmy Yan | da878fc | 2016-09-02 16:32:01 -0700 | [diff] [blame] | 42 | function attenuationCb(data) { |
| 43 | flowCbTable[data.flowId](data.valid, data.message); |
| 44 | } |
| 45 | |
| 46 | // check if value is an integer |
| 47 | function isInteger(val) { |
| 48 | var INTEGER_REGEXP = /^\-?\d+$/; |
| 49 | if (INTEGER_REGEXP.test(val)) { |
| 50 | return true; |
| 51 | } |
| 52 | return false; |
| 53 | } |
| 54 | |
| 55 | angular.module('ovRoadmFlow', []) |
| 56 | .controller('OvRoadmFlowCtrl', |
| 57 | ['$log', '$scope', '$location', |
| 58 | 'FnService', 'TableBuilderService', 'WebSocketService', 'NavService', |
| 59 | |
| 60 | function (_$log_, _$scope_, _$location_, _fs_, _tbs_, _wss_, _ns_) { |
| 61 | var params; |
| 62 | $log = _$log_; |
| 63 | $scope = _$scope_; |
| 64 | $location = _$location_; |
| 65 | fs = _fs_; |
| 66 | tbs = _tbs_; |
| 67 | wss = _wss_; |
| 68 | ns = _ns_; |
| 69 | |
| 70 | $scope.addFlowTip = 'Create a flow'; |
| 71 | $scope.deviceTip = 'Show device table'; |
| 72 | $scope.flowTip = 'Show flow view for this device'; |
MaoLu | 937cf42 | 2017-03-03 23:31:46 -0800 | [diff] [blame] | 73 | $scope.portTip = 'Show port view for this device'; |
Jimmy Yan | da878fc | 2016-09-02 16:32:01 -0700 | [diff] [blame] | 74 | |
| 75 | $scope.showFlowForm = false; |
| 76 | |
| 77 | var handlers = {}; |
| 78 | handlers[SET_ATT_RESP] = attenuationCb; |
MaoLu | 937cf42 | 2017-03-03 23:31:46 -0800 | [diff] [blame] | 79 | handlers[SHOW_ITEMS_RESP] = showItemsCb; |
Jimmy Yan | da878fc | 2016-09-02 16:32:01 -0700 | [diff] [blame] | 80 | wss.bindHandlers(handlers); |
| 81 | |
| 82 | params = $location.search(); |
| 83 | if (params.hasOwnProperty('devId')) { |
| 84 | $scope.devId = params['devId']; |
| 85 | } |
| 86 | |
| 87 | tbs.buildTable({ |
| 88 | scope: $scope, |
| 89 | tag: 'roadmFlow', |
| 90 | query: params |
| 91 | }); |
| 92 | |
| 93 | $scope.displayFlowForm = function () { |
| 94 | $scope.showFlowForm = true; |
| 95 | } |
| 96 | |
| 97 | $scope.hideFlowForm = function () { |
| 98 | $scope.showFlowForm = false; |
| 99 | } |
| 100 | |
MaoLu | 937cf42 | 2017-03-03 23:31:46 -0800 | [diff] [blame] | 101 | $scope.queryShowItems = queryShowItems; |
| 102 | |
Jimmy Yan | da878fc | 2016-09-02 16:32:01 -0700 | [diff] [blame] | 103 | $scope.setAttenuation = setAttenuation; |
| 104 | |
| 105 | $scope.deleteFlow = function ($event, row) { |
| 106 | wss.sendEvent(DELETE_FLOW_REQ, |
| 107 | { |
| 108 | devId: $scope.devId, |
| 109 | id: row.id |
| 110 | }); |
| 111 | } |
| 112 | |
| 113 | $scope.createFlow = function(flow) { |
| 114 | wss.sendEvent(CREATE_FLOW_REQ, |
| 115 | { |
| 116 | devId: $scope.devId, |
| 117 | flow: flow |
| 118 | }); |
| 119 | } |
| 120 | |
| 121 | $scope.fakeCurrentPower = function(flow) { |
| 122 | if (!isNaN(flow.currentPower)) { |
| 123 | var val = parseInt(flow.attenuation); |
| 124 | return val + (val % 5 - 2); |
| 125 | } else { |
| 126 | return flow.currentPower; |
| 127 | } |
| 128 | } |
| 129 | |
| 130 | $scope.nav = function (path) { |
| 131 | if ($scope.devId) { |
| 132 | ns.navTo(path, { devId: $scope.devId }); |
| 133 | } |
| 134 | }; |
| 135 | |
| 136 | $scope.$on('$destroy', function () { |
| 137 | wss.unbindHandlers(handlers); |
| 138 | }); |
| 139 | |
| 140 | $log.log('OvRoadmFlowCtrl has been created'); |
| 141 | }]) |
| 142 | |
| 143 | .directive('roadmAtt', ['WebSocketService', function() { |
| 144 | |
| 145 | var retTemplate = |
| 146 | '<span class="attenuation" ng-show="!editMode" ng-click="enableEdit()">{{currItem.attenuation}}</span>' + |
| 147 | '<form ng-show="editMode" name="form" novalidate>' + |
| 148 | '<input type="number" name="formVal" ng-model="formVal">' + |
| 149 | '<button type="submit" class="submit" ng-click="send()">Set</button>' + |
| 150 | '<button type="button" class="cancel" ng-click="cancel()">Cancel</button>' + |
| 151 | '<span class="input-error" ng-show="showError">{{errorMessage}}</span>' + |
| 152 | '</form>'; |
| 153 | |
| 154 | return { |
| 155 | restrict: 'A', |
| 156 | scope: { |
| 157 | currItem: '=roadmAtt', |
| 158 | roadmSetAtt: '&' |
| 159 | }, |
| 160 | template: retTemplate, |
| 161 | link: function ($scope, $element) { |
| 162 | $scope.editMode = false; |
| 163 | $scope.showError = false; |
| 164 | $scope.errorMessage = "Invalid attenuation" |
| 165 | }, |
| 166 | controller: function($scope, $timeout) { |
| 167 | $scope.enableEdit = function() { |
| 168 | // connection must support attenuation to be editable |
MaoLu | 937cf42 | 2017-03-03 23:31:46 -0800 | [diff] [blame] | 169 | if ($scope.currItem.hasAttenuation === 'true' && $scope.editMode === false) { |
Jimmy Yan | da878fc | 2016-09-02 16:32:01 -0700 | [diff] [blame] | 170 | // Ensure that the entry being edited remains the same even |
| 171 | // if the table entries are shifted around. |
| 172 | $scope.targetItem = $scope.currItem; |
| 173 | // Ensure the value seen in the field remains the same |
| 174 | $scope.formVal = parseInt($scope.currItem.attenuation); |
| 175 | $scope.editMode = true; |
| 176 | $timeout(function () { |
| 177 | $scope.$apply() |
| 178 | }); |
| 179 | } |
| 180 | }; |
| 181 | $scope.send = function() { |
| 182 | // check input is an integer |
| 183 | if (!isInteger($scope.formVal)) { |
| 184 | $scope.sendCb(false, "Attenuation must be an integer"); |
| 185 | return; |
| 186 | } |
| 187 | $scope.roadmSetAtt({flow: $scope.targetItem, targetVal: $scope.formVal, cb: $scope.sendCb}); |
| 188 | }; |
| 189 | // Callback for server-side validation. Displays the error message |
| 190 | // if the input is invalid. |
| 191 | $scope.sendCb = function(valid, message) { |
| 192 | if (valid) { |
| 193 | // check if it's still pointing to the same item |
| 194 | // reordering the entries may change the binding |
| 195 | if ($scope.currItem.id === $scope.targetItem.id) { |
| 196 | // update the ui to display the new attenuation value |
| 197 | $scope.currItem.attenuation = $scope.formVal; |
| 198 | } |
| 199 | $scope.cancel(); |
| 200 | } else { |
| 201 | $scope.errorMessage = message; |
| 202 | $scope.showError = true; |
| 203 | } |
| 204 | $timeout(function () { |
| 205 | $scope.$apply() |
| 206 | }); |
| 207 | } |
| 208 | $scope.cancel = function() { |
| 209 | $scope.editMode = false; |
| 210 | $scope.showError = false; |
| 211 | } |
| 212 | } |
| 213 | }; |
| 214 | }]) |
| 215 | |
| 216 | .controller('FlowFormController', function($timeout) { |
| 217 | var notIntegerError = "Must be an integer."; |
| 218 | |
| 219 | this.clearErrors = function() { |
| 220 | this.priorityError = false; |
| 221 | this.timeoutError = false; |
| 222 | this.isPermanentError = false; |
| 223 | this.inPortError = false; |
| 224 | this.outPortError = false; |
| 225 | this.spacingError = false; |
| 226 | this.multiplierError = false; |
| 227 | this.attenuationError = false; |
| 228 | this.connectionError = false; |
| 229 | this.channelError = false; |
| 230 | } |
| 231 | this.clearErrors(); |
| 232 | |
| 233 | this.spacings = [ |
| 234 | {index: 0, freq: "100 GHz"}, |
| 235 | {index: 1, freq: "50 GHz"}, |
| 236 | {index: 2, freq: "25 GHz"}, |
| 237 | {index: 3, freq: "12.5 GHz"} |
| 238 | ]; |
| 239 | |
| 240 | this.flow = {}; |
| 241 | //this.flow.priority = 88; |
| 242 | this.flow.permanent = true; |
| 243 | this.flow.timeout = 0; |
| 244 | //this.flow.inPort = 2; |
| 245 | //this.flow.outPort = 2; |
| 246 | this.flow.spacing = this.spacings[1]; |
| 247 | //this.flow.multiplier = 0; |
MaoLu | 937cf42 | 2017-03-03 23:31:46 -0800 | [diff] [blame] | 248 | this.flow.channelFrequency = ""; |
Jimmy Yan | da878fc | 2016-09-02 16:32:01 -0700 | [diff] [blame] | 249 | this.flow.attenuation = 0; |
| 250 | |
| 251 | var parent = this; |
| 252 | |
| 253 | function createFlowCb(data) { |
| 254 | if (!data.inPort.valid) { |
| 255 | parent.inPortMessage = data.inPort.message; |
| 256 | parent.inPortError = true; |
| 257 | } |
| 258 | if (!data.outPort.valid) { |
| 259 | parent.outPortMessage = data.outPort.message; |
| 260 | parent.outPortError = true; |
| 261 | } |
| 262 | if (!data.connection.valid) { |
| 263 | parent.connectionMessage = data.connection.message; |
| 264 | parent.connectionError = true; |
| 265 | } |
| 266 | if (!data.spacing.valid) { |
| 267 | parent.spacingMessage = data.spacing.message; |
| 268 | parent.spacingError = true; |
| 269 | } |
MaoLu | 937cf42 | 2017-03-03 23:31:46 -0800 | [diff] [blame] | 270 | if ($scope.includeChannel) |
| 271 | { |
| 272 | if (!data.multiplier.valid) { |
| 273 | parent.multiplierMessage = data.multiplier.message; |
| 274 | parent.multiplierError = true; |
| 275 | } |
| 276 | if (!data.channelAvailable.valid) { |
| 277 | parent.channelMessage = data.channelAvailable.message; |
| 278 | parent.channelError = true; |
| 279 | } |
Jimmy Yan | da878fc | 2016-09-02 16:32:01 -0700 | [diff] [blame] | 280 | } |
MaoLu | 937cf42 | 2017-03-03 23:31:46 -0800 | [diff] [blame] | 281 | if ($scope.includeAttenuation && !data.attenuation.valid) { |
Jimmy Yan | da878fc | 2016-09-02 16:32:01 -0700 | [diff] [blame] | 282 | parent.attenuationMessage = data.attenuation.message; |
| 283 | parent.attenuationError = true; |
| 284 | } |
| 285 | $timeout(function () { |
| 286 | $scope.$apply() |
| 287 | }); |
| 288 | } |
| 289 | |
| 290 | var handlers = {} |
| 291 | handlers[CREATE_FLOW_RESP] = createFlowCb; |
| 292 | wss.bindHandlers(handlers); |
Jimmy Yan | da878fc | 2016-09-02 16:32:01 -0700 | [diff] [blame] | 293 | this.createFlow = function(connection) { |
| 294 | this.clearErrors(); |
| 295 | |
| 296 | var error = false; |
| 297 | if (!isInteger(connection.priority)) { |
| 298 | this.priorityMessage = notIntegerError; |
| 299 | this.priorityError = true; |
| 300 | error = true; |
| 301 | } |
| 302 | if (!connection.permanent && !isInteger(connection.timeout)) { |
| 303 | this.timeoutMessage = notIntegerError; |
| 304 | this.timeoutError = true; |
| 305 | error = true; |
| 306 | } |
| 307 | if (!isInteger(connection.inPort)) { |
| 308 | this.inPortMessage = notIntegerError; |
| 309 | this.inPortError = true; |
| 310 | error = true; |
| 311 | } |
| 312 | if (!isInteger(connection.outPort)) { |
| 313 | this.outPortMessage = notIntegerError; |
| 314 | this.outPortError = true; |
| 315 | error = true; |
| 316 | } |
MaoLu | 937cf42 | 2017-03-03 23:31:46 -0800 | [diff] [blame] | 317 | if ($scope.includeChannel && !isInteger(connection.multiplier)) { |
Jimmy Yan | da878fc | 2016-09-02 16:32:01 -0700 | [diff] [blame] | 318 | this.multiplierMessage = notIntegerError; |
| 319 | this.multiplierError = true; |
| 320 | error = true; |
| 321 | } |
MaoLu | 937cf42 | 2017-03-03 23:31:46 -0800 | [diff] [blame] | 322 | if ($scope.includeAttenuation && !isInteger(connection.attenuation)) { |
Jimmy Yan | da878fc | 2016-09-02 16:32:01 -0700 | [diff] [blame] | 323 | this.attenuationMessage = notIntegerError; |
| 324 | this.attenuationError = true; |
| 325 | error = true; |
| 326 | } |
| 327 | |
| 328 | if (!error) { |
| 329 | wss.sendEvent(CREATE_FLOW_REQ, |
| 330 | { |
| 331 | devId: $scope.devId, |
| 332 | formData: connection |
| 333 | }); |
| 334 | $log.log('Request to create connection has been sent'); |
| 335 | } |
| 336 | } |
| 337 | |
| 338 | $scope.$on('$destroy', function () { |
| 339 | wss.unbindHandlers(handlers); |
| 340 | }); |
| 341 | }); |
| 342 | |
| 343 | }()); |