diff options
| -rw-r--r-- | www/js/DataModel.js | 29 | ||||
| -rw-r--r-- | www/js/EventModalCtrl.js | 34 | ||||
| -rw-r--r-- | www/js/LoginCtrl.js | 4 | ||||
| -rw-r--r-- | www/js/MontageCtrl.js | 198 | ||||
| -rw-r--r-- | www/js/app.js | 65 | ||||
| -rw-r--r-- | www/templates/login.html | 8 | ||||
| -rw-r--r-- | www/templates/montage-history.html | 2 | ||||
| -rw-r--r-- | www/templates/montage.html | 7 |
8 files changed, 320 insertions, 27 deletions
diff --git a/www/js/DataModel.js b/www/js/DataModel.js index 02c719ed..6c9b806c 100644 --- a/www/js/DataModel.js +++ b/www/js/DataModel.js @@ -121,6 +121,7 @@ angular.module('zmApp.controllers') 'enableBlog': true, 'use24hr': false, 'packeryPositions': '', + 'currentMontageProfile': '', 'packeryPositionsArray': {}, 'EHpackeryPositions': '', 'packerySizes': '', @@ -133,6 +134,8 @@ angular.module('zmApp.controllers') 'vibrateOnPush': true, 'soundOnPush': true, 'cycleMonitors': false, + 'cycleMontage': false, + 'cycleMontageInterval': 10, // 10sec 'cycleMonitorsInterval': 10, // 10sec 'enableLowBandwidth': false, 'autoSwitchBandwidth': false, @@ -262,8 +265,11 @@ angular.module('zmApp.controllers') var positionsStr = loginData.packeryPositions; //console.log ("positionStr="+positionsStr); var positions = {}; - if (loginData.packeryPositions != '') + if (loginData.packeryPositions != '' && loginData.packeryPositions != undefined) { + console.log ("positions="+loginData.packeryPositions); + + positions = JSON.parse(positionsStr); for (var m = 0; m < monitors.length; m++) { @@ -861,6 +867,20 @@ angular.module('zmApp.controllers') } + if (typeof loginData.cycleMontage == 'undefined') + { + + loginData.cycleMontage = false; + + } + + if (typeof loginData.cycleMontageInterval == 'undefined') + { + + loginData.cycleMontageInterval = 10; + + } + if (typeof loginData.enableLowBandwidth == 'undefined') { @@ -908,6 +928,13 @@ angular.module('zmApp.controllers') } + if (typeof loginData.currentMontageProfile == 'undefined') + { + + loginData.currentMontageProfile = ''; + + } + if (typeof loginData.followTimeLine == 'undefined') { diff --git a/www/js/EventModalCtrl.js b/www/js/EventModalCtrl.js index c1633d1f..4b15e997 100644 --- a/www/js/EventModalCtrl.js +++ b/www/js/EventModalCtrl.js @@ -609,7 +609,7 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro // console.log ("DUMPING " + JSON.stringify(event)); $scope.mycarousel.index = myFrame; // console.log ("STEP 1 : Computed index as "+ $scope.mycarousel.index); - var i; + var i, p = 0; for (i = 1; i <= event.Frame.length; i++) { var fname = padToN(event.Frame[i - 1].FrameId, eventImageDigits) + "-capture.jpg"; @@ -621,6 +621,7 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro { if (event.Frame[i - 1] && event.Frame[i - 1].Type == 'Alarm') { + p++; $scope.slides.push( { id: event.Frame[i - 1].FrameId, @@ -631,15 +632,41 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro } else // push all frames { + //now handle bulk frames pushing before pushing this one + if (event.Frame[i-1].Type == 'Bulk') + { + var f1 = parseInt(event.Frame[i-2].FrameId); + var f2 = parseInt(event.Frame[i-1].FrameId); + + //console.log ("Filling in bulk from:"+f1+" to "+(f2-1)); + for (var bulk=f1+1; bulk < f2; bulk++) + { + //console.log ("Storing bulk:"+bulk); + var bfname = padToN(bulk, eventImageDigits) + "-capture.jpg"; + p++; + $scope.slides.push({ + id: bulk, + img: bfname + + }); + + + } + } + //console.log ("storing: "+event.Frame[i - 1].FrameId); + p++; $scope.slides.push( { id: event.Frame[i - 1].FrameId, img: fname, }); - //console.log ("PUSHED " + fname); + + + } } + //console.log ("I PUSHED:" + p+" BUT SLIDE LENGHT BEFORE DISPLAY:"+$scope.slides.length); // console.log ("STEP 2 : calling Save Event To Phone"); $ionicLoading.hide(); saveEventImageToPhone(onlyAlarms); @@ -669,8 +696,10 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro } + // don't think this is used anymore function saveEventImageToPhone(onlyAlarms) { + // console.log ("________________UNUSED?_______________________"); var curState = carouselUtils.getStop(); carouselUtils.setStop(true); @@ -688,6 +717,7 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro $scope.selectEventUrl = url; $scope.slideIndex = $scope.mycarousel.index; $scope.slideLastIndex = $scope.slides.length - 1; + console.log ("FRAMES LENGTH IS " +$scope.slideLastIndex ); // console.log ("URL TO DISPLAY " + url); diff --git a/www/js/LoginCtrl.js b/www/js/LoginCtrl.js index 59b7ad2d..5424dbd4 100644 --- a/www/js/LoginCtrl.js +++ b/www/js/LoginCtrl.js @@ -773,6 +773,10 @@ angular.module('zmApp.controllers').controller('zmApp.LoginCtrl', ['$scope', '$r }); } + else // make sure CGI error is always shown + { + NVRDataModel.displayBanner((status < 500)? 'error':'info', [loginStatus]); + } NVRDataModel.debug("refreshing API version..."); NVRDataModel.getAPIversion() .then(function(data) diff --git a/www/js/MontageCtrl.js b/www/js/MontageCtrl.js index 8a8209df..43c72b4c 100644 --- a/www/js/MontageCtrl.js +++ b/www/js/MontageCtrl.js @@ -13,6 +13,7 @@ angular.module('zmApp.controllers') var intervalHandleMontage; // image re-load handler var intervalHandleAlarmStatus; // status of each alarm state + var intervalHandleMontageCycle; var gridcontainer; var pckry, draggie; @@ -24,6 +25,8 @@ angular.module('zmApp.controllers') var ld; var refreshSec; + + //-------------------------------------------------------------------------------------- // Handles bandwidth change, if required // @@ -45,12 +48,21 @@ angular.module('zmApp.controllers') NVRDataModel.displayBanner('net', [ds]); var ld = NVRDataModel.getLogin(); refreshSec = (NVRDataModel.getBandwidth() == 'lowbw') ? ld.refreshSecLowBW : ld.refreshSec; + $interval.cancel(intervalHandleMontage); + $interval.cancel(intervalHandleMontageCycle); + + intervalHandleMontage = $interval(function() { loadNotifications(); }.bind(this), refreshSec * 1000); + intervalHandleMontageCycle = $interval(function() + { + cycleMontageProfiles(); + }.bind(this), NVRDataModel.getLogin().cycleMontageInterval* 1000); + if (NVRDataModel.getBandwidth() == 'lowbw') { NVRDataModel.debug("Enabling low bandwidth parameters"); @@ -126,7 +138,7 @@ angular.module('zmApp.controllers') var positionsStr = ld.packeryPositions; var positions = {}; - if (positionsStr == '') + if (positionsStr == '' || positionsStr == undefined) { NVRDataModel.log("Did NOT find a packery layout"); layouttype = true; @@ -338,6 +350,70 @@ angular.module('zmApp.controllers') return attr; }; + + function findNext (key,obj) + { + + var keys = Object.keys(obj); + return keys[(keys.indexOf(key) + 1) % keys.length]; + + /* var size = Object.keys(obj).length; + var i; + for (i=0; i<size; i++) + { + if (Object.keys(obj)[i] == key) + break; + } + i = (i + 1) % size; + return Object.keys(obj)[i];*/ + + } + + //---------------------------------------------- + // cycle profiles + //----------------------------------------------- + + function cycleMontageProfiles() + { + + var ld = NVRDataModel.getLogin(); + + if (!ld.cycleMontageProfiles) + { + // NVRDataModel.debug ("cycling disabled"); + return; + + } + + if ($scope.reOrderActive) + { + NVRDataModel.debug ("not cycling, re-order in progress"); + return; + } + + if ($scope.isDragabillyOn) + { + NVRDataModel.debug ("not cycling, edit in progress"); + return; + + } + + var nextProfile = findNext(ld.currentMontageProfile, ld.packeryPositionsArray); + + if (nextProfile == ld.currentMontageProfile) + { + NVRDataModel.debug ("Not cycling profiles, looks like you only have one"); + } + else + { + NVRDataModel.debug ("Cycling profile from: "+ld.currentMontageProfile+" to:"+nextProfile); + switchMontageProfile(nextProfile); + + } + + + } + //----------------------------------------------------------------------- // cycle through all displayed monitors and check alarm status //----------------------------------------------------------------------- @@ -499,6 +575,22 @@ angular.module('zmApp.controllers') }; + $scope.getCycleStatus = function() + { + var c = NVRDataModel.getLogin().cycleMontageProfiles; + var str = (c) ? $translate.instant('kOn'):$translate.instant('kOff'); + return str; + }; + + $scope.toggleCycle = function() + { + var ld = NVRDataModel.getLogin(); + ld.cycleMontageProfiles = !ld.cycleMontageProfiles; + NVRDataModel.setLogin(ld); + NVRDataModel.debug ("cycle="+ld.cycleMontageProfiles); + + }; + $scope.toggleHide = function(i) { @@ -522,15 +614,29 @@ angular.module('zmApp.controllers') $ionicModal.fromTemplateUrl('templates/reorder-modal.html', { scope: $scope, - animation: 'slide-in-up' + animation: 'slide-in-up', + id:'reorder', }) .then(function(modal) { $scope.modal = modal; + $scope.reOrderActive = true; $scope.modal.show(); }); }; + + $scope.$on('modal.removed', function(e, m) + { + + if (m.id != 'reorder') + return; + $scope.reOrderActive = false; + + //console.log ("************** FOOTAGE CLOSED"); + + }); + /* $scope.closeReorderModal = function () { @@ -611,6 +717,7 @@ angular.module('zmApp.controllers') ionic.Platform.fullScreen($scope.minimal, !$scope.minimal); //console.log ("alarms:Cancelling timer"); $interval.cancel(intervalHandleMontage); + $interval.cancel(intervalHandleMontageCycle); $interval.cancel(intervalHandleAlarmStatus); if (!$rootScope.isAlarm) @@ -656,6 +763,7 @@ angular.module('zmApp.controllers') ionic.Platform.fullScreen($scope.minimal, !$scope.minimal); //console.log ("minimal switch:Cancelling timer"); $interval.cancel(intervalHandleMontage); //we will renew on reload + $interval.cancel(intervalHandleMontageCycle); $interval.cancel(intervalHandleAlarmStatus); // We are reloading this view, so we don't want entry animations $ionicHistory.nextViewOptions( @@ -876,6 +984,7 @@ angular.module('zmApp.controllers') // NVRDataModel.log("Starting Modal timer"); //console.log ("openModal:Cancelling timer"); $interval.cancel(intervalHandleMontage); + $interval.cancel(intervalHandleMontageCycle); $interval.cancel(intervalHandleAlarmStatus); $scope.monitor = monitor; @@ -909,7 +1018,8 @@ angular.module('zmApp.controllers') $ionicModal.fromTemplateUrl('templates/monitors-modal.html', { scope: $scope, - animation: 'slide-in-up' + animation: 'slide-in-up', + id: 'monitorsmodal' }) .then(function(modal) @@ -954,6 +1064,7 @@ angular.module('zmApp.controllers') // console.log ("closeModal: Cancelling timer"); $interval.cancel(intervalHandleMontage); $interval.cancel(intervalHandleAlarmStatus); + $interval.cancel(intervalHandleMontageCycle); intervalHandleMontage = $interval(function() { @@ -967,6 +1078,13 @@ angular.module('zmApp.controllers') // console.log ("Refreshing Image..."); }.bind(this), 5000); + intervalHandleMontageCycle = $interval(function() + { + cycleMontageProfiles(); + // console.log ("Refreshing Image..."); + }.bind(this), 5000); + + // $timeout (function() {pckry.shiftLayout();},zm.packeryTimer); } @@ -992,6 +1110,7 @@ angular.module('zmApp.controllers') { NVRDataModel.debug("MontageCtrl: onpause called"); $interval.cancel(intervalHandleMontage); + $interval.cancel(intervalHandleMontageCycle); $interval.cancel(intervalHandleAlarmStatus); // $interval.cancel(modalIntervalHandle); @@ -1099,12 +1218,52 @@ angular.module('zmApp.controllers') delete posArray[$scope.data.selectedVal]; var ld = NVRDataModel.getLogin(); ld.packeryPositionsArray = posArray; + + if (ld.currentMontageProfile == $scope.data.selectedVal) + { + ld.currentMontageProfile = ""; + + } + + if ($scope.currentMontageProfile == $scope.data.selectedVal) + $scope.currentProfileName = $translate.instant('kMontage'); + NVRDataModel.setLogin(ld); }); }; + + function switchMontageProfile (mName) + { + $interval.cancel(intervalHandleMontageCycle); + intervalHandleMontageCycle = $interval(function() + { + cycleMontageProfiles(); + // console.log ("Refreshing Image..."); + }.bind(this), NVRDataModel.getLogin().cycleMontageInterval* 1000); + + + //console.log ("SELECTED " + $scope.data.selectedVal); + var ld = NVRDataModel.getLogin(); + //console.log ("OLD POS="+ld.packeryPositions); + ld.packeryPositions = ld.packeryPositionsArray[mName]; + ld.currentMontageProfile = mName; + $scope.currentProfileName =mName; + //console.log ("NEW POS="+ld.packeryPositions); + NVRDataModel.setLogin(ld); + //console.log ("SAVING "+ld.packeryPositions.name+ " but "+$scope.data.selectedVal); + NVRDataModel.reloadMonitorDisplayStatus(); + draggies.forEach(function(drag) + { + drag.destroy(); + }); + draggies = []; + pckry.destroy(); + initPackery(); + + } // switch to another montage profile $scope.switchMontageProfile = function() { @@ -1168,20 +1327,11 @@ angular.module('zmApp.controllers') { if (res) { - //console.log ("SELECTED " + $scope.data.selectedVal); - var ld = NVRDataModel.getLogin(); - //console.log ("OLD POS="+ld.packeryPositions); - ld.packeryPositions = ld.packeryPositionsArray[$scope.data.selectedVal]; - //console.log ("NEW POS="+ld.packeryPositions); - NVRDataModel.setLogin(ld); - NVRDataModel.reloadMonitorDisplayStatus(); - draggies.forEach(function(drag) - { - drag.destroy(); - }); - draggies = []; - pckry.destroy(); - initPackery(); + // destroy cycle timer and redo it + // + switchMontageProfile($scope.data.selectedVal); + + //pckry.reloadItems(); } @@ -1217,7 +1367,9 @@ angular.module('zmApp.controllers') var pos = JSON.stringify(pckry.getShiftPositions('data-item-id')); ld.packeryPositionsArray[$scope.data.montageName] = pos; NVRDataModel.debug("Saving " + $scope.data.montageName + " with:" + pos); + ld.currentMontageProfile =$scope.data.montageName ; NVRDataModel.setLogin(ld); + $scope.currentProfileName = $scope.data.montageName; } } @@ -1270,6 +1422,7 @@ angular.module('zmApp.controllers') NVRDataModel.debug("Setting image mode to snapshot, will change to image when packery is all done"); $scope.areImagesLoading = true; $scope.isDragabillyOn = false; + $scope.reOrderActive = false; if (NVRDataModel.isTzSupported()) $scope.iconTimeNow = 'server'; @@ -1306,6 +1459,7 @@ angular.module('zmApp.controllers') sizeInProgress = false; $scope.imageStyle = true; intervalHandleMontage = ""; + intervalHandleMontageCycle = ""; $scope.isModalActive = false; $scope.isReorder = false; @@ -1322,6 +1476,7 @@ angular.module('zmApp.controllers') NVRDataModel.setAwake(NVRDataModel.getKeepAwake()); $interval.cancel(intervalHandleMontage); + $interval.cancel(intervalHandleMontageCycle); $interval.cancel(intervalHandleAlarmStatus); intervalHandleMontage = $interval(function() @@ -1330,6 +1485,12 @@ angular.module('zmApp.controllers') // console.log ("Refreshing Image..."); }.bind(this), refreshSec * 1000); + intervalHandleMontageCycle = $interval(function() + { + cycleMontageProfiles(); + // console.log ("Refreshing Image..."); + }.bind(this), NVRDataModel.getLogin().cycleMontageInterval* 1000); + intervalHandleAlarmStatus = $interval(function() { loadAlarmStatus(); @@ -1425,6 +1586,7 @@ angular.module('zmApp.controllers') //console.log ("beforeLeave:Cancelling timer"); $interval.cancel(intervalHandleMontage); + $interval.cancel(intervalHandleMontageCycle); $interval.cancel(intervalHandleAlarmStatus); pckry.destroy(); window.removeEventListener("resize", orientationChanged, false); @@ -1659,6 +1821,8 @@ angular.module('zmApp.controllers') // $rootScope.rand = Math.floor((Math.random() * 100000) + 1); }); + $scope.currentProfileName = NVRDataModel.getLogin().currentMontageProfile || $translate.instant ('kMontage'); + $scope.reloadView = function() { $rootScope.rand = Math.floor((Math.random() * 100000) + 1); diff --git a/www/js/app.js b/www/js/app.js index dd8a16cc..359343ff 100644 --- a/www/js/app.js +++ b/www/js/app.js @@ -140,7 +140,7 @@ angular.module('zmApp', [ angular.forEach(input, function(item) { - if ((item.Monitor.Function != 'None') && (item.Monitor.Enabled != '0') && (item.Monitor.eventUrl != 'img/noevent.png')) + if ((item.Monitor.Function != 'None') && (item.Monitor.Enabled != '0') && (item.Monitor.eventUrl != 'img/noevent.png') && (item.Monitor.listDisplay != 'noshow')) { out.push(item); } @@ -152,6 +152,69 @@ angular.module('zmApp', [ }) + +//credit: http://stackoverflow.com/a/23931217/1361529 +.directive('hidepassword', function () { + + var modelSet = function (str) + { + + return str; + }; + + var viewSet = function (str) + { + //https://github.com/garycourt/uri-js + if (!str) return str; + var c = URI.parse(str); + //if (c.userinfo) c.userinfo="***:***"; + if (c.userinfo) c.userinfo="\u2022\u2022\u2022:\u2022\u2022\u2022"; + + var ostr = ""; + if (c.scheme) ostr = ostr+c.scheme+"://"; + if (c.userinfo) ostr = ostr+c.userinfo+"@"; + if (c.host) ostr = ostr+c.host; + if (c.port) ostr = ostr+":"+c.port; + if (c.path) ostr = ostr+c.path; + if (c.query) ostr = ostr+c.query; + if (c.fragment) ostr = ostr+c.fragment; + + + /*var vc = URI.serialize({scheme : c.scheme, + userinfo: c.userinfo, + host: c.host, + port: c.port, + path: c.path, + query: c.query, + fragment: c.fragment + },{unicodeSupport:true});*/ + // console.log ("CONVERTED IS "+vc); + + + return ostr; + }; + + return { + + restrict: 'A', + require: 'ngModel', + link: function (scope, element, attr, ngModel) { + ngModel.$parsers.push(modelSet); + ngModel.$formatters.push(viewSet); + + element.bind('blur', function() { + element.val(viewSet(ngModel.$modelValue)); + }); + element.bind('focus', function () { + element.val(ngModel.$modelValue); + }); + + } + }; +}) + + + // credit https://gist.github.com/Zren/beaafd64f395e23f4604 .directive('mouseWheelScroll', function($timeout) diff --git a/www/templates/login.html b/www/templates/login.html index 9372aae0..f351016a 100644 --- a/www/templates/login.html +++ b/www/templates/login.html @@ -33,7 +33,7 @@ <div ng-if="check.isUseAuth"> <label class="item item-input item-floating-label"> <span class="input-label">{{'kUserName'|translate}}</span> - <input autocapitalize="none" autocomplete="off" autocorrect="off" type="text" placeholder="username" ng-model="loginData.username"> + <input autocapitalize="none" autocomplete="off" autocorrect="off" type="text" placeholder="username" ng-model="loginData.username"> </label> <label class="item item-input item-floating-label"> <span class="input-label">{{'kPassword' | translate}}</span> @@ -43,18 +43,18 @@ </div> <label class="item item-input item-floating-label"> <span class="input-label">{{'kPortalUrl' | translate}}</span> - <input autocapitalize="none" autocomplete="off" autocorrect="off" type="text" placeholder="ZM portal url " ng-model="loginData.url" ng-keyup="portalKeypress($event)"> + <input hidepassword autocapitalize="none" autocomplete="off" autocorrect="off" type="text" placeholder="ZM portal url " ng-model="loginData.url" ng-keyup="portalKeypress($event)"> </label> <!--<button class="button button-small button-clear icon-left ion-wand" ng-click="detectCgi()">tap here to discover cgi-bin </button>--> <label class="item item-input item-floating-label"> <!--<span style="float:right;margin-top:-7px;background-color:#6d0909;color:#fff;font-size:14px;opacity:0.7;width:90px;border-radius: 0px 0px 5px 5px;" on-tap="detectCgi();"> <i class="ion-wand"></i>discover</span>--> <span class="input-label">{{'kPathToCgi' | translate}}</span> - <input autocapitalize="none" autocomplete="off" autocorrect="off" type="text" placeholder="eg. server.com/zm/cgi-bin" ng-model="loginData.streamingurl"> + <input hidepassword autocapitalize="none" autocomplete="off" autocorrect="off" type="text" placeholder="eg. server.com/zm/cgi-bin" ng-model="loginData.streamingurl"> </label> <label class="item item-input item-floating-label"> <span class="input-label">{{'kApiUrl' | translate}}</span> - <input autocapitalize="none" autocomplete="off" autocorrect="off" type="text" placeholder="ZM api url" ng-model="loginData.apiurl"> + <input hidepassword autocapitalize="none" autocomplete="off" autocorrect="off" type="text" placeholder="ZM api url" ng-model="loginData.apiurl"> </label> <a class="item item-icon-right" href="" ng-click="selectFallback()"> <i class="icon ion-ios-arrow-right"> diff --git a/www/templates/montage-history.html b/www/templates/montage-history.html index da7b5974..8888cc1d 100644 --- a/www/templates/montage-history.html +++ b/www/templates/montage-history.html @@ -21,7 +21,7 @@ <div ng-if="$root.authSession!='undefined'"> <div ng-if = "monitor.Monitor.eventUrl == 'img/noevent.png' "> <!-- make sure we don't use id here - -- or we lose the handle for cleanup forever!--> + or we lose the handle for cleanup forever!--> <div class="grid-item grid-item-{{monitor.Monitor.gridScale}} " data-item-id="{{monitor.Monitor.Id}}" data-item-size="{{monitor.Monitor.gridScale}}" data-item-listdisplay="{{monitor.Monitor.listDisplay}}" > <figure height="{{Monitor.monitor.height}}" width="{{Monitor.monitor.width}}" class="{{dragBorder}}" ng-show=" monitor.Monitor.listDisplay!='noshow'"> <img class="{{monitor.Monitor.selectStyle}}" image-spinner-src="{{monitor.Monitor.eventUrl}}" image-spinner-loader="lines" on-tap="!isDragabillyOn?noop():toggleSelectItem($index)" > diff --git a/www/templates/montage.html b/www/templates/montage.html index e8ff5337..3f17116a 100644 --- a/www/templates/montage.html +++ b/www/templates/montage.html @@ -1,4 +1,5 @@ -<ion-view view-title="{{'kMontage' | translate}}" cache-view="false" hide-nav-bar="{{minimal}}"> +<ion-view cache-view="false" hide-nav-bar="{{minimal}}"> + <ion-nav-title>{{currentProfileName}}</ion-nav-title> <ion-nav-buttons side="left"> <button class="button button-icon button-clear ion-navicon" ng-click="openMenu()"></button> <button class="button button-icon button-clear ion-eye" ng-click="hideUnhide();"> @@ -34,6 +35,10 @@ <li> <a href="" ng-click="sliderChanged(-1)"> <i class="ion-minus-circled"></i></a> </li> + + <li ng-if="!isDragabillyOn"> + <a href="" ng-click="toggleCycle()"> <i class="ion-android-bicycle"></i>:{{getCycleStatus()}}</a> + </li> <li ng-if="isDragabillyOn"> <a href="" ng-click="hideMonitor(monitor.Monitor.Id)"> <i class="ion-close-circled"></i></a> |
