Revised version of the resource page + related plugins
[myslice.git] / plugins / scheduler2 / static / js / scheduler-SchedulerCtrl.js
1 var myApp = angular.module('myApp', []);\r
2 myApp.config(function ($interpolateProvider) {\r
3     $interpolateProvider.startSymbol('{[{').endSymbol('}]}');\r
4 });\r
5 myApp.factory('$exceptionHandler', function () {\r
6     return function (exception, cause) {\r
7         if (exception.message.contains('leases')) {\r
8             console.log(exception.message);\r
9             \r
10             var tmpScope = angular.element(document.getElementById('SchedulerCtrl')).scope();\r
11             //tmpScope.initSlots(_schedulerCurrentCellPosition, _schedulerCurrentCellPosition + SchedulerTotalVisibleCells);\r
12         }\r
13             \r
14     };\r
15 });\r
16 \r
17 myApp.filter('offset', function() {\r
18   return function(input, start) {\r
19     start = parseInt(start, 10);\r
20     return input.slice(start);\r
21   };\r
22 });\r
23 \r
24 // Create a private execution space for our controller. When\r
25 // executing this function expression, we're going to pass in\r
26 // the Angular reference and our application module.\r
27 (function (ng, app) {\r
28 \r
29 \r
30     // Define our Controller constructor.\r
31     function Controller($scope) {\r
32 \r
33         // Store the scope so we can reference it in our\r
34         // class methods\r
35         this.scope = $scope;\r
36 \r
37         // Set up the default scope value.\r
38         this.scope.errorMessage = null;\r
39         this.scope.name = "";\r
40 \r
41         //Pagin\r
42         $scope.current_page = 1;\r
43         this.scope.items_per_page = 10;\r
44         $scope.from = 0; // JORDAN\r
45 \r
46         $scope.resources = new Array();\r
47         $scope.slots = SchedulerSlotsViewData;\r
48         $scope.granularity = DEFAULT_GRANULARITY; /* Will be setup */\r
49         //$scope.msg = "hello";\r
50 \r
51         angular.element(document).ready(function() {\r
52             //console.log('Hello World');\r
53             //alert('Hello World');\r
54             //afterAngularRendered();\r
55         });\r
56 \r
57         // Jordan\r
58 /*\r
59         $scope.redraw = function()\r
60         {\r
61 \r
62             // Refresh slots\r
63             $scope.slots = [];\r
64             for (var i = $scope.from; i < $scope.from + SchedulerTotalVisibleCells; i++)\r
65                 $scope.slots.push(SchedulerSlots[i]);\r
66 \r
67 \r
68             // Collect lease information. This could be made once if no refresh... \r
69             lease_by_resource = {};\r
70             manifold.query_store.iter_visible_records($scope.options.query_lease_uuid, function (record_key, record) {\r
71                 lease_by_resource[record['resource']] = record;\r
72                 // Need something to interrupt the loop\r
73             });\r
74 \r
75             // Create resources\r
76             $scope.resources = [];\r
77             // current_page, items_per_page indicates which resources to show\r
78             manifold.query_store.iter_visible_records($scope.options.query_uuid, function (record_key, record) {\r
79                 // copy not to modify original record\r
80                 var resource = jQuery.extend(true, {}, record);\r
81                 resource.leases = []; // a list of occupied timeslots\r
82 \r
83                 // How many timeslots ? SchedulerTotalVisibleCells\r
84                 // SchedulerDateSelected\r
85                 // from : to ??\r
86                 // slot duration ?\r
87                 for (i=0; i < SchedulerTotalVisibleCells; i++) {\r
88                     resource.leases.push({\r
89                         'id': 'coucou',\r
90                         'status': 'free', // 'selected', 'reserved', 'maintenance'\r
91                     });\r
92                 }\r
93 \r
94                 // For each lease we need to mark slots appropriately\r
95                 if (lease_by_resource[resource['urn']]) {\r
96                     $.each(lease_by_resource[resource['urn']], function(i, lease) {\r
97                         // $scope.from * GRANULARITY minutes since start\r
98                         $scope.from * GRANULARITY\r
99                         from_date = new Date(date.getTime() + ($scope.from * GRANULARITY) * 60000);\r
100                         to_date   = new Date(date.getTime() + (($scope.from + SchedulerTotalVisibleCells) * GRANULARITY) * 60000);\r
101                         // start_time, end_time\r
102                     });\r
103                 }\r
104                 \r
105                 $scope.resources.push(resource);\r
106                 $scope.$apply();\r
107             });\r
108         }\r
109 */\r
110         $scope.clearStuff = function() {\r
111             $scope.resources = new Array();\r
112             $scope.$apply();\r
113         }\r
114 \r
115         // Called at initialization, after filtering, and after changing the date.\r
116         // this is like setpage(1) ???\r
117 /*\r
118         $scope.initSchedulerResources = function (items_per_page) {\r
119             $scope.resources = new Array();\r
120 \r
121             for (var k = 0; k < items_per_page; k++) {\r
122                 $scope.resources.push(jQuery.extend(true, {}, SchedulerDataViewData[k]));\r
123                 $scope.resources[k].leases = [];\r
124             }\r
125             $scope.items_per_page = items_per_page;\r
126             $scope.current_page = 0;\r
127             $scope.totalPages = parseInt(Math.ceil(SchedulerDataViewData.length / $scope.items_per_page));\r
128             $scope.initSlots(0, SchedulerTotalVisibleCells);\r
129         };\r
130 */\r
131 \r
132         // Pagination\r
133 \r
134         $scope.range = function() {\r
135             var range_size = $scope.page_count() > DEFAULT_PAGE_RANGE ? DEFAULT_PAGE_RANGE : $scope.page_count();\r
136             var ret = [];\r
137             var start;\r
138 \r
139             start = $scope.current_page;\r
140             if ( start > $scope.page_count()-range_size ) {\r
141               start = $scope.page_count()-range_size+1;\r
142             }\r
143 \r
144             for (var i=start; i<start+range_size; i++) {\r
145               ret.push(i);\r
146             }\r
147             return ret;\r
148         };\r
149 \r
150         $scope.prevPage = function() {\r
151           if ($scope.current_page > 1) {\r
152             $scope.current_page--;\r
153           }\r
154         };\r
155 \r
156         $scope.prevPageDisabled = function() {\r
157           return $scope.current_page === 1 ? "disabled" : "";\r
158         };\r
159   \r
160         $scope.page_count = function() {\r
161           return Math.ceil($scope.resources.length/$scope.items_per_page);\r
162         };\r
163   \r
164         $scope.nextPage = function() {\r
165           if ($scope.current_page < $scope.page_count()) {\r
166             $scope.current_page++;\r
167           }\r
168         };\r
169   \r
170         $scope.nextPageDisabled = function() {\r
171           return $scope.current_page === $scope.page_count() ? "disabled" : "";\r
172         }; \r
173 \r
174         $scope.setPage = function(n) {\r
175             $scope.current_page = n;\r
176         };\r
177         // END pagination\r
178 \r
179         // FILTER\r
180 \r
181         $scope.filter_visible = function(resource)\r
182         {\r
183             return manifold.query_store.get_record_state($scope.options.query_uuid, resource['urn'], STATE_VISIBLE);\r
184         };\r
185 \r
186         // SELECTION\r
187 \r
188         $scope.select = function(index, model_lease, model_resource)\r
189         {\r
190             // XXX\r
191             // XXX Events won't work until we properly handle sets with composite keys\r
192             // XXX\r
193             console.log("Selected", index, model_lease, model_resource);\r
194 \r
195             if (model_lease.status != 'free') {\r
196                 console.log("Already selected slot");\r
197                 return;\r
198             }\r
199             \r
200             var day_timestamp = SchedulerDateSelected.getTime() / 1000;\r
201             var start_time = day_timestamp + index       * model_resource.granularity;\r
202             var end_time   = day_timestamp + (index + 1) * model_resource.granularity;\r
203             var start_date = new Date(start_time * 1000);\r
204             var end_date   = new Date(end_time   * 1000);\r
205 \r
206             var lease_key = manifold.metadata.get_key('lease');\r
207 \r
208             // We search for leases in the cache we previously constructed\r
209             var resource_leases = $scope._leases_by_resource[model_resource.urn];\r
210             if (resource_leases) {\r
211                 /* Search for leases before */\r
212                 $.each(resource_leases, function(i, other) {\r
213                     if (other.end_time != start_time)\r
214                         return true; // ~ continue\r
215 \r
216                     /* The lease 'other' is just before, and there should not exist\r
217                      * any other lease before it */\r
218                     start_time = other.start_time;\r
219 \r
220                     other_key = {\r
221                         resource:   other.resource,\r
222                         start_time: other.start_time,\r
223                         end_time:   other.end_time\r
224                     }\r
225                     // This is needed to create a hashable object\r
226                     other_key.hashCode = manifold.record_hashcode(lease_key.sort());\r
227                     other_key.equals   = manifold.record_equals(lease_key);\r
228 \r
229                     manifold.raise_event($scope.options.query_lease_uuid, SET_REMOVED, other_key);\r
230                     /* Remove from local cache also, unless we listen to events from outside */\r
231                     $.grep($scope._leases_by_resource[model_resource.urn], function(x) { return x != other; });\r
232                     return false; // ~ break\r
233                 });\r
234 \r
235                 /* Search for leases after */\r
236                 $.each(resource_leases, function(i, other) {\r
237                     if (other.start_time != end_time)\r
238                         return true; // ~ continue\r
239 \r
240                     /* The lease 'other' is just after, and there should not exist\r
241                      * any other lease after it */\r
242                     end_time = other.end_time;\r
243                     // XXX SET_ADD and SET_REMOVE should accept full objects\r
244                     other_key = {\r
245                         resource:   other.resource,\r
246                         start_time: other.start_time,\r
247                         end_time:   other.end_time\r
248                     }\r
249                     // This is needed to create a hashable object\r
250                     other_key.hashCode = manifold.record_hashcode(lease_key.sort());\r
251                     other_key.equals   = manifold.record_equals(lease_key);\r
252 \r
253                     manifold.raise_event($scope.options.query_lease_uuid, SET_REMOVED, other_key);\r
254                     /* Remove from local cache also, unless we listen to events from outside */\r
255                     $.grep($scope._leases_by_resource[model_resource.urn], function(x) { return x != other; });\r
256                     return false; // ~ break\r
257                 });\r
258             }\r
259 \r
260             /* Create a new lease */\r
261             new_lease = {\r
262                 resource:   model_resource.urn,\r
263                 start_time: start_time,\r
264                 end_time:   end_time,\r
265             };\r
266 \r
267             // This is needed to create a hashable object\r
268             new_lease.hashCode = manifold.record_hashcode(lease_key.sort());\r
269             new_lease.equals   = manifold.record_equals(lease_key);\r
270 \r
271             manifold.raise_event($scope.options.query_lease_uuid, SET_ADD, new_lease);\r
272             /* Add to local cache also, unless we listen to events from outside */\r
273             if (!(model_resource.urn in $scope._leases_by_resource))\r
274                 $scope._leases_by_resource[model_resource.urn] = [];\r
275             $scope._leases_by_resource[model_resource.urn].push(new_lease);\r
276 \r
277             // XXX Shall we set it or wait for manifold event ?\r
278             model_lease.status = 'reserved'; // XXX pending\r
279 \r
280             // DEBUG: display all leases and their status in the log\r
281             var leases = manifold.query_store.get_records($scope.options.query_lease_uuid);\r
282             console.log("--------------------");\r
283             $.each(leases, function(i, lease) {\r
284                 var key = manifold.metadata.get_key('lease');\r
285                 var lease_key = manifold.record_get_value(lease, key);\r
286                 var state = manifold.query_store.get_record_state($scope.options.query_lease_uuid, lease_key, STATE_SET);\r
287                 var state_str;\r
288                 switch(state) {\r
289                     case STATE_SET_IN:\r
290                         state_str = 'STATE_SET_IN';\r
291                         break;\r
292                     case STATE_SET_OUT:\r
293                         state_str = 'STATE_SET_OUT';\r
294                         break;\r
295                     case STATE_SET_IN_PENDING:\r
296                         state_str = 'STATE_SET_IN_PENDING';\r
297                         break;\r
298                     case STATE_SET_OUT_PENDING:\r
299                         state_str = 'STATE_SET_OUT_PENDING';\r
300                         break;\r
301                     case STATE_SET_IN_SUCCESS:\r
302                         state_str = 'STATE_SET_IN_SUCCESS';\r
303                         break;\r
304                     case STATE_SET_OUT_SUCCESS:\r
305                         state_str = 'STATE_SET_OUT_SUCCESS';\r
306                         break;\r
307                     case STATE_SET_IN_FAILURE:\r
308                         state_str = 'STATE_SET_IN_FAILURE';\r
309                         break;\r
310                     case STATE_SET_OUT_FAILURE:\r
311                         state_str = 'STATE_SET_OUT_FAILURE';\r
312                         break;\r
313                 }\r
314                 console.log("LEASE", new Date(lease.start_time * 1000), new Date(lease.end_time * 1000), lease.resource, state_str);\r
315             });\r
316         };\r
317   \r
318 \r
319 /*\r
320         $scope.setPage = function(page) {\r
321             var tmpFrm = $scope.items_per_page * page;\r
322             var tmpTo = tmpFrm + $scope.items_per_page;\r
323             tmpTo = SchedulerDataViewData.length < tmpTo ? SchedulerDataViewData.length : tmpTo;\r
324             $scope.current_page = page;\r
325             $scope.resources = [];\r
326             var j = 0;\r
327             for (var k = tmpFrm; k < tmpTo; k++) {\r
328                 $scope.resources.push(jQuery.extend(true, {}, SchedulerDataViewData[k]));\r
329                 $scope.resources[j].leases = [];\r
330                 j++;\r
331             }\r
332             //fix slider\r
333             $('#tblSlider').slider('value', 0);\r
334             //init Slots\r
335             $scope.initSlots(0, SchedulerTotalVisibleCells);\r
336         };*/\r
337 \r
338         // Typically we will only init visible slots\r
339         $scope.initSlots = function (from, to) {\r
340             return; // JORDAN !!!\r
341 \r
342             //init\r
343             $scope.slots = [];\r
344 \r
345             var resourceIndex; //gia to paging\r
346             //set\r
347             for (var i = from; i < to; i++) {\r
348                 $scope.slots.push(SchedulerSlots[i]);\r
349                 resourceIndex = $scope.items_per_page * $scope.current_page;\r
350                 for (var j = 0; j < $scope.resources.length; j++) {\r
351                     if (i == from) {\r
352                         $scope.resources[j].leases = [];\r
353                     }\r
354                     $scope.resources[j].leases.push(SchedulerDataViewData[resourceIndex].leases[i]);\r
355                     resourceIndex++;\r
356                 }\r
357             }\r
358             //apply\r
359             $scope.$apply();\r
360         };\r
361 \r
362 /*\r
363         $scope.getPageNumbers = function () {\r
364             var totalNumbersShowned = ($scope.totalPages > 10 ? 10 : $scope.totalPages + 1 );\r
365             var tmtNumDiv = totalNumbersShowned / 2;\r
366             //local\r
367             var numFrom = 1;\r
368             var numTo = totalNumbersShowned;\r
369             var rtrnArr = new Array();\r
370 \r
371             if (totalNumbersShowned > 1) {\r
372                 //set from - to\r
373                 if ($scope.totalPages > totalNumbersShowned) {\r
374                     if ($scope.current_page <= tmtNumDiv) {\r
375                         //nothing\r
376                     } else if ($scope.current_page >= $scope.totalPages - tmtNumDiv) {\r
377                         numTo = $scope.totalPages;\r
378                         numFrom = numTo - totalNumbersShowned;\r
379                     } else {\r
380                         numFrom = $scope.current_page - tmtNumDiv;\r
381                         numTo = numFrom + totalNumbersShowned;\r
382                     }\r
383                 }\r
384 \r
385                 for (var i = numFrom; i < numTo; i++)\r
386                     rtrnArr.push(i);\r
387             } else {\r
388                 rtrnArr.push(1);\r
389             }\r
390             return rtrnArr;\r
391         };\r
392 */\r
393         // Return this object reference.\r
394         return (this);\r
395 \r
396     }\r
397 \r
398 \r
399     // Define the Controller as the constructor function.\r
400     app.controller("SchedulerCtrl", Controller);\r
401 \r
402 \r
403 })(angular, myApp);\r