js: Restore fancybox hook
[ninja.git] / application / views / reports / js / common.js
blobbb5d9be6dd10edd128d9163debadd421823c3a33
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 $(".fancybox").fancybox({
7 'overlayOpacity' : 0.7,
8 'overlayColor' : '#ffffff',
9 'hideOnContentClick' : false,
10 'autoScale':true,
11 'autoDimensions': true,
12 });
14 var direct_link_visible = false;
15 $('#current_report_params').click(function() {
16 // make sure we always empty the field
17 $('#link_container').html('');
18 // .html('<form><input type="text" size="200" value="' + $('#current_report_params').attr('href') + '"></form>')
19 if (!direct_link_visible) {
20 $('#link_container')
21 .html('<form>'+_label_direct_link+' <input class="wide" type="text" value="'
22 + document.location.protocol + '//'
23 + document.location.host
24 + $('#current_report_params').attr('href')
25 + '"></form>')
26 .css('position', 'absolute')
27 .css('top', this.offsetHeight + this.offsetTop + 5)
28 .css('right', '0')
29 .show();
30 direct_link_visible = true;
31 } else {
32 $('#link_container').hide();
33 direct_link_visible = false;
35 return false;
36 });
38 $('#save_report').click(function() {
39 if (!direct_link_visible) {
40 $('#save_report_form')
41 .css('position', 'absolute')
42 .css('top', this.offsetHeight + this.offsetTop + 5)
43 .css('right', '0')
44 .show()
45 .find('input[name=report_name]')
46 .map(function() {
47 var input = this;
48 if(input.value == "") {
49 input.focus();
51 });
52 direct_link_visible = true;
53 } else {
54 $('#save_report_form').hide();
55 direct_link_visible = false;
57 return false;
58 });
60 $("#report_id").bind('change', function() {
61 $("#saved_report_form").trigger('submit');
62 });
64 $('.save_report_btn').parents('form').submit(function(ev) {
65 ev.preventDefault();
66 loopElements();
67 var form = $(this);
68 if (!(check_form_values(this[0]))) {
69 return;
71 var btn = form.find('.save_report_btn');
72 btn.after(loadimg_sml);
73 $.ajax({
74 url: form[0].action,
75 type: form[0].method,
76 data: form.serialize(),
77 complete: function() {
78 btn.parent().find('img:last').remove();
80 success: function(data, status_msg, xhr) {
81 if (data == null) {
82 $.notify(_reports_error + ": " + xhr.responseText, {'sticky': true});
83 return;
85 jgrowl_message(data.status_msg, _reports_success);
86 if (!btn[0].form.report_id)
87 $('form').append('<input type="hidden" name="report_id" value="'+data.report_id+'"/>');
88 else
89 $('#save_report_form').hide();
91 error: function(data) {
92 var resp;
93 try {
94 resp = $.parseJSON(data.responseText).error;
95 } catch (ex) {
96 resp = "Unknown error";
98 $.notify(_reports_error + ": " + resp, {'sticky': true});
99 btn.parent().find('img:last').remove();
101 dataType: 'json'
105 var hostname = window.location.protocol + "//" + window.location.host;
106 $('select[name=report_type]').on('change', function( e ) {
108 var filterable = jQuery.fn.filterable.find( $('select[name="objects[]"]') ),
109 type = e.target.value.replace( /s$/, "" );
111 var url = _site_domain + _index_page;
112 url += '/listview/fetch_ajax?query=[' + type + 's] all&columns[]=key&limit=1000000';
114 if ( filterable ) {
115 $.ajax({
116 url: url,
117 dataType: 'json',
118 error: function( xhr ) {
119 console.log( xhr.responseText );
121 success: function( data ) {
123 var names = [];
125 for ( var i = 0; i < data.data.length; i++ ) {
126 names.push( data.data[ i ].key );
129 filterable.data = new Set( names );
130 filterable.reset();
138 $('#sel_report_type').on('click', function() {
139 var value = this.form.report_type.value;
140 set_selection(value);
141 get_members(value, function(all_names) {
142 populate_options($('#objects_tmp'), $('#objects'), all_names);
146 $('#start_year, #end_year').on('change', function () {
147 var start = 0;
148 var end = 11;
149 // check_custom_months is supposedly initialized by the onload
150 // handler in application/views/reports/js/reports.js or equivalent.
151 if (check_custom_months.start_date == undefined || check_custom_months.end_date == undefined) {
152 return;
154 if (this.value == check_custom_months.start_date.getFullYear()) {
155 start = check_custom_months.start_date.getMonth();
157 if (this.value == check_custom_months.end_date.getFullYear()) {
158 end = check_custom_months.end_date.getMonth();
160 var html = '<option></option>';
161 for (i = start; i <= end; i++) {
162 html += '<option value="' + (i+1) + '">' + Date.monthNames[i] + '</option>';
164 if (this.id == 'start_year')
165 $('#start_month').html(html);
166 else
167 $('#end_month').html(html);
170 $('#start_year, #end_year, #start_month, #end_month').on('change', check_custom_months);
171 $("#delete_report").click(confirm_delete_report);
173 $(".report_form").on('submit', function() {
174 loopElements();
175 return check_form_values();
179 function init_datepicker()
181 // datePicker Jquery plugin
182 var datepicker_enddate = (new Date()).asString();
183 $('.date-pick').datePicker({clickInput:true, startDate:_start_date, endDate:datepicker_enddate});
184 $('#cal_start').on(
185 'dpClosed',
186 function(e, selectedDates)
188 var d = selectedDates[0];
189 if (d) {
190 d = new Date(d);
191 $('#cal_end').dpSetStartDate(d.asString());
195 $('#cal_end').on(
196 'dpClosed',
197 function(e, selectedDates)
199 var d = selectedDates[0];
200 if (d) {
201 d = new Date(d);
202 $('#cal_start').dpSetEndDate(d.asString());
208 function show_calendar(val, update) {
209 if (val=='custom') {
210 $("#custom_time").show();
212 init_datepicker();
213 init_timepicker();
215 if (update == '') {
216 $('input[name=start_time]').attr('value', '');
217 $('input[name=end_time]').attr('value', '');
219 } else {
220 $("#custom_time").hide();
222 disable_sla_fields(val);
225 function set_selection(val) {
226 if ($.inArray(val, ['servicegroups', 'hostgroups', 'services', 'hosts']) === -1)
227 val = 'hostgroups'; // Why? Because I found it like this
228 $('.object-list-type').text(val);
229 $('*[data-show-for]').hide()
230 $('*[data-show-for~='+val+']').show()
233 function get_members(type, cb) {
234 if (!type)
235 return;
236 var field_name = false;
237 var empty_field = false;
239 show_progress('progress', _wait_str);
240 $.ajax({
241 url: _site_domain + _index_page + '/ajax/group_member',
242 data: {type: type},
243 error: function(data) {
244 $.notify("Unable to fetch objects: " + data.responseText, {'sticky': true});
246 success: function(all_names) {
247 if(typeof cb == 'function')
248 cb(all_names);
249 $('#progress').css('display', 'none');
251 dataType: 'json'
256 * Populate HTML select list with supplied JSON data
258 function populate_options(tmp_field, field, json_data)
260 tmp_field.empty();
261 field.empty();
262 show_progress('progress', _wait_str);
263 var available = document.createDocumentFragment();
264 var selected = document.createDocumentFragment();
265 for (i = 0; i < (json_data ? json_data.length : 0); i++) {
266 var option = document.createElement("option");
267 option.appendChild(document.createTextNode(json_data[i]));
268 available.appendChild(option);
270 tmp_field.append(available);
271 field.append(selected);
275 * Loop through all elements of a form
276 * Verify that all multiselect fields (right hand side)
277 * are set to selected
279 function loopElements(f) {
280 // select all elements that doesn't contain the nosave_suffix
281 $('.multiple:not([id$=_tmp])').each(function() {
282 if ($(this).is(':visible')) {
283 $(this).children('option').attr('selected', 'selected');
284 } else {
285 $(this).children('option').attr('selected', false);
290 function check_form_values(form)
292 if (!form)
293 form = document.documentElement;
294 var errors = 0;
295 var err_str = '';
296 var cur_start = '';
297 var cur_end = '';
299 var rpt_type = $("select[name=report_type]", form).val();
300 if ($("#report_period", form).val() == 'custom') {
301 if ($('input[name=type]', form).val() != 'sla') {
302 // date validation
303 cur_start = Date.fromString($("input[name=cal_start]", form).val());
304 var time = $(".time_start", form).val().split(':');
305 cur_start.addHours(time[0]);
306 cur_start.addMinutes(time[1]);
307 cur_end = Date.fromString($("input[name=cal_end]", form).val());
308 time = $(".time_end", form).val().split(':');
309 cur_end.addHours(time[0]);
310 cur_end.addMinutes(time[1]);
311 var now = new Date();
312 if (!cur_start || !cur_end) {
313 if (!cur_start) {
314 errors++;
315 err_str += "<li>" + _reports_invalid_startdate + ".</li>";
317 if (!cur_end) {
318 errors++;
319 err_str += "<li>" + _reports_invalid_enddate + ".</li>";
321 } else {
322 if (cur_end > now) {
323 if (!confirm(_reports_enddate_infuture)) {
324 return false;
325 } else {
326 cur_end = now;
331 if (cur_end < cur_start) {
332 errors++;
333 err_str += "<li>" + _reports_enddate_lessthan_startdate + ".</li>";
334 $(".datepick-start", form).addClass("time_error");
335 $(".datepick-end", form).addClass("time_error");
336 } else {
337 $(".datepick-start", form).removeClass("time_error");
338 $(".datepick-end", form).removeClass("time_error");
340 } else {
341 // verify that we have years and month fields
342 if ($('#start_year', form).val() == '' || $('#start_month', form).val() == ''
343 || $('#end_year', form).val() == '' || $('#end_month', form).val() == '') {
344 errors++;
345 //@@@Fixme: Add translated string
346 err_str += "<li>Please select year and month for both start and end. ";
347 err_str += "<br />Please note that SLA reports can only be generated for previous months</li>";
349 else {
350 // remember: our months are 1-indexed
351 cur_start = new Date(0);
352 cur_start.setYear($("select[name=start_year]", form).val());
353 cur_start.addMonths(Number($("select[name=start_month]", form).val()) - 1);
355 cur_end = new Date(0);
356 cur_end.setYear($("select[name=end_year]", form).val());
357 cur_end.addMonths(Number($("select[name=end_month]", form).val()));
360 if (cur_end < cur_start) {
361 errors++;
362 err_str += "<li>" + _reports_enddate_lessthan_startdate + ".</li>";
363 $(".datepick-start", form).addClass("time_error");
364 $(".datepick-end", form).addClass("time_error");
365 } else {
366 $(".datepick-start", form).removeClass("time_error");
367 $(".datepick-end", form).removeClass("time_error");
372 if ($('input[name=report_mode]:checked', form).val() != 'standard' && !$('#show_all', form).is(':checked') && $("#objects", form).is('select') && $('#objects option', form).length == 0) {
373 errors++;
374 err_str += "<li>" + _reports_err_str_noobjects + ".</li>";
377 if ($("#enter_sla", form).is(":visible")) {
378 // check for sane SLA values
379 var red_error = false;
380 var max_val = 100;
381 var nr_of_slas = 0;
383 for (i=1;i<=12;i++) {
384 var field_name = 'month_' + i;
385 var input = $('input[id="' + field_name + '"]', form);
386 var value = input.attr('value');
387 value = value.replace(',', '.');
388 if (value > max_val || isNaN(value)) {
389 input.css('background', sla_month_error_color);
390 errors++;
391 red_error = true;
392 } else {
393 if (value != '') {
394 nr_of_slas++;
396 if (input.attr('disabled'))
397 input.css('background', sla_month_disabled_color);
398 else
399 input.css('background', sla_month_enabled_color);
402 if (red_error) {
403 err_str += '<li>' + _reports_sla_err_str + '</li>';
406 if (nr_of_slas == 0 && !red_error) {
407 errors++;
408 err_str += "<li>" + _reports_no_sla_str + "</li>";
412 // display err_str if any
413 if (!errors) {
414 $('#response', form).html('');
416 $('#response', form).hide();
417 return true;
420 // clear all style info from progress
421 var resp = $('#response', form);
422 if (!resp.length)
423 resp = $('#response');
424 resp.attr("style", "");
425 resp.html("<ul class='alert error'>" + err_str + "</ul>");
426 window.scrollTo(0,0); // make sure user sees the error message
427 return false;
430 function moveAndSort(from, to)
432 from.find('option:selected').remove().appendTo(to);
433 to.sortOptions();
436 // init timepicker once it it is shown
437 function init_timepicker()
439 $("#time_start, #time_end").timePicker();
442 function disable_sla_fields(report_period)
444 if (!$('#month_1').length)
445 return;
446 var now = new Date();
447 var this_month = now.getMonth()+1;
448 switch (report_period) {
449 case 'thisyear':
450 // weird as it seems, the following call actually ENABLES
451 // all months. If not, we could end up with all months being
452 // disabled for 'thisyear'
453 disable_months(0, 12);
454 for (i=this_month + 1;i<=12;i++)
456 $('.report_form #month_' + i).val('').attr('disabled', true).css('background-color', sla_month_disabled_color);
458 break;
459 case 'custom':
460 check_custom_months();
461 break;
462 case 'lastmonth':
463 enable_last_months(1);
464 break;
465 case 'last3months':
466 enable_last_months(3);
467 break;
468 case 'last6months':
469 enable_last_months(6);
470 break;
471 case 'lastyear':
472 case 'last12months':
473 disable_months(0, 12);
474 break;
475 case 'lastquarter':
476 if(this_month <= 3){
477 from = 10;
478 to = 12;
479 } else if (this_month <= 6) {
480 from = 1;
481 to = 3;
482 } else if (this_month <= 9){
483 from = 4;
484 to = 6;
485 } else {
486 from = 7;
487 to = 9;
489 disable_months(from, to);
490 break;
491 default:
492 for (i=1;i<=12;i++)
494 $('#month_' + i).attr('disabled', false).css('bgcolor', sla_month_enabled_color);
500 function disable_months(start, end)
502 var disabled_state = false;
503 var not_disabled_state = false;
504 var col = false;
505 start = Number(start);
506 end = Number(end);
507 for (i=1;i<=12;i++) {
508 var cell = $('.report_form #month_' + i);
509 if (start>end) {
510 if ( i >= start || i <= end) {
511 cell.attr('disabled', false).css('background-color', sla_month_enabled_color);
512 } else {
513 cell.val('').attr('disabled', true).css('background-color', sla_month_disabled_color);
515 } else {
516 if ( i>= start && i <= end) {
517 cell.attr('disabled', false).css('background-color', sla_month_enabled_color);
518 } else {
519 cell.val('').attr('disabled', true).css('background-color', sla_month_disabled_color);
526 function check_custom_months()
528 var f = $('.report_form').get(0);
529 // not SLA?
530 if (!f['start_month'])
531 return;
533 if (check_custom_months.start_date == undefined) {
534 check_custom_months.start_date = new Date(0);
535 check_custom_months.end_date = new Date();
536 $.ajax({
537 url: _site_domain + _index_page + '/sla/custom_start/',
538 type: 'GET',
539 dataType: 'json',
540 success: function(data) {
541 if (!data.timestamp) {
542 $.notify("Unable to fetch oldest report timestamp: " + data.responseText, {'sticky': true});
544 check_custom_months.start_date.setTime(data.timestamp * 1000);
545 var html = '<option></option>';
546 for (i = check_custom_months.start_date.getFullYear(); i <= check_custom_months.end_date.getFullYear(); i++) {
547 html += '<option>' + i + '</option>';
549 $('#start_year').html(html);
550 $('#end_year').html(html);
555 var start_year = f.start_year.value;
556 var start_month = f.start_month.value;
557 var end_year = f.end_year.value;
558 var end_month = f.end_month.value;
559 if (start_year == '' || end_year == '' || start_month == '' || end_month == '') {
560 disable_months(0, 0);
561 } else if (start_year == end_year - 1 || start_year == end_year) {
562 disable_months(start_month, end_month);
563 } else {
564 disable_months(0, 0);
566 $('#progress').hide();
570 * Generic function to enable month_ fields
571 * depending on if selection is last 1, 3 or 6 months.
573 function enable_last_months(mnr)
575 var now = new Date();
576 var this_month = now.getMonth()+1;
577 var from = this_month - mnr;
578 var to = this_month - 1;
579 if (from <= 0)
580 from += 12;
581 if (to <= 0)
582 to += 12;
583 disable_months(from, to);
586 function missing_objects()
588 this.objs = [];
591 missing_objects.prototype.add = function(name)
593 if (name != '*')
594 this.objs.push(name);
597 missing_objects.prototype.display_if_any = function()
599 if (!this.objs.length)
600 return;
602 var info_str = _reports_missing_objects + ": ";
603 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>';
604 info_str += _reports_missing_objects_pleaseremove;
605 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>';
606 $('#response')
607 .css('background','#f4f4ed url(' + _site_domain + 'application/views/icons/32x32/shield-info.png) 7px 7px no-repeat')
608 .css("position", "relative")
609 .css('top', '0px')
610 .css('width','748px')
611 .css('left', '0px')
612 .css('padding','15px 2px 5px 50px')
613 .css('margin-left','5px')
614 .html(info_str);
617 function confirm_delete_report()
619 var id = $("#report_id").attr('value')
621 var is_scheduled = $('#is_scheduled').text()!='' ? true : false;
622 var msg = _reports_confirm_delete + "\n";
623 var type = $('input[name=type]').attr('value');
624 if (!id)
625 return;
626 if (is_scheduled) {
627 msg += _reports_confirm_delete_warning;
629 msg = msg.replace("this saved report", "the saved report '"+$('#report_id option[selected=selected]').text()+"'");
630 if (confirm(msg)) {
631 $(this).after(loadimg_sml);
632 $.ajax({
633 url: _site_domain + _index_page + '/' + _controller_name + '/delete/',
634 type: 'POST',
635 data: {'report_id': id},
636 complete: function() {
637 $(loadimg_sml).remove();
639 success: function(data) {
640 var a = document.createElement("a");
641 a.href = window.location.href;
642 if(a.search && a.search.indexOf("report_id="+id) !== -1) {
643 window.location.href = a.search.replace(new RegExp("report_id="+id+"&?"), "");
646 error: function(data) {
647 var msg;
648 try {
649 msg = $.parseJSON(data.responseText).error;
650 } catch (ex) {
651 msg = "Unknown error";
653 $.notify("Failed to delete report: " + msg, {'sticky': true});
655 dataType: 'json'
660 jQuery.extend(
661 jQuery.expr[':'], {
662 regex: function(a, i, m, r) {
663 var r = new RegExp(m[3], 'i');
664 return r.test(jQuery(a).text());