Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Load build results on dashboard via AJAX #2355

Merged
merged 1 commit into from
Sep 30, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion assets/javascripts/filter_form.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
function setupFilterForm() {
function setupFilterForm(options) {
// make filter form expandable
$('#filter-panel .card-header').on('click', function() {
$('#filter-panel .card-body').toggle(200);
Expand All @@ -13,6 +13,10 @@ function setupFilterForm() {
event.stopPropagation();
});

if (options && options.preventLoadingIndication) {
return;
}

$('#filter-form').on('submit', function(event) {
if($('#filter-form').serialize() !== window.location.search.substring(1)) {
// show progress indication
Expand Down
37 changes: 19 additions & 18 deletions assets/javascripts/fullscreen.js
Original file line number Diff line number Diff line change
@@ -1,34 +1,35 @@
function hideNavbar(fullscreen) {
// do nothing if not in full screen mode
if (!$('#filter-fullscreen').is(':checked') && fullscreen !== 1) {
return;
}

function toggleFullscreenMode(fullscreen) {
// change ID of main container (to change applied CSS rules)
$("#content").attr('id', 'content_fullscreen');
$('#content').attr('id', fullscreen ? 'content_fullscreen' : 'content');

// hide some elements
$(".navbar, .footer, .jumbotron").hide();
if (fullscreen === 1) {
$("#group_description").hide();
}
// change visiblity of some elements
$('.navbar, .footer, .jumbotron, #group_description')[fullscreen ? 'hide' : 'show']();

// toggle navbar visibility
var navbar = $(".navbar");
var navbar = $('.navbar');
var navbarHeight = navbar.outerHeight();
document.addEventListener('mousemove', function(e) {
var handler = document.showNavbarIfItWouldContainMouse;
if (!fullscreen) {
if (handler === undefined) {
return;
}
document.removeEventListener('mousemove', handler, false);
return;
}
handler = document.showNavbarIfItWouldContainMouse = function(e) {
var mouseY = e.clientY || e.pageY;
if (mouseY <= navbarHeight || navbar.find("[aria-expanded='true']").length != 0) {
if (mouseY <= navbarHeight || navbar.find("[aria-expanded='true']").length !== 0) {
navbar.show();
}
else if (mouseY > navbarHeight && !$("li").hasClass('dropdown open')) {
else if (mouseY > navbarHeight && !$('li').hasClass('dropdown open')) {
navbar.hide();
}
}, false);
};
document.addEventListener('mousemove', handler, false);
}

function autoRefresh(fullscreen, interval) {
if (fullscreen != 1) {
if (!fullscreen) {
return;
}
$($(document).ready(function() {
Expand Down
82 changes: 67 additions & 15 deletions assets/javascripts/index.js
Original file line number Diff line number Diff line change
@@ -1,27 +1,31 @@
function setupIndexPage() {
$('.timeago').timeago();

setupFilterForm();
$('#filter-show-tags').prop('checked', false);
$('#filter-only-tagged').prop('checked', false);
$('#filter-fullscreen').prop('checked', false);
$('#filter-only-tagged').on('change', function() {
var checked = $('#filter-only-tagged').prop('checked');
var showTagsElement = $('#filter-show-tags');
setupFilterForm({preventLoadingIndication: true});

var filterFullScreenCheckBox = $('#filter-fullscreen');
var showTagsCheckBox = $('#filter-show-tags');
var onlyTaggedCheckBox = $('#filter-only-tagged');
var defaultExpanedCheckBox = $('#filter-default-expanded');
filterFullScreenCheckBox.prop('checked', false);
showTagsCheckBox.prop('checked', false);
onlyTaggedCheckBox.prop('checked', false);
onlyTaggedCheckBox.on('change', function() {
var checked = onlyTaggedCheckBox.prop('checked');
if (checked) {
showTagsElement.prop('checked', true);
showTagsCheckBox.prop('checked', true);
}
showTagsElement.prop('disabled', checked);
showTagsCheckBox.prop('disabled', checked);
});
$('#filter-default-expanded').prop('checked', false);
defaultExpanedCheckBox.prop('checked', false);

parseFilterArguments(function(key, val) {
if (key === 'show_tags') {
$('#filter-show-tags').prop('checked', val !== '0');
showTagsCheckBox.prop('checked', val !== '0');
return 'show tags';
} else if (key === 'only_tagged') {
$('#filter-only-tagged').prop('checked', val !== '0');
$('#filter-only-tagged').trigger('change');
onlyTaggedCheckBox.prop('checked', val !== '0');
onlyTaggedCheckBox.trigger('change');
return 'only tagged';
} else if (key === 'group') {
$('#filter-group').prop('value', val);
Expand All @@ -33,11 +37,59 @@ function setupIndexPage() {
$('#filter-time-limit-days').prop('value', val);
return val + ' days old or newer';
} else if (key === 'fullscreen') {
$('#filter-fullscreen').prop('checked', val !== '0');
filterFullScreenCheckBox.prop('checked', val !== '0');
return 'fullscreen';
} else if (key === 'default_expanded') {
$('#filter-default-expanded').prop('checked', val !== '0');
defaultExpanedCheckBox.prop('checked', val !== '0');
return 'expanded';
}
});

setupBuildResults();
toggleFullscreenMode(filterFullScreenCheckBox.is(':checked'));
}

function setupBuildResults(queryParams) {
var buildResultsElement = $('#build-results');
var loadingElement = $('#build-results-loading');
var filterForm = $('#filter-form');
var filterFormApplyButton = $('#filter-apply-button');

loadingElement.show();
buildResultsElement.html('');
filterFormApplyButton.prop('disabled', true);
window.updatingBuildResults = true;

var showBuildResults = function(buildResults) {
loadingElement.hide();
buildResultsElement.html(buildResults);
alignBuildLabels();
filterFormApplyButton.prop('disabled', false);
window.updatingBuildResults = false;
};

// query build results via AJAX using parameters from filter form
$.ajax({
url: buildResultsElement.data('build-results-url'),
data: queryParams ? queryParams : window.location.search.substr(1),
success: function(response) {
showBuildResults(response);
window.buildResultStatus = 'success';
},
error: function(xhr, ajaxOptions, thrownError) {
showBuildResults('<div class="alert alert-danger" role="alert">Unable to fetch build results.</div>');
window.buildResultStatus = 'error: ' + thrownError;
}
});

// prevent page reload when submitting filter form (when we load build results via AJAX anyways)
filterForm.submit(function(event) {
if (!window.updatingBuildResults) {
var queryParams = filterForm.serialize();
setupBuildResults(queryParams);
history.replaceState({} , document.title, window.location.pathname + '?' + queryParams);
}
toggleFullscreenMode($('#filter-fullscreen').is(':checked'));
event.preventDefault();
});
}
7 changes: 4 additions & 3 deletions lib/OpenQA/WebAPI.pm
Original file line number Diff line number Diff line change
Expand Up @@ -172,11 +172,12 @@ sub startup {

# Favicon
$r->get('/favicon.ico' => sub { my $c = shift; $c->render_static('favicon.ico') });
$r->get('/index' => [format => ['html', 'json']])->to('main#index');
okurz marked this conversation as resolved.
Show resolved Hide resolved
$r->get('/api_help' => sub { shift->render('admin/api_help') })->name('api_help');
$r->get('/index' => sub { shift->render('main/index') });
$r->get('/dashboard_build_results')->name('dashboard_build_results')->to('main#dashboard_build_results');
Martchus marked this conversation as resolved.
Show resolved Hide resolved
$r->get('/api_help' => sub { shift->render('admin/api_help') })->name('api_help');

# Default route
$r->get('/')->name('index')->to('main#index');
$r->get('/' => sub { shift->render('main/index') })->name('index');
$r->get('/changelog')->name('changelog')->to('main#changelog');

# shorter version of route to individual job results
Expand Down
22 changes: 12 additions & 10 deletions lib/OpenQA/WebAPI/Controller/Main.pm
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright (C) 2015-2017 SUSE LLC
# Copyright (C) 2015-2019 SUSE LLC
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -41,21 +41,20 @@ sub _map_tags_into_build {
return;
}

sub index {
sub dashboard_build_results {
my ($self) = @_;

my $limit_builds = $self->param('limit_builds');
$limit_builds = 3 unless looks_like_number($limit_builds);
my $time_limit_days = $self->param('time_limit_days');
$time_limit_days = 14 unless looks_like_number($time_limit_days);
$self->app->log->debug("Retrieving results for up to $limit_builds builds up to $time_limit_days days old");
my $only_tagged = $self->param('only_tagged') // 0;
my $default_expanded = $self->param('default_expanded') // 0;
my $show_tags = $self->param('show_tags') // $only_tagged;
my $group_params = $self->every_param('group');
my @results;
my $groups = $self->stash('job_groups_and_parents');
my $groups = $self->stash('job_groups_and_parents');

my @results;
for my $group (@$groups) {
if (@$group_params) {
next unless grep { $_ eq '' || $group->matches_nested($_) } @$group_params;
Expand All @@ -72,13 +71,16 @@ sub index {
}
push(@results, $build_results) if @{$build_results_for_group};
}
$self->stash('limit_builds', $limit_builds);
$self->stash('time_limit_days', $time_limit_days);
$self->stash('default_expanded', $default_expanded);
$self->stash('results', \@results);

$self->stash(
default_expanded => $default_expanded,
results => \@results,
);

$self->respond_to(
json => {json => {results => \@results}},
html => {template => 'main/index'});
html => {template => 'main/dashboard_build_results'},
);
}

sub group_overview {
Expand Down
6 changes: 3 additions & 3 deletions t/17-build_tagging.t
Original file line number Diff line number Diff line change
Expand Up @@ -155,17 +155,17 @@ subtest 'only_tagged=1 query parameter shows only tagged (poo#11052)' => sub {
$t->get_ok('/group_overview/1001?only_tagged=0')->status_is(200);
is(scalar @{$t->tx->res->dom->find('a[href^=/tests/]')}, 5, 'all builds shown again (on group overview)');

$t->get_ok('/?only_tagged=1')->status_is(200);
$t->get_ok('/dashboard_build_results?only_tagged=1')->status_is(200);
is(scalar @{$t->tx->res->dom->find('a[href^=/tests/]')}, 1, 'only one tagged build is shown (on index page)');
is(scalar @{$t->tx->res->dom->find('h2')}, 1, 'only one group shown anymore');
$t->get_ok('/?only_tagged=0')->status_is(200);
$t->get_ok('/dashboard_build_results?only_tagged=0')->status_is(200);
is(scalar @{$t->tx->res->dom->find('a[href^=/tests/]')}, 4, 'all builds shown again (on index page)');
is(scalar @{$t->tx->res->dom->find('h2')}, 2, 'two groups shown again');
};

subtest 'show_tags query parameter enables/disables tags on index page' => sub {
for my $enabled (0, 1) {
$t->get_ok('/?show_tags=' . $enabled)->status_is(200);
$t->get_ok('/dashboard_build_results?show_tags=' . $enabled)->status_is(200);
is(scalar @{$t->tx->res->dom->find('a[href^=/tests/]')},
4, "all builds shown on index page (show_tags=$enabled)");
is(scalar @{$t->tx->res->dom->find("i[title='important']")},
Expand Down
Loading