diff --git a/app/controllers/admin/education/program/role/people_controller.rb b/app/controllers/admin/education/program/role/people_controller.rb new file mode 100644 index 0000000000000000000000000000000000000000..6202bf3e80f4bf070433fb13bcb5163d4688596b --- /dev/null +++ b/app/controllers/admin/education/program/role/people_controller.rb @@ -0,0 +1,40 @@ +class Admin::Education::Program::Role::PeopleController < Admin::Education::Program::ApplicationController + load_and_authorize_resource :role, class: Education::Program::Role, through: :program + load_and_authorize_resource class: Education::Program::Role::Person, through: :role + + include Admin::Reorderable + + def new + breadcrumb + end + + def create + if @person.save + redirect_to admin_education_program_role_path(@role), notice: t('admin.successfully_created_html', model: @person.to_s) + else + breadcrumb + render :new, status: :unprocessable_entity + end + end + + def destroy + @person.destroy + redirect_to admin_education_program_role_path(@role), notice: t('admin.successfully_destroyed_html', model: @person.to_s) + end + + protected + + def breadcrumb + super + add_breadcrumb Education::Program::Role.model_name.human(count: 2) + breadcrumb_for @role + add_breadcrumb Education::Program::Role::Person.model_name.human(count: 2) + breadcrumb_for @person + end + + def person_params + params.require(:education_program_role_person) + .permit(:person_id) + .merge(role_id: @role.id) + end +end diff --git a/app/controllers/admin/education/program/roles_controller.rb b/app/controllers/admin/education/program/roles_controller.rb index b3488e4ad86c359ce2404b33cffcc1b10c3a5450..94d3598b32e5e3ee016155862000a0b19c5e4897 100644 --- a/app/controllers/admin/education/program/roles_controller.rb +++ b/app/controllers/admin/education/program/roles_controller.rb @@ -1,6 +1,8 @@ class Admin::Education::Program::RolesController < Admin::Education::Program::ApplicationController load_and_authorize_resource class: Education::Program::Role, through: :program + include Admin::Reorderable + def show breadcrumb end diff --git a/app/models/communication/website/post.rb b/app/models/communication/website/post.rb index 36099f9fed95cad1cfb9c360a425e38a7bebd062..fe3fb85225e9da1d2bdbc5f3fd3ab86eda26e39b 100644 --- a/app/models/communication/website/post.rb +++ b/app/models/communication/website/post.rb @@ -59,6 +59,7 @@ class Communication::Website::Post < ApplicationRecord before_validation :set_published_at, if: :published_changed? + scope :published, -> { where(published: true) } scope :ordered, -> { order(published_at: :desc, created_at: :desc) } scope :recent, -> { order(published_at: :desc).limit(5) } diff --git a/app/models/education/program/role.rb b/app/models/education/program/role.rb index 5a0365f34fd024730760fe4298958fd0c9d4c693..d79798d0670750128e13cd299656cdf71e3c0619 100644 --- a/app/models/education/program/role.rb +++ b/app/models/education/program/role.rb @@ -25,6 +25,8 @@ class Education::Program::Role < ApplicationRecord belongs_to :university belongs_to :program, class_name: 'Education::Program' + has_many :people, class_name: 'Education::Program::Role::Person', dependent: :destroy + has_many :university_people, through: :people, source: :person def to_s "#{title}" diff --git a/app/models/education/program/role/person.rb b/app/models/education/program/role/person.rb new file mode 100644 index 0000000000000000000000000000000000000000..f61f1d20ff98b9b25167825d552f6a91768f83a0 --- /dev/null +++ b/app/models/education/program/role/person.rb @@ -0,0 +1,37 @@ +# == Schema Information +# +# Table name: education_program_role_people +# +# id :uuid not null, primary key +# position :integer +# created_at :datetime not null +# updated_at :datetime not null +# person_id :uuid not null +# role_id :uuid not null +# +# Indexes +# +# index_education_program_role_people_on_person_id (person_id) +# index_education_program_role_people_on_role_id (role_id) +# +# Foreign Keys +# +# fk_rails_... (person_id => university_people.id) +# fk_rails_... (role_id => education_program_roles.id) +# +class Education::Program::Role::Person < ApplicationRecord + include WithPosition + + belongs_to :person, class_name: 'University::Person' + belongs_to :role, class_name: 'Education::Program::Role' + + def to_s + person.to_s + end + + protected + + def last_ordered_element + role.people.ordered.last + end +end diff --git a/app/models/university/person.rb b/app/models/university/person.rb index 68299e2fa74a136970c24d63b7be6eef2e7ef09c..0a8223ff4d9a1449b8d16df3446a2f7e44009083 100644 --- a/app/models/university/person.rb +++ b/app/models/university/person.rb @@ -100,16 +100,31 @@ class University::Person < ApplicationRecord end def identifiers(website: nil) - website_id = website&.id list = [] - # TODO :administrator - [:author, :researcher, :teacher].each do |role| - list << role if send("#{role.to_s}_websites").pluck(:id).include?(website_id) + [:author, :researcher, :teacher, :administrator].each do |role| + list << role if public_send("is_#{role.to_s}_for_website", website) end list << :static unless list.empty? list end + def is_author_for_website(website) + is_author && communication_website_posts.published.where(communication_website_id: website&.id).any? + end + + def is_researcher_for_website(website) + is_researcher + end + + def is_teacher_for_website(website) + is_teacher && website.programs.published.joins(:teachers).where(education_program_teachers: { person_id: id }).any? + end + + def is_administrator_for_website(website) + # TODO + is_administrative + end + def git_path_static "content/persons/#{slug}.html" end diff --git a/app/views/admin/education/program/role/people/_list.html.erb b/app/views/admin/education/program/role/people/_list.html.erb new file mode 100644 index 0000000000000000000000000000000000000000..fc31ddd11a709929630337c2f87dde710821fc42 --- /dev/null +++ b/app/views/admin/education/program/role/people/_list.html.erb @@ -0,0 +1,30 @@ +<% if people.any? %> + <table class="table table-sortable"> + <thead> + <tr> + <th><%= Education::Program::Role::Person.model_name.human %></th> + <th></th> + </tr> + </thead> + <tbody data-reorder-url="<%= reorder_admin_education_program_role_people_path(program_id: @program.id, role_id: @role.id) %>"> + <% people.each do |person| %> + <tr class="handle" data-id="<%= person.id %>"> + <td> + <%= link_to_if can?(:read, person.person), + person.person, + admin_university_person_path(person.person) %> + </td> + <td class="text-end pe-0"> + <div class="btn-group" role="group"> + <%= link_to t('delete'), + admin_education_program_role_person_path(person, { role_id: @role.id }), + method: :delete, + data: { confirm: t('please_confirm') }, + class: button_classes_danger %> + </div> + </td> + </tr> + <% end %> + </tbody> + </table> +<% end %> diff --git a/app/views/admin/education/program/role/people/new.html.erb b/app/views/admin/education/program/role/people/new.html.erb new file mode 100644 index 0000000000000000000000000000000000000000..402d1727d98c843d5b6807ec06bdd7d73a1f607b --- /dev/null +++ b/app/views/admin/education/program/role/people/new.html.erb @@ -0,0 +1,20 @@ +<% content_for :title, Education::Program::Role::Person.model_name.human %> + +<%= simple_form_for [:admin, @person] do |f| %> + <div class="row"> + <div class="col-md-8"> + <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"> + <% used_person_ids = @role.people.where.not(id: @person.id).pluck(:person_id) %> + <%= f.association :person, collection: current_university.people.where.not(id: used_person_ids).ordered %> + </div> + </div> + </div> + </div> + <% content_for :action_bar_right do %> + <%= submit f %> + <% end %> +<% end %> diff --git a/app/views/admin/education/program/roles/_list.html.erb b/app/views/admin/education/program/roles/_list.html.erb index b3a3b5fee618931e112cf5e7958f796ff8e657cb..9fbda8e94303c28ea6539804cf6efe4186e3961f 100644 --- a/app/views/admin/education/program/roles/_list.html.erb +++ b/app/views/admin/education/program/roles/_list.html.erb @@ -1,18 +1,20 @@ -<table class="table"> +<table class="table table-sortable"> <thead> <tr> <th><%= Education::Program::Role.model_name.human %></th> + <th><%= Education::Program::Role.human_attribute_name('people') %></th> <th></th> </tr> </thead> - <tbody> + <tbody data-reorder-url="<%= reorder_admin_education_program_roles_path(program_id: @program.id) %>"> <% roles.each do |role| %> - <tr> + <tr class="handle" data-id="<%= role.id %>"> <td> <%= link_to_if can?(:read, role), role, admin_education_program_role_path(role, { program_id: @program.id }) %> </td> + <td><%= role.people.includes(:person).ordered.map { |person| person.person.to_s }.to_sentence %></td> <td class="text-end pe-0"> <div class="btn-group" role="group"> <%= link_to t('edit'), diff --git a/app/views/admin/education/program/roles/show.html.erb b/app/views/admin/education/program/roles/show.html.erb index e6d4117f32fda150675fcedacdeab4a3c54ae5d0..051d0859a6b646ee517b4ced7cfab8b9568fae08 100644 --- a/app/views/admin/education/program/roles/show.html.erb +++ b/app/views/admin/education/program/roles/show.html.erb @@ -12,6 +12,17 @@ </div> </div> </div> + <div class="col-md-8"> + <div class="card flex-fill w-100"> + <div class="card-header"> + <h2 class="card-title mb-0 h5"><%= Education::Program::Role.human_attribute_name('people') %></h2> + </div> + <div class="card-body"> + <p><%= link_to t('create'), new_admin_education_program_role_person_path(role_id: @role.id), class: 'btn btn-primary' %></p> + <%= render 'admin/education/program/role/people/list', people: @role.people.includes(:person).ordered %> + </div> + </div> + </div> </div> <% content_for :action_bar_right do %> diff --git a/app/views/admin/education/program/teachers/_form.html.erb b/app/views/admin/education/program/teachers/_form.html.erb index e8c8b9067196b35f5d0599974470e4820b0a1d1d..503032b23e866226f69cd4455e81ada146777148 100644 --- a/app/views/admin/education/program/teachers/_form.html.erb +++ b/app/views/admin/education/program/teachers/_form.html.erb @@ -6,8 +6,8 @@ <div class="card-body"> <div class="row"> <div class="col-md-6"> - <% teacher_ids = @program.teachers.where.not(id: teacher.id).pluck(:person_id) %> - <%= f.association :person, collection: current_university.people.teachers.where.not(id: teacher_ids).ordered %> + <% used_teacher_ids = @program.teachers.where.not(id: teacher.id).pluck(:person_id) %> + <%= f.association :person, collection: current_university.people.teachers.where.not(id: used_teacher_ids).ordered %> </div> <div class="col-md-6"> <%= f.input :description, as: :string %> diff --git a/app/views/admin/university/people/static.html.erb b/app/views/admin/university/people/static.html.erb index 0bbfffa7de21387fcaecd227f1ab6c70eff0c26e..c6e4a98351f7edf255c7b498f423a1fcc26358fa 100644 --- a/app/views/admin/university/people/static.html.erb +++ b/app/views/admin/university/people/static.html.erb @@ -7,16 +7,16 @@ last_name: "<%= @person.last_name %>" phone: "<%= @person.phone %>" email: "<%= @person.email %>" roles: -<% if @person.is_author %> +<% if @person.is_author_for_website(@website) %> - author <% end %> -<% if @person.is_teacher %> +<% if @person.is_teacher_for_website(@website) %> - teacher <% end %> -<% if @person.is_researcher %> +<% if @person.is_researcher_for_website(@website) %> - researcher <% end %> -<% if @person.is_administrative %> +<% if @person.is_administrator_for_website(@website) %> - administrator <% end %> --- diff --git a/config/locales/education/en.yml b/config/locales/education/en.yml index a5e6d3c66d384495ce2d0d80a1bd3e996a457c0a..1cb84dcbc556de93a10b05279a7898ffd1a9c800 100644 --- a/config/locales/education/en.yml +++ b/config/locales/education/en.yml @@ -10,6 +10,9 @@ en: education/program/role: one: Role other: Roles + education/program/role/person: + one: Person + other: People education/program/teacher: one: Teacher other: Teachers @@ -45,6 +48,8 @@ en: education/program/role: people: People title: Title + education/program/role/person: + person: Person education/program/teacher: description: Description person: Person diff --git a/config/locales/education/fr.yml b/config/locales/education/fr.yml index c087f4a27aea731ad9d5d2bc7fc87a8d1bd20b7b..755c0845c9fe9548966d38adfe7106f00dfd79d7 100644 --- a/config/locales/education/fr.yml +++ b/config/locales/education/fr.yml @@ -10,6 +10,9 @@ fr: education/program/role: one: Rôle other: Rôles + education/program/role/person: + one: Personne + other: Personnes education/program/teacher: one: Enseignant·e other: Enseignants·es @@ -47,6 +50,8 @@ fr: education/program/role: people: Personnes title: Titre + education/program/role/person: + person: Personne education/program/teacher: description: Description person: Personne diff --git a/config/routes/admin/education.rb b/config/routes/admin/education.rb index 75ca3697efed49b6227f94127c53190c52936003..79e0e2555fda0126e8550d8739cf36ea24c06e6e 100644 --- a/config/routes/admin/education.rb +++ b/config/routes/admin/education.rb @@ -2,7 +2,17 @@ namespace :education do resources :teachers, only: [:index, :show] resources :schools resources :programs do - resources :roles, controller: 'program/roles', except: :index + resources :roles, controller: 'program/roles', except: :index do + resources :people, controller: 'program/role/people', except: [:index, :show, :edit, :update] do + collection do + post :reorder + end + end + + collection do + post :reorder + end + end resources :teachers, controller: 'program/teachers', except: [:index, :show] collection do post :reorder diff --git a/db/migrate/20220106134525_create_education_program_role_people.rb b/db/migrate/20220106134525_create_education_program_role_people.rb new file mode 100644 index 0000000000000000000000000000000000000000..a967cad41471e5339d6cec0380ee8e77b09a33a9 --- /dev/null +++ b/db/migrate/20220106134525_create_education_program_role_people.rb @@ -0,0 +1,11 @@ +class CreateEducationProgramRolePeople < ActiveRecord::Migration[6.1] + def change + create_table :education_program_role_people, id: :uuid do |t| + t.integer :position + t.references :person, null: false, foreign_key: { to_table: :university_people }, type: :uuid + t.references :role, null: false, foreign_key: { to_table: :education_program_roles }, type: :uuid + + t.timestamps + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 4e15658bfe91a906df335ee677292f24ea11eb68..b8e59bfdb2fe32620e035ad58b35db13a791e2b1 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2022_01_06_104521) do +ActiveRecord::Schema.define(version: 2022_01_06_134525) do # These are extensions that must be enabled in order to support this database enable_extension "pgcrypto" @@ -347,6 +347,16 @@ ActiveRecord::Schema.define(version: 2022_01_06_104521) do t.index ["priority", "run_at"], name: "delayed_jobs_priority" end + create_table "education_program_role_people", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + t.integer "position" + t.uuid "person_id", null: false + t.uuid "role_id", null: false + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + t.index ["person_id"], name: "index_education_program_role_people_on_person_id" + t.index ["role_id"], name: "index_education_program_role_people_on_role_id" + end + create_table "education_program_roles", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| t.string "title" t.integer "position" @@ -590,6 +600,8 @@ ActiveRecord::Schema.define(version: 2022_01_06_104521) do add_foreign_key "communication_website_posts", "universities" add_foreign_key "communication_website_posts", "university_people", column: "author_id" add_foreign_key "communication_websites", "universities" + add_foreign_key "education_program_role_people", "education_program_roles", column: "role_id" + add_foreign_key "education_program_role_people", "university_people", column: "person_id" add_foreign_key "education_program_roles", "education_programs", column: "program_id" add_foreign_key "education_program_roles", "universities" add_foreign_key "education_program_teachers", "education_programs", column: "program_id" diff --git a/test/fixtures/education/program/role/people.yml b/test/fixtures/education/program/role/people.yml new file mode 100644 index 0000000000000000000000000000000000000000..50a25e47a89ea4b3a4cda4a15f37db6331820438 --- /dev/null +++ b/test/fixtures/education/program/role/people.yml @@ -0,0 +1,31 @@ +# == Schema Information +# +# Table name: education_program_role_people +# +# id :uuid not null, primary key +# position :integer +# created_at :datetime not null +# updated_at :datetime not null +# person_id :uuid not null +# role_id :uuid not null +# +# Indexes +# +# index_education_program_role_people_on_person_id (person_id) +# index_education_program_role_people_on_role_id (role_id) +# +# Foreign Keys +# +# fk_rails_... (person_id => university_people.id) +# fk_rails_... (role_id => education_program_roles.id) +# + +one: + position: 1 + person: one + role: one + +two: + position: 1 + person: two + role: two diff --git a/test/models/education/program/role/person_test.rb b/test/models/education/program/role/person_test.rb new file mode 100644 index 0000000000000000000000000000000000000000..a257dd899084f03b9b60d8a932b174c47621aed8 --- /dev/null +++ b/test/models/education/program/role/person_test.rb @@ -0,0 +1,28 @@ +# == Schema Information +# +# Table name: education_program_role_people +# +# id :uuid not null, primary key +# position :integer +# created_at :datetime not null +# updated_at :datetime not null +# person_id :uuid not null +# role_id :uuid not null +# +# Indexes +# +# index_education_program_role_people_on_person_id (person_id) +# index_education_program_role_people_on_role_id (role_id) +# +# Foreign Keys +# +# fk_rails_... (person_id => university_people.id) +# fk_rails_... (role_id => education_program_roles.id) +# +require "test_helper" + +class Education::Program::Role::PersonTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end