Browse Source

HUE-2186 [search] Bulk copy collection templates

Romain Rigaux 11 years ago
parent
commit
ff06225ec5

+ 21 - 70
apps/search/src/search/search_controller.py

@@ -41,95 +41,46 @@ class SearchController(object):
     return Collection.objects.filter(enabled=True)
 
   def delete_collections(self, collection_ids):
-    if isinstance(collection_ids, basestring):
-      collection_ids = collection_ids.split();
-
-    for x in collection_ids:
-      id = x.id
-      try:
-        Collection.objects.get(id=x.id).delete()
-      except Exception, e:
-        LOG.warn('Error deleting collection: %s' % e)
-        id = -1
-
-      return id
-
-  def delete_collection(self, collection_id):
-    id = collection_id
+    result = {'status': -1, 'message': ''}
     try:
-      Collection.objects.get(id=collection_id).delete()
+      Collection.objects.filter(id__in=collection_ids).delete()
+      result['status'] = 0
     except Exception, e:
       LOG.warn('Error deleting collection: %s' % e)
-      id = -1
+      result['message'] = unicode(str(e), "utf8")
 
-    return id
+    return result
 
   def copy_collections(self, collection_ids):
-    if isinstance(collection_ids, basestring):
-      collection_ids = collection_ids.split();
-      
-    for x in collection_ids:
-      id = -1
-
-      try:
-        copy = Collection.objects.get(id=x)
+    result = {'status': -1, 'message': ''}
+    try:
+      for collection in Collection.objects.filter(id__in=collection_ids): 
+        copy = collection
         copy.label += _(' (Copy)')
         copy.id = copy.pk = None
-        copy.save()
-
+  
         facets = copy.facets
         facets.id = None
         facets.save()
         copy.facets = facets
-
-        result = copy.result
-        result.id = None
-        result.save()
-        copy.result = result
-
+  
+        result_ = copy.result
+        result_.id = None
+        result_.save()
+        copy.result = result_
+  
         sorting = copy.sorting
         sorting.id = None
         sorting.save()
         copy.sorting = sorting
-
+  
         copy.save()
-
-        id = copy.id
-      except Exception, e:
-        LOG.warn('Error copying collection: %s' % e)
-
-      return id
-
-  def copy_collection(self, collection_id):
-    id = -1
-
-    try:
-      copy = Collection.objects.get(id=collection_id)
-      copy.label += _(' (Copy)')
-      copy.id = copy.pk = None
-      copy.save()
-
-      facets = copy.facets
-      facets.id = None
-      facets.save()
-      copy.facets = facets
-
-      result = copy.result
-      result.id = None
-      result.save()
-      copy.result = result
-
-
-      sorting = copy.sorting
-      sorting.id = None
-      sorting.save()
-      copy.sorting = sorting
-
-      copy.save()
-
-      id = copy.id
+      result['status'] = 0
     except Exception, e:
       LOG.warn('Error copying collection: %s' % e)
+      result['message'] = unicode(str(e), "utf8")
+      
+    return result
 
   def is_collection(self, collection_name):
     solr_collections = SolrApi(SOLR_URL.get(), self.user).collections()

+ 7 - 29
apps/search/src/search/templates/admin_collections.mako

@@ -97,9 +97,6 @@ ${ commonheader(_('Search'), "search", user, "29px") | n,unicode }
   </div>
 </div>
 
-<!-- PAUL - REMOVE before committing -->
-<pre data-bind="text: ko.toJSON($root, null, 2)"></pre>
-
 <script id="importableTemplate" type="text/html">
   <tr>
     <td width="24">
@@ -115,33 +112,20 @@ ${ commonheader(_('Search'), "search", user, "29px") | n,unicode }
     <h3>${_('Confirm Delete')}</h3>
   </div>
   <div class="modal-body">
-    <p>${_('Are you sure you want to delete this collection?')}</p>
+    <p>${_('Are you sure you want to delete the selected collections?')}</p>
   </div>
   <div class="modal-footer">
-    <a class="btn" data-dismiss="modal">${_('No')}</a>
-    <a id="deleteModalBtn" class="btn btn-danger disable-feedback" data-bind="click: deleteCollection">${_('Yes')}</a>
-  </div>
-</div>
-
-<div id="deleteManyModal" class="modal hide fade">
-  <div class="modal-header">
-    <a href="#" class="close" data-dismiss="modal">&times;</a>
-    <h3>${_('Confirm Delete')}</h3>
-  </div>
-  <div class="modal-body">
-    <p>${_('Are you sure you want to delete this collection?')}</p>
-  </div>
-  <div class="modal-footer">
-    <a class="btn" data-dismiss="modal">${_('No')}</a>
-    <a id="deleteModalBtn" class="btn btn-danger disable-feedback" data-bind="click: deleteCollections">${_('Yes')}</a>
+    <a class="btn" data-dismiss="modal">${ _('No') }</a>
+    <a id="deleteModalBtn" class="btn btn-danger disable-feedback" data-bind="click: deleteCollections">${ _('Yes') }</a>
   </div>
 </div>
 
 <script src="/static/ext/js/knockout-min.js" type="text/javascript" charset="utf-8"></script>
+<script src="/static/ext/js/knockout.mapping-2.3.2.js" type="text/javascript" charset="utf-8"></script>
+
 <script src="/search/static/js/collections.ko.js" type="text/javascript" charset="utf-8"></script>
 
 <script>
-//(function () {
   var appProperties = {
     labels: [],
     listCollectionsUrl: "${ url("search:admin_collections") }?format=json",
@@ -172,7 +156,7 @@ ${ commonheader(_('Search'), "search", user, "29px") | n,unicode }
       }, 300);
     });
 
-    $("#deleteModal, #deleteManyModal").modal({
+    $("#deleteModal").modal({
       show: false
     });
 
@@ -183,7 +167,7 @@ ${ commonheader(_('Search'), "search", user, "29px") | n,unicode }
     });
 
     $(document).on("collectionDeleted", function () {
-      $("#deleteModal, #deleteManyModal").modal("hide");
+      $("#deleteModal").modal("hide");
       $("#deleteModalBtn").button("reset");
       $(document).trigger("info", "${ _("Collection deleted successfully.") }");
     });
@@ -195,13 +179,7 @@ ${ commonheader(_('Search'), "search", user, "29px") | n,unicode }
     $(document).on("confirmDelete", function () {
       $("#deleteModal").modal('show');
     });
-
-    $(document).on("confirmDeleteMany", function () {
-      $("#deleteManyModal").modal('show');
-    });
-
   });
-//}());
 </script>
 
 ${ commonfooter(messages) | n,unicode }

+ 4 - 4
apps/search/src/search/views.py

@@ -230,10 +230,10 @@ def admin_collection_delete(request):
   if request.method != 'POST':
     raise PopupException(_('POST request required.'))
 
-  id = request.POST.get('id')
+  collections = json.loads(request.POST.get('collections'))
   searcher = SearchController(request.user)
   response = {
-    'id': searcher.delete_collection(id)
+    'result': searcher.delete_collections([collection['id'] for collection in collections])
   }
 
   return HttpResponse(json.dumps(response), mimetype="application/json")
@@ -244,10 +244,10 @@ def admin_collection_copy(request):
   if request.method != 'POST':
     raise PopupException(_('POST request required.'))
 
-  id = request.POST.get('id')
+  collections = json.loads(request.POST.get('collections'))
   searcher = SearchController(request.user)
   response = {
-    'id': searcher.copy_collection(id)
+    'result': searcher.copy_collections([collection['id'] for collection in collections])
   }
 
   return HttpResponse(json.dumps(response), mimetype="application/json")

+ 18 - 50
apps/search/static/js/collections.ko.js

@@ -20,7 +20,7 @@ var Importable = function (importable) {
   self.name = ko.observable(importable.name);
   self.selected = ko.observable(false);
   self.handleSelect = function (row, e) {
-    self.selected(!self.selected());
+    self.selected(! self.selected());
   };
 };
 
@@ -36,10 +36,10 @@ var Collection = function (coll) {
   self.hovered = ko.observable(false);
 
   self.handleSelect = function (row, e) {
-    self.selected(!self.selected());
+    self.selected(! self.selected());
   };
   self.toggleHover = function (row, e) {
-    self.hovered(!self.hovered());
+    self.hovered(! self.hovered());
   };
 }
 
@@ -64,7 +64,7 @@ var SearchCollectionsModel = function (props) {
   self.importableCollections = ko.observableArray([]);
   self.importableCores = ko.observableArray([]);
 
-  self.collectionToDelete = null;
+  self.collectionToDelete = null; // --> replace by self.selectedCollections()
 
   self.selectedCollections = ko.computed(function () {
     return ko.utils.arrayFilter(self.collections(), function (coll) {
@@ -105,64 +105,32 @@ var SearchCollectionsModel = function (props) {
     location.href = collection.absoluteUrl();
   };
 
-  self.markForDeletion = function (collection) {
-    self.collectionToDelete = collection;
-    $(document).trigger("confirmDelete");
-  };
-
   self.markManyForDeletion = function (collections) {
     self.collectionToDelete = collections;
-    $(document).trigger("confirmDeleteMany")
-  };
-
-  self.deleteCollection = function () {
-    $(document).trigger("deleting");
-    $.post(self.DELETE_URL,
-      {
-        id: self.collectionToDelete.id()
-      },
-      function (data) {
-        self.updateCollections();
-        $(document).trigger("collectionDeleted");
-      }, "json");
+    $(document).trigger("confirmDelete")
   };
 
   self.deleteCollections = function () {
     self.isLoading = true;
     $(document).trigger("deleting");
-    $.post(self.DELETE_URL,
-    {
-      id: self.selectedCollections()
-    },
-    function (data) {
-      self.updateCollections();
-    }, "json");
-    $(document).trigger("collectionDeleted");
-  };
-
-  self.copyCollection = function (collection) {
-    $(document).trigger("copying");
-    $.post(self.COPY_URL,
-      {
-        id: collection.id(),
-        type: collection.isCoreOnly()?"core":"collection"
+    $.post(self.DELETE_URL, {
+        collections: ko.mapping.toJSON(self.selectedCollections())
       },
       function (data) {
         self.updateCollections();
-        $(document).trigger("collectionCopied");
-      }, "json");
+      }, "json"
+    ).fail(function (xhr, textStatus, errorThrown) {});
+    $(document).trigger("collectionDeleted");
   };
 
   self.copyCollections = function (collections) {
     $(document).trigger("copying");
-    $.post(self.COPY_URL,
-    {
-      id: self.selectedCollections(),
-      //type: coll.isCoreOnly() ? "core" : "collection"
-    },
-    function (data) {
-      self.updateCollections();
-    }, "json");
+    $.post(self.COPY_URL, {
+    	collections: ko.mapping.toJSON(self.selectedCollections())
+      }, function (data) {
+        self.updateCollections();
+      }, "json"
+    ).fail(function (xhr, textStatus, errorThrown) {});
     $(document).trigger("collectionCopied");
   };
 
@@ -217,7 +185,7 @@ var SearchCollectionsModel = function (props) {
   };
 
   self.toggleSelectAll = function() { // duplicated from hue/desktop/libs/indexer/static/js/collections.js
-    var direction = !self.selectedCollections().length;
+    var direction = ! self.selectedCollections().length;
     ko.utils.arrayForEach(self.filteredCollections(), function(collection) {
       collection.selected(direction);
     });
@@ -226,7 +194,7 @@ var SearchCollectionsModel = function (props) {
   self.toggleCollectionSelect = function(collection, e) { // duplicated from hue/desktop/libs/indexer/static/js/collections.js
     ko.utils.arrayForEach(self.collections(), function(other_collection) {
       if(ko.unwrap(other_collection).id() == collection.id()) {
-        other_collection.selected(!other_collection.selected());
+        other_collection.selected(! other_collection.selected());
       }
     });
   };