1"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  var machineInputForm = $("#machine-input-form");
16  var invalidMachineNameHelp = $("#invalid-machine-name-help");
17
18  var distroChangeInput = $("#distro-change-input");
19  var distroChangeBtn = $("#distro-change-btn");
20  var distroForm = $("#select-distro-form");
21  var distroChangeFormToggle = $("#change-distro-toggle");
22  var distroNameTitle = $("#project-distro-name");
23  var distroChangeCancel = $("#cancel-distro-change");
24
25  var freqBuildBtn =  $("#freq-build-btn");
26  var freqBuildList = $("#freq-build-list");
27
28  var releaseChangeFormToggle = $("#release-change-toggle");
29  var releaseTitle = $("#project-release-title");
30  var releaseForm = $("#change-release-form");
31  var releaseModal = $("#change-release-modal");
32  var cancelReleaseChange = $("#cancel-release-change");
33
34  var currentLayerAddSelection;
35  var currentMachineAddSelection = "";
36  var currentDistroAddSelection = "";
37
38  var urlParams = libtoaster.parseUrlParams();
39
40  libtoaster.getProjectInfo(libtoaster.ctx.xhrProjectUrl, function(prjInfo){
41    updateProjectLayers(prjInfo.layers);
42    updateFreqBuildRecipes(prjInfo.freqtargets);
43    updateProjectRelease(prjInfo.release);
44
45    /* If we're receiving a machine set from the url and it's different from
46     * our current machine then activate set machine sequence.
47     */
48    if (urlParams.hasOwnProperty('setMachine') &&
49        urlParams.setMachine !== prjInfo.machine.name){
50        machineChangeInput.val(urlParams.setMachine);
51        machineChangeBtn.click();
52    } else {
53      updateMachineName(prjInfo.machine.name);
54    }
55
56    /* If we're receiving a distro set from the url and it's different from
57     * our current distro then activate set machine sequence.
58     */
59    if (urlParams.hasOwnProperty('setDistro') &&
60        urlParams.setDistro !== prjInfo.distro.name){
61        distroChangeInput.val(urlParams.setDistro);
62        distroChangeBtn.click();
63    } else {
64      updateDistroName(prjInfo.distro.name);
65    }
66
67   /* Now we're really ready show the page */
68    $("#project-page").show();
69
70    /* Set the project name in the delete modal */
71    $("#delete-project-modal .project-name").text(prjInfo.name);
72  });
73
74  if (urlParams.hasOwnProperty('notify') && urlParams.notify === 'new-project'){
75    $("#project-created-notification").show();
76  }
77
78  /* Add/Rm layer functionality */
79
80  libtoaster.makeTypeahead(layerAddInput, libtoaster.ctx.layersTypeAheadUrl, { include_added: "false" }, function(item){
81    currentLayerAddSelection = item;
82    layerAddBtn.removeAttr("disabled");
83  });
84
85  layerAddInput.keyup(function() {
86    if ($(this).val().length == 0) {
87      layerAddBtn.attr("disabled", "disabled")
88    }
89  });
90
91  layerAddBtn.click(function(e){
92    e.preventDefault();
93    var layerObj = currentLayerAddSelection;
94
95    addRmLayer(layerObj, true);
96    /* Reset the text input */
97    layerAddInput.val("");
98    /* Disable the add layer button*/
99    layerAddBtn.attr("disabled", "disabled");
100  });
101
102  function addRmLayer(layerObj, add){
103
104    libtoaster.addRmLayer(layerObj, add, function(layerDepsList){
105      if (add){
106        updateProjectLayers([layerObj]);
107        updateProjectLayers(layerDepsList);
108      }
109
110      /* Show the alert message */
111      var message = libtoaster.makeLayerAddRmAlertMsg(layerObj, layerDepsList, add);
112      libtoaster.showChangeNotification(message);
113    });
114  }
115
116  function updateProjectLayers(layers){
117
118    /* No layers to add */
119    if (layers.length === 0){
120      updateLayersCount();
121      return;
122    }
123
124    for (var i in layers){
125      var layerObj = layers[i];
126
127      var projectLayer = $("<li><a></a><span class=\"glyphicon glyphicon-trash\" data-toggle=\"tooltip\" title=\"Remove\"></span></li>");
128
129      projectLayer.data('layer', layerObj);
130      projectLayer.children("span").tooltip();
131
132      var link = projectLayer.children("a");
133
134      link.attr("href", layerObj.layerdetailurl);
135      link.text(layerObj.name);
136
137      if (layerObj.local_source_dir) {
138        link.tooltip({title: layerObj.local_source_dir, placement: "right"});
139      } else {
140        link.tooltip({title: layerObj.vcs_url + " | "+ layerObj.vcs_reference, placement: "right"});
141      }
142
143      var trashItem = projectLayer.children("span");
144      trashItem.click(function (e) {
145        e.preventDefault();
146        var layerObjToRm = $(this).parent().data('layer');
147
148        addRmLayer(layerObjToRm, false);
149
150        $(this).parent().fadeOut(function (){
151          $(this).remove();
152          updateLayersCount();
153        });
154      });
155
156      layersInPrjList.append(projectLayer);
157
158      updateLayersCount();
159    }
160  }
161
162  function updateLayersCount(){
163    var count = $("#layers-in-project-list").children().length;
164    var noLayerMsg = $("#no-layers-in-project");
165    var buildInput = $("#build-input");
166
167
168    if (count === 0) {
169      noLayerMsg.fadeIn();
170      $("#no-layers-in-project").fadeIn();
171      buildInput.attr("disabled", "disabled");
172    } else {
173      noLayerMsg.hide();
174      buildInput.removeAttr("disabled");
175    }
176
177    $("#project-layers-count").text(count);
178
179    return count;
180  }
181
182  /* Frequent builds functionality */
183  function updateFreqBuildRecipes(recipes) {
184    var noMostBuilt = $("#no-most-built");
185
186    if (recipes.length === 0){
187      noMostBuilt.show();
188      freqBuildBtn.hide();
189    } else {
190      noMostBuilt.hide();
191      freqBuildBtn.show();
192    }
193
194    for (var i in recipes){
195      var freqTargetCheck = $('<li><div class="checkbox"><label><input type="checkbox" /><span class="freq-target-name"></span></label></li>');
196      freqTargetCheck.find(".freq-target-name").text(recipes[i]);
197      freqTargetCheck.find("input").val(recipes[i]);
198      freqTargetCheck.click(function(){
199        if (freqBuildList.find(":checked").length > 0)
200          freqBuildBtn.removeAttr("disabled");
201        else
202          freqBuildBtn.attr("disabled", "disabled");
203      });
204
205      freqBuildList.append(freqTargetCheck);
206    }
207  }
208
209  freqBuildBtn.click(function(e){
210    e.preventDefault();
211
212    var toBuild = "";
213    freqBuildList.find(":checked").each(function(){
214      toBuild += $(this).val() + ' ';
215    });
216
217    toBuild = toBuild.trim();
218
219    libtoaster.startABuild(null, toBuild,
220      function(){
221        /* Build request started */
222        window.location.replace(libtoaster.ctx.projectBuildsUrl);
223      },
224      function(){
225        /* Build request failed */
226        console.warn("Build request failed to be created");
227    });
228  });
229
230
231  /* Change machine functionality */
232  machineChangeInput.keyup(function(){
233    if ($(this).val().indexOf(' ') >= 0) {
234        machineChangeBtn.attr("disabled", "disabled");
235        invalidMachineNameHelp.show();
236        machineInputForm.addClass('has-error');
237    } else {
238        machineChangeBtn.removeAttr("disabled");
239        invalidMachineNameHelp.hide();
240        machineInputForm.removeClass('has-error');
241    }
242  });
243
244  machineChangeFormToggle.click(function(){
245    machineChangeInput.val(machineNameTitle.text());
246    machineChangeBtn.removeAttr("disabled");
247    invalidMachineNameHelp.hide();
248    machineInputForm.removeClass('has-error');
249    machineForm.slideDown();
250    machineNameTitle.hide();
251    $(this).hide();
252  });
253
254  machineChangeCancel.click(function(){
255    machineForm.slideUp(function(){
256      machineNameTitle.show();
257      machineChangeFormToggle.show();
258    });
259  });
260
261  function updateMachineName(machineName){
262    machineChangeInput.val(machineName);
263    machineNameTitle.text(machineName);
264  }
265
266  libtoaster.makeTypeahead(machineChangeInput,
267                           libtoaster.ctx.machinesTypeAheadUrl,
268                           { }, function(item){
269    currentMachineAddSelection = item.name;
270    machineChangeBtn.removeAttr("disabled");
271  });
272
273  machineChangeBtn.click(function(e){
274    e.preventDefault();
275    /* We accept any value regardless of typeahead selection or not */
276    if (machineChangeInput.val().length === 0)
277      return;
278
279    currentMachineAddSelection = machineChangeInput.val();
280
281    libtoaster.editCurrentProject(
282      { machineName : currentMachineAddSelection },
283      function(){
284        /* Success machine changed */
285        updateMachineName(currentMachineAddSelection);
286        machineChangeCancel.click();
287
288        /* Show the alert message */
289        var message = $('<span>You have changed the machine to: <strong><span id="notify-machine-name"></span></strong></span>');
290        message.find("#notify-machine-name").text(currentMachineAddSelection);
291        libtoaster.showChangeNotification(message);
292    },
293      function(){
294        /* Failed machine changed */
295        console.warn("Failed to change machine");
296    });
297  });
298
299
300  /* Change distro functionality */
301
302  distroChangeFormToggle.click(function(){
303    distroForm.slideDown();
304    distroNameTitle.hide();
305    $(this).hide();
306  });
307
308  distroChangeCancel.click(function(){
309    distroForm.slideUp(function(){
310      distroNameTitle.show();
311      distroChangeFormToggle.show();
312    });
313  });
314
315  function updateDistroName(distroName){
316    distroChangeInput.val(distroName);
317    distroNameTitle.text(distroName);
318  }
319
320  libtoaster.makeTypeahead(distroChangeInput,
321                           libtoaster.ctx.distrosTypeAheadUrl,
322                           { }, function(item){
323    currentDistroAddSelection = item.name;
324    distroChangeBtn.removeAttr("disabled");
325  });
326
327  distroChangeBtn.click(function(e){
328    e.preventDefault();
329    /* We accept any value regardless of typeahead selection or not */
330    if (distroChangeInput.val().length === 0)
331      return;
332
333    currentDistroAddSelection = distroChangeInput.val();
334
335    libtoaster.editCurrentProject(
336      { distroName : currentDistroAddSelection },
337      function(){
338        /* Success machine changed */
339        updateDistroName(currentDistroAddSelection);
340        distroChangeCancel.click();
341
342        /* Show the alert message */
343        var message = $('<span>You have changed the distro to: <strong><span id="notify-machine-name"></span></strong></span>');
344        message.find("#notify-machine-name").text(currentDistroAddSelection);
345        libtoaster.showChangeNotification(message);
346    },
347      function(){
348        /* Failed machine changed */
349        console.warn("Failed to change distro");
350    });
351  });
352
353
354  /* Change release functionality */
355  function updateProjectRelease(release){
356    releaseTitle.text(release.description);
357  }
358
359
360  $("#delete-project-confirmed").click(function(e){
361    e.preventDefault();
362    libtoaster.disableAjaxLoadingTimer();
363    $(this).find('[data-role="submit-state"]').hide();
364    $(this).find('[data-role="loading-state"]').show();
365    $(this).attr("disabled", "disabled");
366    $('#delete-project-modal [data-dismiss="modal"]').hide();
367
368    $.ajax({
369        type: 'DELETE',
370        url: libtoaster.ctx.xhrProjectUrl,
371        headers: { 'X-CSRFToken' : $.cookie('csrftoken')},
372        success: function (data) {
373          if (data.error !== "ok") {
374            console.warn(data.error);
375          } else {
376            var msg =  $('<span>You have deleted <strong>1</strong> project: <strong id="project-deleted"></strong></span>');
377
378            msg.find("#project-deleted").text(libtoaster.ctx.projectName);
379            libtoaster.setNotification("project-deleted", msg.html());
380
381            window.location.replace(data.gotoUrl);
382          }
383        },
384        error: function (data) {
385          console.warn(data);
386        }
387    });
388  });
389
390}
391