diff --git a/app/assets/javascripts/angular-new/controllers/statistics_controller.js.coffee b/app/assets/javascripts/angular-new/controllers/statistics_controller.js.coffee index 748e62958..aded34922 100644 --- a/app/assets/javascripts/angular-new/controllers/statistics_controller.js.coffee +++ b/app/assets/javascripts/angular-new/controllers/statistics_controller.js.coffee @@ -24,9 +24,6 @@ RosaABF.controller 'StatisticsController', ['$scope', '$http', '$timeout', ($sco formatYear: 'yy' startingDay: 1 - $('#users_or_groups').on 'autocompleteselect', (e) -> - $timeout($scope.update, 100) - $scope.init = -> $('#statistics-form .date_picker').datepicker 'dateFormat': 'yy-mm-dd' diff --git a/app/assets/javascripts/angularjs/controllers/statistics_controller.js.coffee b/app/assets/javascripts/angularjs/controllers/statistics_controller.js.coffee deleted file mode 100644 index b9345e143..000000000 --- a/app/assets/javascripts/angularjs/controllers/statistics_controller.js.coffee +++ /dev/null @@ -1,163 +0,0 @@ -RosaABF.controller 'StatisticsController', ['$scope', '$http', '$timeout', ($scope, $http, $timeout) -> - - $scope.users_or_groups = null - $scope.range = 'last_30_days' - $scope.range_start = $('#range_start').attr('value') - $scope.range_end = $('#range_end').attr('value') - $scope.loading = false - $scope.statistics = {} - $scope.statistics_path = '/statistics' - - $scope.colors = [ - '56, 132, 158', - '77, 169, 68', - '241, 128, 73', - '174, 199, 232', - # '255, 187, 120', - # '152, 223, 138', - # '214, 39, 40', - # '31, 119, 180' - ] - $scope.charts = {} - - $('#users_or_groups').on 'autocompleteselect', (e) -> - $timeout($scope.update, 100) - - $scope.init = -> - $('#statistics-form .date_picker').datepicker - 'dateFormat': 'yy-mm-dd' - maxDate: 0 - minDate: -366 - showButtonPanel: true - - $scope.update() - true - - $scope.prepareRange = -> - range_start = new Date($scope.range_start) - range_end = new Date($scope.range_end) - - if range_start > range_end - tmp = $scope.range_start - $scope.range_start = $scope.range_end - $scope.range_end = tmp - - $scope.prepareUsersOrGroups = -> - if $scope.users_or_groups - items = _.uniq $('#users_or_groups').val().replace(/\s/g, '').split(/,/) - items = _.reject items, (i) -> - _.isEmpty(i) - $scope.users_or_groups = _.first(items, 3).join(', ') + ', ' - - $scope.update = -> - return if $scope.loading - $scope.loading = true - $scope.statistics = {} - - $scope.prepareRange() - $scope.prepareUsersOrGroups() - $('.doughnut-legend').remove() - - params = - range: $scope.range - range_start: $scope.range_start - range_end: $scope.range_end - users_or_groups: $scope.users_or_groups - format: 'json' - - $http.get($scope.statistics_path, params: params).success (results) -> - $scope.statistics = results - - $scope.loading = false - - # BuildLists - if $scope.statistics.build_lists - $scope.initBuildListsChart() - - # PullRequests - if $scope.statistics.pull_requests - $scope.initPullRequestsChart() - - # Issues - if $scope.statistics.issues - $scope.initIssuesChart() - - # Commits - if $scope.statistics.commits - $scope.initCommitsChart() - - .error (data, status, headers, config) -> - console.log 'error:' - $scope.loading = false - - $scope.dateChart = (id, collections) -> - new_collections = $.grep collections, ( c ) -> - return c - - if collections.length == new_collections.length - $scope.charts[id].destroy() if $scope.charts[id] - - points = collections[0] - factor = points.length // 45 + 1 - - tooltipTitles = [] - labels = _.map points, (d, index) -> - x = d.x - tooltipTitles.push x - if index %% factor == 0 - x - else - '' - - datasets = _.map collections, (collection, index) -> - data = _.map collection, (d) -> - d.y - - dataset = - fillColor: "rgba(#{ $scope.colors[index] }, 0.1)" - strokeColor: "rgba(#{ $scope.colors[index] }, 1)" - pointColor: "rgba(#{ $scope.colors[index] }, 1)" - pointStrokeColor: "#fff" - data: data - - data = - datasets: datasets - # We display only limited count of labels on X axis, but tooltips should have titles - # See: Chart.js "Added by avokhmin" - labels: labels - tooltipTitles: tooltipTitles - - options = - responsive: true - - context = $(id)[0].getContext('2d') - $scope.charts[id] = new Chart(context).Line(data, options) - - $scope.initBuildListsChart = -> - $scope.dateChart '#build_lists_chart', [ - $scope.statistics.build_lists.build_started, - $scope.statistics.build_lists.success, - $scope.statistics.build_lists.build_error, - $scope.statistics.build_lists.build_published - ] - - $scope.initCommitsChart = -> - $scope.dateChart '#commits_chart', [ - $scope.statistics.commits.chart - ] - - $scope.initPullRequestsChart = -> - $scope.dateChart '#pull_requests_chart', [ - $scope.statistics.pull_requests.open, - $scope.statistics.pull_requests.merged - $scope.statistics.pull_requests.closed, - ] - - $scope.initIssuesChart = -> - $scope.dateChart '#issues_chart', [ - $scope.statistics.issues.open, - $scope.statistics.issues.reopen, - $scope.statistics.issues.closed - ] - -] \ No newline at end of file diff --git a/app/assets/javascripts/extra/product.js b/app/assets/javascripts/extra/product.js deleted file mode 100644 index d3b86bed0..000000000 --- a/app/assets/javascripts/extra/product.js +++ /dev/null @@ -1,14 +0,0 @@ -$(document).ready(function() { - - $('#product_project').bind('railsAutocomplete.select', function(event, data){ - var ppv = $("#product_project_version").empty().append(''); - $(data.item.project_versions).each(function(k, i) { - var optgroup = $(''); - $(i[1]).each(function(k, b) { - optgroup.append(''); - }); - ppv.append(optgroup); - }); - }); - -}); \ No newline at end of file diff --git a/app/assets/javascripts/new_application.js b/app/assets/javascripts/new_application.js index bfe09b8c2..34e93bba5 100644 --- a/app/assets/javascripts/new_application.js +++ b/app/assets/javascripts/new_application.js @@ -6,7 +6,7 @@ // require jquery.dataTables // require jquery.dataTables_ext -//= require autocomplete-rails +// require autocomplete-rails // require extra/autocomplete-form //= require bootstrap-sprockets diff --git a/app/controllers/autocompletes_controller.rb b/app/controllers/autocompletes_controller.rb index 76f0a5003..2cebbc752 100644 --- a/app/controllers/autocompletes_controller.rb +++ b/app/controllers/autocompletes_controller.rb @@ -1,8 +1,6 @@ class AutocompletesController < ApplicationController before_filter :authenticate_user! - autocomplete :group, :uname - def autocomplete_user_uname results = User.opened.search(params[:query]).search_order.limit(5) render json: results.map{ |u| { id: u.id, name: u.uname } } diff --git a/app/controllers/groups/base_controller.rb b/app/controllers/groups/base_controller.rb index 7428bfbe4..5af91222e 100644 --- a/app/controllers/groups/base_controller.rb +++ b/app/controllers/groups/base_controller.rb @@ -1,4 +1,6 @@ class Groups::BaseController < ApplicationController + layout 'bootstrap' + before_filter :authenticate_user! before_filter :find_group diff --git a/app/controllers/groups/members_controller.rb b/app/controllers/groups/members_controller.rb index 42f57f86b..01492a1e9 100644 --- a/app/controllers/groups/members_controller.rb +++ b/app/controllers/groups/members_controller.rb @@ -6,36 +6,26 @@ class Groups::MembersController < Groups::BaseController end def update - params['user'].keys.each do |user_id| - role = params['user'][user_id] - if relation = @group.actors.where(actor_id: user_id, actor_type: 'User') - relation.update_all(role: role) if @group.owner.id.to_s != user_id - else - relation = @group.actors.build(actor_id: user_id, actor_type: 'User', role: role) - relation.save! - end - end if params['user'] - if @group.save - flash[:notice] = t("flash.members.successfully_changed") - else - flash[:error] = t("flash.members.error_in_changing") - end + raise CanCan::AccessDenied if @group.owner_id.to_s == params[:member_id] + + relation = @group.actors.where(actor_id: params[:member_id], actor_type: 'User').first + relation ||= @group.actors.build(actor_id: params[:member_id], actor_type: 'User') + relation.role = params[:role] + relation.save! + + flash[:notice] = t("flash.members.successfully_changed") redirect_to group_members_path(@group) end def remove - all_user_ids = [] - params['user_remove'].each do |user_id, remove| - all_user_ids << user_id if remove == ["1"] - end if params['user_remove'] - User.where(id: all_user_ids).each do |user| + User.where(id: params[:members]).each do |user| @group.remove_member(user) end redirect_to group_members_path(@group) end def add - @user = User.find_by uname: params[:user_uname] + @user = User.where(id: params[:member_id]).first if !@user flash[:error] = t("flash.collaborators.wrong_user", uname: params[:user_uname]) elsif @group.add_member(@user, params[:role]) diff --git a/app/controllers/groups/profile_controller.rb b/app/controllers/groups/profile_controller.rb index 42ca97708..899b16940 100644 --- a/app/controllers/groups/profile_controller.rb +++ b/app/controllers/groups/profile_controller.rb @@ -1,6 +1,5 @@ class Groups::ProfileController < Groups::BaseController include AvatarHelper - layout 'bootstrap' load_and_authorize_resource class: Group, instance_name: 'group' skip_before_filter :authenticate_user!, only: :show if APP_CONFIG['anonymous_access'] diff --git a/app/controllers/platforms/platforms_controller.rb b/app/controllers/platforms/platforms_controller.rb index 7b95563e7..f3cb83ea7 100644 --- a/app/controllers/platforms/platforms_controller.rb +++ b/app/controllers/platforms/platforms_controller.rb @@ -124,14 +124,9 @@ class Platforms::PlatformsController < Platforms::BaseController end def remove_members - user_ids = params[:user_remove] ? - params[:user_remove].map{ |k, v| k if v.first == '1' }.compact : [] - User.where(id: user_ids).each{ |user| @platform.remove_member(user) } - redirect_to members_platform_path(@platform) - end - - def remove_member - User.where(id: params[:member_id]).each{ |user| @platform.remove_member(user) } + User.where(id: params[:members]).each do |user| + @platform.remove_member(user) + end redirect_to members_platform_path(@platform) end diff --git a/app/controllers/platforms/repositories_controller.rb b/app/controllers/platforms/repositories_controller.rb index fed6526e2..18b950e0a 100644 --- a/app/controllers/platforms/repositories_controller.rb +++ b/app/controllers/platforms/repositories_controller.rb @@ -36,14 +36,9 @@ class Platforms::RepositoriesController < Platforms::BaseController end def remove_members - user_ids = params[:user_remove] ? - params[:user_remove].map{ |k, v| k if v.first == '1' }.compact : [] - User.where(id: user_ids).each{ |user| @repository.remove_member(user) } - redirect_to edit_platform_repository_path(@platform, @repository) - end - - def remove_member - User.where(id: params[:member_id]).each{ |user| @repository.remove_member(user) } + User.where(id: params[:members]).each do |user| + @repository.remove_member(user) + end redirect_to edit_platform_repository_path(@platform, @repository) end diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb index 317d8c1e4..d16e92799 100644 --- a/app/helpers/projects_helper.rb +++ b/app/helpers/projects_helper.rb @@ -53,11 +53,9 @@ module ProjectsHelper end def options_for_collaborators_roles_select - options_for_select( - Relation::ROLES.collect { |role| - [t("layout.collaborators.role_names.#{ role }"), role] - } - ) + Relation::ROLES.map do |role| + [t("layout.collaborators.role_names.#{ role }"), role] + end end def visibility_icon(visibility) diff --git a/app/models/ability.rb b/app/models/ability.rb index eafc12862..70bda01ab 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -51,7 +51,7 @@ class Ability if user.user? can :edit, User, id: user.id can [:read, :create], Group - can [:update, :manage_members, :members, :add_member, :remove_member, :update_member], Group do |group| + can [:update, :manage_members, :members, :add_member, :remove_members, :update_member], Group do |group| group.actors.exists?(actor_type: 'User', actor_id: user.id, role: 'admin') # or group.owner_id = user.id end can :write, Group do |group| @@ -68,7 +68,7 @@ class Ability # can([:read, :archive, :membered, :get_id], Project, read_relations_for('projects')) {|project| local_reader? project} can([:read, :archive, :membered, :get_id], Project, read_relations_with_projects) {|project| local_reader? project} can(:write, Project) {|project| local_writer? project} # for grack - can [:update, :sections, :manage_collaborators, :autocomplete_maintainers, :add_member, :remove_member, :update_member, :members, :schedule], Project do |project| + can [:update, :sections, :manage_collaborators, :autocomplete_maintainers, :add_member, :remove_members, :update_member, :members, :schedule], Project do |project| local_admin? project end can(:fork, Project) {|project| can? :read, project} @@ -116,7 +116,7 @@ class Ability can([:read, :related, :members], Platform, read_relations_for('platforms')) {|platform| local_reader? platform} can [:read, :related], Platform, id: user.repositories.pluck(:platform_id) can([:update, :destroy, :change_visibility], Platform) {|platform| owner?(platform) } - can([:local_admin_manage, :members, :add_member, :remove_member, :remove_members, :remove_file] , Platform) {|platform| owner?(platform) || local_admin?(platform) } + can([:local_admin_manage, :members, :add_member, :remove_members, :remove_file] , Platform) {|platform| owner?(platform) || local_admin?(platform) } can([:create, :publish], MassBuild) {|mass_build| owner?(mass_build.save_to_platform) || local_admin?(mass_build.save_to_platform)} can(:cancel, MassBuild) {|mass_build| (owner?(mass_build.save_to_platform) || local_admin?(mass_build.save_to_platform)) && !mass_build.stop_build} @@ -126,7 +126,7 @@ class Ability can([:read, :projects_list, :projects], Repository, read_relations_for('repositories')) {|repository| can? :show, repository.platform} can([:read, :projects_list, :projects], Repository, read_relations_for('repositories', 'platforms')) {|repository| local_reader? repository.platform} can([:create, :edit, :update, :destroy, :projects_list, :projects, :add_project, :remove_project, :regenerate_metadata, :sync_lock_file, :add_repo_lock_file, :remove_repo_lock_file], Repository) {|repository| local_admin? repository.platform} - can([:remove_members, :remove_member, :add_member, :signatures, :packages], Repository) {|repository| owner?(repository.platform) || local_admin?(repository.platform)} + can([:remove_members, :add_member, :signatures, :packages], Repository) {|repository| owner?(repository.platform) || local_admin?(repository.platform)} can([:add_project, :remove_project], Repository) {|repository| repository.members.exists?(id: user.id)} can(:clear, Platform) {|platform| owner?(platform) && platform.personal?} can(:regenerate_metadata, Platform) {|platform| owner?(platform) || local_admin?(platform)} @@ -169,12 +169,12 @@ class Ability cannot [:regenerate_metadata, :destroy], Platform, platform_type: 'personal' cannot [:create, :destroy], Repository, platform: {platform_type: 'personal'}, name: 'main' cannot [:packages], Repository, platform: {platform_type: 'personal'} - cannot [:remove_members, :remove_member, :add_member, :sync_lock_file, :add_repo_lock_file, :remove_repo_lock_file], Repository, platform: {platform_type: 'personal'} + cannot [:remove_members, :add_member, :sync_lock_file, :add_repo_lock_file, :remove_repo_lock_file], Repository, platform: {platform_type: 'personal'} cannot :clear, Platform, platform_type: 'main' cannot :destroy, Issue - cannot [:members, :add_member, :remove_member, :remove_members], Platform, platform_type: 'personal' + cannot [:members, :add_member, :remove_members], Platform, platform_type: 'personal' cannot [:create, :update, :destroy, :clone], Product, platform: {platform_type: 'personal'} cannot [:clone], Platform, platform_type: 'personal' diff --git a/app/views/groups/base/_sidebar.html.haml b/app/views/groups/base/_sidebar.html.haml deleted file mode 100644 index 7c09f6192..000000000 --- a/app/views/groups/base/_sidebar.html.haml +++ /dev/null @@ -1,13 +0,0 @@ -.admin-preferences -- act = action_name.to_sym -- contr = controller_name.to_sym - -%aside - .admin-preferences - %ul - - if can? :edit, @group - %li{class: (act == :edit && contr == :profile) ? 'active' : ''} - = link_to t("layout.groups.edit"), edit_group_path(@group) - - if can? :manage_members, @group - %li{class: (act == :index && contr == :members) ? 'active' : ''} - = link_to t("layout.groups.edit_members"), group_members_path(@group) diff --git a/app/views/groups/members/index.html.haml b/app/views/groups/members/index.html.haml deleted file mode 100644 index 32e5f159b..000000000 --- a/app/views/groups/members/index.html.haml +++ /dev/null @@ -1,41 +0,0 @@ --set_meta_tags title: [title_object(@group), t('layout.groups.members')] -= form_tag group_members_path(@group), id: 'members_form', delete_url: remove_group_members_path(@group) do - = hidden_field_tag "_method", "post" - %table.tablesorter{cellpadding: "0", cellspacing: "0"} - %thead - %tr - %th - \  - %th= t("layout.collaborators.members") - %th{colspan: "3"}= t("layout.collaborators.roles") - %tbody - - actors = @group.actors.where(actor_id: @members.map(&:id), actor_type: 'User') - - @members.each do |user| - %tr - %td - %span#niceCheckbox1.niceCheck-main= check_box_tag "user_remove[#{user.id}][]" - %td - .img= image_tag avatar_url(user) - .forimg= link_to user.fullname, user_path(user) - - Relation::ROLES.each_with_index do |role, i| - %td - - checked = actors.find{ |a| a.actor_id == user.id && a.role == role } - .radio= radio_button_tag "user[#{user.id}]", role, (checked ? :checked : nil), class: 'niceRadio' - .forradio= t("layout.collaborators.role_names.#{ role }") - = link_to_function t("layout.delete"), "deleteAdminMember();", class: 'button' - .both -.hr.top - -= form_tag add_group_members_path(@group) do - .admin-search= autocomplete_field_tag 'user_uname', params[:user_uname], autocomplete_user_uname_autocompletes_path - .admin-role - .lineForm= select_tag 'role', options_for_collaborators_roles_select - .both - %br - = submit_tag t('layout.add'), class: 'button', data: {'disable-with' => t('layout.processing')} - -.hr.bottom -.both -= link_to_function t("layout.save"), "saveAdminMember();", class: 'button' - -- content_for :sidebar, render('sidebar') diff --git a/app/views/groups/members/index.html.slim b/app/views/groups/members/index.html.slim new file mode 100644 index 000000000..5a67744b1 --- /dev/null +++ b/app/views/groups/members/index.html.slim @@ -0,0 +1,12 @@ +-set_meta_tags title: [title_object(@group), t('layout.groups.members')] + += render 'groups/base/submenu' + +.container.col-md-offset-2.col-md-8 + .row + = render 'shared/members_table', + remove_members_path: remove_group_members_path(@group), + add_member_path: add_group_members_path(@group), + members: @members, + update_roles_path: group_members_path(@group), + editable_object: @group diff --git a/app/views/platforms/platforms/members.html.slim b/app/views/platforms/platforms/members.html.slim index c8d6bbd2e..ebbf4e2bd 100644 --- a/app/views/platforms/platforms/members.html.slim +++ b/app/views/platforms/platforms/members.html.slim @@ -5,7 +5,6 @@ .row = render "shared/members_table", remove_members_path: remove_members_platform_path(@platform), - remove_member_path: remove_member_platform_path(@platform), add_member_path: add_member_platform_path(@platform), members: @members.select{|u| u != @platform.owner}, editable_object: @platform diff --git a/app/views/platforms/repositories/edit.html.slim b/app/views/platforms/repositories/edit.html.slim index 2f2d90233..ab50fbc26 100644 --- a/app/views/platforms/repositories/edit.html.slim +++ b/app/views/platforms/repositories/edit.html.slim @@ -70,7 +70,6 @@ - if @platform.main? = render "shared/members_table", remove_members_path: remove_members_platform_repository_path(@platform, @repository), - remove_member_path: remove_member_platform_repository_path(@platform, @repository), - add_member_path: add_member_platform_repository_path(@platform, @repository), - members: @members, - editable_object: @repository + add_member_path: add_member_platform_repository_path(@platform, @repository), + members: @members, + editable_object: @repository diff --git a/app/views/shared/_members_table.html.slim b/app/views/shared/_members_table.html.slim index 643da7f34..6c742562d 100644 --- a/app/views/shared/_members_table.html.slim +++ b/app/views/shared/_members_table.html.slim @@ -1,7 +1,5 @@ - - - -= form_tag remove_members_path, id: 'members_form', method: :post do +- update_roles_path ||= false += form_tag remove_members_path, id: 'members_form', method: :delete do table.table.table-striped thead tr @@ -9,25 +7,51 @@ th th = t("layout.collaborators.members") - - if can? :remove_member, editable_object + - if can? :remove_members, editable_object + - if update_roles_path + th.buttons.text-center colspan=3 + = t("layout.collaborators.roles") th.buttons = t("layout.remove") tbody - - members.each_with_index do |user, num| - tr id="admin-table-members-row#{num}" + - if update_roles_path + - actors = editable_object.actors.where(actor_id: members.map(&:id), actor_type: 'User').to_a + - members.each do |user| + tr - if can? :remove_members, editable_object td - = check_box_tag "user_remove[#{user.id}][]" + = check_box_tag "members[]", user.id td span - = image_tag avatar_url(user) + = image_tag avatar_url(user), size: '30x30' |   = link_to user.fullname, user_path(user) - - if can? :remove_member, editable_object + - if can? :remove_members, editable_object + - if update_roles_path + - actor = actors.find{ |a| a.actor_id == user.id } + - Relation::ROLES.each_with_index do |role, i| + td ng-init="user_#{user.id}_role = '#{actor.role}'" + input[ + type = 'radio' + ng-model = "user_#{user.id}_role" + value = role ] + |   + = t("layout.collaborators.role_names.#{ role }") td - = link_to "#{remove_member_path}?member_id=#{user.id}", method: :delete, data: { confirm: t("layout.confirm") } do + - if update_roles_path + - path = "#{update_roles_path}?member_id=#{user.id}" + a[ + ng-href = "{{'#{path}&role=' + user_#{user.id}_role}}" + data-method = 'put' + data-confirm = t('layout.confirm') ] + + span.glyphicon.glyphicon-ok + |   + + = link_to "#{remove_members_path}?members=#{user.id}", method: :delete, data: { confirm: t("layout.confirm") } do span.glyphicon.glyphicon-remove |   + - if can? :remove_members, editable_object = submit_tag t('layout.delete'), class: 'btn btn-danger', data: {'disable-with' => t('layout.processing')} @@ -44,5 +68,12 @@ 'data-id' => '#member_id_field', class: 'typeahead' } + - if update_roles_path + |   + = f.input :role, + collection: options_for_collaborators_roles_select, + input_html: { name: :role }, + include_blank: false + |   = f.button :submit, t('layout.add') diff --git a/config/routes.rb b/config/routes.rb index 39b5f20d8..27f2eeb7b 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -169,9 +169,8 @@ Rosa::Application.routes.draw do put :clear get :clone get :members - post :remove_members # fixme: change post to delete + delete :remove_members post :change_visibility - delete :remove_member post :add_member post :make_clone get :advisories @@ -198,8 +197,7 @@ Rosa::Application.routes.draw do get :remove_project delete :remove_project get :projects_list - post :remove_members # fixme: change post to delete - delete :remove_member + delete :remove_members post :add_member put :regenerate_metadata put :sync_lock_file @@ -229,7 +227,6 @@ Rosa::Application.routes.draw do resources :autocompletes, only: [] do collection do get :autocomplete_user_uname - get :autocomplete_group_uname get :autocomplete_extra_build_list get :autocomplete_extra_mass_build get :autocomplete_extra_repositories @@ -267,8 +264,8 @@ Rosa::Application.routes.draw do delete :remove_user, on: :member resources :members, only: [:index] do collection do - post :add - post :update + post :add + put :update delete :remove end end