summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bitbake/lib/toaster/toastergui/static/css/default.css2
-rw-r--r--bitbake/lib/toaster/toastergui/static/html/layer_deps_modal.html17
-rw-r--r--bitbake/lib/toaster/toastergui/static/js/importlayer.js8
-rw-r--r--bitbake/lib/toaster/toastergui/static/js/layerBtn.js63
-rw-r--r--bitbake/lib/toaster/toastergui/static/js/layerDepsModal.js90
-rw-r--r--bitbake/lib/toaster/toastergui/static/js/layerdetails.js90
-rw-r--r--bitbake/lib/toaster/toastergui/static/js/libtoaster.js79
-rw-r--r--bitbake/lib/toaster/toastergui/static/js/machines.js95
-rw-r--r--bitbake/lib/toaster/toastergui/static/js/projectapp.js9
-rw-r--r--bitbake/lib/toaster/toastergui/templates/base.html2
-rw-r--r--bitbake/lib/toaster/toastergui/templates/importlayer.html2
-rw-r--r--bitbake/lib/toaster/toastergui/templates/layerdetails.html4
-rw-r--r--bitbake/lib/toaster/toastergui/templates/layers.html223
-rw-r--r--bitbake/lib/toaster/toastergui/templates/layers_dep_modal.html99
-rw-r--r--bitbake/lib/toaster/toastergui/templates/machines.html31
-rw-r--r--bitbake/lib/toaster/toastergui/templates/targets.html220
-rwxr-xr-xbitbake/lib/toaster/toastergui/views.py2
17 files changed, 361 insertions, 675 deletions
diff --git a/bitbake/lib/toaster/toastergui/static/css/default.css b/bitbake/lib/toaster/toastergui/static/css/default.css
index 7ee1251529..bc3d63e6b9 100644
--- a/bitbake/lib/toaster/toastergui/static/css/default.css
+++ b/bitbake/lib/toaster/toastergui/static/css/default.css
@@ -158,7 +158,7 @@ select { width: auto; }
158.project-name .label > a { color: #fff; font-weight: normal; } 158.project-name .label > a { color: #fff; font-weight: normal; }
159 159
160/* Remove bottom margin for forms inside modal dialogs */ 160/* Remove bottom margin for forms inside modal dialogs */
161#dependencies_modal_form { margin-bottom: 0px; } 161#dependencies-modal-form { margin-bottom: 0px; }
162 162
163/* Configuration styles */ 163/* Configuration styles */
164.icon-trash { color: #B94A48; font-size: 16px; padding-left: 5px; } 164.icon-trash { color: #B94A48; font-size: 16px; padding-left: 5px; }
diff --git a/bitbake/lib/toaster/toastergui/static/html/layer_deps_modal.html b/bitbake/lib/toaster/toastergui/static/html/layer_deps_modal.html
new file mode 100644
index 0000000000..e1dba4358d
--- /dev/null
+++ b/bitbake/lib/toaster/toastergui/static/html/layer_deps_modal.html
@@ -0,0 +1,17 @@
1<div id="dependencies-modal" class="modal hide fade" tabindex="-1" role="dialog" aria-hidden="false">
2 <form id="dependencies-modal-form">
3 <div class="modal-header">
4 <button type="button" class="close" data-dismiss="modal" aria-hidden="true">x</button>
5 <h3><span id="title"></span> dependencies</h3>
6 </div>
7 <div class="modal-body">
8 <p id="body-text"> <strong id="layer-name"></strong> depends on some layers that are not added to your project. Select the ones you want to add:</p>
9 <ul class="unstyled" id="dependencies-list">
10 </ul>
11 </div>
12 <div class="modal-footer">
13 <button class="btn btn-primary" type="submit">Add layers</button>
14 <button class="btn" type="reset" data-dismiss="modal">Cancel</button>
15 </div>
16 </form>
17</div>
diff --git a/bitbake/lib/toaster/toastergui/static/js/importlayer.js b/bitbake/lib/toaster/toastergui/static/js/importlayer.js
index ec1cc19e90..875cc342b8 100644
--- a/bitbake/lib/toaster/toastergui/static/js/importlayer.js
+++ b/bitbake/lib/toaster/toastergui/static/js/importlayer.js
@@ -117,10 +117,10 @@ function importLayerPageInit (ctx) {
117 var body = "<strong>"+layer.name+"</strong>'s dependencies ("+ 117 var body = "<strong>"+layer.name+"</strong>'s dependencies ("+
118 depNames.join(", ")+"</span>) require some layers that are not added to your project. Select the ones you want to add:</p>"; 118 depNames.join(", ")+"</span>) require some layers that are not added to your project. Select the ones you want to add:</p>";
119 119
120 show_layer_deps_modal(ctx.projectId, layer, depDepsArray, title, body, false, function(selected){ 120 showLayerDepsModal(layer, depDepsArray, title, body, false, function(layerObsList){
121 /* Add the accepted dependencies to the allDeps array */ 121 /* Add the accepted layer dependencies' ids to the allDeps array */
122 if (selected.length > 0){ 122 for (var key in layerObsList){
123 allDeps = allDeps.concat (selected); 123 allDeps.push(layerObsList[key].id);
124 } 124 }
125 import_and_add (); 125 import_and_add ();
126 }); 126 });
diff --git a/bitbake/lib/toaster/toastergui/static/js/layerBtn.js b/bitbake/lib/toaster/toastergui/static/js/layerBtn.js
new file mode 100644
index 0000000000..6a1d4b1606
--- /dev/null
+++ b/bitbake/lib/toaster/toastergui/static/js/layerBtn.js
@@ -0,0 +1,63 @@
1"use strict";
2
3function layerBtnsInit(ctx) {
4
5 $(".layerbtn").click(function (){
6 var layerObj = $(this).data("layer");
7 var add = ($(this).data('directive') === "add");
8 var thisBtn = $(this);
9
10 libtoaster.addRmLayer(layerObj, add, function (layerDepsList){
11 var alertMsg = $("#alert-msg");
12 alertMsg.html(libtoaster.makeLayerAddRmAlertMsg(layerObj, layerDepsList, add));
13
14 /* In-cell notification */
15 var notification = $('<div id="temp-inline-notify" style="display: none; font-size: 11px; line-height: 1.3;" class="tooltip-inner"></div>');
16 thisBtn.parent().append(notification);
17
18 if (add){
19 if (layerDepsList.length > 0)
20 notification.text(String(layerDepsList.length + 1) + " layers added");
21 else
22 notification.text("1 layer added");
23
24 var layerBtnsFadeOut = $();
25 var layerExistsBtnFadeIn = $();
26
27 layerBtnsFadeOut = layerBtnsFadeOut.add(".layer-add-" + layerObj.id);
28 layerExistsBtnFadeIn = layerExistsBtnFadeIn.add(".layer-exists-" + layerObj.id);
29
30 for (var i in layerDepsList){
31 layerBtnsFadeOut = layerBtnsFadeOut.add(".layer-add-" + layerDepsList[i].id);
32 layerExistsBtnFadeIn = layerExistsBtnFadeIn.add(".layer-exists-" + layerDepsList[i].id);
33 }
34
35 layerBtnsFadeOut.fadeOut().promise().done(function(){
36 notification.fadeIn().delay(500).fadeOut(function(){
37 /* Fade in the buttons */
38 layerExistsBtnFadeIn.fadeIn();
39 notification.remove();
40 });
41 });
42 } else {
43 notification.text("1 layer deleted");
44 /* Deleting a layer we only hanlde the one button */
45 thisBtn.fadeOut(function(){
46 notification.fadeIn().delay(500).fadeOut(function(){
47 $(".layer-add-" + layerObj.id).fadeIn();
48 notification.remove();
49 });
50 });
51 }
52
53 $("#zone1alerts, #zone1alerts *").fadeIn();
54 });
55 });
56
57 /* Setup the initial state of the buttons */
58
59 for (var i in ctx.projectLayers){
60 $(".layer-exists-" + ctx.projectLayers[i]).show();
61 $(".layer-add-" + ctx.projectLayers[i]).hide();
62 }
63}
diff --git a/bitbake/lib/toaster/toastergui/static/js/layerDepsModal.js b/bitbake/lib/toaster/toastergui/static/js/layerDepsModal.js
new file mode 100644
index 0000000000..825f9dccd5
--- /dev/null
+++ b/bitbake/lib/toaster/toastergui/static/js/layerDepsModal.js
@@ -0,0 +1,90 @@
1/*
2 * layer: Object representing the parent layer { id: .. name: ... url }
3 * dependencies: array of dependency layer objects { id: .. name: ..}
4 * title: optional override for title
5 * body: optional override for body
6 * addToProject: Whether to add layers to project on accept
7 * successAdd: function to run on success
8 */
9function showLayerDepsModal(layer, dependencies, title, body, addToProject, successAdd) {
10
11 if ($("#dependencies-modal").length === 0) {
12 $.get(libtoaster.ctx.htmlUrl + "/layer_deps_modal.html", function(html){
13 $("body").append(html);
14 setupModal();
15 });
16 } else {
17 setupModal();
18 }
19
20 function setupModal(){
21
22 if (title) {
23 $('#dependencies-modal #title').text(title);
24 } else {
25 $('#dependencies-modal #title').text(layer.name);
26 }
27
28 if (body) {
29 $("#dependencies-modal #body-text").html(body);
30 } else {
31 $("#dependencies-modal #layer-name").text(layer.name);
32 }
33
34 var deplistHtml = "";
35 for (var i = 0; i < dependencies.length; i++) {
36 deplistHtml += "<li><label class=\"checkbox\"><input name=\"dependencies\" value=\"";
37 deplistHtml += dependencies[i].id;
38 deplistHtml +="\" type=\"checkbox\" checked=\"checked\"/>";
39 deplistHtml += dependencies[i].name;
40 deplistHtml += "</label></li>";
41 }
42 $('#dependencies-list').html(deplistHtml);
43
44 $("#dependencies-modal").data("deps", dependencies);
45
46 $('#dependencies-modal').modal('show');
47
48 /* Discard the old submission function */
49 $("#dependencies-modal-form").unbind('submit');
50
51 $("#dependencies-modal-form").submit(function (e) {
52 e.preventDefault();
53 var selectedLayerIds = [];
54 var selectedLayers = [];
55
56 $("input[name='dependencies']:checked").each(function () {
57 selectedLayerIds.push(parseInt($(this).val()));
58 });
59
60 /* -1 is a special dummy Id which we use when the layer isn't yet in the
61 * system, normally we would add the current layer to the selection.
62 */
63 if (layer.id != -1)
64 selectedLayerIds.push(layer.id);
65
66 /* Find the selected layer objects from our original list */
67 for (var i = 0; i < selectedLayerIds.length; i++) {
68 for (var j = 0; j < dependencies.length; j++) {
69 if (dependencies[j].id == selectedLayerIds[i]) {
70 selectedLayers.push(dependencies[j]);
71 }
72 }
73 }
74
75 if (addToProject) {
76 libtoaster.editCurrentProject({ 'layerAdd': selectedLayerIds.join(",") }, function () {
77 if (successAdd) {
78 successAdd(selectedLayers);
79 }
80 }, function () {
81 console.warn("Adding layers to project failed");
82 });
83 } else {
84 successAdd(selectedLayers);
85 }
86
87 $('#dependencies-modal').modal('hide');
88 });
89 }
90}
diff --git a/bitbake/lib/toaster/toastergui/static/js/layerdetails.js b/bitbake/lib/toaster/toastergui/static/js/layerdetails.js
index 3b6423f7f4..3c4d632563 100644
--- a/bitbake/lib/toaster/toastergui/static/js/layerdetails.js
+++ b/bitbake/lib/toaster/toastergui/static/js/layerdetails.js
@@ -41,7 +41,7 @@ function layerDetailsPageInit (ctx) {
41 }); 41 });
42 } 42 }
43 43
44 function layerRemoveClick() { 44 function layerDepRemoveClick() {
45 var toRemove = $(this).parent().data('layer-id'); 45 var toRemove = $(this).parent().data('layer-id');
46 var layerDepItem = $(this); 46 var layerDepItem = $(this);
47 47
@@ -71,7 +71,7 @@ function layerDetailsPageInit (ctx) {
71 71
72 /* Connect up the tash icon */ 72 /* Connect up the tash icon */
73 var trashItem = newLayerDep.children("span"); 73 var trashItem = newLayerDep.children("span");
74 trashItem.click(layerRemoveClick); 74 trashItem.click(layerDepRemoveClick);
75 75
76 layerDepsList.append(newLayerDep); 76 layerDepsList.append(newLayerDep);
77 /* Clear the current selection */ 77 /* Clear the current selection */
@@ -129,13 +129,6 @@ function layerDetailsPageInit (ctx) {
129 window.location.replace(libtoaster.ctx.projectPageUrl); 129 window.location.replace(libtoaster.ctx.projectPageUrl);
130 }); 130 });
131 131
132 $(".select-machine-btn").click(function(){
133 var data = { machineName : $(this).data('machine-name') };
134 libtoaster.editCurrentProject(data, function (){
135 window.location.replace(libtoaster.ctx.projectPageUrl+"#/machineselected");
136 }, null);
137 });
138
139 function defaultAddBtnText(){ 132 function defaultAddBtnText(){
140 var text = " Add the "+ctx.layerVersion.name+" layer to your project"; 133 var text = " Add the "+ctx.layerVersion.name+" layer to your project";
141 addRmLayerBtn.text(text); 134 addRmLayerBtn.text(text);
@@ -196,9 +189,6 @@ function layerDetailsPageInit (ctx) {
196 */ 189 */
197 function setLayerInCurrentPrj(added, depsList) { 190 function setLayerInCurrentPrj(added, depsList) {
198 ctx.layerVersion.inCurrentPrj = added; 191 ctx.layerVersion.inCurrentPrj = added;
199 var alertMsg = $("#alert-msg");
200 /* Reset alert message */
201 alertMsg.text("");
202 192
203 if (added){ 193 if (added){
204 /* enable and switch all the button states */ 194 /* enable and switch all the button states */
@@ -209,25 +199,6 @@ function layerDetailsPageInit (ctx) {
209 addRmLayerBtn.text(" Delete the "+ctx.layerVersion.name+" layer from your project"); 199 addRmLayerBtn.text(" Delete the "+ctx.layerVersion.name+" layer from your project");
210 addRmLayerBtn.prepend("<span class=\"icon-trash\"></span>"); 200 addRmLayerBtn.prepend("<span class=\"icon-trash\"></span>");
211 201
212 if (depsList) {
213 alertMsg.append("You have added <strong>"+(depsList.length+1)+"</strong> layers to <a id=\"project-affected-name\"></a>: <span id=\"layer-affected-name\"></span> and its dependencies ");
214
215 /* Build the layer deps list */
216 depsList.map(function(layer, i){
217 var link = $("<a></a>");
218
219 link.attr("href", layer.layerdetailurl);
220 link.text(layer.name);
221 link.tooltip({title: layer.tooltip});
222
223 if (i != 0)
224 alertMsg.append(", ");
225
226 alertMsg.append(link);
227 });
228 } else {
229 alertMsg.append("You have added <strong>1</strong> layer to <a id=\"project-affected-name\"></a>: <span id=\"layer-affected-name\"></span>");
230 }
231 } else { 202 } else {
232 /* disable and switch all the button states */ 203 /* disable and switch all the button states */
233 $(".build-target-btn").attr("disabled","disabled"); 204 $(".build-target-btn").attr("disabled","disabled");
@@ -250,53 +221,24 @@ function layerDetailsPageInit (ctx) {
250 defaultAddBtnText(); 221 defaultAddBtnText();
251 break; 222 break;
252 } 223 }
253
254 alertMsg.append("You have deleted <strong>1</strong> layer from <a id=\"project-affected-name\"></a>: <strong id=\"layer-affected-name\"></strong>");
255 } 224 }
256
257 alertMsg.children("#layer-affected-name").text(ctx.layerVersion.name);
258 alertMsg.children("#project-affected-name").text(libtoaster.ctx.projectName);
259 alertMsg.children("#project-affected-name").attr("href", libtoaster.ctx.projectPageUrl);
260 $("#alert-area").show();
261 } 225 }
262 226
263 $("#dismiss-alert").click(function(){ $(this).parent().hide() }); 227 $("#dismiss-alert").click(function(){ $(this).parent().hide() });
264 228
265 /* Add or remove this layer from the project */ 229 /* Add or remove this layer from the project */
266 addRmLayerBtn.click(function() { 230 addRmLayerBtn.click(function() {
267 var directive = $(this).data('directive'); 231
268 232 var add = ($(this).data('directive') === "add")
269 if (directive == 'add') { 233
270 /* If adding get the deps for this layer */ 234 libtoaster.addRmLayer(ctx.layerVersion, add, function (layersList){
271 libtoaster.getLayerDepsForProject(libtoaster.ctx.projectId, ctx.layerVersion.id, function (data) { 235 var alertMsg = $("#alert-msg");
272 /* got result for dependencies */ 236 alertMsg.html(libtoaster.makeLayerAddRmAlertMsg(ctx.layerVersion, layersList, add));
273 if (data.list.length == 0){ 237
274 var editData = { layerAdd : ctx.layerVersion.id }; 238 setLayerInCurrentPrj(add, layersList);
275 libtoaster.editCurrentProject(editData, function() { 239
276 setLayerInCurrentPrj(true); 240 $("#alert-area").show();
277 }); 241 });
278 return;
279 } else {
280 /* The add deps will include this layer so no need to add it
281 * separately.
282 */
283 show_layer_deps_modal(ctx.projectId, ctx.layerVersion, data.list, null, null, true, function () {
284 /* Success add deps and layer */
285 setLayerInCurrentPrj(true, data.list);
286 });
287 }
288 }, null);
289 } else if (directive == 'remove') {
290 var editData = { layerDel : ctx.layerVersion.id };
291
292 libtoaster.editCurrentProject(editData, function () {
293 /* Success removed layer */
294 //window.location.reload();
295 setLayerInCurrentPrj(false);
296 }, function () {
297 console.warn ("Removing layer from project failed");
298 });
299 }
300 }); 242 });
301 243
302 /* Handler for all of the Change buttons */ 244 /* Handler for all of the Change buttons */
@@ -395,8 +337,12 @@ function layerDetailsPageInit (ctx) {
395 $(this).parents("form").submit(); 337 $(this).parents("form").submit();
396 }); 338 });
397 339
340 $(".select-machine-btn").click(function(e){
341 if ($(this).attr("disabled") === "disabled")
342 e.preventDefault();
343 });
398 344
399 layerDepsList.find(".icon-trash").click(layerRemoveClick); 345 layerDepsList.find(".icon-trash").click(layerDepRemoveClick);
400 layerDepsList.find("a").tooltip(); 346 layerDepsList.find("a").tooltip();
401 $(".icon-trash").tooltip(); 347 $(".icon-trash").tooltip();
402 $(".commit").tooltip(); 348 $(".commit").tooltip();
diff --git a/bitbake/lib/toaster/toastergui/static/js/libtoaster.js b/bitbake/lib/toaster/toastergui/static/js/libtoaster.js
index 9257f735db..1cf1693dde 100644
--- a/bitbake/lib/toaster/toastergui/static/js/libtoaster.js
+++ b/bitbake/lib/toaster/toastergui/static/js/libtoaster.js
@@ -114,7 +114,7 @@ var libtoaster = (function (){
114 error: function (_data) { 114 error: function (_data) {
115 console.warn("Call failed"); 115 console.warn("Call failed");
116 console.warn(_data); 116 console.warn(_data);
117 if (onfail) onfail(data); 117 if (onfail) onfail(_data);
118 } 118 }
119 }); 119 });
120 } 120 }
@@ -219,6 +219,76 @@ var libtoaster = (function (){
219 return str; 219 return str;
220 } 220 }
221 221
222 function _addRmLayer(layerObj, add, doneCb){
223 if (add === true) {
224 /* If adding get the deps for this layer */
225 libtoaster.getLayerDepsForProject(libtoaster.ctx.projectId,
226 layerObj.id,
227 function (layers) {
228
229 /* got result for dependencies */
230 if (layers.list.length === 0){
231 var editData = { layerAdd : layerObj.id };
232 libtoaster.editCurrentProject(editData, function() {
233 doneCb([]);
234 });
235 return;
236 } else {
237 try {
238 showLayerDepsModal(layerObj, layers.list, null, null, true, doneCb);
239 } catch (e) {
240 $.getScript(libtoaster.ctx.jsUrl + "layerDepsModal.js", function(){
241 showLayerDepsModal(layerObj, layers.list, null, null, true, doneCb);
242 }, function(){
243 console.warn("Failed to load layerDepsModal");
244 });
245 }
246 }
247 }, null);
248 } else if (add === false) {
249 var editData = { layerDel : layerObj.id };
250
251 libtoaster.editCurrentProject(editData, function () {
252 doneCb([]);
253 }, function () {
254 console.warn ("Removing layer from project failed");
255 doneCb(null);
256 });
257 }
258 }
259
260 function _makeLayerAddRmAlertMsg(layer, layerDepsList, add) {
261 var alertMsg;
262
263 if (layerDepsList.length > 0 && add === true) {
264 alertMsg = $("<span>You have added <strong>"+(layerDepsList.length+1)+"</strong> layers to <a id=\"project-affected-name\"></a>: <span id=\"layer-affected-name\"></span> and its dependencies </span>");
265
266 /* Build the layer deps list */
267 layerDepsList.map(function(layer, i){
268 var link = $("<a></a>");
269
270 link.attr("href", layer.layerdetailurl);
271 link.text(layer.name);
272 link.tooltip({title: layer.tooltip});
273
274 if (i !== 0)
275 alertMsg.append(", ");
276
277 alertMsg.append(link);
278 });
279 } else if (layerDepsList.length === 0 && add === true) {
280 alertMsg = $("<span>You have added <strong>1</strong> layer to <a id=\"project-affected-name\"></a>: <span id=\"layer-affected-name\"></span></span>");
281 } else if (add === false) {
282 alertMsg = $("<span>You have deleted <strong>1</strong> layer from <a id=\"project-affected-name\"></a>: <strong id=\"layer-affected-name\"></strong></span>");
283 }
284
285 alertMsg.children("#layer-affected-name").text(layer.name);
286 alertMsg.children("#project-affected-name").text(libtoaster.ctx.projectName);
287 alertMsg.children("#project-affected-name").attr("href", libtoaster.ctx.projectPageUrl);
288
289 return alertMsg.html();
290 }
291
222 292
223 return { 293 return {
224 reload_params : reload_params, 294 reload_params : reload_params,
@@ -231,6 +301,8 @@ var libtoaster = (function (){
231 debug: false, 301 debug: false,
232 parseUrlParams : _parseUrlParams, 302 parseUrlParams : _parseUrlParams,
233 dumpsUrlParams : _dumpsUrlParams, 303 dumpsUrlParams : _dumpsUrlParams,
304 addRmLayer : _addRmLayer,
305 makeLayerAddRmAlertMsg : _makeLayerAddRmAlertMsg,
234 }; 306 };
235})(); 307})();
236 308
@@ -394,6 +466,11 @@ $(document).ready(function() {
394 $('#collapse-exceptions').toggleClass('in'); 466 $('#collapse-exceptions').toggleClass('in');
395 }); 467 });
396 468
469
470 $("#hide-alert").click(function(){
471 $(this).parent().fadeOut();
472 });
473
397 //show warnings section when requested from the previous page 474 //show warnings section when requested from the previous page
398 if (location.href.search('#warnings') > -1) { 475 if (location.href.search('#warnings') > -1) {
399 $('#collapse-warnings').addClass('in'); 476 $('#collapse-warnings').addClass('in');
diff --git a/bitbake/lib/toaster/toastergui/static/js/machines.js b/bitbake/lib/toaster/toastergui/static/js/machines.js
deleted file mode 100644
index fbcafc26b5..0000000000
--- a/bitbake/lib/toaster/toastergui/static/js/machines.js
+++ /dev/null
@@ -1,95 +0,0 @@
1"use strict"
2
3function machinesPageInit (ctx) {
4
5
6 function setLayerInCurrentPrj(addLayerBtn, depsList){
7 var alertMsg = $("#alert-msg");
8
9 $(".select-or-add").each(function(){
10 /* If we have added a layer it may also enable other machines so search
11 * for other machines that have that layer and enable them */
12 var selectMachineBtn = $(this).children(".select-machine-btn");
13 var otherAddLayerBtns = $(this).children(".add-layer");
14
15 if (addLayerBtn.data('layer-version-id') == selectMachineBtn.data('layer-version-id')) {
16 otherAddLayerBtns.fadeOut(function(){
17 selectMachineBtn.fadeIn();
18 });
19 }
20 });
21
22 /* Reset alert message */
23 alertMsg.text("");
24
25 /* If we have added layer dependencies */
26 if (depsList) {
27 alertMsg.append("You have added <strong>"+(depsList.length+1)+"</strong> layers to <a id=\"project-affected-name\"></a>: <span id=\"layer-affected-name\"></span> and its dependencies ");
28
29 /* Build the layer deps list */
30 depsList.map(function(layer, i){
31 var link = $("<a></a>");
32
33 link.attr("href", layer.layerdetailurl);
34 link.text(layer.name);
35 link.tooltip({title: layer.tooltip});
36
37 if (i != 0)
38 alertMsg.append(", ");
39
40 alertMsg.append(link);
41 });
42 } else {
43 alertMsg.append("You have added <strong>1</strong> layer to <a id=\"project-affected-name\"></a>: <strong id=\"layer-affected-name\"></strong>");
44 }
45
46 var layerName = addLayerBtn.data('layer-name');
47 alertMsg.children("#layer-affected-name").text(layerName);
48 alertMsg.children("#project-affected-name").text(libtoaster.ctx.projectName).attr('href', libtoaster.ctx.projectPageUrl);
49
50 $("#alert-area").show();
51 }
52
53 $("#dismiss-alert").click(function(){ $(this).parent().hide() });
54
55 /* Add or remove this layer from the project */
56 $(".add-layer").click(function() {
57 var btn = $(this);
58 /* If adding get the deps for this layer */
59 var layer = {
60 id : $(this).data('layer-version-id'),
61 name : $(this).data('layer-name'),
62 };
63
64 libtoaster.getLayerDepsForProject(libtoaster.ctx.projectId, layer.id, function (data) {
65 /* got result for dependencies */
66 if (data.list.length == 0){
67 var editData = { layerAdd : layer.id };
68 libtoaster.editCurrentProject(editData, function() {
69 setLayerInCurrentPrj(btn);
70 });
71 return;
72 } else {
73 /* The add deps will include this layer so no need to add it
74 * separately.
75 */
76 show_layer_deps_modal(ctx.projectId, layer, data.list, null, null, true, function () {
77 /* Success add deps and layer */
78 setLayerInCurrentPrj(btn, data.list);
79 });
80 }
81 }, null);
82 });
83
84 $(".select-machine-btn").click(function(){
85 var data = { machineName : $(this).data('machine-name') };
86 libtoaster.editCurrentProject(data, function (){
87 window.location.replace(libtoaster.ctx.projectPageUrl+"#/machineselected");
88 }, null);
89 });
90
91 $("#show-all-btn").click(function(){
92 $("#search").val("")
93 $("#searchform").submit();
94 });
95}
diff --git a/bitbake/lib/toaster/toastergui/static/js/projectapp.js b/bitbake/lib/toaster/toastergui/static/js/projectapp.js
index 1fd4a54f57..43436c5e69 100644
--- a/bitbake/lib/toaster/toastergui/static/js/projectapp.js
+++ b/bitbake/lib/toaster/toastergui/static/js/projectapp.js
@@ -713,15 +713,6 @@ projectApp.controller('prjCtrl', function($scope, $modal, $http, $interval, $loc
713 "\">select recipes</a> you want to build.", "alert-success"); 713 "\">select recipes</a> you want to build.", "alert-success");
714 }); 714 });
715 715
716 _cmdExecuteWithParam("/machineselected", function () {
717 $scope.displayAlert($scope.zone2alerts, "You have changed the machine to: <strong>" + $scope.machine.name + "</strong>", "alert-info");
718 var machineDistro = angular.element("#machine-distro");
719
720 angular.element("html, body").animate({ scrollTop: machineDistro.position().top }, 700).promise().done(function() {
721 $animate.addClass(machineDistro, "machines-highlight");
722 });
723 });
724
725 _cmdExecuteWithParam("/layerimported", function () { 716 _cmdExecuteWithParam("/layerimported", function () {
726 var imported = $cookieStore.get("layer-imported-alert"); 717 var imported = $cookieStore.get("layer-imported-alert");
727 var text; 718 var text;
diff --git a/bitbake/lib/toaster/toastergui/templates/base.html b/bitbake/lib/toaster/toastergui/templates/base.html
index 25933a1e90..47bbbbda14 100644
--- a/bitbake/lib/toaster/toastergui/templates/base.html
+++ b/bitbake/lib/toaster/toastergui/templates/base.html
@@ -30,6 +30,8 @@
30 libtoaster.ctx = { 30 libtoaster.ctx = {
31 projectId : {{project.id|default:'undefined'}}, 31 projectId : {{project.id|default:'undefined'}},
32 xhrDataTypeaheadUrl : "{% url 'xhr_datatypeahead' %}", 32 xhrDataTypeaheadUrl : "{% url 'xhr_datatypeahead' %}",
33 jsUrl : "{% static 'js/' %}",
34 htmlUrl : "{% static 'html/' %}",
33 {% if project.id %} 35 {% if project.id %}
34 xhrProjectEditUrl : "{% url 'xhr_projectedit' project.id %}", 36 xhrProjectEditUrl : "{% url 'xhr_projectedit' project.id %}",
35 projectPageUrl : "{% url 'project' project.id %}", 37 projectPageUrl : "{% url 'project' project.id %}",
diff --git a/bitbake/lib/toaster/toastergui/templates/importlayer.html b/bitbake/lib/toaster/toastergui/templates/importlayer.html
index c92b5d8b24..ed03b2eea7 100644
--- a/bitbake/lib/toaster/toastergui/templates/importlayer.html
+++ b/bitbake/lib/toaster/toastergui/templates/importlayer.html
@@ -9,6 +9,7 @@
9 9
10{% block projectinfomain %} 10{% block projectinfomain %}
11 11
12 <script src="{% static 'js/layerDepsModal.js' %}"></script>
12 <script src="{% static 'js/importlayer.js' %}"></script> 13 <script src="{% static 'js/importlayer.js' %}"></script>
13 <script> 14 <script>
14 $(document).ready(function (){ 15 $(document).ready(function (){
@@ -30,7 +31,6 @@
30 <h1>Import layer</h1> 31 <h1>Import layer</h1>
31 </div> 32 </div>
32 33
33 {% include "layers_dep_modal.html" %}
34 <form> 34 <form>
35 {% if project %} 35 {% if project %}
36 <span class="help-block" style="padding-left:19px;">The layer you are importing must be compatible with <strong>{{project.release.description}}</strong>, which is the release you are using in this project.</span> 36 <span class="help-block" style="padding-left:19px;">The layer you are importing must be compatible with <strong>{{project.release.description}}</strong>, which is the release you are using in this project.</span>
diff --git a/bitbake/lib/toaster/toastergui/templates/layerdetails.html b/bitbake/lib/toaster/toastergui/templates/layerdetails.html
index 435bf04e42..4b27d052d0 100644
--- a/bitbake/lib/toaster/toastergui/templates/layerdetails.html
+++ b/bitbake/lib/toaster/toastergui/templates/layerdetails.html
@@ -58,7 +58,6 @@
58</style> 58</style>
59{% endif %} 59{% endif %}
60 60
61{% include "layers_dep_modal.html" %}
62 <div class="row-fluid span11"> 61 <div class="row-fluid span11">
63 <div class="page-header"> 62 <div class="page-header">
64 <h1>{{layerversion.layer.name}} <small class="commit" 63 <h1>{{layerversion.layer.name}} <small class="commit"
@@ -404,7 +403,8 @@
404 {% endif %} 403 {% endif %}
405 </td> 404 </td>
406 <td>{{machine.description}}</td> 405 <td>{{machine.description}}</td>
407 <td><button class="btn btn-block select-machine-btn" data-machine-name="{{machine.name}}" {% if layer_in_project == 0 %}disabled="disabled"{% endif %}}>Select machine</button></td> 406 <td>
407 <a href="{% url 'project' project.id %}#/machineselect={{machine.name}}" class="btn btn-block select-machine-btn" {% if layer_in_project == 0 %}disabled="disabled"{% endif %}>Select machine</a>
408 </tr> 408 </tr>
409 {% endfor %} 409 {% endfor %}
410 </tbody> 410 </tbody>
diff --git a/bitbake/lib/toaster/toastergui/templates/layers.html b/bitbake/lib/toaster/toastergui/templates/layers.html
index 24d31c770e..2367e7c33a 100644
--- a/bitbake/lib/toaster/toastergui/templates/layers.html
+++ b/bitbake/lib/toaster/toastergui/templates/layers.html
@@ -1,12 +1,32 @@
1{% extends "baseprojectpage.html" %} 1{% extends "baseprojectpage.html" %}
2{% load projecttags %} 2{% load projecttags %}
3{% load humanize %} 3{% load humanize %}
4{% load static %}
4 5
5{% block localbreadcrumb %} 6{% block localbreadcrumb %}
6<li>All compatible layers</li> 7<li>All compatible layers</li>
7{% endblock %} 8{% endblock %}
8 9
10
9{% block projectinfomain %} 11{% block projectinfomain %}
12
13<script src="{% static 'js/layerBtn.js' %}"></script>
14<script>
15
16 $(document).ready(function (){
17 var ctx = {
18 projectLayers : {{projectlayerset}},
19 };
20
21 try {
22 layerBtnsInit(ctx);
23 } catch (e) {
24 document.write("Sorry, An error has occurred loading this page");
25 console.warn(e);
26 }
27 });
28</script>
29
10 <div class="page-header"> 30 <div class="page-header">
11 <h1> 31 <h1>
12 {% if request.GET.filter and objects.paginator.count > 0 or request.GET.search and objects.paginator.count > 0 %} 32 {% if request.GET.filter and objects.paginator.count > 0 or request.GET.search and objects.paginator.count > 0 %}
@@ -20,7 +40,11 @@
20 </h1> 40 </h1>
21 </div> 41 </div>
22 42
23 <div id="zone1alerts"> 43 <div id="zone1alerts" style="display:none">
44 <div class="alert alert-info lead">
45 <button type="button" class="close" id="hide-alert">&times;</button>
46 <span id="alert-msg"></span>
47 </div>
24 </div> 48 </div>
25 49
26{% if objects.paginator.count == 0 %} 50{% if objects.paginator.count == 0 %}
@@ -89,12 +113,11 @@
89 </td> 113 </td>
90 {% if project %} 114 {% if project %}
91 <td class="add-del-layers" value="{{o.pk}}"> 115 <td class="add-del-layers" value="{{o.pk}}">
92 <div id="layer-tooltip-{{o.pk}}" style="display: none; font-size: 11px; line-height: 1.3;" class="tooltip-inner">layer was modified</div> 116 <button class="btn btn-danger btn-block layer-exists-{{o.pk}} layerbtn" style="display:none;" data-layer='{ "id": {{o.pk}}, "name": "{{o.layer.name}}", "url": "{%url 'layerdetails' o.pk%}"}' data-directive="remove" >
93 <button id="layer-del-{{o.pk}}" class="btn btn-danger btn-block remove-layer layerbtn" style="display:none;" onclick="layerDel({{o.pk}}, '{{o.layer.name}}', '{%url 'layerdetails' o.pk%}')" >
94 <i class="icon-trash"></i> 117 <i class="icon-trash"></i>
95 Delete layer 118 Delete layer
96 </button> 119 </button>
97 <button id="layer-add-{{o.pk}}" class="btn btn-block layerbtn" style="display:none;" onclick="layerAdd({{o.pk}}, '{{o.layer.name}}', '{%url 'layerdetails' o.pk%}')" title="layer added"> 120 <button class="btn btn-block layer-add-{{o.pk}} layerbtn" data-layer='{ "id": {{o.pk}}, "name": "{{o.layer.name}}", "url": "{%url 'layerdetails' o.pk%}"}' data-directive="add">
98 <i class="icon-plus"></i> 121 <i class="icon-plus"></i>
99 Add layer 122 Add layer
100 </button> 123 </button>
@@ -104,198 +127,6 @@
104 {% endfor %} 127 {% endfor %}
105{% include "basetable_bottom.html" %} 128{% include "basetable_bottom.html" %}
106 129
107 <!-- Modals -->
108
109 <!-- 'Layer dependencies modal' -->
110 <div id="dependencies_modal" class="modal hide fade" tabindex="-1" role="dialog" aria-hidden="true">
111 <form id="dependencies_modal_form">
112 <div class="modal-header">
113 <button type="button" class="close" data-dismiss="modal" aria-hidden="true">x</button>
114 <h3><span class="layer-name"></span> dependencies</h3>
115 </div>
116 <div class="modal-body">
117 <p><strong class="layer-name"></strong> depends on some layers that are not added to your project. Select the ones you want to add:</p>
118 <ul class="unstyled" id="dependencies_list">
119 </ul>
120 </div>
121 <div class="modal-footer">
122 <button class="btn btn-primary" type="submit">Add layers</button>
123 <button class="btn" type="reset" data-dismiss="modal">Cancel</button>
124 </div>
125 </form>
126 </div>
127
128{% if project %}
129<script>
130
131var tooltipUpdateText;
132
133/* ensure csrf cookie exists {% csrf_token %} */
134function _makeXHREditCall(data, onsuccess, onfail) {
135 $.ajax( {
136 type: "POST",
137 url: "{% url 'xhr_projectedit' project.id %}",
138 data: data,
139 headers: { 'X-CSRFToken' : $.cookie('csrftoken')},
140 success: function (_data) {
141 if (_data.error != "ok") {
142 console.warn(_data.error);
143 } else {
144 updateButtons(_data.layers.map(function (e) {return e.id}));
145 if (onsuccess != undefined) onsuccess(_data);
146 }
147 },
148 error: function (_data) {
149 console.warn("Call failed");
150 console.warn(_data);
151 }
152 });
153}
154
155function updateLayerCountLabels (amount) {
156 /* Update the filter labels */
157 var countLabel = $("#projectlayer__project\\:{{project.id}}_count");
158 countLabel.text(Number(countLabel.text())+amount);
159
160 var countLabelRemaining = $("#projectlayer__project\\:NOT{{project.id}}_count");
161 countLabelRemaining.text(Number(countLabelRemaining.text())-amount);
162}
163
164
165function layerDel(layerId, layerName, layerURL) {
166 tooltipUpdateText = "1 layer deleted";
167 _makeXHREditCall({ 'layerDel': layerId }, function () {
168 updateLayerCountLabels(-1);
169
170 show_alert("You have deleted <strong>1</strong> layer from <a href=\"{% url 'project' project.id%}\">{{project.name}}</a>: <a href=\""+layerURL+"\">" + layerName +"</a>");
171 });
172}
173
174function show_alert(text, cls) {
175 $("#zone1alerts").html("<div class=\"alert alert-info lead\"><button type=\"button\" class=\"close\" data-dismiss=\"alert\">&times;</button>" + text + "</div>");
176}
177
178function show_dependencies_modal(layerId, layerName, layerURL, dependencies) {
179 // update layer name
180 $('.layer-name').text(layerName);
181 var deplistHtml = "";
182 for (var i = 0; i < dependencies.length; i++) {
183 deplistHtml += "<li><label class=\"checkbox\"><input name=\"dependencies\" value=\""
184 deplistHtml += dependencies[i].id;
185 deplistHtml +="\" type=\"checkbox\" checked=\"checked\"/>";
186 deplistHtml += dependencies[i].name;
187 deplistHtml += "</label></li>";
188 }
189 $('#dependencies_list').html(deplistHtml);
190
191 var selected = [layerId];
192 var layer_link_list = "<a href='"+layerURL+"'>"+layerName+"</a>";
193
194 $("#dependencies_modal_form").submit(function (e) {
195 e.preventDefault();
196 $("input[name='dependencies']:checked").map(function () { selected.push(parseInt($(this).val()))});
197 if (selected.length > 1) {
198 tooltipUpdateText = "" + selected.length + " layers added";
199 } else {
200 tooltipUpdateText = "1 layer added";
201 }
202
203 for (var i = 0; i < selected.length; i++) {
204 for (var j = 0; j < dependencies.length; j++) {
205 if (dependencies[j].id == selected[i]) {
206 layer_link_list+= ", <a href='"+dependencies[j].layerdetailurl+"'>"+dependencies[j].name+"</a>"
207 break;
208 }
209 }
210 }
211
212 $('#dependencies_modal').modal('hide');
213
214 {% if project %}
215 _makeXHREditCall({ 'layerAdd': selected.join(",") }, function () {
216 show_alert("You have added <strong>"+selected.length+"</strong> layers to <a href=\"{% url 'project' project.id%}\">{{project.name}}</a>: " + layer_link_list);
217 });
218 {% endif %}
219
220 });
221 $('#dependencies_modal').modal('show');
222}
223
224
225function layerAdd(layerId, layerName, layerURL) {
226 $.ajax({
227 url: '{% url "xhr_datatypeahead" %}',
228 data: {'type': 'layerdeps','value':layerId},
229 success: function(_data) {
230 if (_data.error != "ok") {
231 console.warn(_data.error);
232 } else {
233 updateLayerCountLabels(_data.list.length+1);
234
235 if (_data.list.length > 0) {
236 show_dependencies_modal(layerId, layerName, layerURL, _data.list);
237 }
238 else {
239 tooltipUpdateText = "1 layer added";
240 _makeXHREditCall({ 'layerAdd': layerId }, function () {
241 show_alert("You have added <strong>1</strong> layer to <a href=\"{% url 'project' project.id%}\">{{project.name}}</a>: <a href=\""+layerURL+"\">" + layerName +"</a>");
242 });
243 }
244 }
245 }
246 })
247}
248
249function button_set(id, state) {
250 var tohide, toshow;
251 if (state == "add")
252 {
253 tohide = "#layer-del-";
254 toshow = "#layer-add-";
255 }
256 else if (state == "del")
257 {
258 tohide = "#layer-add-";
259 toshow = "#layer-del-";
260 }
261
262
263 var previouslyvisible = $(tohide + id).is(":visible");
264 if (previouslyvisible) {
265 $(tohide + id).fadeOut( function() {
266 $("#layer-tooltip-" + id).text(tooltipUpdateText);
267 $("#layer-tooltip-" + id).fadeIn().delay(2000).fadeOut(function(){
268 $(toshow + id).delay(300).fadeIn();
269 });
270 });
271 } else {
272 $(tohide + id).hide();
273 $("#layer-tooltip-" + id).hide();
274 $(toshow + id).show();
275 }
276};
277
278function updateButtons(projectLayers) {
279 var displayedLayers = [];
280 $(".add-del-layers").map(function () { displayedLayers.push(parseInt($(this).attr('value')))});
281 for (var i=0; i < displayedLayers.length; i++) {
282 if (projectLayers.indexOf(displayedLayers[i]) > -1) {
283 button_set(displayedLayers[i], "del");
284 }
285 else {
286 button_set(displayedLayers[i], "add");
287 }
288 }
289}
290
291$(document).ready(function (){
292 $('.layerbtn').tooltip({ trigger: 'manual' });
293 updateButtons({{projectlayerset}});
294});
295
296</script>
297{%endif%}
298
299{%endif%} 130{%endif%}
300 131
301{% endblock %} 132{% endblock %}
diff --git a/bitbake/lib/toaster/toastergui/templates/layers_dep_modal.html b/bitbake/lib/toaster/toastergui/templates/layers_dep_modal.html
deleted file mode 100644
index ea49af50d8..0000000000
--- a/bitbake/lib/toaster/toastergui/templates/layers_dep_modal.html
+++ /dev/null
@@ -1,99 +0,0 @@
1<!-- 'Layer dependencies modal' -->
2 <div id="dependencies_modal" class="modal hide fade" tabindex="-1" role="dialog" aria-hidden="true">
3 <form id="dependencies_modal_form">
4 <div class="modal-header">
5 <button type="button" class="close" data-dismiss="modal" aria-hidden="true">x</button>
6 <h3><span id="title"></span> dependencies</h3>
7 </div>
8 <div class="modal-body">
9 <p id="body-text"> <strong id="layer-name"></strong> depends on some layers that are not added to your project. Select the ones you want to add:</p>
10 <ul class="unstyled" id="dependencies_list">
11 </ul>
12 </div>
13 <div class="modal-footer">
14 <button class="btn btn-primary" type="submit">Add layers</button>
15 <button class="btn" type="reset" data-dismiss="modal">Cancel</button>
16 </div>
17 </form>
18 </div>
19
20<script>
21 /*
22 * layer: Object representing the parent layer { id: .. name: ... url }
23 * dependencies: array of dependency layer objects { id: .. name: ..}
24 * title: optional override for title
25 * body: optional override for body
26 * addToProject: Whether to add layers to project on accept
27 * successAdd: function to run on success
28 */
29function show_layer_deps_modal(projectId, layer, dependencies, title, body, addToProject, successAdd) {
30
31 // update layer name
32 if (title) {
33 $('#dependencies_modal #title').text(title);
34 } else {
35 $('#dependencies_modal #title').text(layer.name);
36 }
37
38 if (body) {
39 $("#dependencies_modal #body-text").html(body);
40 } else {
41 $("#dependencies_modal #layer-name").text(layer.name);
42 }
43
44 var deplistHtml = "";
45 for (var i = 0; i < dependencies.length; i++) {
46 deplistHtml += "<li><label class=\"checkbox\"><input name=\"dependencies\" value=\"";
47 deplistHtml += dependencies[i].id;
48 deplistHtml +="\" type=\"checkbox\" checked=\"checked\"/>";
49 deplistHtml += dependencies[i].name;
50 deplistHtml += "</label></li>";
51 }
52 $('#dependencies_list').html(deplistHtml);
53
54 var selected = [];
55 /* -1 is a special dummy Id which we use when the layer isn't yet in the
56 * system, normally we would add the current layer to the selection.
57 */
58 if (layer.id != -1)
59 selected.push(layer.id);
60
61 var layer_link_list = "<a href='"+layer.url+"'>"+layer.name+"</a>";
62
63 $("#dependencies_modal_form").submit(function (e) {
64 e.preventDefault();
65 $("input[name='dependencies']:checked").map(function () { selected.push(parseInt($(this).val()))});
66 if (selected.length > 1) {
67 tooltipUpdateText = "" + selected.length + " layers added";
68 } else {
69 tooltipUpdateText = "1 layer added";
70 }
71
72 for (var i = 0; i < selected.length; i++) {
73 for (var j = 0; j < dependencies.length; j++) {
74 if (dependencies[j].id == selected[i]) {
75 layer_link_list+= ", <a href='"+dependencies[j].layerdetailurl+"'>"+dependencies[j].name+"</a>"
76 break;
77 }
78 }
79 }
80
81 $('#dependencies_modal').modal('hide');
82
83 if (addToProject) {
84 var editProjectUrl = "{% url 'xhr_projectedit' project.id %}";
85 libtoaster.editProject(editProjectUrl, projectId, { 'layerAdd': selected.join(",") }, function () {
86 if (successAdd) {
87 successAdd(selected);
88 }
89 }, function () {
90 console.log ("Adding layers to project failed");
91 });
92 } else {
93 successAdd(selected);
94 }
95 });
96
97 $('#dependencies_modal').modal('show');
98}
99</script>
diff --git a/bitbake/lib/toaster/toastergui/templates/machines.html b/bitbake/lib/toaster/toastergui/templates/machines.html
index 64db0f9ca7..d116a45f3b 100644
--- a/bitbake/lib/toaster/toastergui/templates/machines.html
+++ b/bitbake/lib/toaster/toastergui/templates/machines.html
@@ -7,22 +7,23 @@
7{% endblock %} 7{% endblock %}
8 8
9{% block projectinfomain %} 9{% block projectinfomain %}
10<script src="{% static 'js/machines.js' %}"></script> 10
11<script src="{% static 'js/layerBtn.js' %}"></script>
11<script> 12<script>
12 13
13 $(document).ready(function (){ 14 $(document).ready(function (){
14 var ctx = { 15 var ctx = {
16 projectLayers : {{projectlayerset}},
15 }; 17 };
16 18
17 try { 19 try {
18 machinesPageInit(ctx); 20 layerBtnsInit(ctx);
19 } catch (e) { 21 } catch (e) {
20 document.write("Sorry, An error has occurred loading this page"); 22 document.write("Sorry, An error has occurred loading this page");
21 console.warn(e); 23 console.warn(e);
22 } 24 }
23 }); 25 });
24</script> 26</script>
25{% include "layers_dep_modal.html" %}
26<div class="page-header"> 27<div class="page-header">
27 <h1> 28 <h1>
28 {% if request.GET.search or request.GET.filter %} 29 {% if request.GET.search or request.GET.filter %}
@@ -33,14 +34,17 @@
33 {% endif %} 34 {% endif %}
34 {% else %} 35 {% else %}
35 36
36 All machines 37 All compatible machines
37 <i class="icon-question-sign get-help heading-help" title="This page lists all the machines compatible with the current project that Toaster knows about. They include community-created targets suitable for use on top of OpenEmbedded Core and any targets you have imported"></i> 38 <i class="icon-question-sign get-help heading-help" title="This page lists all the machines compatible with the current project that Toaster knows about. They include community-created targets suitable for use on top of OpenEmbedded Core and any targets you have imported"></i>
38 {% endif %} 39 {% endif %}
39 </h1> 40 </h1>
40</div> 41</div>
41<div class="alert alert-info lead" id="alert-area" style="display:none"> 42
42 <button type="button" class="close" id="dismiss-alert">&times;</button> 43<div id="zone1alerts" style="display:none">
43 <span id="alert-msg"></span> 44 <div class="alert alert-info lead">
45 <button type="button" class="close" id="hide-alert">&times;</button>
46 <span id="alert-msg"></span>
47 </div>
44</div> 48</div>
45{% if objects.paginator.count == 0 %} 49{% if objects.paginator.count == 0 %}
46 {% if request.GET.search %} 50 {% if request.GET.search %}
@@ -68,19 +72,16 @@
68 <td class="layer"><a href="{%url "layerdetails" o.layer_version.id %}">{{o.layer_version.layer.name}}</a></td> 72 <td class="layer"><a href="{%url "layerdetails" o.layer_version.id %}">{{o.layer_version.layer.name}}</a></td>
69 <td class="branch">{{o.layer_version.get_vcs_reference}}</td> 73 <td class="branch">{{o.layer_version.get_vcs_reference}}</td>
70 <td class="machinefile"><code>/machine/conf/{{o.name}}.conf</code><a href="{{o.get_vcs_machine_file_link_url}}" target="_blank"><i class="icon-share get-info"></i></a></td> 74 <td class="machinefile"><code>/machine/conf/{{o.name}}.conf</code><a href="{{o.get_vcs_machine_file_link_url}}" target="_blank"><i class="icon-share get-info"></i></a></td>
71 <td class="select-or-add"> 75 <td class="select-or-add" style="height: 32px;">
72 <a href="#" class="btn btn-block select-machine-btn" data-machine-name="{{o.name}}" data-layer-version-id="{{o.layer_version.id}}" 76 <a href="{% url 'project' project.id %}#/machineselect={{o.name}}" class="btn btn-block layer-exists-{{o.layer_version.id}}" style="margin-top: 5px; display:none">Select machine</a>
73 {%if o.layer_version.id not in project_layers %}style="display:none" {%endif%} >Select machine</a> 77 <button class="btn btn-block layerbtn layer-add-{{o.layer_version.id}}" data-layer='{ "id": {{o.layer_version.id}}, "name": "{{o.layer_version.layer.name}}", "url": "{%url 'layerdetails' o.layer_version.id %}"}' data-directive="add">
74 <a href="#" class="btn btn-block nopop add-layer" data-layer-version-id="{{o.layer_version.id}}" data-layer-name="{{o.layer_version.layer.name}}" {%if o.layer_version.id in project_layers %}style="display:none" {%endif%}
75 >
76 <i class="icon-plus"></i> 78 <i class="icon-plus"></i>
77 Add layer 79 Add layer
78 <i class="icon-question-sign get-help" title="To build this machine, you must first add the {{o.layer_version.layer.name}} layer to your project"></i> 80 <i title="" class="icon-question-sign get-help" data-original-title="To enable this machine, you must first add the {{o.layer_version.layer.name}} layer to your project"></i></i>
79 </a> 81 </button>
80 </td> 82 </td>
81 </tr> 83 </tr>
82 {% endfor %} 84 {% endfor %}
83
84 {% include "basetable_bottom.html" %} 85 {% include "basetable_bottom.html" %}
85{% endif %} 86{% endif %}
86 87
diff --git a/bitbake/lib/toaster/toastergui/templates/targets.html b/bitbake/lib/toaster/toastergui/templates/targets.html
index c27292095d..903e841ae5 100644
--- a/bitbake/lib/toaster/toastergui/templates/targets.html
+++ b/bitbake/lib/toaster/toastergui/templates/targets.html
@@ -1,14 +1,34 @@
1{% extends "baseprojectpage.html" %} 1{% extends "baseprojectpage.html" %}
2{% load projecttags %} 2{% load projecttags %}
3{% load humanize %} 3{% load humanize %}
4{% load static %}
4 5
5{% block localbreadcrumb %} 6{% block localbreadcrumb %}
6<li>All compatible recipes</li> 7<li>All compatible recipes</li>
7{% endblock %} 8{% endblock %}
8 9
9{% block projectinfomain %} 10{% block projectinfomain %}
10 <div class="page-header"> 11
11 <h1> 12<script src="{% static 'js/layerBtn.js' %}"></script>
13<script>
14
15 $(document).ready(function (){
16 var ctx = {
17 projectLayers : {{projectlayerset}},
18 };
19
20 try {
21 layerBtnsInit(ctx);
22 } catch (e) {
23 document.write("Sorry, An error has occurred loading this page");
24 console.warn(e);
25 }
26 });
27</script>
28
29
30<div class="page-header">
31 <h1>
12 {% if request.GET.filter and objects.paginator.count > 0 or request.GET.search and objects.paginator.count > 0 %} 32 {% if request.GET.filter and objects.paginator.count > 0 or request.GET.search and objects.paginator.count > 0 %}
13 {{objects.paginator.count}} recipe{{objects.paginator.count|pluralize}} found 33 {{objects.paginator.count}} recipe{{objects.paginator.count|pluralize}} found
14 {% elif request.GET.filter and objects.paginator.count == 0 or request.GET.search and objects.paginator.count == 0 %} 34 {% elif request.GET.filter and objects.paginator.count == 0 or request.GET.search and objects.paginator.count == 0 %}
@@ -16,14 +36,16 @@
16 {%else%} 36 {%else%}
17 All compatible recipes 37 All compatible recipes
18 {%endif%} 38 {%endif%}
19 <i class="icon-question-sign get-help heading-help" title="This page lists all the recipes compatible with the release selected for this project, which is {{project.release.description}}"></i> 39 <i class="icon-question-sign get-help heading-help" title="This page lists all the recipes compatible with the release selected for this project, which is {{project.release.description}}"></i>
20 </h1> 40 </h1>
21 </div> 41</div>
22 42
23 <div id="zone1alerts"> 43<div id="zone1alerts" style="display:none">
24 44 <div class="alert alert-info lead">
45 <button type="button" class="close" id="hide-alert">&times;</button>
46 <span id="alert-msg"></span>
25 </div> 47 </div>
26 48</div>
27{% if objects.paginator.count == 0 %} 49{% if objects.paginator.count == 0 %}
28 {% if request.GET.filter or request.GET.search %} 50 {% if request.GET.filter or request.GET.search %}
29 <div class="row-fluid"> 51 <div class="row-fluid">
@@ -75,17 +97,16 @@
75 </a> 97 </a>
76 {% endif %} 98 {% endif %}
77 </td> 99 </td>
78 <td class="add-layer" value="{{o.pk}}" layerversion_id="{{o.preffered_layerversion.pk}}"> 100 <td class="add-layer" value="{{o.pk}}">
79 <div id="layer-tooltip-{{o.pk}}" style="display: none; font-size: 11px; line-height: 1.3;" class="tooltip-inner">layer was modified</div> 101 <a href="{% url 'project' project.id %}#/targetbuild={{o.name}}" class="btn btn-block layer-exists-{{o.preffered_layerversion.pk}}" style="display:none; margin-top: 5px;" >
80 <a href="{% url 'project' project.id %}#/targetbuild={{o.name}}" id="target-build-{{o.pk}}" class="btn btn-block remove-layer" style="display:none;" > 102 Build recipe
81 Build recipe 103 </a>
82 </a> 104 <button class="btn btn-block layerbtn layer-add-{{o.preffered_layerversion.pk}}" data-layer='{ "id": {{o.preffered_layerversion.pk}}, "name": "{{o.preffered_layerversion.layer.name}}", "url": "{%url 'layerdetails' o.preffered_layerversion.pk%}"}' data-directive="add">
83 <a id="layer-add-{{o.pk}}" class="btn btn-block" style="display:none;" href="javascript:layerAdd({{o.preffered_layerversion.pk}}, '{{o.preffered_layerversion.layer.name}}', '{%url 'layerdetails' o.preffered_layerversion.pk%}', {{o.pk}})" > 105 <i class="icon-plus"></i>
84 <i class="icon-plus"></i> 106 Add layer
85 Add layer 107 <i title="" class="icon-question-sign get-help" data-original-title="To build this target, you must first add the {{o.preffered_layerversion.layer.name}} layer to your project"></i></i>
86 <i title="" class="icon-question-sign get-help" data-original-title="To build this target, you must first add the {{o.preffered_layerversion.layer.name}} layer to your project"></i> 108 </button>
87 </a> 109 </td>
88 </td>
89 </tr> 110 </tr>
90 {% endfor %} 111 {% endfor %}
91{% include "basetable_bottom.html" %} 112{% include "basetable_bottom.html" %}
@@ -115,165 +136,6 @@
115 136
116{% if project %} 137{% if project %}
117<script> 138<script>
118
119var tooltipUpdateText;
120
121/* ensure csrf cookie exists {% csrf_token %} */
122function _makeXHREditCall(data, onsuccess, onfail) {
123 $.ajax( {
124 type: "POST",
125 url: "{% url 'xhr_projectedit' project.id %}",
126 data: data,
127 headers: { 'X-CSRFToken' : $.cookie('csrftoken')},
128 success: function (_data) {
129 if (_data.error != "ok") {
130 console.warn(_data.error);
131 } else {
132 updateButtons(_data.layers.map(function (e) {return e.id}));
133 if (onsuccess != undefined) onsuccess(_data);
134 }
135 },
136 error: function (_data) {
137 console.warn("Call failed");
138 console.warn(_data);
139 }
140 });
141}
142
143function show_alert(text, cls) {
144 $("#zone1alerts").html("<div class=\"alert alert-info lead\"><button type=\"button\" class=\"close\" data-dismiss=\"alert\">&times;</button>" + text + "</div>");
145}
146
147
148function show_dependencies_modal(layerId, layerName, layerURL, dependencies) {
149 // update layer name
150 $('.layer-name').text(layerName);
151 var deplistHtml = "";
152 for (var i = 0; i < dependencies.length; i++) {
153 deplistHtml += "<li><label class=\"checkbox\"><input name=\"dependencies\" value=\""
154 deplistHtml += dependencies[i].id;
155 deplistHtml +="\" type=\"checkbox\" checked=\"checked\"/>";
156 deplistHtml += dependencies[i].name;
157 deplistHtml += "</label></li>";
158 }
159 $('#dependencies_list').html(deplistHtml);
160
161 var selected = [layerId];
162 var layer_link_list = undefined;
163
164 $("#dependencies_modal_form").submit(function (e) {
165 e.preventDefault();
166 $("input[name='dependencies']:checked").map(function () { selected.push(parseInt($(this).val()))});
167 layer_link_list = "<a href='"+layerURL+"'>"+layerName+"</a>";
168 if (selected.length > 1) {
169 tooltipUpdateText = "" + selected.length + " layers added";
170 } else {
171 tooltipUpdateText = "1 layer added";
172 }
173
174 for (var i = 0; i < selected.length; i++) {
175 for (var j = 0; j < dependencies.length; j++) {
176 if (dependencies[j].id == selected[i]) {
177 layer_link_list+= ", <a href='"+dependencies[j].layerdetailurl+"'>"+dependencies[j].name+"</a>"
178 break;
179 }
180 }
181 }
182
183 $('#dependencies_modal').modal('hide');
184
185 {% if project %}
186 _makeXHREditCall({ 'layerAdd': selected.join(",") }, function onXHRSuccess() {
187 show_alert("You have added <strong>"+selected.length+"</strong> layer(s) to <a href=\"{% url 'project' project.id%}\">{{project.name}}</a>: " + layer_link_list);
188 });
189 {% endif %}
190
191 });
192 $('#dependencies_modal').modal('show');
193}
194
195function updateLayerCountLabels (amount) {
196 /* Update the filter labels */
197 var countLabel = $("#layer_version__projectlayer__project\\:{{project.id}}_count");
198 countLabel.text(Number(countLabel.text())+amount);
199
200 var countLabelRemaining = $("#layer_version__projectlayer__project\\:NOT{{project.id}}_count");
201 countLabelRemaining.text(Number(countLabelRemaining.text())-amount);
202}
203
204var pressedButton = undefined;
205
206function layerAdd(layerId, layerName, layerURL, pressedButtonId) {
207 pressedButton = pressedButtonId;
208 $.ajax({
209 url: '{% url "xhr_datatypeahead" %}',
210 data: {'type': 'layerdeps','value':layerId},
211 success: function(_data) {
212 if (_data.error != "ok") {
213 console.warn(_data.error);
214 } else {
215 updateLayerCountLabels(_data.list.length+1);
216
217 if (_data.list.length > 0) {
218 show_dependencies_modal(layerId, layerName, layerURL, _data.list);
219 }
220 else {
221 tooltipUpdateText = "1 layer added";
222 _makeXHREditCall({ 'layerAdd': layerId }, function () {
223 show_alert("You have added <strong>1</strong> layer to <a href=\"{% url 'project' project.id%}\">{{project.name}}</a>: <a href=\""+layerURL+"\">" + layerName +"</a>");
224 });
225 }
226 }
227 }
228 })
229}
230
231function buttonSet(id, state) {
232 var tohide, toshow;
233 if (state == "add")
234 {
235 toshow = "#layer-add-";
236 tohide = "#target-build-";
237 }
238 else if (state == "build")
239 {
240 tohide = "#layer-add-";
241 toshow = "#target-build-";
242 }
243
244 var previouslyvisible = $(tohide + id).is(":visible");
245 if (previouslyvisible && id == pressedButton) {
246 $(tohide + id).fadeOut( function() {
247 $("#layer-tooltip-" + id).text(tooltipUpdateText);
248 $("#layer-tooltip-" + id).fadeIn().delay(2000).fadeOut(function(){
249 $(toshow + id).delay(300).fadeIn();
250 });
251 });
252 } else {
253 $(tohide + id).hide();
254 $("#layer-tooltip-" + id).hide();
255 $(toshow + id).show();
256 }
257};
258
259
260function updateButtons(projectLayers) {
261 var displayedLayers = [];
262 $(".add-layer").map(function () { displayedLayers.push( { "l": parseInt($(this).attr('layerversion_id')), "i": parseInt($(this).attr('value'))})});
263 for (var i=0; i < displayedLayers.length; i++) {
264 if (projectLayers.indexOf(displayedLayers[i].l) > -1) {
265 buttonSet(displayedLayers[i].i, "build");
266 }
267 else {
268 buttonSet(displayedLayers[i].i, "add");
269 }
270 }
271}
272
273$(document).ready(function (){
274 updateButtons({{projectlayerset}});
275});
276
277</script> 139</script>
278{%endif%} 140{%endif%}
279 141
diff --git a/bitbake/lib/toaster/toastergui/views.py b/bitbake/lib/toaster/toastergui/views.py
index b5c4d87c56..7e90926559 100755
--- a/bitbake/lib/toaster/toastergui/views.py
+++ b/bitbake/lib/toaster/toastergui/views.py
@@ -2987,7 +2987,7 @@ if toastermain.settings.MANAGED:
2987 2987
2988 context = { 2988 context = {
2989 'objects' : machine_info, 2989 'objects' : machine_info,
2990 'project_layers' : project_layers, 2990 'projectlayerset' : jsonfilter(map(lambda x: x.layercommit.id, prj.projectlayer_set.all())),
2991 'objectname' : "machines", 2991 'objectname' : "machines",
2992 'default_orderby' : 'name:+', 2992 'default_orderby' : 'name:+',
2993 2993