浏览代码

[security] Enable KO deferred updates and improve the saving UX

Enrico Berti 9 年之前
父节点
当前提交
9a7eaebfdc

+ 10 - 0
apps/security/src/security/static/security/js/hive.ko.js

@@ -203,6 +203,7 @@ var Role = function (vm, role) {
 
   self.showEditGroups = ko.observable(false);
   self.isEditing = ko.observable(false);
+  self.isLoading = ko.observable(false);
 
   self.privilegesChanged = ko.computed(function () {
     return $.grep(self.privileges(), function (privilege) {
@@ -275,6 +276,7 @@ var Role = function (vm, role) {
 
   self.create = function () {
     $(".jHueNotify").hide();
+    self.isLoading(true);
     $.post("/security/api/hive/create_role", {
       role: ko.mapping.toJSON(self)
     }, function (data) {
@@ -292,11 +294,14 @@ var Role = function (vm, role) {
       }
     }).fail(function (xhr, textStatus, errorThrown) {
       $(document).trigger("error", xhr.responseText);
+    }).always(function() {
+      self.isLoading(false);
     });
   }
 
   self.update = function () {
     $(".jHueNotify").hide();
+    self.isLoading(true);
     $.post("/security/api/hive/save_privileges", {
       role: ko.mapping.toJSON(self)
     }, function (data) {
@@ -310,11 +315,14 @@ var Role = function (vm, role) {
       }
     }).fail(function (xhr, textStatus, errorThrown) {
       $(document).trigger("error", xhr.responseText);
+    }).always(function() {
+      self.isLoading(false);
     });
   }
 
   self.remove = function (role) {
     $(".jHueNotify").hide();
+    self.isLoading(true);
     $.post("/security/api/hive/drop_sentry_role", {
       roleName: role.name
     }, function (data) {
@@ -327,6 +335,8 @@ var Role = function (vm, role) {
       }
     }).fail(function (xhr, textStatus, errorThrown) {
       $(document).trigger("error", xhr.responseText);
+    }).always(function() {
+      self.isLoading(false);
     });
   }
 

+ 5 - 3
apps/security/src/security/templates/hive.mako

@@ -326,7 +326,7 @@ ${ layout.menubar(section='hive1') }
                     <a class="pointer" data-bind="visible: groupsChanged() && ! $root.isLoadingRoles(), click: resetGroups">
                       <i class="fa fa-undo"></i>
                     </a>
-                    <a class="pointer" data-bind="visible: groupsChanged && ! $root.isLoadingRoles(), click: saveGroups">
+                    <a class="pointer" data-bind="visible: groupsChanged() && ! $root.isLoadingRoles(), click: saveGroups">
                       <i class="fa fa-save"></i>
                     </a>
                   </div>
@@ -389,8 +389,8 @@ ${ layout.menubar(section='hive1') }
   </div>
   <div class="modal-footer">
     <button class="btn" data-dismiss="modal" aria-hidden="true">${ _('Cancel') }</button>
-    <button data-loading-text="${ _('Saving...') }" class="btn btn-primary disable-enter" data-bind="click: $root.role().create, visible: ! $root.role().isEditing()">${ _('Save') }</button>
-    <button data-loading-text="${ _('Saving...') }" class="btn btn-primary disable-enter" data-bind="click: $root.role().update, visible: $root.role().isEditing()">${ _('Update') }</button>
+    <button class="btn btn-primary disable-enter disable-feedback" data-bind="click: $root.role().create, visible: ! $root.role().isEditing(), css: {'disabled': $root.role().isLoading()}">${ _('Save') }</button>
+    <button class="btn btn-primary disable-enter disable-feedback" data-bind="click: $root.role().update, visible: $root.role().isEditing(), css: {'disabled': $root.role().isLoading()}"">${ _('Update') }</button>
   </div>
 </div>
 
@@ -562,6 +562,8 @@ ${ tree.import_templates(itemClick='$root.assist.setPath', iconClick='$root.assi
 
 <script type="text/javascript" charset="utf-8">
 
+    ko.options.deferUpdates = true;
+
     function deletePrivilegeModal(role) {
       var cascadeDeletes = $.grep(role.privilegesChanged(), function(privilege) {
           return privilege.status() == 'deleted' && (privilege.privilegeScope() == 'SERVER' || privilege.privilegeScope() == 'DATABASE'); }