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() {
6 // handle the move-between-lists-button (> + <) and double click events
7 function move_right() {
8 var selects = $(this).parent().parent().find('select');
9 moveAndSort(selects.filter(':first'), selects.filter(':last'));
11 function move_left() {
12 var selects = $(this).parent().parent().find('select');
13 moveAndSort(selects.filter(':last'), selects.filter(':first'));
15 $('.arrow-right').click(move_right);
16 $('.arrow-left').click(move_left);
17 $('#hostgroup_tmp, #servicegroup_tmp, #host_tmp, #service_tmp, #objects_tmp').dblclick(move_right);
18 $('#hostgroup, #servicegroup, #host_name, #service_description, #objects').dblclick(move_left);
20 $('#response').on('click', "#hide_response", function() {
21 $('#response').hide('slow');
24 $(".fancybox").fancybox({
25 'overlayOpacity' : 0.7,
26 'overlayColor' : '#ffffff',
27 'hideOnContentClick' : false,
29 'autoDimensions': true,
33 $('#filter_field').keyup(function() {
34 if ($(this).attr('value') == '') {
35 MyRegexp.resetFilter($("select[id$=_tmp]").filter(":visible").attr('id'));
38 MyRegexp.selectFilter($("select[id$=_tmp]").filter(":visible").attr('id'), this.value);
41 $('#clear_filter').click(function() {
42 $('#filter_field').attr('value', '');
43 MyRegexp.resetFilter($("select[id$=_tmp]").filter(":visible").attr('id'));
44 $('#filter_field').focus();
47 var direct_link_visible = false;
48 $('#current_report_params').click(function() {
49 // make sure we always empty the field
50 $('#link_container').html('');
51 // .html('<form><input type="text" size="200" value="' + $('#current_report_params').attr('href') + '"></form>')
52 if (!direct_link_visible) {
54 .html('<form>'+_label_direct_link+' <input class="wide" type="text" value="'
55 + document.location.protocol + '//'
56 + document.location.host
57 + $('#current_report_params').attr('href')
59 .css('position', 'absolute')
60 .css('top', this.offsetHeight + this.offsetTop + 5)
63 direct_link_visible = true;
65 $('#link_container').hide();
66 direct_link_visible = false;
71 $('#save_report').click(function() {
72 if (!direct_link_visible) {
73 $('#save_report_form')
74 .css('position', 'absolute')
75 .css('top', this.offsetHeight + this.offsetTop + 5)
78 .find('input[name=report_name]')
81 if(input.value == "") {
85 direct_link_visible = true;
87 $('#save_report_form').hide();
88 direct_link_visible = false;
93 $("#report_id").bind('change', function() {
94 $("#saved_report_form").trigger('submit');
97 $('.save_report_btn').parents('form').submit(function(ev) {
101 if (!(check_form_values(this[0]))) {
104 var btn = form.find('.save_report_btn');
105 btn.after(loadimg_sml);
108 type: form[0].method,
109 data: form.serialize(),
110 complete: function() {
111 btn.parent().find('img:last').remove();
113 success: function(data, status_msg, xhr) {
115 $.notify(_reports_error + ": " + xhr.responseText, {'sticky': true});
118 jgrowl_message(data.status_msg, _reports_success);
119 if (!btn[0].form.report_id)
120 $('form').append('<input type="hidden" name="report_id" value="'+data.report_id+'"/>');
122 $('#save_report_form').hide();
124 error: function(data) {
127 resp = $.parseJSON(data.responseText).error;
129 resp = "Unknown error";
131 $.notify(_reports_error + ": " + resp, {'sticky': true});
132 btn.parent().find('img:last').remove();
138 $('select[name=report_type]').on('change', function() {
139 var value = this.value;
140 set_selection(value);
141 get_members(value, function(all_names) {
142 populate_options($('#objects_tmp'), $('#objects'), all_names);
145 var value = this.value;
146 set_selection(value);
147 get_members(value, function(all_names) {
148 populate_options($('#objects_tmp'), $(), all_names);
149 var tmp = $('#objects_tmp');
150 var mo = new missing_objects();
151 var objs = $('#objects');
152 var elems = objs.children();
153 for (var i = 0; i < elems.length; i++) {
155 if (tmp.containsOption(prop.value)) {
156 tmp.removeOption(prop.value);
159 objs.removeOption(prop.value);
165 $('#sel_report_type').on('click', function() {
166 var value = this.form.report_type.value;
167 set_selection(value);
168 get_members(value, function(all_names) {
169 populate_options($('#objects_tmp'), $('#objects'), all_names);
173 $('#start_year, #end_year').on('change', function () {
176 // check_custom_months is supposedly initialized by the onload
177 // handler in application/views/reports/js/reports.js or equivalent.
178 if (check_custom_months.start_date == undefined || check_custom_months.end_date == undefined) {
181 if (this.value == check_custom_months.start_date.getFullYear()) {
182 start = check_custom_months.start_date.getMonth();
184 if (this.value == check_custom_months.end_date.getFullYear()) {
185 end = check_custom_months.end_date.getMonth();
187 var html = '<option></option>';
188 for (i = start; i <= end; i++) {
189 html += '<option value="' + (i+1) + '">' + Date.monthNames[i] + '</option>';
191 if (this.id == 'start_year')
192 $('#start_month').html(html);
194 $('#end_month').html(html);
197 $('#start_year, #end_year, #start_month, #end_month').on('change', check_custom_months);
198 $("#delete_report").click(confirm_delete_report);
200 $(".report_form").on('submit', function() {
202 return check_form_values();
206 function init_datepicker()
208 // datePicker Jquery plugin
209 var datepicker_enddate = (new Date()).asString();
210 $('.date-pick').datePicker({clickInput:true, startDate:_start_date, endDate:datepicker_enddate});
213 function(e, selectedDates)
215 var d = selectedDates[0];
218 $('#cal_end').dpSetStartDate(d.asString());
224 function(e, selectedDates)
226 var d = selectedDates[0];
229 $('#cal_start').dpSetEndDate(d.asString());
235 function show_calendar(val, update) {
237 $("#custom_time").show();
243 $('input[name=start_time]').attr('value', '');
244 $('input[name=end_time]').attr('value', '');
247 $("#custom_time").hide();
249 disable_sla_fields(val);
252 function set_selection(val) {
253 if ($.inArray(val, ['servicegroups', 'hostgroups', 'services', 'hosts']) === -1)
254 val = 'hostgroups'; // Why? Because I found it like this
255 $('.object-list-type').text(val);
256 $('*[data-show-for]').hide()
257 $('*[data-show-for~='+val+']').show()
260 function get_members(type, cb) {
263 var field_name = false;
264 var empty_field = false;
266 show_progress('progress', _wait_str);
268 url: _site_domain + _index_page + '/ajax/group_member',
270 error: function(data) {
271 $.notify("Unable to fetch objects: " + data.responseText, {'sticky': true});
273 success: function(all_names) {
274 if(typeof cb == 'function')
276 $('#progress').css('display', 'none');
283 * Populate HTML select list with supplied JSON data
285 function populate_options(tmp_field, field, json_data)
289 show_progress('progress', _wait_str);
290 var available = document.createDocumentFragment();
291 var selected = document.createDocumentFragment();
292 for (i = 0; i < (json_data ? json_data.length : 0); i++) {
293 var option = document.createElement("option");
294 option.appendChild(document.createTextNode(json_data[i]));
295 available.appendChild(option);
297 tmp_field.append(available);
298 field.append(selected);
302 * Loop through all elements of a form
303 * Verify that all multiselect fields (right hand side)
304 * are set to selected
306 function loopElements(f) {
307 // select all elements that doesn't contain the nosave_suffix
308 $('.multiple:not([id$=_tmp])').each(function() {
309 if ($(this).is(':visible')) {
310 $(this).children('option').attr('selected', 'selected');
312 $(this).children('option').attr('selected', false);
317 function check_form_values(form)
320 form = document.documentElement;
326 var rpt_type = $("select[name=report_type]", form).val();
327 if ($("#report_period", form).val() == 'custom') {
328 if ($('input[name=type]', form).val() != 'sla') {
330 cur_start = Date.fromString($("input[name=cal_start]", form).val());
331 var time = $(".time_start", form).val().split(':');
332 cur_start.addHours(time[0]);
333 cur_start.addMinutes(time[1]);
334 cur_end = Date.fromString($("input[name=cal_end]", form).val());
335 time = $(".time_end", form).val().split(':');
336 cur_end.addHours(time[0]);
337 cur_end.addMinutes(time[1]);
338 var now = new Date();
339 if (!cur_start || !cur_end) {
342 err_str += "<li>" + _reports_invalid_startdate + ".</li>";
346 err_str += "<li>" + _reports_invalid_enddate + ".</li>";
350 if (!confirm(_reports_enddate_infuture)) {
358 if (cur_end < cur_start) {
360 err_str += "<li>" + _reports_enddate_lessthan_startdate + ".</li>";
361 $(".datepick-start", form).addClass("time_error");
362 $(".datepick-end", form).addClass("time_error");
364 $(".datepick-start", form).removeClass("time_error");
365 $(".datepick-end", form).removeClass("time_error");
368 // verify that we have years and month fields
369 if ($('#start_year', form).val() == '' || $('#start_month', form).val() == ''
370 || $('#end_year', form).val() == '' || $('#end_month', form).val() == '') {
372 //@@@Fixme: Add translated string
373 err_str += "<li>Please select year and month for both start and end. ";
374 err_str += "<br />Please note that SLA reports can only be generated for previous months</li>";
377 // remember: our months are 1-indexed
378 cur_start = new Date(0);
379 cur_start.setYear($("select[name=start_year]", form).val());
380 cur_start.addMonths(Number($("select[name=start_month]", form).val()) - 1);
382 cur_end = new Date(0);
383 cur_end.setYear($("select[name=end_year]", form).val());
384 cur_end.addMonths(Number($("select[name=end_month]", form).val()));
387 if (cur_end < cur_start) {
389 err_str += "<li>" + _reports_enddate_lessthan_startdate + ".</li>";
390 $(".datepick-start", form).addClass("time_error");
391 $(".datepick-end", form).addClass("time_error");
393 $(".datepick-start", form).removeClass("time_error");
394 $(".datepick-end", form).removeClass("time_error");
399 if ($('input[name=report_mode]:checked', form).val() != 'standard' && !$('#show_all', form).is(':checked') && $("#objects", form).is('select') && $('#objects option', form).length == 0) {
401 err_str += "<li>" + _reports_err_str_noobjects + ".</li>";
404 if ($("#enter_sla", form).is(":visible")) {
405 // check for sane SLA values
406 var red_error = false;
410 for (i=1;i<=12;i++) {
411 var field_name = 'month_' + i;
412 var input = $('input[id="' + field_name + '"]', form);
413 var value = input.attr('value');
414 value = value.replace(',', '.');
415 if (value > max_val || isNaN(value)) {
416 input.css('background', sla_month_error_color);
423 if (input.attr('disabled'))
424 input.css('background', sla_month_disabled_color);
426 input.css('background', sla_month_enabled_color);
430 err_str += '<li>' + _reports_sla_err_str + '</li>';
433 if (nr_of_slas == 0 && !red_error) {
435 err_str += "<li>" + _reports_no_sla_str + "</li>";
439 // display err_str if any
441 $('#response', form).html('');
443 $('#response', form).hide();
447 // clear all style info from progress
448 var resp = $('#response', form);
450 resp = $('#response');
451 resp.attr("style", "");
452 resp.html("<ul class='alert error'>" + err_str + "</ul>");
453 window.scrollTo(0,0); // make sure user sees the error message
457 function moveAndSort(from, to)
459 from.find('option:selected').remove().appendTo(to);
463 // init timepicker once it it is shown
464 function init_timepicker()
466 $("#time_start, #time_end").timePicker();
469 function disable_sla_fields(report_period)
471 if (!$('#month_1').length)
473 var now = new Date();
474 var this_month = now.getMonth()+1;
475 switch (report_period) {
477 // weird as it seems, the following call actually ENABLES
478 // all months. If not, we could end up with all months being
479 // disabled for 'thisyear'
480 disable_months(0, 12);
481 for (i=this_month + 1;i<=12;i++)
483 $('.report_form #month_' + i).val('').attr('disabled', true).css('background-color', sla_month_disabled_color);
487 check_custom_months();
490 enable_last_months(1);
493 enable_last_months(3);
496 enable_last_months(6);
500 disable_months(0, 12);
506 } else if (this_month <= 6) {
509 } else if (this_month <= 9){
516 disable_months(from, to);
521 $('#month_' + i).attr('disabled', false).css('bgcolor', sla_month_enabled_color);
527 function disable_months(start, end)
529 var disabled_state = false;
530 var not_disabled_state = false;
532 start = Number(start);
534 for (i=1;i<=12;i++) {
535 var cell = $('.report_form #month_' + i);
537 if ( i >= start || i <= end) {
538 cell.attr('disabled', false).css('background-color', sla_month_enabled_color);
540 cell.val('').attr('disabled', true).css('background-color', sla_month_disabled_color);
543 if ( i>= start && i <= end) {
544 cell.attr('disabled', false).css('background-color', sla_month_enabled_color);
546 cell.val('').attr('disabled', true).css('background-color', sla_month_disabled_color);
553 function check_custom_months()
555 var f = $('.report_form').get(0);
557 if (!f['start_month'])
560 if (check_custom_months.start_date == undefined) {
561 check_custom_months.start_date = new Date(0);
562 check_custom_months.end_date = new Date();
564 url: _site_domain + _index_page + '/sla/custom_start/',
567 success: function(data) {
568 if (!data.timestamp) {
569 $.notify("Unable to fetch oldest report timestamp: " + data.responseText, {'sticky': true});
571 check_custom_months.start_date.setTime(data.timestamp * 1000);
572 var html = '<option></option>';
573 for (i = check_custom_months.start_date.getFullYear(); i <= check_custom_months.end_date.getFullYear(); i++) {
574 html += '<option>' + i + '</option>';
576 $('#start_year').html(html);
577 $('#end_year').html(html);
582 var start_year = f.start_year.value;
583 var start_month = f.start_month.value;
584 var end_year = f.end_year.value;
585 var end_month = f.end_month.value;
586 if (start_year == '' || end_year == '' || start_month == '' || end_month == '') {
587 disable_months(0, 0);
588 } else if (start_year == end_year - 1 || start_year == end_year) {
589 disable_months(start_month, end_month);
591 disable_months(0, 0);
593 $('#progress').hide();
597 * Generic function to enable month_ fields
598 * depending on if selection is last 1, 3 or 6 months.
600 function enable_last_months(mnr)
602 var now = new Date();
603 var this_month = now.getMonth()+1;
604 var from = this_month - mnr;
605 var to = this_month - 1;
610 disable_months(from, to);
613 function missing_objects()
618 missing_objects.prototype.add = function(name)
621 this.objs.push(name);
624 missing_objects.prototype.display_if_any = function()
626 if (!this.objs.length)
629 var info_str = _reports_missing_objects + ": ";
630 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>';
631 info_str += _reports_missing_objects_pleaseremove;
632 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>';
634 .css('background','#f4f4ed url(' + _site_domain + 'application/views/icons/32x32/shield-info.png) 7px 7px no-repeat')
635 .css("position", "relative")
637 .css('width','748px')
639 .css('padding','15px 2px 5px 50px')
640 .css('margin-left','5px')
644 function confirm_delete_report()
646 var id = $("#report_id").attr('value')
648 var is_scheduled = $('#is_scheduled').text()!='' ? true : false;
649 var msg = _reports_confirm_delete + "\n";
650 var type = $('input[name=type]').attr('value');
654 msg += _reports_confirm_delete_warning;
656 msg = msg.replace("this saved report", "the saved report '"+$('#report_id option[selected=selected]').text()+"'");
658 $(this).after(loadimg_sml);
660 url: _site_domain + _index_page + '/' + _controller_name + '/delete/',
662 data: {'report_id': id},
663 complete: function() {
664 $(loadimg_sml).remove();
666 success: function(data) {
667 var a = document.createElement("a");
668 a.href = window.location.href;
669 if(a.search && a.search.indexOf("report_id="+id) !== -1) {
670 window.location.href = a.search.replace(new RegExp("report_id="+id+"&?"), "");
673 error: function(data) {
676 msg = $.parseJSON(data.responseText).error;
678 msg = "Unknown error";
680 $.notify("Failed to delete report: " + msg, {'sticky': true});
689 regex: function(a, i, m, r) {
690 var r = new RegExp(m[3], 'i');
691 return r.test(jQuery(a).text());
697 * Regexp filter that (hopefully) works for all browsers
700 function init_regexpfilter() {
701 MyRegexp = new Object();
702 MyRegexp.selectFilterData = new Object();
703 MyRegexp.selectFilter = function(selectId, filter) {
704 var list = document.getElementById(selectId);
705 if(!MyRegexp.selectFilterData[selectId]) {
706 //if we don't have a list of all the options, cache them now'
707 MyRegexp.selectFilterData[selectId] = new Array();
708 for(var i = 0; i < list.options.length; i++)
709 MyRegexp.selectFilterData[selectId][i] = list.options[i];
711 list.options.length = 0; //remove all elements from the list
712 var r = new RegExp(filter, 'i');
713 for(var i = 0; i < MyRegexp.selectFilterData[selectId].length; i++) {
714 //add elements from cache if they match filter
715 var o = MyRegexp.selectFilterData[selectId][i];
716 //if(o.text.toLowerCase().indexOf(filter.toLowerCase()) >= 0) list.add(o, null);
717 if(!o.parentNode && r.test(o.text)) list.add(o, null);
720 MyRegexp.resetFilter = function(selectId) {
721 if (typeof MyRegexp.selectFilterData[selectId] == 'undefined' || !MyRegexp.selectFilterData[selectId].length)
723 var list = document.getElementById(selectId);
724 list.options.length = 0; //remove all elements from the list
725 for(var i = 0; i < MyRegexp.selectFilterData[selectId].length; i++) {
726 //add elements from cache if they match filter
727 var o = MyRegexp.selectFilterData[selectId][i];