Removed dep on API
[ninja.git] / application / views / reports / js / common.js
blob6304eeeefc55f2e744b26767e459c208ee3f65ac
1 var sla_month_error_color    = 'red';
2 var sla_month_disabled_color = '#cdcdcd';
3 var sla_month_enabled_color  = '#fafafa';
4 var current_obj_type = false; // keep track of what we are viewing
5 $(document).ready(function() {
7         var direct_link_visible = false;
8         $('#current_report_params').click(function() {
9                 // make sure we always empty the field
10                 $('#link_container').html('');
11                 // .html('<form><input type="text" size="200" value="' + $('#current_report_params').attr('href') + '"></form>')
12                 if (!direct_link_visible) {
13                         $('#link_container')
14                                 .html('<form>'+_label_direct_link+' <input class="wide" type="text" value="'
15                                         + document.location.protocol + '//'
16                                         + document.location.host
17                                         + $('#current_report_params').attr('href')
18                                         + '"></form>')
19                                 .css('position', 'absolute')
20                                 .css('top', this.offsetHeight + this.offsetTop + 5)
21                                 .css('right', '0')
22                                 .show();
23                                 direct_link_visible = true;
24                 } else {
25                         $('#link_container').hide();
26                         direct_link_visible = false;
27                 }
28                 return false;
29         });
31         $('#save_report').click(function() {
32                 if (!direct_link_visible) {
33                         $('#save_report_form')
34                                 .css('position', 'absolute')
35                                 .css('top', this.offsetHeight + this.offsetTop + 5)
36                                 .css('right', '0')
37                                 .show()
38                                 .find('input[name=report_name]')
39                                         .map(function() {
40                                                 var input = this;
41                                                 if(input.value == "") {
42                                                         input.focus();
43                                                 }
44                                         });
45                                 direct_link_visible = true;
46                 } else {
47                         $('#save_report_form').hide();
48                         direct_link_visible = false;
49                 }
50                 return false;
51         });
53         $("#report_id").bind('change', function() {
54                 $("#saved_report_form").trigger('submit');
55         });
57         $('.save_report_btn').parents('form').submit(function(ev) {
58                 ev.preventDefault();
59                 loopElements();
60                 var form = $(this);
61                 if (!(check_form_values(this[0]))) {
62                         return;
63                 }
64                 var btn = form.find('.save_report_btn');
65                 btn.after(loadimg_sml);
66                 $.ajax({
67                         url: form[0].action,
68                         type: form[0].method,
69                         data: form.serialize(),
70                         complete: function() {
71                                 btn.parent().find('img:last').remove();
72                         },
73                         success: function(data, status_msg, xhr) {
74                                 if (data == null) {
75                                         $.notify(_reports_error + ": " + xhr.responseText, {'sticky': true});
76                                         return;
77                                 }
78                                 jgrowl_message(data.status_msg, _reports_success);
79                                 if (!btn[0].form.report_id)
80                                         $('form').append('<input type="hidden" name="report_id" value="'+data.report_id+'"/>');
81                                 else
82                                         $('#save_report_form').hide();
83                         },
84                         error: function(data) {
85                                 var resp;
86                                 try {
87                                         resp = $.parseJSON(data.responseText).error;
88                                 } catch (ex) {
89                                         resp = "Unknown error";
90                                 }
91                                 $.notify(_reports_error + ": " + resp, {'sticky': true});
92                                 btn.parent().find('img:last').remove();
93                         },
94                         dataType: 'json'
95                 });
96         });
98         var hostname = window.location.protocol + "//" + window.location.host;
99         $('select[name=report_type]').on('change', function( e ) {
101                 var filterable = jQuery.fn.filterable.find( $('select[name="objects[]"]') ),
102                         type = e.target.value.replace( /s$/, "" );
104                 var url = _site_domain + _index_page;
105                 url += '/listview/fetch_ajax?query=[' + type + 's] all&columns[]=key&limit=1000000';
107                 if ( filterable ) {
108                         $.ajax({
109                                 url: url,
110                                 dataType: 'json',
111                                 error: function( xhr ) {
112                                         console.log( xhr.responseText );
113                                 },
114                                 success: function( data ) {
116                                         var names = [];
118                                         for ( var i = 0; i < data.data.length; i++ ) {
119                                                 names.push( data.data[ i ].key );
120                                         }
122                                         filterable.data = new Set( names );
123                                         filterable.reset();
125                                 }
126                         });
127                 }
129         });
131         $('#sel_report_type').on('click', function() {
132                 var value = this.form.report_type.value;
133                 set_selection(value);
134                 get_members(value, function(all_names) {
135                         populate_options($('#objects_tmp'), $('#objects'), all_names);
136                 });
137         });
139         $('#start_year, #end_year').on('change', function () {
140                 var start = 0;
141                 var end = 11;
142                 // check_custom_months is supposedly initialized by the onload
143                 // handler in application/views/reports/js/reports.js or equivalent.
144                 if (check_custom_months.start_date == undefined || check_custom_months.end_date == undefined) {
145                         return;
146                 }
147                 if (this.value == check_custom_months.start_date.getFullYear()) {
148                         start = check_custom_months.start_date.getMonth();
149                 }
150                 if (this.value == check_custom_months.end_date.getFullYear()) {
151                         end = check_custom_months.end_date.getMonth();
152                 }
153                 var html = '<option></option>';
154                 for (i = start; i <= end; i++) {
155                         html += '<option value="' + (i+1) + '">' + Date.monthNames[i] + '</option>';
156                 }
157                 if (this.id == 'start_year')
158                         $('#start_month').html(html);
159                 else
160                         $('#end_month').html(html);
161         });
163         $('#start_year, #end_year, #start_month, #end_month').on('change', check_custom_months);
164         $("#delete_report").click(confirm_delete_report);
166         $(".report_form").on('submit', function() {
167                 loopElements();
168                 return check_form_values();
169         });
172 function init_datepicker()
174         // datePicker Jquery plugin
175         var datepicker_enddate = (new Date()).asString();
176         $('.date-pick').datePicker({clickInput:true, startDate:_start_date, endDate:datepicker_enddate});
177         $('#cal_start').on(
178                 'dpClosed',
179                 function(e, selectedDates)
180                 {
181                         var d = selectedDates[0];
182                         if (d) {
183                                 d = new Date(d);
184                                 $('#cal_end').dpSetStartDate(d.asString());
185                         }
186                 }
187         );
188         $('#cal_end').on(
189                 'dpClosed',
190                 function(e, selectedDates)
191                 {
192                         var d = selectedDates[0];
193                         if (d) {
194                                 d = new Date(d);
195                                 $('#cal_start').dpSetEndDate(d.asString());
196                         }
197                 }
198         );
201 function show_calendar(val, update) {
202         if (val=='custom') {
203                 $("#custom_time").show();
205                 init_datepicker();
206                 init_timepicker();
208                 if (update == '') {
209                         $('input[name=start_time]').attr('value', '');
210                         $('input[name=end_time]').attr('value', '');
211                 }
212         } else {
213                 $("#custom_time").hide();
214         }
215         disable_sla_fields(val);
218 function set_selection(val) {
219         if ($.inArray(val, ['servicegroups', 'hostgroups', 'services', 'hosts']) === -1)
220                 val = 'hostgroups'; // Why? Because I found it like this
221         $('.object-list-type').text(val);
222         $('*[data-show-for]').hide()
223         $('*[data-show-for~='+val+']').show()
226 function get_members(type, cb) {
227         if (!type)
228                 return;
229         var field_name = false;
230         var empty_field = false;
232         show_progress('progress', _wait_str);
233         $.ajax({
234                 url: _site_domain + _index_page + '/ajax/group_member',
235                 data: {type: type},
236                 error: function(data) {
237                         $.notify("Unable to fetch objects: " + data.responseText, {'sticky': true});
238                 },
239                 success: function(all_names) {
240                         if(typeof cb == 'function')
241                                 cb(all_names);
242                         $('#progress').css('display', 'none');
243                 },
244                 dataType: 'json'
245         });
249 *       Populate HTML select list with supplied JSON data
251 function populate_options(tmp_field, field, json_data)
253         tmp_field.empty();
254         field.empty();
255         show_progress('progress', _wait_str);
256         var available = document.createDocumentFragment();
257         var selected = document.createDocumentFragment();
258         for (i = 0; i < (json_data ? json_data.length : 0); i++) {
259                 var option = document.createElement("option");
260                 option.appendChild(document.createTextNode(json_data[i]));
261                 available.appendChild(option);
262         }
263         tmp_field.append(available);
264         field.append(selected);
268 *       Loop through all elements of a form
269 *       Verify that all multiselect fields (right hand side)
270 *       are set to selected
272 function loopElements(f) {
273         // select all elements that doesn't contain the nosave_suffix
274         $('.multiple:not([id$=_tmp])').each(function() {
275                 if ($(this).is(':visible')) {
276                         $(this).children('option').attr('selected', 'selected');
277                 } else {
278                         $(this).children('option').attr('selected', false);
279                 }
280         });
283 function check_form_values(form)
285         if (!form)
286                 form = document.documentElement;
287         var errors = 0;
288         var err_str = '';
289         var cur_start = '';
290         var cur_end = '';
292         var rpt_type = $("select[name=report_type]", form).val();
293         if ($("#report_period", form).val() == 'custom') {
294                 if ($('input[name=type]', form).val() != 'sla') {
295                         // date validation
296                         cur_start = Date.fromString($("input[name=cal_start]", form).val());
297                         var time =  $(".time_start", form).val().split(':');
298                         cur_start.addHours(time[0]);
299                         cur_start.addMinutes(time[1]);
300                         cur_end = Date.fromString($("input[name=cal_end]", form).val());
301                         time = $(".time_end", form).val().split(':');
302                         cur_end.addHours(time[0]);
303                         cur_end.addMinutes(time[1]);
304                         var now = new Date();
305                         if (!cur_start || !cur_end) {
306                                 if (!cur_start) {
307                                         errors++;
308                                         err_str += "<li>" + _reports_invalid_startdate + ".</li>";
309                                 }
310                                 if (!cur_end) {
311                                         errors++;
312                                         err_str += "<li>" + _reports_invalid_enddate + ".</li>";
313                                 }
314                         } else {
315                                 if (cur_end > now) {
316                                         if (!confirm(_reports_enddate_infuture)) {
317                                                 return false;
318                                         } else {
319                                                 cur_end = now;
320                                         }
321                                 }
322                         }
324                         if (cur_end < cur_start) {
325                                 errors++;
326                                 err_str += "<li>" + _reports_enddate_lessthan_startdate + ".</li>";
327                                 $(".datepick-start", form).addClass("time_error");
328                                 $(".datepick-end", form).addClass("time_error");
329                         } else {
330                                 $(".datepick-start", form).removeClass("time_error");
331                                 $(".datepick-end", form).removeClass("time_error");
332                         }
333                 } else {
334                         // verify that we have years and month fields
335                         if ($('#start_year', form).val() == '' || $('#start_month', form).val() == ''
336                         || $('#end_year', form).val() == '' || $('#end_month', form).val() == '') {
337                                 errors++;
338                                 //@@@Fixme: Add translated string
339                                 err_str += "<li>Please select year and month for both start and end. ";
340                                 err_str += "<br />Please note that SLA reports can only be generated for previous months</li>";
341                         }
342                         else {
343                                 // remember: our months are 1-indexed
344                                 cur_start = new Date(0);
345                                 cur_start.setYear($("select[name=start_year]", form).val());
346                                 cur_start.addMonths(Number($("select[name=start_month]", form).val()) - 1);
348                                 cur_end = new Date(0);
349                                 cur_end.setYear($("select[name=end_year]", form).val());
350                                 cur_end.addMonths(Number($("select[name=end_month]", form).val()));
351                         }
353                         if (cur_end < cur_start) {
354                                 errors++;
355                                 err_str += "<li>" + _reports_enddate_lessthan_startdate + ".</li>";
356                                 $(".datepick-start", form).addClass("time_error");
357                                 $(".datepick-end", form).addClass("time_error");
358                         } else {
359                                 $(".datepick-start", form).removeClass("time_error");
360                                 $(".datepick-end", form).removeClass("time_error");
361                         }
362                 }
363         }
365         if ($('input[name=report_mode]:checked', form).val() != 'standard' && !$('#show_all', form).is(':checked') && $("#objects", form).is('select') && $('#objects option', form).length == 0) {
366                 errors++;
367                 err_str += "<li>" + _reports_err_str_noobjects + ".</li>";
368         }
370         if ($("#enter_sla", form).is(":visible")) {
371                 // check for sane SLA values
372                 var red_error = false;
373                 var max_val = 100;
374                 var nr_of_slas = 0;
376                 for (i=1;i<=12;i++) {
377                         var field_name = 'month_' + i;
378                         var input = $('input[id="' + field_name + '"]', form);
379                         var value = input.attr('value');
380                         value = value.replace(',', '.');
381                         if (value > max_val || isNaN(value)) {
382                                 input.css('background', sla_month_error_color);
383                                 errors++;
384                                 red_error = true;
385                         } else {
386                                 if (value != '') {
387                                         nr_of_slas++;
388                                 }
389                                 if (input.attr('disabled'))
390                                         input.css('background', sla_month_disabled_color);
391                                 else
392                                         input.css('background', sla_month_enabled_color);
393                         }
394                 }
395                 if (red_error) {
396                         err_str += '<li>' + _reports_sla_err_str + '</li>';
397                 }
399                 if (nr_of_slas == 0 && !red_error) {
400                         errors++;
401                         err_str += "<li>" + _reports_no_sla_str + "</li>";
402                 }
403         }
405         // display err_str if any
406         if (!errors) {
407                 $('#response', form).html('');
409                 $('#response', form).hide();
410                 return true;
411         }
413         // clear all style info from progress
414         var resp = $('#response', form);
415         if (!resp.length)
416                 resp = $('#response');
417         resp.attr("style", "");
418         resp.html("<ul class='alert error'>" + err_str + "</ul>");
419         window.scrollTo(0,0); // make sure user sees the error message
420         return false;
423 function moveAndSort(from, to)
425         from.find('option:selected').remove().appendTo(to);
426         to.sortOptions();
429 // init timepicker once it it is shown
430 function init_timepicker()
432         $("#time_start, #time_end").timePicker();
435 function disable_sla_fields(report_period)
437         if (!$('#month_1').length)
438                 return;
439         var now = new Date();
440         var this_month = now.getMonth()+1;
441         switch (report_period) {
442                 case 'thisyear':
443                         // weird as it seems, the following call actually ENABLES
444                         // all months. If not, we could end up with all months being
445                         // disabled for 'thisyear'
446                         disable_months(0, 12);
447                         for (i=this_month + 1;i<=12;i++)
448                         {
449                                 $('.report_form #month_' + i).val('').attr('disabled', true).css('background-color', sla_month_disabled_color);
450                         }
451                         break;
452                 case 'custom':
453                         check_custom_months();
454                         break;
455                 case 'lastmonth':
456                         enable_last_months(1);
457                         break;
458                 case 'last3months':
459                         enable_last_months(3);
460                         break;
461                 case 'last6months':
462                         enable_last_months(6);
463                         break;
464                 case 'lastyear':
465                 case 'last12months':
466                         disable_months(0, 12);
467                         break;
468                 case 'lastquarter':
469                         if(this_month <= 3){
470                                 from = 10;
471                                 to = 12;
472                         } else if (this_month <= 6) {
473                                 from = 1;
474                                 to = 3;
475                         } else if (this_month <= 9){
476                                 from = 4;
477                                 to = 6;
478                         } else {
479                                 from = 7;
480                                 to = 9;
481                         }
482                         disable_months(from, to);
483                         break;
484                 default:
485                         for (i=1;i<=12;i++)
486                         {
487                                 $('#month_' + i).attr('disabled', false).css('bgcolor', sla_month_enabled_color);
488                         }
489         }
493 function disable_months(start, end)
495         var disabled_state              = false;
496         var not_disabled_state  = false;
497         var col                                 = false;
498         start   = Number(start);
499         end     = Number(end);
500         for (i=1;i<=12;i++) {
501                 var cell = $('.report_form #month_' + i);
502                 if (start>end) {
503                         if ( i >= start || i <= end) {
504                                 cell.attr('disabled', false).css('background-color', sla_month_enabled_color);
505                         } else {
506                                 cell.val('').attr('disabled', true).css('background-color', sla_month_disabled_color);
507                         }
508                 } else {
509                         if ( i>= start && i <= end) {
510                                 cell.attr('disabled', false).css('background-color', sla_month_enabled_color);
511                         } else {
512                                 cell.val('').attr('disabled', true).css('background-color', sla_month_disabled_color);
513                         }
514                 }
515         }
519 function check_custom_months()
521         var f                   = $('.report_form').get(0);
522         // not SLA?
523         if (!f['start_month'])
524                 return;
526         if (check_custom_months.start_date == undefined) {
527                 check_custom_months.start_date = new Date(0);
528                 check_custom_months.end_date = new Date();
529                 $.ajax({
530                         url:  _site_domain + _index_page + '/sla/custom_start/',
531                         type: 'GET',
532                         dataType: 'json',
533                         success: function(data) {
534                                 if (!data.timestamp) {
535                                         $.notify("Unable to fetch oldest report timestamp: " + data.responseText, {'sticky': true});
536                                 }
537                                 check_custom_months.start_date.setTime(data.timestamp * 1000);
538                                 var html = '<option></option>';
539                                 for (i = check_custom_months.start_date.getFullYear(); i <= check_custom_months.end_date.getFullYear(); i++) {
540                                         html += '<option>' + i + '</option>';
541                                 }
542                                 $('#start_year').html(html);
543                                 $('#end_year').html(html);
544                         }
545                 });
546         }
548         var start_year  = f.start_year.value;
549         var start_month = f.start_month.value;
550         var end_year    = f.end_year.value;
551         var end_month   = f.end_month.value;
552         if (start_year == '' || end_year == '' || start_month == '' || end_month == '') {
553                 disable_months(0, 0);
554         } else if (start_year == end_year - 1 || start_year == end_year) {
555                 disable_months(start_month, end_month);
556         } else {
557                 disable_months(0, 0);
558         }
559         $('#progress').hide();
563  * Generic function to enable month_ fields
564  * depending on if selection is last 1, 3 or 6 months.
565  */
566 function enable_last_months(mnr)
568         var now = new Date();
569         var this_month = now.getMonth()+1;
570         var from = this_month - mnr;
571         var to = this_month - 1;
572         if (from <= 0)
573                 from += 12;
574         if (to <= 0)
575                 to += 12;
576         disable_months(from, to);
579 function missing_objects()
581         this.objs = [];
584 missing_objects.prototype.add = function(name)
586         if (name != '*')
587                 this.objs.push(name);
590 missing_objects.prototype.display_if_any = function()
592         if (!this.objs.length)
593                 return;
595         var info_str = _reports_missing_objects + ": ";
596         info_str += "<ul><li><img src=\"" + _site_domain + "application/views/icons/arrow-right.gif" + "\" /> " + this.objs.join('</li><li><img src="' + _site_domain + 'application/views/icons/arrow-right.gif' + '" /> ') + '</li></ul>';
597         info_str += _reports_missing_objects_pleaseremove;
598         info_str += '<a href="#" id="hide_response" style="position:absolute;top:8px;left:700px;">Close <img src="' + _site_domain + '' + 'application/views/icons/12x12/cross.gif" /></a>';
599         $('#response')
600                 .css('background','#f4f4ed url(' + _site_domain + 'application/views/icons/32x32/shield-info.png) 7px 7px no-repeat')
601                 .css("position", "relative")
602                 .css('top', '0px')
603                 .css('width','748px')
604                 .css('left', '0px')
605                 .css('padding','15px 2px 5px 50px')
606                 .css('margin-left','5px')
607                 .html(info_str);
610 function confirm_delete_report()
612         var id = $("#report_id").attr('value')
614         var is_scheduled = $('#is_scheduled').text()!='' ? true : false;
615         var msg = _reports_confirm_delete + "\n";
616         var type = $('input[name=type]').attr('value');
617         if (!id)
618                 return;
619         if (is_scheduled) {
620                 msg += _reports_confirm_delete_warning;
621         }
622         msg = msg.replace("this saved report", "the saved report '"+$('#report_id option[selected=selected]').text()+"'");
623         if (confirm(msg)) {
624                 $(this).after(loadimg_sml);
625                 $.ajax({
626                         url: _site_domain + _index_page + '/' + _controller_name + '/delete/',
627                         type: 'POST',
628                         data: {'report_id': id},
629                         complete: function() {
630                                 $(loadimg_sml).remove();
631                         },
632                         success: function(data) {
633                                 var a = document.createElement("a");
634                                 a.href = window.location.href;
635                                 if(a.search && a.search.indexOf("report_id="+id) !== -1) {
636                                         window.location.href = a.search.replace(new RegExp("report_id="+id+"&?"), "");
637                                 }
638                         },
639                         error: function(data) {
640                                 var msg;
641                                 try {
642                                         msg = $.parseJSON(data.responseText).error;
643                                 } catch (ex) {
644                                         msg = "Unknown error";
645                                 }
646                                 $.notify("Failed to delete report: " + msg, {'sticky': true});
647                         },
648                         dataType: 'json'
649                 });
650         }
653 jQuery.extend(
654         jQuery.expr[':'], {
655                 regex: function(a, i, m, r) {
656                         var r = new RegExp(m[3], 'i');
657                         return r.test(jQuery(a).text());
658                 }
659         }