소스 검색

HUE-894 [core] Log search

Added action bar with search and highlighting functionality
It's now possible to pass a parameter to the page to scroll automatically to the search query
Enrico Berti 13 년 전
부모
커밋
b4cf5b5
2개의 변경된 파일118개의 추가작업 그리고 14개의 파일을 삭제
  1. 117 13
      desktop/core/src/desktop/templates/logs.mako
  2. 1 1
      desktop/core/src/desktop/views.py

+ 117 - 13
desktop/core/src/desktop/templates/logs.mako

@@ -20,21 +20,125 @@ from desktop.views import commonheader, commonfooter
 from django.utils.translation import ugettext as _
 import re
 %>
+<%namespace name="actionbar" file="actionbar.mako" />
 <%namespace name="layout" file="about_layout.mako" />
 ${commonheader(_('About'), "about", user, "100px")}
 ${layout.menubar(section='log_view')}
-	<div class="container-fluid">
-		<h1>${_('Log entries (most recent first)')}</h1>
-
-		<a href="/download_logs">${_('Download entire log as zip')}</a>
-		<hr/>
-		<% log.reverse() %>
-		<pre>
-		% for l in log:
-${smart_unicode(l, errors='ignore') | h}
-		% endfor
-		</pre>
-
-	</div>
+
+<style>
+  pre {
+    margin: 0;
+    padding: 2px;
+    border: 0;
+  }
+
+  pre.highlighted {
+    background-color: #FFFF88;
+  }
+
+  #logs {
+    overflow: auto;
+  }
+
+  #logs pre:first-child {
+    padding-top: 10px;
+  }
+
+  #logs pre:last-child {
+    padding-bottom: 10px;
+  }
+
+  .notFound {
+    background-color: #f09999 !important;
+  }
+</style>
+
+<div class="container-fluid">
+  <h1>${_('Log entries (most recent first)')}</h1>
+
+  <%actionbar:render>
+    <%def name="search()">
+        <input type="text" class="input-xxlarge search-query" placeholder="${_('Search...')}" value="${query}">
+    </%def>
+    <%def name="creation()">
+        <span class="btn-group">
+          <a href="/download_logs" class="btn"><i class="icon-download-alt"></i> ${_('Download entire log as zip')}</a>
+        </span>
+    </%def>
+  </%actionbar:render>
+
+  <% log.reverse() %>
+
+  <div id="logs">
+      % for l in log:
+        <pre>${smart_unicode(l, errors='ignore') | h}</pre>
+      % endfor
+  </div>
+
+</div>
+
+<script>
+  $(document).ready(function () {
+
+    resizeScrollingLogs();
+
+    var resizeTimeout = -1;
+    $(window).resize(function () {
+      window.clearTimeout(resizeTimeout);
+      resizeTimeout = window.setTimeout(function () {
+        resizeScrollingLogs();
+      }, 200);
+    });
+
+    var filterTimeout = -1;
+    $(".search-query").keyup(function () {
+      window.clearTimeout(filterTimeout);
+      filterTimeout = window.setTimeout(function () {
+        filterLogs($(".search-query").val());
+      }, 500);
+    });
+
+    if ("${query}" != "") {
+      filterLogs("${query}");
+    }
+
+    function resizeScrollingLogs() {
+      var _el = $("#logs");
+      if (!$.browser.msie) {
+        _el.css("overflow-y", "").css("height", "");
+      }
+      var heightAfter = 0;
+      _el.nextAll(":visible").each(function () {
+        heightAfter += $(this).outerHeight(true);
+      });
+      if (_el.height() > ($(window).height() - _el.offset().top - heightAfter)) {
+        _el.css("overflow-y", "auto").height($(window).height() - _el.offset().top - heightAfter);
+      }
+    }
+
+    function filterLogs(query) {
+      $(".search-query").removeClass("notFound");
+      if ($.trim(query) == "") {
+        $("#logs").scrollTop(0);
+        return false;
+      }
+      $("pre.highlighted").removeClass("highlighted");
+      var found = false;
+      $("#logs pre").each(function () {
+        var _el = $(this);
+        if (_el.text().toLowerCase().replace(/\s/g, "").indexOf(query.toLowerCase().replace(/\s/g, "")) > -1) {
+          _el.addClass("highlighted");
+          $("#logs").scrollTop(_el.offset().top - $("#logs").position().top - 4);
+          found = true;
+          return false;
+        }
+      });
+      if (!found) {
+        $(".search-query").addClass("notFound");
+        $("#logs").scrollTop(0);
+      }
+    }
+  });
+</script>
 
 ${commonfooter(messages)}

+ 1 - 1
desktop/core/src/desktop/views.py

@@ -51,7 +51,7 @@ def log_view(request):
   l = logging.getLogger()
   for h in l.handlers:
     if isinstance(h, desktop.log.log_buffer.FixedBufferHandler):
-      return render('logs.mako', request, dict(log=[l for l in h.buf]))
+      return render('logs.mako', request, dict(log=[l for l in h.buf], query=request.GET.get("q", "")))
 
   return render('logs.mako', request, dict(log=[_("No logs found!")]))