Browse Source

HUE-2210 [search] Improve reliability of the timeline start/date fields

All the changes are sync'd between custom and pickers
Added 6hours interval
Changed non-edit mode interval to dropdown
Group by hidden if just with one value
Removed Custom from the picker interval
Updated timeline chart formatting to 24H format
Enrico Berti 11 years ago
parent
commit
c8b0ce8

+ 2 - 0
apps/search/src/search/api.py

@@ -113,6 +113,8 @@ def _guess_range_facet(widget_type, solr_api, collection, facet_field, propertie
         gap = '+1HOURS'
         gap = '+1HOURS'
       elif difference < 3600 * 3:
       elif difference < 3600 * 3:
         gap = '+3HOURS'
         gap = '+3HOURS'
+      elif difference < 3600 * 6:
+        gap = '+6HOURS'
       elif difference < 3600 * 12:
       elif difference < 3600 * 12:
         gap = '+12HOURS'
         gap = '+12HOURS'
       elif difference < 3600 * 24:
       elif difference < 3600 * 24:

+ 6 - 3
apps/search/src/search/templates/search.mako

@@ -721,12 +721,15 @@ ${ dashboard.layout_skeleton() }
     <div style="padding-bottom: 10px; text-align: right; padding-right: 20px" data-bind="visible: counts.length > 0">
     <div style="padding-bottom: 10px; text-align: right; padding-right: 20px" data-bind="visible: counts.length > 0">
       <span data-bind="visible: ! $root.isEditing(), with: $root.collection.getFacetById($parent.id())">
       <span data-bind="visible: ! $root.isEditing(), with: $root.collection.getFacetById($parent.id())">
         <span class="facet-field-label">${ _('Interval') }</span>
         <span class="facet-field-label">${ _('Interval') }</span>
-        <input type="text" data-bind="value: properties.gap" />
+         <select class="input-small" data-bind="options: $root.intervalOptions,
+                       optionsText: 'label',
+                       optionsValue: 'value',
+                       value: properties.gap"></select>&nbsp;
       </span>
       </span>
       <span class="facet-field-label">${ _('Zoom') }</span>
       <span class="facet-field-label">${ _('Zoom') }</span>
       <a href="javascript:void(0)" data-bind="click: $root.collection.rangeZoomOut"><i class="fa fa-search-minus"></i> ${ _('reset') }</a>
       <a href="javascript:void(0)" data-bind="click: $root.collection.rangeZoomOut"><i class="fa fa-search-minus"></i> ${ _('reset') }</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>
+      <span class="facet-field-label" data-bind="visible: $root.query.multiqs().length > 1">${ _('Group by') }</span>
+      <select class="input-medium" data-bind="visible: $root.query.multiqs().length > 1, options: $root.query.multiqs, optionsValue: 'id', optionsText: 'label', value: $root.query.selectedMultiq"></select>
     </div>
     </div>
 
 
     <div data-bind="timelineChart: {datum: {counts: counts, extraSeries: (typeof extraSeries != 'undefined' ? extraSeries : []), widget_id: $parent.id(), label: label}, stacked: $root.collection.getFacetById($parent.id()).properties.stacked(), field: field, label: label, transformer: timelineChartDataTransformer,
     <div data-bind="timelineChart: {datum: {counts: counts, extraSeries: (typeof extraSeries != 'undefined' ? extraSeries : []), widget_id: $parent.id(), label: label}, stacked: $root.collection.getFacetById($parent.id()).properties.stacked(), field: field, label: label, transformer: timelineChartDataTransformer,

+ 2 - 0
apps/search/static/js/search.ko.js

@@ -863,6 +863,8 @@ var RANGE_SELECTABLE_WIDGETS = ['histogram-widget', 'bar-widget', 'line-widget']
 var SearchViewModel = function (collection_json, query_json, initial_json) {
 var SearchViewModel = function (collection_json, query_json, initial_json) {
   var self = this;
   var self = this;
 
 
+  self.intervalOptions = ko.observableArray(ko.bindingHandlers.daterangepicker.INTERVAL_OPTIONS);
+
   // Models
   // Models
   self.collection = new Collection(self, collection_json.collection);
   self.collection = new Collection(self, collection_json.collection);
   self.query = new Query(self, query_json);
   self.query = new Query(self, query_json);

+ 1 - 1
desktop/core/static/js/ko.charts.js

@@ -446,7 +446,7 @@ function barChartBuilder(element, options, isTimeline) {
         var _el = d3.select(this);
         var _el = d3.select(this);
         var _mom = moment(d);
         var _mom = moment(d);
         if (_mom != null && _mom.isValid()) {
         if (_mom != null && _mom.isValid()) {
-          var _words = _mom.format("hh:mm:ss YYYY-MM-DD").split(" ");
+          var _words = _mom.format("HH:mm:ss YYYY-MM-DD").split(" ");
           _el.text("");
           _el.text("");
           for (var i = 0; i < _words.length; i++) {
           for (var i = 0; i < _words.length; i++) {
             var tspan = _el.append("tspan").text(_words[i]);
             var tspan = _el.append("tspan").text(_words[i]);

+ 96 - 56
desktop/core/static/js/ko.hue-bindings.js

@@ -195,6 +195,69 @@ ko.bindingHandlers.slider = {
 }
 }
 
 
 ko.bindingHandlers.daterangepicker = {
 ko.bindingHandlers.daterangepicker = {
+  INTERVAL_OPTIONS: [
+    {
+      value: "+200MILLISECONDS",
+      label: "200ms"
+    },
+    {
+      value: "+1SECONDS",
+      label: "1s"
+    },
+    {
+      value: "+1MINUTES",
+      label: "1m"
+    },
+    {
+      value: "+5MINUTES",
+      label: "5m"
+    },
+    {
+      value: "+10MINUTES",
+      label: "10m"
+    },
+    {
+      value: "+30MINUTES",
+      label: "30m"
+    },
+    {
+      value: "+1HOURS",
+      label: "1h"
+    },
+    {
+      value: "+3HOURS",
+      label: "3h"
+    },
+    {
+      value: "+6HOURS",
+      label: "6h"
+    },
+    {
+      value: "+12HOURS",
+      label: "12h"
+    },
+    {
+      value: "+1DAYS",
+      label: "1d"
+    },
+    {
+      value: "+7DAYS",
+      label: "7d"
+    },
+    {
+      value: "+1MONTHS",
+      label: "1M"
+    },
+    {
+      value: "+6MONTHS",
+      label: "6M"
+    },
+    {
+      value: "+1YEARS",
+      label: "1y"
+    }
+  ],
+
   init: function (element, valueAccessor, allBindingsAccessor, viewModel) {
   init: function (element, valueAccessor, allBindingsAccessor, viewModel) {
     var DATE_FORMAT = "YYYY-MM-DD";
     var DATE_FORMAT = "YYYY-MM-DD";
     var TIME_FORMAT = "HH:mm:ss";
     var TIME_FORMAT = "HH:mm:ss";
@@ -203,22 +266,10 @@ ko.bindingHandlers.daterangepicker = {
     var _el = $(element);
     var _el = $(element);
     var _options = $.extend(valueAccessor(), {});
     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>'
-    ];
+    var _intervalOptions = [];
+    ko.bindingHandlers.daterangepicker.INTERVAL_OPTIONS.forEach(function (interval) {
+      _intervalOptions.push('<option value="' + interval.value + '">' + interval.label + '</option>');
+    });
 
 
     function enableOptions() {
     function enableOptions() {
       var _opts = [];
       var _opts = [];
@@ -236,7 +287,6 @@ ko.bindingHandlers.daterangepicker = {
       for (var i = 0; i < opts.length; i++) {
       for (var i = 0; i < opts.length; i++) {
         _html += opts[i];
         _html += opts[i];
       }
       }
-      _html += '<option value="">Custom</option>';
       return _html;
       return _html;
     }
     }
 
 
@@ -265,10 +315,11 @@ ko.bindingHandlers.daterangepicker = {
             '</div>' +
             '</div>' +
             '<div class="facet-field-cnt picker">' +
             '<div class="facet-field-cnt picker">' +
             '<div class="facet-field-label facet-field-label-fixed-width">' + KO_DATERANGEPICKER_LABELS.INTERVAL + '</div>' +
             '<div class="facet-field-label facet-field-label-fixed-width">' + KO_DATERANGEPICKER_LABELS.INTERVAL + '</div>' +
+            '<div class="input-prepend input-group"><span class="add-on input-group-addon"><i class="fa fa-repeat"></i></span></div>&nbsp;' +
             '<select class="input-small interval-select" style="margin-right: 6px">' +
             '<select class="input-small interval-select" style="margin-right: 6px">' +
             renderOptions(_intervalOptions) +
             renderOptions(_intervalOptions) +
             '</select>' +
             '</select>' +
-            '<input class="input interval hide" type="text" value="" />' +
+            '<input class="input interval hide" type="hidden" value="" />' +
             '</div>' +
             '</div>' +
             '<div class="facet-field-cnt picker">' +
             '<div class="facet-field-cnt picker">' +
             '<div class="facet-field-label facet-field-label-fixed-width"></div>' +
             '<div class="facet-field-label facet-field-label-fixed-width"></div>' +
@@ -307,16 +358,14 @@ ko.bindingHandlers.daterangepicker = {
 
 
     var _minMoment = moment(_options.min());
     var _minMoment = moment(_options.min());
     var _maxMoment = moment(_options.max());
     var _maxMoment = moment(_options.max());
-    var _startMoment = moment(_options.start());
-    var _endMoment = moment(_options.end());
 
 
     if (_minMoment.isValid() && _maxMoment.isValid()) {
     if (_minMoment.isValid() && _maxMoment.isValid()) {
       _tmpl.find(".facet-field-cnt.custom").hide();
       _tmpl.find(".facet-field-cnt.custom").hide();
       _tmpl.find(".facet-field-cnt.picker").show();
       _tmpl.find(".facet-field-cnt.picker").show();
-      _tmpl.find(".start-date").val(_minMoment.format(DATE_FORMAT));
-      _tmpl.find(".start-time").val(_minMoment.format(TIME_FORMAT));
-      _tmpl.find(".end-date").val(_maxMoment.format(DATE_FORMAT));
-      _tmpl.find(".end-time").val(_maxMoment.format(TIME_FORMAT));
+      _tmpl.find(".start-date").val(_minMoment.utc().format(DATE_FORMAT));
+      _tmpl.find(".start-time").val(_minMoment.utc().format(TIME_FORMAT));
+      _tmpl.find(".end-date").val(_maxMoment.utc().format(DATE_FORMAT));
+      _tmpl.find(".end-time").val(_maxMoment.utc().format(TIME_FORMAT));
       _tmpl.find(".interval").val(_options.gap());
       _tmpl.find(".interval").val(_options.gap());
       _tmpl.find(".interval-custom").val(_options.gap());
       _tmpl.find(".interval-custom").val(_options.gap());
     }
     }
@@ -392,45 +441,36 @@ ko.bindingHandlers.daterangepicker = {
 
 
     _tmpl.find(".start-date-custom").on("change", function () {
     _tmpl.find(".start-date-custom").on("change", function () {
       _options.min(_tmpl.find(".start-date-custom").val());
       _options.min(_tmpl.find(".start-date-custom").val());
+      _tmpl.find(".start-date").val(moment(_options.min()).utc().format(DATE_FORMAT));
+      _tmpl.find(".start-time").val(moment(_options.min()).utc().format(TIME_FORMAT));
       _options.start(_options.min());
       _options.start(_options.min());
     });
     });
 
 
     _tmpl.find(".end-date-custom").on("change", function () {
     _tmpl.find(".end-date-custom").on("change", function () {
       _options.max(_tmpl.find(".end-date-custom").val());
       _options.max(_tmpl.find(".end-date-custom").val());
+      _tmpl.find(".end-date").val(moment(_options.max()).utc().format(DATE_FORMAT));
+      _tmpl.find(".end-time").val(moment(_options.max()).utc().format(TIME_FORMAT));
       _options.end(_options.max());
       _options.end(_options.max());
     });
     });
 
 
     _tmpl.find(".interval-custom").on("change", function () {
     _tmpl.find(".interval-custom").on("change", function () {
       _options.gap(_tmpl.find(".interval-custom").val());
       _options.gap(_tmpl.find(".interval-custom").val());
+      matchIntervals();
     });
     });
 
 
     function matchIntervals() {
     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-select").val(_options.gap());
+      if (_tmpl.find(".interval-select").val() == null){
+        _tmpl.find(".interval-select").val(_tmpl.find(".interval-select option:first").val());
+        _options.gap(_tmpl.find(".interval-select").val());
+        _tmpl.find(".interval-custom").val(_options.gap());
       }
       }
     }
     }
 
 
     _tmpl.find(".interval-select").on("change", function () {
     _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());
-        _tmpl.find(".interval-custom").val(_options.gap());
-      }
+      _options.gap(_tmpl.find(".interval-select").val());
+      _tmpl.find(".interval").val(_options.gap());
+      _tmpl.find(".interval-custom").val(_options.gap());
     });
     });
 
 
     function rangeHandler(isStart) {
     function rangeHandler(isStart) {
@@ -438,14 +478,14 @@ ko.bindingHandlers.daterangepicker = {
       var endDate = moment(_tmpl.find(".end-date").val() + " " + _tmpl.find(".end-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 (startDate.valueOf() > endDate.valueOf()) {
         if (isStart) {
         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").val(startDate.utc().format(DATE_FORMAT));
+          _tmpl.find(".end-date").datepicker('setValue', startDate.utc().format(DATE_FORMAT));
           _tmpl.find(".end-date").data("original-val", _tmpl.find(".end-date").val());
           _tmpl.find(".end-date").data("original-val", _tmpl.find(".end-date").val());
-          _tmpl.find(".end-time").val(startDate.format(TIME_FORMAT));
+          _tmpl.find(".end-time").val(startDate.utc().format(TIME_FORMAT));
         }
         }
         else {
         else {
           if (_tmpl.find(".end-date").val() == _tmpl.find(".start-date").val()) {
           if (_tmpl.find(".end-date").val() == _tmpl.find(".start-date").val()) {
-            _tmpl.find(".end-time").val(startDate.format(TIME_FORMAT));
+            _tmpl.find(".end-time").val(startDate.utc().format(TIME_FORMAT));
             _tmpl.find(".end-time").data("timepicker").setValues(startDate.format(TIME_FORMAT));
             _tmpl.find(".end-time").data("timepicker").setValues(startDate.format(TIME_FORMAT));
           }
           }
           else {
           else {
@@ -465,8 +505,8 @@ ko.bindingHandlers.daterangepicker = {
         _tmpl.find(".end-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();
+      var _calculatedStartDate = moment(_tmpl.find(".start-date").val() + " " + _tmpl.find(".start-time").val(), DATETIME_FORMAT);
+      var _calculatedEndDate = moment(_tmpl.find(".end-date").val() + " " + _tmpl.find(".end-time").val(), DATETIME_FORMAT);
 
 
       _options.min(_calculatedStartDate.format("YYYY-MM-DD[T]HH:mm:ss[Z]"));
       _options.min(_calculatedStartDate.format("YYYY-MM-DD[T]HH:mm:ss[Z]"));
       _options.start(_options.min());
       _options.start(_options.min());
@@ -485,18 +525,18 @@ ko.bindingHandlers.daterangepicker = {
         _opts = enableOptions("5MINUTES", "10MINUTES", "30MINUTES", "1HOURS", "3HOURS");
         _opts = enableOptions("5MINUTES", "10MINUTES", "30MINUTES", "1HOURS", "3HOURS");
       }
       }
       if (_calculatedEndDate.diff(_calculatedStartDate, 'hours') > 12 && _calculatedEndDate.diff(_calculatedStartDate, 'hours') < 36) {
       if (_calculatedEndDate.diff(_calculatedStartDate, 'hours') > 12 && _calculatedEndDate.diff(_calculatedStartDate, 'hours') < 36) {
-        _opts = enableOptions("10MINUTES", "30MINUTES", "1HOURS", "3HOURS", "12HOURS");
+        _opts = enableOptions("10MINUTES", "30MINUTES", "1HOURS", "3HOURS", "6HOURS", "12HOURS");
       }
       }
       if (_calculatedEndDate.diff(_calculatedStartDate, 'days') > 1 && _calculatedEndDate.diff(_calculatedStartDate, 'days') <= 7) {
       if (_calculatedEndDate.diff(_calculatedStartDate, 'days') > 1 && _calculatedEndDate.diff(_calculatedStartDate, 'days') <= 7) {
-        _opts = enableOptions("30MINUTES", "1HOURS", "3HOURS", "12HOURS", "1DAYS");
+        _opts = enableOptions("30MINUTES", "1HOURS", "3HOURS", "6HOURS", "12HOURS", "1DAYS");
       }
       }
       if (_calculatedEndDate.diff(_calculatedStartDate, 'days') > 7 && _calculatedEndDate.diff(_calculatedStartDate, 'days') <= 14) {
       if (_calculatedEndDate.diff(_calculatedStartDate, 'days') > 7 && _calculatedEndDate.diff(_calculatedStartDate, 'days') <= 14) {
-        _opts = enableOptions("3HOURS", "12HOURS", "1DAYS");
+        _opts = enableOptions("3HOURS", "6HOURS", "12HOURS", "1DAYS");
       }
       }
       if (_calculatedEndDate.diff(_calculatedStartDate, 'days') > 14 && _calculatedEndDate.diff(_calculatedStartDate, 'days') <= 31) {
       if (_calculatedEndDate.diff(_calculatedStartDate, 'days') > 14 && _calculatedEndDate.diff(_calculatedStartDate, 'days') <= 31) {
         _opts = enableOptions("12HOURS", "1DAYS", "7DAYS");
         _opts = enableOptions("12HOURS", "1DAYS", "7DAYS");
       }
       }
-      if (_calculatedEndDate.diff(_calculatedStartDate, 'months') > 1) {
+      if (_calculatedEndDate.diff(_calculatedStartDate, 'months') >= 1) {
         _opts = enableOptions("1DAYS", "7DAYS", "1MONTHS");
         _opts = enableOptions("1DAYS", "7DAYS", "1MONTHS");
       }
       }
       if (_calculatedEndDate.diff(_calculatedStartDate, 'months') > 6) {
       if (_calculatedEndDate.diff(_calculatedStartDate, 'months') > 6) {