blob: 3013416dd1ef8914bfb742128c349e247c5b0187 [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("");
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500119 /* Disable the add layer button*/
120 layerAddBtn.attr("disabled", "disabled");
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500121 });
122
123 function addRmLayer(layerObj, add){
124
125 libtoaster.addRmLayer(layerObj, add, function(layerDepsList){
126 if (add){
127 updateProjectLayers([layerObj]);
128 updateProjectLayers(layerDepsList);
129 }
130
131 /* Show the alert message */
132 var message = libtoaster.makeLayerAddRmAlertMsg(layerObj, layerDepsList, add);
133 libtoaster.showChangeNotification(message);
134 });
135 }
136
137 function updateProjectLayers(layers){
138
139 /* No layers to add */
140 if (layers.length === 0){
141 updateLayersCount();
142 return;
143 }
144
145 for (var i in layers){
146 var layerObj = layers[i];
147
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500148 var projectLayer = $("<li><a></a><span class=\"icon-trash\" data-toggle=\"tooltip\" title=\"Remove\"></span></li>");
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500149
150 projectLayer.data('layer', layerObj);
151 projectLayer.children("span").tooltip();
152
153 var link = projectLayer.children("a");
154
155 link.attr("href", layerObj.layerdetailurl);
156 link.text(layerObj.name);
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500157 link.tooltip({title: layerObj.vcs_url + " | "+ layerObj.vcs_reference, placement: "right"});
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500158
159 var trashItem = projectLayer.children("span");
160 trashItem.click(function (e) {
161 e.preventDefault();
162 var layerObjToRm = $(this).parent().data('layer');
163
164 addRmLayer(layerObjToRm, false);
165
166 $(this).parent().fadeOut(function (){
167 $(this).remove();
168 updateLayersCount();
169 });
170 });
171
172 layersInPrjList.append(projectLayer);
173
174 updateLayersCount();
175 }
176 }
177
178 function updateLayersCount(){
179 var count = $("#layers-in-project-list").children().length;
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500180 var noLayerMsg = $("#no-layers-in-project");
181 var buildInput = $("#build-input");
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500182
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500183
184 if (count === 0) {
185 noLayerMsg.fadeIn();
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500186 $("#no-layers-in-project").fadeIn();
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500187 buildInput.attr("disabled", "disabled");
188 } else {
189 noLayerMsg.hide();
190 buildInput.removeAttr("disabled");
191 }
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500192
193 $("#project-layers-count").text(count);
194
195 return count;
196 }
197
198 /* Frequent builds functionality */
199 function updateFreqBuildRecipes(recipes) {
200 var noMostBuilt = $("#no-most-built");
201
202 if (recipes.length === 0){
203 noMostBuilt.show();
204 freqBuildBtn.hide();
205 } else {
206 noMostBuilt.hide();
207 freqBuildBtn.show();
208 }
209
210 for (var i in recipes){
211 var freqTargetCheck = $('<li><label class="checkbox"><input type="checkbox" /><span class="freq-target-name"></span></label></li>');
212 freqTargetCheck.find(".freq-target-name").text(recipes[i]);
213 freqTargetCheck.find("input").val(recipes[i]);
214 freqTargetCheck.click(function(){
215 if (freqBuildList.find(":checked").length > 0)
216 freqBuildBtn.removeAttr("disabled");
217 else
218 freqBuildBtn.attr("disabled", "disabled");
219 });
220
221 freqBuildList.append(freqTargetCheck);
222 }
223 }
224
225 freqBuildBtn.click(function(e){
226 e.preventDefault();
227
228 var toBuild = "";
229 freqBuildList.find(":checked").each(function(){
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500230 toBuild += $(this).val() + ' ';
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500231 });
232
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500233 toBuild = toBuild.trim();
234
235 libtoaster.startABuild(null, toBuild,
236 function(){
237 /* Build request started */
238 window.location.replace(libtoaster.ctx.projectBuildsUrl);
239 },
240 function(){
241 /* Build request failed */
242 console.warn("Build request failed to be created");
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500243 });
244 });
245
246
247 /* Change machine functionality */
248
249 machineChangeFormToggle.click(function(){
250 machineForm.slideDown();
251 machineNameTitle.hide();
252 $(this).hide();
253 });
254
255 machineChangeCancel.click(function(){
256 machineForm.slideUp(function(){
257 machineNameTitle.show();
258 machineChangeFormToggle.show();
259 });
260 });
261
262 function updateMachineName(machineName){
263 machineChangeInput.val(machineName);
264 machineNameTitle.text(machineName);
265 }
266
267 libtoaster.makeTypeahead(machineChangeInput, libtoaster.ctx.machinesTypeAheadUrl, { }, function(item){
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500268 currentMachineAddSelection = item.name;
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500269 machineChangeBtn.removeAttr("disabled");
270 });
271
272 machineChangeBtn.click(function(e){
273 e.preventDefault();
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500274 /* We accept any value regardless of typeahead selection or not */
275 if (machineChangeInput.val().length === 0)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500276 return;
277
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500278 currentMachineAddSelection = machineChangeInput.val();
279
280 libtoaster.editCurrentProject(
281 { machineName : currentMachineAddSelection },
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500282 function(){
283 /* Success machine changed */
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500284 updateMachineName(currentMachineAddSelection);
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500285 machineChangeCancel.click();
286
287 /* Show the alert message */
288 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 -0500289 message.find("#notify-machine-name").text(currentMachineAddSelection);
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500290 libtoaster.showChangeNotification(message);
291 },
292 function(){
293 /* Failed machine changed */
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500294 console.warn("Failed to change machine");
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500295 });
296 });
297
298
299 /* Change release functionality */
300 function updateProjectRelease(release){
301 releaseTitle.text(release.description);
302 }
303
304 function updateProjectReleases(releases, current){
305 for (var i in releases){
306 var releaseOption = $("<option></option>");
307
308 releaseOption.val(releases[i].id);
309 releaseOption.text(releases[i].description);
310 releaseOption.data('release', releases[i]);
311
312 if (releases[i].id == current.id)
313 releaseOption.attr("selected", "selected");
314
315 releaseForm.children("select").append(releaseOption);
316 }
317 }
318
319 releaseChangeFormToggle.click(function(){
320 releaseForm.slideDown();
321 releaseTitle.hide();
322 $(this).hide();
323 });
324
325 cancelReleaseChange.click(function(e){
326 e.preventDefault();
327 releaseForm.slideUp(function(){
328 releaseTitle.show();
329 releaseChangeFormToggle.show();
330 });
331 });
332
333 function changeProjectRelease(release, layersToRm){
334 libtoaster.editCurrentProject({ projectVersion : release.id },
335 function(){
336 /* Success */
337 /* Update layers list with new layers */
338 layersInPrjList.addClass('muted');
339 libtoaster.getProjectInfo(libtoaster.ctx.projectPageUrl,
340 function(prjInfo){
341 layersInPrjList.children().remove();
342 updateProjectLayers(prjInfo.layers);
343 layersInPrjList.removeClass('muted');
344 releaseChangedNotification(release, prjInfo.layers, layersToRm);
345 });
346 updateProjectRelease(release);
347 cancelReleaseChange.click();
348 });
349 }
350
351 /* Create a notification to show the changes to the layer configuration
352 * caused by changing a release.
353 */
354
355 function releaseChangedNotification(release, layers, layersToRm){
356
357 var message;
358
359 if (layers.length === 0 && layersToRm.length === 0){
360 message = $('<span><span class="lead">You have changed the project release to: <strong><span id="notify-release-name"></span></strong>.');
361 message.find("#notify-release-name").text(release.description);
362 libtoaster.showChangeNotification(message);
363 return;
364 }
365
366 /* Create the whitespace separated list of layers removed */
367 var layersDelList = "";
368
369 layersToRm.map(function(layer, i){
370 layersDelList += layer.name;
371 if (layersToRm[i+1] !== undefined)
372 layersDelList += ', ';
373 });
374
375 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>');
376
377 var changedList = message.find("#notify-layers-changed-list");
378
379 message.find("#notify-release-name").text(release.description);
380
381 /* Manually construct the list item for changed layers */
382 var li = '<li><strong>'+layers.length+'</strong> layers changed to the <strong>'+release.name+'</strong> release: ';
383 for (var i in layers){
384 li += '<a href='+layers[i].layerdetailurl+'>'+layers[i].name+'</a>';
385 if (i !== 0)
386 li += ', ';
387 }
388
389 changedList.append($(li));
390
391 /* Layers removed */
392 if (layersToRm && layersToRm.length > 0){
393 if (layersToRm.length == 1)
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500394 li = '<li><strong>1</strong> layer removed: '+layersToRm[0].name+'</li>';
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500395 else
396 li = '<li><strong>'+layersToRm.length+'</strong> layers deleted: '+layersDelList+'</li>';
397
398 changedList.append($(li));
399 }
400
401 libtoaster.showChangeNotification(message);
402 }
403
404 /* Show the modal dialog which gives the option to remove layers which
405 * aren't compatible with the proposed release
406 */
407 function showReleaseLayerChangeModal(release, layers){
408 var layersToRmList = releaseModal.find("#layers-to-remove-list");
409 layersToRmList.text("");
410
411 releaseModal.find(".proposed-release-change-name").text(release.description);
412 releaseModal.data("layers", layers);
413 releaseModal.data("release", release);
414
415 for (var i in layers){
416 layersToRmList.append($("<li></li>").text(layers[i].name));
417 }
418 releaseModal.modal('show');
419 }
420
421 $("#change-release-btn").click(function(e){
422 e.preventDefault();
423
424 var newRelease = releaseForm.find("option:selected").data('release');
425
426 $.getJSON(ctx.testReleaseChangeUrl,
427 { new_release_id: newRelease.id },
428 function(layers) {
429 if (layers.rows.length === 0){
430 /* No layers to change for this release */
431 changeProjectRelease(newRelease, []);
432 } else {
433 showReleaseLayerChangeModal(newRelease, layers.rows);
434 }
435 });
436 });
437
438 /* Release change modal accept */
439 $("#change-release-and-rm-layers").click(function(){
440 var layers = releaseModal.data("layers");
441 var release = releaseModal.data("release");
442
443 changeProjectRelease(release, layers);
444 });
445
446}