2 var sla_month_error_color
= 'red';
3 var sla_month_disabled_color
= '#cdcdcd';
4 var sla_month_enabled_color
= '#fafafa';
5 var nr_of_scheduled_instances
= 0;
6 var current_obj_type
= false; // keep track of what we are viewing
7 $(document
).ready(function() {
8 // handle the move-between-lists-button (> + <) and double click events
9 function move_right() {
10 var selects
= $(this).parent().parent().find('select');
11 moveAndSort(selects
.filter(':first'), selects
.filter(':last'));
13 function move_left() {
14 var selects
= $(this).parent().parent().find('select');
15 moveAndSort(selects
.filter(':last'), selects
.filter(':first'));
17 $('.arrow-right').click(move_right
);
18 $('.arrow-left').click(move_left
);
19 $('#hostgroup_tmp, #servicegroup_tmp, #host_tmp, #service_tmp, #objects_tmp').dblclick(move_right
);
20 $('#hostgroup, #servicegroup, #host_name, #service_description, #objects').dblclick(move_left
);
22 $("#hide_response").click(function() {
23 $('#response').hide('slow');
26 $(".fancybox").fancybox({
27 'overlayOpacity' : 0.7,
28 'overlayColor' : '#ffffff',
29 'hideOnContentClick' : false,
31 'autoDimensions': true,
35 $('#filter_field').keyup(function() {
36 if ($(this).attr('value') == '') {
37 MyRegexp
.resetFilter($("select[id$=_tmp]").filter(":visible").attr('id'));
40 MyRegexp
.selectFilter($("select[id$=_tmp]").filter(":visible").attr('id'), this.value
);
43 $('#clear_filter').click(function() {
44 $('#filter_field').attr('value', '');
45 MyRegexp
.resetFilter($("select[id$=_tmp]").filter(":visible").attr('id'));
46 $('#filter_field').focus();
49 var direct_link_visible
= false;
50 $('#current_report_params').click(function() {
51 // make sure we always empty the field
52 $('#link_container').html('');
53 // .html('<form><input type="text" size="200" value="' + $('#current_report_params').attr('href') + '"></form>')
54 if (!direct_link_visible
) {
56 .html('<form>'+_label_direct_link
+' <input class="wide" type="text" value="'
57 + document
.location
.protocol
+ '//'
58 + document
.location
.host
59 + $('#current_report_params').attr('href')
61 .css('position', 'absolute')
62 .css('top', this.offsetHeight
+ this.offsetTop
+ 5)
65 direct_link_visible
= true;
67 $('#link_container').hide();
68 direct_link_visible
= false;
73 $('#save_report').click(function() {
74 if (!direct_link_visible
) {
75 $('#save_report_form')
76 .css('position', 'absolute')
77 .css('top', this.offsetHeight
+ this.offsetTop
+ 5)
80 .find('input[name=report_name]')
83 if(input
.value
== "") {
87 direct_link_visible
= true;
89 $('#save_report_form').hide();
90 direct_link_visible
= false;
95 $("#report_id").bind('change', function() {
96 $("#saved_report_form").trigger('submit');
99 $('.save_report_btn').parents('form').submit(function(ev
) {
103 if (!(check_form_values(this[0]))) {
106 var btn
= form
.find('.save_report_btn');
110 type
: form
[0].method
,
111 data
: form
.serialize(),
112 complete: function() {
113 btn
.parent().find('img:last').remove();
115 success: function(data
, status_msg
, xhr
) {
117 $.notify(_reports_error
+ ": " + xhr
.responseText
, {'sticky': true});
120 jgrowl_message(data
.status_msg
, _reports_success
);
121 if (!btn
[0].form
.report_id
)
122 $('form').append('<input type="hidden" name="report_id" value="'+data
.report_id
+'"/>');
124 $('#save_report_form').hide();
126 error: function(data
) {
127 $.notify(_reports_error
+ ": " + data
.responseText
, {'sticky': true});
128 btn
.parent().find('img:last').remove();
134 $('select[name=report_type]').on('change', function() {
135 var value
= this.value
;
136 set_selection(value
);
137 get_members(value
, function(all_names
) {
138 populate_options($('#objects_tmp'), $('#objects'), all_names
);
141 var value
= this.value
;
142 set_selection(value
);
143 get_members(value
, function(all_names
) {
144 populate_options($('#objects_tmp'), $(), all_names
);
145 var tmp
= $('#objects_tmp');
146 var mo
= new missing_objects();
147 var elems
= $('#objects').children();
148 for (var i
= 0; i
< elems
.length
; i
++) {
150 if (tmp
.containsOption(prop
.value
))
151 tmp
.removeOption(prop
.value
);
158 $('#sel_report_type').on('click', function() {
159 var value
= this.form
.report_type
.value
;
160 set_selection(value
);
161 get_members(value
, function(all_names
) {
162 populate_options($('#objects_tmp'), $('#objects'), all_names
);
166 $('#start_year, #end_year').on('change', function () {
169 // check_custom_months is supposedly initialized by the onload
170 // handler in application/views/reports/js/reports.js or equivalent.
171 if (check_custom_months
.start_date
== undefined || check_custom_months
.end_date
== undefined) {
174 if (this.value
== check_custom_months
.start_date
.getFullYear()) {
175 start
= check_custom_months
.start_date
.getMonth();
177 if (this.value
== check_custom_months
.end_date
.getFullYear()) {
178 end
= check_custom_months
.end_date
.getMonth();
180 var html
= '<option></option>';
181 for (i
= start
; i
<= end
; i
++) {
182 html
+= '<option value="' + (i
+1) + '">' + Date
.monthNames
[i
] + '</option>';
184 if (this.id
== 'start_year')
185 $('#start_month').html(html
);
187 $('#end_month').html(html
);
190 $('#start_year, #end_year, #start_month, #end_month').on('change', check_custom_months
);
191 $("#delete_report").click(confirm_delete_report
);
193 $(".report_form").on('submit', function() {
195 return check_form_values();
199 var loadimg
= new Image(16,16);
200 loadimg
.src
= _site_domain
+ 'application/media/images/loading_small.gif';
202 function init_datepicker()
204 // datePicker Jquery plugin
205 var datepicker_enddate
= (new Date()).asString();
206 $('.date-pick').datePicker({clickInput
:true, startDate
:_start_date
, endDate
:datepicker_enddate
});
209 function(e
, selectedDates
)
211 var d
= selectedDates
[0];
214 $('#cal_end').dpSetStartDate(d
.asString());
220 function(e
, selectedDates
)
222 var d
= selectedDates
[0];
225 $('#cal_start').dpSetEndDate(d
.asString());
231 function show_calendar(val
, update
) {
233 $("#custom_time").show();
239 $('input[name=start_time]').attr('value', '');
240 $('input[name=end_time]').attr('value', '');
243 $("#custom_time").hide();
245 disable_sla_fields(val
);
248 function set_selection(val
) {
249 if ($.inArray(val
, ['servicegroups', 'hostgroups', 'services', 'hosts']) === -1)
250 val
= 'hostgroups'; // Why? Because I found it like this
251 $('.object-list-type').text(val
);
252 $('*[data-show-for]').hide()
253 $('*[data-show-for~='+val
+']').show()
256 function get_members(type
, cb
) {
259 var field_name
= false;
260 var empty_field
= false;
262 show_progress('progress', _wait_str
);
264 url
: _site_domain
+ _index_page
+ '/ajax/group_member',
266 error: function(data
) {
267 $.notify("Unable to fetch objects: " + data
.responseText
, {'sticky': true});
269 success: function(all_names
) {
270 if(typeof cb
== 'function')
272 $('#progress').css('display', 'none');
279 * Populate HTML select list with supplied JSON data
281 function populate_options(tmp_field
, field
, json_data
)
285 show_progress('progress', _wait_str
);
286 var available
= document
.createDocumentFragment();
287 var selected
= document
.createDocumentFragment();
288 for (i
= 0; i
< (json_data
? json_data
.length
: 0); i
++) {
289 var option
= document
.createElement("option");
290 option
.appendChild(document
.createTextNode(json_data
[i
]));
291 available
.appendChild(option
);
293 tmp_field
.append(available
);
294 field
.append(selected
);
298 * Loop through all elements of a form
299 * Verify that all multiselect fields (right hand side)
300 * are set to selected
302 function loopElements(f
) {
303 // select all elements that doesn't contain the nosave_suffix
304 $('.multiple:not([id$=_tmp])').each(function() {
305 if ($(this).is(':visible')) {
306 $(this).children('option').attr('selected', 'selected');
308 $(this).children('option').attr('selected', false);
313 function check_form_values(form
)
316 form
= document
.documentElement
;
322 var rpt_type
= $("select[name=report_type]", form
).val();
323 if ($("#report_period", form
).val() == 'custom') {
324 if ($('input[name=type]', form
).val() != 'sla') {
326 cur_start
= Date
.fromString($("input[name=cal_start]", form
).val());
327 var time
= $(".time_start", form
).val().split(':');
328 cur_start
.addHours(time
[0]);
329 cur_start
.addMinutes(time
[1]);
330 cur_end
= Date
.fromString($("input[name=cal_end]", form
).val());
331 time
= $(".time_end", form
).val().split(':');
332 cur_end
.addHours(time
[0]);
333 cur_end
.addMinutes(time
[1]);
334 var now
= new Date();
335 if (!cur_start
|| !cur_end
) {
338 err_str
+= "<li>" + _reports_invalid_startdate
+ ".</li>";
342 err_str
+= "<li>" + _reports_invalid_enddate
+ ".</li>";
346 if (!confirm(_reports_enddate_infuture
)) {
354 if (cur_end
< cur_start
) {
356 err_str
+= "<li>" + _reports_enddate_lessthan_startdate
+ ".</li>";
357 $(".datepick-start", form
).addClass("time_error");
358 $(".datepick-end", form
).addClass("time_error");
360 $(".datepick-start", form
).removeClass("time_error");
361 $(".datepick-end", form
).removeClass("time_error");
364 // verify that we have years and month fields
365 if ($('#start_year', form
).val() == '' || $('#start_month', form
).val() == ''
366 || $('#end_year', form
).val() == '' || $('#end_month', form
).val() == '') {
368 //@@@Fixme: Add translated string
369 err_str
+= "<li>Please select year and month for both start and end. ";
370 err_str
+= "<br />Please note that SLA reports can only be generated for previous months</li>";
373 // remember: our months are 1-indexed
374 cur_start
= new Date(0);
375 cur_start
.setYear($("select[name=start_year]", form
).val());
376 cur_start
.addMonths(Number($("select[name=start_month]", form
).val()) - 1);
378 cur_end
= new Date(0);
379 cur_end
.setYear($("select[name=end_year]", form
).val());
380 cur_end
.addMonths(Number($("select[name=end_month]", form
).val()));
383 if (cur_end
< cur_start
) {
385 err_str
+= "<li>" + _reports_enddate_lessthan_startdate
+ ".</li>";
386 $(".datepick-start", form
).addClass("time_error");
387 $(".datepick-end", form
).addClass("time_error");
389 $(".datepick-start", form
).removeClass("time_error");
390 $(".datepick-end", form
).removeClass("time_error");
395 if ($('input[name=report_mode]:checked', form
).val() != 'standard' && !$('#show_all', form
).is(':checked') && $("#objects", form
).is('select') && $('#objects option', form
).length
== 0) {
397 err_str
+= "<li>" + _reports_err_str_noobjects
+ ".</li>";
400 if ($("#enter_sla", form
).is(":visible")) {
401 // check for sane SLA values
402 var red_error
= false;
406 for (i
=1;i
<=12;i
++) {
407 var field_name
= 'month_' + i
;
408 var input
= $('input[id="' + field_name
+ '"]', form
);
409 var value
= input
.attr('value');
410 value
= value
.replace(',', '.');
411 if (value
> max_val
|| isNaN(value
)) {
412 input
.css('background', sla_month_error_color
);
419 if (input
.attr('disabled'))
420 input
.css('background', sla_month_disabled_color
);
422 input
.css('background', sla_month_enabled_color
);
426 err_str
+= '<li>' + _reports_sla_err_str
+ '</li>';
429 if (nr_of_slas
== 0 && !red_error
) {
431 err_str
+= "<li>" + _reports_no_sla_str
+ "</li>";
435 // create array prototype to sole the lack of in_array() in javascript
436 Array
.prototype.has = function(value
) {
438 for (var i
= 0, loopCnt
= this.length
; i
< loopCnt
; i
++) {
439 if (this[i
] === value
) {
446 var report_name
= $("input[name=report_name]", form
).attr('value');
447 report_name
= $.trim(report_name
);
448 var saved_report_id
= $("input[name=saved_report_id]", form
).attr('value');
449 var do_save_report
= $('input[name=save_report_settings]', form
).is(':checked') ? 1 : 0;
452 * Only perform checks if:
453 * - Saved report exists
454 * - User checked the 'Save Report' checkbox
455 * - We are currently editing a report (i.e. have saved_report_id)
457 if ($('#report_id', form
) && do_save_report
&& saved_report_id
) {
458 // Saved reports exists
459 $('#report_id option', form
).each(function(i
) {
460 if ($(this).val()) {// first item is empty
461 if (saved_report_id
!= $(this).val()) {
462 // check all the other saved reports
463 // make sure we don't miss the scheduled reports
464 var chk_text
= $(this).text();
465 chk_text
= chk_text
.replace(" ( *" + _scheduled_label
+ "* )", '');
466 if (report_name
== chk_text
) {
467 // trying to save an item with an existing name
469 err_str
+= "<li>" + _reports_error_name_exists
+ ".</li>";
475 } else if (do_save_report
&& report_name
== '') {
476 // trying to save a report without a name
478 err_str
+= "<li>" + _reports_name_empty
+ "</li>";
481 // display err_str if any
483 $('#response', form
).html('');
485 $('#response', form
).hide();
489 // clear all style info from progress
490 var resp
= $('#response', form
);
492 resp
= $('#response');
493 resp
.attr("style", "");
494 resp
.html("<ul class='alert error'>" + err_str
+ "</ul>");
495 window
.scrollTo(0,0); // make sure user sees the error message
499 function moveAndSort(from, to
)
501 from.find('option:selected').remove().appendTo(to
);
505 // init timepicker once it it is shown
506 function init_timepicker()
508 $("#time_start, #time_end").timePicker();
511 function disable_sla_fields(report_period
)
513 if (!$('#month_1').length
)
515 var now
= new Date();
516 var this_month
= now
.getMonth()+1;
517 switch (report_period
) {
519 // weird as it seems, the following call actually ENABLES
520 // all months. If not, we could end up with all months being
521 // disabled for 'thisyear'
522 disable_months(0, 12);
523 for (i
=this_month
+ 1;i
<=12;i
++)
525 $('.report_form #month_' + i
).val('').attr('disabled', true).css('background-color', sla_month_disabled_color
);
529 check_custom_months();
532 enable_last_months(1);
535 enable_last_months(3);
538 enable_last_months(6);
542 disable_months(0, 12);
548 } else if (this_month
<= 6) {
551 } else if (this_month
<= 9){
558 disable_months(from, to
);
563 $('#month_' + i
).attr('disabled', false).css('bgcolor', sla_month_enabled_color
);
569 function disable_months(start
, end
)
571 var disabled_state
= false;
572 var not_disabled_state
= false;
574 start
= Number(start
);
576 for (i
=1;i
<=12;i
++) {
577 var cell
= $('.report_form #month_' + i
);
579 if ( i
>= start
|| i
<= end
) {
580 cell
.attr('disabled', false).css('background-color', sla_month_enabled_color
);
582 cell
.val('').attr('disabled', true).css('background-color', sla_month_disabled_color
);
585 if ( i
>= start
&& i
<= end
) {
586 cell
.attr('disabled', false).css('background-color', sla_month_enabled_color
);
588 cell
.val('').attr('disabled', true).css('background-color', sla_month_disabled_color
);
595 function check_custom_months()
597 var f
= $('.report_form').get(0);
599 if (!f
['start_month'])
602 if (check_custom_months
.start_date
== undefined) {
603 check_custom_months
.start_date
= new Date(0);
604 check_custom_months
.end_date
= new Date();
606 url
: _site_domain
+ _index_page
+ '/sla/custom_start/',
609 success: function(data
) {
610 if (!data
.timestamp
) {
611 $.notify("Unable to fetch oldest report timestamp: " + data
.responseText
, {'sticky': true});
613 check_custom_months
.start_date
.setTime(data
.timestamp
* 1000);
614 var html
= '<option></option>';
615 for (i
= check_custom_months
.start_date
.getFullYear(); i
<= check_custom_months
.end_date
.getFullYear(); i
++) {
616 html
+= '<option>' + i
+ '</option>';
618 $('#start_year').html(html
);
619 $('#end_year').html(html
);
624 var start_year
= f
.start_year
.value
;
625 var start_month
= f
.start_month
.value
;
626 var end_year
= f
.end_year
.value
;
627 var end_month
= f
.end_month
.value
;
628 if (start_year
!='' && end_year
!='' && start_month
!='' && end_month
!='') {
629 disable_months(0, 0);
630 } else if (start_year
== end_year
- 1 || start_year
== end_year
) {
631 disable_months(start_month
, end_month
);
633 disable_months(0, 0);
635 $('#progress').hide();
639 * Generic function to enable month_ fields
640 * depending on if selection is last 1, 3 or 6 months.
642 function enable_last_months(mnr
)
644 var now
= new Date();
645 var this_month
= now
.getMonth()+1;
646 var from = this_month
- mnr
;
647 var to
= this_month
- 1;
652 disable_months(from, to
);
655 function missing_objects()
660 missing_objects
.prototype.add = function(name
)
663 this.objs
.push(name
);
666 missing_objects
.prototype.display_if_any = function()
668 if (!this.objs
.length
)
671 var info_str
= _reports_missing_objects
+ ": ";
672 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>';
673 info_str
+= _reports_missing_objects_pleaseremove
;
674 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>';
676 .css('background','#f4f4ed url(' + _site_domain
+ 'application/views/icons/32x32/shield-info.png) 7px 7px no-repeat')
677 .css("position", "relative")
679 .css('width','748px')
681 .css('padding','15px 2px 5px 50px')
682 .css('margin-left','5px')
686 function confirm_delete_report()
689 var id
= $("#report_id").attr('value')
691 var is_scheduled
= $('#is_scheduled').text()!='' ? true : false;
692 var msg
= _reports_confirm_delete
+ "\n";
693 var type
= $('input[name=type]').attr('value');
697 msg
+= _reports_confirm_delete_warning
;
699 msg
= msg
.replace("this saved report", "the saved report '"+$('#report_id option[selected=selected]').text()+"'");
703 url
: _site_domain
+ _index_page
+ '/' + _controller_name
+ '/delete/',
706 success: function(data
) {
707 var a
= document
.createElement("a");
708 a
.href
= window
.location
.href
;
709 if(a
.search
&& a
.search
.indexOf("report_id="+id
) !== -1) {
710 window
.location
.href
= a
.search
.replace(new RegExp("report_id="+id
+"&?"), "");
714 $.notify(_reports_error
+ ": failed to save report.", {'sticky': true});
723 regex: function(a
, i
, m
, r
) {
724 var r
= new RegExp(m
[3], 'i');
725 return r
.test(jQuery(a
).text());
731 * Regexp filter that (hopefully) works for all browsers
734 function init_regexpfilter() {
735 MyRegexp
= new Object();
736 MyRegexp
.selectFilterData
= new Object();
737 MyRegexp
.selectFilter = function(selectId
, filter
) {
738 var list
= document
.getElementById(selectId
);
739 if(!MyRegexp
.selectFilterData
[selectId
]) {
740 //if we don't have a list of all the options, cache them now'
741 MyRegexp
.selectFilterData
[selectId
] = new Array();
742 for(var i
= 0; i
< list
.options
.length
; i
++)
743 MyRegexp
.selectFilterData
[selectId
][i
] = list
.options
[i
];
745 list
.options
.length
= 0; //remove all elements from the list
746 var r
= new RegExp(filter
, 'i');
747 for(var i
= 0; i
< MyRegexp
.selectFilterData
[selectId
].length
; i
++) {
748 //add elements from cache if they match filter
749 var o
= MyRegexp
.selectFilterData
[selectId
][i
];
750 //if(o.text.toLowerCase().indexOf(filter.toLowerCase()) >= 0) list.add(o, null);
751 if(!o
.parentNode
&& r
.test(o
.text
)) list
.add(o
, null);
754 MyRegexp
.resetFilter = function(selectId
) {
755 if (typeof MyRegexp
.selectFilterData
[selectId
] == 'undefined' || !MyRegexp
.selectFilterData
[selectId
].length
)
757 var list
= document
.getElementById(selectId
);
758 list
.options
.length
= 0; //remove all elements from the list
759 for(var i
= 0; i
< MyRegexp
.selectFilterData
[selectId
].length
; i
++) {
760 //add elements from cache if they match filter
761 var o
= MyRegexp
.selectFilterData
[selectId
][i
];