summaryrefslogtreecommitdiffstats
path: root/bitbake/lib/toaster/toastergui/static/js/importlayer.js
diff options
context:
space:
mode:
Diffstat (limited to 'bitbake/lib/toaster/toastergui/static/js/importlayer.js')
-rw-r--r--bitbake/lib/toaster/toastergui/static/js/importlayer.js277
1 files changed, 277 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}