blob: e742ef291a6a3d6c7fc25926ef90a8dc6cd6ca72 [file] [log] [blame]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001"use strict";
2
3function projectPageInit(ctx) {
4
5 var layerAddInput = $("#layer-add-input");
6 var layersInPrjList = $("#layers-in-project-list");
7 var layerAddBtn = $("#add-layer-btn");
8
9 var machineChangeInput = $("#machine-change-input");
10 var machineChangeBtn = $("#machine-change-btn");
11 var machineForm = $("#select-machine-form");
12 var machineChangeFormToggle = $("#change-machine-toggle");
13 var machineNameTitle = $("#project-machine-name");
14 var machineChangeCancel = $("#cancel-machine-change");
15
16 var freqBuildBtn = $("#freq-build-btn");
17 var freqBuildList = $("#freq-build-list");
18
19 var releaseChangeFormToggle = $("#release-change-toggle");
20 var releaseTitle = $("#project-release-title");
21 var releaseForm = $("#change-release-form");
22 var releaseModal = $("#change-release-modal");
23 var cancelReleaseChange = $("#cancel-release-change");
24
25 var currentLayerAddSelection;
Patrick Williamsf1e5d692016-03-30 15:21:19 -050026 var currentMachineAddSelection = "";
Patrick Williamsc124f4f2015-09-15 14:41:29 -050027
28 var urlParams = libtoaster.parseUrlParams();
29
30 libtoaster.getProjectInfo(libtoaster.ctx.projectPageUrl, function(prjInfo){
31 updateProjectLayers(prjInfo.layers);
32 updateFreqBuildRecipes(prjInfo.freqtargets);
33 updateProjectRelease(prjInfo.release);
34 updateProjectReleases(prjInfo.releases, prjInfo.release);
35
36 /* If we're receiving a machine set from the url and it's different from
37 * our current machine then activate set machine sequence.
38 */
39 if (urlParams.hasOwnProperty('setMachine') &&
40 urlParams.setMachine !== prjInfo.machine.name){
Patrick Williamsf1e5d692016-03-30 15:21:19 -050041 machineChangeInput.val(urlParams.setMachine);
Patrick Williamsc124f4f2015-09-15 14:41:29 -050042 machineChangeBtn.click();
43 } else {
44 updateMachineName(prjInfo.machine.name);
45 }
46
47 /* Now we're really ready show the page */
48 $("#project-page").show();
49 });
50
51 (function notificationRequest(){
52
53 if (urlParams.hasOwnProperty('notify')){
54 switch (urlParams.notify){
55 case 'new-project':
56 $("#project-created-notification").show();
57 break;
58 case 'layer-imported':
59 layerImportedNotification();
60 break;
61 default:
62 break;
63 }
64 }
65 })();
66
67 /* Layer imported notification */
68 function layerImportedNotification(){
69 var imported = $.cookie("layer-imported-alert");
70 var message = "Layer imported";
71
72 if (!imported)
73 return;
74 else
75 imported = JSON.parse(imported);
76
77 if (imported.deps_added.length === 0) {
78 message = "You have imported <strong><a href=\""+imported.imported_layer.layerdetailurl+"\">"+imported.imported_layer.name+"</a></strong> and added it to your project.";
79 } else {
80
81 var links = "<a href=\""+imported.imported_layer.layerdetailurl+"\">"+imported.imported_layer.name+"</a>, ";
82
83 imported.deps_added.map (function(item, index){
84 links +='<a href="'+item.layerdetailurl+'">'+item.name+'</a>';
85 /*If we're at the last element we don't want the trailing comma */
86 if (imported.deps_added[index+1] !== undefined)
87 links += ', ';
88 });
89
90 /* Length + 1 here to do deps + the imported layer */
91 message = 'You have imported <strong><a href="'+imported.imported_layer.layerdetailurl+'">'+imported.imported_layer.name+'</a></strong> and added <strong>'+(imported.deps_added.length+1)+'</strong> layers to your project: <strong>'+links+'</strong>';
92 }
93
94 libtoaster.showChangeNotification(message);
95
96 $.removeCookie("layer-imported-alert", { path: "/"});
97 }
98
99 /* Add/Rm layer functionality */
100
101 libtoaster.makeTypeahead(layerAddInput, libtoaster.ctx.layersTypeAheadUrl, { include_added: "false" }, function(item){
102 currentLayerAddSelection = item;
103 layerAddBtn.removeAttr("disabled");
104 });
105
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500106 layerAddInput.keyup(function() {
107 if ($(this).val().length == 0) {
108 layerAddBtn.attr("disabled", "disabled")
109 }
110 });
111
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500112 layerAddBtn.click(function(e){
113 e.preventDefault();
114 var layerObj = currentLayerAddSelection;
115
116 addRmLayer(layerObj, true);
117 /* Reset the text input */
118 layerAddInput.val("");
119 });
120
121 function addRmLayer(layerObj, add){
122
123 libtoaster.addRmLayer(layerObj, add, function(layerDepsList){
124 if (add){
125 updateProjectLayers([layerObj]);
126 updateProjectLayers(layerDepsList);
127 }
128
129 /* Show the alert message */
130 var message = libtoaster.makeLayerAddRmAlertMsg(layerObj, layerDepsList, add);
131 libtoaster.showChangeNotification(message);
132 });
133 }
134
135 function updateProjectLayers(layers){
136
137 /* No layers to add */
138 if (layers.length === 0){
139 updateLayersCount();
140 return;
141 }
142
143 for (var i in layers){
144 var layerObj = layers[i];
145
146 var projectLayer = $("<li><a></a><span class=\"icon-trash\" data-toggle=\"tooltip\" title=\"Delete\"></span></li>");
147
148 projectLayer.data('layer', layerObj);
149 projectLayer.children("span").tooltip();
150
151 var link = projectLayer.children("a");
152
153 link.attr("href", layerObj.layerdetailurl);
154 link.text(layerObj.name);
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500155 link.tooltip({title: layerObj.vcs_url + " | "+ layerObj.vcs_reference, placement: "right"});
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500156
157 var trashItem = projectLayer.children("span");
158 trashItem.click(function (e) {
159 e.preventDefault();
160 var layerObjToRm = $(this).parent().data('layer');
161
162 addRmLayer(layerObjToRm, false);
163
164 $(this).parent().fadeOut(function (){
165 $(this).remove();
166 updateLayersCount();
167 });
168 });
169
170 layersInPrjList.append(projectLayer);
171
172 updateLayersCount();
173 }
174 }
175
176 function updateLayersCount(){
177 var count = $("#layers-in-project-list").children().length;
178
179 if (count === 0)
180 $("#no-layers-in-project").fadeIn();
181 else
182 $("#no-layers-in-project").hide();
183
184 $("#project-layers-count").text(count);
185
186 return count;
187 }
188
189 /* Frequent builds functionality */
190 function updateFreqBuildRecipes(recipes) {
191 var noMostBuilt = $("#no-most-built");
192
193 if (recipes.length === 0){
194 noMostBuilt.show();
195 freqBuildBtn.hide();
196 } else {
197 noMostBuilt.hide();
198 freqBuildBtn.show();
199 }
200
201 for (var i in recipes){
202 var freqTargetCheck = $('<li><label class="checkbox"><input type="checkbox" /><span class="freq-target-name"></span></label></li>');
203 freqTargetCheck.find(".freq-target-name").text(recipes[i]);
204 freqTargetCheck.find("input").val(recipes[i]);
205 freqTargetCheck.click(function(){
206 if (freqBuildList.find(":checked").length > 0)
207 freqBuildBtn.removeAttr("disabled");
208 else
209 freqBuildBtn.attr("disabled", "disabled");
210 });
211
212 freqBuildList.append(freqTargetCheck);
213 }
214 }
215
216 freqBuildBtn.click(function(e){
217 e.preventDefault();
218
219 var toBuild = "";
220 freqBuildList.find(":checked").each(function(){
221 toBuild += $(this).val();
222 });
223
224 libtoaster.startABuild(libtoaster.ctx.projectBuildsUrl, libtoaster.ctx.projectId, toBuild, function(){
225 /* Build started */
226 window.location.replace(libtoaster.ctx.projectBuildsUrl);
227 },
228 function(){
229 /* Build start failed */
230 /* [YOCTO #7995] */
231 window.location.replace(libtoaster.ctx.projectBuildsUrl);
232 });
233 });
234
235
236 /* Change machine functionality */
237
238 machineChangeFormToggle.click(function(){
239 machineForm.slideDown();
240 machineNameTitle.hide();
241 $(this).hide();
242 });
243
244 machineChangeCancel.click(function(){
245 machineForm.slideUp(function(){
246 machineNameTitle.show();
247 machineChangeFormToggle.show();
248 });
249 });
250
251 function updateMachineName(machineName){
252 machineChangeInput.val(machineName);
253 machineNameTitle.text(machineName);
254 }
255
256 libtoaster.makeTypeahead(machineChangeInput, libtoaster.ctx.machinesTypeAheadUrl, { }, function(item){
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500257 currentMachineAddSelection = item.name;
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500258 machineChangeBtn.removeAttr("disabled");
259 });
260
261 machineChangeBtn.click(function(e){
262 e.preventDefault();
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500263 /* We accept any value regardless of typeahead selection or not */
264 if (machineChangeInput.val().length === 0)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500265 return;
266
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500267 currentMachineAddSelection = machineChangeInput.val();
268
269 libtoaster.editCurrentProject(
270 { machineName : currentMachineAddSelection },
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500271 function(){
272 /* Success machine changed */
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500273 updateMachineName(currentMachineAddSelection);
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500274 machineChangeCancel.click();
275
276 /* Show the alert message */
277 var message = $('<span class="lead">You have changed the machine to: <strong><span id="notify-machine-name"></span></strong></span>');
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500278 message.find("#notify-machine-name").text(currentMachineAddSelection);
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500279 libtoaster.showChangeNotification(message);
280 },
281 function(){
282 /* Failed machine changed */
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500283 console.warn("Failed to change machine");
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500284 });
285 });
286
287
288 /* Change release functionality */
289 function updateProjectRelease(release){
290 releaseTitle.text(release.description);
291 }
292
293 function updateProjectReleases(releases, current){
294 for (var i in releases){
295 var releaseOption = $("<option></option>");
296
297 releaseOption.val(releases[i].id);
298 releaseOption.text(releases[i].description);
299 releaseOption.data('release', releases[i]);
300
301 if (releases[i].id == current.id)
302 releaseOption.attr("selected", "selected");
303
304 releaseForm.children("select").append(releaseOption);
305 }
306 }
307
308 releaseChangeFormToggle.click(function(){
309 releaseForm.slideDown();
310 releaseTitle.hide();
311 $(this).hide();
312 });
313
314 cancelReleaseChange.click(function(e){
315 e.preventDefault();
316 releaseForm.slideUp(function(){
317 releaseTitle.show();
318 releaseChangeFormToggle.show();
319 });
320 });
321
322 function changeProjectRelease(release, layersToRm){
323 libtoaster.editCurrentProject({ projectVersion : release.id },
324 function(){
325 /* Success */
326 /* Update layers list with new layers */
327 layersInPrjList.addClass('muted');
328 libtoaster.getProjectInfo(libtoaster.ctx.projectPageUrl,
329 function(prjInfo){
330 layersInPrjList.children().remove();
331 updateProjectLayers(prjInfo.layers);
332 layersInPrjList.removeClass('muted');
333 releaseChangedNotification(release, prjInfo.layers, layersToRm);
334 });
335 updateProjectRelease(release);
336 cancelReleaseChange.click();
337 });
338 }
339
340 /* Create a notification to show the changes to the layer configuration
341 * caused by changing a release.
342 */
343
344 function releaseChangedNotification(release, layers, layersToRm){
345
346 var message;
347
348 if (layers.length === 0 && layersToRm.length === 0){
349 message = $('<span><span class="lead">You have changed the project release to: <strong><span id="notify-release-name"></span></strong>.');
350 message.find("#notify-release-name").text(release.description);
351 libtoaster.showChangeNotification(message);
352 return;
353 }
354
355 /* Create the whitespace separated list of layers removed */
356 var layersDelList = "";
357
358 layersToRm.map(function(layer, i){
359 layersDelList += layer.name;
360 if (layersToRm[i+1] !== undefined)
361 layersDelList += ', ';
362 });
363
364 message = $('<span><span class="lead">You have changed the project release to: <strong><span id="notify-release-name"></span></strong>. This has caused the following changes in your project layers:</span><ul id="notify-layers-changed-list"></ul></span>');
365
366 var changedList = message.find("#notify-layers-changed-list");
367
368 message.find("#notify-release-name").text(release.description);
369
370 /* Manually construct the list item for changed layers */
371 var li = '<li><strong>'+layers.length+'</strong> layers changed to the <strong>'+release.name+'</strong> release: ';
372 for (var i in layers){
373 li += '<a href='+layers[i].layerdetailurl+'>'+layers[i].name+'</a>';
374 if (i !== 0)
375 li += ', ';
376 }
377
378 changedList.append($(li));
379
380 /* Layers removed */
381 if (layersToRm && layersToRm.length > 0){
382 if (layersToRm.length == 1)
383 li = '<li><strong>1</strong> layer deleted: '+layersToRm[0].name+'</li>';
384 else
385 li = '<li><strong>'+layersToRm.length+'</strong> layers deleted: '+layersDelList+'</li>';
386
387 changedList.append($(li));
388 }
389
390 libtoaster.showChangeNotification(message);
391 }
392
393 /* Show the modal dialog which gives the option to remove layers which
394 * aren't compatible with the proposed release
395 */
396 function showReleaseLayerChangeModal(release, layers){
397 var layersToRmList = releaseModal.find("#layers-to-remove-list");
398 layersToRmList.text("");
399
400 releaseModal.find(".proposed-release-change-name").text(release.description);
401 releaseModal.data("layers", layers);
402 releaseModal.data("release", release);
403
404 for (var i in layers){
405 layersToRmList.append($("<li></li>").text(layers[i].name));
406 }
407 releaseModal.modal('show');
408 }
409
410 $("#change-release-btn").click(function(e){
411 e.preventDefault();
412
413 var newRelease = releaseForm.find("option:selected").data('release');
414
415 $.getJSON(ctx.testReleaseChangeUrl,
416 { new_release_id: newRelease.id },
417 function(layers) {
418 if (layers.rows.length === 0){
419 /* No layers to change for this release */
420 changeProjectRelease(newRelease, []);
421 } else {
422 showReleaseLayerChangeModal(newRelease, layers.rows);
423 }
424 });
425 });
426
427 /* Release change modal accept */
428 $("#change-release-and-rm-layers").click(function(){
429 var layers = releaseModal.data("layers");
430 var release = releaseModal.data("release");
431
432 changeProjectRelease(release, layers);
433 });
434
435}