summaryrefslogtreecommitdiffstats
path: root/bitbake/lib/toaster/toastergui/static/js
diff options
context:
space:
mode:
authorMichael Wood <michael.g.wood@intel.com>2014-11-28 20:12:18 +0000
committerRichard Purdie <richard.purdie@linuxfoundation.org>2014-12-18 10:24:07 +0000
commit1605cd37dbfcd75043f57dd527e0bfc0a79e1e78 (patch)
tree505bf86cdde6993010c5a153d153b3206ab98cf2 /bitbake/lib/toaster/toastergui/static/js
parent13141af70813d84b27e41d7a6e5792c748b3ae90 (diff)
downloadpoky-1605cd37dbfcd75043f57dd527e0bfc0a79e1e78.tar.gz
bitbake: toaster: Add import layer feature.
This feature allows users to import layers from git into their current project and associate it with the release of the current project and the dependencies for the newly imported layer with existing layers. It will also resolve the child dependencies of the dependencies added. [YOCTO #6595] (Bitbake rev: 017f5c746e894f9d87d927c848386459ea332378) Signed-off-by: Michael Wood <michael.g.wood@intel.com> Signed-off-by: Alexandru DAMIAN <alexandru.damian@intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'bitbake/lib/toaster/toastergui/static/js')
-rw-r--r--bitbake/lib/toaster/toastergui/static/js/importlayer.js277
-rw-r--r--bitbake/lib/toaster/toastergui/static/js/projectapp.js6
2 files changed, 283 insertions, 0 deletions
diff --git a/bitbake/lib/toaster/toastergui/static/js/importlayer.js b/bitbake/lib/toaster/toastergui/static/js/importlayer.js
new file mode 100644
index 0000000000..e2bc1ab607
--- /dev/null
+++ b/bitbake/lib/toaster/toastergui/static/js/importlayer.js
@@ -0,0 +1,277 @@
1"use strict"
2
3function importLayerPageInit (ctx) {
4
5 var layerDepBtn = $("#add-layer-dependency-btn");
6 var importAndAddBtn = $("#import-and-add-btn");
7 var layerNameInput = $("#layer-name");
8 var vcsURLInput = $("#layer-git-repo-url");
9 var gitRefInput = $("#layer-git-ref");
10 var layerDepInput = $("#layer-dependency");
11 var layerNameCtrl = $("#layer-name-ctrl");
12 var duplicatedLayerName = $("#duplicated-layer-name-hint");
13
14 var layerDeps = {};
15 var layerDepsDeps = {};
16 var currentLayerDepSelection;
17 var validLayerName = /^(\w|-)+$/;
18
19 $("#new-project-button").hide();
20
21 libtoaster.makeTypeahead(layerDepInput, ctx.xhrDataTypeaheadUrl, { type : "layers", project_id: ctx.projectId, include_added: "true" }, function(item){
22 currentLayerDepSelection = item;
23
24 layerDepBtn.removeAttr("disabled");
25 });
26
27
28 /* We automatically add "openembedded-core" layer for convenience as a
29 * dependency as pretty much all layers depend on this one
30 */
31 $.getJSON(ctx.xhrDataTypeaheadUrl, { type : "layers", project_id: ctx.projectId, include_added: "true" , value: "openembedded-core" }, function(layer) {
32 if (layer.list.length == 1) {
33 currentLayerDepSelection = layer.list[0];
34 layerDepBtn.click();
35 }
36 });
37
38 layerDepBtn.click(function(){
39 if (currentLayerDepSelection == undefined)
40 return;
41
42 layerDeps[currentLayerDepSelection.id] = currentLayerDepSelection;
43
44 /* Make a list item for the new layer dependency */
45 var newLayerDep = $("<li><a></a><span class=\"icon-trash\" data-toggle=\"tooltip\" title=\"Delete\"></span></li>");
46
47 newLayerDep.data('layer-id', currentLayerDepSelection.id);
48 newLayerDep.children("span").tooltip();
49
50 var link = newLayerDep.children("a");
51 link.attr("href", ctx.layerDetailsUrl+String(currentLayerDepSelection.id));
52 link.text(currentLayerDepSelection.name);
53 link.tooltip({title: currentLayerDepSelection.tooltip, placement: "right"});
54
55 var trashItem = newLayerDep.children("span");
56 trashItem.click(function () {
57 var toRemove = $(this).parent().data('layer-id');
58 delete layerDeps[toRemove];
59 $(this).parent().fadeOut(function (){
60 $(this).remove();
61 });
62 });
63
64 $("#layer-deps-list").append(newLayerDep);
65
66 libtoaster.getLayerDepsForProject(ctx.xhrDataTypeaheadUrl, ctx.projectId, currentLayerDepSelection.id, function (data){
67 /* These are the dependencies of the layer added as a dependency */
68 if (data.list.length > 0) {
69 currentLayerDepSelection.url = ctx.layerDetailsUrl+currentLayerDepSelection.id;
70 layerDeps[currentLayerDepSelection.id].deps = data.list
71 }
72
73 /* Clear the current selection */
74 layerDepInput.val("");
75 currentLayerDepSelection = undefined;
76 layerDepBtn.attr("disabled","disabled");
77 }, null);
78 });
79
80 importAndAddBtn.click(function(){
81 /* arrray of all layer dep ids includes parent and child deps */
82 var allDeps = [];
83 /* temporary object to use to do a reduce on the dependencies for each
84 * layer dependency added
85 */
86 var depDeps = {};
87
88 /* the layers that have dependencies have an extra property "deps"
89 * look in this for each layer and reduce this to a unquie object
90 * of deps.
91 */
92 for (var key in layerDeps){
93 if (layerDeps[key].hasOwnProperty('deps')){
94 for (var dep in layerDeps[key].deps){
95 var layer = layerDeps[key].deps[dep];
96 depDeps[layer.id] = layer;
97 }
98 }
99 allDeps.push(layerDeps[key].id);
100 }
101
102 /* we actually want it as an array so convert it now */
103 var depDepsArray = [];
104 for (var key in depDeps)
105 depDepsArray.push (depDeps[key]);
106
107 if (depDepsArray.length > 0) {
108 var layer = { name: layerNameInput.val(), url: "#", id: -1 };
109 show_layer_deps_modal(ctx.projectId, layer, depDepsArray, function(selected){
110 /* Add the accepted dependencies to the allDeps array */
111 if (selected.length > 0){
112 allDeps.concat (selected);
113 }
114 import_and_add ();
115 });
116 } else {
117 import_and_add ();
118 }
119
120 function import_and_add () {
121 /* convert to a csv of all the deps to be added */
122 var layerDepsCsv = allDeps.join(",");
123
124 var layerData = {
125 name: layerNameInput.val(),
126 vcs_url: vcsURLInput.val(),
127 git_ref: gitRefInput.val(),
128 summary: $("#layer-summary").val(),
129 dir_path: $("#layer-subdir").val(),
130 project_id: ctx.projectId,
131 layer_deps: layerDepsCsv,
132 };
133
134 $.ajax({
135 type: "POST",
136 url: ctx.xhrImportLayerUrl,
137 data: layerData,
138 headers: { 'X-CSRFToken' : $.cookie('csrftoken')},
139 success: function (data) {
140 if (data.error != "ok") {
141 show_error_message(data, layerData);
142 console.log(data.error);
143 } else {
144 /* Success layer import now go to the project page */
145 window.location.replace(ctx.projectPageUrl+'#/layerimported='+layerData.name);
146 }
147 },
148 error: function (data) {
149 console.log("Call failed");
150 console.log(data);
151 }
152 });
153 }
154 });
155
156 function show_error_message(error, layerData) {
157
158 var errorMsg = $("#import-error").fadeIn();
159 var errorType = error.error;
160 var body = errorMsg.children("span");
161 var title = errorMsg.children("h3");
162 var optionsList = errorMsg.children("ul");
163 var invalidLayerRevision = $("#invalid-layer-revision-hint");
164 var layerRevisionCtrl = $("#layer-revision-ctrl");
165
166 /* remove any existing items */
167 optionsList.children().each(function(){ $(this).remove(); });
168 body.text("");
169 title.text("");
170 invalidLayerRevision.hide();
171 layerNameCtrl.removeClass("error");
172 layerRevisionCtrl.removeClass("error");
173
174 switch (errorType){
175 case 'hint-layer-version-exists':
176 title.text("This layer already exists");
177 body.html("A layer <strong>"+layerData.name+"</strong> already exists with this Git repository URL and this revision. You can:");
178 optionsList.append("<li>Import <strong>"+layerData.name+"</strong> with a different revision </li>");
179 optionsList.append("<li>or <a href=\""+ctx.layerDetailsUrl+error.existing_layer_version+"/\" >change the revision of the existing layer</a></li>");
180
181 layerRevisionCtrl.addClass("error");
182
183 invalidLayerRevision.html("A layer <strong>"+layerData.name+"</strong> already exists with this revision.<br />You can import <strong>"+layerData.name+"</strong> with a different revision");
184 invalidLayerRevision.show();
185 break;
186
187 case 'hint-layer-exists-with-different-url':
188 title.text("This layer already exists");
189 body.html("A layer <strong>"+layerData.name+"</strong> already exists with a different Git repository URL:<br /><br />"+error.current_url+"<br /><br />You Can:");
190 optionsList.append("<li>Import the layer under a different name</li>");
191 optionsList.append("<li>or <a href=\""+ctx.layerDetailsUrl+error.current_id+"/\" >change the Git repository URL of the existing layer</a></li>");
192 duplicatedLayerName.html("A layer <strong>"+layerData.name+"</strong> already exists with a different Git repository URL.<br />To import this layer give it a different name.");
193 duplicatedLayerName.show();
194 layerNameCtrl.addClass("error");
195 break;
196
197 case 'hint-layer-exists':
198 title.text("This layer already exists");
199 body.html("A layer <strong>"+layerData.name+"</strong> already exists: You Can:");
200 optionsList.append("<li>Import the layer under a different name</li>");
201 break;
202 default:
203 title.text("Error")
204 body.text(data.error);
205 }
206 }
207
208 function enable_import_btn (enabled) {
209 var importAndAddHint = $("#import-and-add-hint");
210
211 if (enabled) {
212 importAndAddBtn.removeAttr("disabled");
213 importAndAddHint.hide();
214 return;
215 }
216
217 importAndAddBtn.attr("disabled", "disabled");
218 importAndAddHint.show();
219 }
220
221 function check_form() {
222 var valid = false;
223 var inputs = $("input:required");
224
225 for (var i=0; i<inputs.length; i++){
226 if (!(valid = inputs[i].value)){
227 enable_import_btn(false);
228 break;
229 }
230 }
231
232 if (valid)
233 enable_import_btn(true);
234 }
235
236 vcsURLInput.keyup(function() {
237 check_form();
238 });
239
240 gitRefInput.keyup(function() {
241 check_form();
242 });
243
244 layerNameInput.keyup(function() {
245 if ($(this).val() && !validLayerName.test($(this).val())){
246 layerNameCtrl.addClass("error")
247 $("#invalid-layer-name-hint").show();
248 enable_import_btn(false);
249 return;
250 }
251
252 /* Don't remove the error class if we're displaying the error for another
253 * reason.
254 */
255 if (!duplicatedLayerName.is(":visible"))
256 layerNameCtrl.removeClass("error")
257
258 $("#invalid-layer-name-hint").hide();
259 check_form();
260 });
261
262 /* Have a guess at the layer name */
263 vcsURLInput.focusout(function (){
264 /* If we a layer name specified don't overwrite it or if there isn't a
265 * url typed in yet return
266 */
267 if (layerNameInput.val() || !$(this).val())
268 return;
269
270 if ($(this).val().search("/")){
271 var urlPts = $(this).val().split("/");
272 var suggestion = urlPts[urlPts.length-1].replace(".git","");
273 layerNameInput.val(suggestion);
274 }
275 });
276
277}
diff --git a/bitbake/lib/toaster/toastergui/static/js/projectapp.js b/bitbake/lib/toaster/toastergui/static/js/projectapp.js
index e9b07c7848..8e3499a94c 100644
--- a/bitbake/lib/toaster/toastergui/static/js/projectapp.js
+++ b/bitbake/lib/toaster/toastergui/static/js/projectapp.js
@@ -571,6 +571,12 @@ projectApp.controller('prjCtrl', function($scope, $modal, $http, $interval, $loc
571 "\">select targets</a> you want to build.", "alert-success"); 571 "\">select targets</a> you want to build.", "alert-success");
572 }); 572 });
573 573
574 _cmdExecuteWithParam("/layerimported", function (layer) {
575 $scope.displayAlert($scope.zone2alerts,
576 "You have imported <strong>" + layer +
577 "</strong> and added it to your project.", "alert-success");
578 });
579
574 _cmdExecuteWithParam("/targetbuild=", function (targets) { 580 _cmdExecuteWithParam("/targetbuild=", function (targets) {
575 var oldTargetName = $scope.targetName; 581 var oldTargetName = $scope.targetName;
576 $scope.targetName = targets.split(",").join(" "); 582 $scope.targetName = targets.split(",").join(" ");