| Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame^] | 1 | "use strict"; | 
 | 2 |  | 
 | 3 | function layerDetailsPageInit (ctx) { | 
 | 4 |  | 
 | 5 |   var layerDepInput = $("#layer-dep-input"); | 
 | 6 |   var layerDepBtn = $("#add-layer-dependency-btn"); | 
 | 7 |   var layerDepsList = $("#layer-deps-list"); | 
 | 8 |   var currentLayerDepSelection; | 
 | 9 |   var addRmLayerBtn = $("#add-remove-layer-btn"); | 
 | 10 |  | 
 | 11 |   /* setup the dependencies typeahead */ | 
 | 12 |   libtoaster.makeTypeahead(layerDepInput, libtoaster.ctx.layersTypeAheadUrl, { include_added: "true" }, function(item){ | 
 | 13 |     currentLayerDepSelection = item; | 
 | 14 |  | 
 | 15 |     layerDepBtn.removeAttr("disabled"); | 
 | 16 |   }); | 
 | 17 |  | 
 | 18 |   $(".breadcrumb li:first a").click(function(e){ | 
 | 19 |     e.preventDefault(); | 
 | 20 |     /* By default this link goes to the project configuration page. However | 
 | 21 |      * if we have some builds we go there instead of the default href | 
 | 22 |      */ | 
 | 23 |     libtoaster.getProjectInfo(libtoaster.ctx.projectPageUrl, function(prjInfo){ | 
 | 24 |       if (prjInfo.builds && prjInfo.builds.length > 0) { | 
 | 25 |         window.location.replace(libtoaster.ctx.projectBuildsUrl); | 
 | 26 |       } else { | 
 | 27 |         window.location.replace(libtoaster.ctx.projectPageUrl); | 
 | 28 |       } | 
 | 29 |     }); | 
 | 30 |   }); | 
 | 31 |  | 
 | 32 |   function addRemoveDep(depLayerId, add, doneCb) { | 
 | 33 |     var data = { layer_version_id : ctx.layerVersion.id }; | 
 | 34 |     if (add) | 
 | 35 |       data.add_dep = depLayerId; | 
 | 36 |     else | 
 | 37 |       data.rm_dep = depLayerId; | 
 | 38 |  | 
 | 39 |     $.ajax({ | 
 | 40 |         type: "POST", | 
 | 41 |         url: ctx.xhrUpdateLayerUrl, | 
 | 42 |         data: data, | 
 | 43 |         headers: { 'X-CSRFToken' : $.cookie('csrftoken')}, | 
 | 44 |         success: function (data) { | 
 | 45 |           if (data.error != "ok") { | 
 | 46 |             console.warn(data.error); | 
 | 47 |           } else { | 
 | 48 |             doneCb(); | 
 | 49 |           } | 
 | 50 |         }, | 
 | 51 |         error: function (data) { | 
 | 52 |           console.warn("Call failed"); | 
 | 53 |           console.warn(data); | 
 | 54 |         } | 
 | 55 |     }); | 
 | 56 |   } | 
 | 57 |  | 
 | 58 |   function layerDepRemoveClick() { | 
 | 59 |     var toRemove = $(this).parent().data('layer-id'); | 
 | 60 |     var layerDepItem = $(this); | 
 | 61 |  | 
 | 62 |     addRemoveDep(toRemove, false, function(){ | 
 | 63 |       layerDepItem.parent().fadeOut(function (){ | 
 | 64 |         layerDepItem.remove(); | 
 | 65 |       }); | 
 | 66 |     }); | 
 | 67 |   } | 
 | 68 |  | 
 | 69 |   /* Add dependency layer button click handler */ | 
 | 70 |   layerDepBtn.click(function(){ | 
 | 71 |     if (currentLayerDepSelection === undefined) | 
 | 72 |       return; | 
 | 73 |  | 
 | 74 |     addRemoveDep(currentLayerDepSelection.id, true, function(){ | 
 | 75 |       /* Make a list item for the new layer dependency */ | 
 | 76 |       var newLayerDep = $("<li><a></a><span class=\"icon-trash\" data-toggle=\"tooltip\" title=\"Delete\"></span></li>"); | 
 | 77 |  | 
 | 78 |       newLayerDep.data('layer-id', currentLayerDepSelection.id); | 
 | 79 |       newLayerDep.children("span").tooltip(); | 
 | 80 |  | 
 | 81 |       var link = newLayerDep.children("a"); | 
 | 82 |       link.attr("href", currentLayerDepSelection.layerdetailurl); | 
 | 83 |       link.text(currentLayerDepSelection.name); | 
 | 84 |       link.tooltip({title: currentLayerDepSelection.tooltip, placement: "right"}); | 
 | 85 |  | 
 | 86 |       /* Connect up the tash icon */ | 
 | 87 |       var trashItem = newLayerDep.children("span"); | 
 | 88 |       trashItem.click(layerDepRemoveClick); | 
 | 89 |  | 
 | 90 |       layerDepsList.append(newLayerDep); | 
 | 91 |       /* Clear the current selection */ | 
 | 92 |       layerDepInput.val(""); | 
 | 93 |       currentLayerDepSelection = undefined; | 
 | 94 |       layerDepBtn.attr("disabled","disabled"); | 
 | 95 |     }); | 
 | 96 |   }); | 
 | 97 |  | 
 | 98 |   $(".icon-pencil").click(function (){ | 
 | 99 |     var mParent = $(this).parent("dd"); | 
 | 100 |     mParent.prev().css("margin-top", "10px"); | 
 | 101 |     mParent.children("form").slideDown(); | 
 | 102 |     var currentVal = mParent.children(".current-value"); | 
 | 103 |     currentVal.hide(); | 
 | 104 |     /* Set the current value to the input field */ | 
 | 105 |     mParent.find("textarea,input").val(currentVal.text()); | 
 | 106 |     /* Hides the "Not set" text */ | 
 | 107 |     mParent.children(".muted").hide(); | 
 | 108 |     /* We're editing so hide the delete icon */ | 
 | 109 |     mParent.children(".delete-current-value").hide(); | 
 | 110 |     mParent.find(".cancel").show(); | 
 | 111 |     $(this).hide(); | 
 | 112 |   }); | 
 | 113 |  | 
 | 114 |   $(".delete-current-value").click(function(){ | 
 | 115 |     var mParent = $(this).parent("dd"); | 
 | 116 |     mParent.find("input").val(""); | 
 | 117 |     mParent.find("textarea").val(""); | 
 | 118 |     mParent.find(".change-btn").click(); | 
 | 119 |   }); | 
 | 120 |  | 
 | 121 |   $(".cancel").click(function(){ | 
 | 122 |     var mParent = $(this).parents("dd"); | 
 | 123 |     $(this).hide(); | 
 | 124 |     mParent.children("form").slideUp(function(){ | 
 | 125 |       mParent.children(".current-value").show(); | 
 | 126 |       /* Show the "Not set" text if we ended up with no value */ | 
 | 127 |       if (!mParent.children(".current-value").html()){ | 
 | 128 |         mParent.children(".muted").fadeIn(); | 
 | 129 |         mParent.children(".delete-current-value").hide(); | 
 | 130 |       } else { | 
 | 131 |         mParent.children(".delete-current-value").show(); | 
 | 132 |       } | 
 | 133 |  | 
 | 134 |       mParent.children(".icon-pencil").show(); | 
 | 135 |       mParent.prev().css("margin-top", "0px"); | 
 | 136 |     }); | 
 | 137 |   }); | 
 | 138 |  | 
 | 139 |   function defaultAddBtnText(){ | 
 | 140 |       var text = " Add the "+ctx.layerVersion.name+" layer to your project"; | 
 | 141 |       addRmLayerBtn.text(text); | 
 | 142 |       addRmLayerBtn.prepend("<span class=\"icon-plus\"></span>"); | 
 | 143 |       addRmLayerBtn.removeClass("btn-danger"); | 
 | 144 |   } | 
 | 145 |  | 
 | 146 |   $("#details-tab").on('show', function(){ | 
 | 147 |     if (!ctx.layerVersion.inCurrentPrj) | 
 | 148 |       defaultAddBtnText(); | 
 | 149 |  | 
 | 150 |     window.location.hash = "details"; | 
 | 151 |   }); | 
 | 152 |  | 
 | 153 |   function targetsTabShow(){ | 
 | 154 |     if (!ctx.layerVersion.inCurrentPrj){ | 
 | 155 |       if (ctx.numTargets > 0) { | 
 | 156 |         var text = " Add the "+ctx.layerVersion.name+" layer to your project "+ | 
 | 157 |           "to enable these recipes"; | 
 | 158 |         addRmLayerBtn.text(text); | 
 | 159 |         addRmLayerBtn.prepend("<span class=\"icon-plus\"></span>"); | 
 | 160 |       } else { | 
 | 161 |         defaultAddBtnText(); | 
 | 162 |       } | 
 | 163 |     } | 
 | 164 |  | 
 | 165 |     window.location.hash = "recipes"; | 
 | 166 |   } | 
 | 167 |  | 
 | 168 |   $("#recipestable").on('table-done', function(e, total, tableParams){ | 
 | 169 |     ctx.numTargets = total; | 
 | 170 |  | 
 | 171 |     if (total === 0 && !tableParams.search) { | 
 | 172 |       $("#no-recipes-yet").show(); | 
 | 173 |     } else { | 
 | 174 |       $("#no-recipes-yet").hide(); | 
 | 175 |     } | 
 | 176 |  | 
 | 177 |     $("#targets-tab").removeClass("muted"); | 
 | 178 |     if (window.location.hash === "#recipes"){ | 
 | 179 |       /* re run the machinesTabShow to update the text */ | 
 | 180 |       targetsTabShow(); | 
 | 181 |     } | 
 | 182 |   }); | 
 | 183 |  | 
 | 184 |   $("#machinestable").on('table-done', function(e, total, tableParams){ | 
 | 185 |     ctx.numMachines = total; | 
 | 186 |  | 
 | 187 |     if (total === 0 && !tableParams.search) | 
 | 188 |       $("#no-machines-yet").show(); | 
 | 189 |     else | 
 | 190 |       $("#no-machines-yet").hide(); | 
 | 191 |  | 
 | 192 |     $("#machines-tab").removeClass("muted"); | 
 | 193 |     if (window.location.hash === "#machines"){ | 
 | 194 |       /* re run the machinesTabShow to update the text */ | 
 | 195 |       machinesTabShow(); | 
 | 196 |     } | 
 | 197 |  | 
 | 198 |     $(".select-machine-btn").click(function(e){ | 
 | 199 |       if ($(this).attr("disabled") === "disabled") | 
 | 200 |         e.preventDefault(); | 
 | 201 |     }); | 
 | 202 |  | 
 | 203 |   }); | 
 | 204 |  | 
 | 205 |   $("#targets-tab").on('show', targetsTabShow); | 
 | 206 |  | 
 | 207 |   function machinesTabShow(){ | 
 | 208 |     if (!ctx.layerVersion.inCurrentPrj) { | 
 | 209 |       if (ctx.numMachines > 0){ | 
 | 210 |         var text = " Add the "+ctx.layerVersion.name+" layer to your project " + | 
 | 211 |           "to enable these machines"; | 
 | 212 |         addRmLayerBtn.text(text); | 
 | 213 |         addRmLayerBtn.prepend("<span class=\"icon-plus\"></span>"); | 
 | 214 |       } else { | 
 | 215 |         defaultAddBtnText(); | 
 | 216 |       } | 
 | 217 |     } | 
 | 218 |  | 
 | 219 |     window.location.hash = "machines"; | 
 | 220 |   } | 
 | 221 |  | 
 | 222 |   $("#machines-tab").on('show', machinesTabShow); | 
 | 223 |  | 
 | 224 |   $(".pagesize").change(function(){ | 
 | 225 |     var search = libtoaster.parseUrlParams(); | 
 | 226 |     search.limit = this.value; | 
 | 227 |  | 
 | 228 |     window.location.search = libtoaster.dumpsUrlParams(search); | 
 | 229 |   }); | 
 | 230 |  | 
 | 231 |   /* Enables the Build target and Select Machine buttons and switches the | 
 | 232 |    * add/remove button | 
 | 233 |    */ | 
 | 234 |   function setLayerInCurrentPrj(added) { | 
 | 235 |     ctx.layerVersion.inCurrentPrj = added; | 
 | 236 |  | 
 | 237 |     if (added){ | 
 | 238 |       /* enable and switch all the button states */ | 
 | 239 |       $(".build-target-btn").removeAttr("disabled"); | 
 | 240 |       $(".select-machine-btn").removeAttr("disabled"); | 
 | 241 |       addRmLayerBtn.addClass("btn-danger"); | 
 | 242 |       addRmLayerBtn.data('directive', "remove"); | 
 | 243 |       addRmLayerBtn.text(" Delete the "+ctx.layerVersion.name+" layer from your project"); | 
 | 244 |       addRmLayerBtn.prepend("<span class=\"icon-trash\"></span>"); | 
 | 245 |  | 
 | 246 |     } else { | 
 | 247 |       /* disable and switch all the button states */ | 
 | 248 |       $(".build-target-btn").attr("disabled","disabled"); | 
 | 249 |       $(".select-machine-btn").attr("disabled", "disabled"); | 
 | 250 |       addRmLayerBtn.removeClass("btn-danger"); | 
 | 251 |       addRmLayerBtn.data('directive', "add"); | 
 | 252 |  | 
 | 253 |       /* "special" handler so that we get the correct button text which depends | 
 | 254 |        * on which tab is currently visible. Unfortunately we can't just call | 
 | 255 |        * tab('show') as if it's already visible it doesn't run the event. | 
 | 256 |        */ | 
 | 257 |       switch ($(".nav-pills .active a").prop('id')){ | 
 | 258 |         case 'machines-tab': | 
 | 259 |           machinesTabShow(); | 
 | 260 |           break; | 
 | 261 |         case 'targets-tab': | 
 | 262 |           targetsTabShow(); | 
 | 263 |           break; | 
 | 264 |         default: | 
 | 265 |           defaultAddBtnText(); | 
 | 266 |           break; | 
 | 267 |       } | 
 | 268 |     } | 
 | 269 |   } | 
 | 270 |  | 
 | 271 |   $("#dismiss-alert").click(function(){ | 
 | 272 |     $(this).parent().fadeOut(); | 
 | 273 |   }); | 
 | 274 |  | 
 | 275 |   /* Add or remove this layer from the project */ | 
 | 276 |   addRmLayerBtn.click(function() { | 
 | 277 |  | 
 | 278 |     var add = ($(this).data('directive') === "add"); | 
 | 279 |  | 
 | 280 |     libtoaster.addRmLayer(ctx.layerVersion, add, function (layersList){ | 
 | 281 |       var alertMsg = $("#alert-msg"); | 
 | 282 |       alertMsg.html(libtoaster.makeLayerAddRmAlertMsg(ctx.layerVersion, layersList, add)); | 
 | 283 |  | 
 | 284 |       setLayerInCurrentPrj(add); | 
 | 285 |  | 
 | 286 |       $("#alert-area").show(); | 
 | 287 |     }); | 
 | 288 |   }); | 
 | 289 |  | 
 | 290 |   /* Handler for all of the Change buttons */ | 
 | 291 |   $(".change-btn").click(function(){ | 
 | 292 |     var mParent = $(this).parent(); | 
 | 293 |     var prop = $(this).data('layer-prop'); | 
 | 294 |  | 
 | 295 |     /* We have inputs, select and textareas to potentially grab the value | 
 | 296 |      * from. | 
 | 297 |      */ | 
 | 298 |     var entryElement = mParent.find("input"); | 
 | 299 |     if (entryElement.length === 0) | 
 | 300 |       entryElement = mParent.find("textarea"); | 
 | 301 |     if (entryElement.length === 0) { | 
 | 302 |       console.warn("Could not find element to get data from for this change"); | 
 | 303 |       return; | 
 | 304 |     } | 
 | 305 |  | 
 | 306 |     var data = { layer_version_id: ctx.layerVersion.id }; | 
 | 307 |     data[prop] = entryElement.val(); | 
 | 308 |  | 
 | 309 |     $.ajax({ | 
 | 310 |         type: "POST", | 
 | 311 |         url: ctx.xhrUpdateLayerUrl, | 
 | 312 |         data: data, | 
 | 313 |         headers: { 'X-CSRFToken' : $.cookie('csrftoken')}, | 
 | 314 |         success: function (data) { | 
 | 315 |           if (data.error != "ok") { | 
 | 316 |             console.warn(data.error); | 
 | 317 |           } else { | 
 | 318 |             /* success layer property changed */ | 
 | 319 |             var inputArea = mParent.parents("dd"); | 
 | 320 |             var text; | 
 | 321 |  | 
 | 322 |             text = entryElement.val(); | 
 | 323 |  | 
 | 324 |             /* Hide the "Not set" text if it's visible */ | 
 | 325 |             inputArea.find(".muted").hide(); | 
 | 326 |             inputArea.find(".current-value").text(text); | 
 | 327 |             /* Same behaviour as cancel in that we hide the form/show current | 
 | 328 |              * value. | 
 | 329 |              */ | 
 | 330 |             inputArea.find(".cancel").click(); | 
 | 331 |           } | 
 | 332 |         }, | 
 | 333 |         error: function (data) { | 
 | 334 |           console.warn("Call failed"); | 
 | 335 |           console.warn(data); | 
 | 336 |         } | 
 | 337 |     }); | 
 | 338 |   }); | 
 | 339 |  | 
 | 340 |   /* Disable the change button when we have no data in the input */ | 
 | 341 |   $("dl input, dl textarea").on("input",function() { | 
 | 342 |     if ($(this).val().length === 0) | 
 | 343 |       $(this).parent().children(".change-btn").attr("disabled", "disabled"); | 
 | 344 |     else | 
 | 345 |       $(this).parent().children(".change-btn").removeAttr("disabled"); | 
 | 346 |   }); | 
 | 347 |  | 
 | 348 |   /* This checks to see if the dt's dd has data in it or if the change data | 
 | 349 |    * form is visible, otherwise hide it | 
 | 350 |    */ | 
 | 351 |   $("dl").children().each(function (){ | 
 | 352 |     if ($(this).is("dt")) { | 
 | 353 |       var dd = $(this).next("dd"); | 
 | 354 |       if (!dd.children("form:visible")|| !dd.find(".current-value").html()){ | 
 | 355 |         if (ctx.layerVersion.sourceId == 3){ | 
 | 356 |         /* There's no current value and the layer is editable | 
 | 357 |          * so show the "Not set" and hide the delete icon | 
 | 358 |          */ | 
 | 359 |         dd.find(".muted").show(); | 
 | 360 |         dd.find(".delete-current-value").hide(); | 
 | 361 |         } else { | 
 | 362 |           /* We're not viewing an editable layer so hide the empty dd/dl pair */ | 
 | 363 |           $(this).hide(); | 
 | 364 |           dd.hide(); | 
 | 365 |         } | 
 | 366 |       } | 
 | 367 |     } | 
 | 368 |   }); | 
 | 369 |  | 
 | 370 |   /* Hide the right column if it contains no information */ | 
 | 371 |   if ($("dl.item-info").children(':visible').length === 0) { | 
 | 372 |     $("dl.item-info").parent().hide(); | 
 | 373 |   } | 
 | 374 |  | 
 | 375 |   /* Clear the current search selection and reload the results */ | 
 | 376 |   $(".target-search-clear").click(function(){ | 
 | 377 |     $("#target-search").val(""); | 
 | 378 |     $(this).parents("form").submit(); | 
 | 379 |   }); | 
 | 380 |  | 
 | 381 |   $(".machine-search-clear").click(function(){ | 
 | 382 |     $("#machine-search").val(""); | 
 | 383 |     $(this).parents("form").submit(); | 
 | 384 |   }); | 
 | 385 |  | 
 | 386 |  | 
 | 387 |   layerDepsList.find(".icon-trash").click(layerDepRemoveClick); | 
 | 388 |   layerDepsList.find("a").tooltip(); | 
 | 389 |   $(".icon-trash").tooltip(); | 
 | 390 |   $(".commit").tooltip(); | 
 | 391 |  | 
 | 392 | } |