blob: 000e8038f670f575aa0ffbe18d139cd7e5a56a5d [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");
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}