16
16
var request_build_response_handler;
17
17
var request_daily_build_response_handler;
19
function set_up_lp_client() {
19
var DISABLED_DISTROSERIES_CHECKBOX_HTML =
20
"<input type='checkbox' class='checkboxType' disabled='disabled'>" +
21
" {distro} (build pending)";
23
var set_up_lp_client = function(io_provider) {
20
24
if (lp_client === undefined) {
21
lp_client = new Y.lp.client.Launchpad();
25
lp_client = new Y.lp.client.Launchpad({io_provider: io_provider});
27
// io_provider may be a different instance of MockIo.
28
lp_client.io_provider = io_provider;
25
32
// This handler is used to process the results of form submission or other
26
33
// such operation (eg get, post). It provides some boiler plate and allows the
61
68
namespace.RequestResponseHandler = RequestResponseHandler;
63
namespace.connect_requestbuilds = function() {
65
var request_build_handle = Y.one('#request-builds');
70
namespace.connect_requestbuilds = function(config) {
71
var io_provider = Y.lp.client.get_configured_io_provider(config),
72
request_build_handle = Y.one('#request-builds');
66
73
request_build_handle.addClass('js-action');
67
74
request_build_handle.on('click', function(e) {
68
75
e.preventDefault();
69
if (request_build_overlay == null) {
76
if (request_build_overlay === null) {
70
77
// Render the form and load the widgets to display
71
var recipe_name = LP.cache.context['name'];
78
var recipe_name = LP.cache.context.name;
72
79
request_build_overlay = new Y.lazr.FormOverlay({
73
80
headerContent: '<h2>Request builds for '
74
81
+ recipe_name + ' </h2>',
251
263
* Render build records and flash the new ones
253
function display_build_records(build_records_markup, current_builds) {
265
var display_build_records = function (build_records_markup, current_builds) {
254
266
var target = Y.one('#builds-target');
255
267
target.set('innerHTML', build_records_markup);
256
268
var new_builds = harvest_current_build_records();
257
269
var nr_new_builds = 0;
258
270
Y.Array.each(new_builds, function(row_id) {
259
if( current_builds.indexOf(row_id)>=0 )
271
if( current_builds.indexOf(row_id)>=0 ) {
261
274
nr_new_builds += 1;
262
275
var row = Y.one('#'+row_id);
263
276
var anim = Y.lp.anim.green_flash({node: row});
266
279
return nr_new_builds;
270
283
* Perform any client side validation
271
284
* Return: true if data is valid
273
function validate(data) {
274
var distros = data['field.distroseries']
275
if (Y.Object.size(distros) == 0) {
286
var validate = function(data) {
287
var distros = data['field.distroseries'];
288
if (Y.Object.size(distros) === 0) {
276
289
request_build_response_handler.showError(
277
290
"You need to specify at least one distro series for " +
278
291
"which to build.", null);
285
298
* The form submit function
287
function do_request_builds(data) {
300
var do_request_builds = function(data, io_provider) {
301
if (!validate(data)) {
290
304
request_build_submit_button.setAttribute("disabled", "disabled");
291
305
var spinner_location = Y.one('.yui3-lazr-formoverlay-actions');
292
306
create_temporary_spinner("Requesting builds...", spinner_location);
301
315
failure: request_build_response_handler.getErrorHandler(
302
316
function(handler, id, response) {
319
error_header_text = "",
320
build_info, build_html, error_info,
321
nr_new, new_builds_message, field_name;
303
322
if( response.status >= 500 ) {
304
323
// There's some error content we need to display.
305
request_build_overlay.set(
306
'form_content', response.responseText);
307
request_build_overlay.get("form_submit_button")
309
request_build_overlay.renderUI();
310
//We want to force the form to be re-created
311
request_build_overlay = null;
314
// The response will be a json data object containing info
315
// about what builds there are, informational text about
316
// any builds already pending, plus any errors. The
317
// FormOverlay infrastructure only supports displaying
318
// errors so we will construct our own HTML where the
319
// informational text will be appropriately displayed.
320
var build_info = Y.JSON.parse(response.responseText);
322
// The result of rendering the +builds view
323
var build_html = build_info['builds'];
324
// Any builds already pending (informational only)
325
var pending_build_info = build_info['already_pending'];
326
// Other more critical errors
327
var error_info = build_info['errors'];
329
var error_header_text = "";
330
if (build_html != null) {
331
var nr_new = display_build_records(
332
build_html, current_builds);
333
var new_builds_message = ONE_BUILD_MESSAGE;
340
error_header_text = new_builds_message;
342
if (pending_build_info != null) {
343
if (error_header_text != "" )
344
error_header_text += "<p/>" + pending_build_info;
346
error_header_text = pending_build_info;
349
for (var field_name in error_info)
350
errors.push(error_info[field_name]);
352
if (error_header_text != "") {
325
response.status + ' ' + response.statusText];
327
// The response will be a json data object containing
328
// info about what builds there are, informational
329
// text about any builds already pending, plus any
330
// errors. The FormOverlay infrastructure only
331
// supports displaying errors so we will construct
332
// our own HTML where the informational text will be
333
// appropriately displayed.
334
build_info = Y.JSON.parse(response.responseText);
336
// The result of rendering the +builds view
337
build_html = build_info.builds;
338
// Any builds already pending (informational only)
339
pending_build_info = build_info.already_pending;
340
// Other more critical errors
341
error_info = build_info.errors;
343
if (build_html !== null) {
344
nr_new = display_build_records(
345
build_html, current_builds);
346
new_builds_message = ONE_BUILD_MESSAGE;
353
error_header_text = new_builds_message;
355
if (pending_build_info !== null) {
356
if (error_header_text !== "" ) {
357
error_header_text += "<p/>" +
360
error_header_text = pending_build_info;
363
for (field_name in error_info) {
364
if (error_info.hasOwnProperty(field_name)) {
365
errors.push(error_info[field_name]);
368
if (error_header_text !== "") {
354
370
"<p><div class='popup-build-informational'>"
355
+error_header_text+"</p></div>";
356
if (Y.Object.size(errors)>0) {
371
+ error_header_text + "</p></div>";
372
if (Y.Object.size(errors)>0) {
358
374
"<p/>" + "There were also some errors:";
377
error_header = "There were some errors:";
361
error_header = "There were some errors:"
363
380
handler.showError(error_header, errors);
410
427
// restore it when needed.
411
428
var distroseries_node_html;
413
function get_distroseries_nodes() {
430
var get_distroseries_nodes = function() {
414
431
return request_build_overlay.form_node.all(
415
432
"label[for^='field.distroseries.']");
418
var DISABLED_DISTROSERIES_CHECKBOX_HTML =
419
"<input type='checkbox' class='checkboxType' disabled='disabled'>" +
420
" {distro} (build pending)";
423
436
* Callback used to enable/disable distro series selection when a different
424
437
* ppa is selected.
426
function ppa_changed(ppa_value, submit_button) {
439
var ppa_changed = function(ppa_value, submit_button) {
427
440
// Reset the disro series checkboxs to their default html.
428
var distroseries_nodes = get_distroseries_nodes();
429
for (var i=0; i<distroseries_nodes.size(); i++) {
430
var distroseries_node = distroseries_nodes.item(i);
441
var distroseries_nodes = get_distroseries_nodes(),
442
distroseries_node, distro, escaped_distro,
443
disabled_checkbox_html, i;
444
for (i = 0; i < distroseries_nodes.size(); i++) {
445
distroseries_node = distroseries_nodes.item(i);
431
446
distroseries_node.set("innerHTML", distroseries_node_html[i]);
432
447
distroseries_node.removeClass("lowlight");
435
450
var nr_matches = 0;
436
451
Y.Array.each(last_known_pending_builds, function(distroarchive) {
437
if (ppa_value != distroarchive[1])
452
if (ppa_value !== distroarchive[1]) {
440
for (var i=0; i<distroseries_nodes.size(); i++) {
441
var distroseries_node = distroseries_nodes.item(i);
442
var distro = distroseries_node.get("text").trim();
443
if (distro == distroarchive[0]) {
456
for (i = 0; i < distroseries_nodes.size(); i++) {
457
distroseries_node = distroseries_nodes.item(i);
458
distro = distroseries_node.get("text").trim();
459
if (distro === distroarchive[0]) {
445
var escaped_distro = Y.Escape.html(distro);
446
var disabled_checkbox_html = Y.Lang.substitute(
461
escaped_distro = Y.Escape.html(distro);
462
disabled_checkbox_html = Y.Lang.substitute(
447
463
DISABLED_DISTROSERIES_CHECKBOX_HTML,
448
464
{distro: escaped_distro});
449
465
distroseries_node.set("innerHTML", disabled_checkbox_html);
455
471
// If no distro series can be selected, no need to show the submit btn.
456
if (nr_matches>0 && nr_matches == distroseries_nodes.size())
472
if (nr_matches>0 && nr_matches === distroseries_nodes.size()) {
457
473
submit_button.hide();
459
475
submit_button.show();
462
function disable_existing_builds(submit_button) {
479
var disable_existing_builds = function(submit_button, io_provider) {
463
480
// Lookup a the exiting builds and parse the info into a data structure so
464
481
// so that we can attempt to prevent the user from requesting builds
465
482
// which are already pending. It's not foolproof since a build may finish
466
483
// or be initiated after this initial lookup, but we do handle that
467
484
// situation in the error handling.
485
var ppa_selector, y_config;
469
487
// The ui may not be ready yet.
470
var ppa_selector = request_build_overlay.form_node.one(
488
ppa_selector = request_build_overlay.form_node.one(
471
489
"[name='field.archive']");
472
if (ppa_selector == null) {
490
if (ppa_selector === null) {
475
distroseries_node_html = new Array();
476
last_known_pending_builds = new Array();
493
distroseries_node_html = [];
494
last_known_pending_builds = [];
478
496
headers: {'Accept': 'application/json;'},
481
499
function(build_info) {
501
size, build_record, distro_name, archive_token;
482
502
// We save the inner html of each distro series checkbox
483
503
// so we can restore it when required.
484
var distro_nodes = get_distroseries_nodes();
504
distro_nodes = get_distroseries_nodes();
485
505
distro_nodes.each(function(distro_node) {
486
506
distroseries_node_html.push(
487
507
distro_node.get("innerHTML"));
490
510
// We have a collection of the pending build info.
491
511
// The info is the distroseries displayname and archive
493
var size = build_info.length;
494
for( var i=0; i<size; i++ ) {
495
var build_record = build_info[i];
496
var distro_name = build_record["distroseries"];
497
var archive_token = build_record["archive"];
513
size = build_info.length;
514
for ( i = 0; i < size; i++ ) {
515
build_record = build_info[i];
516
distro_name = build_record.distroseries;
517
archive_token = build_record.archive;
498
518
last_known_pending_builds.push(
499
519
[distro_name, archive_token]);