diff --git a/Gemfile.lock b/Gemfile.lock index f33419243c46e98e47e526a7d42666346b68aee4..efa92a34d47faccb9f7145389826952d43e179f8 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -28,35 +28,35 @@ GIT GEM remote: https://rubygems.org/ specs: - actioncable (7.1.2) - actionpack (= 7.1.2) - activesupport (= 7.1.2) + actioncable (7.1.3) + actionpack (= 7.1.3) + activesupport (= 7.1.3) nio4r (~> 2.0) websocket-driver (>= 0.6.1) zeitwerk (~> 2.6) - actionmailbox (7.1.2) - actionpack (= 7.1.2) - activejob (= 7.1.2) - activerecord (= 7.1.2) - activestorage (= 7.1.2) - activesupport (= 7.1.2) + actionmailbox (7.1.3) + actionpack (= 7.1.3) + activejob (= 7.1.3) + activerecord (= 7.1.3) + activestorage (= 7.1.3) + activesupport (= 7.1.3) mail (>= 2.7.1) net-imap net-pop net-smtp - actionmailer (7.1.2) - actionpack (= 7.1.2) - actionview (= 7.1.2) - activejob (= 7.1.2) - activesupport (= 7.1.2) + actionmailer (7.1.3) + actionpack (= 7.1.3) + actionview (= 7.1.3) + activejob (= 7.1.3) + activesupport (= 7.1.3) mail (~> 2.5, >= 2.5.4) net-imap net-pop net-smtp rails-dom-testing (~> 2.2) - actionpack (7.1.2) - actionview (= 7.1.2) - activesupport (= 7.1.2) + actionpack (7.1.3) + actionview (= 7.1.3) + activesupport (= 7.1.3) nokogiri (>= 1.8.5) racc rack (>= 2.2.4) @@ -64,15 +64,15 @@ GEM rack-test (>= 0.6.3) rails-dom-testing (~> 2.2) rails-html-sanitizer (~> 1.6) - actiontext (7.1.2) - actionpack (= 7.1.2) - activerecord (= 7.1.2) - activestorage (= 7.1.2) - activesupport (= 7.1.2) + actiontext (7.1.3) + actionpack (= 7.1.3) + activerecord (= 7.1.3) + activestorage (= 7.1.3) + activesupport (= 7.1.3) globalid (>= 0.6.0) nokogiri (>= 1.8.5) - actionview (7.1.2) - activesupport (= 7.1.2) + actionview (7.1.3) + activesupport (= 7.1.3) builder (~> 3.1) erubi (~> 1.11) rails-dom-testing (~> 2.2) @@ -82,25 +82,25 @@ GEM activemodel (>= 5.2.0) activestorage (>= 5.2.0) activesupport (>= 5.2.0) - activejob (7.1.2) - activesupport (= 7.1.2) + activejob (7.1.3) + activesupport (= 7.1.3) globalid (>= 0.3.6) - activemodel (7.1.2) - activesupport (= 7.1.2) - activerecord (7.1.2) - activemodel (= 7.1.2) - activesupport (= 7.1.2) + activemodel (7.1.3) + activesupport (= 7.1.3) + activerecord (7.1.3) + activemodel (= 7.1.3) + activesupport (= 7.1.3) timeout (>= 0.4.0) - activestorage (7.1.2) - actionpack (= 7.1.2) - activejob (= 7.1.2) - activerecord (= 7.1.2) - activesupport (= 7.1.2) + activestorage (7.1.3) + actionpack (= 7.1.3) + activejob (= 7.1.3) + activerecord (= 7.1.3) + activesupport (= 7.1.3) marcel (~> 1.0) activestorage-scaleway-service (1.0.1) activestorage aws-sdk-s3 - activesupport (7.1.2) + activesupport (7.1.3) base64 bigdecimal concurrent-ruby (~> 1.0, >= 1.0.2) @@ -123,8 +123,8 @@ GEM autoprefixer-rails (10.4.16.0) execjs (~> 2) aws-eventstream (1.3.0) - aws-partitions (1.880.0) - aws-sdk-core (3.190.2) + aws-partitions (1.883.0) + aws-sdk-core (3.190.3) aws-eventstream (~> 1, >= 1.3.0) aws-partitions (~> 1, >= 1.651.0) aws-sigv4 (~> 1.8) @@ -140,7 +140,7 @@ GEM aws-eventstream (~> 1, >= 1.0.2) base64 (0.2.0) bcrypt (3.1.20) - bigdecimal (3.1.5) + bigdecimal (3.1.6) bindex (0.8.1) bootsnap (1.17.1) msgpack (~> 1.2) @@ -152,7 +152,7 @@ GEM rails (>= 3.1) breadcrumbs_on_rails (4.1.0) railties (>= 5.0) - bugsnag (6.26.1) + bugsnag (6.26.3) concurrent-ruby (~> 1.0) builder (3.2.4) byebug (11.1.3) @@ -307,7 +307,7 @@ GEM image_processing (1.12.2) mini_magick (>= 4.9.5, < 5) ruby-vips (>= 2.0.17, < 3) - io-console (0.7.1) + io-console (0.7.2) irb (1.11.1) rdoc reline (>= 0.4.2) @@ -370,7 +370,7 @@ GEM nokogiri (~> 1.13) mini_magick (4.12.0) mini_mime (1.1.5) - minitest (5.21.1) + minitest (5.21.2) msgpack (1.7.2) multi_xml (0.6.0) multipart-post (2.3.0) @@ -423,7 +423,7 @@ GEM time uri orm_adapter (0.5.0) - parser (3.3.0.4) + parser (3.3.0.5) ast (~> 2.4.1) racc pexels (0.5.0) @@ -436,33 +436,33 @@ GEM puma (6.4.2) nio4r (~> 2.0) racc (1.7.3) - rack (2.2.8) + rack (3.0.8) rack-mini-profiler (2.3.4) rack (>= 1.2.0) - rack-protection (3.2.0) + rack-protection (4.0.0) base64 (>= 0.1.0) - rack (~> 2.2, >= 2.2.4) - rack-session (1.0.2) - rack (< 3) + rack (>= 3.0.0, < 4) + rack-session (2.0.0) + rack (>= 3.0.0) rack-test (2.1.0) rack (>= 1.3) - rackup (1.0.0) - rack (< 3) - webrick - rails (7.1.2) - actioncable (= 7.1.2) - actionmailbox (= 7.1.2) - actionmailer (= 7.1.2) - actionpack (= 7.1.2) - actiontext (= 7.1.2) - actionview (= 7.1.2) - activejob (= 7.1.2) - activemodel (= 7.1.2) - activerecord (= 7.1.2) - activestorage (= 7.1.2) - activesupport (= 7.1.2) + rackup (2.1.0) + rack (>= 3) + webrick (~> 1.8) + rails (7.1.3) + actioncable (= 7.1.3) + actionmailbox (= 7.1.3) + actionmailer (= 7.1.3) + actionpack (= 7.1.3) + actiontext (= 7.1.3) + actionview (= 7.1.3) + activejob (= 7.1.3) + activemodel (= 7.1.3) + activerecord (= 7.1.3) + activestorage (= 7.1.3) + activesupport (= 7.1.3) bundler (>= 1.15.0) - railties (= 7.1.2) + railties (= 7.1.3) rails-autocomplete (2.0.1) rails (>= 4.0) rails-dom-testing (2.2.0) @@ -475,9 +475,9 @@ GEM rails-i18n (7.0.8) i18n (>= 0.7, < 2) railties (>= 6.0.0, < 8) - railties (7.1.2) - actionpack (= 7.1.2) - activesupport (= 7.1.2) + railties (7.1.3) + actionpack (= 7.1.3) + activesupport (= 7.1.3) irb rackup (>= 1.0.0) rake (>= 12.2) @@ -499,7 +499,7 @@ GEM actionpack (>= 5.2) railties (>= 5.2) rexml (3.2.6) - roo (2.10.0) + roo (2.10.1) nokogiri (~> 1) rubyzip (>= 1.3.0, < 3.0.0) rotp (6.3.0) @@ -552,10 +552,11 @@ GEM simplecov_json_formatter (~> 0.1) simplecov-html (0.12.3) simplecov_json_formatter (0.1.4) - sinatra (3.2.0) + sinatra (4.0.0) mustermann (~> 3.0) - rack (~> 2.2, >= 2.2.4) - rack-protection (= 3.2.0) + rack (>= 3.0.0, < 4) + rack-protection (= 4.0.0) + rack-session (>= 2.0.0, < 3) tilt (~> 2.0) snaky_hash (2.0.1) hashie @@ -716,4 +717,4 @@ RUBY VERSION ruby 3.3.0p0 BUNDLED WITH - 2.5.4 + 2.5.3 diff --git a/app/controllers/admin/administration/locations_controller.rb b/app/controllers/admin/administration/locations_controller.rb new file mode 100644 index 0000000000000000000000000000000000000000..3cb94a4abdf118a3ae40f3695cd8969dd0d37995 --- /dev/null +++ b/app/controllers/admin/administration/locations_controller.rb @@ -0,0 +1,68 @@ +class Admin::Administration::LocationsController < Admin::Administration::ApplicationController + load_and_authorize_resource class: Administration::Location, + through: :current_university + + def index + breadcrumb + end + + def show + breadcrumb + end + + def static + @about = @location + @website = @location.websites&.first + render_as_plain_text + end + + def new + breadcrumb + end + + def edit + breadcrumb + add_breadcrumb t('edit') + end + + def create + @location.university = current_university + if @location.save + redirect_to [:admin, @location], + notice: t('admin.successfully_created_html', model: @location.to_s) + else + breadcrumb + render :new, status: :unprocessable_entity + end + end + + def update + if @location.update(location_params) + redirect_to [:admin, @location], + notice: t('admin.successfully_updated_html', model: @location.to_s) + else + breadcrumb + add_breadcrumb t('edit') + render :edit, status: :unprocessable_entity + end + end + + def destroy + @location.destroy + redirect_to admin_education_locations_url, + notice: t('admin.successfully_destroyed_html', model: @location.to_s) + end + + private + + def breadcrumb + super + add_breadcrumb Administration::Location.model_name.human(count: 2), admin_administration_locations_path + breadcrumb_for @location + end + + def location_params + params.require(:administration_location) + .permit(:name, :address, :zipcode, :city, :country, :url, :phone, school_ids: [], program_ids: []) + end +end diff --git a/app/models/administration.rb b/app/models/administration.rb index 364c98970f7677d08c1cf3c1adc5ee5eaedb689e..82053de20c9d2836e7d4d26d78ad8eb1608aa328 100644 --- a/app/models/administration.rb +++ b/app/models/administration.rb @@ -8,6 +8,7 @@ module Administration def self.parts [ + [Administration::Location, :admin_administration_locations_path], [Administration::Qualiopi, :admin_administration_qualiopi_criterions_path], ] end diff --git a/app/models/administration/location.rb b/app/models/administration/location.rb new file mode 100644 index 0000000000000000000000000000000000000000..8908cd91886441cd8e8cf3d7ff3f0dca4fe9ca8c --- /dev/null +++ b/app/models/administration/location.rb @@ -0,0 +1,119 @@ +# == Schema Information +# +# Table name: administration_locations +# +# id :uuid not null, primary key +# address :string +# city :string +# country :string +# latitude :float +# longitude :float +# name :string +# phone :string +# slug :string +# summary :text +# url :string +# zipcode :string +# created_at :datetime not null +# updated_at :datetime not null +# university_id :uuid not null, indexed +# +# Indexes +# +# index_administration_locations_on_university_id (university_id) +# +# Foreign Keys +# +# fk_rails_bfeca0e4b1 (university_id => universities.id) +# +class Administration::Location < ApplicationRecord + include AsIndirectObject + include Contentful + include Sanitizable + include Sluggable + include WebsitesLinkable + include WithBlobs + include WithCountry + include WithGitFiles + include WithGeolocation + include WithPermalink + include WithUniversity + + has_and_belongs_to_many :schools, + class_name: 'Education::School', + foreign_key: :education_school_id, + association_foreign_key: :administration_location_id + alias_method :education_schools, :schools + has_and_belongs_to_many :programs, + class_name: 'Education::Program', + foreign_key: :education_program_id, + association_foreign_key: :administration_location_id + alias_method :education_programs, :programs + has_many :diplomas, + -> { distinct }, + through: :programs, + source: :diploma + alias_method :education_diplomas, :diplomas + + + scope :ordered, -> { order(:name) } + + validates :name, :address, :city, :zipcode, :country, presence: true + + def to_s + "#{name}" + end + + def git_path(website) + "#{git_path_content_prefix(website)}locations/#{slug}/_index.html" if for_website?(website) + end + + def dependencies + active_storage_blobs + + contents_dependencies + + programs + + schools + end + + def references + [] + end + + # WebsitesLinkable + + def has_administrators? + # TODO les administrateurs du site + false + end + + def has_researchers? + # TODO les chercheurs du site + false + end + + def has_teachers? + # TODO les enseignants du site + false + end + + def has_education_programs? + programs.any? + end + + def has_education_diplomas? + diplomas.any? + end + + def has_research_papers? + false + end + + def has_research_volumes? + false + end + + def has_administration_locations? + # Un site (location) n'a pas de site (location) dépendant + false + end +end diff --git a/app/models/communication/extranet/document/category.rb b/app/models/communication/extranet/document/category.rb index 16cdc262a308fd180eab5f7c19edcd6e30c5a081..a34ab07dc246b71b2428cee799d053d4b4628e05 100644 --- a/app/models/communication/extranet/document/category.rb +++ b/app/models/communication/extranet/document/category.rb @@ -22,7 +22,7 @@ # fk_rails_76e327b90f (extranet_id => communication_extranets.id) # class Communication::Extranet::Document::Category < ApplicationRecord - include WithSlug + include Sluggable include WithUniversity belongs_to :extranet, class_name: 'Communication::Extranet' diff --git a/app/models/communication/extranet/document/kind.rb b/app/models/communication/extranet/document/kind.rb index 6c993fc15020b7451c04b6e6788a4e080d0c9b10..3d574467df8a3b768e52b6e33e2f4a64b12a862e 100644 --- a/app/models/communication/extranet/document/kind.rb +++ b/app/models/communication/extranet/document/kind.rb @@ -22,7 +22,7 @@ # fk_rails_2a55cf899a (university_id => universities.id) # class Communication::Extranet::Document::Kind < ApplicationRecord - include WithSlug + include Sluggable include WithUniversity belongs_to :extranet, class_name: 'Communication::Extranet' diff --git a/app/models/communication/extranet/post.rb b/app/models/communication/extranet/post.rb index b8c6fe37c7e7fb7d899e2b6f17d30625df76d07f..a3cf3bc06705c439b1a2a4f9d64a7c879108f573 100644 --- a/app/models/communication/extranet/post.rb +++ b/app/models/communication/extranet/post.rb @@ -36,11 +36,11 @@ class Communication::Extranet::Post < ApplicationRecord include Contentful include Sanitizable + include Sluggable include WithAccessibility include WithFeaturedImage include WithPublication include WithPermalink - include WithSlug include WithUniversity belongs_to :author, class_name: 'University::Person', optional: true diff --git a/app/models/communication/extranet/post/category.rb b/app/models/communication/extranet/post/category.rb index 560a5e574c529f6dd65d053df68689e1ec887cbf..f1849195325583213db073184ac18d5e137de856 100644 --- a/app/models/communication/extranet/post/category.rb +++ b/app/models/communication/extranet/post/category.rb @@ -22,7 +22,7 @@ # fk_rails_e53c2a25fc (extranet_id => communication_extranets.id) # class Communication::Extranet::Post::Category < ApplicationRecord - include WithSlug + include Sluggable include WithUniversity belongs_to :extranet, class_name: 'Communication::Extranet' diff --git a/app/models/communication/website/agenda/category.rb b/app/models/communication/website/agenda/category.rb index a067f66dec6d8780d418a6001671380dc83e1f86..049f0b88f5603e01782321f4fddd4ee594a5f0ce 100644 --- a/app/models/communication/website/agenda/category.rb +++ b/app/models/communication/website/agenda/category.rb @@ -39,15 +39,15 @@ class Communication::Website::Agenda::Category < ApplicationRecord include AsDirectObject include Contentful include Sanitizable + include Sluggable include WithBlobs include WithFeaturedImage include WithMenuItemTarget include WithPermalink include WithPosition - include WithSlug include WithTranslations include WithUniversity - + belongs_to :parent, class_name: 'Communication::Website::Agenda::Category', optional: true diff --git a/app/models/communication/website/agenda/event.rb b/app/models/communication/website/agenda/event.rb index 6e58e6bd8347ae6344b69a859ddb36929fe8ec57..d30cb3a71fc133f1b97fd68180e9faad0f22508f 100644 --- a/app/models/communication/website/agenda/event.rb +++ b/app/models/communication/website/agenda/event.rb @@ -45,6 +45,7 @@ class Communication::Website::Agenda::Event < ApplicationRecord include AsDirectObject include Contentful include Sanitizable + include Sluggable include WithAccessibility include WithBlobs include WithCal @@ -52,7 +53,6 @@ class Communication::Website::Agenda::Event < ApplicationRecord include WithFeaturedImage include WithMenuItemTarget include WithPermalink - include WithSlug include WithTime include WithTranslations include WithTree diff --git a/app/models/communication/website/page/administration_location.rb b/app/models/communication/website/page/administration_location.rb new file mode 100644 index 0000000000000000000000000000000000000000..a9d54d590c833367e87c9ba4fd8ba3e891cf5ea1 --- /dev/null +++ b/app/models/communication/website/page/administration_location.rb @@ -0,0 +1,31 @@ +class Communication::Website::Page::AdministrationLocation < Communication::Website::Page + + def is_necessary_for_website? + website.about && website.about&.respond_to?(:administration_locations) + end + + def editable_width? + false + end + + def full_width_by_default? + true + end + + def full_width + true + end + + def dependencies + super + + [website.config_default_languages] + + website.administration_locations + end + + protected + + def current_git_path + @current_git_path ||= "#{git_path_prefix}locations/_index.html" + end + +end diff --git a/app/models/communication/website/page/with_type.rb b/app/models/communication/website/page/with_type.rb index 49083795f1da4274c18008a991556781997b2753..2f9a6a534478f6d3f7a79298bceb00e89ef4be9d 100644 --- a/app/models/communication/website/page/with_type.rb +++ b/app/models/communication/website/page/with_type.rb @@ -20,6 +20,8 @@ module Communication::Website::Page::WithType Communication::Website::Page::ResearchVolume, Communication::Website::Page::ResearchPaper, Communication::Website::Page::ResearchHalPublication, + # Administration + Communication::Website::Page::AdministrationLocation, # People facets Communication::Website::Page::Administrator, Communication::Website::Page::Author, diff --git a/app/models/communication/website/permalink/location.rb b/app/models/communication/website/permalink/location.rb new file mode 100644 index 0000000000000000000000000000000000000000..ad2b0358cf4ff537cd5e248d3bc1eca7a8218e9b --- /dev/null +++ b/app/models/communication/website/permalink/location.rb @@ -0,0 +1,14 @@ +class Communication::Website::Permalink::Location < Communication::Website::Permalink + def self.required_in_config?(website) + website.has_administration_locations? + end + + def self.static_config_key + :locations + end + + # /campus/:slug/ + def self.pattern_in_website(website, language) + "/#{website.special_page(Communication::Website::Page::AdministrationLocation, language: language).slug_with_ancestors}/:slug/" + end +end diff --git a/app/models/communication/website/post.rb b/app/models/communication/website/post.rb index 89bd6d00f40805c4db70123f61bdd446d72c0775..5bcb5863e37cbfa5f92d00715bd114e3981e8e00 100644 --- a/app/models/communication/website/post.rb +++ b/app/models/communication/website/post.rb @@ -42,6 +42,7 @@ class Communication::Website::Post < ApplicationRecord include AsDirectObject include Contentful include Sanitizable + include Sluggable # We override slug_unavailable? method include WithAccessibility include WithBlobs include WithDuplication @@ -49,7 +50,6 @@ class Communication::Website::Post < ApplicationRecord include WithMenuItemTarget include WithPermalink include WithPublication - include WithSlug # We override slug_unavailable? method include WithTranslations include WithUniversity diff --git a/app/models/communication/website/post/category.rb b/app/models/communication/website/post/category.rb index d8e19451c9082500aa75ea8375ff6f31898b848f..eb21c8709084d88e95a252f5d00e775d3e662b47 100644 --- a/app/models/communication/website/post/category.rb +++ b/app/models/communication/website/post/category.rb @@ -44,12 +44,12 @@ class Communication::Website::Post::Category < ApplicationRecord include AsDirectObject include Contentful include Sanitizable + include Sluggable # We override slug_unavailable? method include WithBlobs include WithFeaturedImage include WithMenuItemTarget include WithPermalink include WithPosition - include WithSlug # We override slug_unavailable? method include WithTranslations include WithTree include WithUniversity diff --git a/app/models/communication/website/with_associated_objects.rb b/app/models/communication/website/with_associated_objects.rb index 5e1fb4721d63aeaae299bf52f4122034554206d3..639bd2c7dcff61f109bc210066bd74d150b8e3fa 100644 --- a/app/models/communication/website/with_associated_objects.rb +++ b/app/models/communication/website/with_associated_objects.rb @@ -62,6 +62,10 @@ module Communication::Website::WithAssociatedObjects has_education_programs? ? about.published_programs : Education::Program.none end + def administration_locations + has_administration_locations? ? about.administration_locations : Administration::Location.none + end + def research_volumes has_research_volumes? ? about.published_volumes : Research::Journal::Volume.none end @@ -122,6 +126,10 @@ module Communication::Website::WithAssociatedObjects about && about.has_education_programs? end + def has_administration_locations? + about && about.has_administration_locations? + end + def has_research_papers? about && about.has_research_papers? end diff --git a/app/models/concerns/with_slug.rb b/app/models/concerns/sluggable.rb similarity index 98% rename from app/models/concerns/with_slug.rb rename to app/models/concerns/sluggable.rb index fe4de4072802c13240bd55a1a3c5b144f32e9d72..14f9cb4efbb9c07d9ddaabc2f3ca7e74b7157c53 100644 --- a/app/models/concerns/with_slug.rb +++ b/app/models/concerns/sluggable.rb @@ -1,4 +1,4 @@ -module WithSlug +module Sluggable extend ActiveSupport::Concern included do diff --git a/app/models/concerns/aboutable.rb b/app/models/concerns/websites_linkable.rb similarity index 53% rename from app/models/concerns/aboutable.rb rename to app/models/concerns/websites_linkable.rb index 5a9f8541b9ed4abdb3e77a0297e4773a94d0e47e..891cc062e87ea62dd733c5366f587f1f353e2585 100644 --- a/app/models/concerns/aboutable.rb +++ b/app/models/concerns/websites_linkable.rb @@ -1,4 +1,10 @@ -module Aboutable +# Means there might be a website about this object +# https://iut-perigueux.u-bordeaux.fr about a location +# https://www.iut.u-bordeaux-montaigne.fr about a school +# https://mmibordeaux.com about a program +# https://www.degrowthjournal.org about a journal +# hthttps://mica.u-bordeaux-montaigne.fr about a laboratory +module WebsitesLinkable extend ActiveSupport::Concern def has_administrators? @@ -28,4 +34,8 @@ module Aboutable def has_research_volumes? raise NotImplementedError end + + def has_administration_locations? + raise NotImplementedError + end end diff --git a/app/models/education/diploma.rb b/app/models/education/diploma.rb index 655948b20e8a82ed045527aa11304c7a2cd3efce..74244ebc514b2eb954aaac6a4133000c24de007d 100644 --- a/app/models/education/diploma.rb +++ b/app/models/education/diploma.rb @@ -27,9 +27,9 @@ class Education::Diploma < ApplicationRecord include AsIndirectObject include Contentful include Sanitizable + include Sluggable include WithGitFiles include WithPermalink - include WithSlug include WithUniversity has_many :programs, dependent: :nullify diff --git a/app/models/education/program.rb b/app/models/education/program.rb index b8e2c446d5b5afcf81aec038d980bea7f1a1bd1c..e636a892ca1036b8c8f8c019a52bfaef4b5482f4 100644 --- a/app/models/education/program.rb +++ b/app/models/education/program.rb @@ -51,10 +51,11 @@ # fk_rails_ec1f16f607 (parent_id => education_programs.id) # class Education::Program < ApplicationRecord - include Aboutable include AsIndirectObject include Contentful include Sanitizable + include Sluggable + include WebsitesLinkable include WithAccessibility include WithAlumni include WithBlobs @@ -62,11 +63,11 @@ class Education::Program < ApplicationRecord include WithFeaturedImage include WithGitFiles include WithInheritance + include WithLocations include WithMenuItemTarget include WithPermalink include WithPosition include WithSchools - include WithSlug include WithTeam include WithTree include WithUniversity @@ -147,6 +148,7 @@ class Education::Program < ApplicationRecord def dependencies active_storage_blobs + contents_dependencies + + locations + university_people_through_involvements.map(&:teacher) + university_people_through_role_involvements.map(&:administrator) + [diploma] @@ -166,7 +168,7 @@ class Education::Program < ApplicationRecord end ##################### - # Aboutable methods # + # WebsitesLinkable methods # ##################### def has_administrators? university_people_through_role_involvements.any? || diff --git a/app/models/education/program/with_locations.rb b/app/models/education/program/with_locations.rb new file mode 100644 index 0000000000000000000000000000000000000000..9c03f1e9c4ebc878677116c361535886fed776a5 --- /dev/null +++ b/app/models/education/program/with_locations.rb @@ -0,0 +1,15 @@ +module Education::Program::WithLocations + extend ActiveSupport::Concern + + included do + has_and_belongs_to_many :administration_locations, + class_name: 'Administration::Location', + foreign_key: :administration_location_id, + association_foreign_key: :education_program_id + alias_method :locations, :administration_locations + end + + def has_administration_locations? + locations.any? + end +end diff --git a/app/models/education/school.rb b/app/models/education/school.rb index 9941eb6814f472623dcfd99f20bc50ab1e37eaf9..1c5de7eb0d150f52662916ccd06d12de803a4181 100644 --- a/app/models/education/school.rb +++ b/app/models/education/school.rb @@ -25,17 +25,17 @@ # fk_rails_e01b37a3ad (university_id => universities.id) # class Education::School < ApplicationRecord - include Aboutable include AsIndirectObject include Sanitizable + include WebsitesLinkable include WithAlumni include WithBlobs include WithCountry include WithGitFiles + include WithLocations include WithPrograms # must come before WithAlumni and WithTeam include WithTeam - - belongs_to :university + include WithUniversity # 'websites' might override the same method defined in WithWebsites, so we use the full name has_many :communication_websites, @@ -75,12 +75,13 @@ class Education::School < ApplicationRecord active_storage_blobs + programs + diplomas + + locations + administrators.map(&:administrator) + researchers.map(&:researcher) end ##################### - # Aboutable methods # + # WebsitesLinkable methods ##################### def has_research_papers? diff --git a/app/models/education/school/with_locations.rb b/app/models/education/school/with_locations.rb new file mode 100644 index 0000000000000000000000000000000000000000..ac62adfdeced3ae2b1a4881ad7eb47f995dcaf69 --- /dev/null +++ b/app/models/education/school/with_locations.rb @@ -0,0 +1,15 @@ +module Education::School::WithLocations + extend ActiveSupport::Concern + + included do + has_and_belongs_to_many :administration_locations, + class_name: 'Administration::Location', + foreign_key: :administration_location_id, + association_foreign_key: :education_school_id + alias_method :locations, :administration_locations + end + + def has_administration_locations? + locations.any? + end +end diff --git a/app/models/research/hal/publication.rb b/app/models/research/hal/publication.rb index 7f01e14ee7e21cc639fa92dfc963080abb204a12..62e543fe86d77005396687a7ba4e68d88327d619 100644 --- a/app/models/research/hal/publication.rb +++ b/app/models/research/hal/publication.rb @@ -30,10 +30,10 @@ class Research::Hal::Publication < ApplicationRecord include AsIndirectObject include Sanitizable + include Sluggable include WithCitations include WithGitFiles include WithPermalink - include WithSlug has_and_belongs_to_many :researchers, class_name: 'University::Person', diff --git a/app/models/research/journal.rb b/app/models/research/journal.rb index adb4d33c798ea53c516127de0188a5eae3405945..508d25bc21a28a6d902eff1c24a6cce89b2d9c67 100644 --- a/app/models/research/journal.rb +++ b/app/models/research/journal.rb @@ -21,9 +21,9 @@ # class Research::Journal < ApplicationRecord include AsIndirectObject - include Aboutable include Favoritable include Sanitizable + include WebsitesLinkable include WithGitFiles include WithUniversity @@ -86,7 +86,7 @@ class Research::Journal < ApplicationRecord end ##################### - # Aboutable methods # + # WebsitesLinkable methods # ##################### def has_administrators? false @@ -107,6 +107,10 @@ class Research::Journal < ApplicationRecord def has_education_diplomas? false end + + def has_administration_locations? + false + end def has_research_papers? published_papers.published.any? diff --git a/app/models/research/journal/paper.rb b/app/models/research/journal/paper.rb index 83946342a9364979794d2a0f95d834fa0da5cf6f..db56fc0a68d3846301e8829ff0bf7a72633de6bb 100644 --- a/app/models/research/journal/paper.rb +++ b/app/models/research/journal/paper.rb @@ -45,15 +45,15 @@ # class Research::Journal::Paper < ApplicationRecord include AsIndirectObject + include Contentful include Sanitizable + include Sluggable include WithBlobs - include Contentful include WithCitations include WithGitFiles include WithPermalink include WithPosition include WithPublication - include WithSlug include WithUniversity has_summernote :bibliography diff --git a/app/models/research/journal/paper/kind.rb b/app/models/research/journal/paper/kind.rb index 4ac1d90d922fa238103851e2c6a6cc4cae694e2a..26044c9bc237de927406af09e83f3fde0e10be51 100644 --- a/app/models/research/journal/paper/kind.rb +++ b/app/models/research/journal/paper/kind.rb @@ -24,8 +24,8 @@ class Research::Journal::Paper::Kind < ApplicationRecord include AsIndirectObject include Sanitizable + include Sluggable include WithGitFiles - include WithSlug include WithUniversity belongs_to :journal, class_name: 'Research::Journal' diff --git a/app/models/research/journal/volume.rb b/app/models/research/journal/volume.rb index c2efddbb93dee263e2d580fdb20bbd009238a3b2..a47e6789f34597bb4167c0a5e96b39eff9ac144d 100644 --- a/app/models/research/journal/volume.rb +++ b/app/models/research/journal/volume.rb @@ -33,12 +33,12 @@ class Research::Journal::Volume < ApplicationRecord include AsIndirectObject include Sanitizable + include Sluggable include WithBlobs include WithFeaturedImage include WithGitFiles include WithPermalink include WithPublication - include WithSlug include WithUniversity has_summernote :text diff --git a/app/models/research/laboratory.rb b/app/models/research/laboratory.rb index 0a091ec6ca552eb0c1a54ab2c5509e3b31cc13fe..29eebf3199adc39ff69660f02616466bf7c2a252 100644 --- a/app/models/research/laboratory.rb +++ b/app/models/research/laboratory.rb @@ -21,9 +21,9 @@ # fk_rails_f61d27545f (university_id => universities.id) # class Research::Laboratory < ApplicationRecord - include Aboutable include AsIndirectObject include Sanitizable + include WebsitesLinkable include WithCountry include WithGitFiles @@ -92,6 +92,11 @@ class Research::Laboratory < ApplicationRecord false end + # TODO en fait un laboratoire peut avoir des locations mais il faut le coder + def has_administration_locations? + false + end + def has_research_papers? false end diff --git a/app/models/university.rb b/app/models/university.rb index 2789a655b08f108b736ea9a3e72e1e65db3358dd..3c6d5233cb7852a9afe2f86873a10530eb2f7c8d 100644 --- a/app/models/university.rb +++ b/app/models/university.rb @@ -40,12 +40,13 @@ class University < ApplicationRecord self.filter_attributes += [:sso_cert] # We don't include Sanitizable because too many complex attributes. We handle it below. - include WithPeopleAndOrganizations + include WithAdministration include WithCommunication include WithCountry include WithEducation include WithIdentifier include WithInvoice + include WithPeopleAndOrganizations include WithResearch include WithSso include WithUsers diff --git a/app/models/university/organization.rb b/app/models/university/organization.rb index 3d2ed70191a43be0f59aede521971f4a02822e9b..97394d6fa82c66fec0b6be29a9c7318f9e16e9d0 100644 --- a/app/models/university/organization.rb +++ b/app/models/university/organization.rb @@ -48,15 +48,15 @@ # class University::Organization < ApplicationRecord include AsIndirectObject - include Contentful include Backlinkable + include Contentful include Sanitizable + include Sluggable include WithBlobs include WithCountry include WithGeolocation include WithGitFiles include WithPermalink - include WithSlug include WithTranslations include WithUniversity diff --git a/app/models/university/person.rb b/app/models/university/person.rb index 97b12794f2ad25ca0514c8cfe21e4d55d696cef1..6e26f2a2d58a7949d1adee796032733064b731da 100644 --- a/app/models/university/person.rb +++ b/app/models/university/person.rb @@ -59,6 +59,7 @@ class University::Person < ApplicationRecord include Backlinkable include Contentful include Sanitizable + include Sluggable include WithBlobs include WithCountry # WithRoles included before WithEducation because needed for the latter @@ -69,7 +70,6 @@ class University::Person < ApplicationRecord include WithPermalink include WithPicture include WithResearch - include WithSlug include WithTranslations include WithUniversity diff --git a/app/models/university/with_administration.rb b/app/models/university/with_administration.rb new file mode 100644 index 0000000000000000000000000000000000000000..c19afd360860e0d22a06241a5d9602f915bdb0fd --- /dev/null +++ b/app/models/university/with_administration.rb @@ -0,0 +1,10 @@ +module University::WithAdministration + extend ActiveSupport::Concern + + included do + has_many :administration_locations, + class_name: 'Administration::Location', + dependent: :destroy + alias_method :locations, :administration_locations + end +end diff --git a/app/services/icon.rb b/app/services/icon.rb index b09a73897fdd87c7293b7ccbb6464f855755690f..78d817d6252c783b839ce1bc56d58fc15a1ffa6f 100644 --- a/app/services/icon.rb +++ b/app/services/icon.rb @@ -47,6 +47,7 @@ class Icon RESEARCH_HAL = RESEARCH_PUBLICATION ADMINISTRATION_CAMPUS = 'fas fa-map-marker-alt' + ADMINISTRATION_LOCATION = 'fas fa-map-marker-alt' ADMINISTRATION_ADMISSIONS = 'fas fa-door-open' ADMINISTRATION_INTERNSHIPS = 'fas fa-hands-helping' ADMINISTRATION_STATISTICS = 'fas fa-chart-bar' diff --git a/app/views/admin/administration/locations/_form.html.erb b/app/views/admin/administration/locations/_form.html.erb new file mode 100644 index 0000000000000000000000000000000000000000..68eb0c747f26bad2f064b4097e9c1bedc89db082 --- /dev/null +++ b/app/views/admin/administration/locations/_form.html.erb @@ -0,0 +1,43 @@ +<%= simple_form_for [:admin, location] do |f| %> + <%= f.error_notification %> + <%= f.error_notification message: f.object.errors[:base].to_sentence if f.object.errors[:base].present? %> + <div class="row mb-5"> + <div class="col-lg-4"> + <%= f.input :name %> + <%= render 'admin/application/summary/form', f: f, about: location %> + </div> + <div class="col-lg-4"> + <%= f.input :address %> + <div class="row pure__row--small"> + <div class="col-md-4"> + <%= f.input :zipcode %> + </div> + <div class="col-md-8"> + <%= f.input :city %> + </div> + </div> + <%= f.input :country, input_html: { class: 'form-select' } %> + </div> + <div class="col-lg-4"> + <%= f.input :phone %> + <%= f.input :url %> + </div> + </div> + <div class="row"> + <div class="col-lg-4"> + <%= f.association :schools, + as: :check_boxes, + collection: current_university.education_schools.ordered %> + </div> + <div class="col-lg-4"> + <%= f.association :programs, + as: :check_boxes, + collection: collection_tree(current_university.education_programs), + label_method: ->(p) { sanitize p[:label] }, + value_method: ->(p) { p[:id] } %> + </div> + </div> + <% content_for :action_bar_right do %> + <%= submit f %> + <% end %> +<% end %> diff --git a/app/views/admin/administration/locations/_list.html.erb b/app/views/admin/administration/locations/_list.html.erb new file mode 100644 index 0000000000000000000000000000000000000000..c7e047114ab08300ece9119f65b1b49f678e1286 --- /dev/null +++ b/app/views/admin/administration/locations/_list.html.erb @@ -0,0 +1,25 @@ +<div class="table-responsive"> + <table class="<%= table_classes %>"> + <thead> + <tr> + <th><%= Administration::Location.human_attribute_name('name') %></th> + <th><%= Administration::Location.human_attribute_name('address') %></th> + <th></th> + </tr> + </thead> + <tbody> + <% locations.ordered.each do |location| %> + <tr> + <td><%= link_to location, [:admin, location] %></td> + <td><%= location.full_street_address %></td> + <td class="text-end"> + <div class="btn-group" role="group"> + <%= edit_link location %> + <%= destroy_link location %> + </div> + </td> + </tr> + <% end %> + </tbody> + </table> +</div> diff --git a/app/views/admin/administration/locations/edit.html.erb b/app/views/admin/administration/locations/edit.html.erb new file mode 100644 index 0000000000000000000000000000000000000000..aa47ec6c2e699cbd878c4fa0c2dd78c1b657efe3 --- /dev/null +++ b/app/views/admin/administration/locations/edit.html.erb @@ -0,0 +1,3 @@ +<% content_for :title, @location %> + +<%= render 'form', location: @location %> diff --git a/app/views/admin/administration/locations/index.html.erb b/app/views/admin/administration/locations/index.html.erb new file mode 100644 index 0000000000000000000000000000000000000000..880744fed19a5f5a81ab1d40b640aa0259b2a633 --- /dev/null +++ b/app/views/admin/administration/locations/index.html.erb @@ -0,0 +1,7 @@ +<% content_for :title, Administration::Location.model_name.human(count: 2) %> + +<%= render 'admin/administration/locations/list', locations: @locations %> + +<% content_for :action_bar_right do %> + <%= create_link Administration::Location %> +<% end %> diff --git a/app/views/admin/administration/locations/new.html.erb b/app/views/admin/administration/locations/new.html.erb new file mode 100644 index 0000000000000000000000000000000000000000..7077a263cff1225f36891018eccdd653aa9ba0cc --- /dev/null +++ b/app/views/admin/administration/locations/new.html.erb @@ -0,0 +1,3 @@ +<% content_for :title, Administration::Location.model_name.human %> + +<%= render 'form', location: @location %> diff --git a/app/views/admin/administration/locations/show.html.erb b/app/views/admin/administration/locations/show.html.erb new file mode 100644 index 0000000000000000000000000000000000000000..808affcddafb8517eb65a1ef785247f2c8d6b093 --- /dev/null +++ b/app/views/admin/administration/locations/show.html.erb @@ -0,0 +1,70 @@ +<% content_for :title, @location %> + +<div class="row"> + <div class="col-lg-4"> + <%= osuny_panel t('metadata') do %> + <%= osuny_label Education::School.human_attribute_name('address') %> + <p> + <%= @location.address %><br> + <%= @location.zipcode %> <%= @location.city %><br> + <%= @location.country %> + </p> + <% if @location.phone.present? %> + <%= osuny_label Education::School.human_attribute_name('phone') %> + <p><%= @location.phone %></p> + <% end %> + <% if @location.url.present? %> + <%= osuny_label Administration::Location.human_attribute_name('url') %> + <p><%= link_to @location.url, @location.url, target: :_blank %></p> + <% end %> + <% end %> + </div> + <% if @location.schools.any? %> + <div class="col-lg-4"> + <%= osuny_panel Administration::Location.human_attribute_name('schools') do %> + <ul class="list-unstyled"> + <% @location.schools.ordered.each do |school| %> + <li><%= link_to_if can?(:read, school), school, [:admin, school] %></li> + <% end %> + </ul> + <% end %> + </div> + <% end %> + + <% if @location.programs.any? %> + <div class="col-lg-4"> + <%= osuny_panel Administration::Location.human_attribute_name('programs') do %> + <ul class="list-unstyled"> + <% @location.programs.ordered.each do |program| %> + <li><%= link_to_if can?(:read, program), program, [:admin, program] %></li> + <% end %> + </ul> + <% end %> + </div> + <% end %> + + <% if @location.websites.any? %> + <div class="col-lg-4"> + <%= osuny_panel Administration::Location.human_attribute_name('websites') do %> + <ul class="list-unstyled"> + <% @location.websites.each do |website| %> + <li><%= link_to website, [:admin, website] %></li> + <% end %> + </ul> + <% end %> + </div> + <% end %> +</div> + +<%= render 'admin/communication/blocks/content/editor', about: @location %> + +<%= render 'admin/application/connections/list', about: @location %> + +<% content_for :action_bar_left do %> + <%= destroy_link @location %> + <%= static_link static_admin_administration_location_path(@location) %> +<% end %> + +<% content_for :action_bar_right do %> + <%= edit_link @location %> +<% end %> diff --git a/app/views/admin/administration/locations/static.html.erb b/app/views/admin/administration/locations/static.html.erb new file mode 100644 index 0000000000000000000000000000000000000000..0e75b24c7be59b8288a314e165deb20cb80e95a0 --- /dev/null +++ b/app/views/admin/administration/locations/static.html.erb @@ -0,0 +1,39 @@ +--- +title: > + <%= prepare_text_for_static @about.name %> +<%= render 'admin/application/static/permalink' if @website %> +<%= render 'admin/application/static/design', full_width: true, toc_offcanvas: true %> +<% if @website %> +<%= render 'admin/application/static/breadcrumbs', + pages: @website.special_page(Communication::Website::Page::AdministrationLocation).ancestors_and_self, + current_title: @about.to_s %> +<% end %> +contact_details: +<%= render 'admin/application/static/contact_detail', variable: :address, data: @about.address, kind: ContactDetails::Base %> +<%= render 'admin/application/static/contact_detail', variable: :zipcode, data: @about.zipcode, kind: ContactDetails::Base %> +<%= render 'admin/application/static/contact_detail', variable: :city, data: @about.city, kind: ContactDetails::Base %> +<%= render 'admin/application/static/contact_detail', variable: :country, data: @about.country, kind: ContactDetails::Country %> +<%= render 'admin/application/static/contact_detail', variable: :address, data: @about.address, kind: ContactDetails::Base %> +<%= render 'admin/application/static/contact_detail', variable: :website, data: @about.url, kind: ContactDetails::Website %> +<%= render 'admin/application/static/contact_detail', variable: :phone, data: @about.phone, kind: ContactDetails::Phone %> + geolocation: + latitude: <%= @about.latitude %> + longitude: <%= @about.longitude %> +programs: +<% @about.programs.each do |program| %> + - <%= program.path %> +<% end %> +diplomas: +<% @about.diplomas.each do |diploma| %> + - name: > + <%= diploma.to_s %> + path: <%= diploma.slug %> + programs: <% @programs = @about.education_programs.where(diploma: diploma).root.ordered %> +<%= render 'admin/education/programs/static_list', + diploma: diploma, + programs: @programs, + all_programs: @about.programs, + depth: 4 %> +<% end %> +<%= render 'admin/communication/blocks/content/static', about: @about %> +--- diff --git a/app/views/admin/communication/websites/connections/_indirect_object.html.erb b/app/views/admin/communication/websites/connections/_indirect_object.html.erb index 8c4794ce55e4b3ff70781a7dab69f3da93db8d7a..4b1a7677348312941be2d2b0a08a12165c13f0cf 100644 --- a/app/views/admin/communication/websites/connections/_indirect_object.html.erb +++ b/app/views/admin/communication/websites/connections/_indirect_object.html.erb @@ -1,8 +1,8 @@ <% -object = connection.indirect_object -object_name = object.to_s -object_name = object.id if object.is_a?(ActiveStorage::Blob) begin + object = connection.indirect_object + object_name = object.to_s + object_name = object.id if object.is_a?(ActiveStorage::Blob) object_link = url_for [:admin, object] rescue end diff --git a/app/views/admin/education/diplomas/static.html.erb b/app/views/admin/education/diplomas/static.html.erb index f904c860702e08d03051850f0396077450141a1c..f568f283461b2ac0a609f3ae2f648f255457fba8 100644 --- a/app/views/admin/education/diplomas/static.html.erb +++ b/app/views/admin/education/diplomas/static.html.erb @@ -9,7 +9,7 @@ title: > <% if @website @programs = @website.education_programs.where(diploma: @about).root.ordered %> programs: -<%= render 'admin/education/diplomas/programs', diploma: @about, programs: @programs %> +<%= render 'admin/education/programs/static_list', diploma: @about, programs: @programs %> <% end %> short_name: > <%= prepare_text_for_static @about.short_name %> diff --git a/app/views/admin/education/diplomas/_programs.html.erb b/app/views/admin/education/programs/_static_list.html.erb similarity index 52% rename from app/views/admin/education/diplomas/_programs.html.erb rename to app/views/admin/education/programs/_static_list.html.erb index af697c37f81cff55735e5400d14983c09ce66e68..831d928dcf6169469e3baa361b23165137d0a78c 100644 --- a/app/views/admin/education/diplomas/_programs.html.erb +++ b/app/views/admin/education/programs/_static_list.html.erb @@ -6,9 +6,13 @@ indentation = ' ' * depth <%= indentation %>- label: > <%= indentation %> <%= program.to_s %> <%= indentation %> path: "<%= program.current_permalink_in_website(@website)&.path %>" -<% children = program.children.where(diploma: diploma) %> +<% +children = program.children.where(diploma: diploma) +# Limit to a global list of programs, for example on a location +children = children.where(id: all_programs) if all_programs +%> <% if children.any? %> <%= indentation %> children: -<%= render 'admin/education/diplomas/programs', diploma: diploma, programs: children, depth: depth + 4 %> +<%= render 'admin/education/programs/static_list', diploma: diploma, programs: children, depth: depth + 4 %> <% end %> <% end %> diff --git a/app/views/admin/education/programs/show/_details.html.erb b/app/views/admin/education/programs/show/_details.html.erb index 94cdb6871b325ee024fd8ceaf57e9aed9ce6d31c..c23c4d6e1e7a204d3a03ff33400d8d5c30cacc97 100644 --- a/app/views/admin/education/programs/show/_details.html.erb +++ b/app/views/admin/education/programs/show/_details.html.erb @@ -10,6 +10,14 @@ <% end %> </ul> <% end %> + <% if program.locations.any? %> + <%= osuny_label Education::Program.human_attribute_name('locations') %> + <ul class="list-unstyled"> + <% program.locations.ordered.each do |location| %> + <li><%= link_to_if can?(:read, location), location, [:admin, location] %></li> + <% end %> + </ul> + <% end %> </div> <div class="col-lg-8"> <%= osuny_label Education::Program.human_attribute_name('short_name') %> diff --git a/app/views/admin/education/schools/show.html.erb b/app/views/admin/education/schools/show.html.erb index 8fae9ac1ca65314010fbac5bde1050467c1b2ba5..6f4961a690385dd8ab23e20470632ebecbd916be 100644 --- a/app/views/admin/education/schools/show.html.erb +++ b/app/views/admin/education/schools/show.html.erb @@ -35,6 +35,18 @@ </div> <% end %> + <% if @school.locations.any? %> + <div class="col-lg-4"> + <%= osuny_panel Education::School.human_attribute_name('locations') do %> + <ul class="list-unstyled"> + <% @school.locations.ordered.each do |location| %> + <li><%= link_to_if can?(:read, location), location, [:admin, location] %></li> + <% end %> + </ul> + <% end %> + </div> + <% end %> + <% if @school.websites.any? %> <div class="col-xxl-4"> <%= osuny_panel Education::School.human_attribute_name('websites') do %> diff --git a/config/admin_navigation.rb b/config/admin_navigation.rb index 80e6adff0f47e400554c4296282797b335a405ab..b6f9c1f8ea82def11009446fbb298701f3210473 100644 --- a/config/admin_navigation.rb +++ b/config/admin_navigation.rb @@ -43,7 +43,6 @@ SimpleNavigation::Configuration.run do |navigation| if feature_administration? primary.item :administration, Administration.model_name.human, admin_administration_root_path, { kind: :header, image: 'admin/administration-thumb.jpg' } load_from_parts Administration, primary - primary.item :administration_campus, 'Campus', nil, { icon: Icon::ADMINISTRATION_CAMPUS } primary.item :administration_admissions, 'Admissions', nil, { icon: Icon::ADMINISTRATION_ADMISSIONS } primary.item :administration_internship, 'Stages', nil, { icon: Icon::ADMINISTRATION_INTERNSHIPS } primary.item :administration_statistics, 'Statistiques', nil, { icon: Icon::ADMINISTRATION_STATISTICS } diff --git a/config/locales/administration/en.yml b/config/locales/administration/en.yml index f5aa929946ff61ac08de19de285d41ea7db6af2a..d2454fdafd213229852a2c617551ce6972b4a8c1 100644 --- a/config/locales/administration/en.yml +++ b/config/locales/administration/en.yml @@ -4,6 +4,9 @@ en: administration/qualiopi: Qualiopi activerecord: models: + administration/location: + one: Location + other: Campus administration/qualiopi/criterion: one: Criterion other: Criterions @@ -11,6 +14,17 @@ en: one: Indicator other: Indicators attributes: + administration/location: + address: Address + city: City + country: Country + name: Name + phone: Telephone + programs: Programs + schools: Schools + url: Website + websites: Linked websites + zipcode: Zipcode administration/qualiopi/criterion: number: Number name: Name @@ -30,5 +44,7 @@ en: text: Administration, in its many forms, is defined primarily by its activities in the service of the general interest. It acts in the general interest and respects the principle of legality. It is bound by the obligation of neutrality and respect for the principle of secularism. It complies with the principle of equality and guarantees everyone impartial treatment. source: Code des relations entre le public et l'administration parts: + location: + description: Management of the various (physical) education and research sites qualiopi: description: Help in checking the conformity of the training offer with the Qualiopi standard \ No newline at end of file diff --git a/config/locales/administration/fr.yml b/config/locales/administration/fr.yml index 5b57ec79688ca012b705af04a0f053d04d03df39..cd2d5d84fea1c3f921846334b082ba96257407da 100644 --- a/config/locales/administration/fr.yml +++ b/config/locales/administration/fr.yml @@ -4,6 +4,9 @@ fr: administration/qualiopi: Qualiopi activerecord: models: + administration/location: + one: Site + other: Campus administration/qualiopi/criterion: one: Critère other: Critères @@ -11,6 +14,17 @@ fr: one: Indicateur other: Indicateurs attributes: + administration/location: + address: Adresse + city: Ville + country: Pays + name: Nom + phone: Téléphone + programs: Formations dispensées + schools: Écoles + url: Site Web + websites: Sites Web associés + zipcode: Code postal administration/qualiopi/criterion: number: Numéro name: Nom @@ -30,5 +44,7 @@ fr: text: L'administration, sous ses multiples formes, se définit principalement par ses activités au service de l'intérêt général. L'administration agit dans l'intérêt général et respecte le principe de légalité. Elle est tenue à l'obligation de neutralité et au respect du principe de laïcité. Elle se conforme au principe d'égalité et garantit à chacun un traitement impartial. source: Code des relations entre le public et l'administration parts: + location: + description: Gestion des différents sites (physiques) de formation et de recherche qualiopi: description: Aide à la vérification de la conformité de l'offre de formation avec la norme Qualiopi diff --git a/config/locales/communication/en.yml b/config/locales/communication/en.yml index 2f0971b8ade0203dec9395949866c55445643861..66df046916b8b236089482edefafb8c59d86a2b0 100644 --- a/config/locales/communication/en.yml +++ b/config/locales/communication/en.yml @@ -366,6 +366,9 @@ en: accessibility: slug: accessibility title: Accessibility + administration_location: + slug: campus + title: Campus administrator: slug: administrators title: Administrators diff --git a/config/locales/communication/fr.yml b/config/locales/communication/fr.yml index 099aee1bfb3e23bde05ae36e603c23930ebb4645..ed541ea417e31cc3c4b1615f9d9b5772314798e9 100644 --- a/config/locales/communication/fr.yml +++ b/config/locales/communication/fr.yml @@ -366,6 +366,9 @@ fr: accessibility: slug: accessibilite title: Accessibilité + administration_location: + slug: campus + title: Campus administrator: slug: equipe-administrative title: Équipe administrative diff --git a/config/locales/education/en.yml b/config/locales/education/en.yml index e79e9c9e285df376023982fabb43a7f78c52d863..38766f83388f7d5f72d3860bfed9a8b73cd842dd 100644 --- a/config/locales/education/en.yml +++ b/config/locales/education/en.yml @@ -53,6 +53,7 @@ en: initial: Initial training is_published: Published is_draft: Draft + locations: Campus main_information: Main information name: Name objectives: Objectifs @@ -77,6 +78,7 @@ en: administrators: Administrators city: City country: Country + locations: Campus name: Name phone: Phone programs: Programs provided diff --git a/config/locales/education/fr.yml b/config/locales/education/fr.yml index 5d0ddd48383afd84ea8902fb2faed6db8cd4d854..4e2252160d136362df4cff92f0e9131ea04d8415 100644 --- a/config/locales/education/fr.yml +++ b/config/locales/education/fr.yml @@ -53,6 +53,7 @@ fr: initial: Formation initiale is_published: Publiée is_draft: Brouillon + locations: Campus main_information: Informations essentielles name: Nom objectives: Objectifs @@ -77,6 +78,7 @@ fr: administrators: Équipe administrative city: Ville country: Pays + locations: Campus name: Nom phone: Téléphone programs: Formations dispensées diff --git a/config/routes/admin/administration.rb b/config/routes/admin/administration.rb index cd5c1ac24aaba28f21c9a2bc72150c41da993670..e4dd1801dfa37b2f85e3e2e3062da1728d400dca 100644 --- a/config/routes/admin/administration.rb +++ b/config/routes/admin/administration.rb @@ -1,4 +1,9 @@ namespace :administration do + resources :locations do + member do + get :static + end + end namespace :qualiopi do resources :criterions, only: [:index, :show] resources :indicators, only: [:index, :show] diff --git a/db/migrate/20240126081127_create_administration_locations.rb b/db/migrate/20240126081127_create_administration_locations.rb new file mode 100644 index 0000000000000000000000000000000000000000..023a95199bb3419c200c69d64eae60321325985b --- /dev/null +++ b/db/migrate/20240126081127_create_administration_locations.rb @@ -0,0 +1,19 @@ +class CreateAdministrationLocations < ActiveRecord::Migration[7.1] + def change + create_table :administration_locations, id: :uuid do |t| + t.references :university, null: false, foreign_key: true, type: :uuid + t.string :name + t.text :summary + t.string :address + t.string :zipcode + t.string :city + t.string :country + t.float :latitude + t.float :longitude + t.string :phone + t.string :url + + t.timestamps + end + end +end diff --git a/db/migrate/20240126090606_create_location_join_tables.rb b/db/migrate/20240126090606_create_location_join_tables.rb new file mode 100644 index 0000000000000000000000000000000000000000..2cb6043baf14d2e3279e72c0a2cdae6eae67cbc0 --- /dev/null +++ b/db/migrate/20240126090606_create_location_join_tables.rb @@ -0,0 +1,12 @@ +class CreateLocationJoinTables < ActiveRecord::Migration[7.1] + def change + create_join_table :administration_locations, :education_schools, column_options: {type: :uuid} do |t| + t.index [:"administration_location_id", :"education_school_id"], name: 'index_location_school' + t.index [:"education_school_id", :"administration_location_id"], name: 'index_school_location' + end + create_join_table :administration_locations, :education_programs, column_options: {type: :uuid} do |t| + t.index [:"administration_location_id", :"education_program_id"], name: 'index_location_program' + t.index [:"education_program_id", :"administration_location_id"], name: 'index_program_location' + end + end +end diff --git a/db/migrate/20240126112021_add_slug_to_administration_location.rb b/db/migrate/20240126112021_add_slug_to_administration_location.rb new file mode 100644 index 0000000000000000000000000000000000000000..8a495db3c373800345ff62475e67c75f5092ffca --- /dev/null +++ b/db/migrate/20240126112021_add_slug_to_administration_location.rb @@ -0,0 +1,5 @@ +class AddSlugToAdministrationLocation < ActiveRecord::Migration[7.1] + def change + add_column :administration_locations, :slug, :string + end +end diff --git a/db/schema.rb b/db/schema.rb index 5f838fbdad1e96af525ad95c76f3eedf28547e27..abd8aece95f9e7eb6959219640e23a6625d52f70 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -56,6 +56,38 @@ ActiveRecord::Schema[7.1].define(version: 2024_01_29_100647) do t.index ["blob_id", "variation_digest"], name: "index_active_storage_variant_records_uniqueness", unique: true end + create_table "administration_locations", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + t.uuid "university_id", null: false + t.string "name" + t.text "summary" + t.string "address" + t.string "zipcode" + t.string "city" + t.string "country" + t.float "latitude" + t.float "longitude" + t.string "phone" + t.string "url" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.string "slug" + t.index ["university_id"], name: "index_administration_locations_on_university_id" + end + + create_table "administration_locations_education_programs", id: false, force: :cascade do |t| + t.uuid "administration_location_id", null: false + t.uuid "education_program_id", null: false + t.index ["administration_location_id", "education_program_id"], name: "index_location_program" + t.index ["education_program_id", "administration_location_id"], name: "index_program_location" + end + + create_table "administration_locations_education_schools", id: false, force: :cascade do |t| + t.uuid "administration_location_id", null: false + t.uuid "education_school_id", null: false + t.index ["administration_location_id", "education_school_id"], name: "index_location_school" + t.index ["education_school_id", "administration_location_id"], name: "index_school_location" + end + create_table "administration_qualiopi_criterions", id: :uuid, default: -> { "public.gen_random_uuid()" }, force: :cascade do |t| t.integer "number" t.text "name" @@ -106,8 +138,8 @@ ActiveRecord::Schema[7.1].define(version: 2024_01_29_100647) do t.datetime "updated_at", null: false t.string "title" t.boolean "published", default: true - t.uuid "communication_website_id" t.uuid "heading_id" + t.uuid "communication_website_id" t.string "migration_identifier" t.index ["about_type", "about_id"], name: "index_communication_website_blocks_on_about" t.index ["communication_website_id"], name: "index_communication_blocks_on_communication_website_id" @@ -419,7 +451,7 @@ ActiveRecord::Schema[7.1].define(version: 2024_01_29_100647) do t.index ["university_id"], name: "index_communication_website_pages_on_university_id" end - create_table "communication_website_permalinks", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + create_table "communication_website_permalinks", id: :uuid, default: -> { "public.gen_random_uuid()" }, force: :cascade do |t| t.uuid "university_id", null: false t.uuid "website_id", null: false t.string "about_type", null: false @@ -1159,6 +1191,7 @@ ActiveRecord::Schema[7.1].define(version: 2024_01_29_100647) do add_foreign_key "active_storage_attachments", "active_storage_blobs", column: "blob_id" add_foreign_key "active_storage_variant_records", "active_storage_blobs", column: "blob_id" + add_foreign_key "administration_locations", "universities" add_foreign_key "administration_qualiopi_indicators", "administration_qualiopi_criterions", column: "criterion_id" add_foreign_key "communication_block_headings", "communication_block_headings", column: "parent_id" add_foreign_key "communication_block_headings", "universities" diff --git a/test/fixtures/administration/locations.yml b/test/fixtures/administration/locations.yml new file mode 100644 index 0000000000000000000000000000000000000000..1c617dac7e7f16e9a529265b08cb444cb5df89c7 --- /dev/null +++ b/test/fixtures/administration/locations.yml @@ -0,0 +1,25 @@ +# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +one: + name: MyString + university: default_university + address: MyString + city: MyString + country: MyString + latitude: 1.5 + longitude: 1.5 + phone: MyString + url: MyString + zipcode: MyString + +two: + name: MyString + university: default_university + address: MyString + city: MyString + country: MyString + latitude: 1.5 + longitude: 1.5 + phone: MyString + url: MyString + zipcode: MyString diff --git a/test/models/communication/website/dependency_test.rb b/test/models/communication/website/dependency_test.rb index 20f72639e472d7e91c445131a21819bbc257ed6d..7819e1b76f4625484ba221951d39670f24a8b059 100644 --- a/test/models/communication/website/dependency_test.rb +++ b/test/models/communication/website/dependency_test.rb @@ -70,11 +70,11 @@ class Communication::Website::DependencyTest < ActiveSupport::TestCase refute(destroy_obsolete_git_files_job) delta = website_with_github.reload.recursive_dependencies.count - dependencies_before_count # En ajoutant l'école, on rajoute en dépendances : - # - L'école, et ses formations et diplômes en cascade (3) + # - L'école, ses formations, diplômes et sites en cascade (4) # - Les catégories d'actus liés aux formations, soit la catégorie racine et la catégorie de default_program (2) # - Les pages "Teachers", "Administrators", "Researchers", "EducationDiplomas", "EducationPrograms" (5) # Donc un total de 3 + 2 + 5 = 10 dépendances - assert_equal 10, delta + assert_equal 11, delta Delayed::Job.destroy_all diff --git a/test/models/university/location_test.rb b/test/models/university/location_test.rb new file mode 100644 index 0000000000000000000000000000000000000000..ba4f84b9d61c9671a8b90179cc13cbd766956727 --- /dev/null +++ b/test/models/university/location_test.rb @@ -0,0 +1,7 @@ +require "test_helper" + +class University::LocationTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end