Эх сурвалжийг харах

HUE-5964 [useradmin] Simplified port of the user list

Enrico Berti 8 жил өмнө
parent
commit
7878feb

+ 130 - 139
apps/useradmin/src/useradmin/templates/list_users.mako

@@ -14,7 +14,7 @@
 ## See the License for the specific language governing permissions and
 ## limitations under the License.
 <%!
-from desktop.views import commonheader, commonfooter, antixss, _ko
+from desktop.views import commonheader, commonfooter, antixss
 from django.template.defaultfilters import date, time
 from django.utils.translation import ugettext as _
 %>
@@ -32,40 +32,45 @@ ${layout.menubar(section='users')}
 
     <%actionbar:render>
       <%def name="search()">
-        <input type="text" class="input-xlarge search-query" placeholder="${_('Search for name, group, etc...')}" data-bind="textInput: filter">
+          <input id="filterInput" type="text" class="input-xlarge search-query"
+                 placeholder="${_('Search for name, group, etc...')}">
       </%def>
       <%def name="actions()">
-        <!-- ko if: isSuperUser -->
-        <button id="deleteUserBtn" class="btn" title="${_('Delete')}" data-bind="enable: chosenUsers().length > 0"><i class="fa fa-trash-o"></i> ${_('Delete')}</button>
-        <!-- /ko -->
+        %if user.is_superuser:
+            <button id="deleteUserBtn" class="btn" title="${_('Delete')}" disabled="disabled"><i
+                class="fa fa-trash-o"></i> ${_('Delete')}</button>
+        %endif
       </%def>
       <%def name="creation()">
-        <!-- ko if: isSuperUser -->
-        % if not is_ldap_setup:
-            <a href="${ url('useradmin.views.edit_user') }" class="btn"><i class="fa fa-user"></i> ${_('Add user')}</a>
+        %if user.is_superuser:
+            % if not is_ldap_setup:
+                <a href="${ url('useradmin.views.edit_user') }" class="btn"><i class="fa fa-user"></i> ${_('Add user')}</a>
+            %endif
+
+            % if is_ldap_setup:
+            <a href="${ url('useradmin.views.add_ldap_users') }" class="btn"><i
+                class="fa fa-briefcase"></i> ${_('Add/Sync LDAP user')}</a>
+            <a href="javascript:void(0)" class="btn confirmationModal"
+               data-confirmation-url="${ url('useradmin.views.sync_ldap_users_groups') }"><i
+                class="fa fa-refresh"></i> ${_('Sync LDAP users/groups')}</a>
+            % endif
+
+            <a href="http://gethue.com/making-hadoop-accessible-to-your-employees-with-ldap/" class="btn"
+              title="${ ('Learn how to integrate Hue with your company') }" target="_blank">
+              <i class="fa fa-question-circle"></i> LDAP
+            </a>
         %endif
-
-        % if is_ldap_setup:
-        <a href="${ url('useradmin.views.add_ldap_users') }" class="btn"><i class="fa fa-briefcase"></i> ${_('Add/Sync LDAP user')}</a>
-        <a href="javascript:void(0)" class="btn confirmationModal" data-confirmation-url="${ url('useradmin.views.sync_ldap_users_groups') }"><i class="fa fa-refresh"></i> ${_('Sync LDAP users/groups')}</a>
-        % endif
-
-        <a href="http://gethue.com/making-hadoop-accessible-to-your-employees-with-ldap/" class="btn" title="${ ('Learn how to integrate Hue with your company') }" target="_blank">
-          <i class="fa fa-question-circle"></i> LDAP
-        </a>
-        <!-- /ko -->
       </%def>
     </%actionbar:render>
 
-    <!-- ko ifnot: isLoadingUsers()  -->
-    <table class="table table-condensed">
+    <table class="table table-condensed datatables">
       <thead>
       <tr>
-        <!-- ko if: isSuperUser -->
-        <th width="1%">
-          <div class="hueCheckbox fa fa-fw" data-bind="css: {'fa-check': allSelected, 'fa-minus': someSelected}, click: toggleAll"></div>
-        </th>
-        <!-- /ko -->
+        %if user.is_superuser:
+            <th width="1%">
+              <div id="selectAll" class="hueCheckbox fa"></div>
+            </th>
+        %endif
         <th>${_('Username')}</th>
         <th>${_('First Name')}</th>
         <th>${_('Last Name')}</th>
@@ -74,37 +79,33 @@ ${layout.menubar(section='users')}
         <th>${_('Last Login')}</th>
       </tr>
       </thead>
-      <tbody data-bind="foreach: filteredUsers">
-        <tr>
-          <!-- ko if: $parent.isSuperUser -->
-            <!-- ko if: username() !== '${ user.username }' -->
-            <td class="center" data-bind="click: function(){ selected(!selected()) }" style="cursor: default" data-row-selector-exclude="true">
-              <div class="hueCheckbox fa" data-bind="css: { 'fa-check': selected }"></div>
-            </td>
-            <!-- /ko -->
-            <!-- ko if: username() === '${ user.username }' -->
-            <td class="center" style="cursor: default" data-row-selector-exclude="true">
-              <div class="hueCheckbox disabled"></div>
-            </td>
-            <!-- /ko -->
-          <!-- /ko -->
+      <tbody>
+          % for listed_user in users:
+          <tr class="tableRow"
+              data-search="${listed_user.username}${listed_user.first_name}${listed_user.last_name}${listed_user.email}${', '.join([group.name for group in listed_user.groups.all()])}">
+          %if user.is_superuser:
+              <td data-row-selector-exclude="true">
+                <div class="hueCheckbox userCheck fa" data-row-selector-exclude="true" data-id="${ listed_user.id }"></div>
+              </td>
+          %endif
           <td>
-            <!-- ko if: $parent.isSuperUser() || username() == '${user.username}' -->
-            <strong><a data-bind="text: username, attr: {'title': '${ _ko('Edit user') } ' + username(), 'href': editURL}, jHueRowSelector"></a></strong>
-            <!-- /ko -->
-            <!-- ko if: !$parent.isSuperUser() && username() != '${user.username}' -->
-            <strong data-bind="text: username"></strong>
-            <!-- /ko -->
+            %if user.is_superuser or user.username == listed_user.username:
+              <strong><a title="${_('Edit %(username)s') % dict(username=listed_user.username)}"
+                         href="${ url('useradmin.views.edit_user', username=listed_user.username) }"
+                         data-row-selector="true">${listed_user.username}</a></strong>
+            %else:
+              <strong>${listed_user.username}</strong>
+            %endif
           </td>
-          <td data-bind="text: first_name"></td>
-          <td data-bind="text: last_name"></td>
-          <td data-bind="text: email"></td>
-          <td data-bind="text: readableGroups"></td>
-          <td data-bind="text: localeFormat(last_login)"></td>
-        </tr>
+            <td>${listed_user.first_name}</td>
+            <td>${listed_user.last_name}</td>
+            <td>${listed_user.email}</td>
+            <td>${', '.join([group.name for group in listed_user.groups.all()])}</td>
+            <td>${date(listed_user.last_login)} ${time(listed_user.last_login).replace("p.m.","PM").replace("a.m.","AM")}</td>
+          </tr>
+          % endfor
       </tbody>
-      <!-- ko if: filteredUsers().length === 0 -->
-      <tfoot>
+      <tfoot class="hide">
       <tr>
         <td colspan="8">
           <div class="alert">
@@ -113,10 +114,7 @@ ${layout.menubar(section='users')}
         </td>
       </tr>
       </tfoot>
-      <!-- /ko -->
     </table>
-    <!-- /ko -->
-    <!-- ko hueSpinner: { spin: isLoadingUsers, center: true, size: 'xlarge' } --><!-- /ko -->
   </div>
 
   <div id="syncLdap" class="modal hide fade"></div>
@@ -134,7 +132,8 @@ ${layout.menubar(section='users')}
         <input type="submit" class="btn btn-danger" value="${_('Yes')}"/>
       </div>
       <div class="hide">
-        <select name="user_ids" data-bind="options: availableUsers().map(function(item){ return item.id() }), selectedOptions: chosenUsers().map(function(item){ return item.id() })" multiple="true"></select>
+        <select name="user_ids" data-bind="options: availableUsers, selectedOptions: chosenUsers"
+                multiple="true"></select>
       </div>
     </form>
   </div>
@@ -144,91 +143,45 @@ ${layout.menubar(section='users')}
 <script src="${ static('desktop/ext/js/datatables-paging-0.1.js') }" type="text/javascript" charset="utf-8"></script>
 
 <script type="text/javascript" charset="utf-8">
-  $(document).ready(function () {
-
-    var ListUsersViewModel = function () {
-      var self = this;
-
-      self.filter = ko.observable('').extend({throttle: 500});
-
-      self.isSuperUser = ko.observable(${ user.is_superuser and 'true' or 'false' })
-      self.availableUsers = ko.observableArray([]);
-
-      self.filteredUsers = ko.pureComputed(function () {
-        return self.availableUsers().filter(function (item) {
-          return item.username().toLowerCase().indexOf(self.filter()) > -1 ||
-              item.first_name().toLowerCase().indexOf(self.filter()) > -1 ||
-              item.last_name().toLowerCase().indexOf(self.filter()) > -1 ||
-              item.email().toLowerCase().indexOf(self.filter()) > -1 ||
-              item.readableGroups().toLowerCase().indexOf(self.filter()) > -1
-        });
-      });
-
-      self.chosenUsers = ko.pureComputed(function () {
-        return self.filteredUsers().filter(function (item) {
-          return item.selected()
-        });
-      });
+  var $usersComponents = $('#usersComponents');
 
-      self.toggleAll = function () {
-        var selected = self.allSelected();
-        ko.utils.arrayForEach(self.filteredUsers(), function (user) {
-          if (user.username() !== '${ user.username }') {
-            user.selected(!selected);
-          }
-          else {
-            user.selected(false);
-          }
-        });
-      };
-
-      self.allSelected = ko.pureComputed(function () {
-        var filtered = self.filteredUsers().filter(function (item) {
-          return item.selected()
-        });
-        return filtered.length > 0 && filtered.length === self.filteredUsers().length - 1
-      });
-
-      self.someSelected = ko.pureComputed(function () {
-        var filtered = self.filteredUsers().filter(function (item) {
-          return item.selected()
-        });
-        return filtered.length > 0 && filtered.length < self.filteredUsers().length - 1
-      });
-
-      self.isLoadingUsers = ko.observable(true);
+  var viewModel = {
+    availableUsers: ko.observableArray(${ users_json | n,antixss }),
+    chosenUsers: ko.observableArray([])
+  };
+  var mainDataTable;
+  $(document).ready(function () {
 
-      self.init = function () {
-        $.getJSON('/useradmin/users?format=json', function (data) {
-          self.isLoadingUsers(false);
-          if (data && data.users) {
-            var users = [];
-            data.users.forEach(function (u) {
-              var user = ko.mapping.fromJS(u);
-              user.selected = ko.observable(false);
-              user.readableGroups = ko.pureComputed(function () {
-                return u.groups ? user.groups().map(function (item) {
-                      return item.name()
-                    }).join(', ') : ''
-              });
-              users.push(user);
-            })
-            self.availableUsers(users);
-          }
-          else {
-            $.jHueNotify.error('${ _('There was an error while loading users.') }')
-          }
-        });
+    ko.applyBindings(viewModel, $usersComponents[0]);
+
+    mainDataTable = $usersComponents.find('.datatables').dataTable({
+      "sPaginationType":"bootstrap",
+      "iDisplayLength":100,
+      "bLengthChange":false,
+      "sDom": "<'row'r>t<'row-fluid'<'dt-pages'p><'dt-records'i>>",
+      "bInfo": false,
+      "bFilter": true,
+      "aoColumns": [
+        %if user.is_superuser:
+            { "bSortable": false },
+        %endif
+        null,
+        null,
+        null,
+        null,
+        null,
+        { "sType": "date" },
+      ],
+      "oLanguage": {
+        "sEmptyTable": "${_('No data available')}",
+        "sZeroRecords": "${_('No matching records')}",
       }
-    };
-
-    var viewModel = new ListUsersViewModel();
-
-    viewModel.init();
+    });
 
-    ko.applyBindings(viewModel, $('#usersComponents')[0]);
+    $usersComponents.find(".dataTables_wrapper").css("min-height", "0");
+    $usersComponents.find(".dataTables_filter").hide();
 
-    $(".confirmationModal").click(function () {
+    $usersComponents.find(".confirmationModal").click(function () {
       var _this = $(this);
       $.ajax({
         url: _this.data("confirmation-url"),
@@ -243,10 +196,48 @@ ${layout.menubar(section='users')}
       });
     });
 
-    $("#deleteUserBtn").click(function () {
-      $("#deleteUser").modal("show");
+    $usersComponents.find("#selectAll").click(function () {
+      if ($(this).attr("checked")) {
+        $(this).removeAttr("checked").removeClass("fa-check");;
+        $usersComponents.find(".userCheck").removeClass("fa-check").removeAttr("checked");
+      }
+      else {
+        $(this).attr("checked", "checked").addClass("fa-check");
+        $usersComponents.find(".userCheck").addClass("fa-check").attr("checked", "checked");
+      }
+      toggleActions();
+    });
+
+    $(document).on('click', '#usersComponents .userCheck', function () {
+      if ($(this).attr("checked")) {
+        $(this).removeClass("fa-check").removeAttr("checked");
+      }
+      else {
+        $(this).addClass("fa-check").attr("checked", "checked");
+      }
+      toggleActions();
+    });
+
+    function toggleActions() {
+      if ($usersComponents.find(".userCheck[checked='checked']").length >= 1) {
+        $usersComponents.find("#deleteUserBtn").removeAttr("disabled");
+      }
+      else {
+        $usersComponents.find("#deleteUserBtn").attr("disabled", "disabled");
+      }
+    }
+
+    $usersComponents.find("#deleteUserBtn").click(function () {
+      viewModel.chosenUsers.removeAll();
+
+      $usersComponents.find(".hueCheckbox[checked='checked']").each(function (index) {
+        viewModel.chosenUsers.push($(this).data("id"));
+      });
+
+      $usersComponents.find("#deleteUser").modal("show");
     });
 
+    $usersComponents.find("a[data-row-selector='true']").jHueRowSelector();
   });
 </script>