Browse Source

HUE-2783 [search] Load and update search definitions

Restyled the definition demi-modal
Name and definition are updateable
Tracker of changes and reload of the initial definition
Got rid of share modal and button
Enrico Berti 10 năm trước cách đây
mục cha
commit
928e8ad

+ 82 - 11
apps/search/src/search/static/search/js/search.ko.js

@@ -54,6 +54,11 @@ var Query = function (vm, query) {
 
   self.uuid = ko.observable(typeof query.uuid != "undefined" && query.uuid != null ? query.uuid : UUID());
   self.qs = ko.mapping.fromJS(query.qs);
+  self.qs.subscribe(function(){
+    if (vm.selectedQDefinition() != null){
+      vm.selectedQDefinition().hasChanged(true);
+    }
+  });
   self.fqs = ko.mapping.fromJS(query.fqs);
   self.start = ko.mapping.fromJS(query.start);
 
@@ -98,10 +103,16 @@ var Query = function (vm, query) {
 
   self.addQ = function (data) {
     self.qs.push(ko.mapping.fromJS({'q': ''}));
+    if (vm.selectedQDefinition() != null) {
+      vm.selectedQDefinition().hasChanged(true);
+    }
   };
 
   self.removeQ = function (query) {
     self.qs.remove(query);
+    if (vm.selectedQDefinition() != null){
+      vm.selectedQDefinition().hasChanged(true);
+    }
   };
 
   self.selectedMultiq.subscribe(function () { // To keep below the computed objects!
@@ -134,6 +145,10 @@ var Query = function (vm, query) {
       });
     }
 
+    if (vm.selectedQDefinition() != null){
+      vm.selectedQDefinition().hasChanged(true);
+    }
+
     self.start(0);
     vm.search();
   }
@@ -196,6 +211,10 @@ var Query = function (vm, query) {
       }
     }
 
+    if (vm.selectedQDefinition() != null){
+      vm.selectedQDefinition().hasChanged(true);
+    }
+
     self.start(0);
     if (data.no_refresh == undefined) {
       vm.search();
@@ -253,6 +272,10 @@ var Query = function (vm, query) {
       }
     }
 
+    if (vm.selectedQDefinition() != null){
+      vm.selectedQDefinition().hasChanged(true);
+    }
+
     self.start(0);
     if (data.no_refresh == undefined) {
       vm.search();
@@ -535,14 +558,16 @@ var Collection = function (vm, collection) {
   self.newQDefinitionName = ko.observable("");
 
   self.addQDefinition = function () {
-    self.qdefinitions.push(
-        ko.mapping.fromJS({
-          'name': self.newQDefinitionName(),
-          'id': UUID(),
-          'data': ko.mapping.toJSON(vm.query)
-        })
-    );
-    self.newQDefinitionName("");
+    if ($.trim(self.newQDefinitionName()) != "") {
+      var _def = ko.mapping.fromJS({
+        'name': $.trim(self.newQDefinitionName()),
+        'id': UUID(),
+        'data': ko.mapping.toJSON(vm.query)
+      });
+      self.qdefinitions.push(_def);
+      self.loadQDefinition(_def);
+      self.newQDefinitionName("");
+    }
   };
 
   self.removeQDefinition = function (qdef) {
@@ -556,15 +581,53 @@ var Collection = function (vm, collection) {
 
   self.loadQDefinition = function (qdefinition) {
     var qdef = ko.mapping.fromJSON(qdefinition.data());
-
     vm.query.uuid(qdef.uuid());
     vm.query.qs(qdef.qs());
     vm.query.fqs(qdef.fqs());
     vm.query.start(qdef.start());
     vm.query.selectedMultiq(qdef.selectedMultiq());
 
-    vm.additionalInfo("<div class='center'><strong>" + qdefinition.name() + "</strong></div>");
+    qdefinition.hasChanged = ko.observable(false);
+    vm.selectedQDefinition(qdefinition);
     vm.search();
+    $(document).trigger("loadedQDefinition");
+  }
+
+  self.reloadQDefinition = function () {
+    self.loadQDefinition(vm.selectedQDefinition());
+    vm.selectedQDefinition().hasChanged(false);
+  }
+
+  self.updateQDefinition = function () {
+    for (var i = 0; i < self.qdefinitions().length; i++) {
+      if (self.qdefinitions()[i].id() == vm.selectedQDefinition().id()) {
+        self.qdefinitions()[i].data(ko.mapping.toJSON(vm.query));
+        break;
+      }
+    }
+    vm.selectedQDefinition().hasChanged(false);
+  }
+
+  self.unloadQDefinition = function () {
+    vm.selectedQDefinition(null);
+    vm.query.uuid(null);
+    vm.query.qs([
+      {
+        q: ""
+      }
+    ]);
+    vm.query.fqs([]);
+    vm.query.start(0);
+    vm.query.selectedMultiq([]);
+  }
+
+  self.getQDefinition = function (qDefID) {
+    for (var i = 0; i < self.qdefinitions().length; i++) {
+      if (self.qdefinitions()[i].id() == qDefID) {
+        return self.qdefinitions()[i];
+      }
+    }
+    return null;
   }
  
   self.addFacet = function (facet_json) {
@@ -1050,7 +1113,7 @@ var SearchViewModel = function (collection_json, query_json, initial_json) {
   self.initial = new NewTemplate(self, initial_json);
 
   // UI
-  self.additionalInfo = ko.observable("");
+  self.selectedQDefinition = ko.observable();
   self.response = ko.observable({});
   self.results = ko.observableArray([]);
   self.resultsHash = '';
@@ -1189,6 +1252,14 @@ var SearchViewModel = function (collection_json, query_json, initial_json) {
     logGA('search');
     self.isRetrievingResults(true);
 
+    if (self.selectedQDefinition() != null) {
+      var _prop = ko.mapping.fromJSON(self.selectedQDefinition().data());
+      if (ko.toJSON(_prop.qs()) != ko.mapping.toJSON(self.query.qs())
+          || ko.toJSON(_prop.selectedMultiq()) != ko.mapping.toJSON(self.query.selectedMultiq())) {
+        self.selectedQDefinition().hasChanged(true);
+      }
+    }
+
     // Multi queries
     var multiQs = [];
     var multiQ = self.query.getMultiq();

+ 31 - 60
apps/search/src/search/templates/search.mako

@@ -54,11 +54,6 @@ ${ commonheader(_('Search'), "search", user, "80px") | n,unicode }
         data-bind="css: {'btn': true}, visible: columns().length != 0">
       <i class="fa fa-bookmark-o"></i>
     </a>
-    <span data-bind="visible: columns().length != 0">&nbsp;&nbsp;</span>
-
-    <a class="btn pointer" title="${ _('Share search definition') }" rel="tooltip" data-placement="bottom" data-bind="click: showShareModal, css: {'btn': true}, visible: columns().length != 0, enable: $root.collection.id() != null">
-      <i class="fa fa-link"></i>
-    </a>
 
     <span data-bind="visible: columns().length != 0">&nbsp;&nbsp;&nbsp;</span>
 
@@ -1531,21 +1526,6 @@ ${ dashboard.layout_skeleton() }
   </table>
 </script>
 
-<div id="shareModal" class="modal hide" data-backdrop="true">
-  <div class="modal-header">
-    <a href="javascript: void(0)" data-dismiss="modal" class="pull-right"><i class="fa fa-times"></i></a>
-    <h3>${_('Share this dashboard definition')}</h3>
-  </div>
-  <div class="modal-body">
-    <p>${_('The following URL will show the current dashboard and its applied filters.')}</p>
-    <input type="text" style="width: 540px" />
-  </div>
-  <div class="modal-footer">
-    <a href="#" class="btn" data-dismiss="modal">${_('Close')}</a>
-  </div>
-</div>
-
-
 <div id="addFacetDemiModal" class="demi-modal fade" data-backdrop="false">
   <div class="modal-body">
     <a href="javascript: void(0)" data-dismiss="modal" data-bind="click: addFacetDemiModalFieldCancel" class="pull-right"><i class="fa fa-times"></i></a>
@@ -1604,32 +1584,32 @@ ${ dashboard.layout_skeleton() }
   <div class="modal-body">
     <div class="row-fluid">
       <div class="span12">
-        <form class="form-horizontal">
+        <form class="form-inline">
           <fieldset>
-            <legend><i class="fa fa-bookmark-o"></i> ${ _('Query definitions') }</legend>
-            <div class="control-group">
-              <label class="control-label" for="newqname">${ _('New defition') }</label>
-              <div class="controls">
-                <div class="input-append">
-                  <input id="newqname" type="text" class="input-xlarge" data-bind="value: $root.collection.newQDefinitionName" style="margin-bottom: 0" placeholder="${ _('Name') }" />
-                  <a title="${ _('Click on this button to add the currenty query as a new definition') }" class="btn plus-btn" data-bind="click: $root.collection.addQDefinition">
-                    <i class="fa fa-plus"></i>
-                  </a>
-                </div>
+            <legend><i class="fa fa-bookmark-o"></i> ${ _('Query definitions') }
+              <div class="input-append" style="margin-left: 30px; margin-top: 4px">
+                <input id="newqname" type="text" class="input-xxlarge" data-bind="value: $root.collection.newQDefinitionName, valueUpdate:'afterkeydown'" style="margin-bottom: 0" placeholder="${ _('Add current query as...') }" />
+                <a title="${ _('Click on this button to add the currenty query as a new definition') }" class="btn plus-btn" data-bind="click: $root.collection.addQDefinition, css:{'disabled': $.trim($root.collection.newQDefinitionName()) == ''}" style="margin-top: 1px">
+                  <i class="fa fa-plus"></i>
+                </a>
               </div>
-            </div>
-            <div class="control-group" data-bind="visible: $root.collection.qdefinitions().length > 0">
-              <label class="control-label" for="settingsdescription">${ _('Saved definitions') }</label>
+            </legend>
+            <div class="control-group" data-bind="visible: $root.collection.qdefinitions().length > 0" style="margin-top: 0">
               <div class="controls">
                 <ul class="unstyled airy qdefinitions" data-bind="foreach: $root.collection.qdefinitions">
                   <li>
                     <span class="badge badge-info badge-left pointer">
-                      <i class="fa fa-bookmark"></i> <span data-bind="text: name, attr:{'title': ko.mapping.toJSON(data, null, 2)}, click: $root.collection.loadQDefinition"></span>
+                      <span data-bind="text: name, attr:{'title': ko.mapping.toJSON(data, null, 2)}, click: $root.collection.loadQDefinition"></span>
                     </span><span class="badge badge-right trash-share" data-bind="click: $root.collection.removeQDefinition"> <i class="fa fa-times"></i></span></li>
                   </li>
                 </ul>
               </div>
             </div>
+            <div class="control-group" data-bind="visible: $root.collection.qdefinitions().length == 0">
+              <div class="controls">
+                <h4>${ _('There are currently no query definitions.') }</h4>
+              </div>
+            </div>
           </fieldset>
 
         </form>
@@ -2356,37 +2336,28 @@ $(document).ready(function () {
       $(".demi-modal.fade.in .demi-modal-chevron").click();
     }
   });
-});
 
-  function showShareModal() {
-    if (window.location.search.indexOf("collection") == -1 && window.location.hash.indexOf("collection") == -1) {
-      $(document).trigger("error", "${_('The current collection must be saved to be shared.')}");
+  $("#newqname").bind("keydown", "return", function (e) {
+    e.preventDefault();
+    viewModel.collection.addQDefinition();
+  });
+
+  $(document).on("loadedQDefinition", function() {
+    if ($(".demi-modal.fade.in").length > 0) {
+      $(".demi-modal.fade.in .demi-modal-chevron").click();
     }
-    else {
-      $("#shareModal input[type='text']").on("focus", function () {
-        this.select();
-      });
-      if (!window.location.origin) {
-        window.location.origin = window.location.protocol + "//" + window.location.hostname + (window.location.port ? ":" + window.location.port: "");
-      }
-      var _search = window.location.search;
-      var _pathname = window.location.pathname;
-      if (_pathname.indexOf("${ url('search:new_search') }") > -1) {
-        _pathname = "${ url('search:index') }";
-      }
-      if (_search == "" && window.location.hash.indexOf("collection") > -1) {
-        _search = "?" + window.location.hash.substr(1);
-      }
+  });
 
-      if (_search != "") {
-        $("#shareModal input[type='text']").val(window.location.origin + _pathname + _search + "#" + LZString.compressToBase64(ko.mapping.toJSON(viewModel.query))).focus();
-        $("#shareModal").modal("show");
-      }
-      else {
-        $(document).trigger("error", "${_('The current collection cannot be shared.')}");
+  if (window.location.hash != "") {
+    if (window.location.hash.indexOf("q=") > -1) {
+      var _qdef = viewModel.collection.getQDefinition(window.location.hash.substr(1).replace(/(<([^>]+)>)/ig, "").split("=")[1]);
+      if (_qdef != null){
+        viewModel.collection.loadQDefinition(_qdef);
       }
     }
   }
+});
+
 
   function toggleGridFieldsSelection() {
     if (viewModel.collection.template.fields().length > 0) {

+ 1 - 0
desktop/core/src/desktop/static/desktop/css/common_dashboard.css

@@ -440,4 +440,5 @@ body.modal-open {
 .card-additional {
   padding: 10px;
   margin-bottom: 10px;
+  text-align: center;
 }

+ 9 - 2
desktop/core/src/desktop/templates/common_dashboard.mako

@@ -121,9 +121,16 @@
 
 <div data-bind="css: {'dashboard': true, 'with-top-margin': isEditing()}">
   <div class="container-fluid">
-    <!-- ko if: $root.additionalInfo && $root.additionalInfo() != "" -->
+    <!-- ko if: $root.selectedQDefinition() != null -->
     <div class="row-fluid">
-      <div class="card card-additional card-home span12" data-bind="html: $root.additionalInfo"></div>
+      <div class="card card-additional card-home span12">
+        <a class="pointer pull-right" data-bind="click: $root.collection.unloadQDefinition"><i class="fa fa-times"></i></a>
+        <strong data-bind="editable: $root.selectedQDefinition().name, editableOptions: {enabled: true, placement: 'right'}"></strong>
+        <!-- ko if: $root.selectedQDefinition().hasChanged() -->
+        &nbsp;&nbsp;
+        <a class="pointer" data-bind="click: $root.collection.reloadQDefinition" title="${ _('Reload this definition') }"><i class="fa fa-undo"></i></a> <a class="pointer" data-bind="click: $root.collection.updateQDefinition" title="${ _('Update the definition') }"><i class="fa fa-save"></i></a>
+        <!-- /ko -->
+      </div>
     </div>
     <!-- /ko -->
     <div class="row-fluid" data-bind="template: { name: 'column-template', foreach: columns}">