diff --git a/app/controllers/admin/users_controller.rb b/app/controllers/admin/users_controller.rb index 49ea1676..727354fb 100644 --- a/app/controllers/admin/users_controller.rb +++ b/app/controllers/admin/users_controller.rb @@ -1,6 +1,6 @@ module Admin class UsersController < ApplicationController - load_and_authorize_resource :user + load_and_authorize_resource def index @users = User.all @@ -11,16 +11,28 @@ module Admin # Variable @show_attributes holds the attributes that are visible for the 'show' action # If you want to change the attributes that are shown in the 'show' action of users # add/remove the attributes in the following string array - @show_attributes = %w(name email affiliation biography registered attended created_at + @show_attributes = %w(name email affiliation biography registered attended roles created_at updated_at sign_in_count current_sign_in_at last_sign_in_at current_sign_in_ip last_sign_in_ip) end def update + params[:user].delete :roles_attributes if params[:user] @user.update_attributes!(params[:user]) redirect_to admin_users_path, notice: "Updated #{@user.email}" end + def add_role + role = params[:user][:roles_attributes][:"0"] + @user.add_role role['name'].parameterize.underscore.to_sym, Conference.find(role['resource_id']) + + respond_to do |format| + format.html + format.js + end + + end + def edit end diff --git a/app/controllers/conference_registration_controller.rb b/app/controllers/conference_registration_controller.rb index 6bd5c248..27179c4e 100644 --- a/app/controllers/conference_registration_controller.rb +++ b/app/controllers/conference_registration_controller.rb @@ -1,7 +1,7 @@ class ConferenceRegistrationController < ApplicationController before_filter :verify_user - authorize_resource class: false load_and_authorize_resource :conference, find_by: :short_title + authorize_resource :conference_registration, class: Registration def register @workshops = @conference.events.where('require_registration = ? AND state LIKE ?', diff --git a/app/models/ability.rb b/app/models/ability.rb index 902edff6..7d833ed2 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -21,7 +21,30 @@ class Ability user ||= User.new # guest user (not logged in) - # Abilities per role + # Check roles of user, using rolify. Role name is *case sensitive* + # user.is_organizer? or user.has_role? :organizer + # user.is_cfp_of? Conference or user.has_role? :cfp, Conference + # user.is_info_desk_of? Conference + # user.is_volunteer_coordinator_of? Conference + # user.is_attendee_of? Conference + # The following is wrong because a user will only have 'cfp' role for a specific conference + # user.is_cfp? # This is always false + + # Ids of all the conferences for which the user has an 'organizer' role + conf_ids_for_organizer = + Conference.with_role(:organizer, user).pluck(:id) unless user.new_record? + # Ids of the venues of the conference for which (conferences) the user has an 'organizer' role + conf_ids_for_organizer_venue = + Conference.with_role(:organizer, user).pluck(:venue_id) unless user.new_record? + # Ids of all the conferences for which the user has a 'cfp' role + conf_ids_for_cfp = + Conference.with_role(:cfp, user).pluck(:id) unless user.new_record? + # Ids of all the conferences for which the user has an 'info_desk' role + conf_ids_for_info_desk = + Conference.with_role(:info_desk, user).pluck(:id) unless user.new_record? + # Ids of all the conferences for which the user has a 'volunteer_coordinator' role + conf_ids_for_volunteer_coordinator = + Conference.with_role(:volunteer_coordinator, user).pluck(:id) unless user.new_record? # Abilities for signed in users unless user.new_record? @@ -30,7 +53,7 @@ class Ability can :manage, Conference, id: Conference.with_role(:organizer, user).map(&:id) # Conference Registration - can :manage, :conference_registration + can :manage, Registration # Proposals # Users can edit their own proposals @@ -59,30 +82,13 @@ class Ability can :show, Event # if confirmed...? can :index, :schedule # show? - # Check roles of user, using rolify. Role name is *case sensitive* - # user.is_organizer? or user.has_role? :organizer - # user.is_cfp_of? Conference or user.has_role? :cfp, Conference - # user.is_info_desk_of? Conference - # user.is_volunteer_coordinator_of? Conference - # user.is_attendee_of? Conference - # The following is wrong because a user will only have 'cfp' role for a specific conference - # user.is_cfp? # This is always false - - # Ids of all the conferences for which the user has an 'organizer' role - conf_ids_for_organizer = - Conference.with_role(:organizer, user).pluck(:id) unless user.new_record? - # Ids of the venues of the conference for which (conferences) the user has an 'organizer' role - conf_ids_for_organizer_venue = - Conference.with_role(:organizer, user).pluck(:venue_id) unless user.new_record? - # Ids of all the conferences for which the user has a 'cfp' role - conf_ids_for_cfp = - Conference.with_role(:cfp, user).pluck(:id) unless user.new_record? - # Ids of all the conferences for which the user has an 'info_desk' role - conf_ids_for_info_desk = - Conference.with_role(:info_desk, user).pluck(:id) unless user.new_record? - # Ids of all the conferences for which the user has a 'volunteer_coordinator' role - conf_ids_for_volunteer_coordinator = - Conference.with_role(:volunteer_coordinator, user).pluck(:id) unless user.new_record? + ## Authorization for admins + if user.is_admin # is_admin is an attribute of User + can :create, Conference + can :index, Conference # this will allow the Conference to appear in the menu + can :view, Conference # for /admin/conference overview + can :manage, User # to make other users admins + end ## Authorization for ORGANIZER # If a user is organizer of a conference, they can manage everything related to this conference @@ -116,13 +122,6 @@ class Ability # can :manage, Role, resource_id: conf_ids_for_organizer end - if user.is_admin # is_admin is an attribute of User - can :create, Conference - can :index, Conference # this will allow the Conference to appear in the menu - can :view, Conference # for /admin/conference overview - can :manage, User # to make other users admins - end - ## Authorization for CfP # A user can manage events of the conference, for which conference the user has a 'cfp' role if user.has_role? :cfp, :any diff --git a/app/models/role.rb b/app/models/role.rb index ac2b9011..0a9bdf88 100644 --- a/app/models/role.rb +++ b/app/models/role.rb @@ -4,4 +4,6 @@ class Role < ActiveRecord::Base belongs_to :resource, polymorphic: true scopify + + LABELS = ['Participant', 'Attendee', 'Volunteer', 'Speaker', 'Sponsor', 'Press', 'Organizer', 'CfP', 'Info Desk', 'Volunteers Coordinator'] end diff --git a/app/views/admin/users/_add_roles.html.haml b/app/views/admin/users/_add_roles.html.haml new file mode 100644 index 00000000..93a0651f --- /dev/null +++ b/app/views/admin/users/_add_roles.html.haml @@ -0,0 +1,11 @@ += semantic_form_for(user, url: add_role_admin_user_path(user), remote: true) do |f| + .pull-left + = f.action :submit, as: :button, label: 'Add Role', button_html: {value: 'Save', class: 'btn btn-success'} + %br + %br + = f.fields_for :roles, Role.new do |role| + = role.input :name, label: 'Select role', collection: Role::LABELS + = role.label 'Select Conference' + %br + = role.input :resource, label: false, collection: Conference.all.map { |c| [c.short_title, c.id] } + %br diff --git a/app/views/admin/users/_form.html.haml b/app/views/admin/users/_form.html.haml index ddd33cf8..18a751f5 100644 --- a/app/views/admin/users/_form.html.haml +++ b/app/views/admin/users/_form.html.haml @@ -1,8 +1,13 @@ = semantic_form_for [:admin, @user] do |f| - = f.inputs "Basic Information" do + = f.inputs 'Basic Information' do = f.input :name, :as => :string = f.input :email - = f.input :affiliation, :as => :string - = f.input :biography, :input_html => {:rows => 10} - = f.actions do - = f.action :submit, :button_html => {:class => "btn btn-primary"} + = f.input :affiliation, as: :string + = f.input :biography, input_html: { rows: 5, "onkeyup" => "word_count(this, 'biography-count', 150)" } + You have used + %span#biography-count #{@user.biography_word_count} + words. Biographies are limited to 150 words. + %br + %br + = f.actions do + = f.action :submit, button_html: { class: 'btn btn-primary' } diff --git a/app/views/admin/users/_roles.html.haml b/app/views/admin/users/_roles.html.haml deleted file mode 100644 index 6b225689..00000000 --- a/app/views/admin/users/_roles.html.haml +++ /dev/null @@ -1,12 +0,0 @@ -- if current_user == user - You cannot modify your own role! - %br - %button{:class=> "btn btn-danger", "data-dismiss"=> "modal", "aria-hidden"=>"true"} - Cancel -- else - = "Give #{user.name} (#{user.email}) the following roles:" - = semantic_form_for(user, :url => admin_user_path(user), :method => :put) do |f| - = f.input :roles, :label => false, collection: @roles - %button{:class=> "btn btn-danger", "data-dismiss"=> "modal", "aria-hidden"=>"true"} - Cancel - = f.action :submit, :as => :button, :button_html => {:value => "Save", :class => "btn btn-primary"} diff --git a/app/views/admin/users/_user_roles.html.haml b/app/views/admin/users/_user_roles.html.haml new file mode 100644 index 00000000..caceec39 --- /dev/null +++ b/app/views/admin/users/_user_roles.html.haml @@ -0,0 +1,10 @@ +- user ||= @user +.roles{ id: 'current_roles' } + = semantic_form_for(user, url: admin_user_path(user)) do |f| + = f.action :submit, as: :button, label: 'Update Roles', button_html: {value: 'Save', class: 'btn btn-primary'} + = f.inputs "Roles for #{@user.name}" do + - user.roles.each do |role| + %br + = hidden_field_tag "user[role_ids][]", nil + = check_box_tag "user[role_ids][]", role.id, user.roles.include?(role), id: dom_id(role) + = label_tag dom_id(role), "#{ role.name.capitalize } for #{ role.resource_type.constantize.find(role.resource_id).short_title }" diff --git a/app/views/admin/users/add_role.js.erb b/app/views/admin/users/add_role.js.erb new file mode 100644 index 00000000..9c38fbbd --- /dev/null +++ b/app/views/admin/users/add_role.js.erb @@ -0,0 +1 @@ +$('#current_roles').html("<%= escape_javascript(render partial: 'user_roles').html_safe %>"); diff --git a/app/views/admin/users/edit.html.haml b/app/views/admin/users/edit.html.haml new file mode 100644 index 00000000..2536e5b6 --- /dev/null +++ b/app/views/admin/users/edit.html.haml @@ -0,0 +1,19 @@ +.row + .col-md-12 + .tabbable + %ul.nav.nav-tabs + %li.active + = link_to 'User', '#user-content', 'data-toggle'=>'tab' + %li= link_to 'Roles', '#roles-content', 'data-toggle'=>'tab' + .tab-content + #user-content.tab-pane.active + = render partial: 'form' + + #roles-content.tab-pane + .row + .col-md-6 + %br + = render partial: 'user_roles', locals: { user: @user } + .col-md-6 + %br + = render partial: 'add_roles', locals: { user: @user } diff --git a/app/views/admin/users/index.html.haml b/app/views/admin/users/index.html.haml index 89ac5736..f8cabef6 100644 --- a/app/views/admin/users/index.html.haml +++ b/app/views/admin/users/index.html.haml @@ -40,26 +40,17 @@ %td = user.registrations.count %td - .modal.fade{:id => "user-role-selection-#{user.id}", "role" => "dialog", "aria-hidden" => "true"} - .modal-dialog - .modal-content - .modal-header - %button{"type"=>"button", :class=>"close", "data-dismiss"=>"modal", "aria-hidden"=>"true"} - × - %h3{:id => "role-selector-header-#{user.id}"} - Modifying Roles - .modal-body - = render partial: 'roles', locals: { user: user } - if can? :update, Role - =link_to "#{user.roles.map { |role| role.name }.join ', '}", "#", "data-toggle" => "modal", "data-target" => "#user-role-selection-#{user.id}",id: "user-modify-role-#{user.id}" + = link_to "#{ user.roles.present? ? (user.roles.map { |role| "#{ role.name.titleize }(#{ role.resource_type.constantize.find(role.resource_id).short_title })" }.join ', ') : 'Add Role'}", "#", "data-toggle" => "modal", "data-target" => "#user-role-selection-#{user.id}",id: "user-modify-role-#{user.id}" + - else - = user.roles.map { |role| role.name }.join ', ' - - if can? :update, user - %td - = link_to "Edit", edit_admin_user_path(user) + = user.roles.map { |role| "#{ role.name.capitalize } for #{ role.resource_type.constantize.find(role.resource_id).short_title }" }.join ', ' - if can? :show, user %td - = link_to "View", admin_user_path(user) + = link_to "View", admin_user_path(user), class: 'btn btn-success' + - if can? :update, user + %td + = link_to "Edit", edit_admin_user_path(user), class: 'btn btn-primary' - if can? :destroy, user %td - if current_user.id == user.id or user.role_ids.include? 3 diff --git a/app/views/admin/users/show.html.haml b/app/views/admin/users/show.html.haml index c41a6b3b..56aaa5a7 100644 --- a/app/views/admin/users/show.html.haml +++ b/app/views/admin/users/show.html.haml @@ -1,7 +1,11 @@ %table.table - @show_attributes.each do |attr| %tr - %td + %td{style: 'width:20%'} %b = attr.capitalize.gsub('_', ' ') - %td= @user.send(attr) + - if attr == 'roles' + %td + = @user.send(attr).map { |role| "#{ role.name.capitalize } of #{ role.resource_type.constantize.find(role.resource_id).short_title }"}.join(', ') + - else + %td= @user.send(attr) diff --git a/config/routes.rb b/config/routes.rb index 3995e25c..feab1685 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -5,7 +5,11 @@ Osem::Application.routes.draw do path: 'accounts' namespace :admin do - resources :users + resources :users do + member do + patch 'add_role' => 'users#add_role' + end + end resources :people resources :conference do resource :schedule, only: [:show, :update]