diff --git a/Gemfile.lock b/Gemfile.lock index e0b2792..05cab02 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -48,6 +48,7 @@ rake (>= 10.4, < 13.0) annotate_gem (0.0.13) bundler (~> 1.1) + api-pagination (4.8.2) archive-zip (0.12.0) io-like (~> 0.3.0) arel (6.0.4) @@ -281,7 +282,6 @@ omniauth (>= 1.0.0) options (2.3.2) orm_adapter (0.5.0) - pager_api (0.3.1) parallel (1.17.0) parser (2.6.2.1) ast (~> 2.4.0) @@ -483,6 +483,7 @@ activerecord-session_store annotate annotate_gem + api-pagination autoprefixer-rails better_errors binding_of_caller @@ -522,7 +523,6 @@ omniauth omniauth-orcid omniauth-shibboleth - pager_api pg (~> 0.19.0) progress_bar puma diff --git a/app/controllers/org_admin/departments_controller.rb b/app/controllers/org_admin/departments_controller.rb new file mode 100644 index 0000000..fc32fb9 --- /dev/null +++ b/app/controllers/org_admin/departments_controller.rb @@ -0,0 +1,74 @@ +# frozen_string_literal: true + +class OrgAdmin::DepartmentsController < ApplicationController + + after_action :verify_authorized + respond_to :html + + # GET add new department + def new + @department = Department.new + authorize @department + end + + # POST /departments + # POST /departments.json + def create + @department = Department.new(department_params) + authorize @department + @department.org_id = current_user.org_id + + if @department.save + flash.now[:notice] = success_message(@department, _("created")) + # reset value + @department = nil + render :new + else + flash.now[:alert] = failure_message(@department, _("create")) + render :new + end + end + + # GET /departments/1/edit + def edit + @department = Department.find(params[:id]) + authorize @department + end + + # PUT /departments/1 + def update + @department = Department.find(params[:id]) + authorize @department + @department.org_id = current_user.org_id + + if @department.update(department_params) + flash.now[:notice] = success_message(@department, _("saved")) + render :edit + else + flash.now[:alert] = failure_message(@department, _("save")) + render :edit + end + end + + # DELETE /departments/1 + def destroy + @department = Department.find(params[:id]) + authorize @department + url = "#{admin_edit_org_path(current_user.org_id)}\#departments" + if @department.destroy + flash[:notice] = success_message(@department, _("deleted")) + redirect_to url + else + flash[:alert] = failure_message(@department, _("delete")) + redirect_to url + end + end + + + private + + def department_params + params.require(:department).permit(:id, :name, :code, :org_id) + end + +end diff --git a/app/controllers/paginable/departments_controller.rb b/app/controllers/paginable/departments_controller.rb new file mode 100644 index 0000000..9bef30d --- /dev/null +++ b/app/controllers/paginable/departments_controller.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +class Paginable::DepartmentsController < ApplicationController + + after_action :verify_authorized + respond_to :html + + include Paginable + + # /paginable/departments/index/:page + def index + authorize Department + paginable_renderise( + partial: "index", + scope: Department.by_org(current_user.org), + query_params: { sort_field: "departments.name", sort_direction: :asc } + ) + end + +end diff --git a/app/controllers/paginable/guidances_controller.rb b/app/controllers/paginable/guidances_controller.rb index efec2eb..5f6fa0b 100644 --- a/app/controllers/paginable/guidances_controller.rb +++ b/app/controllers/paginable/guidances_controller.rb @@ -9,8 +9,7 @@ authorize(Guidance) paginable_renderise( partial: "index", - scope: Guidance.by_org(current_user.org) - .includes(:guidance_group, :themes), + scope: org.admin, query_params: { sort_field: "guidances.text", sort_direction: :asc } ) end diff --git a/app/controllers/registrations_controller.rb b/app/controllers/registrations_controller.rb index 3defde5..503b2f6 100644 --- a/app/controllers/registrations_controller.rb +++ b/app/controllers/registrations_controller.rb @@ -190,7 +190,9 @@ else successfully_updated = current_user.update_with_password(password_update) if !successfully_updated - message = _("Save unsuccessful. That email address is already registered. You must enter a unique email address.") + message = _("Save unsuccessful. \ + That email address is already registered. \ + You must enter a unique email address.") end end else @@ -268,14 +270,14 @@ def update_params params.require(:user).permit(:firstname, :org_id, :other_organisation, - :language_id, :surname) + :language_id, :surname, :department_id) end def password_update params.require(:user).permit(:email, :firstname, :current_password, :org_id, :language_id, :password, :password_confirmation, :surname, - :other_organisation) + :other_organisation, :department_id) end end diff --git a/app/models/department.rb b/app/models/department.rb new file mode 100644 index 0000000..16ca731 --- /dev/null +++ b/app/models/department.rb @@ -0,0 +1,43 @@ +# frozen_string_literal: true + +# == Schema Information +# +# Table name: departments +# +# id :integer not null, primary key +# code :string +# name :string +# created_at :datetime not null +# updated_at :datetime not null +# org_id :integer +# +# Indexes +# +# index_departments_on_org_id (org_id) +# + +class Department < ActiveRecord::Base + + include ValidationMessages + + belongs_to :org + + has_many :users + + # =============== + # = Validations = + # =============== + + validates :org, presence: { message: PRESENCE_MESSAGE } + + validates :name, presence: { message: PRESENCE_MESSAGE }, + uniqueness: { message: UNIQUENESS_MESSAGE, + scope: :org_id } + + validates :name, uniqueness: { message: UNIQUENESS_MESSAGE, + scope: :org_id } + + # Retrieves every department associated to an org + scope :by_org, ->(org) { where(org_id: org.id) } + +end diff --git a/app/models/org.rb b/app/models/org.rb index ade85ba..c1970be 100644 --- a/app/models/org.rb +++ b/app/models/org.rb @@ -73,6 +73,7 @@ has_many :identifier_schemes, through: :org_identifiers + has_many :departments # =============== # = Validations = @@ -166,9 +167,9 @@ # Returns nil def get_locale if !self.language.nil? - return self.language.abbreviation + self.language.abbreviation else - return nil + nil end end @@ -188,7 +189,7 @@ ret << "Research Institute" if self.research_institute? ret << "Project" if self.project? ret << "School" if self.school? - return (ret.length > 0 ? ret.join(", ") : "None") + (ret.length > 0 ? ret.join(", ") : "None") end def funder_only? @@ -209,9 +210,9 @@ # Returns String def short_name if abbreviation.nil? then - return name + name else - return abbreviation + abbreviation end end @@ -220,7 +221,7 @@ # # Returns ActiveRecord::Relation def published_templates - return templates.where("published = ?", true) + templates.where("published = ?", true) end def org_admins diff --git a/app/models/user.rb b/app/models/user.rb index 479c74c..9e10a71 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -32,6 +32,7 @@ # surname :string # created_at :datetime not null # updated_at :datetime not null +# department_id :integer # invited_by_id :integer # language_id :integer # org_id :integer @@ -43,6 +44,7 @@ # # Foreign Keys # +# fk_rails_... (department_id => departments.id) # fk_rails_... (language_id => languages.id) # fk_rails_... (org_id => orgs.id) # @@ -78,6 +80,8 @@ belongs_to :org + belongs_to :department, required: false + has_one :pref has_many :answers @@ -190,11 +194,11 @@ # Returns nil def get_locale if !self.language.nil? - return self.language.abbreviation + self.language.abbreviation elsif !self.org.nil? - return self.org.get_locale + self.org.get_locale else - return nil + nil end end @@ -205,10 +209,10 @@ # Returns String def name(use_email = true) if (firstname.blank? && surname.blank?) || use_email then - return email + email else name = "#{firstname} #{surname}" - return name.strip + name.strip end end @@ -226,7 +230,7 @@ # # Returns Boolean def can_super_admin? - return self.can_add_orgs? || self.can_grant_api_to_orgs? || self.can_change_org? + self.can_add_orgs? || self.can_grant_api_to_orgs? || self.can_change_org? end # Checks if the user is an organisation admin if the user has any privlege which @@ -234,9 +238,9 @@ # # Returns Boolean def can_org_admin? - return self.can_grant_permissions? || self.can_modify_guidance? || - self.can_modify_templates? || self.can_modify_org_details? || - self.can_review_plans? + self.can_grant_permissions? || self.can_modify_guidance? || + self.can_modify_templates? || self.can_modify_org_details? || + self.can_review_plans? end # Can the User add new organisations? diff --git a/app/policies/department_policy.rb b/app/policies/department_policy.rb new file mode 100644 index 0000000..bfcf900 --- /dev/null +++ b/app/policies/department_policy.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +class DepartmentPolicy < ApplicationPolicy + + attr_reader :user + attr_reader :department + + def initialize(user, department) + raise Pundit::NotAuthorizedError, "must be logged in" unless user + @user = user + @department = department + end + + def new? + @user.can_org_admin? + end + + def create? + @user.can_org_admin? + end + + def edit? + # Only org_admins can edit their own org's departments + @user.can_org_admin? && @user.org.id === @department.org_id + end + + def update? + # Only org_admins can update their own org's departments + @user.can_org_admin? && @user.org.id === @department.org_id + end + + def destroy? + # Only org_admins can delete their own org's departments + @user.can_org_admin? && @user.org.id === @department.org_id + end + +end diff --git a/app/views/devise/registrations/_personal_details.html.erb b/app/views/devise/registrations/_personal_details.html.erb index 29ae105..266e720 100644 --- a/app/views/devise/registrations/_personal_details.html.erb +++ b/app/views/devise/registrations/_personal_details.html.erb @@ -29,6 +29,17 @@ <% if org_admin %> <% end %> + + <% departments = current_user.org.departments %> +
<%= _('School or Department') %> <%= paginable_sort_link('departments.name') %> | +<%= _('Abbreviated Name or Code') %> <%= paginable_sort_link('departments.code') %> | +<%= _('Actions') %> | +
---|---|---|
<%= department.name %> | +<%= department.code %> | +
+
+
+
+
+ |
+