sabisu 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/LICENSE +191 -0
- data/README.md +72 -0
- data/bin/sabisu +39 -0
- data/lib/sabisu.rb +5 -0
- data/lib/sabisu/config.rb +116 -0
- data/lib/sabisu/event.rb +184 -0
- data/lib/sabisu/public/css/base.css +32 -0
- data/lib/sabisu/public/css/bootstrap.min.css +9 -0
- data/lib/sabisu/public/css/events.css +194 -0
- data/lib/sabisu/public/fonts/glyphicons-halflings-regular.eot +0 -0
- data/lib/sabisu/public/fonts/glyphicons-halflings-regular.svg +228 -0
- data/lib/sabisu/public/fonts/glyphicons-halflings-regular.ttf +0 -0
- data/lib/sabisu/public/fonts/glyphicons-halflings-regular.woff +0 -0
- data/lib/sabisu/public/js/sabisu.js +893 -0
- data/lib/sabisu/public/js/typeahead.js +1718 -0
- data/lib/sabisu/routes/api.rb +38 -0
- data/lib/sabisu/routes/client.rb +13 -0
- data/lib/sabisu/routes/events.rb +9 -0
- data/lib/sabisu/routes/init.rb +4 -0
- data/lib/sabisu/routes/sensu.rb +44 -0
- data/lib/sabisu/sensu.rb +67 -0
- data/lib/sabisu/server.rb +110 -0
- data/lib/sabisu/templates/events.haml +268 -0
- data/lib/sabisu/templates/layout.haml +85 -0
- data/lib/sabisu/templates/login.haml +22 -0
- data/lib/sabisu/version.rb +4 -0
- metadata +284 -0
| Binary file | 
| Binary file | 
| @@ -0,0 +1,893 @@ | |
| 1 | 
            +
            (function() {
         | 
| 2 | 
            +
              var sabisu,
         | 
| 3 | 
            +
                __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
         | 
| 4 | 
            +
             | 
| 5 | 
            +
              sabisu = angular.module('sabisu', []);
         | 
| 6 | 
            +
             | 
| 7 | 
            +
              sabisu.config(function($locationProvider) {
         | 
| 8 | 
            +
                return $locationProvider.html5Mode(true);
         | 
| 9 | 
            +
              });
         | 
| 10 | 
            +
             | 
| 11 | 
            +
              sabisu.filter('slice', function() {
         | 
| 12 | 
            +
                return function(arr, start, end) {
         | 
| 13 | 
            +
                  return arr.slice(start, end);
         | 
| 14 | 
            +
                };
         | 
| 15 | 
            +
              });
         | 
| 16 | 
            +
             | 
| 17 | 
            +
              sabisu.filter('joinBy', function() {
         | 
| 18 | 
            +
                return function(input, delimiter) {
         | 
| 19 | 
            +
                  return (input || []).join(delimiter || ',');
         | 
| 20 | 
            +
                };
         | 
| 21 | 
            +
              });
         | 
| 22 | 
            +
             | 
| 23 | 
            +
              sabisu.controller('eventsController', function($scope, $log, $location, $filter, $sce, eventsFactory, stashesFactory) {
         | 
| 24 | 
            +
                $scope.first_search = true;
         | 
| 25 | 
            +
                $scope.alt_pressed = false;
         | 
| 26 | 
            +
                $scope.checks = [];
         | 
| 27 | 
            +
                $scope.clients = [];
         | 
| 28 | 
            +
                $scope.events = [];
         | 
| 29 | 
            +
                $scope.event_fields = [];
         | 
| 30 | 
            +
                $scope.event_fields_custom = [];
         | 
| 31 | 
            +
                $scope.event_fields_facet = [];
         | 
| 32 | 
            +
                $scope.event_fields_int = [];
         | 
| 33 | 
            +
                $scope.event_fields_name = [];
         | 
| 34 | 
            +
                $scope.events_spin = false;
         | 
| 35 | 
            +
                $scope.showAll = false;
         | 
| 36 | 
            +
                $scope.bulk = 'show';
         | 
| 37 | 
            +
                $scope.isActive = true;
         | 
| 38 | 
            +
                $scope.showDetails = [];
         | 
| 39 | 
            +
                $scope.previous_events_ranges = {};
         | 
| 40 | 
            +
                $scope.previous_events_counts = {};
         | 
| 41 | 
            +
                $scope.previous_events_events = {};
         | 
| 42 | 
            +
                $(window).on('focus', function() {
         | 
| 43 | 
            +
                  $scope.isActive = true;
         | 
| 44 | 
            +
                  $scope.updateEvents();
         | 
| 45 | 
            +
                  return $scope.changes();
         | 
| 46 | 
            +
                });
         | 
| 47 | 
            +
                $(window).on('blur', function() {
         | 
| 48 | 
            +
                  return $scope.isActive = false;
         | 
| 49 | 
            +
                });
         | 
| 50 | 
            +
                $(window).keydown(function(evt) {
         | 
| 51 | 
            +
                  if (evt.which === 18) {
         | 
| 52 | 
            +
                    return $scope.alt_pressed = true;
         | 
| 53 | 
            +
                  }
         | 
| 54 | 
            +
                });
         | 
| 55 | 
            +
                $(window).keyup(function(evt) {
         | 
| 56 | 
            +
                  if (evt.which === 18) {
         | 
| 57 | 
            +
                    return $scope.alt_pressed = false;
         | 
| 58 | 
            +
                  }
         | 
| 59 | 
            +
                });
         | 
| 60 | 
            +
                if ($location.search().query != null) {
         | 
| 61 | 
            +
                  $scope.search_field = $location.search().query;
         | 
| 62 | 
            +
                  $scope.search = $location.search().query;
         | 
| 63 | 
            +
                } else {
         | 
| 64 | 
            +
                  $scope.search_field = '';
         | 
| 65 | 
            +
                  $scope.search = '';
         | 
| 66 | 
            +
                }
         | 
| 67 | 
            +
                if ($location.search().sort != null) {
         | 
| 68 | 
            +
                  $scope.sort_field = $location.search().sort;
         | 
| 69 | 
            +
                  $scope.sort = $location.search().sort;
         | 
| 70 | 
            +
                } else {
         | 
| 71 | 
            +
                  $scope.sort = '-age';
         | 
| 72 | 
            +
                  $scope.sort_field = '-age';
         | 
| 73 | 
            +
                }
         | 
| 74 | 
            +
                if ($location.search().limit != null) {
         | 
| 75 | 
            +
                  $scope.limit = $location.search().limit;
         | 
| 76 | 
            +
                  $scope.limit_field = $location.search().limit;
         | 
| 77 | 
            +
                } else {
         | 
| 78 | 
            +
                  $scope.limit = '50';
         | 
| 79 | 
            +
                  $scope.limit_field = '50';
         | 
| 80 | 
            +
                }
         | 
| 81 | 
            +
                if ($location.search().showAll != null) {
         | 
| 82 | 
            +
                  $scope.showAll = $location.search().showAll;
         | 
| 83 | 
            +
                  $log.info($scope.showAll);
         | 
| 84 | 
            +
                }
         | 
| 85 | 
            +
                $scope.updateEventFields = function() {
         | 
| 86 | 
            +
                  return eventsFactory.event_fields().success(function(data, status, headers, config) {
         | 
| 87 | 
            +
                    var defaults, field, _i, _len, _ref, _ref1, _results;
         | 
| 88 | 
            +
                    defaults = ['client', 'check', 'status', 'state_change', 'occurrence', 'issued', 'output'];
         | 
| 89 | 
            +
                    $scope.event_fields = data;
         | 
| 90 | 
            +
                    _ref = $scope.event_fields;
         | 
| 91 | 
            +
                    _results = [];
         | 
| 92 | 
            +
                    for (_i = 0, _len = _ref.length; _i < _len; _i++) {
         | 
| 93 | 
            +
                      field = _ref[_i];
         | 
| 94 | 
            +
                      $scope.event_fields_name.push(field.name);
         | 
| 95 | 
            +
                      if (field.type === 'int') {
         | 
| 96 | 
            +
                        $scope.event_fields_int.push(field.name);
         | 
| 97 | 
            +
                        $scope.event_fields_int.push('-' + field.name);
         | 
| 98 | 
            +
                      }
         | 
| 99 | 
            +
                      if (field.facet === true) {
         | 
| 100 | 
            +
                        $scope.event_fields_facet.push(field.name);
         | 
| 101 | 
            +
                      }
         | 
| 102 | 
            +
                      if (_ref1 = field.name, __indexOf.call(defaults, _ref1) < 0) {
         | 
| 103 | 
            +
                        _results.push($scope.event_fields_custom.push(field));
         | 
| 104 | 
            +
                      } else {
         | 
| 105 | 
            +
                        _results.push(void 0);
         | 
| 106 | 
            +
                      }
         | 
| 107 | 
            +
                    }
         | 
| 108 | 
            +
                    return _results;
         | 
| 109 | 
            +
                  }).error(function(data, status, headers, config) {
         | 
| 110 | 
            +
                    return alert("Failed to get fields");
         | 
| 111 | 
            +
                  });
         | 
| 112 | 
            +
                };
         | 
| 113 | 
            +
                $scope.updateStashes = function() {
         | 
| 114 | 
            +
                  return stashesFactory.stashes().success(function(data, status, headers, config) {
         | 
| 115 | 
            +
                    var check, client, event, parts, stash, stashes, _base, _base1, _i, _j, _k, _len, _len1, _len2, _ref, _ref1;
         | 
| 116 | 
            +
                    stashes = [];
         | 
| 117 | 
            +
                    for (_i = 0, _len = data.length; _i < _len; _i++) {
         | 
| 118 | 
            +
                      stash = data[_i];
         | 
| 119 | 
            +
                      if (stash['path'].match(/^silence\//)) {
         | 
| 120 | 
            +
                        stashes.push(stash);
         | 
| 121 | 
            +
                      }
         | 
| 122 | 
            +
                    }
         | 
| 123 | 
            +
                    $scope.stashes = stashes;
         | 
| 124 | 
            +
                    _ref = $scope.stashes;
         | 
| 125 | 
            +
                    for (_j = 0, _len1 = _ref.length; _j < _len1; _j++) {
         | 
| 126 | 
            +
                      stash = _ref[_j];
         | 
| 127 | 
            +
                      parts = stash['path'].split('/', 3);
         | 
| 128 | 
            +
                      client = parts[1];
         | 
| 129 | 
            +
                      if (parts.length > 2) {
         | 
| 130 | 
            +
                        check = parts[2];
         | 
| 131 | 
            +
                      } else {
         | 
| 132 | 
            +
                        check = null;
         | 
| 133 | 
            +
                      }
         | 
| 134 | 
            +
                      _ref1 = $scope.events;
         | 
| 135 | 
            +
                      for (_k = 0, _len2 = _ref1.length; _k < _len2; _k++) {
         | 
| 136 | 
            +
                        event = _ref1[_k];
         | 
| 137 | 
            +
                        if ((_base = event.client).silenced == null) {
         | 
| 138 | 
            +
                          _base.silenced = false;
         | 
| 139 | 
            +
                        }
         | 
| 140 | 
            +
                        if ((_base1 = event.check).silenced == null) {
         | 
| 141 | 
            +
                          _base1.silenced = false;
         | 
| 142 | 
            +
                        }
         | 
| 143 | 
            +
                        if (client === event.client.name) {
         | 
| 144 | 
            +
                          if (check === null) {
         | 
| 145 | 
            +
                            event.client.silenced = true;
         | 
| 146 | 
            +
                            event.client.silence_stash = stash;
         | 
| 147 | 
            +
                            break;
         | 
| 148 | 
            +
                          } else {
         | 
| 149 | 
            +
                            if (check === event.check.name) {
         | 
| 150 | 
            +
                              event.check.silenced = true;
         | 
| 151 | 
            +
                              event.check.silence_stash = stash;
         | 
| 152 | 
            +
                              break;
         | 
| 153 | 
            +
                            }
         | 
| 154 | 
            +
                          }
         | 
| 155 | 
            +
                        }
         | 
| 156 | 
            +
                      }
         | 
| 157 | 
            +
                    }
         | 
| 158 | 
            +
                    $('.close_popover').click(function() {
         | 
| 159 | 
            +
                      return $scope.closePopovers();
         | 
| 160 | 
            +
                    });
         | 
| 161 | 
            +
                    $('body').on('click', function(e) {
         | 
| 162 | 
            +
                      return $('[data-toggle="popover"]').each(function() {
         | 
| 163 | 
            +
                        if (!$(this).is(e.target) && $(this).has(e.target).length === 0 && $('.popover').has(e.target).length === 0) {
         | 
| 164 | 
            +
                          return $(this).popover('hide');
         | 
| 165 | 
            +
                        }
         | 
| 166 | 
            +
                      });
         | 
| 167 | 
            +
                    });
         | 
| 168 | 
            +
                    return $('.glyphicon-question-sign').tooltip();
         | 
| 169 | 
            +
                  });
         | 
| 170 | 
            +
                };
         | 
| 171 | 
            +
                $scope.closePopovers = function() {
         | 
| 172 | 
            +
                  return $('.silenceBtn').popover('hide');
         | 
| 173 | 
            +
                };
         | 
| 174 | 
            +
                $scope.createSilenceDetails = function(client, check) {
         | 
| 175 | 
            +
                  if (check == null) {
         | 
| 176 | 
            +
                    check = null;
         | 
| 177 | 
            +
                  }
         | 
| 178 | 
            +
                  $scope.silencePath = client;
         | 
| 179 | 
            +
                  if (check) {
         | 
| 180 | 
            +
                    return $scope.silencePath += '/' + check;
         | 
| 181 | 
            +
                  }
         | 
| 182 | 
            +
                };
         | 
| 183 | 
            +
                $scope.updateSilenceDetails = function(stash) {
         | 
| 184 | 
            +
                  var check, client, parts;
         | 
| 185 | 
            +
                  parts = stash['path'].split('/', 3);
         | 
| 186 | 
            +
                  client = parts[1];
         | 
| 187 | 
            +
                  check = null;
         | 
| 188 | 
            +
                  if (parts.length > 2) {
         | 
| 189 | 
            +
                    check = parts[2];
         | 
| 190 | 
            +
                  }
         | 
| 191 | 
            +
                  $scope.silencePath = client;
         | 
| 192 | 
            +
                  if (check) {
         | 
| 193 | 
            +
                    $scope.silencePath += '/' + check;
         | 
| 194 | 
            +
                  }
         | 
| 195 | 
            +
                  if (stash['content']['timestamp']) {
         | 
| 196 | 
            +
                    $scope.silenceCreated = $filter('date')(stash['content']['timestamp'] * 1000, 'short');
         | 
| 197 | 
            +
                  }
         | 
| 198 | 
            +
                  $scope.silenceOwner = stash['content']['owner'];
         | 
| 199 | 
            +
                  if (stash['content']['expiration'] === 'resolve') {
         | 
| 200 | 
            +
                    $scope.silenceExpires = 'On resolve';
         | 
| 201 | 
            +
                    $scope.silenceExpirationClass = 'success';
         | 
| 202 | 
            +
                  } else if (stash['content']['expiration'] === 'never') {
         | 
| 203 | 
            +
                    $scope.silenceExpires = 'Never';
         | 
| 204 | 
            +
                    $scope.silenceExpirationClass = 'danger';
         | 
| 205 | 
            +
                  } else if ((stash['expire'] != null) && stash['expire'] !== -1) {
         | 
| 206 | 
            +
                    $scope.silenceExpires = moment.unix(parseInt(stash['content']['timestamp']) + parseInt(stash['expire'])).fromNow();
         | 
| 207 | 
            +
                    $scope.silenceExpirationClass = 'warning';
         | 
| 208 | 
            +
                  }
         | 
| 209 | 
            +
                  if (stash['content']['reason'] != null) {
         | 
| 210 | 
            +
                    return $scope.silenceReason = stash['content']['reason'];
         | 
| 211 | 
            +
                  }
         | 
| 212 | 
            +
                };
         | 
| 213 | 
            +
                $scope.saveSilence = function() {
         | 
| 214 | 
            +
                  var expiration, owner, re, reason, stash, timerToSec, timer_val, valid;
         | 
| 215 | 
            +
                  valid = true;
         | 
| 216 | 
            +
                  owner = $('#owner').val();
         | 
| 217 | 
            +
                  if (owner === '') {
         | 
| 218 | 
            +
                    $('.silence_owner').removeClass('has-success');
         | 
| 219 | 
            +
                    $('.silence_owner').addClass('has-error');
         | 
| 220 | 
            +
                    valid = false;
         | 
| 221 | 
            +
                  } else {
         | 
| 222 | 
            +
                    $('.silence_owner').removeClass('has-error');
         | 
| 223 | 
            +
                    $('.silence_owner').addClass('has-success');
         | 
| 224 | 
            +
                  }
         | 
| 225 | 
            +
                  reason = $('#reason').val();
         | 
| 226 | 
            +
                  if (reason === '') {
         | 
| 227 | 
            +
                    $('.silence_reason').removeClass('has-success');
         | 
| 228 | 
            +
                    $('.silence_reason').addClass('has-error');
         | 
| 229 | 
            +
                    valid = false;
         | 
| 230 | 
            +
                  } else {
         | 
| 231 | 
            +
                    $('.silence_reason').removeClass('has-error');
         | 
| 232 | 
            +
                    $('.silence_reason').addClass('has-success');
         | 
| 233 | 
            +
                  }
         | 
| 234 | 
            +
                  timer_val = $('#timer_val').val();
         | 
| 235 | 
            +
                  expiration = $('input[name=expiration]:checked', '#silence_form').val();
         | 
| 236 | 
            +
                  if (expiration === 'timer') {
         | 
| 237 | 
            +
                    re = new RegExp('^\\d*(m|h|d|w)$');
         | 
| 238 | 
            +
                    if (re.test(timer_val)) {
         | 
| 239 | 
            +
                      $('.silence_timer_val').removeClass('has-error');
         | 
| 240 | 
            +
                      $('.silence_timer_val').addClass('has-success');
         | 
| 241 | 
            +
                    } else {
         | 
| 242 | 
            +
                      $('.silence_timer_val').removeClass('has-success');
         | 
| 243 | 
            +
                      $('.silence_timer_val').addClass('has-error');
         | 
| 244 | 
            +
                      valid = false;
         | 
| 245 | 
            +
                    }
         | 
| 246 | 
            +
                  } else {
         | 
| 247 | 
            +
                    $('.silence_timer_val').removeClass('has-error');
         | 
| 248 | 
            +
                    $('.silence_timer_val').removeClass('has-success');
         | 
| 249 | 
            +
                  }
         | 
| 250 | 
            +
                  timerToSec = function(val) {
         | 
| 251 | 
            +
                    var conversion, q, quantity, u, unit;
         | 
| 252 | 
            +
                    q = new RegExp('^\\d*');
         | 
| 253 | 
            +
                    u = new RegExp('[a-z]$');
         | 
| 254 | 
            +
                    conversion = {
         | 
| 255 | 
            +
                      m: 60,
         | 
| 256 | 
            +
                      h: 60 * 60,
         | 
| 257 | 
            +
                      d: 60 * 60 * 24,
         | 
| 258 | 
            +
                      w: 60 * 60 * 24 * 7
         | 
| 259 | 
            +
                    };
         | 
| 260 | 
            +
                    quantity = val.match(q)[0];
         | 
| 261 | 
            +
                    unit = val.match(u)[0];
         | 
| 262 | 
            +
                    return quantity * conversion[unit];
         | 
| 263 | 
            +
                  };
         | 
| 264 | 
            +
                  if (valid) {
         | 
| 265 | 
            +
                    stash = {};
         | 
| 266 | 
            +
                    stash['path'] = "silence/" + $scope.silencePath;
         | 
| 267 | 
            +
                    stash['content'] = {};
         | 
| 268 | 
            +
                    stash['content']['timestamp'] = Math.round((new Date().getTime()) / 1000);
         | 
| 269 | 
            +
                    stash['content']['owner'] = owner;
         | 
| 270 | 
            +
                    stash['content']['reason'] = reason;
         | 
| 271 | 
            +
                    stash['content']['expiration'] = expiration;
         | 
| 272 | 
            +
                    if (expiration === 'timer') {
         | 
| 273 | 
            +
                      stash['expire'] = timerToSec(timer_val);
         | 
| 274 | 
            +
                    }
         | 
| 275 | 
            +
                    return stashesFactory.saveStash(stash).success(function(data, status, headers, config) {
         | 
| 276 | 
            +
                      $scope.updateStashes();
         | 
| 277 | 
            +
                      owner = $('#owner').val();
         | 
| 278 | 
            +
                      $('.silence_owner').removeClass('has-success');
         | 
| 279 | 
            +
                      $('.silence_owner').removeClass('has-error');
         | 
| 280 | 
            +
                      reason = $('#reason').val();
         | 
| 281 | 
            +
                      $('.silence_reason').removeClass('has-success');
         | 
| 282 | 
            +
                      $('.silence_reason').removeClass('has-error');
         | 
| 283 | 
            +
                      timer_val = $('#timer_val').val();
         | 
| 284 | 
            +
                      expiration = $('input[name=expiration]:checked', '#silence_form').val();
         | 
| 285 | 
            +
                      $('.silence_timer_val').removeClass('has-error');
         | 
| 286 | 
            +
                      $('.silence_timer_val').removeClass('has-success');
         | 
| 287 | 
            +
                      return $('#silence_window').modal('hide');
         | 
| 288 | 
            +
                    }).error(function(data, status, headers, config) {
         | 
| 289 | 
            +
                      return alert("Failed to silence: (" + status + ") " + data);
         | 
| 290 | 
            +
                    });
         | 
| 291 | 
            +
                  }
         | 
| 292 | 
            +
                };
         | 
| 293 | 
            +
                $scope.deleteSilence = function(path) {
         | 
| 294 | 
            +
                  return stashesFactory.deleteStash(path).success(function(data, status, headers, config) {
         | 
| 295 | 
            +
                    $scope.updateStashes();
         | 
| 296 | 
            +
                    return $scope.closePopovers();
         | 
| 297 | 
            +
                  }).error(function(data, status, headers, config) {
         | 
| 298 | 
            +
                    return alert("Failed to delete silence");
         | 
| 299 | 
            +
                  });
         | 
| 300 | 
            +
                };
         | 
| 301 | 
            +
                $scope.resolveEvent = function(client, check) {
         | 
| 302 | 
            +
                  return eventsFactory.resolveEvent(client, check).success(function(data, status, headers, config) {
         | 
| 303 | 
            +
                    return $scope.updateEvents();
         | 
| 304 | 
            +
                  }).error(function(data, status, headers, config) {
         | 
| 305 | 
            +
                    return alert("Faild to resolve event: " + client + "/" + check);
         | 
| 306 | 
            +
                  });
         | 
| 307 | 
            +
                };
         | 
| 308 | 
            +
                $scope.updateParams = function() {
         | 
| 309 | 
            +
                  $scope.search = $scope.search_field;
         | 
| 310 | 
            +
                  $scope.sort = $scope.sort_field;
         | 
| 311 | 
            +
                  $scope.limit = $scope.limit_field;
         | 
| 312 | 
            +
                  $location.search('query', $scope.search);
         | 
| 313 | 
            +
                  $location.search('sort', $scope.sort);
         | 
| 314 | 
            +
                  $location.search('limit', $scope.limit);
         | 
| 315 | 
            +
                  return $scope.updateEvents();
         | 
| 316 | 
            +
                };
         | 
| 317 | 
            +
                $scope.format_attr_value = function(event, key, path) {
         | 
| 318 | 
            +
                  var field, p, val, _i, _j, _len, _len1, _ref;
         | 
| 319 | 
            +
                  path = path.split('.');
         | 
| 320 | 
            +
                  val = event;
         | 
| 321 | 
            +
                  for (_i = 0, _len = path.length; _i < _len; _i++) {
         | 
| 322 | 
            +
                    p = path[_i];
         | 
| 323 | 
            +
                    if (p in val) {
         | 
| 324 | 
            +
                      val = val[p];
         | 
| 325 | 
            +
                    } else {
         | 
| 326 | 
            +
                      val = null;
         | 
| 327 | 
            +
                      break;
         | 
| 328 | 
            +
                    }
         | 
| 329 | 
            +
                  }
         | 
| 330 | 
            +
                  if (val === void 0 || val === null) {
         | 
| 331 | 
            +
                    val = 'n/a';
         | 
| 332 | 
            +
                  } else if ($scope.typeIsArray(val)) {
         | 
| 333 | 
            +
                    val = $filter('joinBy')(val, ', ');
         | 
| 334 | 
            +
                  } else if (String(val).match('^[0-9]{13}$')) {
         | 
| 335 | 
            +
                    val = $filter('date')(val, 'short');
         | 
| 336 | 
            +
                  } else {
         | 
| 337 | 
            +
                    _ref = $scope.event_fields;
         | 
| 338 | 
            +
                    for (_j = 0, _len1 = _ref.length; _j < _len1; _j++) {
         | 
| 339 | 
            +
                      field = _ref[_j];
         | 
| 340 | 
            +
                      if (field.name === key && field.type === 'url') {
         | 
| 341 | 
            +
                        val = "<a href='" + val + "'>goto</a>";
         | 
| 342 | 
            +
                      }
         | 
| 343 | 
            +
                    }
         | 
| 344 | 
            +
                  }
         | 
| 345 | 
            +
                  return $sce.trustAsHtml(String(val));
         | 
| 346 | 
            +
                };
         | 
| 347 | 
            +
                $scope.getEventAttributes = function(event) {
         | 
| 348 | 
            +
                  var a, attr, i, side, _i, _j, _len, _len1, _ref, _ref1;
         | 
| 349 | 
            +
                  attr = {
         | 
| 350 | 
            +
                    'left': [['issued', 'check.issued'], ['interval', 'check.interval'], ['occurrences', 'occurrences']].concat((function() {
         | 
| 351 | 
            +
                      var _i, _len, _ref, _results;
         | 
| 352 | 
            +
                      _ref = $scope.event_fields_custom;
         | 
| 353 | 
            +
                      _results = [];
         | 
| 354 | 
            +
                      for (_i = 0, _len = _ref.length; _i < _len; _i += 2) {
         | 
| 355 | 
            +
                        i = _ref[_i];
         | 
| 356 | 
            +
                        _results.push([i.name, i.path]);
         | 
| 357 | 
            +
                      }
         | 
| 358 | 
            +
                      return _results;
         | 
| 359 | 
            +
                    })()),
         | 
| 360 | 
            +
                    'right': [['state change', 'rel_time'], ['subscribers', 'check.subscribers'], ['handlers', 'check.handlers']].concat((function() {
         | 
| 361 | 
            +
                      var _i, _len, _ref, _results;
         | 
| 362 | 
            +
                      _ref = $scope.event_fields_custom.slice(1);
         | 
| 363 | 
            +
                      _results = [];
         | 
| 364 | 
            +
                      for (_i = 0, _len = _ref.length; _i < _len; _i += 2) {
         | 
| 365 | 
            +
                        i = _ref[_i];
         | 
| 366 | 
            +
                        _results.push([i.name, i.path]);
         | 
| 367 | 
            +
                      }
         | 
| 368 | 
            +
                      return _results;
         | 
| 369 | 
            +
                    })())
         | 
| 370 | 
            +
                  };
         | 
| 371 | 
            +
                  _ref = ['left', 'right'];
         | 
| 372 | 
            +
                  for (_i = 0, _len = _ref.length; _i < _len; _i++) {
         | 
| 373 | 
            +
                    side = _ref[_i];
         | 
| 374 | 
            +
                    _ref1 = attr[side];
         | 
| 375 | 
            +
                    for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
         | 
| 376 | 
            +
                      a = _ref1[_j];
         | 
| 377 | 
            +
                      a[1] = $scope.format_attr_value(event, a[0], a[1]);
         | 
| 378 | 
            +
                    }
         | 
| 379 | 
            +
                  }
         | 
| 380 | 
            +
                  return attr;
         | 
| 381 | 
            +
                };
         | 
| 382 | 
            +
                $scope.appendQuery = function(val, type, quote) {
         | 
| 383 | 
            +
                  var q;
         | 
| 384 | 
            +
                  if (type == null) {
         | 
| 385 | 
            +
                    type = null;
         | 
| 386 | 
            +
                  }
         | 
| 387 | 
            +
                  if (quote == null) {
         | 
| 388 | 
            +
                    quote = true;
         | 
| 389 | 
            +
                  }
         | 
| 390 | 
            +
                  q = '';
         | 
| 391 | 
            +
                  if ($scope.search.length > 0) {
         | 
| 392 | 
            +
                    if ($scope.alt_pressed) {
         | 
| 393 | 
            +
                      q += ' AND NOT ';
         | 
| 394 | 
            +
                    } else {
         | 
| 395 | 
            +
                      q += ' AND ';
         | 
| 396 | 
            +
                    }
         | 
| 397 | 
            +
                  } else {
         | 
| 398 | 
            +
                    if ($scope.alt_pressed) {
         | 
| 399 | 
            +
                      q += '*:* AND NOT ';
         | 
| 400 | 
            +
                    }
         | 
| 401 | 
            +
                  }
         | 
| 402 | 
            +
                  if (type != null) {
         | 
| 403 | 
            +
                    q += type + ':';
         | 
| 404 | 
            +
                  }
         | 
| 405 | 
            +
                  if (quote) {
         | 
| 406 | 
            +
                    q += "\"" + val + "\"";
         | 
| 407 | 
            +
                  } else {
         | 
| 408 | 
            +
                    q += "" + val;
         | 
| 409 | 
            +
                  }
         | 
| 410 | 
            +
                  $scope.search += q;
         | 
| 411 | 
            +
                  $scope.search_field = $scope.search;
         | 
| 412 | 
            +
                  $location.search('query', $scope.search);
         | 
| 413 | 
            +
                  return $scope.updateEvents();
         | 
| 414 | 
            +
                };
         | 
| 415 | 
            +
                $scope.updateEvents = function() {
         | 
| 416 | 
            +
                  if ($scope.first_search) {
         | 
| 417 | 
            +
                    $scope.events_spin = true;
         | 
| 418 | 
            +
                  }
         | 
| 419 | 
            +
                  $scope.first_search = false;
         | 
| 420 | 
            +
                  return eventsFactory.searchEvents($scope.search, $scope.sort, $scope.limit, $scope.event_fields_int).success(function(data, status, headers, config) {
         | 
| 421 | 
            +
                    var check, client, color, event, events, field, id, k, parts, stash, stats, statuses, v, _base, _base1, _i, _j, _len, _len1, _ref, _ref1, _ref2, _ref3;
         | 
| 422 | 
            +
                    color = ['success', 'warning', 'danger', 'info'];
         | 
| 423 | 
            +
                    status = ['OK', 'Warning', 'Critical', 'Unknown'];
         | 
| 424 | 
            +
                    events = [];
         | 
| 425 | 
            +
                    if ('bookmark' in data) {
         | 
| 426 | 
            +
                      $scope.bookmark = data['bookmark'];
         | 
| 427 | 
            +
                    }
         | 
| 428 | 
            +
                    if ('count' in data) {
         | 
| 429 | 
            +
                      $scope.count = data['count'];
         | 
| 430 | 
            +
                    }
         | 
| 431 | 
            +
                    if ('ranges' in data && !angular.equals($scope.previous_events_ranges, data['ranges']['status'])) {
         | 
| 432 | 
            +
                      statuses = data['ranges']['status'];
         | 
| 433 | 
            +
                      $scope.previous_events_ranges = statuses;
         | 
| 434 | 
            +
                      $('#stats_status').find('#totals').find('.label-warning').text("Warning: " + statuses['Warning']);
         | 
| 435 | 
            +
                      $('#stats_status').find('#totals').find('.label-danger').text("Critical: " + statuses['Critical']);
         | 
| 436 | 
            +
                      $('#stats_status').find('#totals').find('.label-info').text("Unknown: " + statuses['Unknown']);
         | 
| 437 | 
            +
                    }
         | 
| 438 | 
            +
                    if ('counts' in data && !angular.equals($scope.previous_events_counts, data['counts'])) {
         | 
| 439 | 
            +
                      $scope.previous_events_counts = data['counts'];
         | 
| 440 | 
            +
                      stats = {};
         | 
| 441 | 
            +
                      for (field in data['counts']) {
         | 
| 442 | 
            +
                        stats[field] = [];
         | 
| 443 | 
            +
                        _ref = data['counts'][field];
         | 
| 444 | 
            +
                        for (k in _ref) {
         | 
| 445 | 
            +
                          v = _ref[k];
         | 
| 446 | 
            +
                          stats[field].push([k, v]);
         | 
| 447 | 
            +
                        }
         | 
| 448 | 
            +
                        stats[field].sort(function(a, b) {
         | 
| 449 | 
            +
                          return a[1] - b[1];
         | 
| 450 | 
            +
                        }).reverse();
         | 
| 451 | 
            +
                      }
         | 
| 452 | 
            +
                      $scope.stats = stats;
         | 
| 453 | 
            +
                    }
         | 
| 454 | 
            +
                    if ('rows' in data && !angular.equals($scope.previous_events_events, data.rows)) {
         | 
| 455 | 
            +
                      $scope.previous_events_events = angular.copy(data.rows);
         | 
| 456 | 
            +
                      _ref1 = data.rows;
         | 
| 457 | 
            +
                      for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
         | 
| 458 | 
            +
                        event = _ref1[_i];
         | 
| 459 | 
            +
                        event = event.doc.event;
         | 
| 460 | 
            +
                        id = "" + event.client.name + "/" + event.check.name;
         | 
| 461 | 
            +
                        event.id = CryptoJS.MD5(id).toString(CryptoJS.enc.Base64);
         | 
| 462 | 
            +
                        if ((_ref2 = event.id, __indexOf.call($scope.showDetails, _ref2) >= 0) || $scope.showAll === 'true') {
         | 
| 463 | 
            +
                          event.showdetails = 'in';
         | 
| 464 | 
            +
                        } else {
         | 
| 465 | 
            +
                          event.showdetails = '';
         | 
| 466 | 
            +
                        }
         | 
| 467 | 
            +
                        event.color = color[event.check.status];
         | 
| 468 | 
            +
                        event.wstatus = status[event.check.status];
         | 
| 469 | 
            +
                        if (event.check.state_change === null || event.check.state_change === void 0) {
         | 
| 470 | 
            +
                          event.rel_time = 'n/a';
         | 
| 471 | 
            +
                        } else {
         | 
| 472 | 
            +
                          event.rel_time = moment.unix(event.check.state_change).fromNow();
         | 
| 473 | 
            +
                        }
         | 
| 474 | 
            +
                        event.check.issued = event.check.issued * 1000;
         | 
| 475 | 
            +
                        if (event.check.state_change != null) {
         | 
| 476 | 
            +
                          event.check.state_change = event.check.state_change * 1000;
         | 
| 477 | 
            +
                        }
         | 
| 478 | 
            +
                        if ((_base = event.client).silenced == null) {
         | 
| 479 | 
            +
                          _base.silenced = false;
         | 
| 480 | 
            +
                        }
         | 
| 481 | 
            +
                        if ((_base1 = event.check).silenced == null) {
         | 
| 482 | 
            +
                          _base1.silenced = false;
         | 
| 483 | 
            +
                        }
         | 
| 484 | 
            +
                        if ($scope.stashes != null) {
         | 
| 485 | 
            +
                          _ref3 = $scope.stashes;
         | 
| 486 | 
            +
                          for (_j = 0, _len1 = _ref3.length; _j < _len1; _j++) {
         | 
| 487 | 
            +
                            stash = _ref3[_j];
         | 
| 488 | 
            +
                            parts = stash['path'].split('/', 3);
         | 
| 489 | 
            +
                            client = parts[1];
         | 
| 490 | 
            +
                            if (parts.length > 2) {
         | 
| 491 | 
            +
                              check = parts[2];
         | 
| 492 | 
            +
                            } else {
         | 
| 493 | 
            +
                              check = null;
         | 
| 494 | 
            +
                            }
         | 
| 495 | 
            +
                            if (client === event.client.name) {
         | 
| 496 | 
            +
                              if (check === null) {
         | 
| 497 | 
            +
                                event.client.silenced = true;
         | 
| 498 | 
            +
                                event.client.silence_stash = stash;
         | 
| 499 | 
            +
                              } else if (check === event.check.name) {
         | 
| 500 | 
            +
                                event.check.silenced = true;
         | 
| 501 | 
            +
                                event.check.silence_stash = stash;
         | 
| 502 | 
            +
                              }
         | 
| 503 | 
            +
                            }
         | 
| 504 | 
            +
                          }
         | 
| 505 | 
            +
                        }
         | 
| 506 | 
            +
                        event.attributes = $scope.getEventAttributes(event);
         | 
| 507 | 
            +
                        events.push(event);
         | 
| 508 | 
            +
                      }
         | 
| 509 | 
            +
                      $scope.events_spin = false;
         | 
| 510 | 
            +
                      if (!angular.equals($scope.events, events)) {
         | 
| 511 | 
            +
                        $scope.events = events;
         | 
| 512 | 
            +
                        $scope.updateStashes();
         | 
| 513 | 
            +
                      }
         | 
| 514 | 
            +
                    }
         | 
| 515 | 
            +
                    $scope.events_spin = false;
         | 
| 516 | 
            +
                    return $('#corner_status').text("Last Update: " + $filter('date')(Date.now(), 'mediumTime'));
         | 
| 517 | 
            +
                  });
         | 
| 518 | 
            +
                };
         | 
| 519 | 
            +
                $scope.updateEventFields();
         | 
| 520 | 
            +
                $scope.updateEvents();
         | 
| 521 | 
            +
                $scope.changes = function() {
         | 
| 522 | 
            +
                  var params;
         | 
| 523 | 
            +
                  $log.info("STARTING _CHANGES FEED");
         | 
| 524 | 
            +
                  params = {
         | 
| 525 | 
            +
                    feed: 'longpoll',
         | 
| 526 | 
            +
                    heartbeat: 10000
         | 
| 527 | 
            +
                  };
         | 
| 528 | 
            +
                  if ($scope.last_seq != null) {
         | 
| 529 | 
            +
                    params['since'] = $scope.last_seq;
         | 
| 530 | 
            +
                    return eventsFactory.changes(params).success(function(data, status, headers, config) {
         | 
| 531 | 
            +
                      $scope.last_seq = data['last_seq'];
         | 
| 532 | 
            +
                      $scope.updateEvents();
         | 
| 533 | 
            +
                      if ($scope.isActive === true) {
         | 
| 534 | 
            +
                        return $scope.changes();
         | 
| 535 | 
            +
                      }
         | 
| 536 | 
            +
                    }).error(function(data, status, headers, config) {
         | 
| 537 | 
            +
                      $log.error("failed changes request (" + status + ") - " + data);
         | 
| 538 | 
            +
                      if ($scope.isActive === true) {
         | 
| 539 | 
            +
                        return $scope.changes();
         | 
| 540 | 
            +
                      }
         | 
| 541 | 
            +
                    });
         | 
| 542 | 
            +
                  }
         | 
| 543 | 
            +
                };
         | 
| 544 | 
            +
                $scope.get_sequence = function() {
         | 
| 545 | 
            +
                  return eventsFactory.last_sequence().success(function(data, status, headers, config) {
         | 
| 546 | 
            +
                    $scope.last_seq = data['last_seq'];
         | 
| 547 | 
            +
                    $log.info($scope.last_seq);
         | 
| 548 | 
            +
                    return $scope.changes();
         | 
| 549 | 
            +
                  });
         | 
| 550 | 
            +
                };
         | 
| 551 | 
            +
                $scope.get_sequence();
         | 
| 552 | 
            +
                $scope.bulkToggleDetails = function() {
         | 
| 553 | 
            +
                  var action, event, _i, _j, _len, _len1, _ref, _ref1, _results;
         | 
| 554 | 
            +
                  if ($scope.bulk === 'show') {
         | 
| 555 | 
            +
                    action = 'show';
         | 
| 556 | 
            +
                    $scope.showDetails = [];
         | 
| 557 | 
            +
                    _ref = $scope.events;
         | 
| 558 | 
            +
                    for (_i = 0, _len = _ref.length; _i < _len; _i++) {
         | 
| 559 | 
            +
                      event = _ref[_i];
         | 
| 560 | 
            +
                      $scope.showDetails.push(event.id);
         | 
| 561 | 
            +
                    }
         | 
| 562 | 
            +
                  } else {
         | 
| 563 | 
            +
                    action = 'hide';
         | 
| 564 | 
            +
                    $scope.showDetails = [];
         | 
| 565 | 
            +
                  }
         | 
| 566 | 
            +
                  _ref1 = $scope.events;
         | 
| 567 | 
            +
                  _results = [];
         | 
| 568 | 
            +
                  for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
         | 
| 569 | 
            +
                    event = _ref1[_j];
         | 
| 570 | 
            +
                    _results.push($("#" + event.id).collapse(action));
         | 
| 571 | 
            +
                  }
         | 
| 572 | 
            +
                  return _results;
         | 
| 573 | 
            +
                };
         | 
| 574 | 
            +
                $('.collapse').on('hide.bs.collapse', function() {
         | 
| 575 | 
            +
                  if ($scope.showDetails.length === 0) {
         | 
| 576 | 
            +
                    return $scope.bulk = 'show';
         | 
| 577 | 
            +
                  }
         | 
| 578 | 
            +
                });
         | 
| 579 | 
            +
                $('.collapse').on('show.bs.collapse', function() {
         | 
| 580 | 
            +
                  if ($scope.showDetails.length > 0) {
         | 
| 581 | 
            +
                    return $scope.bulk = 'hide';
         | 
| 582 | 
            +
                  }
         | 
| 583 | 
            +
                });
         | 
| 584 | 
            +
                $scope.toggleDetails = function(id) {
         | 
| 585 | 
            +
                  var i;
         | 
| 586 | 
            +
                  if (!$("#" + id).hasClass('in')) {
         | 
| 587 | 
            +
                    $("#" + id).collapse('show');
         | 
| 588 | 
            +
                    if ($scope.showDetails.indexOf(id) === -1) {
         | 
| 589 | 
            +
                      $scope.showDetails.push(id);
         | 
| 590 | 
            +
                    }
         | 
| 591 | 
            +
                    $("#" + id).parent().find('.toggleBtnIcon').removeClass('glyphicon-collapse-down');
         | 
| 592 | 
            +
                    return $("#" + id).parent().find('.toggleBtnIcon').addClass('glyphicon-collapse-up');
         | 
| 593 | 
            +
                  } else {
         | 
| 594 | 
            +
                    $("#" + id).collapse('hide');
         | 
| 595 | 
            +
                    i = $scope.showDetails.indexOf(id);
         | 
| 596 | 
            +
                    if (i !== -1) {
         | 
| 597 | 
            +
                      $scope.showDetails.splice(i, 1);
         | 
| 598 | 
            +
                    }
         | 
| 599 | 
            +
                    $("#" + id).parent().find('.toggleBtnIcon').removeClass('glyphicon-collapse-up');
         | 
| 600 | 
            +
                    return $("#" + id).parent().find('.toggleBtnIcon').addClass('glyphicon-collapse-down');
         | 
| 601 | 
            +
                  }
         | 
| 602 | 
            +
                };
         | 
| 603 | 
            +
                $scope.togglePopover = function() {
         | 
| 604 | 
            +
                  $(this).popover();
         | 
| 605 | 
            +
                  return $(this).popover('toggle');
         | 
| 606 | 
            +
                };
         | 
| 607 | 
            +
                $scope.typeIsArray = function(value) {
         | 
| 608 | 
            +
                  return value && typeof value === 'object' && value instanceof Array && typeof value.length === 'number' && typeof value.splice === 'function' && !(value.propertyIsEnumerable('length'));
         | 
| 609 | 
            +
                };
         | 
| 610 | 
            +
             | 
| 611 | 
            +
                /* Keyboard Shortcuts */
         | 
| 612 | 
            +
                Mousetrap.bind('?', function() {
         | 
| 613 | 
            +
                  $log.info('showing shortcuts');
         | 
| 614 | 
            +
                  return $("#keyboard_shortcuts").modal('show');
         | 
| 615 | 
            +
                }, 'keyup');
         | 
| 616 | 
            +
                Mousetrap.bind('.', function() {
         | 
| 617 | 
            +
                  return $('#search_input').focus();
         | 
| 618 | 
            +
                }, 'keyup');
         | 
| 619 | 
            +
                Mousetrap.bind('s', function() {
         | 
| 620 | 
            +
                  $('#sort').focus();
         | 
| 621 | 
            +
                  return $('#sort').click();
         | 
| 622 | 
            +
                }, 'keyup');
         | 
| 623 | 
            +
                return Mousetrap.bind('enter', function() {
         | 
| 624 | 
            +
                  return $scope.updateParams();
         | 
| 625 | 
            +
                }, 'keyup');
         | 
| 626 | 
            +
              });
         | 
| 627 | 
            +
             | 
| 628 | 
            +
              sabisu.directive('searchTypeahead', function($log, $window, $filter, $timeout, eventsFactory) {
         | 
| 629 | 
            +
                return function(scope, element, attrs) {
         | 
| 630 | 
            +
                  var all_but_last_clause, at_bool, at_key, at_none, at_val, clause_char_list, current_clause, el, whitespace_at_end;
         | 
| 631 | 
            +
                  clause_char_list = "a-zA-Z0-9_\\-\\?\\*\\+\\~\\.\\[\\]\\{\\}\\^\"";
         | 
| 632 | 
            +
                  el = angular.element(element);
         | 
| 633 | 
            +
                  current_clause = function() {
         | 
| 634 | 
            +
                    var lastIndex;
         | 
| 635 | 
            +
                    lastIndex = el.current_search_string.lastIndexOf(" ");
         | 
| 636 | 
            +
                    return el.current_search_string.substring(lastIndex + 1).split(':');
         | 
| 637 | 
            +
                  };
         | 
| 638 | 
            +
                  all_but_last_clause = function() {
         | 
| 639 | 
            +
                    var a, lastIndex;
         | 
| 640 | 
            +
                    lastIndex = el.current_search_string.lastIndexOf(" ");
         | 
| 641 | 
            +
                    a = el.current_search_string.substring(0, lastIndex);
         | 
| 642 | 
            +
                    if (a.length > 0) {
         | 
| 643 | 
            +
                      a = a + ' ';
         | 
| 644 | 
            +
                    }
         | 
| 645 | 
            +
                    return a;
         | 
| 646 | 
            +
                  };
         | 
| 647 | 
            +
                  whitespace_at_end = function() {
         | 
| 648 | 
            +
                    var m;
         | 
| 649 | 
            +
                    m = el.current_search_string.match(RegExp(" $"));
         | 
| 650 | 
            +
                    return m != null;
         | 
| 651 | 
            +
                  };
         | 
| 652 | 
            +
                  at_none = function() {
         | 
| 653 | 
            +
                    var c, quote_count;
         | 
| 654 | 
            +
                    c = current_clause();
         | 
| 655 | 
            +
                    quote_count = 0;
         | 
| 656 | 
            +
                    if (c.length >= 2) {
         | 
| 657 | 
            +
                      quote_count = c[1].split('"').length - 1;
         | 
| 658 | 
            +
                    }
         | 
| 659 | 
            +
                    return el.current_search_string.slice(-1) === '"' && quote_count === 2;
         | 
| 660 | 
            +
                  };
         | 
| 661 | 
            +
                  at_val = function() {
         | 
| 662 | 
            +
                    return (current_clause() != null) && current_clause().length === 2 && !whitespace_at_end();
         | 
| 663 | 
            +
                  };
         | 
| 664 | 
            +
                  at_bool = function() {
         | 
| 665 | 
            +
                    if (all_but_last_clause().match(RegExp("(AND|AND NOT|OR|OR NOT) $"))) {
         | 
| 666 | 
            +
                      return false;
         | 
| 667 | 
            +
                    }
         | 
| 668 | 
            +
                    if (all_but_last_clause() === '') {
         | 
| 669 | 
            +
                      return false;
         | 
| 670 | 
            +
                    }
         | 
| 671 | 
            +
                    if ((current_clause() != null) && current_clause().length === 2 && whitespace_at_end()) {
         | 
| 672 | 
            +
                      return true;
         | 
| 673 | 
            +
                    }
         | 
| 674 | 
            +
                    if (current_clause() !== null) {
         | 
| 675 | 
            +
                      if ('AND NOT'.match(RegExp("^" + (current_clause()[0]))) != null) {
         | 
| 676 | 
            +
                        return true;
         | 
| 677 | 
            +
                      }
         | 
| 678 | 
            +
                      if ('OR NOT'.match(RegExp("^" + (current_clause()[0]))) != null) {
         | 
| 679 | 
            +
                        return true;
         | 
| 680 | 
            +
                      }
         | 
| 681 | 
            +
                    }
         | 
| 682 | 
            +
                    return false;
         | 
| 683 | 
            +
                  };
         | 
| 684 | 
            +
                  at_key = function() {
         | 
| 685 | 
            +
                    return !at_bool() && !at_val() && !at_none();
         | 
| 686 | 
            +
                  };
         | 
| 687 | 
            +
                  el.typeahead({
         | 
| 688 | 
            +
                    minLength: 0,
         | 
| 689 | 
            +
                    highlight: true,
         | 
| 690 | 
            +
                    hint: true
         | 
| 691 | 
            +
                  }, {
         | 
| 692 | 
            +
                    name: 'keys',
         | 
| 693 | 
            +
                    displayKey: 'name',
         | 
| 694 | 
            +
                    source: function(search_string, cb) {
         | 
| 695 | 
            +
                      var data, dd, indent, key, search_word, search_word_clean, sel_start;
         | 
| 696 | 
            +
                      el.current_search_string = search_string;
         | 
| 697 | 
            +
                      search_word = current_clause() ? current_clause().slice(-1)[0] : '';
         | 
| 698 | 
            +
                      if (at_key() && whitespace_at_end()) {
         | 
| 699 | 
            +
                        search_word = '';
         | 
| 700 | 
            +
                      }
         | 
| 701 | 
            +
                      search_word_clean = search_word.trim().replace(/"/, '');
         | 
| 702 | 
            +
                      sel_start = element[0].selectionStart || 0;
         | 
| 703 | 
            +
                      if (whitespace_at_end()) {
         | 
| 704 | 
            +
                        indent = Math.max(0, sel_start) * 0.535;
         | 
| 705 | 
            +
                      } else {
         | 
| 706 | 
            +
                        if (current_clause().length > 1) {
         | 
| 707 | 
            +
                          key = current_clause()[0].length + 1;
         | 
| 708 | 
            +
                        } else {
         | 
| 709 | 
            +
                          key = 0;
         | 
| 710 | 
            +
                        }
         | 
| 711 | 
            +
                        indent = Math.max(0, sel_start - (search_word.length + key)) * 0.535;
         | 
| 712 | 
            +
                      }
         | 
| 713 | 
            +
                      dd = angular.element("#" + element[0].id + " ~ .tt-dropdown-menu");
         | 
| 714 | 
            +
                      dd[0].style.left = "" + indent + "em";
         | 
| 715 | 
            +
                      if (search_string.length === 0) {
         | 
| 716 | 
            +
                        angular.element(".tt-hint").hide();
         | 
| 717 | 
            +
                      } else {
         | 
| 718 | 
            +
                        angular.element(".tt-hint").show();
         | 
| 719 | 
            +
                      }
         | 
| 720 | 
            +
                      if (at_val()) {
         | 
| 721 | 
            +
                        key = current_clause()[0];
         | 
| 722 | 
            +
                        if (scope.stats[key]) {
         | 
| 723 | 
            +
                          data = [];
         | 
| 724 | 
            +
                          angular.forEach(scope.stats[key], function(v, k) {
         | 
| 725 | 
            +
                            if (v[0].trim() !== "" && v[0].indexOf(search_word_clean) === 0) {
         | 
| 726 | 
            +
                              return data.push({
         | 
| 727 | 
            +
                                name: "" + key + ":" + v[0]
         | 
| 728 | 
            +
                              });
         | 
| 729 | 
            +
                            }
         | 
| 730 | 
            +
                          });
         | 
| 731 | 
            +
                          data = $filter('orderBy')(data, 'name');
         | 
| 732 | 
            +
                          return cb(data);
         | 
| 733 | 
            +
                        } else {
         | 
| 734 | 
            +
                          return cb([]);
         | 
| 735 | 
            +
                        }
         | 
| 736 | 
            +
                      } else if (at_bool()) {
         | 
| 737 | 
            +
                        return cb([
         | 
| 738 | 
            +
                          {
         | 
| 739 | 
            +
                            name: 'AND'
         | 
| 740 | 
            +
                          }, {
         | 
| 741 | 
            +
                            name: 'AND NOT'
         | 
| 742 | 
            +
                          }, {
         | 
| 743 | 
            +
                            name: 'OR'
         | 
| 744 | 
            +
                          }, {
         | 
| 745 | 
            +
                            name: 'OR NOT'
         | 
| 746 | 
            +
                          }
         | 
| 747 | 
            +
                        ]);
         | 
| 748 | 
            +
                      } else if (at_none()) {
         | 
| 749 | 
            +
                        return cb([]);
         | 
| 750 | 
            +
                      } else {
         | 
| 751 | 
            +
                        return eventsFactory.event_fields().success(function(data, status, headers, config) {
         | 
| 752 | 
            +
                          var field, fields, _i, _len;
         | 
| 753 | 
            +
                          fields = [];
         | 
| 754 | 
            +
                          for (_i = 0, _len = data.length; _i < _len; _i++) {
         | 
| 755 | 
            +
                            field = data[_i];
         | 
| 756 | 
            +
                            if (field.index) {
         | 
| 757 | 
            +
                              fields.push(field);
         | 
| 758 | 
            +
                            }
         | 
| 759 | 
            +
                          }
         | 
| 760 | 
            +
                          if (search_word_clean.length > 0) {
         | 
| 761 | 
            +
                            fields = $.grep(fields, function(n, i) {
         | 
| 762 | 
            +
                              return n.name.indexOf(search_word_clean) === 0;
         | 
| 763 | 
            +
                            });
         | 
| 764 | 
            +
                          }
         | 
| 765 | 
            +
                          fields = $filter('orderBy')(fields, 'name');
         | 
| 766 | 
            +
                          return cb(fields);
         | 
| 767 | 
            +
                        });
         | 
| 768 | 
            +
                      }
         | 
| 769 | 
            +
                    }
         | 
| 770 | 
            +
                  });
         | 
| 771 | 
            +
                  el.on('focus', function() {
         | 
| 772 | 
            +
                    var curval;
         | 
| 773 | 
            +
                    curval = scope.search_field;
         | 
| 774 | 
            +
                    el.typeahead('val', 'c').typeahead('open');
         | 
| 775 | 
            +
                    return el.typeahead('val', curval).typeahead('open');
         | 
| 776 | 
            +
                  });
         | 
| 777 | 
            +
                  el.on('typeahead:selected', function($e, datum) {
         | 
| 778 | 
            +
                    var val;
         | 
| 779 | 
            +
                    if (at_val()) {
         | 
| 780 | 
            +
                      val = datum.name.split(':');
         | 
| 781 | 
            +
                      el.typeahead('val', all_but_last_clause() + val[0] + ':"' + val[1] + '" ');
         | 
| 782 | 
            +
                    } else if (at_key()) {
         | 
| 783 | 
            +
                      el.typeahead('val', all_but_last_clause() + datum.name + ':');
         | 
| 784 | 
            +
                    } else {
         | 
| 785 | 
            +
                      el.typeahead('val', all_but_last_clause() + datum.name + ' ');
         | 
| 786 | 
            +
                    }
         | 
| 787 | 
            +
                    scope.search_field = el.typeahead('val');
         | 
| 788 | 
            +
                    return $timeout(function() {
         | 
| 789 | 
            +
                      var curval;
         | 
| 790 | 
            +
                      curval = el.typeahead('val');
         | 
| 791 | 
            +
                      el.typeahead('val', 'c').typeahead('open');
         | 
| 792 | 
            +
                      return el.typeahead('val', curval).typeahead('open');
         | 
| 793 | 
            +
                    }, 100);
         | 
| 794 | 
            +
                  });
         | 
| 795 | 
            +
                  el.on('typeahead:autocompleted', function($e, datum) {
         | 
| 796 | 
            +
                    var val;
         | 
| 797 | 
            +
                    if (at_key()) {
         | 
| 798 | 
            +
                      el.typeahead('val', all_but_last_clause() + datum.name + ':');
         | 
| 799 | 
            +
                    } else if (at_val()) {
         | 
| 800 | 
            +
                      val = datum.name.split(':');
         | 
| 801 | 
            +
                      el.typeahead('val', all_but_last_clause() + val[0] + ':"' + val[1] + '" ');
         | 
| 802 | 
            +
                    } else {
         | 
| 803 | 
            +
                      el.typeahead('val', all_but_last_clause() + datum.name + ' ');
         | 
| 804 | 
            +
                    }
         | 
| 805 | 
            +
                    scope.search_field = el.typeahead('val');
         | 
| 806 | 
            +
                    return el.typeahead('open');
         | 
| 807 | 
            +
                  });
         | 
| 808 | 
            +
                  return el.on('typeahead:cursorchanged', function($e, datum, dsName) {
         | 
| 809 | 
            +
                    angular.element(".tt-input").val(all_but_last_clause() + datum.name);
         | 
| 810 | 
            +
                    return angular.element(".tt-hint").val("");
         | 
| 811 | 
            +
                  });
         | 
| 812 | 
            +
                };
         | 
| 813 | 
            +
              });
         | 
| 814 | 
            +
             | 
| 815 | 
            +
              sabisu.factory('eventsFactory', function($log, $http) {
         | 
| 816 | 
            +
                var factory;
         | 
| 817 | 
            +
                factory = {};
         | 
| 818 | 
            +
                factory.searchEvents = function(search_query, sort, limit, ints) {
         | 
| 819 | 
            +
                  if (sort === 'age') {
         | 
| 820 | 
            +
                    sort = 'state_change';
         | 
| 821 | 
            +
                  }
         | 
| 822 | 
            +
                  if (sort === '-age') {
         | 
| 823 | 
            +
                    sort = '-state_change';
         | 
| 824 | 
            +
                  }
         | 
| 825 | 
            +
                  if (__indexOf.call(ints, sort) < 0) {
         | 
| 826 | 
            +
                    sort = sort + '<string>';
         | 
| 827 | 
            +
                  }
         | 
| 828 | 
            +
                  sort = "[\"" + sort + "\"]";
         | 
| 829 | 
            +
                  if (search_query === '') {
         | 
| 830 | 
            +
                    search_query = '*:*';
         | 
| 831 | 
            +
                  }
         | 
| 832 | 
            +
                  return $http({
         | 
| 833 | 
            +
                    method: 'GET',
         | 
| 834 | 
            +
                    url: '/api/events/search',
         | 
| 835 | 
            +
                    params: {
         | 
| 836 | 
            +
                      query: search_query,
         | 
| 837 | 
            +
                      limit: limit,
         | 
| 838 | 
            +
                      sort: sort
         | 
| 839 | 
            +
                    }
         | 
| 840 | 
            +
                  });
         | 
| 841 | 
            +
                };
         | 
| 842 | 
            +
                factory.resolveEvent = function(client, check) {
         | 
| 843 | 
            +
                  return $http({
         | 
| 844 | 
            +
                    method: 'POST',
         | 
| 845 | 
            +
                    url: '/sensu/resolve',
         | 
| 846 | 
            +
                    data: {
         | 
| 847 | 
            +
                      client: client,
         | 
| 848 | 
            +
                      check: check
         | 
| 849 | 
            +
                    }
         | 
| 850 | 
            +
                  });
         | 
| 851 | 
            +
                };
         | 
| 852 | 
            +
                factory.changes = function(params) {
         | 
| 853 | 
            +
                  return $http({
         | 
| 854 | 
            +
                    method: 'GET',
         | 
| 855 | 
            +
                    url: '/api/events/changes',
         | 
| 856 | 
            +
                    params: params
         | 
| 857 | 
            +
                  });
         | 
| 858 | 
            +
                };
         | 
| 859 | 
            +
                factory.last_sequence = function() {
         | 
| 860 | 
            +
                  return $http({
         | 
| 861 | 
            +
                    method: 'GET',
         | 
| 862 | 
            +
                    url: '/api/events/changes',
         | 
| 863 | 
            +
                    params: {
         | 
| 864 | 
            +
                      limit: 1,
         | 
| 865 | 
            +
                      descending: true
         | 
| 866 | 
            +
                    }
         | 
| 867 | 
            +
                  });
         | 
| 868 | 
            +
                };
         | 
| 869 | 
            +
                factory.event_fields = function() {
         | 
| 870 | 
            +
                  return $http({
         | 
| 871 | 
            +
                    method: 'GET',
         | 
| 872 | 
            +
                    url: '/api/configuration/fields'
         | 
| 873 | 
            +
                  });
         | 
| 874 | 
            +
                };
         | 
| 875 | 
            +
                return factory;
         | 
| 876 | 
            +
              });
         | 
| 877 | 
            +
             | 
| 878 | 
            +
              sabisu.factory('stashesFactory', function($log, $http) {
         | 
| 879 | 
            +
                var factory;
         | 
| 880 | 
            +
                factory = {};
         | 
| 881 | 
            +
                factory.stashes = function() {
         | 
| 882 | 
            +
                  return $http.get('/sensu/stashes');
         | 
| 883 | 
            +
                };
         | 
| 884 | 
            +
                factory.saveStash = function(stash) {
         | 
| 885 | 
            +
                  return $http.post("/sensu/stashes", stash);
         | 
| 886 | 
            +
                };
         | 
| 887 | 
            +
                factory.deleteStash = function(path) {
         | 
| 888 | 
            +
                  return $http["delete"]("/sensu/stashes/" + path);
         | 
| 889 | 
            +
                };
         | 
| 890 | 
            +
                return factory;
         | 
| 891 | 
            +
              });
         | 
| 892 | 
            +
             | 
| 893 | 
            +
            }).call(this);
         |