Pārlūkot izejas kodu

[search] Changed date picker

Enrico Berti 11 gadi atpakaļ
vecāks
revīzija
335d623

+ 252 - 11
apps/search/src/search/templates/search.mako

@@ -314,14 +314,16 @@ ${ commonheader(_('Search'), "search", user, "80px") | n,unicode }
         <div class="slider-cnt" data-bind="slider: {start: properties.start, end: properties.end, gap: properties.gap, min: properties.min, max: properties.max}"></div>
       <!-- /ko -->
       <!-- ko if: properties.isDate() -->
-        <div class="input-prepend input-group">
-           <span class="add-on input-group-addon"><i class="fa fa-calendar"></i></span><input type="text" class="input-xxlarge form-control" data-bind="daterangepicker: {start: properties.start, end: properties.end, gap: properties.gap, min: properties.min, max: properties.max}" />
-        </div>
+        <div data-bind="simpledaterangepicker: {start: properties.start, end: properties.end, gap: properties.gap, min: properties.min, max: properties.max}"></div>
         <br/>
       <!-- /ko -->
     <!-- /ko -->
     <!-- ko if: type() == 'field' -->
-      ${ _('Limit') }: <input type="text" class="input-medium" data-bind="spinedit: properties.limit" />
+      <div class="facet-field-cnt">
+        <span class="spinedit-cnt">
+          <span class="facet-field-label">${ _('Limit') }</span> <input type="text" class="input-medium" data-bind="spinedit: properties.limit" />
+        </span>
+      </div>
     <!-- /ko -->
 
     <a href="javascript: void(0)" class="btn btn-loading" data-bind="visible: properties.canRange, click: $root.collection.toggleRangeFacet" data-loading-text="...">
@@ -665,7 +667,7 @@ ${ commonheader(_('Search'), "search", user, "80px") | n,unicode }
 
   <span data-bind="visible: $root.isEditing()">
     ${ _('Show') }
-    <span class="spinedit-pagination">
+    <span class="spinedit-cnt">
       <input type="text" data-bind="spinedit: $root.collection.template.rows, valueUpdate:'afterkeydown'" style="text-align: center; margin-bottom: 0" />
     </span>
     ${ _('results per page') }
@@ -706,12 +708,11 @@ ${ commonheader(_('Search'), "search", user, "80px") | n,unicode }
       </span>
     </div>  
 
-    <a href="javascript:void(0)" data-bind="click: $root.collection.timeLineZoom"><i class="fa fa-search-minus"></i></a>
-    <span>
-      ${ _('Group By') }
-      <select class="input-medium" data-bind="options: $root.query.multiqs, optionsValue: 'id',optionsText: 'label', value: $root.query.selectedMultiq">
-      </select>      
-    </span>
+    <div style="padding-bottom: 10px; text-align: center">
+      <a href="javascript:void(0)" data-bind="click: $root.collection.timeLineZoom"><i class="fa fa-search-minus"></i></a>
+      <span class="facet-field-label">${ _('Group by') }</span>
+      <select class="input-medium" data-bind="options: $root.query.multiqs, optionsValue: 'id',optionsText: 'label', value: $root.query.selectedMultiq"></select>
+    </div>
 
     <div data-bind="timelineChart: {datum: {counts: counts, extraSeries: extraSeries, widget_id: $parent.id(), label: label}, stacked: $root.collection.getFacetById($parent.id()).properties.stacked(), field: field, label: label, transformer: timelineChartDataTransformer,
       fqs: $root.query.fqs,
@@ -944,6 +945,8 @@ ${ commonheader(_('Search'), "search", user, "80px") | n,unicode }
 <link rel="stylesheet" href="/static/css/freshereditor.css">
 <link rel="stylesheet" href="/static/ext/css/codemirror.css">
 <link rel="stylesheet" href="/static/ext/css/bootstrap-editable.css">
+<link rel="stylesheet" href="/static/ext/css/bootstrap-datepicker.min.css">
+<link rel="stylesheet" href="/static/ext/css/bootstrap-timepicker.min.css">
 <link rel="stylesheet" href="/static/css/bootstrap-spinedit.css">
 <link rel="stylesheet" href="/static/css/bootstrap-slider.css">
 <link rel="stylesheet" href="/static/css/bootstrap-daterangepicker.css">
@@ -959,6 +962,8 @@ ${ commonheader(_('Search'), "search", user, "80px") | n,unicode }
 <script src="/static/ext/js/knockout.mapping-2.3.2.js" type="text/javascript" charset="utf-8"></script>
 <script src="/static/ext/js/knockout-sortable.min.js" type="text/javascript" charset="utf-8"></script>
 <script src="/static/ext/js/bootstrap-editable.min.js" type="text/javascript" charset="utf-8"></script>
+<script src="/static/ext/js/bootstrap-datepicker.min.js" type="text/javascript" charset="utf-8"></script>
+<script src="/static/ext/js/bootstrap-timepicker.min.js" type="text/javascript" charset="utf-8"></script>
 <script src="/static/js/bootstrap-spinedit.js" type="text/javascript" charset="utf-8"></script>
 <script src="/static/js/bootstrap-slider.js" type="text/javascript" charset="utf-8"></script>
 <script src="/static/js/bootstrap-daterangepicker.js" type="text/javascript" charset="utf-8"></script>
@@ -1383,6 +1388,241 @@ $(document).ready(function () {
     }
   }
 
+  ko.bindingHandlers.simpledaterangepicker = {
+    init: function (element, valueAccessor, allBindingsAccessor, viewModel) {
+      var DATE_FORMAT = "YYYY-MM-DD";
+      var TIME_FORMAT = "HH:mm:ss";
+      var DATETIME_FORMAT = DATE_FORMAT + " " + TIME_FORMAT;
+
+      var _el = $(element);
+      var _options = $.extend(valueAccessor(), {});
+
+      var _intervalOptions = [
+        '<option value="+200MILLISECONDS">200ms</option>',
+        '<option value="+1SECONDS">1s</option>',
+        '<option value="+1MINUTES">1m</option>',
+        '<option value="+5MINUTES">5m</option>',
+        '<option value="+10MINUTES">10m</option>',
+        '<option value="+30MINUTES">30m</option>',
+        '<option value="+1HOURS">1h</option>',
+        '<option value="+3HOURS">3h</option>',
+        '<option value="+12HOURS">12h</option>',
+        '<option value="+1DAYS">1d</option>',
+        '<option value="+7DAYS">7d</option>',
+        '<option value="+1MONTHS">1M</option>',
+        '<option value="+6MONTHS">6M</option>',
+        '<option value="+1YEARS">1y</option>'
+      ];
+
+      function enableOptions() {
+        var _opts = [];
+        var _tmp = $("<div>").html(_intervalOptions.join(""))
+        $.each(arguments, function(cnt, item){
+          if (_tmp.find("option[value='+"+item+"']").length > 0){
+            _opts.push('<option value="+'+item+'">' + _tmp.find("option[value='+"+item+"']").eq(0).text() + '</option>');
+          }
+        });
+        return _opts;
+      }
+
+      function renderOptions(opts) {
+        var _html = "";
+        for (var i=0; i<opts.length; i++){
+          _html += opts[i];
+        }
+        _html += '<option value="">${ _('Custom') }</option>';
+        return _html;
+      }
+
+      var _tmpl = $('<div class="simpledaterangepicker">' +
+                    '<div class="facet-field-cnt">' +
+                      '<div class="facet-field-label facet-field-label-fixed-width">${ _('Start') }</div>' +
+                      '<div class="input-prepend input-group">' +
+                        '<span class="add-on input-group-addon"><i class="fa fa-calendar"></i></span>' +
+                        '<input type="text" class="input-small form-control start-date" />' +
+                      '</div>&nbsp;' +
+                      '<div class="input-prepend input-group">' +
+                        '<span class="add-on input-group-addon"><i class="fa fa-clock-o"></i></span>' +
+                        '<input type="text" class="input-mini form-control start-time" />' +
+                      '</div>' +
+                    '</div>' +
+                    '<div class="facet-field-cnt">' +
+                      '<div class="facet-field-label facet-field-label-fixed-width">${ _('End') }</div>' +
+                      '<div class="input-prepend input-group">' +
+                        '<span class="add-on input-group-addon"><i class="fa fa-calendar"></i></span>' +
+                        '<input type="text" class="input-small form-control end-date" />' +
+                      '</div>&nbsp;' +
+                      '<div class="input-prepend input-group">' +
+                        '<span class="add-on input-group-addon"><i class="fa fa-clock-o"></i></span>' +
+                        '<input type="text" class="input-mini form-control end-time" />' +
+                      '</div>' +
+                    '</div>' +
+                    '<div class="facet-field-cnt">' +
+                      '<div class="facet-field-label facet-field-label-fixed-width">${ _('Interval') }</div>' +
+                      '<select class="input-small interval-select" style="margin-right: 6px">' +
+                          renderOptions(_intervalOptions) +
+                      '</select>' +
+                      '<input class="input interval hide" type="text" value="" />' +
+                    '</div>' +
+                  '</div>'
+      );
+
+      _tmpl.insertAfter(_el);
+
+      _tmpl.find(".start-date").val(moment(_options.min()).format(DATE_FORMAT));
+      _tmpl.find(".start-date").datepicker({
+				format: DATE_FORMAT.toLowerCase()
+			}).on("changeDate", function () {
+        rangeHandler(true);
+      });
+
+      _tmpl.find(".start-time").val(moment(_options.min()).format(TIME_FORMAT));
+      _tmpl.find(".start-time").timepicker({
+          minuteStep: 1,
+          showSeconds: true,
+          showMeridian: false,
+          defaultTime: false
+      });
+
+      _tmpl.find(".end-date").val(moment(_options.max()).format(DATE_FORMAT));
+      _tmpl.find(".end-date").datepicker({
+				format: DATE_FORMAT.toLowerCase()
+			}).on("changeDate", function () {
+        rangeHandler(false);
+      });
+
+      _tmpl.find(".end-time").val(moment(_options.max()).format(TIME_FORMAT));
+      _tmpl.find(".end-time").timepicker({
+          minuteStep: 1,
+          showSeconds: true,
+          showMeridian: false,
+          defaultTime: false
+      });
+
+      _tmpl.find(".start-time").on("change", function () {
+        // the timepicker plugin doesn't have a change event handler
+        // so we need to wait a bit to handle in with the default field event
+        window.setTimeout(function () {
+          rangeHandler(true)
+        }, 200);
+      });
+
+      _tmpl.find(".end-time").on("change", function () {
+        window.setTimeout(function () {
+          rangeHandler(false)
+        }, 200);
+      });
+
+      rangeHandler(true);
+
+      function matchIntervals(){
+        if (_tmpl.find(".interval-select option[value='"+_options.gap()+"']").length > 0){
+          _tmpl.find(".interval-select").val(_options.gap());
+          _tmpl.find(".interval").hide();
+        }
+        else {
+          _tmpl.find(".interval-select").val("");
+          _tmpl.find(".interval").show();
+        }
+      }
+
+      _tmpl.find(".interval").val(_options.gap());
+
+      _tmpl.find(".interval-select").on("change", function () {
+        if (_tmpl.find(".interval-select").val() == ""){
+          _tmpl.find(".interval").show();
+        }
+        else {
+          _tmpl.find(".interval").hide();
+          _options.gap(_tmpl.find(".interval-select").val());
+          _tmpl.find(".interval").val(_options.gap());
+        }
+      });
+
+      _tmpl.find(".interval").on("change", function () {
+        if (_tmpl.find(".interval-select").val() == ""){
+          _options.gap(_tmpl.find(".interval").val());
+        }
+      });
+
+      function rangeHandler(isStart) {
+        var startDate = moment(_tmpl.find(".start-date").val() + " " + _tmpl.find(".start-time").val(), DATETIME_FORMAT);
+        var endDate = moment(_tmpl.find(".end-date").val() + " " + _tmpl.find(".end-time").val(), DATETIME_FORMAT);
+        if (startDate.valueOf() > endDate.valueOf()) {
+          if (isStart) {
+            _tmpl.find(".end-date").val(startDate.format(DATE_FORMAT));
+            _tmpl.find(".end-date").datepicker('setValue', startDate.format(DATE_FORMAT));
+            _tmpl.find(".end-date").data("original-val", _tmpl.find(".end-date").val());
+            _tmpl.find(".end-time").val(startDate.format(TIME_FORMAT));
+          }
+          else {
+            if (_tmpl.find(".end-date").val() == _tmpl.find(".start-date").val()) {
+              _tmpl.find(".end-time").val(startDate.format(TIME_FORMAT));
+              _tmpl.find(".end-time").data("timepicker").setValues(startDate.format(TIME_FORMAT));
+            }
+            else {
+              _tmpl.find(".end-date").val(_tmpl.find(".end-date").data("original-val"));
+              _tmpl.find(".end-date").datepicker("setValue", _tmpl.find(".end-date").data("original-val"));
+            }
+            // non-sticky error notification
+            $.jHueNotify.notify({
+              level:"ERROR",
+              message:"${ _("The end cannot be before the starting moment") }"
+            });
+          }
+        }
+        else {
+          _tmpl.find(".end-date").data("original-val", _tmpl.find(".end-date").val());
+          _tmpl.find(".start-date").datepicker("hide");
+          _tmpl.find(".end-date").datepicker("hide");
+        }
+
+        var _calculatedStartDate = moment(_tmpl.find(".start-date").val() + " " + _tmpl.find(".start-time").val(), DATETIME_FORMAT).utc();
+        var _calculatedEndDate = moment(_tmpl.find(".end-date").val() + " " + _tmpl.find(".end-time").val(), DATETIME_FORMAT).utc();
+
+        _options.min(_calculatedStartDate.format("YYYY-MM-DD[T]HH:mm:ss[Z]"));
+        _options.start(_options.min());
+        _options.max(_calculatedEndDate.format("YYYY-MM-DD[T]HH:mm:ss[Z]"));
+        _options.end(_options.max());
+
+        var _opts = [];
+        // hide not useful options from interval
+        if (_calculatedEndDate.diff(_calculatedStartDate, 'minutes') > 1 && _calculatedEndDate.diff(_calculatedStartDate, 'minutes') <= 60){
+          _opts = enableOptions("200MILLISECONDS", "1SECONDS", "1MINUTES", "5MINUTES", "10MINUTES", "30MINUTES");
+        }
+        if (_calculatedEndDate.diff(_calculatedStartDate, 'hours') > 1 && _calculatedEndDate.diff(_calculatedStartDate, 'hours') <= 12){
+          _opts = enableOptions("5MINUTES", "10MINUTES", "30MINUTES", "1HOURS", "3HOURS");
+        }
+        if (_calculatedEndDate.diff(_calculatedStartDate, 'hours') > 12 && _calculatedEndDate.diff(_calculatedStartDate, 'hours') < 36){
+          _opts = enableOptions("10MINUTES", "30MINUTES", "1HOURS", "3HOURS", "12HOURS");
+        }
+        if (_calculatedEndDate.diff(_calculatedStartDate, 'days') > 1 && _calculatedEndDate.diff(_calculatedStartDate, 'days') <= 7){
+          _opts = enableOptions("30MINUTES", "1HOURS", "3HOURS", "12HOURS", "1DAYS");
+        }
+        if (_calculatedEndDate.diff(_calculatedStartDate, 'days') > 7 && _calculatedEndDate.diff(_calculatedStartDate, 'days') <= 14){
+          _opts = enableOptions("3HOURS", "12HOURS", "1DAYS");
+        }
+        if (_calculatedEndDate.diff(_calculatedStartDate, 'days') > 14 && _calculatedEndDate.diff(_calculatedStartDate, 'days') <= 31){
+          _opts = enableOptions("12HOURS", "1DAYS", "7DAYS");
+        }
+        if (_calculatedEndDate.diff(_calculatedStartDate, 'months') > 1){
+          _opts = enableOptions("1DAYS", "7DAYS", "1MONTHS");
+        }
+        if (_calculatedEndDate.diff(_calculatedStartDate, 'months') > 6){
+          _opts = enableOptions("1DAYS", "7DAYS", "1MONTHS", "6MONTHS");
+        }
+        if (_calculatedEndDate.diff(_calculatedStartDate, 'months') > 12){
+          _opts = enableOptions("7DAYS", "1MONTHS", "6MONTHS", "1YEARS");
+        }
+
+        $(".interval-select").html(renderOptions(_opts));
+
+        matchIntervals();
+      }
+    }
+  }
+
+
   ko.bindingHandlers.daterangepicker = {
     init: function (element, valueAccessor, allBindingsAccessor, viewModel) {
       var _el = $(element);
@@ -1576,6 +1816,7 @@ $(document).ready(function () {
   }
 
   viewModel = new SearchViewModel(${ collection.get_c(user) | n,unicode }, _query, ${ initial | n,unicode });
+  viewModel.isEditing(true);
   ko.applyBindings(viewModel);
 
 

+ 30 - 3
apps/search/static/css/search.css

@@ -517,13 +517,15 @@ body.modal-open {
   border-radius: 3px;
 }
 
-.spinedit-pagination div.spinedit .fa-chevron-up {
+.spinedit-cnt div.spinedit .fa-chevron-up {
   top: -7px;
+  color: #666;
 }
 
-.spinedit-pagination div.spinedit .fa-chevron-down {
+.spinedit-cnt div.spinedit .fa-chevron-down {
   top: 7px;
   left: -4px;
+  color: #666;
 }
 
 .clearable {
@@ -555,4 +557,29 @@ body.modal-open {
 
 .field-selector:hover {
   background-color: #DDD;
-}
+}
+
+.facet-field-cnt {
+  margin-bottom: 6px;
+}
+
+.facet-field-label {
+  color: #333;
+  font-size: 11px;
+  margin-bottom: 2px;
+  margin-right: 4px;
+  text-transform: uppercase;
+  text-shadow: 1px 1px 0 #fff;
+}
+
+.facet-field-label-fixed-width {
+  width: 90px;
+  text-align: right;
+  padding-right: 8px;
+  display: inline-block;
+}
+
+.card-widget .input-append, .card-widget .input-prepend, .card-widget select, .card-widget input {
+  margin-bottom: 0;
+}
+