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