d29d547dcfce819fe52d42daf2957399ea290c38
[ccsdk/apps.git] / sdnr / wireless-transport / code-Carbon-SR1 / ux / mwtnFault / mwtnFault-module / src / main / resources / mwtnFault / mwtnFault.controller.js
1 /*
2  * Copyright (c) 2016 highstreet technologies GmbH and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 define(['app/mwtnFault/mwtnFault.module',
10         'app/mwtnFault/mwtnFault.services',
11         'app/mwtnFault/mwtnFault.directives'], 
12         function(mwtnFaultApp) {
13     
14   mwtnFaultApp.register.controller('mwtnFaultCtrl', ['uiGridConstants', '$uibModal', '$scope', '$rootScope', '$window', '$timeout', '$mwtnFault', '$mwtnLog', '$http',
15                                                  function(uiGridConstants, $uibModal, $scope, $rootScope, $window, $timeout, $mwtnFault,  $mwtnLog, $http) {
16
17                                                     
18     var COMPONENT = 'mwtnFaultCtrl';
19     $mwtnLog.info({component: COMPONENT, message: 'mwtnFaultCtrl started!'});
20     
21     $rootScope.section_logo = 'src/app/mwtnFault/images/mwtnFault.png'; // Add your topbar logo location here such as 'assets/images/logo_topology.gif'
22
23     $scope.date = new Date().toISOString().toHumanReadableTimeFormat();
24     $scope.highlightFilteredHeader = $mwtnFault.highlightFilteredHeader;
25     $scope.oneATime = true;
26     
27     // var rowTemplate = '<div ng-click="grid.appScope.fnOne(row)" ng-repeat="col in colContainer.renderedColumns track by col.colDef.name" ng-class="[\'ui-grid-cell\', row.entity.type]" ui-grid-cell></div>';
28     var iconCell = '<div class="ui-grid-cell-contents tooltip-uigrid" title="TOOLTIP"><i class="fa {{COL_FIELD}}" aria-hidden="true"></i></div>';
29     var getIconFromSeverity = function(severity) {
30       var mapping = {
31         Cleared : '',
32         NonAlarmed : '',
33         Critical : 'fa-exclamation-triangle',
34         Major : 'fa-exclamation-triangle',
35         Minor : 'fa-exclamation-triangle',
36         Warning : 'fa-times-circle'
37       };
38       return mapping[severity];
39     };
40     
41     // Current Problem List
42     $scope.gridOptionsCurrentProblemList = JSON.parse(JSON.stringify($mwtnFault.gridOptions));
43     $scope.gridOptionsCurrentProblemList.columnDefs = [
44      // { field: 'id', type: 'number', displayName: 'No.',  headerCellClass: $scope.highlightFilteredHeader, width : 50, cellClass: 'number', pinnedLeft : true },
45      { field: 'icon',  type: 'string', displayName: '',  headerCellClass: $scope.highlightFilteredHeader, width: 25, enableSorting: false, enableFiltering:false, cellTemplate: iconCell },
46      { field: 'timestamp',  type: 'string', displayName: 'Timestamp',  headerCellClass: $scope.highlightFilteredHeader, width : 200, sort: {
47        direction: uiGridConstants.DESC,
48        priority: 1
49      } },
50      { field: 'node',  type: 'string', displayName: 'Node name',  headerCellClass: $scope.highlightFilteredHeader, width: 200 },
51      { field: 'counter',  type: 'number', displayName: 'Counter',  headerCellClass: $scope.highlightFilteredHeader, width: 70, cellClass: 'number' },
52      { field: 'object',  type: 'string', displayName: 'Object Id',  headerCellClass: $scope.highlightFilteredHeader, width: 300 },
53      { field: 'problem',  type: 'string', displayName: 'Alarm type',  headerCellClass: $scope.highlightFilteredHeader, width : 200 },
54      { field: 'severity',  type: 'string', displayName: 'Severity',  headerCellClass: $scope.highlightFilteredHeader, width : 150 }
55      
56    ];
57     
58     var processCurrentProblemEntries = function(logEntries) {
59       if (logEntries.data.hits.hits) {
60         $scope.gridOptionsCurrentProblemList.data = logEntries.data.hits.hits.map(function(entry){
61           return {
62               id: entry._id,
63               icon: getIconFromSeverity(entry._source.faultCurrent.severity),
64               timestamp: $mwtnFault.formatTimeStamp(entry._source.faultCurrent.timeStamp),
65               node: entry._source.faultCurrent.nodeName,
66               counter: entry._source.faultCurrent.counter,
67               object: entry._source.faultCurrent.objectId,
68               problem: entry._source.faultCurrent.problem,
69               severity: entry._source.faultCurrent.severity,
70           };
71         });
72         $scope.progress.max = logEntries.data.hits.total;         
73         $scope.progress.value = $scope.gridOptionsCurrentProblemList.data.length;         
74         $scope.progress.show = $scope.gridOptionsCurrentProblemList.data.length < logEntries.data.hits.total;
75       }
76     };
77     
78     $scope.refreshCurrentProblemList = function() {
79       // $scope.gridOptionsCurrentProblemList.data = [];
80       var from = 0;
81       var size = 10000;
82       $scope.processing = true;
83       $mwtnFault.getAllCurrentProblemEntries(from, size).then(function(logEntries){
84         $scope.processing = false;
85         $scope.spinner.currentProblemList = false;
86         processCurrentProblemEntries(logEntries);
87         from = from + size;
88         while (from < $scope.progress.max) {
89           $mwtnFault.getAllCurrentProblemEntries(from, size).then(function(logEntries){
90             processCurrentProblemEntries(logEntries);
91           }, function(error){
92             console.error(JSON.stringify(error));
93           });
94           from = from + size;
95         }
96       }, function(error){
97         $scope.processing = false;
98         $scope.spinner.currentProblemList = false;
99         console.error(JSON.stringify(error));
100       });      
101     };
102
103     // Alarm Notifications
104     $scope.gridOptionsAlarmNotifications = JSON.parse(JSON.stringify($mwtnFault.gridOptions));
105     $scope.gridOptionsAlarmNotifications.columnDefs = [
106       // { field: 'id', type: 'number', displayName: 'No.',  headerCellClass: $scope.highlightFilteredHeader, width : 50, cellClass: 'number', pinnedLeft : true },
107       { field: 'icon',  type: 'string', displayName: '',  headerCellClass: $scope.highlightFilteredHeader, width: 25, enableSorting: false, enableFiltering:false, cellTemplate: iconCell },
108       { field: 'timeStamp',  type: 'string', displayName: 'Timestamp',  headerCellClass: $scope.highlightFilteredHeader, width : 200,sort: {
109         direction: uiGridConstants.DESC,
110         priority: 1
111       } },
112       { field: 'counter',  type: 'number', displayName: 'Counter',  headerCellClass: $scope.highlightFilteredHeader, width: 90 },
113       { field: 'nodeName',  type: 'string', displayName: 'NetworkElement',  headerCellClass: $scope.highlightFilteredHeader, width: 170 },
114       { field: 'objectId',  type: 'string', displayName: 'Object',  headerCellClass: $scope.highlightFilteredHeader, width: 400 },
115
116       { field: 'problem',  type: 'string', displayName: 'Alarm',  headerCellClass: $scope.highlightFilteredHeader, width : 140 },
117       { field: 'severity',  type: 'string', displayName: 'Severity',  headerCellClass: $scope.highlightFilteredHeader, width : 100 }
118     ];
119     var listenToNotifications = function() {
120       $mwtnFault.getMwtnWebSocketUrl().then(function(success){
121         try {
122           var notificationSocket = new WebSocket(success);
123
124           notificationSocket.onmessage = function(event) {
125             // we process our received event here
126             if (typeof event.data === 'string') {
127               // console.log("Client Received:\n" + event.data);
128               // console.log("---------------------------");
129               $mwtnFault.formatData(event).then(function(formated) {
130                 switch (formated.notifType) {
131                 case 'ProblemNotification':
132                   formated.icon = getIconFromSeverity(formated.severity);
133                   $scope.gridOptionsAlarmNotifications.data.push(formated);
134                   $timeout(function(){$scope.refreshCurrentProblemList();}, 500);
135                   break;
136                 case 'AttributeValueChangedNotification':
137                 case 'ObjectCreationNotification':
138                 case 'ObjectDeletionNotification':
139                   // ignore
140                   break;
141                 default:
142                   console.error('Missing implementation for', formated.notifType);
143                 }
144               }, function(error) {
145                 // do nothing
146               });
147             }
148           };
149
150           notificationSocket.onerror = function(error) {
151             console.log("Socket error: " + error);
152           };
153
154           notificationSocket.onopen = function(event) {
155             console.log("Socket connection opened.");
156
157             function subscribe() {
158               if (notificationSocket.readyState === notificationSocket.OPEN) {
159                 var data = {
160                   'data' : 'scopes',
161                   'scopes' : [ "ProblemNotification" ]
162                 };
163                 notificationSocket.send(JSON.stringify(data));
164               }
165             }
166             subscribe();
167           };
168
169           notificationSocket.onclose = function(event) {
170             console.log("Socket connection closed.");
171           };
172         } catch (e) {
173           console.error("Error when creating WebSocket.\n" + e);
174         }
175       }, function(error){
176         console.error("Error when creating WebSocket.\n" + error);
177       });
178     };
179     listenToNotifications();
180     
181     // Alarm Log
182    // $scope.gridOptionsAlarmLog = JSON.parse(JSON.stringify($mwtnFault.gridOptions));
183
184   $scope.paginationOptions = {
185     pageNumber: 1,
186     pageSize: 25,
187     sort: null
188   };
189
190   $scope.gridOptionsAlarmLog = {
191     paginationPageSizes: [25, 100, 1000, 10000],
192     paginationPageSize: 25,
193     useExternalPagination: true,
194     useExternalSorting: true,
195     enablePaginationControls: false,
196     enableFiltering: true,
197     useExternalFiltering: true,
198     columnDefs : [
199        // { field: 'id', type: 'number', displayName: 'No.',  headerCellClass: $scope.highlightFilteredHeader, width : 50, cellClass: 'number', pinnedLeft : true },
200        { field: 'icon',  type: 'string', displayName: '',  headerCellClass: $scope.highlightFilteredHeader, width: 25, enableSorting: false, enableFiltering:false, cellTemplate: iconCell },
201        { field: 'timestamp',  type: 'string', displayName: 'Timestamp',  headerCellClass: $scope.highlightFilteredHeader, width : 200, sort: {
202        direction: uiGridConstants.DESC,
203        priority: 1
204        } },
205        { field: 'node',  type: 'string', displayName: 'Node name',  headerCellClass: $scope.highlightFilteredHeader, width: 200 },
206        { field: 'counter',  type: 'number', displayName: 'Counter',  headerCellClass: $scope.highlightFilteredHeader, width: 70, cellClass: 'number' },
207        { field: 'object',  type: 'string', displayName: 'Object Id',  headerCellClass: $scope.highlightFilteredHeader, width: 300 },
208        { field: 'problem',  type: 'string', displayName: 'Alarm type',  headerCellClass: $scope.highlightFilteredHeader, width : 200 },
209        { field: 'severity',  type: 'string', displayName: 'Severity',  headerCellClass: $scope.highlightFilteredHeader, width : 150 }
210     ],
211     data: 'data',
212     onRegisterApi: function(gridApi) {
213       $scope.gridApi = gridApi;
214       $scope.gridApi.core.on.filterChanged( $scope, $scope.filter);
215       $scope.gridApi.core.on.sortChanged( $scope, $scope.sortChanged );
216       $scope.sortChanged($scope.gridApi.grid, [ $scope.gridOptionsAlarmLog.columnDefs[1] ] );
217
218       $scope.gridApi.pagination.on.paginationChanged($scope, function (newPage, pageSize) {
219         $scope.paginationOptions.pageNumber = newPage;
220         $scope.paginationOptions.pageSize = pageSize;
221         getPage();
222       });
223     }
224 };
225
226  //stateobject
227  $scope.state={};
228  $scope.state.filter=false;
229  $scope.state.sort=false;
230  $scope.state.lastfilter=null;
231  $scope.state.lastSort=null;
232
233  $scope.maxCount=0; //value shown on screen
234
235  
236  $scope.seekPage= function(page){
237    if(!page){ //catch NaN values
238      page=1;
239      return;
240    }
241      $scope.gridApi.pagination.seek(parseInt(page));
242  };
243
244  $scope.paginationStatusMessage = function() {
245    
246    var startnum=($scope.paginationOptions.pageNumber-1)*$scope.paginationOptions.pageSize+1;
247    var pagenednum=($scope.paginationOptions.pageNumber-1)*$scope.paginationOptions.pageSize+1+$scope.data.length;
248    if(pagenednum>$scope.gridOptionsAlarmLog.totalItems) pagenednum=pagenednum-1; //reduce by initial added 1
249    
250    if($scope.state.filter){
251      var filterTpl = 'Showing {0} to {1} of {2} items (filtered from {3} total items)';
252      return filterTpl.format(startnum, pagenednum, $scope.gridOptionsAlarmLog.totalItems, $scope.maxCount);
253
254    } else {
255      var defaultTpl = 'Showing {0} to {1} of {2} total items';
256      return defaultTpl.format( startnum, pagenednum, $scope.maxCount);
257    }
258  };
259
260 //list visible on screen
261  $scope.data = [];
262
263  var getPage = function() {
264     //from, how many, sort, filter
265     getData(($scope.gridOptionsAlarmLog.paginationCurrentPage-1)*$scope.paginationOptions.pageSize, $scope.paginationOptions.pageSize,$scope.state.lastSort,$scope.state.lastfilter)
266     .then(function (data) {
267       $scope.gridOptionsAlarmLog.totalItems = data.data.hits.total;
268       processResponseRecreateList(data);
269     });
270   };
271
272   //filter 
273   $scope.filter = function()
274   {
275      var grid = this.grid;
276      var columns=[];
277
278      //get all columns where data was typed in
279      angular.forEach(grid.columns, function(value, key) {
280         if(value.filters[0].term) {
281              var col=findColumn(value.displayName);
282              if(col==="fault.timeStamp"){
283                 //convert timestamp to db format
284                 var timestamp= $mwtnFault.TimeStampToONFFormat(value.filters[0].term);
285                 columns.push({ column: col ,value: timestamp });
286              }
287              else
288                 columns.push({ column: col ,value: value.filters[0].term }); //create column object
289           }
290     });
291
292   if(columns.length === 0){ //all filter data cleared away
293       $scope.state.filter=false;
294       $scope.state.lastfilter=null;
295
296       //get unfiltered data
297       getData(($scope.gridOptionsAlarmLog.paginationCurrentPage-1)*$scope.paginationOptions.pageSize,$scope.paginationOptions.pageSize,$scope.state.lastSort,$scope.state.lastfilter).then(function(response) {
298         if (response.data.hits.hits) { 
299                processResponseRecreateList(response);
300               
301             }
302          });
303      
304   }else{
305       //base filter string
306       var filter={"query":{"bool":{"must":[]}}};
307
308       //create filter objects
309       var prefixs=[];
310       for(var obj of columns){
311            var prefixObj={};
312            prefixObj[obj.column]=obj.value;//add  like: {column: "fault.counter", value: "1"} => {"fault.counter":1}
313            prefixs.push({prefix:prefixObj}); // => {"prefix":{...}}
314       }
315
316      //add objects to must property
317      filter.query.bool.must=prefixs;
318     
319     //save filter
320     $scope.state.lastfilter=filter;
321     $scope.state.filter=true;
322      
323     //send data to sdnevents/faultlog/_search
324     getData(($scope.gridOptionsAlarmLog.paginationCurrentPage-1)*$scope.paginationOptions.pageSize,$scope.paginationOptions.pageSize,$scope.state.lastSort,$scope.state.lastfilter).then(function(response) {
325         if (response.data.hits.total>0) { //only, when hits exist
326                 processResponseRecreateList(response);
327                 $scope.gridOptionsAlarmLog.totalItems = response.data.hits.total;
328         }else{
329                //clear data from list
330                 $scope.data=[];
331                  $scope.gridOptionsAlarmLog.totalItems =0;
332                 $scope.state.filter=false;
333                 $scope.state.lastfilter=null;
334         }
335       });
336   }
337 };
338
339   //sort
340
341   $scope.sortChanged=function(grid, sortColumns){    // sortColumns is an array containing just the column sorted in the grid
342
343
344           if(sortColumns.length>0){
345               if(sortColumns[0].sort){
346                 var name = sortColumns[0].displayName; // the name of the column sorted
347                 var direction = sortColumns[0].sort.direction; // the direction of the column sorted: "desc" or "asc"
348                 sort(direction,findColumn(name));
349               }
350           }else{
351               $scope.state.sort=false;
352               $scope.state.lastSort=null;
353
354               //get unsorted data
355               getData(($scope.gridOptionsAlarmLog.paginationCurrentPage-1)*$scope.paginationOptions.pageSize,$scope.paginationOptions.pageSize,$scope.state.lastSort,$scope.state.lastfilter).then(function(response) {
356               if (response.data.hits.hits) { 
357                     processResponseRecreateList(response);
358                 }
359               });
360           }
361   };
362
363   function sort(direction, columnName){
364
365     var sortObj={};
366     var sort = [ sortObj];
367     switch(direction) {
368         case uiGridConstants.ASC:
369              
370              //create sort object
371              sortObj[columnName]={order : 'asc'};
372              sort = [ sortObj];
373              //save last sort
374              $scope.state.lastSort=sort;
375
376              getData(($scope.paginationOptions.pageNumber-1)*$scope.paginationOptions.pageSize,$scope.paginationOptions.pageSize,$scope.state.lastSort,$scope.state.lastfilter).then(function(response) {
377                 if (response.data.hits.hits) {
378                     processResponseRecreateList(response);
379                     $scope.state.sort=true;
380                 }
381               });
382
383           break;
384
385         case uiGridConstants.DESC:
386            
387              sortObj[columnName]={order : 'desc'};
388              sort = [ sortObj];
389              $scope.state.lastSort=sort;
390
391              getData(($scope.paginationOptions.pageNumber-1)*$scope.paginationOptions.pageSize,$scope.paginationOptions.pageSize,$scope.state.lastSort,$scope.state.lastfilter).then(function(response) {
392                  if (response.data.hits.hits) {
393                       processResponseRecreateList(response);
394                        $scope.state.sort=true;
395                    }
396               });
397           break;
398
399         case undefined:
400           
401             $scope.state.sort=false;
402             $scope.state.lastSort=null;
403
404             getData(($scope.gridOptionsAlarmLog.paginationCurrentPage-1)*$scope.paginationOptions.pageSize,$scope.paginationOptions.pageSize,$scope.state.lastSort,$scope.state.lastfilter)
405            .then(function(response) {
406                 if (response.data.hits.hits) {
407                      processResponseRecreateList(response);
408                }
409             });
410
411           break;
412     }
413   }
414
415   var findColumn = function(name) {
416
417     if(name==="Timestamp"){ return "fault.timeStamp"; }
418     else if(name==="Node name"){ return "fault.nodeName"; }
419     else if(name==="Counter"){ return "fault.counter"; }
420     else if(name==="Object Id"){ return "fault.objectId"; }
421     else if(name==="Alarm type"){return "fault.problem"; }
422     else if(name==="Severity"){ return "fault.severity"; }
423
424   };
425
426   var getData = function(from, size, sort, query){
427     if(sort === null){ //default sort value
428       sort = [ { "fault.timeStamp" : {order : 'desc'}}];
429     }
430     if(query === null){ //default filter value
431       query= {match_all: {}};
432     }
433     return $mwtnFault.getFilteredSortedData(from, size, sort, query);
434   };
435
436   var processResponseAddToList=function(response) {
437         if (response.data.hits.hits) {
438                                                 response.data.hits.hits.map(function(entry){
439             var log = {
440               id: entry._id,
441               icon: getIconFromSeverity(entry._source.fault.severity),
442               timestamp: $mwtnFault.formatTimeStamp(entry._source.fault.timeStamp),
443               node: entry._source.fault.nodeName,
444               counter: entry._source.fault.counter,
445               object: entry._source.fault.objectId,
446               problem: entry._source.fault.problem,
447               severity: entry._source.fault.severity,
448           };
449
450          $scope.data.push(log);
451         });
452
453           $scope.gridOptionsAlarmLog.totalItems = response.data.hits.total; // needed by ui-grid to calculate page number, always update!
454           if($scope.maxCount<response.data.hits.total){
455             $scope.maxCount=response.data.hits.total; //only if total is higher (can be lower due to eg filtering)
456           }
457    }};
458
459  function processResponseRecreateList(response){
460             var list=[];
461                                                 response.data.hits.hits.map(function(entry){
462             var log = {
463               id: entry._id,
464               icon: getIconFromSeverity(entry._source.fault.severity),
465               timestamp: $mwtnFault.formatTimeStamp(entry._source.fault.timeStamp),
466               node: entry._source.fault.nodeName,
467               counter: entry._source.fault.counter,
468               object: entry._source.fault.objectId,
469               problem: entry._source.fault.problem,
470               severity: entry._source.fault.severity,
471           };
472
473          list.push(log);
474         });
475       $scope.data=list;
476       $scope.gridOptionsAlarmLog.totalItems = response.data.hits.total; // needed by ui-grid to calculate page number, always update!
477        if($scope.maxCount<response.data.hits.total){
478             $scope.maxCount=response.data.hits.total; //only if total is higher (can be lower due to eg filtering)
479           }
480     }
481
482     $scope.refreshLog = function() {
483      
484       var from =  ($scope.gridOptionsAlarmLog.paginationCurrentPage-1)*$scope.paginationOptions.pageSize;
485       var size = $scope.paginationOptions.pageSize;
486       $scope.processing = true;
487       getData(from, size,$scope.state.lastSort,$scope.state.lastfilter).then(function(logEntries){
488         $scope.processing = false;
489         $scope.spinner.alarmLog = false;
490         processResponseRecreateList(logEntries);
491         
492       }, function(error){
493         $scope.processing = false;
494         $scope.spinner.alarmLog = false;
495         console.error(JSON.stringify(error));
496       });      
497     };
498
499     // [sko] TODO check from here on 
500     $scope.progress = {
501         show: true
502     };
503     
504     $scope.clearLog = function () {
505
506       var modalInstance = $uibModal.open({
507         animation: true,
508         ariaLabelledBy: 'modal-title',
509         ariaDescribedBy: 'modal-body',
510         templateUrl: 'src/app/mwtnFault/templates/clearLogConfirmation.tpl.html',
511         controller: 'ClearFaultLogCtrl',
512         size: 'lg',
513         resolve: {
514           now: function () {
515             var onfDateAndTime = new Date().toISOString().replace(/-/g, '').replace(/T/g, '').replace(/:/g, '').substring(0,16) + 'Z';
516             return {timestamp: onfDateAndTime};
517           }
518         }
519       });
520
521       modalInstance.result.then(function (now) {
522         var spec = {
523           functionId : 'sdnevents',
524           docType : 'faultlog',
525           query: {
526             match_all: {}
527           }
528         };
529         $mwtnFault.deleteDocType(spec).then(function(deleted){
530           //set all to 'null' (empty)
531           $scope.data = [];
532           $scope.maxCount=0;
533           $scope.gridOptionsAlarmLog.totalItems=0;
534
535           $timeout( function() { $scope.refreshLog(); getPage(); }, 1000);
536
537           $mwtnLog.info({component: COMPONENT, message: 'Fault log cleared!'});
538         }, function(error){
539           $mwtnLog.error({component: COMPONENT, message:JSON.stringify(error)});
540         });
541       }, function () {
542         $mwtnLog.info({component: COMPONENT, message: 'Clear fault log dismissed!'});
543       });
544     };    
545
546     
547     // UI events 
548     $scope.status = {currentProblemList: true};
549     $scope.spinner = {currentProblemList: false};
550     $scope.$watch('status', function(status, oldValue) {
551       Object.keys(status).map(function(key){
552         if (status[key] !== oldValue[key]) {
553           $scope.spinner[key] = status[key];
554           
555           switch (key) {
556           case 'currentProblemList':
557             if (status[key]) {
558               $scope.refreshCurrentProblemList();
559             }
560             break;
561           case 'alarmNotifications':
562             $scope.spinner[key] = false;
563             break;
564           case 'alarmLog':
565             $scope.refreshLog();
566             break;
567           default:
568             $mwtnLog.error({component: COMPONENT, message: key + ' is not implemented!'});
569           }
570         }
571       });   
572     }, true);
573
574     // init
575     $scope.refreshCurrentProblemList();
576
577      getPage();
578
579   }]);
580
581   mwtnFaultApp.register.controller('ClearFaultLogCtrl', ['$scope', '$uibModalInstance', '$mwtnFault', 'now',
582                                                     function ($scope, $uibModalInstance, $mwtnFault, now) {
583
584     $scope.now = $mwtnFault.formatTimeStamp(now.timestamp);
585     $scope.processing = false;
586
587     $scope.ok = function () {
588       $uibModalInstance.close(now);
589       $scope.processing = true;
590     };
591
592     $scope.cancel = function () {
593       $uibModalInstance.dismiss();
594     };
595   }]);
596     
597 });