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

Bootstrap/monitor #6421

Merged
merged 3 commits into from
Dec 4, 2018
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
1 change: 1 addition & 0 deletions src/api/app/assets/javascripts/webui2/application.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,4 @@
//= require webui2/jquery-ui.min.js
//= require webui2/cm2/use-codemirror.js
//= require webui2/package-view_file.js
//= require webui2/project_monitor.js
3 changes: 2 additions & 1 deletion src/api/app/assets/javascripts/webui2/datatables.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
//= require datatables/dataTables.bootstrap4
//= require datatables/extensions/Responsive/dataTables.responsive
//= require datatables/extensions/Responsive/responsive.bootstrap4
//= require datatables/extensions/FixedColumns/fixedColumns.bootstrap4
//= require datatables/extensions/FixedColumns/dataTables.fixedColumns

function initializeDataTable(cssSelector, params){ // jshint ignore:line
var defaultParams = {
Expand All @@ -10,4 +12,3 @@ function initializeDataTable(cssSelector, params){ // jshint ignore:line
var newParams = $.extend(defaultParams, params);
$(cssSelector).DataTable(newParams);
}

105 changes: 105 additions & 0 deletions src/api/app/assets/javascripts/webui2/project_monitor.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
function hideRepositoryColumns() {
var table = $('#project-monitor-table').DataTable();

var repositories = [];
$('#project-monitor-repositories-dropdown input:checked').each(function () {
repositories.push($(this).val().trim());
Ana06 marked this conversation as resolved.
Show resolved Hide resolved
});

if (repositories.length === 0) {
return;
}

var toShowColumns = [];
var offSet = 0;
$('#project-monitor-table thead tr:eq(0) th').each(function () {
var column = $(this);
var colSpan = column.prop('colspan');
if (repositories.includes(column.text().trim())) {
var range = [];
for (var i = offSet; i < offSet + colSpan; i++) {
range.push(i);
}
toShowColumns = toShowColumns.concat(range);
}
offSet += colSpan;
});

table.columns().every(function () {
var index = this.index();
if (index === 0) return;
this.visible(toShowColumns.includes(index));
});
}

function hideArchitectureColumns() {
var table = $('#project-monitor-table').DataTable();
Ana06 marked this conversation as resolved.
Show resolved Hide resolved

var architectures = [];
$('#project-monitor-architectures-dropdown input:checked').each(function () {
architectures.push($(this).val());
});

if (architectures.length === 0) {
return;
}

table.columns().every(function () {
if (this.index() === 0) return;
if (!this.visible()) return;

var title = $(this.header()).text().trim();
this.visible(architectures.includes(title));
});
}

function updateStatusSearch() {
var table = $('#project-monitor-table').DataTable();
var searchInput = $('#project-monitor_filter input');

var terms = [];
$('#project-monitor-status-dropdown input:checked').each(function () {
terms.push($(this).val());
});

var searchTerm = terms.join("|");
searchInput.val(searchTerm);
table.search(searchTerm).draw();
}

function updateMonitorFilters() {
updateStatusSearch();
var table = $('#project-monitor-table').DataTable();
table.columns().visible(true);
hideRepositoryColumns();
hideArchitectureColumns();
}

function setupProjectMonitor() { // jshint ignore:line
initializeDataTable('#project-monitor-table', { // jshint ignore:line
scrollX: true,
scrollY: "50vh",
fixedColumns: true,
pageLength: 50,
search: {
regex: true,
smart: false,
}
});

$('[data-toggle="popover"]').popover({ trigger: 'hover click' });

$('#project-monitor-status-dropdown input:checkbox').on('change', function () {
updateStatusSearch();
});

$('.monitor-no-filter-link').on('click', function () {
$(this).siblings().children('input:checked').prop('checked', false);
updateMonitorFilters();

});

$('#project-monitor-architectures-dropdown input:checkbox, #project-monitor-repositories-dropdown input:checkbox').on('change', function () {
updateMonitorFilters();
});
}
1 change: 1 addition & 0 deletions src/api/app/assets/stylesheets/webui2/datatables.scss
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
@import 'datatables/dataTables.bootstrap4';
@import 'datatables/extensions/Responsive/responsive.bootstrap4';
@import 'datatables/extensions/FixedColumns/fixedColumns.bootstrap4';

table.table-fixed {
table-layout: fixed
Expand Down
4 changes: 0 additions & 4 deletions src/api/app/assets/stylesheets/webui2/modals.scss
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,3 @@
overflow-x: hidden;
overflow-wrap: break-word;
}

.modal-body p {
white-space: pre-wrap;
}
9 changes: 9 additions & 0 deletions src/api/app/controllers/webui/project_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,14 @@ def move_path
end

def monitor
if params.keys.length < 4
@activate_client_search = true
else
flash[:notice] = "Limited search results, click #{view_context.link_to('here', project_monitor_path(@project))} to remove the filter."
end

@legend = Buildresult::STATUS_DESCRIPTION

@name_filter = params[:pkgname]
@lastbuild_switch = params[:lastbuild]
if params[:defaults]
Expand Down Expand Up @@ -454,6 +462,7 @@ def monitor
@repohash[repo].delete(arch) unless has_packages
end
end
switch_to_webui2
end

# should be in the package controller, but all the helper functions to render the result of a build are in the project
Expand Down
58 changes: 58 additions & 0 deletions src/api/app/views/webui2/webui/project/_monitor_control.html.haml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
.row
.col-md-12
- if activate_client_search
%span.dropdown#project-monitor-status-dropdown
%button.btn.btn-outline-secondary.dropdown-toggle{ data: { toggle: :dropdown }, type: :button }
%span.caret
Status
.dropdown-menu
%button.btn.btn-link.monitor-no-filter-link No filter
- status.each do |status|
.custom-control.custom-checkbox.dropdown-item.ml-2
%input.custom-control-input{ type: :checkbox, id: "#{status}-checkbox".parameterize, checked: false, value: status }
%label.custom-control-label{ for: "#{status}-checkbox".parameterize }
= status
%span.dropdown#project-monitor-architectures-dropdown
%button.btn.btn-outline-secondary.dropdown-toggle{ data: { toggle: :dropdown }, type: :button }
%span.caret
Architecture
.dropdown-menu
%button.btn.btn-link.monitor-no-filter-link No filter
- architectures.each do |architecture|
.custom-control.custom-checkbox.dropdown-item.ml-2
%input.custom-control-input{ type: :checkbox, id: "#{architecture}-checkbox".parameterize, checked: false, value: architecture }
%label.custom-control-label{ for: "#{architecture}-checkbox".parameterize }
= architecture
%span.dropdown#project-monitor-repositories-dropdown
%button.btn.btn-outline-secondary.dropdown-toggle{ data: { toggle: :dropdown }, type: :button }
%span.caret
Repository
.dropdown-menu
%button.btn.btn-link.monitor-no-filter-link No filter
- repositories.each do |repository|
.custom-control.custom-checkbox.dropdown-item.ml-2
%input.custom-control-input{ type: :checkbox, id: "#{repository}-checkbox".parameterize, checked: false, value: repository }
%label.custom-control-label{ for: "#{repository}-checkbox".parameterize }
= repository
%button.btn.btn-outline-secondary{ data: { toggle: 'modal', target: '#build-monitor-legend' }, title: 'Build status legend' }
Legend
- unless activate_client_search
.float-right
%a.btn.btn-outline-primary{ href: project_monitor_path(project) }
Remove filter

.modal.fade#build-monitor-legend{ tabindex: -1, role: 'dialog', aria: { labelledby: 'confirm-modal-label', hidden: true } }
.modal-dialog.modal-dialog-centered.modal-lg{ role: 'document' }
.modal-content
.modal-header
%h5.modal-title
Build status legend
.modal-body
- @legend.each do |status, description|
%p
%strong
#{status}:
Ana06 marked this conversation as resolved.
Show resolved Hide resolved
= description
.modal-footer
%button.btn.btn-sm.btn-outline-secondary.px-4{ data: { dismiss: 'modal' } }
Cancel
2 changes: 2 additions & 0 deletions src/api/app/views/webui2/webui/project/_tabs.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
- unless project.defines_remote_instance? || project.is_maintenance?
%li.nav-item
= tab_link('Repositories', repositories_path)
%li.nav-item
= tab_link('Monitor', project_monitor_path(project))
%li.nav-item
= tab_link('Requests', project_requests_path)
- unless project.defines_remote_instance?
Expand Down
37 changes: 37 additions & 0 deletions src/api/app/views/webui2/webui/project/monitor.html.haml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
:ruby
@pagetitle = "Show #{@project}"
@layouttype = 'custom'

.card.mb-3
= render partial: 'tabs', locals: { project: @project }
.card-body#project-monitor
= render partial: 'monitor_control',
locals: { project: @project, activate_client_search: @activate_client_search,
status: @avail_status_values, repositories: @avail_repo_values, architectures: @avail_arch_values }
.row.mt-4
.col-md-12.obs-dataTable
%table.table.table-striped.table-bordered.text-nowrap.w-100#project-monitor-table
%thead.header
%tr
%th
- @repohash.sort.each do |repo, archlist|
- next if archlist.empty?
%th.text-center{ colspan: archlist.length }
= repo
%tr
%th
- @repohash.sort.each do |_repo, archlist|
- archlist.sort.each do |arch|
%th
= arch
%tbody
- @packagenames.each do |packname|
%tr
%td
= link_to word_break(packname, 40), controller: :package, action: :show, package: packname, project: @project.to_s
- @repohash.sort.each do |repo, archlist|
- archlist.sort.each do |arch|
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isn't this already sorted? 🤔

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apparently not, no

Copy link
Member

@Ana06 Ana06 Dec 3, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it comes sorted from the backend.... 🤔

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How do you know? I would keep it for now, that is c&p from the old view.

%td
= webui2_arch_repo_table_cell(repo, arch, packname, nil, false)
:javascript
setupProjectMonitor();
101 changes: 101 additions & 0 deletions src/api/spec/bootstrap/features/webui/projects/monitor_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
require 'browser_helper'
require 'bootstrap/support/page/monitor_page'

RSpec.feature 'Monitor', type: :feature, js: true do
describe 'monitor' do
let(:admin_user) { create(:admin_user) }
let!(:project) { create(:project, name: 'TestProject') }
let!(:package1) { create(:package, project: project, name: 'TestPackage') }
let!(:package2) { create(:package, project: project, name: 'SecondPackage') }
let!(:repository1) { create(:repository, project: project, name: 'openSUSE_Tumbleweed', architectures: ['x86_64', 'i586']) }
let!(:repository2) { create(:repository, project: project, name: 'openSUSE_Leap_42.3', architectures: ['x86_64', 'i586']) }
let!(:repository3) { create(:repository, project: project, name: 'openSUSE_Leap_42.2', architectures: ['x86_64', 'i586']) }

let(:build_results_xml) do
<<-XML
<resultlist state="dc66a487ea4d97b4f157d075a0e747b9">
<result project="TestProject" repository="openSUSE_Tumbleweed" arch="x86_64" code="published" state="published">
<status package="SecondPackage" code="broken">
<details>no source uploaded</details>
</status>
<status package="TestPackage" code="succeeded">
<details>no source uploaded</details>
</status>
</result>
<result project="TestProject" repository="openSUSE_Leap_42.3" arch="x86_64" code="published" state="published">
<status package="SecondPackage" code="broken">
<details>no source uploaded</details>
</status>
<status package="TestPackage" code="broken">
<details>no source uploaded</details>
</status>
</result>
<result project="TestProject" repository="openSUSE_Leap_42.2" arch="x86_64" code="published" state="published">
<status package="SecondPackage" code="broken">
<details>no source uploaded</details>
</status>
<status package="TestPackage" code="broken">
<details>no source uploaded</details>
</status>
</result>
<result project="TestProject" repository="openSUSE_Tumbleweed" arch="i586" code="published" state="published">
<status package="SecondPackage" code="broken">
<details>no source uploaded</details>
</status>
<status package="TestPackage" code="broken">
<details>no source uploaded</details>
</status>
</result>
<result project="TestProject" repository="openSUSE_Leap_42.3" arch="i586" code="published" state="published">
<status package="SecondPackage" code="broken">
<details>no source uploaded</details>
</status>
<status package="TestPackage" code="broken">
<details>no source uploaded</details>
</status>
</result>
<result project="TestProject" repository="openSUSE_Leap_42.2" arch="i586" code="published" state="published">
<status package="SecondPackage" code="broken">
<details>no source uploaded</details>
</status>
<status package="TestPackage" code="broken">
<details>no source uploaded</details>
</status>
</result>
</resultlist>
XML
end

before do
login admin_user
allow(Backend::Api::BuildResults::Status).to receive(:result_swiss_knife).and_return(build_results_xml)
visit project_monitor_path(project.name)
end

scenario 'filtering build results by architecture' do
page = Page::MonitorPage.new(:architectures)
page.filter('i586')

expect(page).to have_column('i586')
expect(page).not_to have_column('x86_64')
end

scenario 'filtering build results by repository' do
page = Page::MonitorPage.new(:repositories)
page.filter('openSUSE_Leap_42.2')
page.filter('openSUSE_Leap_42.3')

expect(page).to have_column('openSUSE_Leap_42.2')
expect(page).to have_column('openSUSE_Leap_42.3')
expect(page).not_to have_column('Tumbleweed')
end

scenario 'filtering build results by status' do
page = Page::MonitorPage.new(:status)
page.filter('succeeded')

expect(page).to have_row('TestPackage')
expect(page).not_to have_row('SecondPackage')
end
end
end
Loading