Browse Source

HUE-950 [core] Support for saving and displaying permissions, added History section functions too

Enrico Berti 12 years ago
parent
commit
641f14f789

+ 12 - 2
desktop/core/src/desktop/models.py

@@ -93,7 +93,7 @@ class DocumentTagManager(models.Manager):
       raise Exception(_("Can't remove %s: it is a reserved tag.") % tag)
       raise Exception(_("Can't remove %s: it is a reserved tag.") % tag)
 
 
     doc = Document.objects.get_doc(doc_id, owner=owner)
     doc = Document.objects.get_doc(doc_id, owner=owner)
-    doc.remove(tag)
+    doc.remove_tag(tag)
 
 
   def delete_tag(self, tag_id, owner):
   def delete_tag(self, tag_id, owner):
     tag = DocumentTag.objects.get(id=tag_id, owner=owner)
     tag = DocumentTag.objects.get(id=tag_id, owner=owner)
@@ -111,7 +111,7 @@ class DocumentTagManager(models.Manager):
 
 
     for tag in doc.tags.all():
     for tag in doc.tags.all():
       if tag.tag not in DocumentTag.RESERVED:
       if tag.tag not in DocumentTag.RESERVED:
-        doc.remove(tag)
+        doc.remove_tag(tag)
 
 
     for tag_id in tag_ids:
     for tag_id in tag_ids:
       tag = DocumentTag.objects.get(id=tag_id, owner=owner)
       tag = DocumentTag.objects.get(id=tag_id, owner=owner)
@@ -283,6 +283,9 @@ class Document(models.Model):
   def add_tag(self, tag):
   def add_tag(self, tag):
     self.tags.add(tag)
     self.tags.add(tag)
 
 
+  def remove_tag(self, tag):
+    self.tags.remove(tag)
+
   def send_to_trash(self):
   def send_to_trash(self):
     tag = DocumentTag.objects.get_trash_tag(user=self.owner)
     tag = DocumentTag.objects.get_trash_tag(user=self.owner)
     self.tags.add(tag)
     self.tags.add(tag)
@@ -370,6 +373,9 @@ class Document(models.Model):
 
 
       DocumentPermission.objects.sync(document=self, name=name, users=users, groups=groups)
       DocumentPermission.objects.sync(document=self, name=name, users=users, groups=groups)
 
 
+  def list_permissions(self):
+    return DocumentPermission.objects.list(document=self)
+
 
 
 class DocumentPermissionManager(models.Manager):
 class DocumentPermissionManager(models.Manager):
 
 
@@ -418,6 +424,10 @@ class DocumentPermissionManager(models.Manager):
     if not perm.users and not perm.groups:
     if not perm.users and not perm.groups:
       perm.delete()
       perm.delete()
 
 
+  def list(self, document):
+    perm, created = DocumentPermission.objects.get_or_create(doc=document, perms=DocumentPermission.READ_PERM)
+    return perm
+
 
 
 class DocumentPermission(models.Model):
 class DocumentPermission(models.Model):
   READ_PERM = 'read'
   READ_PERM = 'read'

+ 108 - 39
desktop/core/src/desktop/templates/home.mako

@@ -35,7 +35,7 @@ ${ commonheader(_('Welcome Home'), "home", user) | n,unicode }
     margin-bottom: 4px;
     margin-bottom: 4px;
   }
   }
 
 
-  #trashCounter {
+  #trashCounter, #historyCounter {
     margin-top: 3px;
     margin-top: 3px;
   }
   }
 
 
@@ -118,11 +118,11 @@ ${ commonheader(_('Welcome Home'), "home", user) | n,unicode }
                 % endif
                 % endif
               </ul>
               </ul>
            </li>
            </li>
-           <li class="viewTrash"><a href="javascript:void(0)"><i class="icon-trash"></i> ${_('Trash')} <span id="trashCounter" class="badge pull-right">0</span></a></li>
-           <li class="viewTrash"><a href="javascript:void(0)"><i class="icon-th-list"></i> ${_('History')} <span id="trashCounter" class="badge pull-right">0</span></a></li>
+           <li class="viewTrash toggableSection"><a href="javascript:void(0)"><i class="icon-trash"></i> ${_('Trash')} <span id="trashCounter" class="badge pull-right">0</span></a></li>
+           <li class="viewHistory toggableSection"><a href="javascript:void(0)"><i class="icon-time"></i> ${_('History')} <span id="historyCounter" class="badge pull-right">0</span></a></li>
           <li class="nav-header tag-header">${_('Tags')} <div id="editTags" style="display: inline;cursor: pointer;margin-left: 6px"><i class="icon-tags"></i></div> </li>
           <li class="nav-header tag-header">${_('Tags')} <div id="editTags" style="display: inline;cursor: pointer;margin-left: 6px"><i class="icon-tags"></i></div> </li>
           % for tag in tags:
           % for tag in tags:
-            %if tag.tag != "trash":
+            %if tag.tag != "trash" and tag.tag != "history":
             <li class="toggleTag white" data-tag="${ tag.tag }"><div class="hueCheckbox pull-left"></div>${ tag.tag }</li>
             <li class="toggleTag white" data-tag="${ tag.tag }"><div class="hueCheckbox pull-left"></div>${ tag.tag }</li>
             %endif
             %endif
           % endfor
           % endfor
@@ -242,21 +242,21 @@ var JSON_USERS_GROUPS;
 var documentsTable;
 var documentsTable;
 
 
 $(document).ready(function () {
 $(document).ready(function () {
-  var selectedUserOrGroup = null;
+  var selectedUserOrGroup, map, dropdown = null;
   $.getJSON("${ url('useradmin.views.list_for_autocomplete') }", function (data) {
   $.getJSON("${ url('useradmin.views.list_for_autocomplete') }", function (data) {
     JSON_USERS_GROUPS = data;
     JSON_USERS_GROUPS = data;
+    dropdown = [];
+    map = {};
+    $.each(JSON_USERS_GROUPS.users, function (i, user) {
+      map[user.username] = user;
+      dropdown.push(user.username);
+    });
+    $.each(JSON_USERS_GROUPS.groups, function (i, group) {
+      map[group.name] = group;
+      dropdown.push(group.name);
+    });
     $("#documentShareAdd").typeahead({
     $("#documentShareAdd").typeahead({
       source: function (query, process) {
       source: function (query, process) {
-        dropdown = [];
-        map = {};
-        $.each(JSON_USERS_GROUPS.users, function (i, user) {
-          map[user.username] = user;
-          dropdown.push(user.username);
-        });
-        $.each(JSON_USERS_GROUPS.groups, function (i, group) {
-          map[group.name] = group;
-          dropdown.push(group.name);
-        });
         process(dropdown);
         process(dropdown);
       },
       },
       matcher: function (item) {
       matcher: function (item) {
@@ -294,7 +294,7 @@ $(document).ready(function () {
       { "bSortable": false, "sClass": "row-selector-exclude", "sWidth": "20px"}
       { "bSortable": false, "sClass": "row-selector-exclude", "sWidth": "20px"}
     ],
     ],
     "aaSorting": [
     "aaSorting": [
-      [ 1, "desc" ]
+      [ 5, "desc" ]
     ],
     ],
     "oLanguage": {
     "oLanguage": {
       "sEmptyTable": "${_('No data available')}",
       "sEmptyTable": "${_('No data available')}",
@@ -329,20 +329,29 @@ $(document).ready(function () {
   populateTable();
   populateTable();
 
 
   $(".viewTrash").on("click", function () {
   $(".viewTrash").on("click", function () {
+    $(".viewHistory").removeClass("active");
+    toggleSpecificSection($(this), "trash");
+  });
+
+  $(".viewHistory").on("click", function () {
+    $(".viewTrash").removeClass("active");
+    toggleSpecificSection($(this), "history");
+  });
+
+  function toggleSpecificSection(section, filter){
     $(".hueCheckbox").removeClass("icon-ok");
     $(".hueCheckbox").removeClass("icon-ok");
-    var _this = $(this);
-    if (_this.hasClass("active")) {
+    if (section.hasClass("active")) {
       populateTable();
       populateTable();
-      _this.removeClass("active");
+      section.removeClass("active");
     }
     }
     else {
     else {
-      populateTable("trash");
-      _this.addClass("active");
+      populateTable(filter);
+      section.addClass("active");
     }
     }
-  });
+  }
 
 
   $(document).on("click", ".toggleTag", function (e) {
   $(document).on("click", ".toggleTag", function (e) {
-    $(".viewTrash").removeClass("active");
+    $(".toggableSection").removeClass("active");
     var _this = $(this);
     var _this = $(this);
     _this.blur();
     _this.blur();
     if (_this.find(".hueCheckbox").hasClass("icon-ok")) {
     if (_this.find(".hueCheckbox").hasClass("icon-ok")) {
@@ -359,12 +368,17 @@ $(document).ready(function () {
   });
   });
 
 
   var _trashCounter = 0;
   var _trashCounter = 0;
+  var _historyCounter = 0;
   $(JSON_DOCS).each(function (cnt, doc) {
   $(JSON_DOCS).each(function (cnt, doc) {
     if (isInTags(doc, "trash")) {
     if (isInTags(doc, "trash")) {
       _trashCounter++;
       _trashCounter++;
     }
     }
+    if (isInTags(doc, "history")) {
+      _historyCounter++;
+    }
   });
   });
   $("#trashCounter").text(_trashCounter);
   $("#trashCounter").text(_trashCounter);
+  $("#historyCounter").text(_historyCounter);
 
 
   $(document).on("click", ".documentTags", function () {
   $(document).on("click", ".documentTags", function () {
     $("#documentTagsModal").data("document-id", $(this).data("document-id"));
     $("#documentTagsModal").data("document-id", $(this).data("document-id"));
@@ -374,7 +388,7 @@ $(document).ready(function () {
   function renderTags() {
   function renderTags() {
     $(".toggleTag").remove();
     $(".toggleTag").remove();
     for (var i = JSON_TAGS.length - 1; i >= 0; i--) {
     for (var i = JSON_TAGS.length - 1; i >= 0; i--) {
-      if (!JSON_TAGS[i].isTrash) {
+      if (!JSON_TAGS[i].isTrash && !JSON_TAGS[i].isHistory) {
         var _t = $("<li>").addClass("toggleTag").addClass("white");
         var _t = $("<li>").addClass("toggleTag").addClass("white");
         _t.data("tag", JSON_TAGS[i].name);
         _t.data("tag", JSON_TAGS[i].name);
         _t.html('<div class="hueCheckbox pull-left"></div>' + JSON_TAGS[i].name);
         _t.html('<div class="hueCheckbox pull-left"></div>' + JSON_TAGS[i].name);
@@ -386,7 +400,7 @@ $(document).ready(function () {
   function renderTagsModal() {
   function renderTagsModal() {
     var _tags = "";
     var _tags = "";
     for (var i = 0; i < JSON_TAGS.length; i++) {
     for (var i = 0; i < JSON_TAGS.length; i++) {
-      if (!JSON_TAGS[i].isTrash) {
+      if (!JSON_TAGS[i].isTrash && !JSON_TAGS[i].isHistory) {
         _tags += '<div style="margin-right:10px;margin-bottom: 6px;float:left;"><span class="tagsModalCheckbox badge" data-value="' + JSON_TAGS[i].id + '"><i class="icon-trash hide"></i> ' + JSON_TAGS[i].name + '</span></div>';
         _tags += '<div style="margin-right:10px;margin-bottom: 6px;float:left;"><span class="tagsModalCheckbox badge" data-value="' + JSON_TAGS[i].id + '"><i class="icon-trash hide"></i> ' + JSON_TAGS[i].name + '</span></div>';
       }
       }
     }
     }
@@ -400,7 +414,7 @@ $(document).ready(function () {
       $("#documentTagsModalName").text(_doc.name);
       $("#documentTagsModalName").text(_doc.name);
       var _tags = "";
       var _tags = "";
       for (var i = 0; i < JSON_TAGS.length; i++) {
       for (var i = 0; i < JSON_TAGS.length; i++) {
-        if (!JSON_TAGS[i].isTrash) {
+        if (!JSON_TAGS[i].isTrash && !JSON_TAGS[i].isHistory) {
           var _inTags = isInTags(_doc, JSON_TAGS[i].name);
           var _inTags = isInTags(_doc, JSON_TAGS[i].name);
           _tags += '<div style="margin-right:10px;margin-bottom: 6px;float:left;"><span class="documentTagsModalCheckbox badge' + (_inTags ? ' badge-info selected' : '') + '" data-value="' + JSON_TAGS[i].id + '"><i class="icon-ok-sign' + (_inTags ? '' : ' hide') + '"></i> ' + JSON_TAGS[i].name + '</span></div>';
           _tags += '<div style="margin-right:10px;margin-bottom: 6px;float:left;"><span class="documentTagsModalCheckbox badge' + (_inTags ? ' badge-info selected' : '') + '" data-value="' + JSON_TAGS[i].id + '"><i class="icon-ok-sign' + (_inTags ? '' : ' hide') + '"></i> ' + JSON_TAGS[i].name + '</span></div>';
         }
         }
@@ -495,6 +509,7 @@ $(document).ready(function () {
       })
       })
     }, function (response) {
     }, function (response) {
       if (response.doc != null) {
       if (response.doc != null) {
+        $(document).trigger("info", "${ _("Tags updated successfully.") }");
         var _doc = response.doc;
         var _doc = response.doc;
         var _dtNodes = documentsTable.fnGetNodes();
         var _dtNodes = documentsTable.fnGetNodes();
         $(_dtNodes).each(function (iNode, node) {
         $(_dtNodes).each(function (iNode, node) {
@@ -526,21 +541,42 @@ $(document).ready(function () {
         tag_ids: _tags
         tag_ids: _tags
       })
       })
     }, function (response) {
     }, function (response) {
-      $.getJSON("/tag/list_tags", function (data) {
-        JSON_TAGS = data;
-        renderTags();
-        renderTagsModal();
-        renderDocs(function () {
-          $("#removeTags").button("reset");
-          $("#tagsModal").modal("hide");
-        });
-      });
+        if (response!=null){
+          if (response.status == 0){
+            $(document).trigger("info", response.message);
+            $.getJSON("/tag/list_tags", function (data) {
+              JSON_TAGS = data;
+              renderTags();
+              renderTagsModal();
+              renderDocs(function () {
+                $("#removeTags").button("reset");
+                $("#tagsModal").modal("hide");
+              });
+            });
+          }
+          else {
+            $(document).trigger("error", "${_("There was an error processing your action: ")}"+response.message);
+          }
+        }
     });
     });
   });
   });
 
 
   $(document).on("click", ".shareDocument", function () {
   $(document).on("click", ".shareDocument", function () {
     var _doc = getDocById($(this).data("document-id"));
     var _doc = getDocById($(this).data("document-id"));
     if (_doc != null) {
     if (_doc != null) {
+      if (_doc.perms != null && _doc.perms.read != null){
+        if (_doc.perms.read.users != null){
+          for (var i=0; i<_doc.perms.read.users.length;i++){
+            addToShareList(map[_doc.perms.read.users[i].username]);
+          }
+        }
+        if (_doc.perms.read.groups != null){
+          for (var i=0; i<_doc.perms.read.groups.length;i++){
+            addToShareList(map[_doc.perms.read.groups[i].name]);
+          }
+        }
+      }
+      $("#documentShareModal").data("document-id", _doc.id);
       $("#documentShareAdd").val("");
       $("#documentShareAdd").val("");
       $("#documentShareModalName").text(_doc.name);
       $("#documentShareModalName").text(_doc.name);
       renderShareList();
       renderShareList();
@@ -594,8 +630,40 @@ $(document).ready(function () {
   });
   });
 
 
   $("#saveDocumentShare").on("click", function () {
   $("#saveDocumentShare").on("click", function () {
-    // TODO: post to permissions stuff
-    console.log(shareList);
+    var _postPerms = {
+      read: {
+        user_ids: [],
+        group_ids: []
+      }
+    }
+
+    for (var id in shareList) {
+      if (shareList.hasOwnProperty(id)) {
+        var _obj = shareList[id];
+        if (_obj.username != null) {
+          _postPerms.read.user_ids.push(id);
+        }
+        else {
+          _postPerms.read.group_ids.push(id);
+        }
+      }
+    }
+
+    $.post("/doc/update_permissions", {
+      doc_id: $("#documentShareModal").data("document-id"),
+      data: JSON.stringify(_postPerms)
+    }, function (response) {
+      $("#documentShareModal").modal("hide");
+      if (response!=null){
+        if (response.status == 0){
+          $(document).trigger("info", response.message);
+          updateDoc(response.doc);
+        }
+        else {
+          $(document).trigger("error", "${_("There was an error processing your action: ")}"+response.message);
+        }
+      }
+    });
   });
   });
 
 
 });
 });
@@ -628,7 +696,7 @@ function populateTable(tags) {
   documentsTable.fnDraw();
   documentsTable.fnDraw();
   if (tags == null || tags == "") {
   if (tags == null || tags == "") {
     $(JSON_DOCS).each(function (cnt, doc) {
     $(JSON_DOCS).each(function (cnt, doc) {
-      if (!isInTags(doc, "trash")) {
+      if (!isInTags(doc, "trash") && !isInTags(doc, "history")) {
         addRow(doc);
         addRow(doc);
       }
       }
     });
     });
@@ -657,7 +725,7 @@ function addRow(doc) {
     for (var i = 0; i < doc.tags.length; i++) {
     for (var i = 0; i < doc.tags.length; i++) {
       _tags += '<span class="badge">' + doc.tags[i].name + '</span> ';
       _tags += '<span class="badge">' + doc.tags[i].name + '</span> ';
     }
     }
-    documentsTable.fnAddData([
+    var _addedRow = documentsTable.fnAddData([
       '<img src="' + doc.icon + '" width="80%"/>',
       '<img src="' + doc.icon + '" width="80%"/>',
       '<a href="' + doc.url + '" data-row-selector="true">' + doc.name + '</a>',
       '<a href="' + doc.url + '" data-row-selector="true">' + doc.name + '</a>',
       emptyStringIfNull(doc.description),
       emptyStringIfNull(doc.description),
@@ -666,6 +734,7 @@ function addRow(doc) {
       emptyStringIfNull(doc.lastModified),
       emptyStringIfNull(doc.lastModified),
       '<a href="#" class="shareDocument" data-document-id="' + doc.id + '" rel="tooltip" title="${_('Share')} ' + doc.name + '" data-placement="left" style="padding-left:10px"><i class="icon-share-sign"></i></a>',
       '<a href="#" class="shareDocument" data-document-id="' + doc.id + '" rel="tooltip" title="${_('Share')} ' + doc.name + '" data-placement="left" style="padding-left:10px"><i class="icon-share-sign"></i></a>',
     ], false);
     ], false);
+    $("td", documentsTable.fnGetNodes(_addedRow[0]))[5].setAttribute("data-sort-value", doc.lastModifiedInMillis); // a bit of black magic.
   }
   }
   catch (error) {
   catch (error) {
     $(document).trigger("error", error);
     $(document).trigger("error", error);

+ 12 - 2
desktop/core/src/desktop/views.py

@@ -81,6 +81,7 @@ def massaged_documents_for_json(documents):
   return docs
   return docs
 
 
 def massage_doc_for_json(doc):
 def massage_doc_for_json(doc):
+  perms = doc.list_permissions()
   return {
   return {
       'id': doc.id,
       'id': doc.id,
       'contentType': doc.content_type.name,
       'contentType': doc.content_type.name,
@@ -89,6 +90,12 @@ def massage_doc_for_json(doc):
       'url': doc.content_object.get_absolute_url(),
       'url': doc.content_object.get_absolute_url(),
       'description': doc.description,
       'description': doc.description,
       'tags': [{'id': tag.id, 'name': tag.tag} for tag in doc.tags.all()],
       'tags': [{'id': tag.id, 'name': tag.tag} for tag in doc.tags.all()],
+      'perms': {
+        'read': {
+          'users': [{'id': user.id, 'username': user.username} for user in perms.users.all()],
+          'groups': [{'id': group.id, 'name': group.name} for group in perms.groups.all()]
+        }
+      },
       'owner': doc.owner.username,
       'owner': doc.owner.username,
       'lastModified': doc.last_modified.strftime("%x %X"),
       'lastModified': doc.last_modified.strftime("%x %X"),
       'lastModifiedInMillis': time.mktime(doc.last_modified.timetuple())
       'lastModifiedInMillis': time.mktime(doc.last_modified.timetuple())
@@ -97,11 +104,13 @@ def massage_doc_for_json(doc):
 def massaged_tags_for_json(tags, user):
 def massaged_tags_for_json(tags, user):
   ts = []
   ts = []
   trash = DocumentTag.objects.get_trash_tag(user)
   trash = DocumentTag.objects.get_trash_tag(user)
+  history = DocumentTag.objects.get_history_tag(user)
   for tag in tags:
   for tag in tags:
     massaged_tag = {
     massaged_tag = {
       'id': tag.id,
       'id': tag.id,
       'name': tag.tag,
       'name': tag.tag,
-      'isTrash': tag.id == trash.id
+      'isTrash': tag.id == trash.id,
+      'isHistory': tag.id == history.id
     }
     }
     ts.append(massaged_tag)
     ts.append(massaged_tag)
 
 
@@ -180,13 +189,14 @@ def update_permissions(request):
 
 
   if request.method == 'POST':
   if request.method == 'POST':
     data = json.loads(request.POST['data'])
     data = json.loads(request.POST['data'])
-    doc_id = json.loads(request.POST['doc_id'])
+    doc_id = request.POST['doc_id']
     try:
     try:
       doc = Document.objects.get_doc(doc_id, request.user)
       doc = Document.objects.get_doc(doc_id, request.user)
       # doc.sync_permissions({'read': {'user_ids': [1, 2, 3], 'group_ids': [1, 2, 3]}})
       # doc.sync_permissions({'read': {'user_ids': [1, 2, 3], 'group_ids': [1, 2, 3]}})
       doc.sync_permissions(data)
       doc.sync_permissions(data)
       response['message'] = _('Permissions updated!')
       response['message'] = _('Permissions updated!')
       response['status'] = 0
       response['status'] = 0
+      response['doc'] = massage_doc_for_json(doc)
     except Exception, e:
     except Exception, e:
       response['message'] = force_unicode(e)
       response['message'] = force_unicode(e)
   else:
   else: