blob: d36704751cb02cac3fa1b8dc85b902a82d746c08 [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;
26 var currentMachineAddSelection = {};
27
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){
41 currentMachineAddSelection.name = urlParams.setMachine;
42 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
106 layerAddBtn.click(function(e){
107 e.preventDefault();
108 var layerObj = currentLayerAddSelection;
109
110 addRmLayer(layerObj, true);
111 /* Reset the text input */
112 layerAddInput.val("");
113 });
114
115 function addRmLayer(layerObj, add){
116
117 libtoaster.addRmLayer(layerObj, add, function(layerDepsList){
118 if (add){
119 updateProjectLayers([layerObj]);
120 updateProjectLayers(layerDepsList);
121 }
122
123 /* Show the alert message */
124 var message = libtoaster.makeLayerAddRmAlertMsg(layerObj, layerDepsList, add);
125 libtoaster.showChangeNotification(message);
126 });
127 }
128
129 function updateProjectLayers(layers){
130
131 /* No layers to add */
132 if (layers.length === 0){
133 updateLayersCount();
134 return;
135 }
136
137 for (var i in layers){
138 var layerObj = layers[i];
139
140 var projectLayer = $("<li><a></a><span class=\"icon-trash\" data-toggle=\"tooltip\" title=\"Delete\"></span></li>");
141
142 projectLayer.data('layer', layerObj);
143 projectLayer.children("span").tooltip();
144
145 var link = projectLayer.children("a");
146
147 link.attr("href", layerObj.layerdetailurl);
148 link.text(layerObj.name);
149 /* YOCTO #8024
150 link.tooltip({title: layerObj.giturl + " | "+ layerObj.branch.name, placement: "right"});
151 branch name not accessible sometimes it is revision instead
152 */
153
154 var trashItem = projectLayer.children("span");
155 trashItem.click(function (e) {
156 e.preventDefault();
157 var layerObjToRm = $(this).parent().data('layer');
158
159 addRmLayer(layerObjToRm, false);
160
161 $(this).parent().fadeOut(function (){
162 $(this).remove();
163 updateLayersCount();
164 });
165 });
166
167 layersInPrjList.append(projectLayer);
168
169 updateLayersCount();
170 }
171 }
172
173 function updateLayersCount(){
174 var count = $("#layers-in-project-list").children().length;
175
176 if (count === 0)
177 $("#no-layers-in-project").fadeIn();
178 else
179 $("#no-layers-in-project").hide();
180
181 $("#project-layers-count").text(count);
182
183 return count;
184 }
185
186 /* Frequent builds functionality */
187 function updateFreqBuildRecipes(recipes) {
188 var noMostBuilt = $("#no-most-built");
189
190 if (recipes.length === 0){
191 noMostBuilt.show();
192 freqBuildBtn.hide();
193 } else {
194 noMostBuilt.hide();
195 freqBuildBtn.show();
196 }
197
198 for (var i in recipes){
199 var freqTargetCheck = $('<li><label class="checkbox"><input type="checkbox" /><span class="freq-target-name"></span></label></li>');
200 freqTargetCheck.find(".freq-target-name").text(recipes[i]);
201 freqTargetCheck.find("input").val(recipes[i]);
202 freqTargetCheck.click(function(){
203 if (freqBuildList.find(":checked").length > 0)
204 freqBuildBtn.removeAttr("disabled");
205 else
206 freqBuildBtn.attr("disabled", "disabled");
207 });
208
209 freqBuildList.append(freqTargetCheck);
210 }
211 }
212
213 freqBuildBtn.click(function(e){
214 e.preventDefault();
215
216 var toBuild = "";
217 freqBuildList.find(":checked").each(function(){
218 toBuild += $(this).val();
219 });
220
221 libtoaster.startABuild(libtoaster.ctx.projectBuildsUrl, libtoaster.ctx.projectId, toBuild, function(){
222 /* Build started */
223 window.location.replace(libtoaster.ctx.projectBuildsUrl);
224 },
225 function(){
226 /* Build start failed */
227 /* [YOCTO #7995] */
228 window.location.replace(libtoaster.ctx.projectBuildsUrl);
229 });
230 });
231
232
233 /* Change machine functionality */
234
235 machineChangeFormToggle.click(function(){
236 machineForm.slideDown();
237 machineNameTitle.hide();
238 $(this).hide();
239 });
240
241 machineChangeCancel.click(function(){
242 machineForm.slideUp(function(){
243 machineNameTitle.show();
244 machineChangeFormToggle.show();
245 });
246 });
247
248 function updateMachineName(machineName){
249 machineChangeInput.val(machineName);
250 machineNameTitle.text(machineName);
251 }
252
253 libtoaster.makeTypeahead(machineChangeInput, libtoaster.ctx.machinesTypeAheadUrl, { }, function(item){
254 currentMachineAddSelection = item;
255 machineChangeBtn.removeAttr("disabled");
256 });
257
258 machineChangeBtn.click(function(e){
259 e.preventDefault();
260 if (currentMachineAddSelection.name === undefined)
261 return;
262
263 libtoaster.editCurrentProject({ machineName : currentMachineAddSelection.name },
264 function(){
265 /* Success machine changed */
266 updateMachineName(currentMachineAddSelection.name);
267 machineChangeCancel.click();
268
269 /* Show the alert message */
270 var message = $('<span class="lead">You have changed the machine to: <strong><span id="notify-machine-name"></span></strong></span>');
271 message.find("#notify-machine-name").text(currentMachineAddSelection.name);
272 libtoaster.showChangeNotification(message);
273 },
274 function(){
275 /* Failed machine changed */
276 console.log("failed to change machine");
277 });
278 });
279
280
281 /* Change release functionality */
282 function updateProjectRelease(release){
283 releaseTitle.text(release.description);
284 }
285
286 function updateProjectReleases(releases, current){
287 for (var i in releases){
288 var releaseOption = $("<option></option>");
289
290 releaseOption.val(releases[i].id);
291 releaseOption.text(releases[i].description);
292 releaseOption.data('release', releases[i]);
293
294 if (releases[i].id == current.id)
295 releaseOption.attr("selected", "selected");
296
297 releaseForm.children("select").append(releaseOption);
298 }
299 }
300
301 releaseChangeFormToggle.click(function(){
302 releaseForm.slideDown();
303 releaseTitle.hide();
304 $(this).hide();
305 });
306
307 cancelReleaseChange.click(function(e){
308 e.preventDefault();
309 releaseForm.slideUp(function(){
310 releaseTitle.show();
311 releaseChangeFormToggle.show();
312 });
313 });
314
315 function changeProjectRelease(release, layersToRm){
316 libtoaster.editCurrentProject({ projectVersion : release.id },
317 function(){
318 /* Success */
319 /* Update layers list with new layers */
320 layersInPrjList.addClass('muted');
321 libtoaster.getProjectInfo(libtoaster.ctx.projectPageUrl,
322 function(prjInfo){
323 layersInPrjList.children().remove();
324 updateProjectLayers(prjInfo.layers);
325 layersInPrjList.removeClass('muted');
326 releaseChangedNotification(release, prjInfo.layers, layersToRm);
327 });
328 updateProjectRelease(release);
329 cancelReleaseChange.click();
330 });
331 }
332
333 /* Create a notification to show the changes to the layer configuration
334 * caused by changing a release.
335 */
336
337 function releaseChangedNotification(release, layers, layersToRm){
338
339 var message;
340
341 if (layers.length === 0 && layersToRm.length === 0){
342 message = $('<span><span class="lead">You have changed the project release to: <strong><span id="notify-release-name"></span></strong>.');
343 message.find("#notify-release-name").text(release.description);
344 libtoaster.showChangeNotification(message);
345 return;
346 }
347
348 /* Create the whitespace separated list of layers removed */
349 var layersDelList = "";
350
351 layersToRm.map(function(layer, i){
352 layersDelList += layer.name;
353 if (layersToRm[i+1] !== undefined)
354 layersDelList += ', ';
355 });
356
357 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>');
358
359 var changedList = message.find("#notify-layers-changed-list");
360
361 message.find("#notify-release-name").text(release.description);
362
363 /* Manually construct the list item for changed layers */
364 var li = '<li><strong>'+layers.length+'</strong> layers changed to the <strong>'+release.name+'</strong> release: ';
365 for (var i in layers){
366 li += '<a href='+layers[i].layerdetailurl+'>'+layers[i].name+'</a>';
367 if (i !== 0)
368 li += ', ';
369 }
370
371 changedList.append($(li));
372
373 /* Layers removed */
374 if (layersToRm && layersToRm.length > 0){
375 if (layersToRm.length == 1)
376 li = '<li><strong>1</strong> layer deleted: '+layersToRm[0].name+'</li>';
377 else
378 li = '<li><strong>'+layersToRm.length+'</strong> layers deleted: '+layersDelList+'</li>';
379
380 changedList.append($(li));
381 }
382
383 libtoaster.showChangeNotification(message);
384 }
385
386 /* Show the modal dialog which gives the option to remove layers which
387 * aren't compatible with the proposed release
388 */
389 function showReleaseLayerChangeModal(release, layers){
390 var layersToRmList = releaseModal.find("#layers-to-remove-list");
391 layersToRmList.text("");
392
393 releaseModal.find(".proposed-release-change-name").text(release.description);
394 releaseModal.data("layers", layers);
395 releaseModal.data("release", release);
396
397 for (var i in layers){
398 layersToRmList.append($("<li></li>").text(layers[i].name));
399 }
400 releaseModal.modal('show');
401 }
402
403 $("#change-release-btn").click(function(e){
404 e.preventDefault();
405
406 var newRelease = releaseForm.find("option:selected").data('release');
407
408 $.getJSON(ctx.testReleaseChangeUrl,
409 { new_release_id: newRelease.id },
410 function(layers) {
411 if (layers.rows.length === 0){
412 /* No layers to change for this release */
413 changeProjectRelease(newRelease, []);
414 } else {
415 showReleaseLayerChangeModal(newRelease, layers.rows);
416 }
417 });
418 });
419
420 /* Release change modal accept */
421 $("#change-release-and-rm-layers").click(function(){
422 var layers = releaseModal.data("layers");
423 var release = releaseModal.data("release");
424
425 changeProjectRelease(release, layers);
426 });
427
428}