Răsfoiți Sursa

[home2] Add the delete action to the file context menu

Johan Ahlen 9 ani în urmă
părinte
comite
87aa1fd

+ 64 - 19
desktop/core/src/desktop/static/desktop/js/fileBrowser/hueFileEntry.js

@@ -29,7 +29,7 @@
    * @param {Object} options
    * @param {AssistHelper} options.assistHelper
    * @param {Object} options.definition
-   * @param {Function} options.currentDirectory - The observable keeping track of the current open directory
+   * @param {Function} options.activeEntry - The observable keeping track of the current open directory
    * @param {HueFolder} options.parent
    * @param {string} options.app - Currently only 'documents' is supported
    *
@@ -37,7 +37,7 @@
    */
   function HueFileEntry (options) {
     var self = this;
-    self.currentDirectory = options.currentDirectory;
+    self.activeEntry = options.activeEntry;
     self.parent = options.parent;
     self.definition = options.definition;
     self.assistHelper = options.assistHelper;
@@ -47,6 +47,8 @@
     self.path = self.definition.name;
     self.app = options.app;
 
+    self.entriesToDelete = ko.observableArray();
+
     self.selected = ko.observable(false);
 
     self.loaded = ko.observable(false);
@@ -59,14 +61,10 @@
 
     self.entries = ko.observableArray([]);
 
-    self.selectedEntryIds = ko.pureComputed(function () {
-      var ids = [];
-      $.each(self.entries(), function (idx, entry) {
-        if (entry.selected()) {
-          ids.push(entry.definition.id);
-        }
+    self.selectedEntries = ko.pureComputed(function () {
+      return $.grep(self.entries(), function (entry) {
+        return entry.selected();
       });
-      return ids;
     });
 
     self.breadcrumbs = [];
@@ -85,7 +83,7 @@
   HueFileEntry.prototype.open = function () {
     var self = this;
     if (self.definition.type === 'directory') {
-      self.currentDirectory(self);
+      self.makeActive();
     } else {
       window.location.href = self.definition.absoluteUrl;
     }
@@ -109,7 +107,7 @@
           });
           self.entries($.map(cleanEntries, function (definition) {
             return new HueFileEntry({
-              currentDirectory: self.currentDirectory,
+              activeEntry: self.activeEntry,
               assistHelper: self.assistHelper,
               definition: definition,
               app: self.app,
@@ -128,16 +126,55 @@
     }
   };
 
-  HueFileEntry.prototype.delete = function () {
+  HueFileEntry.prototype.topMenuDelete = function () {
     var self = this;
-    if (self.app === 'documents') {
-      self.assistHelper.deleteDocument({
-        successCallback: self.parent.load.bind(self.parent),
-        id: self.definition.id
-      });
+    if (self.selectedEntries().length > 0 ) {
+      self.entriesToDelete(self.selectedEntries());
+    } else {
+      self.entriesToDelete([ self ]);
+    }
+    $('#deleteEntriesModal').modal('show');
+  };
+
+  HueFileEntry.prototype.contextMenuDelete = function () {
+    var self = this;
+    if (self.selected()) {
+      self.parent.entriesToDelete(self.parent.selectedEntries());
+    } else {
+      self.parent.entriesToDelete([self]);
     }
+    $('#deleteEntriesModal').modal('show');
+  };
+
+  HueFileEntry.prototype.performDelete = function () {
+    var self = this;
+    if (self.app === 'documents') {
+      if (self.entriesToDelete().indexOf(self) !== -1) {
+        self.activeEntry(self.parent);
+      }
+
+      var deleteNext = function () {
+        if (self.entriesToDelete().length > 0) {
+          var nextId = self.entriesToDelete().shift().definition.id;
+          self.assistHelper.deleteDocument({
+            successCallback: function () {
+              deleteNext();
+            },
+            errorCallback: function () {
+              self.activeEntry().load();
+            },
+            id: nextId
+          });
+        } else {
+          self.activeEntry().load();
+        }
+      };
+    };
+    deleteNext();
+    $('#deleteEntriesModal').modal('hide');
   };
 
+
   HueFileEntry.prototype.closeUploadModal = function () {
     var self = this;
     if (self.app === 'documents') {
@@ -177,6 +214,11 @@
     }
   };
 
+  HueFileEntry.prototype.makeActive = function () {
+    var self = this;
+    self.activeEntry(this);
+  };
+
   HueFileEntry.prototype.showUploadModal = function () {
     if (self.app = 'documents') {
       $('#importDocumentsModal').modal('show');
@@ -200,8 +242,11 @@
   HueFileEntry.prototype.download = function () {
     var self = this;
     if (self.app = 'documents') {
-      if (self.selectedEntryIds().length > 0) {
-        window.location.href = '/desktop/api2/doc/export?documents=' + ko.mapping.toJSON(self.selectedEntryIds());
+      if (self.selectedEntries().length > 0) {
+        var ids = self.selectedEntries().map(function (entry) {
+          return entry.definition.id;
+        })
+        window.location.href = '/desktop/api2/doc/export?documents=' + ko.mapping.toJSON(ids);
       } else {
         self.downloadThis();
       }

+ 4 - 4
desktop/core/src/desktop/static/desktop/js/home2.vm.js

@@ -34,9 +34,9 @@
     self.isLeftPanelVisible = ko.observable();
     self.assistHelper.withTotalStorage('assist', 'assist_panel_visible', self.isLeftPanelVisible, true);
 
-    self.currentDirectory = ko.observable();
-    self.currentDirectory(new HueFileEntry({
-      currentDirectory: self.currentDirectory,
+    self.activeEntry = ko.observable();
+    self.activeEntry(new HueFileEntry({
+      activeEntry: self.activeEntry,
       assistHelper: self.assistHelper,
       app: 'documents',
       definition: {
@@ -44,7 +44,7 @@
       }
     }));
 
-    self.currentDirectory().load();
+    self.activeEntry().load();
 
     self.shareFormDocId = ko.observable('');
     self.exportFormDocIds = ko.observable('');

+ 7 - 4
desktop/core/src/desktop/static/desktop/js/ko.hue-bindings.js

@@ -209,17 +209,20 @@
           }, 300);
           active = false;
         }
-      }
+      };
 
       huePubSub.subscribe('contextmenu-active', function (origin) {
         if (origin !== element) {
           hideMenu();
         }
-      })
+      });
       document.addEventListener("contextmenu", function (event) {
         hideMenu();
-      })
-      $menu.click(hideMenu)
+      });
+      $menu.click(function (e) {
+        hideMenu();
+        e.stopPropagation();
+      });
       $element.click(hideMenu);
       $(document).click(hideMenu);
     }

+ 22 - 15
desktop/core/src/desktop/templates/file_browser.mako

@@ -157,7 +157,7 @@ from desktop.views import _ko
 
   <script type="text/html" id="fb-template">
     <div id="importDocumentsModal" class="modal hide fade fileupload-modal">
-      <!-- ko with: currentDirectory -->
+      <!-- ko with: activeEntry -->
       <div class="modal-header">
         <a href="#" class="close" data-clear="importDocumentsForm" data-bind="click: closeUploadModal">&times;</a>
         <h3>${_('Import Hue documents')}</h3>
@@ -190,7 +190,7 @@ from desktop.views import _ko
       <!-- /ko -->
     </div>
     <div id="createDirectoryModal" class="modal hide fade">
-      <!-- ko with: currentDirectory -->
+      <!-- ko with: activeEntry -->
       <div class="modal-body form-horizontal">
         <div class="control-group">
           <label class="control-label" for="newDirectoryName">${ _('Name') }</label>
@@ -205,29 +205,32 @@ from desktop.views import _ko
       </div>
       <!-- /ko -->
     </div>
-    <div id="deleteDirectoryModal" class="modal hide fade">
-      <!-- ko with: currentDirectory -->
+    <div id="deleteEntriesModal" class="modal hide fade">
+      <!-- ko with: activeEntry -->
       <div class="modal-header">
         <a href="#" class="close" data-dismiss="modal">&times</a>
-        <h3>${ _('Do you really want to delete:') } <span data-bind="text: name"></span></h3>
+        <h3>${ _('Do you really want to delete') }
+          <!-- ko if: entriesToDelete().length == 1 --> <span data-bind="text: entriesToDelete()[0].name"></span><!-- /ko -->
+          <!-- ko if: entriesToDelete().length > 1 --> <span data-bind="text: entriesToDelete().length"></span> ${ _('entries') }<!-- /ko -->
+        </h3>
       </div>
       <div class="modal-footer">
         <input type="button" class="btn" data-dismiss="modal" value="${ _('Cancel') }">
-        <input type="submit" data-bind="click: function () { $parents[1].currentDirectory($data.parent); $data.delete(); $('#deleteDirectoryModal').modal('hide'); }" class="btn btn-danger" value="${_('Yes')}"/>
+        <input type="submit" data-bind="click: performDelete" class="btn btn-danger" value="${_('Yes')}"/>
       </div>
       <!-- /ko -->
     </div>
     <div class="fb-container">
       <div class="fb-action-bar">
         <h4>
-          <div class="fb-breadcrumb" data-bind="with: currentDirectory">
+          <div class="fb-breadcrumb" data-bind="with: activeEntry">
             <ul class="nav nav-pills hueBreadcrumbBar">
               <!-- ko if: isRoot -->
               <li class="active-breadcrumb">${ _('My documents') }</li>
               <!-- /ko -->
 
               <!-- ko foreach: breadcrumbs -->
-              <li><a href="javascript:void(0);" data-bind="text: isRoot ? '${ _('My documents') }' : name, click: function () { $parents[1].currentDirectory($data); } "></a> <span class="divider">&gt;</span></li>
+              <li><a href="javascript:void(0);" data-bind="text: isRoot ? '${ _('My documents') }' : name, click: makeActive"></a> <span class="divider">&gt;</span></li>
               <!-- /ko -->
               <!-- ko ifNot: isRoot -->
               <li class="active-breadcrumb" data-bind="text: name"></li>
@@ -235,7 +238,7 @@ from desktop.views import _ko
             </ul>
           </div>
         </h4>
-        <div class="fb-folder-actions" data-bind="with: currentDirectory">
+        <div class="fb-folder-actions" data-bind="with: activeEntry">
           <!-- ko if: app === 'documents' -->
           <span class="dropdown">
             <a class="inactive-action fb-action" data-toggle="dropdown" href="javascript:void(0);"><span class="fa-stack fa-fw" style="width: 1.28571429em"><i class="fa fa-file-o fa-stack-1x"></i><i class="fa fa-plus-circle fa-stack-1x" style="font-size: 14px; margin-left: 6px; margin-top: 6px;"></i></span></a>
@@ -261,8 +264,11 @@ from desktop.views import _ko
           </span>
           <!-- /ko -->
           <a class="inactive-action fb-action" href="javascript:void(0);" data-bind="click: function () { $('#createDirectoryModal').modal('show'); }"><span class="fa-stack fa-fw" style="width: 1.28571429em;"><i class="fa fa-folder-o fa-stack-1x" ></i><i class="fa fa-plus-circle fa-stack-1x" style="font-size: 14px; margin-left: 7px; margin-top: 3px;"></i></span></a>
-          <!-- ko ifnot: isRoot -->
-          <a class="inactive-action fb-action" href="javascript:void(0);" data-bind="click: function () { $('#deleteDirectoryModal').modal('show'); }"><i class="fa fa-fw fa-times"></i></a>
+          <!-- ko if: !isRoot || selectedEntries().length > 0 -->
+          <a class="inactive-action fb-action" href="javascript:void(0);" data-bind="click: topMenuDelete"><i class="fa fa-fw fa-times"></i></a>
+          <!-- /ko -->
+          <!-- ko if: isRoot && selectedEntries().length == 0 -->
+          <span class="inactive-action fb-action"><i class="fa fa-fw fa-times"></i></span>
           <!-- /ko -->
           <a class="inactive-action fb-action" href="javascript:void(0);"><i class="fa fa-fw fa-users"></i></a>
           <a class="inactive-action fb-action" href="javascript:void(0);" data-bind="click: download"><i class="fa fa-fw fa-download"></i></a>
@@ -277,15 +283,16 @@ from desktop.views import _ko
           <div class="fb-attr-col fb-modified">${ _('Last Modified') }</div>
         </div>
       </div>
-      <div class="fb-list" data-bind="with: currentDirectory">
+      <div class="fb-list" data-bind="with: activeEntry">
         <ul data-bind="foreach: { data: entries, itemHeight: 39, scrollableElement: '.fb-list' }">
           <li data-bind="fileSelect: $parent.entries, css: { 'fb-selected': selected }">
             <div style="width: 100%; height: 100%" data-bind="contextMenu: '.hue-context-menu'">
               <ul class="hue-context-menu">
                 <li><a href="javascript:void(0);" data-bind="click: contextMenuDownload"><i class="fa fa-download"></i> ${ _('Download') }</a></li>
+                <li><a href="javascript:void(0);" data-bind="click: contextMenuDelete"><i class="fa fa-fw fa-times"></i> ${ _('Delete') }</a></li>
               </ul>
               <div class="fb-primary-col">
-                <i class="fa fa-fw" data-bind="css: { 'fa-folder-o' : definition.type === 'directory', 'fa-file-o': definition.type !== 'directory' }"></i>
+                <i class="fa fa-fw" data-bind="css: { 'fa-folder-o' : isDirectory, 'fa-file-o': ! isDirectory }"></i>
                 <a href="javascript: void(0);" data-bind="text: name, click: open"></a>
               </div>
               <div class="fb-attr-group">
@@ -360,12 +367,12 @@ from desktop.views import _ko
 
       /**
        * @param {Object} params
-       * @param {HueFileEntry} params.currentDirectory - Observable holding the current directory
+       * @param {HueFileEntry} params.activeEntry - Observable holding the current directory
        * @constructor
        */
       function FileBrowser (params) {
         var self = this;
-        self.currentDirectory = params.currentDirectory;
+        self.activeEntry = params.activeEntry;
       }
 
       ko.components.register('file-browser', {

+ 1 - 1
desktop/core/src/desktop/templates/home2.mako

@@ -215,7 +215,7 @@ ${ fileBrowser.fileBrowser() }
         <div class="file-browser" data-bind="component: {
           name: 'file-browser',
           params: {
-            currentDirectory: currentDirectory
+            activeEntry: activeEntry
           }
         }"></div>
       </div>