浏览代码

[security] Improved tree UX

Enrico Berti 11 年之前
父节点
当前提交
48fec4e

+ 13 - 9
apps/security/src/security/api/hdfs.py

@@ -50,20 +50,24 @@ def list_hdfs(request, path):
   try:
     stats = request.fs.stats(path)
     if stats.isDir:
-        json_response = listdir_paged(request, path)
+      json_response = listdir_paged(request, path)
     else:
-        json_response = display(request, path)
+      json_response = display(request, path)
   except:
     json_response = HttpResponse(json.dumps({'files': []}), mimetype="application/json") # AccessControlException: Permission denied: user=test, access=READ_EXECUTE, inode="/tmp/dir":romain:supergroup:drwxr-xr-x:group::r-x,group:bob:---,group:test:---,default:user::rwx,default:group::r--,default:mask::r--,default:other::rwx (error 403)
+
+  print "pass"
+  print json_response
   if json.loads(request.GET.get('isDiffMode', 'false')):
-    print "@@@@@@@@"
     request.doas = 'hdfs'
-    hdfs_response = json.loads(listdir_paged(request, path).content)
-    resp = json.loads(json_response.content)
-    resp['page'] = hdfs_response['page']
-    resp['files'] = _diff_list_dir(resp, hdfs_response)
-    json_response.content = json.dumps(resp)
-      
+    stats = request.fs.stats(path)
+    if stats.isDir:
+      hdfs_response = json.loads(listdir_paged(request, path).content)
+      resp = json.loads(json_response.content)
+      resp['page'] = hdfs_response['page']
+      resp['files'] = _diff_list_dir(resp, hdfs_response)
+      json_response.content = json.dumps(resp)
+
   return json_response
 
 

+ 1 - 3
apps/security/src/security/templates/hdfs.mako

@@ -263,7 +263,7 @@ ${ layout.menubar(section='hdfs') }
                     <select class="user-list" data-bind="options: $root.selectableHadoopUsers, select2: { placeholder: '${ _("Select a user") }', update: $root.doAs}" style="width: 120px"></select>
                     <i class="fa fa-group" title="List of groups in popover for this user?"></i>
                   </div>
-                  <i class="fa fa-sitemap fa-rotate-270"></i>
+                  <i class="fa fa-sitemap fa-rotate-270" data-bind="css: {'fa-spin': $root.assist.isLoadingTree()}"></i>
                   <a href="javascript: void(0)" data-bind="click: $root.assist.collapseTree">
                     <i class="fa fa-compress"></i> ${_('Collapse')}
                   </a>
@@ -407,8 +407,6 @@ ${ tree.import_templates(itemClick='$root.assist.setPath', iconClick='$root.assi
     }
     viewModel.init(_initialPath);
 
-    //$(document).on("loaded.acls", movePopover);
-
     $("#path").jHueHdfsAutocomplete({
       home: viewModel.assist.path(),
       onPathChange: function (path) {

+ 57 - 7
apps/security/static/js/hdfs.ko.js

@@ -53,7 +53,16 @@ function printAcl(acl) {
 var Assist = function (vm, assist) {
   var self = this;
 
+  self.compareNames = function (a,b) {
+    if (a.name.toLowerCase() < b.name.toLowerCase())
+      return -1;
+    if (a.name.toLowerCase() > b.name.toLowerCase())
+      return 1;
+    return 0;
+  }
+
   self.isLoadingAcls = ko.observable(false);
+  self.isLoadingTree = ko.observable(false);
   self.showAclsAsText = ko.observable(false);
   self.isDiffMode = ko.observable(false);
   self.isDiffMode.subscribe(function () {
@@ -105,6 +114,7 @@ var Assist = function (vm, assist) {
   self.pagenum = ko.observable(1);
   self.files = ko.observableArray();
   self.fromLoadMore = false;
+  self.fromRebuildTree = false;
 
   self.acls = ko.observableArray();
   self.originalAcls = ko.observableArray();
@@ -128,10 +138,11 @@ var Assist = function (vm, assist) {
   self.group = ko.observable('');
 
   self.afterRender = function() {
-    if (! self.fromLoadMore) {
+    if (! self.fromLoadMore && ! self.fromRebuildTree) {
       $(document).trigger("rendered.tree");
     }
     self.fromLoadMore = false;
+    self.fromRebuildTree = false;
   }
 
 
@@ -187,13 +198,14 @@ var Assist = function (vm, assist) {
         aclBit: item.rwx.indexOf('+') != -1,
         striked: item.striked != null,
         isExpanded: true,
-        isDir: item.type == "dir",
+        isDir: item.type == "dir" || item.isDir == true,
         page: {
           number: -1,
           num_pages: -1
         },
         nodes: []
       });
+      leaf.nodes.sort(self.compareNames);
     }
     return leaf;
   }
@@ -241,15 +253,32 @@ var Assist = function (vm, assist) {
     self.loadData(self.growingTree());
   }
 
-  self.refreshTree = function () {
+  self.refreshTree = function (force) {
     self.growingTree(jQuery.extend(true, {}, self.initialGrowingTree));
     Object.keys(self.treeAdditionalData).forEach(function (path) {
-      if (self.treeAdditionalData[path].loaded) {
+      if (typeof force == "boolean" && force){
         self.fetchPath(path);
       }
+      else {
+        if (self.treeAdditionalData[path].loaded) {
+          self.fetchPath(path);
+        }
+      }
     });
   }
 
+  self.rebuildTree = function (leaf, paths) {
+    paths.push(leaf.path);
+    if (leaf.nodes.length > 0) {
+      leaf.nodes.forEach(function (node) {
+        if (node.isDir){
+          self.rebuildTree(node, paths);
+        }
+      });
+    }
+    return paths;
+  }
+
   self.setPath = function (obj, toggle) {
     if (self.getTreeAdditionalDataForPath(obj.path()).loaded || (! obj.isExpanded() && ! self.getTreeAdditionalDataForPath(obj.path()).loaded)) {
       if (typeof toggle == "boolean" && toggle){
@@ -284,10 +313,11 @@ var Assist = function (vm, assist) {
           self.convertItemToObject(_item);
         }
       });
+      $(document).trigger("loaded.parents");
     }
   }
 
-  self.fetchPath = function (optionalPath) {
+  self.fetchPath = function (optionalPath, loadCallback) {
     var _path = typeof optionalPath != "undefined" ? optionalPath : self.path();
     $.getJSON('/security/api/hdfs/list' + _path, {
         'pagesize': 15,
@@ -315,8 +345,15 @@ var Assist = function (vm, assist) {
         }
         self.getTreeAdditionalDataForPath(_path).loaded = true;
         self.updatePathProperty(self.growingTree(), _path, "page", data.page);
-        self.loadData(self.growingTree());
-        self.getAcls();
+        if (typeof loadCallback != "undefined"){
+          loadCallback(data);
+        }
+        else {
+          self.loadData(self.growingTree());
+        }
+        if (typeof optionalPath == "undefined"){
+          self.getAcls();
+        }
       }).fail(function (xhr, textStatus, errorThrown) {
         $(document).trigger("error", xhr.responseText);
       });
@@ -418,6 +455,19 @@ var HdfsViewModel = function (initial) {
   self.init = function (path) {
     self.fetchUsers();
     self.assist.path(path);
+    $(document).one("loaded.parents", function(){
+      self.assist.isLoadingTree(true);
+      var _paths = self.assist.rebuildTree(self.assist.growingTree().nodes[0], []);
+      _paths.forEach(function(path, cnt){
+        self.assist.fetchPath(path, function(){
+          if (cnt == _paths.length -1){
+            self.assist.fromRebuildTree = true;
+            self.assist.loadData(self.assist.growingTree());
+            self.assist.isLoadingTree(false);
+          }
+        });
+      });
+    });
   }
 
   self.fetchUsers = function () {

+ 5 - 2
desktop/core/src/desktop/templates/common_tree.mako

@@ -74,7 +74,7 @@
   <script type="text/html" id="node-name-template">
     <div class="node-row" data-bind="
     %if styleModifier:
-      style: { border: ${styleModifier}() ? '1px dashed #bce8f1': '',  background: ${styleModifier}() ? '#d9edf7': ''},
+      style: { border: ${styleModifier}() ? '1px dashed #eed3d7': '',  background: ${styleModifier}() ? '#f2dede': ''},
     %endif
     %if itemSelected:
      css:{selected: ${itemSelected}}">
@@ -94,7 +94,7 @@
             %endif
         },
         %if styleModifier:
-          style: { color: ${styleModifier}() ? '#338bb8': '#999999'}
+          style: { color: ${styleModifier}() ? '#b94a48': '#999999'}
         %else:
           style: { color: '#999999'}
         %endif
@@ -109,6 +109,9 @@
       %if itemDblClick:
         event : { dblclick: ${itemDblClick} },
       %endif
+      %if styleModifier:
+        style: { color: ${styleModifier}() ? '#b94a48': ''},
+      %endif
       css:{'striked': striked}"></a></strong>
 
       %if styleModifierPullRight: