Merge branch 'onelab' of ssh://git.onelab.eu/git/myslice into onelab
[unfold.git] / plugins / scheduler2 / static / js / scheduler2.js
1 /*\r
2 #\r
3 # Copyright (c) 2013 NITLab, University of Thessaly, CERTH, Greece\r
4 #\r
5 # Permission is hereby granted, free of charge, to any person obtaining a copy\r
6 # of this software and associated documentation files (the "Software"), to deal\r
7 # in the Software without restriction, including without limitation the rights\r
8 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
9 # copies of the Software, and to permit persons to whom the Software is\r
10 # furnished to do so, subject to the following conditions:\r
11 #\r
12 # The above copyright notice and this permission notice shall be included in\r
13 # all copies or substantial portions of the Software.\r
14 #\r
15 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
16 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
17 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE\r
18 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
19 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
20 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r
21 # THE SOFTWARE.\r
22 #\r
23 #\r
24 # This is a MySlice plugin for the NITOS Scheduler\r
25 # Nitos Scheduler v1\r
26 #\r
27 */\r
28 \r
29 /* some params */\r
30 var init_start_visible_index = 10;\r
31 var init_end_visible_index = 21;\r
32 var rsvrTblNm = "scheduler-reservation-table";\r
33 var SchedulerResources = [];\r
34 var schdlr_totalColums = 0;\r
35 var SetPerFun = null;\r
36 var Sched2 = null;\r
37 var Debug = true;\r
38 var schdlr_PartsInOneHour = 6;\r
39 \r
40 (function ($) {\r
41     var Scheduler2 = Plugin.extend({\r
42 \r
43         /** XXX to check\r
44          * @brief Plugin constructor\r
45          * @param options : an associative array of setting values\r
46          * @param element : \r
47          * @return : a jQuery collection of objects on which the plugin is\r
48          *     applied, which allows to maintain chainability of calls\r
49          */\r
50         init: function (options, element) {\r
51             this.classname="scheduler2";\r
52             // Call the parent constructor, see FAQ when forgotten\r
53             this._super(options, element);\r
54 \r
55             schdlr_totalColums = $("#scheduler-reservation-table th").length;\r
56 \r
57             //selection from table \r
58             $(window).keydown(function (evt) {\r
59                 if (evt.which == 17) { // ctrl\r
60                     ctrlPressed = true;\r
61                 }\r
62             }).keyup(function (evt) {\r
63                 if (evt.which == 17) { // ctrl\r
64                     ctrlPressed = false;\r
65                 }\r
66             });\r
67             $("#" + rsvrTblNm).on('mousedown', 'td', rangeMouseDown).on('mouseup', 'td', rangeMouseUp).on('mousemove', 'td', rangeMouseMove);\r
68 \r
69             // Explain this will allow query events to be handled\r
70             // What happens when we don't define some events ?\r
71             // Some can be less efficient\r
72 \r
73             if (Debug) console.time("Listening_to_queries");\r
74             /* Listening to queries */\r
75             this.listen_query(options.query_uuid, 'all_ev');\r
76             this.listen_query(options.query_all_resources_uuid, 'all_resources');\r
77             this.listen_query(options.query_lease_uuid, 'lease');\r
78             //this.listen_query(options.query_lease_uuid, 'lease');\r
79             if (Debug) console.timeEnd("Listening_to_queries");\r
80 \r
81         },\r
82 \r
83         /* PLUGIN EVENTS */\r
84         // on_show like in querytable\r
85 \r
86 \r
87         /* GUI EVENTS */\r
88 \r
89         // a function to bind events here: click change\r
90         // how to raise manifold events\r
91 \r
92 \r
93         /* GUI MANIPULATION */\r
94 \r
95         // We advise you to write function to change behaviour of the GUI\r
96         // Will use naming helpers to access content _inside_ the plugin\r
97         // always refer to these functions in the remaining of the code\r
98 \r
99         show_hide_button: function () {\r
100             // this.id, this.el, this.cl, this.elts\r
101             // same output as a jquery selector with some guarantees\r
102         },\r
103 \r
104         drawResources: function () {\r
105             \r
106             //if (Debug) this.debug('foo');\r
107             if (Debug) console.time("each:SchedulerResources");\r
108 \r
109             //scheduler-reservation-table main table columns\r
110             totalColums = $("#scheduler-reservation-table thead tr th").length;\r
111             //var totalCell = [];\r
112             //for (var i = 0; i < totalColums; i++) { totalCell.push("<td></td>"); }\r
113             //var srt_body = [];\r
114             var totalCell = "";\r
115             for (var i = 0; i < totalColums; i++) totalCell +="<td></td>"; \r
116             var srt_body = "";\r
117             \r
118             $.each(SchedulerResources, function (i, group) {\r
119                 console.log(group.groupName);\r
120                 //var groupTR = $("#ShedulerNodes tbody").html('<tr><td class="no-image verticalIndex" rowspan="' + group.resources.length + '"><div class="verticalText">' + group.groupName + '</div></td><td id="schdlr_frstTD" class="info fixed"></td></tr>');\r
121                 //var groupTR = $("#ShedulerNodes tbody").html('<tr><td class="no-image verticalIndex" rowspan="' + 30 + '"><div class="verticalText">' + group.groupName + '</div></td><td id="schdlr_frstTD" class="info fixed"></td></tr>');\r
122                 var groupTR = $("#ShedulerNodes tbody").html('<tr><td id="schdlr_frstTD" class="info fixed"></td></tr>');\r
123                 \r
124                 //$.each(group.resources.slice(0,30), function (i, resource) {\r
125                 $.each(group.resources, function (i, resource) {\r
126                     if (i == 0) {\r
127                         //$("#ShedulerNodes tbody tr:first").append('<td class="info fixed">' + resource.hostname + '</td>');\r
128                         $(groupTR).find("#schdlr_frstTD").html(resource.urn);\r
129                         //$(srt_body).html("<tr>" + totalCell + "</tr>");\r
130                     } else {\r
131                         $(groupTR).find("tr:last").after('<tr><td class="info fixed">' + resource.urn + '</td></tr>');\r
132                         //$(srt_body).find("tr:last").after("<tr>" + totalCell + "</tr>");\r
133                     }\r
134                     srt_body += "<tr>" + totalCell + "</tr>";\r
135                     //srt_body.push('<tr>'); srt_body = srt_body.concat(totalCell.concat()); srt_body.push('/<tr>');\r
136                 });\r
137             });\r
138 \r
139             //$("#scheduler-reservation-table tbody").html(srt_body.join(""));\r
140             $("#scheduler-reservation-table tbody").html(srt_body);\r
141 \r
142             if (Debug) console.timeEnd("each:SchedulerResources");\r
143             \r
144 \r
145             $("#" + rsvrTblNm + " tbody tr").each(function (index) { $(this).attr("data-trindex", index); });\r
146 \r
147         },\r
148 \r
149         /* TEMPLATES */\r
150 \r
151         // see in the html template\r
152         // How to load a template, use of mustache\r
153 \r
154         /* QUERY HANDLERS */\r
155         loadWithDate: function () {\r
156             // only convention, not strictly enforced at the moment\r
157         },\r
158         // How to make sure the plugin is not desynchronized\r
159         // He should manifest its interest in filters, fields or records\r
160         // functions triggered only if the proper listen is done\r
161 \r
162         /* all_ev QUERY HANDLERS Start */\r
163         on_all_ev_clear_records: function (data) {\r
164             //alert('all_ev clear_records');\r
165         },\r
166         on_all_ev_query_in_progress: function (data) {\r
167            // alert('all_ev query_in_progress');\r
168         },\r
169         on_all_ev_new_record: function (data) {\r
170             //alert('all_ev new_record');\r
171         },\r
172         on_all_ev_query_done: function (data) {\r
173             //alert('all_ev query_done');\r
174         },\r
175         //another plugin has modified something, that requires you to update your display. \r
176         on_all_ev_field_state_changed: function (data) {\r
177             //alert('all_ev query_done');\r
178         },\r
179         /* all_ev QUERY HANDLERS End */\r
180         /* all_resources QUERY HANDLERS Start */\r
181         on_all_resources_clear_records: function (data) {\r
182             //data is empty on load\r
183         },\r
184         on_all_resources_query_in_progress: function (data) {\r
185             //data is empty on load\r
186         },\r
187         on_all_resources_new_record: function (data) {\r
188             //console.log(data);\r
189             var tmpGroup = lookup(SchedulerResources, 'groupName', data.type);\r
190             if (tmpGroup == null) {\r
191                 tmpGroup = { groupName: data.type, resources: [] };\r
192                 SchedulerResources.push(tmpGroup);\r
193                 //if (data.type != "node")  alert('not all node');\r
194             }\r
195             tmpGroup.resources.push(data);\r
196             //alert('new_record');\r
197         },\r
198         on_all_resources_query_done: function (data) {\r
199             this.drawResources();\r
200             //data is empty on load\r
201             /* GUI setup and event binding */\r
202             this._initUI();\r
203             this._SetPeriodInPage(init_start_visible_index, init_end_visible_index);\r
204             this.loadWithDate();\r
205         },\r
206         //another plugin has modified something, that requires you to update your display. \r
207         on_all_resources_field_state_changed: function (data) {\r
208             //alert('all_resources query_done');\r
209         },\r
210         /* all_resources QUERY HANDLERS End */\r
211         /* lease QUERY HANDLERS Start */\r
212         on_lease_clear_records: function (data) { console.log('clear_records'); },\r
213         on_lease_query_in_progress: function (data) { console.log('lease_query_in_progress'); },\r
214         on_lease_new_record: function (data) { console.log('lease_new_record'); },\r
215         on_lease_query_done: function (data) { console.log('lease_query_done'); },\r
216         //another plugin has modified something, that requires you to update your display. \r
217         on_lease_field_state_changed: function (data) { console.log('lease_field_state_changed'); },\r
218         /* lease QUERY HANDLERS End */\r
219 \r
220 \r
221         // no prefix\r
222 \r
223         on_filter_added: function (filter) {\r
224 \r
225         },\r
226 \r
227         // ... be sure to list all events here\r
228 \r
229         /* RECORD HANDLERS */\r
230         on_all_new_record: function (record) {\r
231             //\r
232             alert('on_all_new_record');\r
233         },\r
234 \r
235         debug : function (log_txt) {\r
236             if (typeof window.console != 'undefined') {\r
237                 console.debug(log_txt);\r
238             }\r
239         },\r
240 \r
241         /* INTERNAL FUNCTIONS */\r
242         _initUI: function () {\r
243             if (Debug) console.time("_initUI");\r
244             //fix margins in tables\r
245             mtNodesTbl = $("#" + rsvrTblNm + " tr:first").outerHeight() + 6;\r
246             mtSchrollCon = $("#nodes").outerWidth();\r
247             $("#nodes").css("margin-top", mtNodesTbl);\r
248             $("#reservation-table-scroll-container").css("margin-left", mtSchrollCon);\r
249             SetPerFun = this._SetPeriodInPage;\r
250             //slider\r
251             $("#time-range").slider({\r
252                 range: true,\r
253                 min: 0,\r
254                 max: 24,\r
255                 step: 0.5,\r
256                 values: [init_start_visible_index, init_end_visible_index],\r
257                 slide: function (event, ui) {\r
258                     SetPerFun(ui.values[0], ui.values[1]);\r
259                 }\r
260             });\r
261             $("#DateToRes").datepicker({\r
262                 dateFormat: "yy-mm-dd",\r
263                 minDate: 0,\r
264                 numberOfMonths: 3\r
265             }).change(function () {\r
266                 //Scheduler2.loadWithDate();\r
267             }).click(function () {\r
268                 $("#ui-datepicker-div").css("z-index", 5);\r
269             });\r
270             //other stuff\r
271             fixOddEvenClasses();\r
272             $("#" + rsvrTblNm + " td:not([class])").addClass("free");\r
273             if (Debug) console.timeEnd("_initUI");\r
274         },\r
275         _SetPeriodInPage: function (start, end) {\r
276             if (Debug) console.time("_SetPeriodInPage");\r
277             ClearTableSelection();\r
278             $("#lbltime").html(GetTimeFromInt(start) + " - " + GetTimeFromInt(end));\r
279             \r
280             var start_visible_index = (start * schdlr_PartsInOneHour) + 1;\r
281             var end_visible_index = (end * schdlr_PartsInOneHour);\r
282 \r
283             //hide - show\r
284             for (i = 0; i < start_visible_index; i++) {\r
285                 $("#" + rsvrTblNm + " td:nth-child(" + i + "), #" + rsvrTblNm + " th:nth-child(" + i + ")").hide();\r
286             }\r
287             for (i = end_visible_index + 1; i <= schdlr_totalColums; i++) {\r
288                 $("#" + rsvrTblNm + " td:nth-child(" + i + "), #" + rsvrTblNm + " th:nth-child(" + i + ")").hide();\r
289             }\r
290             /*$("#" + rsvrTblNm + " td:not([class*='info']), #" + rsvrTblNm + " th:not([class*='fixed'])").hide();*/\r
291             for (i = start_visible_index; i <= end_visible_index; i++) {\r
292                 $("#" + rsvrTblNm + " td:nth-child(" + i + "), #" + rsvrTblNm + " th:nth-child(" + i + ")").show();\r
293             }\r
294 \r
295             if ($("#" + rsvrTblNm + " th:visible:first").width() > 105) {\r
296                 $("#" + rsvrTblNm + " th span").css("display", "inline")\r
297             } else {\r
298                 $("#" + rsvrTblNm + " th span").css("display", "block");\r
299             }\r
300             mtNodesTbl = $("#" + rsvrTblNm + " tr:first").outerHeight() + 6;\r
301             $("#nodes").css("margin-top", mtNodesTbl);\r
302             //$("#scroll_container").width($("#Search").width() - $("#nodes").width());\r
303             //$("#nodes th").height($("#tblReservation th:visible:first").height() - 2);\r
304             if (Debug) console.timeEnd("_SetPeriodInPage");\r
305         }\r
306     });\r
307 \r
308     //Sched2 = new Scheduler2();\r
309 \r
310     /* Plugin registration */\r
311     $.plugin('Scheduler2', Scheduler2);\r
312 \r
313     // TODO Here use cases for instanciating plugins in different ways like in the pastie.\r
314 \r
315 \r
316 })(jQuery);\r
317 \r
318 \r
319 \r