diff --git a/app/controllers/admin/education/school/administrators_controller.rb b/app/controllers/admin/education/school/administrators_controller.rb new file mode 100644 index 0000000000000000000000000000000000000000..d7788a8b49a0ce838ac66a389ae470bacf113151 --- /dev/null +++ b/app/controllers/admin/education/school/administrators_controller.rb @@ -0,0 +1,50 @@ +class Admin::Education::School::AdministratorsController < Admin::Education::School::ApplicationController + load_and_authorize_resource class: Education::School::Administrator, through: :school + + def new + breadcrumb + end + + def edit + breadcrumb + add_breadcrumb t('edit') + end + + def create + if @administrator.save + redirect_to admin_education_school_path(@school), notice: t('admin.successfully_created_html', model: @administrator.to_s) + else + breadcrumb + render :new, status: :unprocessable_entity + end + end + + def update + if @administrator.update(administrator_params) + redirect_to admin_education_school_path(@school), notice: t('admin.successfully_updated_html', model: @administrator.to_s) + else + breadcrumb + render :edit, status: :unprocessable_entity + add_breadcrumb t('edit') + end + end + + def destroy + @administrator.destroy + redirect_to admin_education_school_path(@school), notice: t('admin.successfully_destroyed_html', model: @administrator.to_s) + end + + protected + + def breadcrumb + super + add_breadcrumb Education::School::Administrator.model_name.human(count: 2) + breadcrumb_for @administrator + end + + def administrator_params + params.require(:education_school_administrator) + .permit(:description, :person_id) + .merge(school_id: @school.id) + end +end diff --git a/app/controllers/admin/education/school/application_controller.rb b/app/controllers/admin/education/school/application_controller.rb new file mode 100644 index 0000000000000000000000000000000000000000..56a79f71492195875c2a9aaa3cd17481e8cf5ed8 --- /dev/null +++ b/app/controllers/admin/education/school/application_controller.rb @@ -0,0 +1,20 @@ +class Admin::Education::School::ApplicationController < Admin::Education::ApplicationController + load_and_authorize_resource :school, + class: Education::School, + through: :current_university, + through_association: :education_schools + + protected + + def breadcrumb + super + add_breadcrumb @school, [:admin, @school] + end + + def default_url_options + return {} unless params.has_key? :school_id + { + school_id: params[:school_id] + } + end +end diff --git a/app/models/communication/website.rb b/app/models/communication/website.rb index 6749b6482fb3ae250b40d349c1da56673646dd0e..b7a4d67ae028d7c1bcad3f057dd672394a7c93b4 100644 --- a/app/models/communication/website.rb +++ b/app/models/communication/website.rb @@ -59,6 +59,6 @@ class Communication::Website < ApplicationRecord dependencies.concat [about.articles, about.volumes] end - dependencies.flatten.uniq.compact + dependencies end end diff --git a/app/models/concerns/with_git.rb b/app/models/concerns/with_git.rb index 981a0b1022ac4e0762adb29d6bb1016316f45e32..2bbe7cc57f37599c2ce0a3818a1c2058fb7b1183 100644 --- a/app/models/concerns/with_git.rb +++ b/app/models/concerns/with_git.rb @@ -39,7 +39,7 @@ module WithGit websites_for_self.each do |website| identifiers(website: website).each do |identifier| Communication::Website::GitFile.sync website, self, identifier - dependencies = send "git_dependencies_#{identifier}" + dependencies = send("git_dependencies_#{identifier}").flatten.uniq.compact dependencies.each do |object| Communication::Website::GitFile.sync website, object, identifier end @@ -53,7 +53,7 @@ module WithGit websites_for_self.each do |website| identifiers(website: website).each do |identifier| Communication::Website::GitFile.sync website, self, identifier, destroy: true - dependencies = send "git_destroy_dependencies_#{identifier}" + dependencies = send("git_destroy_dependencies_#{identifier}").flatten.uniq.compact dependencies.each do |object| Communication::Website::GitFile.sync website, object, identifier, destroy: true end diff --git a/app/models/education/program.rb b/app/models/education/program.rb index ba085aa570d28f80cdc2f7b7454e0f7a6085fd01..ebf7b7d8bd138de1814d4e528018ff9a664c4a06 100644 --- a/app/models/education/program.rb +++ b/app/models/education/program.rb @@ -121,11 +121,11 @@ class Education::Program < ApplicationRecord end def git_dependencies_static - [ - active_storage_blobs, - university_people_through_teachers, + ( + active_storage_blobs + + university_people_through_teachers + university_people_through_roles - ].flatten.uniq.compact + ) end def git_destroy_dependencies_static diff --git a/app/models/education/school.rb b/app/models/education/school.rb index c6be336047fb8fe10188c9cb9dfbede775789d10..ad5acb370e3e51f897ecfe4e301dd18eae3d0003 100644 --- a/app/models/education/school.rb +++ b/app/models/education/school.rb @@ -28,6 +28,7 @@ class Education::School < ApplicationRecord belongs_to :university has_many :websites, class_name: 'Communication::Website', as: :about, dependent: :nullify + has_many :administrators, dependent: :destroy has_and_belongs_to_many :programs, class_name: 'Education::Program', join_table: 'education_programs_schools', diff --git a/app/models/education/school/administrator.rb b/app/models/education/school/administrator.rb new file mode 100644 index 0000000000000000000000000000000000000000..42c86f05d85da39dabe4259c4f405644814febc5 --- /dev/null +++ b/app/models/education/school/administrator.rb @@ -0,0 +1,33 @@ +# == Schema Information +# +# Table name: education_school_administrators +# +# id :uuid not null, primary key +# description :text +# created_at :datetime not null +# updated_at :datetime not null +# person_id :uuid not null +# school_id :uuid not null +# +# Indexes +# +# index_education_school_administrators_on_person_id (person_id) +# index_education_school_administrators_on_school_id (school_id) +# +# Foreign Keys +# +# fk_rails_... (person_id => university_people.id) +# fk_rails_... (school_id => education_schools.id) +# +class Education::School::Administrator < ApplicationRecord + belongs_to :school + belongs_to :person, class_name: "University::Person" + + validates :person_id, uniqueness: { scope: :school_id } + + scope :ordered, -> { joins(:person).order('university_people.last_name, university_people.first_name') } + + def to_s + person.to_s + end +end diff --git a/app/views/admin/education/school/administrators/_form.html.erb b/app/views/admin/education/school/administrators/_form.html.erb new file mode 100644 index 0000000000000000000000000000000000000000..b5bedea8c7871307d8a0422c6a931bf3ddf88bff --- /dev/null +++ b/app/views/admin/education/school/administrators/_form.html.erb @@ -0,0 +1,21 @@ +<%= simple_form_for [:admin, administrator] 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_administrator_ids = @school.administrators.where.not(id: administrator.id).pluck(:person_id) %> + <%= f.association :person, collection: current_university.people.administratives.where.not(id: used_administrator_ids).ordered %> + </div> + <div class="col-md-6"> + <%= f.input :description, as: :string %> + </div> + </div> + </div> + </div> + <% content_for :action_bar_right do %> + <%= submit f %> + <% end %> +<% end %> diff --git a/app/views/admin/education/school/administrators/_list.html.erb b/app/views/admin/education/school/administrators/_list.html.erb new file mode 100644 index 0000000000000000000000000000000000000000..569c595ec8484f23a561d1d16fb4ac9aea34466b --- /dev/null +++ b/app/views/admin/education/school/administrators/_list.html.erb @@ -0,0 +1,35 @@ +<% if administrators.any? %> + <table class="table"> + <thead> + <tr> + <th class="ps-0"><%= Education::School::Administrator.model_name.human %></th> + <th><%= Education::School::Administrator.human_attribute_name('description') %></th> + <th></th> + </tr> + </thead> + <tbody> + <% administrators.each do |administrator| %> + <tr> + <td class="ps-0"> + <%= link_to_if can?(:read, administrator.person), + administrator.person, + admin_university_person_path(administrator.person) %> + </td> + <td><%= administrator.description %></td> + <td class="text-end pe-0"> + <div class="btn-group" role="group"> + <%= link_to t('edit'), + edit_admin_education_school_administrator_path(administrator, { school_id: @school.id }), + class: button_classes %> + <%= link_to t('delete'), + admin_education_school_administrator_path(administrator, { school_id: @school.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/school/administrators/edit.html.erb b/app/views/admin/education/school/administrators/edit.html.erb new file mode 100644 index 0000000000000000000000000000000000000000..d2a82994691505b7789cdf1252c47e02b635ad7c --- /dev/null +++ b/app/views/admin/education/school/administrators/edit.html.erb @@ -0,0 +1,3 @@ +<% content_for :title, @administrator %> + +<%= render 'form', administrator: @administrator %> diff --git a/app/views/admin/education/school/administrators/new.html.erb b/app/views/admin/education/school/administrators/new.html.erb new file mode 100644 index 0000000000000000000000000000000000000000..491f71583cc0b5c2f5be4abc2e892f093ad25d9e --- /dev/null +++ b/app/views/admin/education/school/administrators/new.html.erb @@ -0,0 +1,3 @@ +<% content_for :title, Education::School::Administrator.model_name.human %> + +<%= render 'form', administrator: @administrator %> diff --git a/app/views/admin/education/schools/show.html.erb b/app/views/admin/education/schools/show.html.erb index 6c3c7800cd0e22c9c6ab72deae562e43bba725b8..5367e4558ab1221f8c894ae179fcc1a437f85a94 100644 --- a/app/views/admin/education/schools/show.html.erb +++ b/app/views/admin/education/schools/show.html.erb @@ -56,6 +56,16 @@ </div> +<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> + <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 %> + </div> +</div> + <% content_for :action_bar_right do %> <%= edit_link @school %> <% end %> diff --git a/config/locales/education/en.yml b/config/locales/education/en.yml index 1cb84dcbc556de93a10b05279a7898ffd1a9c800..011a5cad49bc54f2f9701b567a679a3ce3584654 100644 --- a/config/locales/education/en.yml +++ b/config/locales/education/en.yml @@ -19,6 +19,9 @@ en: education/school: one: School other: Schools + education/school/administrator: + one: Administrator + other: Administrators attributes: education/program: accessibility: Accessibilité @@ -55,6 +58,7 @@ en: person: Person education/school: address: Address + administrators: Administrators city: City country: Country name: Name @@ -62,6 +66,9 @@ en: programs: Programs provided websites: Associated websites zipcode: Zipcode + education/school/administrator: + description: Description + person: Person education: manage_teachers: Manage teachers number_of_programs: Number of programs diff --git a/config/locales/education/fr.yml b/config/locales/education/fr.yml index 755c0845c9fe9548966d38adfe7106f00dfd79d7..ceece053513aa0543ea09a1d1434c64a7054367a 100644 --- a/config/locales/education/fr.yml +++ b/config/locales/education/fr.yml @@ -19,6 +19,9 @@ fr: education/school: one: École other: Écoles + education/school/administrator: + one: Administrateur·trice + other: Administrateurs·trices attributes: education/program: accessibility: Accessibilité @@ -57,6 +60,7 @@ fr: person: Personne education/school: address: Adresse + administrators: Administrateurs·trices city: Ville country: Pays name: Nom @@ -64,6 +68,9 @@ fr: programs: Formations dispensées websites: Sites webs associés zipcode: Code postal + education/school/administrator: + description: Description + person: Personne education: manage_teachers: Gérer les Enseignants·es number_of_programs: Nombre de formations diff --git a/config/routes/admin/education.rb b/config/routes/admin/education.rb index 79e0e2555fda0126e8550d8739cf36ea24c06e6e..c3ac5899ec1bdaae385534f3d240cf8716955689 100644 --- a/config/routes/admin/education.rb +++ b/config/routes/admin/education.rb @@ -1,6 +1,8 @@ namespace :education do resources :teachers, only: [:index, :show] - resources :schools + resources :schools do + resources :administrators, controller: 'school/administrators', except: [:index, :show] + end resources :programs do resources :roles, controller: 'program/roles', except: :index do resources :people, controller: 'program/role/people', except: [:index, :show, :edit, :update] do diff --git a/db/migrate/20220107111002_create_education_school_administrators.rb b/db/migrate/20220107111002_create_education_school_administrators.rb new file mode 100644 index 0000000000000000000000000000000000000000..d3454d325129e53e5f82073bacfe5c0693be6088 --- /dev/null +++ b/db/migrate/20220107111002_create_education_school_administrators.rb @@ -0,0 +1,11 @@ +class CreateEducationSchoolAdministrators < ActiveRecord::Migration[6.1] + def change + create_table :education_school_administrators, id: :uuid do |t| + t.text :description + t.references :school, null: false, foreign_key: { to_table: :education_schools }, type: :uuid + t.references :person, null: false, foreign_key: { to_table: :university_people }, type: :uuid + + t.timestamps + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 0271d56506cd95bbd33ce4d258f38011215c180c..da37739dbbe4b74153ea08627eb1a8552639f2cf 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_07_094053) do +ActiveRecord::Schema.define(version: 2022_01_07_111002) do # These are extensions that must be enabled in order to support this database enable_extension "pgcrypto" @@ -405,6 +405,16 @@ ActiveRecord::Schema.define(version: 2022_01_07_094053) do t.index ["education_school_id", "education_program_id"], name: "school_program" end + create_table "education_school_administrators", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + t.text "description" + t.uuid "school_id", null: false + t.uuid "person_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_school_administrators_on_person_id" + t.index ["school_id"], name: "index_education_school_administrators_on_school_id" + end + create_table "education_schools", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| t.uuid "university_id", null: false t.string "name" @@ -608,6 +618,8 @@ ActiveRecord::Schema.define(version: 2022_01_07_094053) do add_foreign_key "education_program_teachers", "university_people", column: "person_id" add_foreign_key "education_programs", "education_programs", column: "parent_id" add_foreign_key "education_programs", "universities" + add_foreign_key "education_school_administrators", "education_schools", column: "school_id" + add_foreign_key "education_school_administrators", "university_people", column: "person_id" add_foreign_key "education_schools", "universities" add_foreign_key "research_journal_articles", "research_journal_volumes" add_foreign_key "research_journal_articles", "research_journals" diff --git a/test/fixtures/education/school/administrators.yml b/test/fixtures/education/school/administrators.yml new file mode 100644 index 0000000000000000000000000000000000000000..cb3dfca46f6efbe84e6a429141b5ebdd31d4d64c --- /dev/null +++ b/test/fixtures/education/school/administrators.yml @@ -0,0 +1,32 @@ +# == Schema Information +# +# Table name: education_school_administrators +# +# id :uuid not null, primary key +# description :text +# created_at :datetime not null +# updated_at :datetime not null +# person_id :uuid not null +# school_id :uuid not null +# +# Indexes +# +# index_education_school_administrators_on_person_id (person_id) +# index_education_school_administrators_on_school_id (school_id) +# +# Foreign Keys +# +# fk_rails_... (person_id => university_people.id) +# fk_rails_... (school_id => education_schools.id) +# +# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +one: + description: MyText + school: one + person: one + +two: + description: MyText + school: two + person: two diff --git a/test/models/education/school/administrator_test.rb b/test/models/education/school/administrator_test.rb new file mode 100644 index 0000000000000000000000000000000000000000..bdf223d6db7b2ae4bf2e3898d934c14310cc7024 --- /dev/null +++ b/test/models/education/school/administrator_test.rb @@ -0,0 +1,28 @@ +# == Schema Information +# +# Table name: education_school_administrators +# +# id :uuid not null, primary key +# description :text +# created_at :datetime not null +# updated_at :datetime not null +# person_id :uuid not null +# school_id :uuid not null +# +# Indexes +# +# index_education_school_administrators_on_person_id (person_id) +# index_education_school_administrators_on_school_id (school_id) +# +# Foreign Keys +# +# fk_rails_... (person_id => university_people.id) +# fk_rails_... (school_id => education_schools.id) +# +require "test_helper" + +class Education::School::AdministratorTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end