From 76f20b0ede0896d6eb71b04b36e87391c092483b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Gaya?= <sebastien.gaya@gmail.com> Date: Wed, 26 Jan 2022 15:52:21 +0100 Subject: [PATCH] wip school roles --- .../school/role/people_controller.rb | 56 +++++++++++++++++ .../education/school/roles_controller.rb | 62 +++++++++++++++++++ .../admin/education/schools_controller.rb | 1 + app/models/ability.rb | 4 ++ app/models/education/school.rb | 4 ++ app/models/university/person/involvement.rb | 12 +++- app/models/university/role.rb | 9 +++ .../school/role/people/_form.html.erb | 23 +++++++ .../school/role/people/_list.html.erb | 33 ++++++++++ .../school/role/people/edit.html.erb | 3 + .../education/school/role/people/new.html.erb | 3 + .../education/school/roles/_form.html.erb | 17 +++++ .../education/school/roles/_list.html.erb | 35 +++++++++++ .../education/school/roles/edit.html.erb | 3 + .../education/school/roles/index.html.erb | 3 + .../admin/education/school/roles/new.html.erb | 3 + .../education/school/roles/show.html.erb | 4 ++ .../admin/education/schools/show.html.erb | 31 +++++++++- config/locales/university/en.yml | 6 ++ config/locales/university/fr.yml | 6 ++ config/routes/admin/education.rb | 10 +++ lib/tasks/app.rake | 2 +- 22 files changed, 325 insertions(+), 5 deletions(-) create mode 100644 app/controllers/admin/education/school/role/people_controller.rb create mode 100644 app/controllers/admin/education/school/roles_controller.rb create mode 100644 app/views/admin/education/school/role/people/_form.html.erb create mode 100644 app/views/admin/education/school/role/people/_list.html.erb create mode 100644 app/views/admin/education/school/role/people/edit.html.erb create mode 100644 app/views/admin/education/school/role/people/new.html.erb create mode 100644 app/views/admin/education/school/roles/_form.html.erb create mode 100644 app/views/admin/education/school/roles/_list.html.erb create mode 100644 app/views/admin/education/school/roles/edit.html.erb create mode 100644 app/views/admin/education/school/roles/index.html.erb create mode 100644 app/views/admin/education/school/roles/new.html.erb create mode 100644 app/views/admin/education/school/roles/show.html.erb diff --git a/app/controllers/admin/education/school/role/people_controller.rb b/app/controllers/admin/education/school/role/people_controller.rb new file mode 100644 index 000000000..d1929ee37 --- /dev/null +++ b/app/controllers/admin/education/school/role/people_controller.rb @@ -0,0 +1,56 @@ +class Admin::Education::School::Role::PeopleController < Admin::Education::School::ApplicationController + load_and_authorize_resource :role, class: University::Role, through: :school, param: :role_id, through_association: :university_roles + load_and_authorize_resource :involvement, class: University::Person::Involvement, through: :role, parent: false + + def new + breadcrumb + end + + def edit + breadcrumb + add_breadcrumb t('edit') + end + + def create + if @involvement.save + redirect_to admin_education_school_role_path(@role, { school_id: @school.id }), notice: t('admin.successfully_created_html', model: @involvement.to_s) + else + breadcrumb + render :new, status: :unprocessable_entity + end + end + + def update + if @involvement.update(involvement_params) + redirect_to admin_education_school_role_path(@role, { school_id: @school.id }), notice: t('admin.successfully_updated_html', model: @involvement.to_s) + else + breadcrumb + render :edit, status: :unprocessable_entity + add_breadcrumb t('edit') + end + end + + def destroy + @involvement.destroy + redirect_to admin_education_school_role_path(@role, { school_id: @school.id }), notice: t('admin.successfully_destroyed_html', model: @involvement.to_s) + end + + protected + + def breadcrumb + super + add_breadcrumb University::Role.model_name.human(count: 2), admin_education_school_roles_path(@school) + @role.persisted? ? add_breadcrumb(@role, admin_education_school_role_path(@role, { school_id: @school.id })) + : add_breadcrumb(t('create')) + if @involvement + @involvement.persisted? ? add_breadcrumb(@involvement, admin_education_school_role_person_path(@involvement, { school_id: @school.id, role_id: @role.id })) + : add_breadcrumb(t('create')) + end + end + + def involvement_params + params.require(:university_person_involvement) + .permit(:description, :position, :person_id) + .merge(university_id: @school.university_id) + end +end diff --git a/app/controllers/admin/education/school/roles_controller.rb b/app/controllers/admin/education/school/roles_controller.rb new file mode 100644 index 000000000..f795f26cc --- /dev/null +++ b/app/controllers/admin/education/school/roles_controller.rb @@ -0,0 +1,62 @@ +class Admin::Education::School::RolesController < Admin::Education::School::ApplicationController + load_and_authorize_resource class: University::Role, through: :school, through_association: :university_roles + + def index + breadcrumb + end + + def show + @involvements = @role.involvements.ordered + breadcrumb + end + + def new + breadcrumb + end + + def edit + breadcrumb + add_breadcrumb t('edit') + end + + def create + if @role.save + redirect_to admin_education_school_role_path(@role), notice: t('admin.successfully_created_html', model: @role.to_s) + else + breadcrumb + render :new, status: :unprocessable_entity + end + end + + def update + if @role.update(role_params) + redirect_to admin_education_school_role_path(@role), notice: t('admin.successfully_updated_html', model: @role.to_s) + else + breadcrumb + render :edit, status: :unprocessable_entity + add_breadcrumb t('edit') + end + end + + def destroy + @role.destroy + redirect_to admin_education_school_role_path(@role), notice: t('admin.successfully_destroyed_html', model: @role.to_s) + end + + protected + + def breadcrumb + super + add_breadcrumb University::Role.model_name.human(count: 2), admin_education_school_roles_path(@school) + if @role + @role.persisted? ? add_breadcrumb(@role, admin_education_school_role_path(@role, { school_id: @school.id })) + : add_breadcrumb(t('create')) + end + end + + def role_params + params.require(:university_role) + .permit(:description, :position) + .merge(target: @school, university_id: @school.university_id) + end +end diff --git a/app/controllers/admin/education/schools_controller.rb b/app/controllers/admin/education/schools_controller.rb index e1368257c..7152bbd27 100644 --- a/app/controllers/admin/education/schools_controller.rb +++ b/app/controllers/admin/education/schools_controller.rb @@ -8,6 +8,7 @@ class Admin::Education::SchoolsController < Admin::Education::ApplicationControl end def show + @roles = @school.university_roles.ordered breadcrumb end diff --git a/app/models/ability.rb b/app/models/ability.rb index 905dd2f6a..a193260c5 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -36,6 +36,8 @@ class Ability can :manage, Education::Program::Teacher, person_id: @user.person&.id can :read, Education::Program::Role, university_id: @user.university_id can :manage, Education::Program::Role::Person, person_id: @user.person&.id + can :read, University::Role, university_id: @user.university_id + can :manage, University::Person::Involvement, person_id: @user.person&.id end def program_manager @@ -66,6 +68,8 @@ class Ability can :manage, Research::Journal::Article, university_id: @user.university_id can :manage, Research::Journal::Volume, university_id: @user.university_id can :manage, Research::Laboratory, university_id: @user.university_id + can :manage, University::Role, university_id: @user.university_id + can :manage, University::Person::Involvement, university_id: @user.university_id can :read, User, university_id: @user.university_id can :manage, User, university_id: @user.university_id, role: @user.managed_roles end diff --git a/app/models/education/school.rb b/app/models/education/school.rb index 6f79e2f3b..c62ab123b 100644 --- a/app/models/education/school.rb +++ b/app/models/education/school.rb @@ -32,6 +32,10 @@ class Education::School < ApplicationRecord has_many :university_people_through_administrators, through: :administrators, source: :person + has_many :university_roles, class_name: 'University::Role', as: :target, dependent: :destroy + has_many :university_people_through_roles, + through: :university_roles, + source: :person has_and_belongs_to_many :programs, class_name: 'Education::Program', join_table: 'education_programs_schools', diff --git a/app/models/university/person/involvement.rb b/app/models/university/person/involvement.rb index 83c1b444a..d555cccbc 100644 --- a/app/models/university/person/involvement.rb +++ b/app/models/university/person/involvement.rb @@ -27,15 +27,25 @@ class University::Person::Involvement < ApplicationRecord include WithPosition + enum kind: { administrator: 10, researcher: 20, teacher: 30 } + belongs_to :university belongs_to :person belongs_to :target, polymorphic: true - enum kind: { administrator: 10, researcher: 20, teacher: 30 } + after_commit :sync_target + + def to_s + "#{person}" + end protected def last_ordered_element self.class.unscoped.where(university_id: university_id, target: target).ordered.last end + + def sync_target + target.sync_with_git + end end diff --git a/app/models/university/role.rb b/app/models/university/role.rb index d63eb7041..2e4987077 100644 --- a/app/models/university/role.rb +++ b/app/models/university/role.rb @@ -25,6 +25,15 @@ class University::Role < ApplicationRecord belongs_to :university belongs_to :target, polymorphic: true, optional: true + has_many :involvements, class_name: 'University::Person::Involvement', as: :target + + def to_s + "#{description}" + end + + def sync_with_git + target.sync_with_git + end protected diff --git a/app/views/admin/education/school/role/people/_form.html.erb b/app/views/admin/education/school/role/people/_form.html.erb new file mode 100644 index 000000000..81fb739c7 --- /dev/null +++ b/app/views/admin/education/school/role/people/_form.html.erb @@ -0,0 +1,23 @@ +<%= simple_form_for [:admin, involvement], + url: involvement.new_record? ? admin_education_school_role_people_path(@role, { school_id: @school.id }) + : admin_education_school_role_person_path(involvement, { school_id: @school.id, role_id: @role.id }) do |f| %> + <div class="card flex-fill w-100"> + <div class="card-header"> + <h5 class="card-title mb-0"><%= t('admin.infos') %></h5> + </div> + <div class="card-body"> + <div class="row"> + <div class="col-md-6"> + <% used_person_ids = @role.involvements.where.not(id: involvement.id).pluck(:person_id) %> + <%= f.association :person, collection: current_university.people.administration.where.not(id: used_person_ids).ordered %> + </div> + <div class="col-md-6"> + <%= f.input :description %> + </div> + </div> + </div> + </div> + <% content_for :action_bar_right do %> + <%= submit f %> + <% end %> +<% end %> diff --git a/app/views/admin/education/school/role/people/_list.html.erb b/app/views/admin/education/school/role/people/_list.html.erb new file mode 100644 index 000000000..5f10eb42c --- /dev/null +++ b/app/views/admin/education/school/role/people/_list.html.erb @@ -0,0 +1,33 @@ +<% if involvements.any? %> + <table class="table table-sortable"> + <thead> + <tr> + <th class="ps-0"><%= University::Person.model_name.human %></th> + <th><%= University::Person::Involvement.human_attribute_name("description") %></th> + <th></th> + </tr> + </thead> + <tbody data-reorder-url="<%= reorder_admin_education_school_role_people_path(@role, { school_id: @school.id }) %>"> + <% involvements.each do |involvement| %> + <tr class="handle" data-id="<%= involvement.id %>"> + <td class="ps-0"> + <%= involvement %> + </td> + <td><%= involvement.description %></td> + <td class="text-end pe-0"> + <div class="btn-group" role="group"> + <%= link_to t('edit'), + edit_admin_education_school_role_person_path(involvement, { school_id: @school.id, role_id: @role.id }), + class: button_classes if can?(:edit, involvement) %> + <%= link_to t('delete'), + admin_education_school_role_person_path(involvement, { school_id: @school.id, role_id: @role.id }), + method: :delete, + data: { confirm: t('please_confirm') }, + class: button_classes_danger if can?(:destroy, involvement) %> + </div> + </td> + </tr> + <% end %> + </tbody> + </table> +<% end %> diff --git a/app/views/admin/education/school/role/people/edit.html.erb b/app/views/admin/education/school/role/people/edit.html.erb new file mode 100644 index 000000000..da924cd05 --- /dev/null +++ b/app/views/admin/education/school/role/people/edit.html.erb @@ -0,0 +1,3 @@ +<% content_for :title, @involvement %> + +<%= render 'form', involvement: @involvement %> diff --git a/app/views/admin/education/school/role/people/new.html.erb b/app/views/admin/education/school/role/people/new.html.erb new file mode 100644 index 000000000..f07ff39c1 --- /dev/null +++ b/app/views/admin/education/school/role/people/new.html.erb @@ -0,0 +1,3 @@ +<% content_for :title, University::Person.model_name.human %> + +<%= render 'form', involvement: @involvement %> diff --git a/app/views/admin/education/school/roles/_form.html.erb b/app/views/admin/education/school/roles/_form.html.erb new file mode 100644 index 000000000..f09aa1ee3 --- /dev/null +++ b/app/views/admin/education/school/roles/_form.html.erb @@ -0,0 +1,17 @@ +<%= simple_form_for [:admin, role], + url: role.new_record? ? admin_education_school_roles_path(@school) + : admin_education_school_role_path(role, { school_id: @school.id }) do |f| %> + <div class="card flex-fill w-100"> + <div class="card-header"> + <h5 class="card-title mb-0"><%= t('admin.infos') %></h5> + </div> + <div class="card-body"> + <div class="row"> + <%= f.input :description %> + </div> + </div> + </div> + <% content_for :action_bar_right do %> + <%= submit f %> + <% end %> +<% end %> diff --git a/app/views/admin/education/school/roles/_list.html.erb b/app/views/admin/education/school/roles/_list.html.erb new file mode 100644 index 000000000..084f107a7 --- /dev/null +++ b/app/views/admin/education/school/roles/_list.html.erb @@ -0,0 +1,35 @@ +<% if roles.any? %> + <table class="table table-sortable"> + <thead> + <tr> + <th class="ps-0"><%= University::Role.model_name.human %></th> + <th><%= University::Role.human_attribute_name('people') %></th> + <th></th> + </tr> + </thead> + <tbody data-reorder-url="<%= reorder_admin_education_school_roles_path(school_id: @school.id) %>"> + <% roles.each do |role| %> + <tr class="handle" data-id="<%= role.id %>"> + <td class="ps-0"> + <%= link_to_if can?(:read, role), + role, + admin_education_school_role_path(role, { school_id: @school.id }) %> + </td> + <td><%= role.involvements.includes(:person).ordered.map { |involvement| involvement.person.to_s }.to_sentence %></td> + <td class="text-end pe-0"> + <div class="btn-group" role="group"> + <%= link_to t('edit'), + edit_admin_education_school_role_path(role, { school_id: @school.id }), + class: button_classes if can?(:edit, role) %> + <%= link_to t('delete'), + admin_education_school_role_path(role, { school_id: @school.id }), + method: :delete, + data: { confirm: t('please_confirm') }, + class: button_classes_danger if can?(:destroy, role) %> + </div> + </td> + </tr> + <% end %> + </tbody> + </table> +<% end %> diff --git a/app/views/admin/education/school/roles/edit.html.erb b/app/views/admin/education/school/roles/edit.html.erb new file mode 100644 index 000000000..ff1ec73bd --- /dev/null +++ b/app/views/admin/education/school/roles/edit.html.erb @@ -0,0 +1,3 @@ +<% content_for :title, @role %> + +<%= render 'form', role: @role %> diff --git a/app/views/admin/education/school/roles/index.html.erb b/app/views/admin/education/school/roles/index.html.erb new file mode 100644 index 000000000..d8dda13f8 --- /dev/null +++ b/app/views/admin/education/school/roles/index.html.erb @@ -0,0 +1,3 @@ +<% content_for :title, University::Role.model_name.human(count: 2) %> +<%= link_to t('create'), new_admin_education_school_role_path(school_id: @school.id), class: button_classes %> +<%= render 'admin/education/school/roles/list', roles: @roles %> diff --git a/app/views/admin/education/school/roles/new.html.erb b/app/views/admin/education/school/roles/new.html.erb new file mode 100644 index 000000000..1e11d9157 --- /dev/null +++ b/app/views/admin/education/school/roles/new.html.erb @@ -0,0 +1,3 @@ +<% content_for :title, University::Role.model_name.human %> + +<%= render 'form', role: @role %> diff --git a/app/views/admin/education/school/roles/show.html.erb b/app/views/admin/education/school/roles/show.html.erb new file mode 100644 index 000000000..f4c18babf --- /dev/null +++ b/app/views/admin/education/school/roles/show.html.erb @@ -0,0 +1,4 @@ +<% content_for :title, @role %> + +<%= link_to t('create'), new_admin_education_school_role_person_path(school_id: @school.id, role_id: @role.id), class: button_classes %> +<%= render 'admin/education/school/role/people/list', involvements: @involvements %> diff --git a/app/views/admin/education/schools/show.html.erb b/app/views/admin/education/schools/show.html.erb index 5367e4558..bb527954d 100644 --- a/app/views/admin/education/schools/show.html.erb +++ b/app/views/admin/education/schools/show.html.erb @@ -58,11 +58,36 @@ <div class="card flex-fill w-100"> <div class="card-header"> - <h2 class="card-title mb-0 h5"><%= Education::School.human_attribute_name('administrators') %></h2> + <div class="float-end"> + <%= link_to "Gérer les rôles", + admin_education_school_roles_path(school_id: @school.id), + class: button_classes if can?(:update, University::Role) %> + </div> + <h2 class="card-title mb-0 h5">Rôles</h2> </div> <div class="card-body"> - <%= render 'admin/education/school/administrators/list', administrators: @school.administrators.includes(:person).ordered %> - <%= link_to t('create'), new_admin_education_school_administrator_path(school_id: @school.id), class: button_classes %> + <% if @roles.any? %> + <table class="table"> + <thead> + <tr> + <th class="ps-0"><%= University::Role.model_name.human %></th> + <th><%= University::Role.human_attribute_name('people') %></th> + </tr> + </thead> + <tbody> + <% @roles.each do |role| %> + <tr> + <td class="ps-0"> + <%= link_to_if can?(:read, role), + role, + admin_education_school_role_path(role, { school_id: @school.id }) %> + </td> + <td><%= role.involvements.includes(:person).ordered.map { |involvement| involvement.person.to_s }.to_sentence %></td> + </tr> + <% end %> + </tbody> + </table> + <% end %> </div> </div> diff --git a/config/locales/university/en.yml b/config/locales/university/en.yml index 8d690dbb6..6d8df213d 100644 --- a/config/locales/university/en.yml +++ b/config/locales/university/en.yml @@ -42,6 +42,12 @@ en: university/person: one: Person other: People + university/person/involvement: + one: Involvement + other: Involvements + university/role: + one: Role + other: Roles simple_form: hints: university: diff --git a/config/locales/university/fr.yml b/config/locales/university/fr.yml index d40b74e83..a47bf3c9b 100644 --- a/config/locales/university/fr.yml +++ b/config/locales/university/fr.yml @@ -42,6 +42,12 @@ fr: university/person: one: Personne other: Personnes + university/person/involvement: + one: Involvement + other: Involvements + university/role: + one: Rôle + other: Rôles simple_form: hints: university: diff --git a/config/routes/admin/education.rb b/config/routes/admin/education.rb index c3ac5899e..125c44a9e 100644 --- a/config/routes/admin/education.rb +++ b/config/routes/admin/education.rb @@ -1,6 +1,16 @@ namespace :education do resources :teachers, only: [:index, :show] resources :schools do + resources :roles, controller: 'school/roles' do + resources :people, controller: 'school/role/people', except: [:index, :show] do + collection do + post :reorder + end + end + collection do + post :reorder + end + end resources :administrators, controller: 'school/administrators', except: [:index, :show] end resources :programs do diff --git a/lib/tasks/app.rake b/lib/tasks/app.rake index 0e862f5d6..4899fc661 100644 --- a/lib/tasks/app.rake +++ b/lib/tasks/app.rake @@ -53,7 +53,7 @@ namespace :app do Education::Program::Role.find_each { |program_role| university_role = University::Role.where( - description: program_role.description, + description: program_role.title, target: program_role.program, position: program_role.position, university_id: program_role.university_id -- GitLab