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 }