blob: c68f3669f6c50cfcd5a72ac49b1eae85cf16e9de [file] [log] [blame]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001"use strict"
2
3function importLayerPageInit (ctx) {
4
5 var layerDepBtn = $("#add-layer-dependency-btn");
6 var importAndAddBtn = $("#import-and-add-btn");
7 var layerNameInput = $("#import-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 libtoaster.makeTypeahead(layerDepInput, libtoaster.ctx.layersTypeAheadUrl, { include_added: "true" }, function(item){
20 currentLayerDepSelection = item;
21
22 layerDepBtn.removeAttr("disabled");
23 });
24
25
26 /* We automatically add "openembedded-core" layer for convenience as a
27 * dependency as pretty much all layers depend on this one
28 */
29 $.getJSON(libtoaster.ctx.layersTypeAheadUrl,
30 { include_added: "true" , search: "openembedded-core" },
31 function(layer) {
32 if (layer.results.length > 0) {
33 currentLayerDepSelection = layer.results[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", currentLayerDepSelection.layerdetailurl);
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(currentLayerDepSelection.layerdetailurl, function (data){
67 /* These are the dependencies of the layer added as a dependency */
68 if (data.list.length > 0) {
69 currentLayerDepSelection.url = currentLayerDepSelection.layerdetailurl;
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 /* This is a list of the names from layerDeps for the layer deps
82 * modal dialog body
83 */
84 var depNames = [];
85
86 /* arrray of all layer dep ids includes parent and child deps */
87 var allDeps = [];
88
89 /* temporary object to use to do a reduce on the dependencies for each
90 * layer dependency added
91 */
92 var depDeps = {};
93
94 /* the layers that have dependencies have an extra property "deps"
95 * look in this for each layer and reduce this to a unquie object
96 * of deps.
97 */
98 for (var key in layerDeps){
99 if (layerDeps[key].hasOwnProperty('deps')){
100 for (var dep in layerDeps[key].deps){
101 var layer = layerDeps[key].deps[dep];
102 depDeps[layer.id] = layer;
103 }
104 }
105 depNames.push(layerDeps[key].name);
106 allDeps.push(layerDeps[key].id);
107 }
108
109 /* we actually want it as an array so convert it now */
110 var depDepsArray = [];
111 for (var key in depDeps)
112 depDepsArray.push (depDeps[key]);
113
114 if (depDepsArray.length > 0) {
115 var layer = { name: layerNameInput.val(), url: "#", id: -1 };
116 var title = "Layer";
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>";
119
120 showLayerDepsModal(layer, depDepsArray, title, body, false, function(layerObsList){
121 /* Add the accepted layer dependencies' ids to the allDeps array */
122 for (var key in layerObsList){
123 allDeps.push(layerObsList[key].id);
124 }
125 import_and_add ();
126 });
127 } else {
128 import_and_add ();
129 }
130
131 function import_and_add () {
132 /* convert to a csv of all the deps to be added */
133 var layerDepsCsv = allDeps.join(",");
134
135 var layerData = {
136 name: layerNameInput.val(),
137 vcs_url: vcsURLInput.val(),
138 git_ref: gitRefInput.val(),
139 dir_path: $("#layer-subdir").val(),
140 project_id: libtoaster.ctx.projectId,
141 layer_deps: layerDepsCsv,
142 };
143
144 $.ajax({
145 type: "POST",
146 url: ctx.xhrImportLayerUrl,
147 data: layerData,
148 headers: { 'X-CSRFToken' : $.cookie('csrftoken')},
149 success: function (data) {
150 if (data.error != "ok") {
151 console.log(data.error);
152 } else {
153 /* Success layer import now go to the project page */
154 $.cookie('layer-imported-alert', JSON.stringify(data), { path: '/'});
155 window.location.replace(libtoaster.ctx.projectPageUrl+'?notify=layer-imported');
156 }
157 },
158 error: function (data) {
159 console.log("Call failed");
160 console.log(data);
161 }
162 });
163 }
164 });
165
166 function enable_import_btn(enabled) {
167 var importAndAddHint = $("#import-and-add-hint");
168
169 if (enabled) {
170 importAndAddBtn.removeAttr("disabled");
171 importAndAddHint.hide();
172 return;
173 }
174
175 importAndAddBtn.attr("disabled", "disabled");
176 importAndAddHint.show();
177 }
178
179 function check_form() {
180 var valid = false;
181 var inputs = $("input:required");
182
183 for (var i=0; i<inputs.length; i++){
184 if (!(valid = inputs[i].value)){
185 enable_import_btn(false);
186 break;
187 }
188 }
189
190 if (valid)
191 enable_import_btn(true);
192 }
193
194 function layerExistsError(layer){
195 var dupLayerInfo = $("#duplicate-layer-info");
196 dupLayerInfo.find(".dup-layer-name").text(layer.name);
197 dupLayerInfo.find(".dup-layer-link").attr("href", layer.layerdetailurl);
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500198 dupLayerInfo.find("#dup-layer-vcs-url").text(layer.vcs_url);
199 dupLayerInfo.find("#dup-layer-revision").text(layer.vcs_reference);
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500200
201 $(".fields-apart-from-layer-name").fadeOut(function(){
202
203 dupLayerInfo.fadeIn();
204 });
205 }
206
207 layerNameInput.on('blur', function() {
208 if (!$(this).val()){
209 return;
210 }
211 var name = $(this).val();
212
213 /* Check if the layer name exists */
214 $.getJSON(libtoaster.ctx.layersTypeAheadUrl,
215 { include_added: "true" , search: name, format: "json" },
216 function(layer) {
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500217 if (layer.results.length > 0) {
218 for (var i in layer.results){
219 if (layer.results[i].name == name) {
220 layerExistsError(layer.results[i]);
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500221 }
222 }
223 }
224 });
225 });
226
227 vcsURLInput.on('input', function() {
228 check_form();
229 });
230
231 gitRefInput.on('input', function() {
232 check_form();
233 });
234
235 layerNameInput.on('input', function() {
236 if ($(this).val() && !validLayerName.test($(this).val())){
237 layerNameCtrl.addClass("error")
238 $("#invalid-layer-name-hint").show();
239 enable_import_btn(false);
240 return;
241 }
242
243 if ($("#duplicate-layer-info").css("display") != "None"){
244 $("#duplicate-layer-info").fadeOut(function(){
245 $(".fields-apart-from-layer-name").show();
246 });
247
248 }
249
250 /* Don't remove the error class if we're displaying the error for another
251 * reason.
252 */
253 if (!duplicatedLayerName.is(":visible"))
254 layerNameCtrl.removeClass("error")
255
256 $("#invalid-layer-name-hint").hide();
257 check_form();
258 });
259
260 /* Have a guess at the layer name */
261 vcsURLInput.focusout(function (){
262 /* If we a layer name specified don't overwrite it or if there isn't a
263 * url typed in yet return
264 */
265 if (layerNameInput.val() || !$(this).val())
266 return;
267
268 if ($(this).val().search("/")){
269 var urlPts = $(this).val().split("/");
270 var suggestion = urlPts[urlPts.length-1].replace(".git","");
271 layerNameInput.val(suggestion);
272 }
273 });
274
275}