Index: branches/WebJobManager/HeuristicLab.Clients.Hive.WebJobManager/wwwroot/css/site.min.css
===================================================================
--- branches/WebJobManager/HeuristicLab.Clients.Hive.WebJobManager/wwwroot/css/site.min.css	(revision 13775)
+++ branches/WebJobManager/HeuristicLab.Clients.Hive.WebJobManager/wwwroot/css/site.min.css	(revision 13782)
@@ -1,3 +1,3 @@
-@import url(http://fonts.googleapis.com/css?family=Roboto:400);.wrapper,h4{text-align:center}.label,sub,sup{vertical-align:baseline}[role=button],div[data-tree-model] li i,div[data-tree-model] li span{cursor:pointer}.fc table,table{border-spacing:0}.btn-group>.btn-group,.btn-toolbar .btn,.btn-toolbar .btn-group,.btn-toolbar .input-group,.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9,.dropdown-menu{float:left}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse,.pre-scrollable{max-height:340px}.fa,.glyphicon{-moz-osx-font-smoothing:grayscale}body{-webkit-font-smoothing:antialiased;font:400 14px Roboto,arial,sans-serif}.container{padding:25px;position:fixed}.form-login{background-color:#EDEDED;border-radius:15px;border-color:#d2d2d2;border-width:5px;box-shadow:0 1px 0 #cfcfcf;padding:10px 20px 20px;padding:10px 20px 20px}h4{border:0 solid #fff;border-bottom-width:1px;padding-bottom:10px}.panel-warning>.panel-heading{background-image:linear-gradient(to bottom,#eb9114 0,#f1b25b 100%)!important;color:#fff!important}.panel-danger>.panel-heading{background-image:linear-gradient(to bottom,#c12e2a 0,#d9534f 100%)!important;color:#fff!important}.label-as-badge{border-radius:1em}.bar-off{fill:#c2c2d6}.bar-off:hover{fill:#e0e0eb}.bar-wait{fill:#f0a742}.bar-wait:hover{fill:#f4bd71}.bar-trans{fill:#80d4ff}.bar-trans:hover{fill:#9df}.bar-calc{fill:#2f6fa6}.bar-calc:hover{fill:#3884c7}.bar-paus{fill:#47476b}.bar-paus:hover{fill:#5c5c8a}.bar-fin{fill:#5cb85c}.bar-fin:hover{fill:#71c171}.bar-abo{fill:#c2302c}.bar-abo:hover{fill:#d54944}.bar-fail{fill:#c2302c}.bar-fail:hover{fill:#d54944}rect.selection{stroke:gray;stroke-dasharray:4px;stroke-opacity:.5;fill:transparent}svg ::selection{background:0 0}svg ::-moz-selection{background:0 0}svg ::-webkit-selection{background:0 0}.btn-danger:focus,.btn-danger:hover,.btn-default:focus,.btn-default:hover,.btn-info:focus,.btn-info:hover,.btn-primary:focus,.btn-primary:hover,.btn-success:focus,.btn-success:hover,.btn-warning:focus,.btn-warning:hover{background-position:0 -15px}div[data-tree-model] li .changed{background-color:#ff0;font-weight:700;padding:1px 5px}div[data-tree-model] li .loaded{text-decoration:underline;font-style:oblique}div[data-angular-treeview]{-moz-user-select:-moz-none;-khtml-user-select:none;-webkit-user-select:none;-ms-user-select:none;user-select:none;font-family:Tahoma;font-size:13px;color:#555;text-decoration:none}div[data-tree-model] ul{margin:0;padding:0;list-style:none;border:none;overflow:hidden}div[data-tree-model] li{position:relative;padding:0 0 0 20px;line-height:20px}div[data-tree-model] li .expanded{padding:1px 10px;background-image:url(../img/folder.png);background-repeat:no-repeat}div[data-tree-model] li .collapsed{padding:1px 10px;background-image:url(../img/folder-closed.png);background-repeat:no-repeat}div[data-tree-model] li .normal{padding:1px 10px;background-image:url(../img/file.png);background-repeat:no-repeat}div[data-tree-model] li .selected{background-color:#adf;font-weight:700;padding:1px 5px}/*!
+@import url(http://fonts.googleapis.com/css?family=Roboto:400);.wrapper,h4{text-align:center}.label,sub,sup{vertical-align:baseline}[role=button],div[data-tree-model] li i,div[data-tree-model] li span{cursor:pointer}.fc table,table{border-spacing:0}.btn-group>.btn-group,.btn-toolbar .btn,.btn-toolbar .btn-group,.btn-toolbar .input-group,.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9,.dropdown-menu{float:left}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse,.pre-scrollable{max-height:340px}.fa,.glyphicon{-moz-osx-font-smoothing:grayscale}body{-webkit-font-smoothing:antialiased;font:400 14px Roboto,arial,sans-serif}.container{padding:25px;position:fixed}.form-login{background-color:#EDEDED;border-radius:15px;border-color:#d2d2d2;border-width:5px;box-shadow:0 1px 0 #cfcfcf;padding:10px 20px 20px;padding:10px 20px 20px}h4{border:0 solid #fff;border-bottom-width:1px;padding-bottom:10px}.panel-warning>.panel-heading{background-image:linear-gradient(to bottom,#eb9114 0,#f1b25b 100%)!important;color:#fff!important}.panel-danger>.panel-heading{background-image:linear-gradient(to bottom,#c12e2a 0,#d9534f 100%)!important;color:#fff!important}.label-as-badge{border-radius:1em}.bar-off{fill:#c2c2d6}.bar-off:hover{fill:#e0e0eb}.bar-wait{fill:#f0a742}.bar-wait:hover{fill:#f4bd71}.bar-trans{fill:#80d4ff}.bar-trans:hover{fill:#9df}.bar-calc{fill:#2f6fa6}.bar-calc:hover{fill:#3884c7}.bar-paus{fill:#47476b}.bar-paus:hover{fill:#5c5c8a}.bar-fin{fill:#5cb85c}.bar-fin:hover{fill:#71c171}.bar-abo{fill:#c2302c}.bar-abo:hover{fill:#d54944}.bar-fail{fill:#c2302c}.bar-fail:hover{fill:#d54944}rect.selection{stroke:gray;stroke-dasharray:4px;stroke-opacity:.5;fill:transparent}svg ::selection{background:0 0}svg ::-moz-selection{background:0 0}svg ::-webkit-selection{background:0 0}.btn-danger:focus,.btn-danger:hover,.btn-default:focus,.btn-default:hover,.btn-info:focus,.btn-info:hover,.btn-primary:focus,.btn-primary:hover,.btn-success:focus,.btn-success:hover,.btn-warning:focus,.btn-warning:hover{background-position:0 -15px}div[data-tree-model] li .changed{background-color:#ff0;font-weight:700;padding:1px 5px}div[data-tree-model] li .loaded{text-decoration:underline;font-style:oblique}[animate-on-change]{transition:all 1s;-webkit-transition:all 1s}[animate-on-change].changed{background-color:#add8e6;transition:none;-webkit-transition:none}[animate-on-change].changedshut{background-color:#ffa07a;transition:none;-webkit-transition:none}div[data-angular-treeview]{-moz-user-select:-moz-none;-khtml-user-select:none;-webkit-user-select:none;-ms-user-select:none;user-select:none;font-family:Tahoma;font-size:13px;color:#555;text-decoration:none}div[data-tree-model] ul{margin:0;padding:0;list-style:none;border:none;overflow:hidden}div[data-tree-model] li{position:relative;padding:0 0 0 20px;line-height:20px}div[data-tree-model] li .expanded{padding:1px 10px;background-image:url(../img/folder.png);background-repeat:no-repeat}div[data-tree-model] li .collapsed{padding:1px 10px;background-image:url(../img/folder-closed.png);background-repeat:no-repeat}div[data-tree-model] li .normal{padding:1px 10px;background-image:url(../img/file.png);background-repeat:no-repeat}div[data-tree-model] li .selected{background-color:#adf;font-weight:700;padding:1px 5px}/*!
  * Bootstrap v3.3.6 (http://getbootstrap.com)
  * Copyright 2011-2015 Twitter, Inc.
Index: branches/WebJobManager/HeuristicLab.Clients.Hive.WebJobManager/wwwroot/js/hubs/calendarhubber.js
===================================================================
--- branches/WebJobManager/HeuristicLab.Clients.Hive.WebJobManager/wwwroot/js/hubs/calendarhubber.js	(revision 13775)
+++ branches/WebJobManager/HeuristicLab.Clients.Hive.WebJobManager/wwwroot/js/hubs/calendarhubber.js	(revision 13782)
@@ -15,5 +15,6 @@
                vm.currentcal = [];
                vm.selectedEventId = -1;
-
+               vm.groups = [];
+               vm.clients = [];
                vm.init = function () {
 
@@ -33,11 +34,18 @@
                    };
                    hubber.client.savingCurrentDone = function () {
+                       vm.calendarSaver = false;
                        $scope.clearCurrentCalendar();
                        $scope.$apply();
                    };
                    hubber.client.savingAllDone = function () {
+                       vm.calendarSaver = false;
                        clearAllCalendarsFunc();
                        $scope.$apply();
                    };
+                   hubber.client.processDispose = function (disp) {
+                       vm.treeview.currentNode.IsDisposable = disp;
+                       $scope.calendarDispose = false;
+                       $scope.$apply();
+                   }
                    hubber.client.processDowntime = function (id, down) {
                        var json = JSON.parse(down);
@@ -83,5 +91,5 @@
                        $(".selected.ng-binding").addClass('loaded');
                        $scope.selectedEventId = -1;
-                       if ($scope.treeview.currentNode != null) {
+                       if ($scope.treeview.currentNode != null && $scope.treeview.currentNode.Id != undefined) {
                            if ($scope.treeview.currentNode.calendar.length === 0) {
                                hubber.server.requestDownTime(vm.treeview.currentNode.Id);
@@ -98,4 +106,11 @@
 
                    });
+               }
+               $scope.clearTreeSelect = function () {
+                   if (vm.treeview.currentNode != undefined) {
+                       vm.treeview.currentNode.selected = undefined;
+                       vm.treeview.currentNode = undefined;
+                       vm.selectedEventId = -1;
+                   }
                }
                $scope.buildTree = function () {
@@ -103,15 +118,30 @@
                    vm.temptree = [];
                    vm.top = false;
+                   var ungrouped = {
+                       children: [],
+                       Name: 'Ungrouped'
+                   }
                    for (; vm.data.length > 0;) {
 
-                       if (vm.data[0].ParentResourceId == null) {
+                       if (vm.data[0].ParentResourceId == null && vm.data[0].IsDisposable !== undefined) {
                            var curr = $scope.seekChildren(vm.data.splice(0, 1)[0]);
+                           vm.clients.push(curr);
+                           ungrouped.children.push(curr);
+                       }
+                       else if (vm.data[0].ParentResourceId == null) {
+                           var curr = $scope.seekChildren(vm.data.splice(0, 1)[0]);
+                           vm.groups.push(curr);
                            vm.tree.push(curr);
                        }
                        else {
                            var curr = $scope.seekChildren(vm.data.splice(0, 1)[0]);
+                           if (curr.IsDisposable !== undefined)
+                               vm.clients.push(curr);
+                           else
+                               vm.groups.push(curr);
                            vm.temptree.push(curr);
                        }
                    }
+                   vm.tree.push(ungrouped);
 
                };
@@ -134,4 +164,8 @@
                    for (var t = 0; t < vm.data.length;) {
                        if (current.Id == vm.data[t].ParentResourceId) {
+                           if (vm.data[t].IsDisposable !== undefined)
+                               vm.clients.push(vm.data[t]);
+                           else
+                               vm.groups.push(vm.data[t]);
                            current.children.push(vm.data.splice(t, 1)[0]);
                        }
@@ -145,4 +179,10 @@
                    return current;
                }
+
+               $scope.toggleDisposable = function () {
+                   $scope.calendarDispose = true;
+                   hubber.server.toggleDisposable(vm.treeview.currentNode.Id);
+               }
+
                function collectInfoToSave(node, refresh, last) {
                    var arr = node.calendar.down[0];
@@ -164,5 +204,5 @@
                                "" + Date.parse(arr[i].rec.end),
                                arr[i].rec.days.join(",")
-                               
+
 
                            ]);
@@ -181,5 +221,5 @@
                                "" + Date.parse(arr[i].rec.end),
                                arr[i].rec.days.join(",")
-                               
+
                            ]);
                        }
@@ -189,8 +229,10 @@
                }
                $scope.saveCurrentCalendar = function () {
+                   vm.calendarSaver = true;
                    collectInfoToSave(vm.treeview.currentNode, true, false);
                    //true for refresh, false for showing it's only one calendar saved.
                }
                $scope.saveAllCalendars = function () {
+
                    $scope.allSave = [];
                    for (var i = 0; i < $scope.tree.length; i++)
@@ -205,4 +247,5 @@
                        plain: true
                    }).then(function (success) {
+                       vm.calendarSaver = true;
                        for (var i = 0; i < $scope.allSave.length; i++) {
                            if (i >= $scope.allSave.length - 1)
@@ -255,9 +298,9 @@
                    $scope.currentcal = [];
                    for (var i = 0; i < $scope.tree.length; i++)
-                       removeCalendarsRecurse($scope.tree[i]);
+                       clearCalendarsRecurse($scope.tree[i]);
                    hubber.server.requestDownTime(vm.treeview.currentNode.Id);
                    $(".selected.ng-binding").addClass('loaded');
                }
-               function removeCalendarsRecurse(node) {
+               function clearCalendarsRecurse(node) {
 
                    node.calendar = [];
@@ -265,9 +308,26 @@
                    node.changes = false;
                    for (var i = 0; i < node.children.length; i++) {
-                       removeCalendarsRecurse(node.children[i]);
-                   }
-               }
-
+                       clearCalendarsRecurse(node.children[i]);
+                   }
+               }
+               $scope.deleteAllEvents = function () {
+                   vm.calendarDeleter = true;
+                   vm.selectedEventId = -1;
+                   var node = vm.treeview.currentNode.calendar.down[0];
+                   for (var i = 0; i < node.length;) {
+                       if (node[i].id != '00000000-0000-0000-0000-000000000000')
+                           vm.treeview.currentNode.todelete.push(node[i].id);
+                       $scope.setChanged(vm.selectedEventId);
+                       node.splice(i, 1);
+                   }
+                   vm.calendarDeleter = false;
+                   ngDialog.open({
+                       template:
+                        '<p>All events have been deleted. Save the changes to confirm deletion, clearing will restore all the events from the server</p>',
+                       plain: true
+                   });
+               }
                $scope.deleteAllPreviousEvents = function () {
+                   vm.calendarDeleter = true;
                    vm.selectedEventId = -1;
                    var node = vm.treeview.currentNode.calendar.down[0];
@@ -282,4 +342,5 @@
                            i++;
                    }
+                   vm.calendarDeleter = false;
                    ngDialog.open({
                        template:
@@ -329,5 +390,7 @@
                    vm.selectedEventId = vm.treeview.currentNode.calendar.down[0].length - 1;
                    vm.setChanged(vm.selectedEventId);
-                   //  $("#resourcecalendar").fullCalendar('refetchEvents');
+                   $scope.currentcal = [];
+                   $scope.currentcal = vm.treeview.currentNode.calendar;
+
 
                }
@@ -342,4 +405,8 @@
                $scope.eventClick = function (date, jsEvent, view) {
                    vm.selectedEventId = checkId(date._id);
+               };
+               $scope.eventClickBtn = function (id) {
+                   vm.selectedEventId = checkId(id);
+                   vm.goToDate();
                };
                /* alert on Drop */
@@ -381,15 +448,26 @@
 
                };
+               $scope.removeList = function (id) {
+                   var index = checkId(id);
+                   vm.selectedEventId = -1;
+                   vm.setChanged(vm.selectedEventId);
+                   if (vm.treeview.currentNode.calendar.down[0][index].id != "00000000-0000-0000-0000-000000000000") {
+                       vm.treeview.currentNode.todelete.push(vm.treeview.currentNode.calendar.down[0][index].id);
+                   }
+                   vm.treeview.currentNode.calendar.down[0].splice(index, 1);
+
+
+               };
 
                $scope.checkDateStartEnd = function () {
                    if ($scope.currentcal.down[0][vm.selectedEventId].rec.start > $scope.currentcal.down[0][vm.selectedEventId].rec.end ||
                        $scope.currentcal.down[0][vm.selectedEventId].rec.end === undefined) {
-                       
+
                        $scope.currentcal.down[0][vm.selectedEventId].rec.end = new Date($scope.currentcal.down[0][vm.selectedEventId].rec.start);
-                       
+
                    }
                    if ($scope.currentcal.down[0][vm.selectedEventId].rec.start < Date.now())
                        $scope.currentcal.down[0][vm.selectedEventId].rec.start = new Date();
-                  }
+               }
                //pushes all changes to other recurs
                $scope.pushRecurChanges = function (recid) {
@@ -415,5 +493,5 @@
                                }
                                else {
-                                   
+
                                    arr[i].start.setHours(ob.start.getHours(), ob.start.getMinutes());
                                    arr[i].end.setHours(ob.end.getHours(), ob.end.getMinutes());
@@ -439,7 +517,7 @@
                                    loop2:
                                        for (var i = 0; i < arr.length; i++) {
-                                           
+
                                            if (arr[i].rec.recid === recid) {
-                                               var dend = (d+1000 * 3600 * 24);
+                                               var dend = (d + 1000 * 3600 * 24);
                                                if (arr[i].start.getTime() >= d &&
                                                    arr[i].end.getTime() <= dend) {
@@ -449,5 +527,5 @@
                                            }
                                        }
- 
+
                                    var ts = new Date(d);
                                    ts.setHours(new Date(ob.start).getHours(), new Date(ob.start).getMinutes());
@@ -465,7 +543,7 @@
 
                                }
-                               
+
                                d += (1000 * 3600 * 24);// 1 day
-                              
+
                            }
                    });
@@ -491,4 +569,7 @@
                }
 
+               $scope.goToDate = function () {
+                   $("#resourcecalendar").fullCalendar('gotoDate', vm.currentcal.down[0][vm.selectedEventId].start);
+               }
                /* Render Tooltip */
                $scope.eventRender = function (event, element, view) {
@@ -508,5 +589,5 @@
                        header: {
                            left: 'title',
-                           center: '',
+                           center: 'agendaWeek, agendaDay',
                            right: 'today prev,next'
                        },
@@ -520,9 +601,34 @@
 
 
-                   }
-               };
-
-
-
+
+                   }
+               };
+
+
+
+           }).filter('disp', function () {
+               return function (input) {
+                   return input ? 'Disposable' : 'Not disposable';
+               }
+           }).directive('animateOnChange', function ($timeout) {
+               return function (scope, element, attr) {
+                   scope.$watch(attr.animateOnChange, function (nv, ov) {
+
+                       if (nv != ov) {
+                           if (scope.currentcal.down[0][scope.selectedEventId].title === "Unavailable") {
+                               element.addClass('changed');
+                               $timeout(function () {
+                                   element.removeClass('changed');
+                               }, 250); // Could be enhanced to take duration as a parameter
+                           }
+                           else {
+                               element.addClass('changedshut');
+                               $timeout(function () {
+                                   element.removeClass('changedshut');
+                               }, 250); // Could be enhanced to take duration as a parameter
+                           }
+                       }
+                   });
+               };
            });
 
