diff --git a/app/assets/javascripts/angular-new/controllers/new_build_list_controller.js.erb b/app/assets/javascripts/angular-new/controllers/new_build_list_controller.js.erb
index 7db57b668..5fb051841 100644
--- a/app/assets/javascripts/angular-new/controllers/new_build_list_controller.js.erb
+++ b/app/assets/javascripts/angular-new/controllers/new_build_list_controller.js.erb
@@ -1,6 +1,9 @@
-RosaABF.controller('NewBuildListController', ['$scope', '$http', '$timeout', function($scope, $http, $timeout) {
+RosaABF.controller('NewBuildListController', ['$scope', '$http', '$timeout', '$window',
+ function($scope, $http, $timeout, $window) {
$scope.save_to_repository_id = null;
+ $scope.extra_repositories = {};
+ $scope.extra_build_lists = {};
var save_to_repository = $('#build_list_save_to_repository_id');
var all_repositories = $('.all_platforms input');
@@ -107,4 +110,23 @@ RosaABF.controller('NewBuildListController', ['$scope', '$http', '$timeout', fun
bl_version_sel[0].innerHTML = bl_version_sel[0].innerHTML;
}
}
+
+ $scope.get_extra_repositories = function(val) {
+ return $http.get('http://maps.googleapis.com/maps/api/geocode/json', {
+ params: {
+ address: val,
+ sensor: false
+ }
+ }).then(function(res){
+ var addresses = [];
+ angular.forEach(res.data.results, function(item){
+ addresses.push(item.formatted_address);
+ });
+ return addresses;
+ });
+ }
+
+ $scope.select_extra_repositories = function(item, model, label) {
+
+ }
}]);
diff --git a/app/assets/javascripts/angular-new/controllers/platforms_controller.js b/app/assets/javascripts/angular-new/controllers/platforms_controller.js
new file mode 100644
index 000000000..972c3a04c
--- /dev/null
+++ b/app/assets/javascripts/angular-new/controllers/platforms_controller.js
@@ -0,0 +1,25 @@
+RosaABF.controller('PlatformsCtrl', ['$scope', '$http', '$timeout', function($scope, $http, $timeout) {
+ $scope.total_items = null;
+ $scope.page = null;
+ $scope.platforms = null;
+
+ $scope.init = function(total_items, page) {
+ $scope.total_items = total_items;
+ $scope.page = page;
+ };
+
+ $scope.getPlatforms = function() {
+ $http.get(Routes.platforms_path({format: 'json', page: $scope.page})).then(function(res) {
+ $scope.page = res.data.page;
+ $scope.total_items = parseInt(res.data.platforms_count, 10);
+ $scope.platforms = res.data.platforms;
+ });
+ };
+
+ $scope.goToPage = function(page) {
+ $scope.page = page;
+ $scope.getPlatforms();
+ };
+
+ $scope.getPlatforms();
+}]);
diff --git a/app/assets/javascripts/angularjs/controllers/build_lists_controller.js.erb b/app/assets/javascripts/angularjs/controllers/build_lists_controller.js.erb
new file mode 100644
index 000000000..3a69e8e02
--- /dev/null
+++ b/app/assets/javascripts/angularjs/controllers/build_lists_controller.js.erb
@@ -0,0 +1,161 @@
+RosaABF.controller('BuildListsController', ['$scope', '$http', '$location', '$timeout', function($scope, $http, $location, $timeout) {
+
+ $scope.params = null;
+ $scope.first_run = true;
+ $scope.server_status = null;
+ $scope.build_lists = [];
+ $scope.isRequest = false; // Disable 'Search' button
+ $scope.pages = [];
+
+ $scope.opened = {};
+ $scope.map_priorities = {
+ <%=BuildList::WAITING_FOR_RESPONSE%>: 13,
+ <%=BuildList::BUILD_PENDING%>: 12,
+ <%=BuildList::RERUN_TESTS%>: 11,
+ <%=BuildList::BUILD_CANCELING%>: 10,
+ <%=BuildList::BUILD_CANCELED%>: 9,
+ <%=BuildList::BUILD_STARTED%>: 8,
+ <%=BuildList::RERUNNING_TESTS%>: 7,
+ <%=BuildList::BUILD_PUBLISH%>: 6,
+ <%=BuildList::BUILD_PUBLISHED%>: 5,
+ <%=BuildList::BUILD_ERROR%>: 4,
+ <%=BuildList::SUCCESS%>: 3,
+ <%=BuildList::TESTS_FAILED%>: 2,
+ <%=BuildList::FAILED_PUBLISH%>: 1,
+ <%=BuildList::REJECTED_PUBLISH%>: 0
+ };
+
+
+ // Fixes: redirect to page after form submit
+ $("#monitoring_filter").on('submit', function(){ return false; });
+
+ $scope.getBuildLists = function() {
+ // Disable 'Search' button
+ $scope.isRequest = true;
+
+
+ $http.get(Routes.build_lists_path({format: 'json'}), {params: $location.search()}).success(function(results) {
+ // Render Server status
+ $scope.server_status = results.server_status;
+
+ // TMP fields
+ var dictionary = results.dictionary;
+ var build_lists = [];
+ var groups = {};
+
+ var to_open = [];
+ // Grouping of build_lists
+ _.each(results.build_lists, function(r){
+ var bl = new BuildList(r, dictionary);
+ var key = bl.project_id + '-';
+ key += bl.group_id ? bl.group_id : (bl.commit_hash + '-' + bl.user_id);
+ if (groups[key]) {
+ groups[key].addRelated(bl);
+ } else {
+ groups[key] = bl;
+ build_lists.push(bl);
+ if ( bl.id in $scope.opened ) { to_open.push(bl); }
+ }
+ });
+
+ // Adds all build_lists into the table (group by group)
+ $scope.build_lists = [];
+ $scope.opened = {};
+ _.each(build_lists, function(bl){
+ if (bl.related.length > 1) {
+ var sorted_build_lists = _.sortBy(bl.related, function(b) { return $scope.map_priorities[b.status]; });
+ bl.clearRelated();
+ var first_in_group = sorted_build_lists[0];
+ first_in_group.clearRelated();
+ _.each(sorted_build_lists, function(b){
+ if (b != first_in_group) { first_in_group.addRelated(b); }
+ $scope.build_lists.push(b);
+ });
+ } else {
+ $scope.build_lists.push(bl);
+ }
+ });
+ // Shows groups which have been opened before
+ _.each(to_open, function(bl){ $scope.showRelated(bl, true); });
+
+ // Render pagination
+ $scope.pages = results.pages;
+ // Enable 'Search' button
+ $scope.isRequest = false;
+ }).error(function(data, status, headers, config) {
+ // Enable 'Search' button
+ $scope.isRequest = false;
+ });;
+ }
+
+ $scope.showRelated = function(build_list, disable_effect) {
+ build_list.relatedHidden = false;
+ _.each(build_list.related, function(bl){
+ bl.show = true;
+ $scope.opened[bl.id] = true;
+ // Waits for render of build_lists
+ if (!disable_effect)
+ $timeout(function() {
+ $('#build-list-' + bl.id + ' td:visible').effect('highlight', {}, 1000);
+ }, 100);
+ });
+ }
+
+ $scope.hideRelated = function(build_list) {
+ build_list.relatedHidden = true;
+ _.each(build_list.related, function(bl){
+ bl.show = false;
+ delete $scope.opened[bl.id];
+ });
+ build_list.show = true;
+ }
+
+ $scope.cancelRefresh = null;
+ $scope.refresh = function(force) {
+ if ($('#autoreload').is(':checked') || force) {
+ var params = {};
+ _.each($("#monitoring_filter").serializeArray(), function(a){
+ if (a.value) { params[a.name] = a.value; }
+ });
+ $location.search(params);
+ $scope.first_run = false;
+ $scope.getBuildLists();
+ }
+ if (!force)
+ $scope.cancelRefresh = $timeout($scope.refresh, 60000);
+ }
+
+
+ $scope.$on('$locationChangeSuccess', function(event) {
+ $scope.updateParams();
+ if (!$scope.first_run) { $scope.getBuildLists(); }
+ });
+
+ $scope.updateParams = function() {
+ var params = $location.search();
+ $scope.params = {
+ page: params.page || 1,
+ per_page: params.per_page || 25,
+ filter: {
+ ownership: params['filter[ownership]'] || 'owned',
+ status: params['filter[status]'],
+ platform_id: params['filter[platform_id]'],
+ arch_id: params['filter[arch_id]'],
+ mass_build_id: params['filter[mass_build_id]'],
+ updated_at_start: params['filter[updated_at_start]'],
+ updated_at_end: params['filter[updated_at_end]'],
+ project_name: params['filter[project_name]'],
+ id: params['filter[id]']
+ }
+ }
+ }
+
+ $scope.goToPage = function(number) {
+ $location.search('page', number);
+ $scope.getBuildLists();
+ }
+
+ $scope.updateParams();
+ // Waits for render of filters
+ $timeout($scope.refresh, 100);
+}]);
diff --git a/app/assets/javascripts/extra/autocomplete-form.js b/app/assets/javascripts/extra/autocomplete-form.js
index 9d92651d7..9a660ea1c 100644
--- a/app/assets/javascripts/extra/autocomplete-form.js
+++ b/app/assets/javascripts/extra/autocomplete-form.js
@@ -36,10 +36,9 @@ function addDataToAutocompleteForm(form, path, label, name, value) {
var tr = '
' +
'' +
'' + label + '' +
- ' | ' +
- '' +
- '' +
- ' ' +
+ ' ' +
+ '' +
+ ' ' +
' | ' +
'
';
form.find('table tbody').append($(tr));
diff --git a/app/assets/javascripts/new_application.js b/app/assets/javascripts/new_application.js
index 2624017b4..ff77ac268 100644
--- a/app/assets/javascripts/new_application.js
+++ b/app/assets/javascripts/new_application.js
@@ -3,6 +3,9 @@
//= require jquery-ui
//= require js-routes
+//= require autocomplete-rails
+//= require extra/autocomplete-form
+
// Loads all Bootstrap javascripts
//= require bootstrap
diff --git a/app/controllers/platforms/platforms_controller.rb b/app/controllers/platforms/platforms_controller.rb
index 65dfd46da..3ae58107f 100644
--- a/app/controllers/platforms/platforms_controller.rb
+++ b/app/controllers/platforms/platforms_controller.rb
@@ -1,12 +1,19 @@
class Platforms::PlatformsController < Platforms::BaseController
include FileStoreHelper
+ layout 'bootstrap', only: [:index]
before_filter :authenticate_user!
skip_before_filter :authenticate_user!, only: [:advisories, :members, :show] if APP_CONFIG['anonymous_access']
load_and_authorize_resource
def index
- @platforms = @platforms.accessible_by(current_ability, :related).order(:name).paginate(page: params[:page], per_page: 20)
+ @platforms = @platforms.accessible_by(current_ability, :related)
+ @platforms_count = @platforms.count
+ @platforms = @platforms.paginate(page: current_page, per_page: Platform.per_page)
+ respond_to do |format|
+ format.html {}
+ format.json {}
+ end
end
def show
diff --git a/app/helpers/paginate_helper.rb b/app/helpers/paginate_helper.rb
index 645293d6f..6da203cf4 100644
--- a/app/helpers/paginate_helper.rb
+++ b/app/helpers/paginate_helper.rb
@@ -19,4 +19,13 @@ module PaginateHelper
will_paginate *[collection_or_options, options].compact
end
+ def paginate(options)
+ return nil if options.blank?
+ render 'shared/paginate',
+ total_items: options[:total_items],
+ page: options[:page],
+ per_page: options[:per_page],
+ ng_show: options[:ng_show],
+ select_page: options[:select_page]
+ end
end
diff --git a/app/models/platform.rb b/app/models/platform.rb
index ee6a6fd40..96b34c238 100644
--- a/app/models/platform.rb
+++ b/app/models/platform.rb
@@ -12,6 +12,7 @@ class Platform < ActiveRecord::Base
VISIBILITIES = %w(open hidden)
NAME_PATTERN = /[\w\-\.]+/
HUMAN_STATUSES = HUMAN_STATUSES.clone.freeze
+ self.per_page = 20
belongs_to :parent, class_name: 'Platform', foreign_key: 'parent_platform_id'
belongs_to :owner, polymorphic: true
diff --git a/app/views/home/_tracker_and_pulls_tabs.html.haml b/app/views/home/_tracker_and_pulls_tabs.html.haml
index 970b93b5d..d91ef35f9 100644
--- a/app/views/home/_tracker_and_pulls_tabs.html.haml
+++ b/app/views/home/_tracker_and_pulls_tabs.html.haml
@@ -45,14 +45,8 @@
%a{ 'ng-href' => '{{issue.assignee.link}}',
'title' => "#{t('layout.issues.assigned_to')} {{issue.assignee.fullname}}" }
%img{ 'ng-src' => '{{issue.assignee.image}}' }
-
- %pagination.pagination-sm{ 'boundary-links' => 'true',
- 'total-items' => "#{kind}_tab.pagination.total_items",
- 'page' => "#{kind}_tab.pagination.page",
- 'previous-text' => "‹", 'next-text' => "›",
- 'first-text' => "«", "last-text" => "»",
- 'items-per-page' => Issue.per_page,
- 'max-size' => 5,
- 'rotate' => 'false',
- 'ng-show' => "#{kind}_tab.pagination.total_items > #{Issue.per_page}",
- 'on-select-page' => "selectPage('#{kind}', page)" }
+ = paginate( total_items: "#{kind}_tab.pagination.total_items",
+ page: "#{kind}_tab.pagination.page",
+ per_page: Issue.per_page,
+ ng_show: "#{kind}_tab.pagination.total_items > #{Issue.per_page}",
+ select_page: "selectPage('#{kind}', page)" )
diff --git a/app/views/home/activity.json.jbuilder b/app/views/home/activity.json.jbuilder
index 4bf7fbdc4..c3feedd0a 100644
--- a/app/views/home/activity.json.jbuilder
+++ b/app/views/home/activity.json.jbuilder
@@ -4,7 +4,7 @@ end
json.feed do
json.array!(@activity_feeds) do |item|
- #json.cache! item, expires_in: 10.minutes do
+ json.cache! item, expires_in: 10.minutes do
json.date item.created_at
json.kind item.kind
user = get_user_from_activity_item(item)
@@ -20,6 +20,6 @@ json.feed do
json.project_name_with_owner project_name_with_owner
json.partial! item.partial, item: item, project_name_with_owner: project_name_with_owner
json.id item.id
- #end
+ end
end
end
diff --git a/app/views/platforms/platforms/_list.html.haml b/app/views/platforms/platforms/_list.html.haml
index 052a86884..9a9dde666 100644
--- a/app/views/platforms/platforms/_list.html.haml
+++ b/app/views/platforms/platforms/_list.html.haml
@@ -1,10 +1,10 @@
-%table#myTable.tablesorter.platforms{cellspacing: "0", cellpadding: "0"}
+%table.table.table-striped
%thead
%tr
- %th.th1= t("activerecord.attributes.platform.name")
- %th.th2= t("activerecord.attributes.platform.distrib_type")
+ %th= t 'activerecord.attributes.platform.name'
+ %th= t 'activerecord.attributes.platform.distrib_type'
%tbody
- @platforms.each do |platform|
- %tr{class: cycle("odd", "even")}
+ %tr
%td= link_to platform_printed_name(platform), platform_path(platform)
%td= platform.distrib_type
diff --git a/app/views/platforms/platforms/index.html.haml b/app/views/platforms/platforms/index.html.haml
index 89abeaab6..8f1e82c56 100644
--- a/app/views/platforms/platforms/index.html.haml
+++ b/app/views/platforms/platforms/index.html.haml
@@ -1,4 +1,23 @@
-set_meta_tags title: t('layout.platforms.list_header')
-= link_to t("layout.platforms.new"), new_platform_path, class: 'button' if can? :create, Platform
-= render 'list', object: @platforms
-= will_paginate @platforms
+.row{ 'ng-controller' => 'PlatformsCtrl', 'ng-cloak' => true,
+ 'ng-init' => "init(#{@platforms_count}, #{params[:page]})" }
+ .col-md-6.col-md-offset-3
+ = link_to t('layout.platforms.new'), new_platform_path, class: 'btn btn-primary' if can? :create, Platform
+ =# render 'list', object: @platforms
+ %table.table.table-striped.offset20
+ %thead
+ %tr
+ %th= t 'activerecord.attributes.platform.name'
+ %th= t 'activerecord.attributes.platform.distrib_type'
+ %tbody
+ %tr{ 'ng-repeat' => 'item in platforms' }
+ %td
+ %a{ 'ng-href' => "{{item.link}}" }
+ {{item.name}}
+ %td {{item.distrib_type}}
+
+ = paginate( total_items: 'total_items',
+ page: 'page',
+ per_page: Platform.per_page,
+ ng_show: "total_items > #{Platform.per_page}",
+ select_page: "goToPage(page)" )
diff --git a/app/views/platforms/platforms/index.json.jbuilder b/app/views/platforms/platforms/index.json.jbuilder
new file mode 100644
index 000000000..7d4c59d5b
--- /dev/null
+++ b/app/views/platforms/platforms/index.json.jbuilder
@@ -0,0 +1,12 @@
+json.platforms do
+ json.array!(@platforms) do |item|
+ json.cache! item, expires_in: 10.minutes do
+ json.name platform_printed_name(item)
+ json.link platform_path(item)
+ json.distrib_type item.distrib_type
+ end
+ end
+end
+
+json.page params[:page]
+json.platforms_count @platforms_count
\ No newline at end of file
diff --git a/app/views/projects/build_lists/index.html.haml b/app/views/projects/build_lists/index.html.haml
index 28ad9ca28..ef1aef8e8 100644
--- a/app/views/projects/build_lists/index.html.haml
+++ b/app/views/projects/build_lists/index.html.haml
@@ -70,16 +70,10 @@
/ updated_at
%td{'am-time-ago' => 'bl.updated_at', title: "{{bl.updated_at | amDateFormat:'ddd, LLL'}}"}
- %pagination{ 'boundary-links' => 'true',
- 'total-items' => 'build_lists_count',
- 'page' => 'page',
- 'previous-text' => "‹", 'next-text' => "›",
- 'first-text' => "«", "last-text" => "»",
- 'items-per-page' => "params.per_page",
- 'max-size' => 5,
- 'rotate' => 'false',
- 'ng-show' => "build_lists_count > params.per_page",
- 'on-select-page' => "goToPage(page)" }
-
+ = paginate( total_items: 'build_lists_count',
+ page: 'page',
+ per_page: 'params.per_page',
+ ng_show: "build_lists_count > params.per_page",
+ select_page: "goToPage(page)" )
= render @project ? 'projects/base/submenu' : 'projects/build_lists/submenu'
diff --git a/app/views/shared/_autocomplete_form.html.haml b/app/views/shared/_autocomplete_form.html.haml
index 6b0d25fc9..a9d3351ba 100644
--- a/app/views/shared/_autocomplete_form.html.haml
+++ b/app/views/shared/_autocomplete_form.html.haml
@@ -14,7 +14,7 @@
.modal-dialog
.modal-content
.modal-header
- %button{ type: 'button', class: 'close', 'data-dismiss' => 'modal', 'aria-hidden' => 'true' } ×
+ %button.close{ type: 'button', 'data-dismiss' => 'modal', 'aria-hidden' => 'true' } ×
%h4.modal-title= t "activerecord.attributes.build_list.#{field}"
.modal-body= render "shared/autocomplete_docs/#{field}"
.modal-footer
@@ -24,6 +24,11 @@
%h3
= t "activerecord.attributes.build_list.#{field}"
%i.fa.fa-question-circle{ 'data-toggle' => 'modal', 'data-target' => "##{field}_dialog" }
+ %input.form-control{ type: 'text', 'ng-model' => "async_#{field}_selected", placeholder: placeholder,
+ 'typeahead' => "extra for extra in get_#{field}($viewValue)", 'typeahead-loading' => "loading_#{field}",
+ 'typeahead-on-select' => "select_#{field}($item, $model, $label)" }
+ %i.glyphicon.glyphicon-refresh{ 'ng-show' => "loading_#{field}" }
+
.row
= hidden_field_tag field, nil, id: "#{field}_field"
= hidden_field_tag field, nil, id: "#{field}_field_path"
@@ -46,14 +51,13 @@
= link_to "#{extra.id} (#{extra.project.name} - #{extra.arch.name})", extra
- else
= link_to "#{extra.platform.name}/#{extra.name}", [extra.platform, extra]
- - field = extra.is_a?(BuildList) ? 'extra_build_lists' : 'extra_repositories'
- = hidden_field_tag field_name, extra.id
.actions.pull-right
+ = hidden_field_tag field_name, extra.id
%span.fa.fa-times.fa-lg.delete.text-danger
.default-values
- field_class.where(id: default_values).each do |extra|
- .hidden{:label => "#{extra.platform.name}/#{extra.name}",
- :path => url_for([extra.platform, extra]),
- :name => field_name, value: extra.id}
+ .hidden{ label: "#{extra.platform.name}/#{extra.name}",
+ path: url_for([extra.platform, extra]),
+ name: field_name, value: extra.id }
diff --git a/app/views/shared/_paginate.html.haml b/app/views/shared/_paginate.html.haml
new file mode 100644
index 000000000..49ba6ccbf
--- /dev/null
+++ b/app/views/shared/_paginate.html.haml
@@ -0,0 +1,10 @@
+%pagination{ 'boundary-links' => 'true',
+ 'total-items' => total_items,
+ 'page' => page,
+ 'previous-text' => "‹", 'next-text' => "›",
+ 'first-text' => "«", "last-text" => "»",
+ 'items-per-page' => per_page,
+ 'max-size' => 5,
+ 'rotate' => 'false',
+ 'ng-show' => ng_show,
+ 'on-select-page' => select_page }