repair the sliver filter logic in xosAdminDashboard
[plstackapi.git] / planetstack / core / xoslib / static / js / xoslib / xosHelper.js
index 4ec75a6..a055093 100644 (file)
@@ -4,6 +4,21 @@ HTMLView = Marionette.ItemView.extend({
   },
 });
 
+FilteredCompositeView = Marionette.CompositeView.extend( {
+    showCollection: function() {
+      var ChildView;
+      this.collection.each(function(child, index) {
+        filterFunc = this.options.filter || this.filter;
+        if (filterFunc && !filterFunc(child)) {
+            return;
+        }
+        ChildView = this.getChildView(child);
+        this.addChild(child, ChildView, index);
+      }, this);
+
+    },
+});
+
 SliceSelectorOption = Marionette.ItemView.extend({
     template: "#xos-sliceselector-option",
     tagName: "option",
@@ -16,10 +31,11 @@ SliceSelectorOption = Marionette.ItemView.extend({
     },
 });
 
-SliceSelectorView = Marionette.CompositeView.extend({
+SliceSelectorView = FilteredCompositeView.extend({
     template: "#xos-sliceselector-select",
     childViewContainer: "select",
     childView: SliceSelectorOption,
+    caption: "Slice",
 
     events: {"change select": "onSliceChanged"},
 
@@ -34,20 +50,8 @@ SliceSelectorView = Marionette.CompositeView.extend({
     sliceChanged: function(id) {
         console.log("sliceChanged " + id);
     },
-});
 
-FilteredCompositeView = Marionette.CompositeView.extend( {
-    showCollection: function() {
-      var ChildView;
-      this.collection.each(function(child, index) {
-        if (this.filter && !this.filter(child)) {
-            return;
-        }
-        ChildView = this.getChildView(child);
-        this.addChild(child, ChildView, index);
-      }, this);
-
-    },
+    templateHelpers: function() { return {caption: this.options.caption || this.caption }; },
 });
 
 XOSRouter = Marionette.AppRouter.extend({
@@ -80,8 +84,13 @@ XOSRouter = Marionette.AppRouter.extend({
             Marionette.AppRouter.prototype.navigate.call(this, href, options);
         },
     });\r
-
-Backbone.Syphon.InputReaders.register('select', function(el) {
+\r
+// XXX - We import backbone multiple times (BAD!) since the import happens\r
+//   inside of the view's html. The second time it's imported (developer\r
+//   view), it wipes out Backbone.Syphon. So, save it as Backbone_Syphon for\r
+//   now.\r
+Backbone_Syphon = Backbone.Syphon\r
+Backbone_Syphon.InputReaders.register('select', function(el) {\r
     // Modify syphon so that if a select has "syphonall" in the class, then
     // the value of every option will be returned, regardless of whether of
     // not it is selected.
@@ -138,10 +147,18 @@ XOSApplication = Marionette.Application.extend({
         }
         console.log(responseText);
         console.log(parsed_error);
-        if (parsed_error) {
+
+        if (parsed_error && ("error" in parsed_error)) {
+            // this error comes from genapi views
+            $("#xos-error-dialog").html(templateFromId("#xos-error-response")(parsed_error));
+        } else if (parsed_error && ("detail" in parsed_error)) {
+            // this error response comes from rest_framework APIException
+            parsed_error["error"] = "API Error";
+            parsed_error["specific_error"] = parsed_error["detail"];
+            parsed_error["reasons"] = [];
             $("#xos-error-dialog").html(templateFromId("#xos-error-response")(parsed_error));
         } else {
-            $("#xos-error-dialog").html(templateFromId("#xos-error-rawresponse")({responseText: responseText}))
+            $("#xos-error-dialog").html(templateFromId("#xos-error-rawresponse")({responseText: strip_scripts(responseText)}))
         }
 
         $("#xos-error-dialog").dialog({
@@ -400,6 +417,8 @@ XOSApplication = Marionette.Application.extend({
             that.destroyModel(model);
             if (afterDelete=="list") {
                 that.navigate("list", modelName);
+            } else if (afterDelete) {
+                afterDelete();
             }
         });
     },
@@ -465,7 +484,7 @@ XOSDetailView = Marionette.ItemView.extend({
             */
 
             initialize: function() {
-                this.on("saveSuccess", this.onAfterSave);
+                this.on("saveSuccess", this.onSaveSuccess);
                 this.synchronous = false;
             },
 
@@ -475,11 +494,20 @@ XOSDetailView = Marionette.ItemView.extend({
                 });
             },
 
+            saveSuccess: function(e) {
+                // always called after a save succeeds
+            },
+
             afterSave: function(e) {
+                // if this.synchronous, then called after the save succeeds
+                // if !this.synchronous, then called after save is initiated
             },
 
-            onAfterSave: function(e) {
-                this.afterSave(e);
+            onSaveSuccess: function(e) {
+                this.saveSuccess(e);
+                if (this.synchronous) {
+                    this.afterSave(e);
+                }
             },
 
             inputChanged: function(e) {
@@ -496,6 +524,9 @@ XOSDetailView = Marionette.ItemView.extend({
             submitLeaveClicked: function(e) {
                 console.log("saveLeave");
                 e.preventDefault();
+                if (this.options.noSubmitButton || this.noSubmitButton) {
+                    return;
+                }
                 var that=this;
                 this.afterSave = function() {
                     that.app.navigate("list", that.model.modelName);
@@ -517,7 +548,7 @@ XOSDetailView = Marionette.ItemView.extend({
 
             save: function() {
                 this.app.hideError();
-                var data = Backbone.Syphon.serialize(this);
+                var data = Backbone_Syphon.serialize(this);
                 var that = this;
                 var isNew = !this.model.id;
 
@@ -546,9 +577,7 @@ XOSDetailView = Marionette.ItemView.extend({
 
                 this.model.save(data, {error: function(model, result, xhr) { that.app.saveError(model,result,xhr,infoMsgId);},
                                        success: function(model, result, xhr) { that.app.saveSuccess(model,result,xhr,infoMsgId);
-                                                                               if (that.synchronous) {
-                                                                                   that.trigger("saveSuccess");
-                                                                               }
+                                                                               that.trigger("saveSuccess");
                                                                              }});
                 this.dirty = false;
 
@@ -645,18 +674,20 @@ XOSDetailView = Marionette.ItemView.extend({
                                                     addFields: this.model.addFields,
                                                     listFields: this.model.listFields,
                                                     detailFields: this.options.detailFields || this.detailFields || this.model.detailFields,
+                                                    fieldDisplayNames: this.options.fieldDisplayNames || this.fieldDisplayNames || this.model.fieldDisplayNames || {},
                                                     foreignFields: this.model.foreignFields,
                                                     detailLinkFields: this.model.detailLinkFields,
                                                     inputType: this.model.inputType,
                                                     model: this.model,
                                                     detailView: this,
                                                     choices: this.options.choices || this.choices || this.model.choices || {},
+                                                    helpText: this.options.helpText || this.helpText || this.model.helpText || {},
                                          }},
 });
 
 XOSDetailView_sliver = XOSDetailView.extend( {
     events: $.extend(XOSDetailView.events,
-        {"change #field_deploymentNetwork": "onDeploymentNetworkChange"}
+        {"change #field_deployment": "onDeploymentChange"}
     ),
 
     onShow: function() {
@@ -664,16 +695,23 @@ XOSDetailView_sliver = XOSDetailView.extend( {
         // first time was when the template was originally invoked, and the
         // selects will all have the full unfiltered set of candidates. Then
         // onShow will fire, and we'll update them with the filtered values.
-        this.onDeploymentNetworkChange();
+        this.onDeploymentChange();
     },
 
-    onDeploymentNetworkChange: function(e) {
-        var deploymentID = this.$el.find("#field_deploymentNetwork").val();
+    onDeploymentChange: function(e) {
+        var deploymentID = this.$el.find("#field_deployment").val();
 
-        console.log("onDeploymentNetworkChange");
-        console.log(deploymentID);
+        //console.log("onDeploymentChange");
 
-        filterFunc = function(model) { return (model.attributes.deployment==deploymentID); }
+        filterFunc = function(model) { for (index in xos.siteDeployments.models) {
+                                           site_deployment = xos.siteDeployments.models[index];
+                                           if (site_deployment.attributes.id == model.attributes.site_deployment) {
+                                               return (site_deployment.attributes.deployment == deploymentID);
+                                           }
+                                        }
+                                        return false;
+                                        // return (model.attributes.deployment==deploymentID); }
+                                      };
         newSelect = idToSelect("node",
                                this.model.attributes.node,
                                this.model.foreignFields["node"],
@@ -683,8 +721,7 @@ XOSDetailView_sliver = XOSDetailView.extend( {
         this.$el.find("#field_node").html(newSelect);
 
         filterFunc = function(model) { for (index in model.attributes.deployments) {
-                                          item=model.attributes.deployments[index];
-                                          if (item.toString()==deploymentID.toString()) return true;
+                                          if (model.attributes.deployments[index] == deploymentID) return true;
                                         };
                                         return false;
                                      }
@@ -696,12 +733,9 @@ XOSDetailView_sliver = XOSDetailView.extend( {
                                filterFunc);
         this.$el.find("#field_flavor").html(newSelect);
 
-        filterFunc = function(model) { for (index in xos.imageDeployments.models) {
-                                           imageDeployment = xos.imageDeployments.models[index];
-                                           if ((imageDeployment.attributes.deployment == deploymentID) && (imageDeployment.attributes.image == model.id)) {
-                                               return true;
-                                           }
-                                       }
+        filterFunc = function(model) { for (index in model.attributes.deployments) {
+                                           if (model.attributes.deployments[index] == deploymentID) return true;
+                                       };
                                        return false;
                                      };
         newSelect = idToSelect("image",
@@ -861,6 +895,7 @@ XOSDataTableView = Marionette.View.extend( {
 
     render: function() {
         var view = this;
+        var fieldDisplayNames = view.options.fieldDisplayNames || view.fieldDisplayNames || {};
 
         view.columnsByIndex = [];
         view.columnsByFieldName = {};
@@ -868,7 +903,7 @@ XOSDataTableView = Marionette.View.extend( {
             inputType = view.options.inputType || view.inputType || {};
             mRender = undefined;
             mSearchText = undefined;
-            sTitle = fieldNameToHumanReadable(fieldName);
+            sTitle = fieldName in fieldDisplayNames ? fieldDisplayNames[fieldName] : fieldNameToHumanReadable(fieldName);
             bSortable = true;
             if (fieldName=="backend_status") {
                 mRender = function(x,y,z) { return xosBackendStatusIconTemplate(z); };
@@ -899,6 +934,8 @@ XOSDataTableView = Marionette.View.extend( {
             "bJQueryUI": true,
             "bStateSave": true,
             "bServerSide": true,
+            "bFilter": ! (view.options.disableFilter || view.disableFilter),
+            "bPaginate": ! (view.options.disablePaginate || view.disablePaginate),
             "aoColumns": view.columnsByIndex,
 
             fnServerData: function(sSource, aoData, fnCallback, settings) {
@@ -991,7 +1028,9 @@ XOSDataTableView = Marionette.View.extend( {
                   aaData.sort(function(a,b) { return compareColumns(sortCols, sortDirs, a, b); });\r
 \r
                   // slice it for pagination\r
-                  aaData = aaData.slice(iDisplayStart, iDisplayStart+iDisplayLength);\r
+                  if (iDisplayLength >= 0) {\r
+                      aaData = aaData.slice(iDisplayStart, iDisplayStart+iDisplayLength);\r
+                  }\r
 \r
                   return fnCallback({iTotalRecords: totalSize,\r
                          iTotalDisplayRecords: filteredSize,\r