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