summaryrefslogtreecommitdiffstats
path: root/bitbake
diff options
context:
space:
mode:
authorMichael Wood <michael.g.wood@intel.com>2015-04-21 11:59:37 +0100
committerRichard Purdie <richard.purdie@linuxfoundation.org>2015-05-08 17:42:06 +0100
commitbec5d164717c6987f81d47d75942e94538649dad (patch)
tree189574b0de84b2f7ebc83fd3c0230be35d28f997 /bitbake
parenta4cfca604b2c5ab35baf69c2070afa0087842b68 (diff)
downloadpoky-bec5d164717c6987f81d47d75942e94538649dad.tar.gz
bitbake: toaster: Refactor and expand layer add remove mechanism
We have multiple pages which have buttons to add and remove layers this patch adds functionality to libtoaster to abstract this and implements it in the pages affected. We handle loading and showing the dependencies dialog here too and generating the notification messages. Also implemented is using the selectmachine api from the projectapp to avoid having to handle this in each page that allows selecting machines. A small number of jshint issues, help text and the machine page name have also been fixed. (Bitbake rev: ae7a656ba7fc6f4356b57aa309a9b6d035e51d2e) Signed-off-by: Michael Wood <michael.g.wood@intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'bitbake')
-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