Free cookie consent management tool by TermsFeed Policy Generator

source: branches/WebJobManager/HeuristicLab.Clients.Hive.WebJobManager/wwwroot/js/hubs/calendarhubber.js @ 13783

Last change on this file since 13783 was 13782, checked in by jlodewyc, 9 years ago

#2582 Resource calendar and client group creation, control implemented

File size: 30.3 KB
Line 
1
2angular.module('wjm', ['ui.bootstrap', 'ui.calendar', 'angularTreeview', 'ngDialog']).
3
4           controller('resourceCtrl', function ($rootScope, $scope, uiCalendarConfig, $compile, ngDialog, $timeout) {
5               var vm = $scope;
6
7               var date = new Date();
8
9               var d = date.getDate();
10               var m = date.getMonth();
11               var y = date.getFullYear();
12               var hubber = $.connection.calendarHub;
13
14               vm.alertMessage = "No alerts";
15               vm.currentcal = [];
16               vm.selectedEventId = -1;
17               vm.groups = [];
18               vm.clients = [];
19               vm.init = function () {
20
21                   //  $.connection.hub.logging = true;
22
23
24                   var v = document.getElementById("userId").innerHTML;
25                   $.connection.hub.qs = { 'userid': v };
26                   $.connection.hub.start().done(function () {
27                       hubber.server.requestInfo();
28                   });
29                   hubber.client.processData = function (data) {
30                       vm.data = JSON.parse(data);
31                       $scope.buildTree();
32
33                       $scope.$apply();
34                   };
35                   hubber.client.savingCurrentDone = function () {
36                       vm.calendarSaver = false;
37                       $scope.clearCurrentCalendar();
38                       $scope.$apply();
39                   };
40                   hubber.client.savingAllDone = function () {
41                       vm.calendarSaver = false;
42                       clearAllCalendarsFunc();
43                       $scope.$apply();
44                   };
45                   hubber.client.processDispose = function (disp) {
46                       vm.treeview.currentNode.IsDisposable = disp;
47                       $scope.calendarDispose = false;
48                       $scope.$apply();
49                   }
50                   hubber.client.processDowntime = function (id, down) {
51                       var json = JSON.parse(down);
52                       var arrdown = [];
53                       var str = "";
54                       for (var i = 0; i < json.length; i++) {
55                           if (json[i].DowntimeType === 0) {
56                               str = "Unavailable";
57                               col = "#006080";
58                           }
59                           else {
60                               str = "Shutdown";
61                               col = "#993300";
62                           }
63                           arrdown.push({
64                               id: json[i].Id,
65                               title: str,
66                               start: new Date(json[i].StartDate),
67                               end: new Date(json[i].EndDate),
68                               allDay: json[i].AllDayEvent,
69                               color: col,
70                               rec: {
71                                   recurrence: json[i].Recurring,
72                                   recid: json[i].RecurringId,
73                                   days: [false, false, false, false, false, false, false],
74                                   start: new Date(json[i].StartDate),
75                                   end: new Date(json[i].EndDate)
76
77                               },
78                               changed: false
79                           });
80                       }
81                       var dat = { 'id': id, 'down': [arrdown] };
82                       $scope.treeview.currentNode.calendar = dat;
83
84                       $scope.currentcal = $scope.treeview.currentNode.calendar;
85                       $("#resourcecalendar").fullCalendar('refresh');
86                       $scope.$apply();
87                   }
88
89                   $scope.$watch("treeview.currentNode", function (newValue, oldValue) {
90                       $scope.currentcal = [];
91                       $(".selected.ng-binding").addClass('loaded');
92                       $scope.selectedEventId = -1;
93                       if ($scope.treeview.currentNode != null && $scope.treeview.currentNode.Id != undefined) {
94                           if ($scope.treeview.currentNode.calendar.length === 0) {
95                               hubber.server.requestDownTime(vm.treeview.currentNode.Id);
96
97                           }
98                           else {
99                               $timeout(function () {
100                                   $scope.currentcal = $scope.treeview.currentNode.calendar;
101
102                               }, 0);
103
104                           }
105                       }
106
107                   });
108               }
109               $scope.clearTreeSelect = function () {
110                   if (vm.treeview.currentNode != undefined) {
111                       vm.treeview.currentNode.selected = undefined;
112                       vm.treeview.currentNode = undefined;
113                       vm.selectedEventId = -1;
114                   }
115               }
116               $scope.buildTree = function () {
117                   vm.tree = [];
118                   vm.temptree = [];
119                   vm.top = false;
120                   var ungrouped = {
121                       children: [],
122                       Name: 'Ungrouped'
123                   }
124                   for (; vm.data.length > 0;) {
125
126                       if (vm.data[0].ParentResourceId == null && vm.data[0].IsDisposable !== undefined) {
127                           var curr = $scope.seekChildren(vm.data.splice(0, 1)[0]);
128                           vm.clients.push(curr);
129                           ungrouped.children.push(curr);
130                       }
131                       else if (vm.data[0].ParentResourceId == null) {
132                           var curr = $scope.seekChildren(vm.data.splice(0, 1)[0]);
133                           vm.groups.push(curr);
134                           vm.tree.push(curr);
135                       }
136                       else {
137                           var curr = $scope.seekChildren(vm.data.splice(0, 1)[0]);
138                           if (curr.IsDisposable !== undefined)
139                               vm.clients.push(curr);
140                           else
141                               vm.groups.push(curr);
142                           vm.temptree.push(curr);
143                       }
144                   }
145                   vm.tree.push(ungrouped);
146
147               };
148
149               $scope.seekChildren = function (current) {
150                   current.calendar = [];
151                   current.children = [];
152                   current.todelete = [];
153                   current.changes = false;
154                   current.collapsed = true;
155                   for (var t = 0; t < vm.temptree.length;) {
156                       if (current.Id == vm.temptree[t].ParentResourceId) {
157                           current.children.push(vm.temptree.splice(t, 1)[0]);
158                       }
159                       else {
160                           t++;
161                       }
162                   }
163                   var childc = current.children.length;//Remembers count of children received from temp tree;
164                   for (var t = 0; t < vm.data.length;) {
165                       if (current.Id == vm.data[t].ParentResourceId) {
166                           if (vm.data[t].IsDisposable !== undefined)
167                               vm.clients.push(vm.data[t]);
168                           else
169                               vm.groups.push(vm.data[t]);
170                           current.children.push(vm.data.splice(t, 1)[0]);
171                       }
172                       else {
173                           t++;
174                       }
175                   }
176                   for (var t = childc; t < current.children.length; t++) {
177                       current.children[t] = $scope.seekChildren(current.children[t]);
178                   }
179                   return current;
180               }
181
182               $scope.toggleDisposable = function () {
183                   $scope.calendarDispose = true;
184                   hubber.server.toggleDisposable(vm.treeview.currentNode.Id);
185               }
186
187               function collectInfoToSave(node, refresh, last) {
188                   var arr = node.calendar.down[0];
189                   var toadd = [];
190                   var todel = node.todelete;
191                   var toupd = [];
192                   for (var i = 0; i < arr.length; i++) {
193                       if (arr[i].id === '00000000-0000-0000-0000-000000000000') {
194                           var t = arr[i].allDay.toString();
195                           toadd.push([
196                               arr[i].title,//status
197                               "" + Date.parse(arr[i].start),//start
198                               "" + Date.parse(arr[i].end),//end
199                               t,// allday
200                               node.Id, //resource id
201                               arr[i].rec.recurrence.toString(),//true on recur
202                               arr[i].rec.recid,//recur id
203                               "" + Date.parse(arr[i].rec.start),
204                               "" + Date.parse(arr[i].rec.end),
205                               arr[i].rec.days.join(",")
206
207
208                           ]);
209                       }
210                       else if (arr[i].changed === true) {
211                           var t = arr[i].allDay.toString();
212                           toupd.push([
213                               arr[i].id,//id to update
214                               arr[i].title,//status
215                               "" + Date.parse(arr[i].start),//start
216                               "" + Date.parse(arr[i].end),//end
217                               t,//allday
218                               arr[i].rec.recurrence.toString(),//true on recur
219                               arr[i].rec.recid,//recur id
220                               "" + Date.parse(arr[i].rec.start),
221                               "" + Date.parse(arr[i].rec.end),
222                               arr[i].rec.days.join(",")
223
224                           ]);
225                       }
226                   }
227                   vm.sendtoserv = [todel, toadd, toupd];
228                   hubber.server.saveCalendar(node.Id, todel, toadd, toupd, refresh, last);
229               }
230               $scope.saveCurrentCalendar = function () {
231                   vm.calendarSaver = true;
232                   collectInfoToSave(vm.treeview.currentNode, true, false);
233                   //true for refresh, false for showing it's only one calendar saved.
234               }
235               $scope.saveAllCalendars = function () {
236
237                   $scope.allSave = [];
238                   for (var i = 0; i < $scope.tree.length; i++)
239                       createSaveRequests($scope.tree[i]);
240                   ngDialog.openConfirm({
241                       template:
242                        '<p>Are you sure you want to save all changes made to ' + $scope.allSave.length + ' calendars?</p>' +
243                        '<div>' +
244                        '<button type="button" class="btn btn-primary" ng-click="confirm(1)">Yes' +
245                        '<button type="button" class="btn btn-default" ng-click="closeThisDialog(0)">No </button> ' +
246                        '</button></div>',
247                       plain: true
248                   }).then(function (success) {
249                       vm.calendarSaver = true;
250                       for (var i = 0; i < $scope.allSave.length; i++) {
251                           if (i >= $scope.allSave.length - 1)
252                               collectInfoToSave($scope.allSave[i], false, true);
253                           else
254                               collectInfoToSave($scope.allSave[i], false, false);
255                       }
256                   });
257
258
259               }
260               function createSaveRequests(node) {
261                   if (node.changes === true)
262                       $scope.allSave.push(node);
263                   for (var i = 0; i < node.children.length; i++) {
264                       createSaveRequests(node.children[i]);
265                   }
266               }
267               $scope.clearCurrentCalendar = function () {
268
269                   $scope.selectedEventId = -1;
270                   $scope.treeview.currentNode.calendar = null;
271                   $scope.treeview.currentNode.todelete = [];
272                   $scope.treeview.currentNode.changes = false;
273                   $scope.currentcal = [];
274                   hubber.server.requestDownTime(vm.treeview.currentNode.Id);
275                   $(".selected.ng-binding").removeClass('changed');
276
277
278               }
279               $scope.clearAllCalendars = function () {
280                   ngDialog.openConfirm({
281                       template:
282                        '<p>Are you sure you want to delete all calendar changes?</p>' +
283                        '<div>' +
284                          '<button type="button" class="btn btn-default" ng-click="closeThisDialog(0)">No </button> ' +
285                          '<button type="button" class="btn btn-primary" ng-click="confirm(1)">Yes' +
286                        '</button></div>',
287                       plain: true
288                   }).then(function (success) {
289                       clearAllCalendarsFunc();
290                   });
291
292               }
293               function clearAllCalendarsFunc() {
294                   $(".ng-binding.changed").removeClass('changed');
295                   $(".ng-binding.loaded").removeClass('loaded');
296                   $scope.selectedEventId = -1;
297                   $scope.treeview.currentNode.calendar = null;
298                   $scope.currentcal = [];
299                   for (var i = 0; i < $scope.tree.length; i++)
300                       clearCalendarsRecurse($scope.tree[i]);
301                   hubber.server.requestDownTime(vm.treeview.currentNode.Id);
302                   $(".selected.ng-binding").addClass('loaded');
303               }
304               function clearCalendarsRecurse(node) {
305
306                   node.calendar = [];
307                   node.todelete = [];
308                   node.changes = false;
309                   for (var i = 0; i < node.children.length; i++) {
310                       clearCalendarsRecurse(node.children[i]);
311                   }
312               }
313               $scope.deleteAllEvents = function () {
314                   vm.calendarDeleter = true;
315                   vm.selectedEventId = -1;
316                   var node = vm.treeview.currentNode.calendar.down[0];
317                   for (var i = 0; i < node.length;) {
318                       if (node[i].id != '00000000-0000-0000-0000-000000000000')
319                           vm.treeview.currentNode.todelete.push(node[i].id);
320                       $scope.setChanged(vm.selectedEventId);
321                       node.splice(i, 1);
322                   }
323                   vm.calendarDeleter = false;
324                   ngDialog.open({
325                       template:
326                        '<p>All events have been deleted. Save the changes to confirm deletion, clearing will restore all the events from the server</p>',
327                       plain: true
328                   });
329               }
330               $scope.deleteAllPreviousEvents = function () {
331                   vm.calendarDeleter = true;
332                   vm.selectedEventId = -1;
333                   var node = vm.treeview.currentNode.calendar.down[0];
334                   for (var i = 0; i < node.length;) {
335                       if (node[i].end < Date.now()) {
336                           if (node[i].id != '00000000-0000-0000-0000-000000000000')
337                               vm.treeview.currentNode.todelete.push(node[i].id);
338                           $scope.setChanged(vm.selectedEventId);
339                           node.splice(i, 1);
340                       }
341                       else
342                           i++;
343                   }
344                   vm.calendarDeleter = false;
345                   ngDialog.open({
346                       template:
347                        '<p>All previous events have been deleted. Save the changes to confirm deletion</p>',
348                       plain: true
349                   });
350               }
351
352
353               $scope.setChanged = function (id) {
354                   if (id != -1) {
355                       if (vm.treeview.currentNode.calendar.down[0][id].title === "Unavailable")
356                           vm.treeview.currentNode.calendar.down[0][id].color = '#0099cc';
357                       else
358                           vm.treeview.currentNode.calendar.down[0][id].color = '#ff5500';
359
360                       vm.treeview.currentNode.calendar.down[0][id].changed = true;
361                   }
362                   vm.treeview.currentNode.changes = true;
363                   $(".selected.ng-binding").addClass('changed');
364               }
365               //*Add event by click
366               $scope.calendarClick = function (date, jsEvent, view) {
367
368                   var newid = 0;
369                   if (vm.treeview.currentNode.calendar.down[0].length != 0)
370                       newid = vm.treeview.currentNode.calendar.down[0][(vm.treeview.currentNode.calendar.down[0].length - 1)]._id + 1;
371                   var dat = date.toDate();
372                   var end = new Date(dat);
373                   end.setHours(dat.getHours() + 2);
374                   vm.treeview.currentNode.calendar.down[0].push({
375                       id: '00000000-0000-0000-0000-000000000000',
376                       title: 'Unavailable',
377                       start: dat,
378                       end: end,
379                       allDay: date._ambigTime,
380                       rec: {
381                           recurrence: false,
382                           recid: '0',
383                           days: [false, false, false, false, false, false, false],
384                           start: dat,
385                           end: end
386
387                       },
388                       _id: (newid)
389                   });
390                   vm.selectedEventId = vm.treeview.currentNode.calendar.down[0].length - 1;
391                   vm.setChanged(vm.selectedEventId);
392                   $scope.currentcal = [];
393                   $scope.currentcal = vm.treeview.currentNode.calendar;
394
395
396               }
397               function checkId(id) {
398                   for (var i = 0; i < vm.treeview.currentNode.calendar.down[0].length ; i++) {
399                       if (vm.treeview.currentNode.calendar.down[0][i]._id === id)
400                           return i;
401                   }
402                   return -1;
403               }
404               /* alert on eventClick */
405               $scope.eventClick = function (date, jsEvent, view) {
406                   vm.selectedEventId = checkId(date._id);
407               };
408               $scope.eventClickBtn = function (id) {
409                   vm.selectedEventId = checkId(id);
410                   vm.goToDate();
411               };
412               /* alert on Drop */
413               $scope.dragandDrop = function (event, delta, revertFunc, jsEvent, ui, view) {
414                   vm.selectedEventId = checkId(event._id);
415                   vm.setChanged(vm.selectedEventId);
416                   if (event.end == null) {
417                       event.end = moment(event.start).add(2, 'hours');
418                   }
419                   if (vm.treeview.currentNode.calendar.down[0][vm.selectedEventId].allDay && event.start._ambigTime == false) {
420                       event.allDay = false;
421                       vm.treeview.currentNode.calendar.down[0][vm.selectedEventId].allDay = false;
422                   }
423                   else if (!vm.treeview.currentNode.calendar.down[0][vm.selectedEventId].allDay && event.start._ambigTime == true) {
424                       event.allDay = true;
425                       vm.treeview.currentNode.calendar.down[0][vm.selectedEventId].allDay = true;
426                       //vm.treeview.currentNode.calendar.down[0][vm.selectedEventId].end = null;
427                   }
428                   vm.treeview.currentNode.calendar.down[0][vm.selectedEventId].start = new Date(event.start);
429                   vm.treeview.currentNode.calendar.down[0][vm.selectedEventId].end = new Date(event.end);
430               };
431               /* alert on Resize */
432               $scope.resizeEvent = function (event, delta, revertFunc, jsEvent, ui, view) {
433                   vm.selectedEventId = checkId(event._id);
434                   vm.setChanged(vm.selectedEventId);
435                   vm.treeview.currentNode.calendar.down[0][vm.selectedEventId].start = new Date(event.start);
436                   vm.treeview.currentNode.calendar.down[0][vm.selectedEventId].end = new Date(event.end);
437               };
438
439               /* remove event */
440               $scope.remove = function (index) {
441                   vm.selectedEventId = -1;
442                   vm.setChanged(vm.selectedEventId);
443                   if (vm.treeview.currentNode.calendar.down[0][index].id != "00000000-0000-0000-0000-000000000000") {
444                       vm.treeview.currentNode.todelete.push(vm.treeview.currentNode.calendar.down[0][index].id);
445                   }
446                   vm.treeview.currentNode.calendar.down[0].splice(index, 1);
447
448
449               };
450               $scope.removeList = function (id) {
451                   var index = checkId(id);
452                   vm.selectedEventId = -1;
453                   vm.setChanged(vm.selectedEventId);
454                   if (vm.treeview.currentNode.calendar.down[0][index].id != "00000000-0000-0000-0000-000000000000") {
455                       vm.treeview.currentNode.todelete.push(vm.treeview.currentNode.calendar.down[0][index].id);
456                   }
457                   vm.treeview.currentNode.calendar.down[0].splice(index, 1);
458
459
460               };
461
462               $scope.checkDateStartEnd = function () {
463                   if ($scope.currentcal.down[0][vm.selectedEventId].rec.start > $scope.currentcal.down[0][vm.selectedEventId].rec.end ||
464                       $scope.currentcal.down[0][vm.selectedEventId].rec.end === undefined) {
465
466                       $scope.currentcal.down[0][vm.selectedEventId].rec.end = new Date($scope.currentcal.down[0][vm.selectedEventId].rec.start);
467
468                   }
469                   if ($scope.currentcal.down[0][vm.selectedEventId].rec.start < Date.now())
470                       $scope.currentcal.down[0][vm.selectedEventId].rec.start = new Date();
471               }
472               //pushes all changes to other recurs
473               $scope.pushRecurChanges = function (recid) {
474                   ngDialog.openConfirm({
475                       template:
476                        '<p>This will change all existing recurrences and create new recurrences where needed. Are you sure?</p>' +
477                        '<div>' +
478                          '<button type="button" class="btn btn-default" ng-click="closeThisDialog(0)">No </button> ' +
479                          '<button type="button" class="btn btn-primary" ng-click="confirm(1)">Yes' +
480                        '</button></div>',
481                       plain: true
482                   }).then(function (success) {
483                       var arr = vm.treeview.currentNode.calendar.down[0];
484                       var ob = $.extend(true, {}, arr[vm.selectedEventId]);
485                       for (var i = 0; i < arr.length;) {
486                           if (arr[i].rec.recid === recid) {
487                               if (new Date(arr[i].start) < new Date(ob.rec.start) ||
488                                        new Date(arr[i].end) > new Date(ob.rec.end) ||
489                                        !ob.rec.days[new Date(arr[i].start).getDay()]) {
490                                   vm.remove(i);
491                                   vm.selectedEventId = -1;
492
493                               }
494                               else {
495
496                                   arr[i].start.setHours(ob.start.getHours(), ob.start.getMinutes());
497                                   arr[i].end.setHours(ob.end.getHours(), ob.end.getMinutes());
498                                   arr[i].title = ob.title;
499                                   arr[i].rec = ob.rec;
500                                   arr[i].allDay = ob.allDay;
501                                   vm.setChanged(i);
502                                   i++;
503                               }
504                           }
505                           else
506                               i++;
507                       }
508                       var start = new Date(ob.rec.start);
509                       start.setHours(2, 0, 0, 0);
510                       var end = new Date(ob.rec.end);
511                       end = new Date(end.setHours(24, 0, 0, 0) + 1000 * 3600 * 2);
512
513                       loop1:
514                           for (var d = (start.getTime()) ; d < (end.getTime()) ;) {
515                               var tog = ob.rec.days[new Date(d).getDay()];
516                               if (tog) {
517                                   loop2:
518                                       for (var i = 0; i < arr.length; i++) {
519
520                                           if (arr[i].rec.recid === recid) {
521                                               var dend = (d + 1000 * 3600 * 24);
522                                               if (arr[i].start.getTime() >= d &&
523                                                   arr[i].end.getTime() <= dend) {
524                                                   d += (1000 * 3600 * 24);
525                                                   continue loop1;
526                                               }
527                                           }
528                                       }
529
530                                   var ts = new Date(d);
531                                   ts.setHours(new Date(ob.start).getHours(), new Date(ob.start).getMinutes());
532                                   var te = new Date(d);
533                                   te.setHours(new Date(ob.end).getHours(), new Date(ob.end).getMinutes());
534                                   arr.push({
535                                       id: '00000000-0000-0000-0000-000000000000',
536                                       title: ob.title,
537                                       start: ts,
538                                       end: te,
539                                       allDay: ob.allDay,
540                                       rec: ob.rec
541                                   });
542                                   vm.setChanged(arr.length - 1);
543
544                               }
545
546                               d += (1000 * 3600 * 24);// 1 day
547
548                           }
549                   });
550               }
551               $scope.deleteAllRecurrences = function (recid) {
552                   ngDialog.openConfirm({
553                       template:
554                        '<p>This will delete every found recurrence. Are you sure?</p>' +
555                        '<div>' +
556                          '<button type="button" class="btn btn-default" ng-click="closeThisDialog(0)">No </button> ' +
557                          '<button type="button" class="btn btn-primary" ng-click="confirm(1)">Yes' +
558                        '</button></div>',
559                       plain: true
560                   }).then(function (success) {
561                       var arr = vm.treeview.currentNode.calendar.down[0];
562                       for (var i = 0; i < arr.length;) {
563                           if (arr[i].rec.recid === recid)
564                               vm.remove(i);
565                           else
566                               i++;
567                       }
568                   });
569               }
570
571               $scope.goToDate = function () {
572                   $("#resourcecalendar").fullCalendar('gotoDate', vm.currentcal.down[0][vm.selectedEventId].start);
573               }
574               /* Render Tooltip */
575               $scope.eventRender = function (event, element, view) {
576                   element.attr({
577                       'tooltip': event.title,
578                       'tooltip-append-to-body': true
579                   });
580                   //$compile(element)($scope);
581               };
582               /* config object */
583               $scope.uiConfig = {
584                   calendar: {
585                       height: 500,
586                       editable: true,
587                       defaultView: 'agendaWeek',
588                       firstDay: 1,
589                       header: {
590                           left: 'title',
591                           center: 'agendaWeek, agendaDay',
592                           right: 'today prev,next'
593                       },
594                       timezone: 'UTC',
595                       timeFormat: 'HH:mm',
596                       eventClick: $scope.eventClick,
597                       eventDrop: $scope.dragandDrop,
598                       eventResize: $scope.resizeEvent,
599                       eventRender: $scope.eventRender,
600                       dayClick: $scope.calendarClick
601
602
603
604                   }
605               };
606
607
608
609           }).filter('disp', function () {
610               return function (input) {
611                   return input ? 'Disposable' : 'Not disposable';
612               }
613           }).directive('animateOnChange', function ($timeout) {
614               return function (scope, element, attr) {
615                   scope.$watch(attr.animateOnChange, function (nv, ov) {
616
617                       if (nv != ov) {
618                           if (scope.currentcal.down[0][scope.selectedEventId].title === "Unavailable") {
619                               element.addClass('changed');
620                               $timeout(function () {
621                                   element.removeClass('changed');
622                               }, 250); // Could be enhanced to take duration as a parameter
623                           }
624                           else {
625                               element.addClass('changedshut');
626                               $timeout(function () {
627                                   element.removeClass('changedshut');
628                               }, 250); // Could be enhanced to take duration as a parameter
629                           }
630                       }
631                   });
632               };
633           });
634
635
Note: See TracBrowser for help on using the repository browser.