diff --git a/Gemfile b/Gemfile index b2bea4e6b13109568039410b6e5863f48a4da884..4a42a43119ec930d1f161e54c5f2af473dad0a8e 100644 --- a/Gemfile +++ b/Gemfile @@ -3,49 +3,55 @@ git_source(:github) { |repo| "https://github.com/#{repo}.git" } ruby '2.7.5' -gem 'angularjs-rails' +# Infrastructure gem 'aws-sdk-s3' +gem 'bugsnag' +gem 'gitlab' +gem 'image_processing' +gem 'mini_magick' +gem 'octokit' +gem 'pg', '~> 1.1' +gem 'puma' + +# Back-end +gem 'cancancan' gem 'bootsnap', '>= 1.4.4', require: false +gem 'curation'#, path: '../../arnaudlevy/curation' +gem 'delayed_job_active_record' +gem 'delayed_job_web' +gem 'faceted_search'#, path: '../faceted_search' +gem 'has_scope', '~> 0.8.0' +gem 'hash_dot' +gem 'rails', '~> 6.1' +gem 'rails-i18n' +gem 'sanitize' +gem 'sib-api-v3-sdk' +gem 'two_factor_authentication', git: 'https://github.com/noesya/two_factor_authentication.git' +# gem 'two_factor_authentication', path: '../two_factor_authentication' + +# Front-end +gem 'angularjs-rails' gem 'bootstrap' gem 'bootstrap5-kaminari-views' gem 'breadcrumbs_on_rails' -gem 'bugsnag' -gem 'cancancan' gem 'cocoon', '~> 1.2' gem 'country_select' -gem 'curation'#, path: '../../arnaudlevy/curation' -gem 'delayed_job_active_record' -gem 'delayed_job_web' gem 'devise' gem 'devise-i18n' gem 'enum_help' gem 'front_matter_parser' gem 'gdpr' -gem 'gitlab' -gem 'has_scope', '~> 0.8.0' -gem 'hash_dot' -gem 'image_processing' gem 'jbuilder' gem 'jquery-rails' gem 'kamifusen'#, path: '../kamifusen' gem 'kaminari' -gem 'mini_magick' -gem 'octokit' -gem 'pg', '~> 1.1' -gem 'puma' -gem 'rails', '~> 6.1' -gem 'rails-i18n' -gem 'sanitize' gem 'sassc-rails' -gem 'sib-api-v3-sdk' gem 'simple_form' gem 'simple_form_bs5_file_input'#, path: '../simple_form_bs5_file_input' gem 'simple_form_password_with_hints'#, path: '../simple_form_password_with_hints' gem 'simple-navigation' gem 'summernote-rails', git: 'https://github.com/noesya/summernote-rails.git', branch: 'activestorage' # gem 'summernote-rails', path: '../summernote-rails' -gem 'two_factor_authentication', git: 'https://github.com/noesya/two_factor_authentication.git' -# gem 'two_factor_authentication', path: '../two_factor_authentication' group :development, :test do gem 'byebug', platforms: [:mri, :mingw, :x64_mingw] diff --git a/Gemfile.lock b/Gemfile.lock index a1cbe2c603b75fd3c9aab9f6f94cb99720852fb2..106b97d221040a40d7d50ad3ec093bc5b3b43faa 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -20,60 +20,60 @@ GIT GEM remote: https://rubygems.org/ specs: - actioncable (6.1.5) - actionpack (= 6.1.5) - activesupport (= 6.1.5) + actioncable (6.1.5.1) + actionpack (= 6.1.5.1) + activesupport (= 6.1.5.1) nio4r (~> 2.0) websocket-driver (>= 0.6.1) - actionmailbox (6.1.5) - actionpack (= 6.1.5) - activejob (= 6.1.5) - activerecord (= 6.1.5) - activestorage (= 6.1.5) - activesupport (= 6.1.5) + actionmailbox (6.1.5.1) + actionpack (= 6.1.5.1) + activejob (= 6.1.5.1) + activerecord (= 6.1.5.1) + activestorage (= 6.1.5.1) + activesupport (= 6.1.5.1) mail (>= 2.7.1) - actionmailer (6.1.5) - actionpack (= 6.1.5) - actionview (= 6.1.5) - activejob (= 6.1.5) - activesupport (= 6.1.5) + actionmailer (6.1.5.1) + actionpack (= 6.1.5.1) + actionview (= 6.1.5.1) + activejob (= 6.1.5.1) + activesupport (= 6.1.5.1) mail (~> 2.5, >= 2.5.4) rails-dom-testing (~> 2.0) - actionpack (6.1.5) - actionview (= 6.1.5) - activesupport (= 6.1.5) + actionpack (6.1.5.1) + actionview (= 6.1.5.1) + activesupport (= 6.1.5.1) rack (~> 2.0, >= 2.0.9) rack-test (>= 0.6.3) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.0, >= 1.2.0) - actiontext (6.1.5) - actionpack (= 6.1.5) - activerecord (= 6.1.5) - activestorage (= 6.1.5) - activesupport (= 6.1.5) + actiontext (6.1.5.1) + actionpack (= 6.1.5.1) + activerecord (= 6.1.5.1) + activestorage (= 6.1.5.1) + activesupport (= 6.1.5.1) nokogiri (>= 1.8.5) - actionview (6.1.5) - activesupport (= 6.1.5) + actionview (6.1.5.1) + activesupport (= 6.1.5.1) builder (~> 3.1) erubi (~> 1.4) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.1, >= 1.2.0) - activejob (6.1.5) - activesupport (= 6.1.5) + activejob (6.1.5.1) + activesupport (= 6.1.5.1) globalid (>= 0.3.6) - activemodel (6.1.5) - activesupport (= 6.1.5) - activerecord (6.1.5) - activemodel (= 6.1.5) - activesupport (= 6.1.5) - activestorage (6.1.5) - actionpack (= 6.1.5) - activejob (= 6.1.5) - activerecord (= 6.1.5) - activesupport (= 6.1.5) + activemodel (6.1.5.1) + activesupport (= 6.1.5.1) + activerecord (6.1.5.1) + activemodel (= 6.1.5.1) + activesupport (= 6.1.5.1) + activestorage (6.1.5.1) + actionpack (= 6.1.5.1) + activejob (= 6.1.5.1) + activerecord (= 6.1.5.1) + activesupport (= 6.1.5.1) marcel (~> 1.0) mini_mime (>= 1.1.0) - activesupport (6.1.5) + activesupport (6.1.5.1) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 1.6, < 2) minitest (>= 5.1) @@ -88,20 +88,20 @@ GEM autoprefixer-rails (10.4.2.0) execjs (~> 2) aws-eventstream (1.2.0) - aws-partitions (1.576.0) - aws-sdk-core (3.130.1) + aws-partitions (1.580.0) + aws-sdk-core (3.130.2) aws-eventstream (~> 1, >= 1.0.2) aws-partitions (~> 1, >= 1.525.0) aws-sigv4 (~> 1.1) jmespath (~> 1.0) - aws-sdk-kms (1.55.0) + aws-sdk-kms (1.56.0) aws-sdk-core (~> 3, >= 3.127.0) aws-sigv4 (~> 1.1) - aws-sdk-s3 (1.113.0) + aws-sdk-s3 (1.113.2) aws-sdk-core (~> 3, >= 3.127.0) aws-sdk-kms (~> 1) aws-sigv4 (~> 1.4) - aws-sigv4 (1.4.0) + aws-sigv4 (1.5.0) aws-eventstream (~> 1, >= 1.0.2) bcrypt (3.1.17) bindex (0.8.1) @@ -172,6 +172,9 @@ GEM ethon (0.15.0) ffi (>= 1.15.0) execjs (2.8.1) + faceted_search (3.5.13) + font-awesome-sass + rails (>= 5.2.0, < 7) faraday (1.10.0) faraday-em_http (~> 1.0) faraday-em_synchrony (~> 1.0) @@ -208,6 +211,8 @@ GEM ffi (1.15.5) figaro (1.2.0) thor (>= 0.14.0, < 2) + font-awesome-sass (6.1.1) + sassc (~> 2.0) front_matter_parser (1.0.1) gdpr (1.2.3) js_cookie_rails @@ -316,20 +321,20 @@ GEM rack rack-test (1.1.0) rack (>= 1.0, < 3) - rails (6.1.5) - actioncable (= 6.1.5) - actionmailbox (= 6.1.5) - actionmailer (= 6.1.5) - actionpack (= 6.1.5) - actiontext (= 6.1.5) - actionview (= 6.1.5) - activejob (= 6.1.5) - activemodel (= 6.1.5) - activerecord (= 6.1.5) - activestorage (= 6.1.5) - activesupport (= 6.1.5) + rails (6.1.5.1) + actioncable (= 6.1.5.1) + actionmailbox (= 6.1.5.1) + actionmailer (= 6.1.5.1) + actionpack (= 6.1.5.1) + actiontext (= 6.1.5.1) + actionview (= 6.1.5.1) + activejob (= 6.1.5.1) + activemodel (= 6.1.5.1) + activerecord (= 6.1.5.1) + activestorage (= 6.1.5.1) + activesupport (= 6.1.5.1) bundler (>= 1.15.0) - railties (= 6.1.5) + railties (= 6.1.5.1) sprockets-rails (>= 2.0.0) rails-dom-testing (2.0.3) activesupport (>= 4.2.0) @@ -339,9 +344,9 @@ GEM rails-i18n (7.0.3) i18n (>= 0.7, < 2) railties (>= 6.0.0, < 8) - railties (6.1.5) - actionpack (= 6.1.5) - activesupport (= 6.1.5) + railties (6.1.5.1) + actionpack (= 6.1.5.1) + activesupport (= 6.1.5.1) method_source rake (>= 12.2) thor (~> 1.0) @@ -350,7 +355,7 @@ GEM rb-fsevent (0.11.1) rb-inotify (0.10.1) ffi (~> 1.0) - regexp_parser (2.3.0) + regexp_parser (2.3.1) responders (3.0.1) actionpack (>= 5.0) railties (>= 5.0) @@ -469,6 +474,7 @@ DEPENDENCIES devise devise-i18n enum_help + faceted_search figaro front_matter_parser gdpr diff --git a/app/assets/javascripts/admin/commons/batch-selectable.js b/app/assets/javascripts/admin/commons/batch-selectable.js new file mode 100644 index 0000000000000000000000000000000000000000..09f9f4f6c896865bf5639443f4c6acc33a2d39a3 --- /dev/null +++ b/app/assets/javascripts/admin/commons/batch-selectable.js @@ -0,0 +1,35 @@ +/* global */ +window.osuny.BatchSelectable = function BatchSelectable (element) { + 'use strict'; + this.element = element; + this.selectAllInput = this.element.querySelector('[data-batch-selectable-role="select-all"]'); + this.selectSingleInputs = this.element.querySelectorAll('[data-batch-selectable-role="select-single"]'); + this.initEvents(); +}; + +window.osuny.BatchSelectable.prototype.initEvents = function () { + 'use strict'; + if (this.selectAllInput === null) { + return; + } + this.selectAllInput.addEventListener('change', function () { + this.toggleSingleInputs(this.selectAllInput.checked); + }.bind(this)); +}; + +window.osuny.BatchSelectable.prototype.toggleSingleInputs = function (checked) { + 'use strict'; + var i; + for (i = 0; i < this.selectSingleInputs.length; i += 1) { + this.selectSingleInputs[i].checked = checked; + } +}; + +window.addEventListener('DOMContentLoaded', function () { + 'use strict'; + var elements = document.querySelectorAll('[data-batch-selectable]'), + i; + for (i = 0; i < elements.length; i += 1) { + new window.osuny.BatchSelectable(elements[i]); + } +}); diff --git a/app/assets/stylesheets/application.sass b/app/assets/stylesheets/application.sass index 1d71576b129df81fc868efe53a4d0f83414091a8..cbdad2dd5161fd3e130203aabb7e325e41f39451 100644 --- a/app/assets/stylesheets/application.sass +++ b/app/assets/stylesheets/application.sass @@ -4,5 +4,6 @@ @import 'simple_form_bs5_file_input' @import 'cropperjs/dist/cropper' @import 'gdpr/cookie_consent' +@import 'faceted_search' @import 'commons/*' @import 'application/*' diff --git a/app/assets/stylesheets/application/faceted_search.sass b/app/assets/stylesheets/application/faceted_search.sass new file mode 100644 index 0000000000000000000000000000000000000000..d3d8bb19432f4bc79f47c1c1fdc63c46c989f821 --- /dev/null +++ b/app/assets/stylesheets/application/faceted_search.sass @@ -0,0 +1,7 @@ +.faceted + &__facet-selected + a + text-decoration: none + &__facet__list + .faceted__facet__list__value + display: inline-block diff --git a/app/controllers/admin/application_controller.rb b/app/controllers/admin/application_controller.rb index 921a46d7ae157ee5413edfc7767c95ae8065efa0..084644e1d0aac2dc59bcc6cd28a4eac79cfcb840 100644 --- a/app/controllers/admin/application_controller.rb +++ b/app/controllers/admin/application_controller.rb @@ -1,6 +1,8 @@ class Admin::ApplicationController < ApplicationController layout 'admin/layouts/application' + before_action :load_filters, only: :index + around_action :switch_locale protected @@ -25,4 +27,12 @@ class Admin::ApplicationController < ApplicationController locale = LocaleService.locale(current_user, request.env['HTTP_ACCEPT_LANGUAGE']) I18n.with_locale(locale, &action) end + + def load_filters + @filters = [] + filter_class_name = "::Filters::#{self.class.to_s.gsub('Controller', '')}" + # filter_class will be nil if filter does not exist + filter_class = filter_class_name.safe_constantize + @filters = filter_class.new(current_user).list unless filter_class.nil? + end end diff --git a/app/controllers/admin/communication/extranets_controller.rb b/app/controllers/admin/communication/extranets_controller.rb index 0cfc44d68431688b8ccd159d35f342cf2cdb369f..6cd178308d3b24fc6208e2454e2cabfce2a9ba4b 100644 --- a/app/controllers/admin/communication/extranets_controller.rb +++ b/app/controllers/admin/communication/extranets_controller.rb @@ -8,9 +8,11 @@ class Admin::Communication::ExtranetsController < Admin::Communication::Applicat end def show - @alumni = @extranet.about&.alumni - @cohorts = @extranet.about&.cohorts - @years = @extranet.about&.academic_years + @about = @extranet.about + @alumni = @about&.alumni + @cohorts = @about&.cohorts + @years = @about&.academic_years + @organizations = @about&.alumni_organizations breadcrumb end diff --git a/app/controllers/admin/communication/website/posts_controller.rb b/app/controllers/admin/communication/website/posts_controller.rb index f9d074f007b6d1e127660e85fab7984400ee1115..ef64565104f4a3bcaac82da9439e1401a002ea04 100644 --- a/app/controllers/admin/communication/website/posts_controller.rb +++ b/app/controllers/admin/communication/website/posts_controller.rb @@ -6,12 +6,26 @@ class Admin::Communication::Website::PostsController < Admin::Communication::Web breadcrumb end + def publish + ids = params[:ids] || [] + target_posts = @website.posts.where(id: ids) + if params[:published] == "true" + target_posts.update(published: true) + elsif params[:published] == "false" + target_posts.update(published: false) + end + @website.sync_objects_with_git(target_posts) if target_posts.any? + redirect_back fallback_location: admin_communication_website_posts_path, + notice: t('communication.website.posts.successful_batch_update') + end + def show breadcrumb end def new @post.website = @website + @post.author_id = current_user.person&.id breadcrumb end diff --git a/app/controllers/admin/university/organizations_controller.rb b/app/controllers/admin/university/organizations_controller.rb index 3aadaf0ddef5521d6092b070ea1853feab56a3ec..4a168b2bec9da1be9d9972cafdd31958c34ce92b 100644 --- a/app/controllers/admin/university/organizations_controller.rb +++ b/app/controllers/admin/university/organizations_controller.rb @@ -62,7 +62,7 @@ class Admin::University::OrganizationsController < Admin::University::Applicatio .permit( :name, :long_name, :slug, :description, :active, :siren, :kind, :address, :zipcode, :city, :country, :text, - :url, :phone, :email, :logo, :logo_delete + :url, :phone, :email, :logo, :logo_delete, :logo_infos ) end end diff --git a/app/controllers/admin/university/people_controller.rb b/app/controllers/admin/university/people_controller.rb index 73b048763c7f2422e60ada101928405974cedd30..bdc9ee2d24cb6797568ca27be11c62683b902ccf 100644 --- a/app/controllers/admin/university/people_controller.rb +++ b/app/controllers/admin/university/people_controller.rb @@ -3,8 +3,12 @@ class Admin::University::PeopleController < Admin::University::ApplicationContro through: :current_university, through_association: :people + + has_scope :for_search_term + has_scope :for_role + def index - @people = @people.ordered.page(params[:page]) + @people = apply_scopes(@people).ordered.page(params[:page]) breadcrumb end diff --git a/app/controllers/admin/users_controller.rb b/app/controllers/admin/users_controller.rb index 1cdadc2ae8ac07723f3ae7f42c6a330b06c38052..ddb1f9b14892952864005cc7807c0495be6273cc 100644 --- a/app/controllers/admin/users_controller.rb +++ b/app/controllers/admin/users_controller.rb @@ -5,7 +5,6 @@ class Admin::UsersController < Admin::ApplicationController has_scope :for_search_term def index - @filters = ::Filters::User.new(current_user).list @users = apply_scopes(@users).ordered.page(params[:page]) breadcrumb end diff --git a/app/controllers/extranet/home_controller.rb b/app/controllers/extranet/home_controller.rb index ec6a69a8ee2e6e746f6314817be13f4884ddc324..6f189dd8b0cff76d40b497875cd8ea06c1b091ed 100644 --- a/app/controllers/extranet/home_controller.rb +++ b/app/controllers/extranet/home_controller.rb @@ -1,7 +1,8 @@ class Extranet::HomeController < Extranet::ApplicationController def index return redirect_to admin_root_path unless current_extranet - @cohorts = current_extranet.about&.cohorts || current_university.education_cohorts - @cohorts = @cohorts.ordered.limit(5) + @about = current_extranet.about || current_university + @cohorts = @about&.cohorts.ordered.limit(5) + @experiences = @about&.experiences.ordered.limit(10) end end diff --git a/app/controllers/extranet/organizations_controller.rb b/app/controllers/extranet/organizations_controller.rb index d91329fb8279c04f91c6a3b8cbc040e21114cb7b..ee06ab51e823f369a0a2571ea27bb2839b246edb 100644 --- a/app/controllers/extranet/organizations_controller.rb +++ b/app/controllers/extranet/organizations_controller.rb @@ -4,7 +4,9 @@ class Extranet::OrganizationsController < Extranet::ApplicationController through_association: :organizations def index + @organizations = current_extranet.about&.alumni_organizations || @organizations @organizations = @organizations.ordered.page(params[:page]) + @count = @organizations.total_count breadcrumb end diff --git a/app/controllers/extranet/persons_controller.rb b/app/controllers/extranet/persons_controller.rb index 172fc4473cb9dcea27c733b9b95c8d3c81b44b4a..e3975a7a7afe0f01c3a25506c8d5b567a25fc03c 100644 --- a/app/controllers/extranet/persons_controller.rb +++ b/app/controllers/extranet/persons_controller.rb @@ -4,7 +4,16 @@ class Extranet::PersonsController < Extranet::ApplicationController through_association: :people def index - @people = current_extranet.about&.alumni || @people.alumni + alumni = current_extranet.about&.alumni || @people.alumni + @facets = University::Person::Alumnus::Facets.new params[:facets], { + model: alumni, + about: current_extranet.about + } + @people = @facets.results + .ordered + .page(params[:page]) + .per(60) + @count = @people.total_count breadcrumb end diff --git a/app/helpers/admin/application_helper.rb b/app/helpers/admin/application_helper.rb index 8b213f3fe0b60082881b34c6762a5a6a7bef92f5..4ecd3416cb65e5531acd9fa4fc63320da5254f19 100644 --- a/app/helpers/admin/application_helper.rb +++ b/app/helpers/admin/application_helper.rb @@ -131,6 +131,7 @@ module Admin::ApplicationHelper 'communication.website.menu.item.kind.research_volumes' => 'fas fa-flask', 'communication.website.menu.item.kind.research_volume' => 'fas fa-flask', 'communication.website.menu.item.kind.researchers' => 'fas fa-user', + 'communication.website.menu.item.kind.organizations' => 'fas fa-building', 'communication.website.menu.item.kind.staff' => 'fas fa-user', 'communication.website.menu.item.kind.teachers' => 'fas fa-user', 'communication.website.menu.item.kind.url' => 'fas fa-globe', diff --git a/app/models/ability.rb b/app/models/ability.rb index 1aaad8c6c88e82b40d6cb44c6c9a345dadfe18a1..643651eb8a158dceea2e76a56f473c5fa8444739 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -30,6 +30,19 @@ class Ability can :read, Communication::Block, university_id: @user.university_id end + def contributor + managed_websites_ids = @user.websites_to_manage.pluck(:communication_website_id) + can :read, Communication::Website, university_id: @user.university_id, id: managed_websites_ids + can :manage, Communication::Website::Post, university_id: @user.university_id, communication_website_id: managed_websites_ids, author_id: @user.person&.id + cannot :publish, Communication::Website::Post + end + + def author + managed_websites_ids = @user.websites_to_manage.pluck(:communication_website_id) + can :read, Communication::Website, university_id: @user.university_id, id: managed_websites_ids + can :manage, Communication::Website::Post, university_id: @user.university_id, communication_website_id: managed_websites_ids, author_id: @user.person&.id + end + def teacher can :manage, University::Person, user_id: @user.id cannot :create, University::Person diff --git a/app/models/communication/block/template.rb b/app/models/communication/block/template.rb index b759d8326836f8ecbd05283ddb811c3745c57775..2eed4643d11775c3ae08abde14ce3cf2f5c03790 100644 --- a/app/models/communication/block/template.rb +++ b/app/models/communication/block/template.rb @@ -7,7 +7,7 @@ class Communication::Block::Template def git_dependencies unless @git_dependencies - @git_dependencies = active_storage_blobs + @git_dependencies = [] build_git_dependencies @git_dependencies.uniq! end diff --git a/app/models/communication/block/template/call_to_action.rb b/app/models/communication/block/template/call_to_action.rb index 8123bb6b918f9fa7b0ee7134e65b9ece92f18a9f..c2592194b24a0a3cda6c8d8e8f63886fdb27c2b4 100644 --- a/app/models/communication/block/template/call_to_action.rb +++ b/app/models/communication/block/template/call_to_action.rb @@ -1,6 +1,6 @@ class Communication::Block::Template::CallToAction < Communication::Block::Template def build_git_dependencies - # image à déclarer + add_dependency image&.blob end def text diff --git a/app/models/communication/block/template/gallery.rb b/app/models/communication/block/template/gallery.rb index da9c83d520d0f87f1e10ef11afdd7088ca3a0089..834169a4de18ae5a13948d1a58bfaaea25a188c0 100644 --- a/app/models/communication/block/template/gallery.rb +++ b/app/models/communication/block/template/gallery.rb @@ -1,6 +1,6 @@ class Communication::Block::Template::Gallery < Communication::Block::Template def build_git_dependencies - # Blobs already added in Communication::Block::Template#git_dependencies + add_dependency active_storage_blobs end def images_with_alt diff --git a/app/models/communication/block/template/partner.rb b/app/models/communication/block/template/partner.rb index 2bc364e062b11cb94e01d96ebe761d74eb2052ca..930e858e956f48b73502fcf49a0186adcf221962 100644 --- a/app/models/communication/block/template/partner.rb +++ b/app/models/communication/block/template/partner.rb @@ -1,7 +1,10 @@ class Communication::Block::Template::Partner < Communication::Block::Template def build_git_dependencies - # Blobs already added in Communication::Block::Template#git_dependencies + add_dependency active_storage_blobs add_dependency organizations + organizations.each do |organization| + add_dependency organization.active_storage_blobs + end end def partners diff --git a/app/models/communication/block/template/testimonial.rb b/app/models/communication/block/template/testimonial.rb index b72a81aa67e474fb8aef108ec58917a4833a82e6..85a231cddf44da4c1df77e7be6ae896aecb7abfa 100644 --- a/app/models/communication/block/template/testimonial.rb +++ b/app/models/communication/block/template/testimonial.rb @@ -1,6 +1,6 @@ class Communication::Block::Template::Testimonial < Communication::Block::Template def build_git_dependencies - # Blobs already added in Communication::Block::Template#git_dependencies + add_dependency active_storage_blobs end def testimonials diff --git a/app/models/communication/website.rb b/app/models/communication/website.rb index 266ba4915a11adbe47316297d0f7512e325ffc06..339043d19ea0cb5d8397d0bd9cd54cc4a2ad01d9 100644 --- a/app/models/communication/website.rb +++ b/app/models/communication/website.rb @@ -62,6 +62,7 @@ class Communication::Website < ApplicationRecord dependencies += pages + pages.map(&:active_storage_blobs).flatten dependencies += posts + posts.map(&:active_storage_blobs).flatten if has_communication_posts? dependencies += people_with_facets + people.map(&:active_storage_blobs).flatten if has_persons? + dependencies += organizations_in_blocks + organizations_in_blocks.map(&:active_storage_blobs).flatten if has_organizations_in_blocks? dependencies += [categories] if has_communication_categories? dependencies += about.git_dependencies(website) if about.present? dependencies diff --git a/app/models/communication/website/index_page.rb b/app/models/communication/website/index_page.rb index 2e11d4a2317138fb6e54aea3c8946a29ebb80a61..4c80742baaf0e5c20f062c70e072ae5a84e4a355 100644 --- a/app/models/communication/website/index_page.rb +++ b/app/models/communication/website/index_page.rb @@ -41,6 +41,7 @@ class Communication::Website::IndexPage < ApplicationRecord legal_terms: 80, sitemap: 81, privacy_policy: 82, + organizations: 90, persons: 100, administrators: 110, authors: 120, diff --git a/app/models/communication/website/menu/item.rb b/app/models/communication/website/menu/item.rb index 4f84f3ebddf63b8241b907e2b7ff9f5028ae8bd2..cc4355371cf5b0138b3ccaa49798e84dcd783d81 100644 --- a/app/models/communication/website/menu/item.rb +++ b/app/models/communication/website/menu/item.rb @@ -58,6 +58,7 @@ class Communication::Website::Menu::Item < ApplicationRecord news: 40, news_category: 41, news_article: 42, + organizations: 45, staff: 50, administrators: 51, authors: 52, diff --git a/app/models/communication/website/menu/item/with_targets.rb b/app/models/communication/website/menu/item/with_targets.rb index 2e83c12458be98cd70bc7e7ee4db2f6480f7b2db..f93175d2f0a2c701b4f5eb9aa98939d0612e1447 100644 --- a/app/models/communication/website/menu/item/with_targets.rb +++ b/app/models/communication/website/menu/item/with_targets.rb @@ -35,6 +35,10 @@ module Communication::Website::Menu::Item::WithTargets "#{website.special_page(:communication_posts).path}#{about.path}".gsub("//", '/') if about end + def target_for_organizations + "#{website.special_page(:organizations).path}" + end + def target_for_staff "#{website.special_page(:persons).path}" end diff --git a/app/models/communication/website/page.rb b/app/models/communication/website/page.rb index a940b3508bb240434c14b4a76e3a1d7ea9448e13..a6446e5da0db183f8f25e06a789c8d2d68c785b5 100644 --- a/app/models/communication/website/page.rb +++ b/app/models/communication/website/page.rb @@ -82,11 +82,20 @@ class Communication::Website::Page < ApplicationRecord after_save :update_children_paths, if: :saved_change_to_path? scope :recent, -> { order(updated_at: :desc).limit(5) } + scope :published, -> { where(published: true) } def generated_path "#{parent&.path}#{slug}/".gsub(/\/+/, '/') end + def path_without_language + if parent_id.present? + "#{parent&.path_without_language}#{slug}/".gsub(/\/+/, '/') + else + "/#{slug}/".gsub(/\/+/, '/') + end + end + def git_path(website) return unless published if kind_home? @@ -106,6 +115,7 @@ class Communication::Website::Page < ApplicationRecord siblings + git_block_dependencies dependencies += website.education_programs if kind_education_programs? + dependencies += [parent] if has_parent? dependencies end diff --git a/app/models/communication/website/page/with_kind.rb b/app/models/communication/website/page/with_kind.rb index 667926934fe5380a9498a4679e9ac6ed815ec718..640d60e836e42258f44e7954a7305978ca99daaf 100644 --- a/app/models/communication/website/page/with_kind.rb +++ b/app/models/communication/website/page/with_kind.rb @@ -12,6 +12,7 @@ module Communication::Website::Page::WithKind legal_terms: 80, sitemap: 81, privacy_policy: 82, + organizations: 90, persons: 100, administrators: 110, authors: 120, @@ -24,6 +25,7 @@ module Communication::Website::Page::WithKind 'education_programs', 'research_articles', 'research_volumes', + 'organizations', 'persons', 'administrators', 'authors', diff --git a/app/models/communication/website/post.rb b/app/models/communication/website/post.rb index 71ca1ad6ee362b58d6d0744b936b825bbb9c8a3e..14cda1e87c58e99446f1e9268fecb73820bcf977 100644 --- a/app/models/communication/website/post.rb +++ b/app/models/communication/website/post.rb @@ -63,6 +63,7 @@ class Communication::Website::Post < ApplicationRecord validates :title, presence: true before_validation :set_published_at, if: :published_changed? + after_save_commit :update_authors_statuses!, if: :saved_change_to_author_id? scope :published, -> { where(published: true) } scope :ordered, -> { order(published_at: :desc, created_at: :desc) } @@ -123,4 +124,12 @@ class Communication::Website::Post < ApplicationRecord def inherited_blob_ids [best_featured_image&.blob_id] end + + def update_authors_statuses! + old_author = University::Person.find_by(id: author_id_before_last_save) + if old_author && old_author.communication_website_posts.none? + old_author.update_and_sync(is_author: false) + end + author.update_and_sync(is_author: true) if author_id + end end diff --git a/app/models/communication/website/with_dependencies.rb b/app/models/communication/website/with_dependencies.rb index 2ee6c344a312b7e5a99ec6d68f09eeabbb82bc9e..c5158c6095581eb50cab223a93a6fb8f3e5a84fa 100644 --- a/app/models/communication/website/with_dependencies.rb +++ b/app/models/communication/website/with_dependencies.rb @@ -61,6 +61,10 @@ module Communication::Website::WithDependencies blocks_dependencies.reject { |dependency| !dependency.is_a? University::Person } end + def organizations_in_blocks + blocks_dependencies.reject { |dependency| !dependency.is_a? University::Organization } + end + def people_with_facets_in_blocks blocks_dependencies.reject { |dependency| !dependency.class.to_s.start_with?('University::Person') } end @@ -114,6 +118,10 @@ module Communication::Website::WithDependencies categories.any? end + def has_organizations? + has_organizations_in_blocks? + end + def has_authors? authors.compact.any? end @@ -122,6 +130,10 @@ module Communication::Website::WithDependencies people_in_blocks.compact.any? end + def has_organizations_in_blocks? + organizations_in_blocks.compact.any? + end + def has_persons? has_authors? || has_administrators? || has_researchers? || has_teachers? || has_people_in_blocks? end diff --git a/app/models/communication/website/with_git_repository.rb b/app/models/communication/website/with_git_repository.rb index 436b1f64ef663f438eff86b1efabc1e93b935e83..1339143e00a5abb1cb3b51e66101999934732bd1 100644 --- a/app/models/communication/website/with_git_repository.rb +++ b/app/models/communication/website/with_git_repository.rb @@ -10,4 +10,18 @@ module Communication::Website::WithGitRepository def git_repository @git_repository ||= Git::Repository.new self end + + def sync_objects_with_git(objects) + touch + return unless git_repository.valid? + objects.each do |object| + next unless object.has_website_for_self?(self) + dependencies = object.git_dependencies(self).to_a.flatten.uniq.compact + dependencies.each do |dependency| + Communication::Website::GitFile.sync self, dependency + end + end + git_repository.sync! + end + handle_asynchronously :sync_objects_with_git, queue: 'default' end diff --git a/app/models/communication/website/with_menu_items.rb b/app/models/communication/website/with_menu_items.rb index 51818072c81d59137a0d1f35bc47f1c359479524..3221927e0af25cf732b530ccf8edc6b3c347083c 100644 --- a/app/models/communication/website/with_menu_items.rb +++ b/app/models/communication/website/with_menu_items.rb @@ -40,6 +40,10 @@ module Communication::Website::WithMenuItems has_communication_posts? end + def menu_item_kind_organizations? + has_organizations? + end + def menu_item_kind_staff? has_persons? end diff --git a/app/models/communication/website/with_special_pages.rb b/app/models/communication/website/with_special_pages.rb index 2b25ff672980cb19bb32673fef4d96ea150135b1..9b898c81fa6bc1ffc53c67360a89cf0acfd2717c 100644 --- a/app/models/communication/website/with_special_pages.rb +++ b/app/models/communication/website/with_special_pages.rb @@ -13,7 +13,7 @@ module Communication::Website::WithSpecialPages def create_missing_special_pages homepage = create_special_page('home') # first level pages with test - ['legal_terms', 'sitemap', 'privacy_policy', 'communication_posts', 'education_programs', 'research_articles', 'research_volumes'].each do |kind| + ['legal_terms', 'sitemap', 'privacy_policy', 'communication_posts', 'education_programs', 'research_articles', 'research_volumes', 'organizations'].each do |kind| create_special_page(kind, homepage.id) if public_send("has_#{kind}?") end # team pages diff --git a/app/models/concerns/importable.rb b/app/models/concerns/importable.rb index 6bc569eef9894ed0082e55ff57a6ceb95c9a7774..e2976a1a2c9b7db5f8a6668628923a241e5333cd 100644 --- a/app/models/concerns/importable.rb +++ b/app/models/concerns/importable.rb @@ -6,7 +6,7 @@ module Importable has_one_attached :file - after_save :parse_async + after_commit :parse_async end def lines diff --git a/app/models/concerns/with_git.rb b/app/models/concerns/with_git.rb index 174e5b227789f34b95b0bd1d5f1baf3ec1646eca..0b6845c2e1381f48f5c50a4c527cc665a2e28ce0 100644 --- a/app/models/concerns/with_git.rb +++ b/app/models/concerns/with_git.rb @@ -64,6 +64,18 @@ module WithGit end end + def has_website_for_self?(website) + websites_for_self.include?(website) + end + + def git_dependencies(website = nil) + [self] + end + + def git_destroy_dependencies(website = nil) + [self] + end + protected def in_block_dependencies?(website) @@ -83,12 +95,4 @@ module WithGit [] end end - - def git_dependencies(website = nil) - [self] - end - - def git_destroy_dependencies(website = nil) - [self] - end end diff --git a/app/models/education/academic_year.rb b/app/models/education/academic_year.rb index 42878678e309e949e9123a3fd43c8270ae39c61d..ac89369971fb7286c5a8a2b490707b66089b7be3 100644 --- a/app/models/education/academic_year.rb +++ b/app/models/education/academic_year.rb @@ -21,6 +21,11 @@ class Education::AcademicYear < ApplicationRecord has_many :cohorts, class_name: 'Education::Cohort' + # Dénormalisation des alumni pour le faceted search + has_and_belongs_to_many :university_people, + class_name: 'University::Person', + foreign_key: 'education_academic_year_id', + association_foreign_key: 'university_person_id' has_many :people, class_name: 'University::Person', through: :cohorts diff --git a/app/models/education/program.rb b/app/models/education/program.rb index 77e3ae32d26ff26481939a0dae5cdb59d3f3d4bb..ef9465eacc3b327140cc2a88e74bc047f0d8cd9f 100644 --- a/app/models/education/program.rb +++ b/app/models/education/program.rb @@ -107,16 +107,39 @@ class Education::Program < ApplicationRecord join_table: 'education_programs_schools', foreign_key: 'education_program_id', association_foreign_key: 'education_school_id' + has_many :websites, + -> { distinct }, + through: :schools + has_many :cohorts, class_name: 'Education::Cohort' - has_many :websites, -> { distinct }, - through: :schools + has_many :alumni, through: :cohorts, source: :people + + has_many :alumni_experiences, + -> { distinct }, + class_name: 'University::Person::Experience', + through: :alumni, + source: :experiences + alias_attribute :experiences, :alumni_experiences + + has_many :alumni_organizations, + -> { distinct }, + class_name: 'University::Organization', + through: :alumni_experiences, + source: :organization + has_many :academic_years, through: :cohorts + # Dénormalisation des alumni pour le faceted search + has_and_belongs_to_many :university_people, + class_name: 'University::Person', + foreign_key: 'education_program_id', + association_foreign_key: 'university_person_id' + accepts_nested_attributes_for :university_person_involvements, reject_if: :all_blank, allow_destroy: true enum level: { diff --git a/app/models/education/school.rb b/app/models/education/school.rb index b5150fba513b7feeb0d2a5f36f469faa8f38cb7f..7149a637cd8a0e01c63cf649c937a507b9114acd 100644 --- a/app/models/education/school.rb +++ b/app/models/education/school.rb @@ -69,6 +69,18 @@ class Education::School < ApplicationRecord has_many :alumni, -> { distinct }, through: :programs + has_many :alumni_experiences, + -> { distinct }, + class_name: 'University::Person::Experience', + through: :alumni, + source: :experiences + alias_attribute :experiences, :alumni_experiences + + has_many :alumni_organizations, + -> { distinct }, + class_name: 'University::Organization', + through: :alumni_experiences, + source: :organization has_many :academic_years, -> { distinct }, through: :programs diff --git a/app/models/university/organization.rb b/app/models/university/organization.rb index 7dd4201622409c85aed1ef46a1dfea5d035422b2..84a53aad21506c275584084e02c0f77aad848d52 100644 --- a/app/models/university/organization.rb +++ b/app/models/university/organization.rb @@ -54,6 +54,16 @@ class University::Organization < ApplicationRecord government: 30 } + def git_dependencies(website) + dependencies = [] + if for_website?(website) + dependencies << self + dependencies.concat active_storage_blobs + end + dependencies += website.menus.to_a + dependencies + end + def websites university.communication_websites end diff --git a/app/models/university/person.rb b/app/models/university/person.rb index acc1f2dd895d59c7d5de7ae81e64c93e1cb05fec..df746435d0c942f8e57ccaa90a477fb3029f96c6 100644 --- a/app/models/university/person.rb +++ b/app/models/university/person.rb @@ -11,10 +11,12 @@ # habilitation :boolean default(FALSE) # is_administration :boolean # is_alumnus :boolean default(FALSE) +# is_author :boolean # is_researcher :boolean # is_teacher :boolean # last_name :string # linkedin :string +# name :string # phone :string # slug :string # tenure :boolean default(FALSE) @@ -44,6 +46,14 @@ class University::Person < ApplicationRecord include WithPicture include WithEducation + LIST_OF_ROLES = [ + :administration, + :teacher, + :researcher, + :alumnus, + :author + ].freeze + has_summernote :biography belongs_to :user, optional: true @@ -87,8 +97,6 @@ class University::Person < ApplicationRecord through: :education_programs, source: :websites - has_many :experiences - accepts_nested_attributes_for :involvements validates_presence_of :first_name, :last_name @@ -101,29 +109,41 @@ class University::Person < ApplicationRecord allow_blank: true, if: :will_save_change_to_email? - before_validation :sanitize_email + before_validation :sanitize_email, :prepare_name scope :ordered, -> { order(:last_name, :first_name) } scope :administration, -> { where(is_administration: true) } scope :teachers, -> { where(is_teacher: true) } scope :researchers, -> { where(is_researcher: true) } scope :alumni, -> { where(is_alumnus: true) } + scope :for_role, -> (role) { where("is_#{role}": true) } + + scope :for_search_term, -> (term) { + where(" + unaccent(concat(university_people.first_name, ' ', university_people.last_name)) ILIKE unaccent(:term) OR + unaccent(concat(university_people.last_name, ' ', university_people.first_name)) ILIKE unaccent(:term) OR + unaccent(university_people.first_name) ILIKE unaccent(:term) OR + unaccent(university_people.last_name) ILIKE unaccent(:term) OR + unaccent(university_people.email) ILIKE unaccent(:term) OR + unaccent(university_people.phone) ILIKE unaccent(:term) OR + unaccent(university_people.biography) ILIKE unaccent(:term) OR + unaccent(university_people.description) ILIKE unaccent(:term) OR + unaccent(university_people.description_short) ILIKE unaccent(:term) OR + unaccent(university_people.twitter) ILIKE unaccent(:term) OR + unaccent(university_people.url) ILIKE unaccent(:term) + ", term: "%#{sanitize_sql_like(term)}%") + } def to_s "#{first_name} #{last_name}" end def roles - [:administration, :teacher, :researcher, :alumnus, :author].reject do |role| + LIST_OF_ROLES.reject do |role| ! send "is_#{role}" end end - # TODO denormalize - def is_author - communication_website_posts.any? - end - def websites university.communication_websites end @@ -133,7 +153,7 @@ class University::Person < ApplicationRecord end def git_dependencies(website) - dependencies = website.menus.to_a + dependencies = [] if for_website?(website) dependencies << self dependencies.concat active_storage_blobs @@ -142,6 +162,7 @@ class University::Person < ApplicationRecord dependencies << author if author.for_website?(website) dependencies << researcher if researcher.for_website?(website) dependencies << teacher if teacher.for_website?(website) + dependencies += website.menus.to_a dependencies end @@ -182,4 +203,8 @@ class University::Person < ApplicationRecord def sanitize_email self.email = self.email.to_s.downcase.strip end + + def prepare_name + self.name = to_s + end end diff --git a/app/models/university/person/administrator.rb b/app/models/university/person/administrator.rb index f5fda080ad57e31d179660161ba2567f1bf4b526..387c93a640f1446247ac545493cbc6ab290b2d42 100644 --- a/app/models/university/person/administrator.rb +++ b/app/models/university/person/administrator.rb @@ -11,10 +11,12 @@ # habilitation :boolean default(FALSE) # is_administration :boolean # is_alumnus :boolean default(FALSE) +# is_author :boolean # is_researcher :boolean # is_teacher :boolean # last_name :string # linkedin :string +# name :string # phone :string # slug :string # tenure :boolean default(FALSE) diff --git a/app/models/university/person/alumnus.rb b/app/models/university/person/alumnus.rb index 06c70f24cd3fd7a02f2ecd63a47a35dd48ed660a..2e140c8c5a3c4c64f2172aea733483431d94cc74 100644 --- a/app/models/university/person/alumnus.rb +++ b/app/models/university/person/alumnus.rb @@ -11,10 +11,12 @@ # habilitation :boolean default(FALSE) # is_administration :boolean # is_alumnus :boolean default(FALSE) +# is_author :boolean # is_researcher :boolean # is_teacher :boolean # last_name :string # linkedin :string +# name :string # phone :string # slug :string # tenure :boolean default(FALSE) diff --git a/app/models/university/person/alumnus/facets.rb b/app/models/university/person/alumnus/facets.rb new file mode 100644 index 0000000000000000000000000000000000000000..cd98815f4885f7ebaea5ab3608f4cb379c0080a3 --- /dev/null +++ b/app/models/university/person/alumnus/facets.rb @@ -0,0 +1,24 @@ +class University::Person::Alumnus::Facets < FacetedSearch::Facets + def initialize(params, options) + super params + + @model = options[:model] + @about = options[:about] + + filter_with_text :name, { + title: University::Person.human_attribute_name('name') + } + + filter_with_list :diploma_years, { + source: @about.academic_years.ordered, + title: Education::AcademicYear.model_name.human(count: 2), + habtm: true + } + + filter_with_list :diploma_programs, { + source: @about.programs.ordered, + title: Education::Program.model_name.human(count: 2), + habtm: true + } unless @about.is_a? Education::Program + end +end diff --git a/app/models/university/person/alumnus/import.rb b/app/models/university/person/alumnus/import.rb index f8a05b767bb3d6168450dff2c1e1dbc205ba63c5..6da4f7198ebb804489d97287313c3f89bc247bba 100644 --- a/app/models/university/person/alumnus/import.rb +++ b/app/models/university/person/alumnus/import.rb @@ -87,7 +87,7 @@ class University::Person::Alumnus::Import < ApplicationRecord person.phone ||= row['phone_professional'] byebug unless person.valid? person.save - cohort.people << person unless person.in?(cohort.people) + person.add_to_cohort cohort add_picture person, row['photo'] company_name = clean_encoding row['company_name'] diff --git a/app/models/university/person/author.rb b/app/models/university/person/author.rb index 67dda6a6e289d65603bd5184ad345b06e76283db..a51eadb10d87ba126e899071f130495f7b315e13 100644 --- a/app/models/university/person/author.rb +++ b/app/models/university/person/author.rb @@ -11,10 +11,12 @@ # habilitation :boolean default(FALSE) # is_administration :boolean # is_alumnus :boolean default(FALSE) +# is_author :boolean # is_researcher :boolean # is_teacher :boolean # last_name :string # linkedin :string +# name :string # phone :string # slug :string # tenure :boolean default(FALSE) diff --git a/app/models/university/person/researcher.rb b/app/models/university/person/researcher.rb index 8fffe668f473cf48fa7237a2d68500b78c507ec1..44616e8492facc2bcb1908e8519bdcccff2d8bac 100644 --- a/app/models/university/person/researcher.rb +++ b/app/models/university/person/researcher.rb @@ -11,10 +11,12 @@ # habilitation :boolean default(FALSE) # is_administration :boolean # is_alumnus :boolean default(FALSE) +# is_author :boolean # is_researcher :boolean # is_teacher :boolean # last_name :string # linkedin :string +# name :string # phone :string # slug :string # tenure :boolean default(FALSE) diff --git a/app/models/university/person/teacher.rb b/app/models/university/person/teacher.rb index df1e88803e668e76624ea44562d02825c1e7ccad..37140ba7b1d670cda457627f9b6feeccffbceb18 100644 --- a/app/models/university/person/teacher.rb +++ b/app/models/university/person/teacher.rb @@ -11,10 +11,12 @@ # habilitation :boolean default(FALSE) # is_administration :boolean # is_alumnus :boolean default(FALSE) +# is_author :boolean # is_researcher :boolean # is_teacher :boolean # last_name :string # linkedin :string +# name :string # phone :string # slug :string # tenure :boolean default(FALSE) diff --git a/app/models/university/person/with_education.rb b/app/models/university/person/with_education.rb index 049d08f97bfa94e462c09995152b1430e9f8b52c..7ceb01ad43e2e20804028b45194de4c4d33be261 100644 --- a/app/models/university/person/with_education.rb +++ b/app/models/university/person/with_education.rb @@ -2,20 +2,32 @@ module University::Person::WithEducation extend ActiveSupport::Concern included do - has_many :involvements_as_teacher, - -> { where(kind: 'teacher') }, - class_name: 'University::Person::Involvement', - dependent: :destroy + has_many :involvements_as_teacher, + -> { where(kind: 'teacher') }, + class_name: 'University::Person::Involvement', + dependent: :destroy - has_many :education_programs_as_teacher, - through: :involvements_as_teacher, - source: :target, - source_type: "Education::Program" + has_many :education_programs_as_teacher, + through: :involvements_as_teacher, + source: :target, + source_type: "Education::Program" + + has_many :experiences has_and_belongs_to_many :cohorts, class_name: 'Education::Cohort', foreign_key: 'university_person_id', association_foreign_key: 'education_cohort_id' + + # Dénormalisation des liens via cohorts, pour la recherche par facettes + has_and_belongs_to_many :diploma_years, + class_name: 'Education::AcademicYear', + foreign_key: 'university_person_id', + association_foreign_key: 'education_academic_year_id' + has_and_belongs_to_many :diploma_programs, + class_name: 'Education::Program', + foreign_key: 'university_person_id', + association_foreign_key: 'education_program_id' end def education_programs_as_administrator @@ -24,4 +36,10 @@ module University::Person::WithEducation .where(university_person_involvements: { person_id: id }) .distinct end + + def add_to_cohort(cohort) + cohorts << cohort unless cohort.in?(cohorts) + diploma_years << cohort.academic_year unless cohort.academic_year.in? diploma_years + diploma_programs << cohort.program unless cohort.program.in? diploma_programs + end end diff --git a/app/models/university/with_communication.rb b/app/models/university/with_communication.rb index ccf765d5ec5650ef9e4e1b17c7f0806e43a16f26..c43441eb8296b3480d6994078aacc5c6eba5e12e 100644 --- a/app/models/university/with_communication.rb +++ b/app/models/university/with_communication.rb @@ -2,8 +2,19 @@ module University::WithCommunication extend ActiveSupport::Concern included do - has_many :communication_extranets, class_name: 'Communication::Extranet', dependent: :destroy - has_many :communication_websites, class_name: 'Communication::Website', dependent: :destroy - has_many :communication_blocks, class_name: 'Communication::Block', dependent: :destroy + has_many :communication_extranets, + class_name: 'Communication::Extranet', + dependent: :destroy + alias_attribute :extranets, :communication_extranets + + has_many :communication_websites, + class_name: 'Communication::Website', + dependent: :destroy + alias_attribute :websites, :communication_websites + + has_many :communication_blocks, + class_name: 'Communication::Block', + dependent: :destroy + alias_attribute :blocks, :communication_blocks end end diff --git a/app/models/university/with_education.rb b/app/models/university/with_education.rb index eab20006b33a912ae68713ef3a0d3892eb1fa1c8..95b2d605b02dcbfa2fc723b00573f8804211766d 100644 --- a/app/models/university/with_education.rb +++ b/app/models/university/with_education.rb @@ -2,9 +2,24 @@ module University::WithEducation extend ActiveSupport::Concern included do - has_many :education_cohorts, class_name: 'Education::Cohort', dependent: :destroy - has_many :education_programs, class_name: 'Education::Program', dependent: :destroy - has_many :education_schools, class_name: 'Education::School', dependent: :destroy - has_many :academic_years, class_name: 'Education::AcademicYear', dependent: :destroy + has_many :education_cohorts, + class_name: 'Education::Cohort', + dependent: :destroy + alias_attribute :cohorts, :education_cohorts + + has_many :education_programs, + class_name: 'Education::Program', + dependent: :destroy + alias_attribute :programs, :education_programs + + has_many :education_schools, + class_name: 'Education::School', + dependent: :destroy + alias_attribute :schools, :education_schools + + has_many :education_academic_years, + class_name: 'Education::AcademicYear', + dependent: :destroy + alias_attribute :academic_years, :education_academic_years end end diff --git a/app/models/university/with_people_and_organizations.rb b/app/models/university/with_people_and_organizations.rb index ad270f63a8638aaef1549a029877ca523464715c..ad18670f9ec33a65633aeeababacedfa66545254 100644 --- a/app/models/university/with_people_and_organizations.rb +++ b/app/models/university/with_people_and_organizations.rb @@ -2,17 +2,25 @@ module University::WithPeopleAndOrganizations extend ActiveSupport::Concern included do - has_many :people, + has_many :university_people, class_name: 'University::Person', dependent: :destroy - has_many :organizations, + alias_attribute :people, :university_people + + has_many :university_organizations, class_name: 'University::Organization', dependent: :destroy - has_many :organization_imports, + alias_attribute :organizations, :university_organizations + + has_many :university_organization_imports, class_name: 'University::Organization::Import', dependent: :destroy - has_many :person_alumnus_imports, + alias_attribute :organization_imports, :university_organization_imports + + has_many :university_person_alumnus_imports, class_name: 'University::Person::Alumnus::Import', dependent: :destroy + alias_attribute :person_alumnus_imports, :university_person_alumnus_imports + alias_attribute :alumnus_imports, :university_person_alumnus_imports end end diff --git a/app/models/user/with_roles.rb b/app/models/user/with_roles.rb index d4c44a698838bf3c44b776ac95bb1e68663401e6..bd1ef525c6855098e33165289fe5546817a311dc 100644 --- a/app/models/user/with_roles.rb +++ b/app/models/user/with_roles.rb @@ -4,7 +4,7 @@ module User::WithRoles included do attr_accessor :modified_by - enum role: { visitor: 0, teacher: 10, program_manager: 12, website_manager: 15, admin: 20, server_admin: 30 } + enum role: { visitor: 0, contributor: 4, author: 5, teacher: 10, program_manager: 12, website_manager: 15, admin: 20, server_admin: 30 } has_and_belongs_to_many :programs_to_manage, class_name: 'Education::Program', @@ -22,7 +22,7 @@ module User::WithRoles before_validation :check_modifier_role def self.roles_with_access_to_global_menu - roles.keys - ["website_manager"] + roles.keys - ['contributor', 'author', 'website_manager'] end def managed_roles diff --git a/app/services/filters/admin/university/people.rb b/app/services/filters/admin/university/people.rb new file mode 100644 index 0000000000000000000000000000000000000000..515697eafa3b0dc4ec161cd5d6715c283f5d9e02 --- /dev/null +++ b/app/services/filters/admin/university/people.rb @@ -0,0 +1,9 @@ +module Filters + class Admin::University::People < Filters::Base + def initialize(user) + super + add_search + add :for_role, ::University::Person::LIST_OF_ROLES.map { |r| { to_s: I18n.t("activerecord.attributes.university/person.#{r}"), id: r } }, I18n.t('filters.attributes.role') + end + end +end diff --git a/app/services/filters/admin/users.rb b/app/services/filters/admin/users.rb new file mode 100644 index 0000000000000000000000000000000000000000..bc431fa8eccedc0ecb727251214081bd884eeb65 --- /dev/null +++ b/app/services/filters/admin/users.rb @@ -0,0 +1,9 @@ +module Filters + class Admin::Users < Filters::Base + def initialize(user) + super + add_search + add :for_role, ::User.roles.keys.map { |r| { to_s: I18n.t("activerecord.attributes.user.roles.#{r}"), id: r } }, I18n.t('filters.attributes.role') + end + end +end diff --git a/app/services/filters/user.rb b/app/services/filters/user.rb deleted file mode 100644 index a71e11effad3718dc0f3e890188e92e6ec83c9e1..0000000000000000000000000000000000000000 --- a/app/services/filters/user.rb +++ /dev/null @@ -1,9 +0,0 @@ -module Filters - class User < Base - def initialize(user) - super - add_search - add :for_role, ::User.roles.keys.map { |r| { to_s: r.humanize, id: r } }, I18n.t('filters.attributes.role') - end - end -end diff --git a/app/views/admin/communication/extranets/show.html.erb b/app/views/admin/communication/extranets/show.html.erb index 23351aae9e712411b746a634e6a4ca210a92f79d..1a270a1963698411e4cee1326a69b7202cba0cf3 100644 --- a/app/views/admin/communication/extranets/show.html.erb +++ b/app/views/admin/communication/extranets/show.html.erb @@ -28,6 +28,12 @@ <%= Education::AcademicYear.model_name.human(count: @years.count).downcase %> </p> <% end %> +<% if @organizations %> + <p> + <%= @organizations.count %> + <%= University::Organization.model_name.human(count: @organizations.count).downcase %> + </p> +<% end %> <% content_for :action_bar_right do %> <%= edit_link @extranet %> diff --git a/app/views/admin/communication/website/configs/permalinks/static.html.erb b/app/views/admin/communication/website/configs/permalinks/static.html.erb index 9a5be71d01c728a12f20c386e8a90ca75bafee5d..ea940c61321255d1a68a1ae7fc885a70290eddc9 100644 --- a/app/views/admin/communication/website/configs/permalinks/static.html.erb +++ b/app/views/admin/communication/website/configs/permalinks/static.html.erb @@ -1,22 +1,22 @@ <% if @website.has_communication_posts? %> -posts: <%= @website.special_page(:communication_posts).path %>/:year/:month/:day/:slug/ +posts: <%= @website.special_page(:communication_posts).path_without_language %>:year/:month/:day/:slug/ <% end %> <% if @website.has_communication_categories? %> -categories: <%= @website.special_page(:communication_posts).path %>/:slug/ +categories: <%= @website.special_page(:communication_posts).path_without_language %>:slug/ <% end %> <% if @website.has_persons? %> -persons: <%= @website.special_page(:persons).path %>/:slug/ +persons: <%= @website.special_page(:persons).path_without_language %>:slug/ <% end %> <% if @website.has_authors? %> -authors: <%= @website.special_page(:persons).path %>/:slug/<%= @website.special_page(:communication_posts).slug %>/ +authors: <%= @website.special_page(:persons).path_without_language %>:slug/<%= @website.special_page(:communication_posts).slug %>/ <% end %> -<%# ces paths complémentaires sont nécessairesà Hugo mais on ne les utilise pas %> +<%# ces paths complémentaires sont nécessaires à Hugo mais on ne les utilise pas %> <% if @website.has_administrators? %> -administrators: <%= @website.special_page(:persons).path %>/:slug/roles/ +administrators: <%= @website.special_page(:persons).path_without_language %>:slug/roles/ <% end %> <% if @website.has_teachers? %> -teachers: <%= @website.special_page(:persons).path %>/:slug/programs/ +teachers: <%= @website.special_page(:persons).path_without_language %>:slug/programs/ <% end %> <% if @website.has_researchers? %> -researchers: <%= @website.special_page(:persons).path %>/:slug/articles/ +researchers: <%= @website.special_page(:persons).path_without_language %>:slug/articles/ <% end %> diff --git a/app/views/admin/communication/website/pages/_form.html.erb b/app/views/admin/communication/website/pages/_form.html.erb index 778a032fcc13267e60cbcf9b1b7b7a4ddfbb2adf..16ce0f956b5a3c56da1e761e41ecd0c02f534e4c 100644 --- a/app/views/admin/communication/website/pages/_form.html.erb +++ b/app/views/admin/communication/website/pages/_form.html.erb @@ -8,7 +8,7 @@ <div class="card-body"> <%= f.input :title %> <%= f.input :breadcrumb_title %> - <%= f.input :description_short %> + <%= f.input :description_short, input_html: { value: page.description_short&.gsub('&', '&') } %> <%= f.input :header_text, as: :summernote, input_html: { diff --git a/app/views/admin/communication/website/pages/show.html.erb b/app/views/admin/communication/website/pages/show.html.erb index c29dbc0f40a4c4da54ff7353c37eeb89435d9907..c21247fd9894e5bd6375e7431b857d2a463e67d0 100644 --- a/app/views/admin/communication/website/pages/show.html.erb +++ b/app/views/admin/communication/website/pages/show.html.erb @@ -4,6 +4,16 @@ <div class="row"> <div class="col-md-8"> + + <% if @page.is_special_page? %> + <div class="card text-white bg-secondary flex-fill w-100"> + <div class="card-body"> + <%= t('admin.communication.website.pages.is_special_page') %> + <b class="text-white"><%= t("communication.website.pages.defaults.#{@page.kind}.admin_description") %></b> + </div> + </div> + <% end %> + <div class="card flex-fill w-100"> <div class="card-header"> <h2 class="card-title mb-0 h5"><%= t('content') %></h2> diff --git a/app/views/admin/communication/website/pages/static.html.erb b/app/views/admin/communication/website/pages/static.html.erb index 305f406207362ad68d420b4111e466a8fa50cab9..4d2c9f2f194ee2dce4bd7c91a775615558f3a377 100644 --- a/app/views/admin/communication/website/pages/static.html.erb +++ b/app/views/admin/communication/website/pages/static.html.erb @@ -9,6 +9,12 @@ bodyclass: <%= @about.best_bodyclass %> image: "<%= @about.best_featured_image.blob.id %>" image_alt: "<%= @about.featured_image_alt %>" <% end %> +<% if @about.children.published.any? %> +children: +<% @about.children.published.ordered.each do |child| %> + - <%= child.path %> +<% end %> +<% end %> <% if @about.related_category %> category: "<%= @about.related_category.path %>" <% end %> diff --git a/app/views/admin/communication/website/posts/_form.html.erb b/app/views/admin/communication/website/posts/_form.html.erb index 32ffdeb4543b4dca0ebb82ff8efb1092f74fcfc0..711e59170816faf4cf6451a67b2a07468456eb87 100644 --- a/app/views/admin/communication/website/posts/_form.html.erb +++ b/app/views/admin/communication/website/posts/_form.html.erb @@ -29,10 +29,16 @@ <% elsif @website.languages.any? %> <%= f.input :language_id, as: :hidden, input_html: { value: @website.languages.first.id }, wrapper: false %> <% end %> - <%= f.input :published %> - <%= f.input :published_at, html5: true %> + <% if can? :publish, post %> + <%= f.input :published %> + <%= f.input :published_at, html5: true %> + <% end %> <%= f.input :pinned %> - <%= f.association :author, collection: current_university.people.ordered %> + <% if current_user.author? || current_user.contributor? %> + <%= f.input :author_id, as: :hidden, input_html: { value: current_user.person&.id }, wrapper: false %> + <% else %> + <%= f.association :author, collection: current_university.people.ordered %> + <% end %> </div> </div> <div class="card flex-fill w-100"> diff --git a/app/views/admin/communication/website/posts/_list.html.erb b/app/views/admin/communication/website/posts/_list.html.erb index 61f78aa6ced46a4de5dcf6c09a939a47100357da..8ebc3a67791990b8cd12e8238044fc6772047791 100644 --- a/app/views/admin/communication/website/posts/_list.html.erb +++ b/app/views/admin/communication/website/posts/_list.html.erb @@ -1,10 +1,16 @@ <% hide_author |= false hide_category |= false + selectable |= false %> -<table class="<%= table_classes %>"> +<table class="<%= table_classes %>" <%= "data-batch-selectable" if selectable %>> <thead> <tr> + <% if selectable %> + <th> + <%= check_box_tag nil, nil, false, data: { batch_selectable_role: "select-all" } %> + </th> + <% end %> <th><%= Communication::Website::Post.human_attribute_name('title') %></th> <th><%= Communication::Website::Post.human_attribute_name('featured_image') %></th> <% unless hide_author %> @@ -20,6 +26,11 @@ <tbody> <% posts.each do |post| %> <tr> + <% if selectable %> + <td> + <%= check_box_tag "ids[]", post.id, false, data: { batch_selectable_role: "select-single" } %> + </td> + <% end %> <td><%= link_to post, admin_communication_website_post_path(website_id: post.website.id, id: post.id), class: "#{'opacity-50' unless post.published?}" %></td> diff --git a/app/views/admin/communication/website/posts/index.html.erb b/app/views/admin/communication/website/posts/index.html.erb index 814a431bf51ab1da6c16ae00eb1bec4d3504f962..7b70ee606cf1881796fadd9d3dadcde245614b32 100644 --- a/app/views/admin/communication/website/posts/index.html.erb +++ b/app/views/admin/communication/website/posts/index.html.erb @@ -2,10 +2,29 @@ <%= render 'admin/communication/websites/sidebar' do %> <div class="card"> - <%= render 'admin/communication/website/posts/list', posts: @posts, hide_author: true %> - <% if @posts.total_pages > 1 %> + <%= form_tag publish_admin_communication_website_posts_path do %> + <input type="hidden" name="ids[]" value=""> + <%= render 'admin/communication/website/posts/list', posts: @posts, selectable: true %> <div class="card-footer"> - <%= paginate @posts, theme: 'bootstrap-5' %> + <% if @posts.total_pages > 1 %> + <div class="float-end"> + <%= paginate @posts, theme: 'bootstrap-5' %> + </div> + <% end %> + <div class="row align-items-center"> + <div class="col-auto"> + Modifier la sélection + </div> + <div class="col-auto"> + <select name="published" class="form-select"> + <option value="false">Non publiée</option> + <option value="true">Publiée</option> + </select> + </div> + <div class="col-auto"> + <input type="submit" value="Enregistrer" class="btn btn-primary"> + </div> + </div> </div> <% end %> </div> diff --git a/app/views/admin/communication/websites/index.html.erb b/app/views/admin/communication/websites/index.html.erb index b4ebe5d3fca6bd2f4b51d1d6521c6ba2ad9c4dd0..a4b8e7879ad34aafd194cf122331daf8d6595a95 100644 --- a/app/views/admin/communication/websites/index.html.erb +++ b/app/views/admin/communication/websites/index.html.erb @@ -16,7 +16,7 @@ <td><%= link_to website, [:admin, website] %></td> <td><%= link_to website.url, website.url, target: :_blank %></td> <td><%= I18n.t("activerecord.attributes.communication/website.about_#{website.about_type}") %></td> - <td><%= link_to website.about, [:admin, website.about] if website.about %></td> + <td><%= link_to_if can?(:read, website.about), website.about, [:admin, website.about] if website.about %></td> <td class="text-end"> <div class="btn-group" role="group"> <%= edit_link website %> diff --git a/app/views/admin/communication/websites/show.html.erb b/app/views/admin/communication/websites/show.html.erb index 5057c724143e0766d113becb013237861bc4dbdc..89747b56bdd697807c6271e9d0733543232323a1 100644 --- a/app/views/admin/communication/websites/show.html.erb +++ b/app/views/admin/communication/websites/show.html.erb @@ -6,7 +6,7 @@ <% end %> <%= I18n.t("activerecord.attributes.communication/website.about_#{@website.about_type}") %> <% if @website.about %> - (<%= link_to @website.about, [:admin, @website.about] unless @website.about.nil? %>) + (<%= link_to_if can?(:read, @website.about), @website.about, [:admin, @website.about] unless @website.about.nil? %>) <% end %> <% end %> diff --git a/app/views/admin/dashboard/index.html.erb b/app/views/admin/dashboard/index.html.erb index 4df287ce4de9a1685862a8367b2e03b4cc29e664..3ce8510ebcbc25717e780df003f37052023eb669 100644 --- a/app/views/admin/dashboard/index.html.erb +++ b/app/views/admin/dashboard/index.html.erb @@ -52,3 +52,22 @@ <% end %> </div> <% end %> + +<% if current_university.communication_extranets.any? && can?(:read, Communication::Extranet) %> + <h2 class="h4 my-4"><%= Communication::Extranet.model_name.human(count: 2) %></h2> + <div class="row"> + <% current_university.communication_extranets.each do |extranet| %> + <% next unless can?(:read, extranet) %> + <div class="col-md-4"> + <div class="card"> + <div class="card-body"> + <span class="float-end"><i class="fas fa-project-diagram fa-2x"></i></span> + <h4><%= extranet %></h4> + <p class="small"><%= extranet.url %></p> + <%= link_to t('show'), [:admin, extranet], class: button_classes('stretched-link') %> + </div> + </div> + </div> + <% end %> + </div> +<% end %> diff --git a/app/views/admin/education/programs/_form.html.erb b/app/views/admin/education/programs/_form.html.erb index 5ee17c146b10ad150a34501f63751edd210a3004..50138adea6e35c294c1a15f9fa8a32c7a55cbf07 100644 --- a/app/views/admin/education/programs/_form.html.erb +++ b/app/views/admin/education/programs/_form.html.erb @@ -58,26 +58,18 @@ </div> <div class="card-body"> <%= render 'admin/education/programs/forms/input_with_inheritance', f: f, property: :presentation %> - <%= render 'admin/education/programs/forms/input_with_inheritance', f: f, property: :registration %> - <%= render 'admin/education/programs/forms/input_with_inheritance', f: f, property: :pricing %> - <%= render 'admin/education/programs/forms/input_with_inheritance', f: f, property: :duration %> - <%= render 'admin/education/programs/forms/input_with_inheritance', f: f, property: :accessibility %> - <%= render 'admin/education/programs/forms/input_with_inheritance', f: f, property: :other %> - </div> - </div> - - <div class="card flex-fill w-100"> - <div class="card-header"> - <h5 class="card-title mb-0"><%= t('education.program.educational_informations') %></h5> - </div> - <div class="card-body"> <%= render 'admin/education/programs/forms/input_with_inheritance', f: f, property: :objectives %> + <%= render 'admin/education/programs/forms/input_with_inheritance', f: f, property: :opportunities %> + <%= render 'admin/education/programs/forms/input_with_inheritance', f: f, property: :results %> + <%= render 'admin/education/programs/forms/input_with_inheritance', f: f, property: :accessibility %> + <%= render 'admin/education/programs/forms/input_with_inheritance', f: f, property: :duration %> + <%= render 'admin/education/programs/forms/input_with_inheritance', f: f, property: :pricing %> <%= render 'admin/education/programs/forms/input_with_inheritance', f: f, property: :content %> - <%= render 'admin/education/programs/forms/input_with_inheritance', f: f, property: :prerequisites %> <%= render 'admin/education/programs/forms/input_with_inheritance', f: f, property: :pedagogy %> <%= render 'admin/education/programs/forms/input_with_inheritance', f: f, property: :evaluation %> - <%= render 'admin/education/programs/forms/input_with_inheritance', f: f, property: :opportunities %> - <%= render 'admin/education/programs/forms/input_with_inheritance', f: f, property: :results %> + <%= render 'admin/education/programs/forms/input_with_inheritance', f: f, property: :prerequisites %> + <%= render 'admin/education/programs/forms/input_with_inheritance', f: f, property: :registration %> + <%= render 'admin/education/programs/forms/input_with_inheritance', f: f, property: :other %> </div> </div> diff --git a/app/views/admin/education/programs/show.html.erb b/app/views/admin/education/programs/show.html.erb index 51064ef1ccb42ed7cfff872bca6f4495356a52f9..906b1a681597d70ac49514cf43195e2d143ca60f 100644 --- a/app/views/admin/education/programs/show.html.erb +++ b/app/views/admin/education/programs/show.html.erb @@ -58,35 +58,23 @@ <div class="card-body"> <% [ :presentation, - :registration, - :pricing, - :duration, - :contacts, + :objectives, + :opportunities, + :results, :accessibility, + :duration, + :pricing, + :content, + :pedagogy, + :evaluation, + :prerequisites, + :registration, :other ].each_with_index do |property, index| %> <%= render 'admin/application/property/text', object: @program, property: property %> <% end %> </div> </div> - <div class="card flex-fill w-100"> - <div class="card-header"> - <h5 class="card-title mb-0"><%= t('education.program.educational_informations') %></h5> - </div> - <div class="card-body"> - <% [ - :objectives, - :content, - :prerequisites, - :pedagogy, - :evaluation, - :opportunities, - :results - ].each do |property| %> - <%= render 'admin/application/property/text', object: @program, property: property %> - <% end %> - </div> - </div> <%= render 'admin/communication/blocks/list', about: @program %> diff --git a/app/views/admin/university/people/index.html.erb b/app/views/admin/university/people/index.html.erb index b95e8aa322d9c79d5f98203b273e6acaa580aea7..df601c13f7ed7424fe37ef9a2f4e46cd067630ee 100644 --- a/app/views/admin/university/people/index.html.erb +++ b/app/views/admin/university/people/index.html.erb @@ -1,5 +1,7 @@ <% content_for :title, "#{University::Person.model_name.human(count: 2)} (#{@people.total_count})" %> +<%= render 'filters', current_path: admin_university_people_path, filters: @filters if @filters.any? %> + <%= render 'admin/university/people/list', people: @people %> <%= paginate @people, theme: 'bootstrap-5' %> diff --git a/app/views/admin/users/_form.html.erb b/app/views/admin/users/_form.html.erb index 6a025d1642892f9c768bfd832951d3f08ad7a777..c2e732e90cea492564749b7fff0bedbecb807356 100644 --- a/app/views/admin/users/_form.html.erb +++ b/app/views/admin/users/_form.html.erb @@ -37,7 +37,7 @@ label_method: ->(p) { sanitize p[:label] }, value_method: ->(p) { p[:id] } %> </div> - <div data-show-for-roles="website_manager"> + <div data-show-for-roles="author,contributor,website_manager"> <%= f.association :websites_to_manage, as: :check_boxes, collection: current_university.communication_websites.ordered diff --git a/app/views/admin/users/index.html.erb b/app/views/admin/users/index.html.erb index af80ff5b3d6d1520db414931e45d74790689756d..1e1ee9d58e0331d332c45fd08d547ff9c80ddef1 100644 --- a/app/views/admin/users/index.html.erb +++ b/app/views/admin/users/index.html.erb @@ -21,7 +21,7 @@ <td><%= link_to user.email, [:admin, user] %></td> <td><%= user.first_name %></td> <td><%= user.last_name %></td> - <td><%= user.role.humanize %></td> + <td><%= t("activerecord.attributes.user.roles.#{user.role}") %></td> <td><%= user.language %></td> <td class="text-end"> <div class="btn-group" role="group"> diff --git a/app/views/extranet/home/index.html.erb b/app/views/extranet/home/index.html.erb index 3a6a045cbdabf5e569b57de4a9afd5061302f7d7..aa3714a7af09b02bc46eaa44c985e84362a29448 100644 --- a/app/views/extranet/home/index.html.erb +++ b/app/views/extranet/home/index.html.erb @@ -2,7 +2,16 @@ <div class="row"> <div class="col-md-8"> - + <h2>Mouvements récents</h2> + <% @experiences.each do |experience| %> + <article> + <%= link_to experience.person, experience.person %> + <%= experience.description %> + <%= experience.from_year %> + <%= experience.to_year %> + <%= link_to experience.organization, experience.organization %> + </article> + <% end %> </div> <div class="col-md-4"> <h2>Promotions actuelles</h2> diff --git a/app/views/extranet/organizations/index.html.erb b/app/views/extranet/organizations/index.html.erb index 5796718de6abe4e3aee343cff839fdb3ac81f74a..b1229875b7627de2122e7d4ec855f4e31c3bd2b2 100644 --- a/app/views/extranet/organizations/index.html.erb +++ b/app/views/extranet/organizations/index.html.erb @@ -2,6 +2,10 @@ <header class="mb-5"> <h1><%= University::Organization.model_name.human(count: 2) %></h1> + <p> + <%= @count %> + <%= University::Organization.model_name.human(count: @count).downcase %> + </p> </header> <table class="<%= table_classes %>"> diff --git a/app/views/extranet/persons/_list.html.erb b/app/views/extranet/persons/_list.html.erb index 7922cd391743569fccc61271a420850d8171c7c8..064c370335f8f7eb06794db58c6ebe770b772ba0 100644 --- a/app/views/extranet/persons/_list.html.erb +++ b/app/views/extranet/persons/_list.html.erb @@ -2,19 +2,7 @@ <div class="row"> <% people_paged.each do |person| %> <div class="col-xxl-2 col-md-3"> - <article class="mb-4 position-relative"> - <% if person.picture.attached? %> - <%= kamifusen_tag person.picture, width: 400, class: 'img-fluid' %> - <% else %> - <%= image_tag 'extranet/avatar.png', width: 400, class: 'img-fluid' %> - <% end %> - <%= link_to person, class: 'stretched-link' do %> - <%= person.first_name %> - <b> - <%= person.last_name %> - </b> - <% end %> - </article> + <%= render 'extranet/persons/person', person: person %> </div> <% end %> </div> diff --git a/app/views/extranet/persons/_person.html.erb b/app/views/extranet/persons/_person.html.erb new file mode 100644 index 0000000000000000000000000000000000000000..f8151bdac4973a6d5355874e2e713a73ded36928 --- /dev/null +++ b/app/views/extranet/persons/_person.html.erb @@ -0,0 +1,11 @@ +<article class="mb-4 position-relative"> + <% if person.picture.attached? %> + <%= kamifusen_tag person.picture, width: 400, class: 'img-fluid' %> + <% else %> + <%= image_tag 'extranet/avatar.png', width: 400, class: 'img-fluid' %> + <% end %> + <%= link_to person, class: 'stretched-link' do %> + <%= person.first_name %> + <b><%= person.last_name %></b> + <% end %> +</article> diff --git a/app/views/extranet/persons/index.html.erb b/app/views/extranet/persons/index.html.erb index f12ba91324d414923362034d30c58f500749eb0c..11b59fcc05a3b300839db66b7ab245544a15c998 100644 --- a/app/views/extranet/persons/index.html.erb +++ b/app/views/extranet/persons/index.html.erb @@ -7,11 +7,26 @@ </div> <div class="col-md-3 text-end"> <p> - <%= @people.count %> - <%= University::Person::Alumnus.model_name.human(count: @people.count).downcase %> + <%= @count %> + <%= University::Person::Alumnus.model_name.human(count: @count).downcase %> </p> </div> </div> </header> -<%= render 'extranet/persons/list', people: @people %> +<div class="row"> + <div class="col-lg-3"> + <%= render 'faceted_search/facets', facets: @facets %> + </div> + <div class="offset-lg-1 col-lg-8"> + <div class="row"> + <% @people.each do |person| %> + <div class="col-xxl-3 col-md-4 col-sm-6"> + <%= render 'extranet/persons/person', person: person %> + </div> + <% end %> + </div> + <%= paginate @people, theme: 'bootstrap-5' %> + + </div> +</div> diff --git a/config/admin_navigation.rb b/config/admin_navigation.rb index b2d084377f0c423b281c766a43c531a1d87449ed..4fccef35596f4b3505cad976350d55b20d6c6fdd 100644 --- a/config/admin_navigation.rb +++ b/config/admin_navigation.rb @@ -34,7 +34,7 @@ SimpleNavigation::Configuration.run do |navigation| if can?(:read, Communication::Website) primary.item :communication, Communication.model_name.human, nil, { kind: :header } primary.item :communication_websites, Communication::Website.model_name.human(count: 2), admin_communication_websites_path, { icon: 'sitemap' } if can?(:read, Communication::Website) - primary.item :communication_extranets, Communication::Extranet.model_name.human(count: 2), admin_communication_extranets_path, { icon: 'project-diagram' } + primary.item :communication_extranets, Communication::Extranet.model_name.human(count: 2), admin_communication_extranets_path, { icon: 'project-diagram' } if can?(:read, Communication::Extranet) primary.item :communication_newsletters, 'Lettres d\'information', nil, { icon: 'envelope' } end diff --git a/config/initializers/active_storage.rb b/config/initializers/active_storage.rb index 09d7980d77629f465a5144e2a5da55eca12d60dd..89b6ff7a9e5abf6fae93de9a005c937736b1cd79 100644 --- a/config/initializers/active_storage.rb +++ b/config/initializers/active_storage.rb @@ -33,22 +33,23 @@ ActiveStorage::Filename.class_eval do end end -module ActiveStorageGitPathStatic - extend ActiveSupport::Concern +# https://stackoverflow.com/questions/8895103/how-can-i-keep-my-initializer-configuration-from-being-lost-in-development-mode +Rails.application.config.to_prepare do + module ActiveStorageGitPathStatic + extend ActiveSupport::Concern - included do - has_many :git_files, class_name: "Communication::Website::GitFile", as: :about, dependent: :destroy - end + included do + has_many :git_files, class_name: "Communication::Website::GitFile", as: :about, dependent: :destroy + end - def git_path(website) - "data/media/#{id[0..1]}/#{id}.yml" - end + def git_path(website) + "data/media/#{id[0..1]}/#{id}.yml" + end - def before_git_sync - analyze unless analyzed? + def before_git_sync + analyze unless analyzed? + end end -end -ActiveSupport::Reloader.to_prepare do ActiveStorage::Blob.include ActiveStorageGitPathStatic end diff --git a/config/locales/communication/en.yml b/config/locales/communication/en.yml index c30154843ee00dee1e5a0e5cd87dfd963e647f4e..abc8d02429e9f58c9aa1d78ffc061aff0291ebc7 100644 --- a/config/locales/communication/en.yml +++ b/config/locales/communication/en.yml @@ -200,6 +200,7 @@ en: website: pages: delete_special_page_notice: Can't delete this page + is_special_page: "This is a page with a special behaviour:" structure: Structure communication: authors: @@ -228,54 +229,72 @@ en: pages: defaults: administrators: + admin_description: list of members in the administrative team description_short: List of members in the administrative team slug: administrative-team title: Administrative team authors: + admin_description: list of members in the editorial team description_short: List of members in the editorial team slug: editorial-team title: Editorial team communication_posts: + admin_description: list of posts description_short: List of posts slug: posts title: Posts education_programs: + admin_description: list of available programs description_short: List of available programs slug: programs title: Programs home: + admin_description: homepage description_short: '' slug: '' title: Home legal_terms: + admin_description: legal terms page description_short: '' slug: legal-terms title: Legal terms + organizations: + admin_description: third parties page + description_short: List of third parties + slug: third-parties + title: Third parties persons: + admin_description: list of members in the team description_short: List of members in the team slug: team title: Team privacy_policy: + admin_description: privacy policy page description_short: '' slug: privacy-policy title: Privacy policy research_articles: + admin_description: list of articles description_short: List of articles slug: articles title: Articles research_volumes: + admin_description: list of volumes description_short: List of volumes slug: volumes title: Volumes researchers: + admin_description: list of members in the research team description_short: List of members in the research team slug: research-team title: Research team sitemap: + admin_description: sitemap page description_short: '' slug: sitemap title: Sitemap teachers: + admin_description: list of members in the educational team description_short: List of members in the educational team slug: educational-team title: Educational team @@ -306,6 +325,7 @@ en: news: News index news_article: Specific news news_category: News category + organizations: Third parties index page: Specific Page program: Specific program programs: Programs index diff --git a/config/locales/communication/fr.yml b/config/locales/communication/fr.yml index bfe0320142a52322982ce96afc50a62a73c11e71..95e7e7433936da3b83b4242f8c7120dd733ed574 100644 --- a/config/locales/communication/fr.yml +++ b/config/locales/communication/fr.yml @@ -202,6 +202,7 @@ fr: website: pages: delete_special_page_notice: Impossible de supprimer cette page + is_special_page: "Ceci est une page avec un comportement spécial :" structure: Arborescence communication: authors: @@ -230,59 +231,78 @@ fr: pages: defaults: administrators: + admin_description: liste des membres de l'équipe administrative description_short: Liste des membres de l'équipe administrative slug: equipe-administrative title: Équipe administrative authors: + admin_description: liste des membres de l'équipe éditoriale description_short: Liste des membres de l'équipe éditoriale slug: equipe-editoriale title: Équipe éditoriale communication_posts: + admin_description: liste des actualités description_short: Liste des actualités slug: actualites title: Actualités education_programs: + admin_description: liste des formations proposées description_short: Liste des formations proposées slug: offre-de-formation title: "L'offre de formation" home: + admin_description: page d'accueil du site description_short: '' slug: '' title: Accueil legal_terms: + admin_description: page des mentions légales description_short: '' slug: mentions-legales title: Mentions légales + organizations: + admin_description: page des tierces parties + description_short: Liste des tierces parties + slug: tierces-parties + title: Tierces parties persons: + admin_description: liste des membres de l'équipe description_short: Liste des membres de l'équipe slug: equipe title: Équipe privacy_policy: + admin_description: page de la politique de confidentialité description_short: '' slug: politique-de-confidentialite title: Politique de confidentialité research_articles: + admin_description: liste des articles description_short: Liste des articles slug: articles title: Articles research_volumes: + admin_description: liste des volumes description_short: Liste des volumes slug: volumes title: Volumes researchers: + admin_description: liste des membres de l'équipe de recherche description_short: Liste des membres de l'équipe de recherche slug: equipe-de-recherche title: Équipe de recherche sitemap: + admin_description: page plan du site description_short: '' slug: plan-du-site title: Plan du site teachers: + admin_description: liste des membres de l'équipe pédagogique description_short: Liste des membres de l'équipe pédagogique slug: equipe-pedagogique title: Équipe pédagogique posts: new_curation: Nouvelle curation + successful_batch_update: Les actualités ont bien été mises à jour see_all: Voir la liste complète (%{number} éléments) enums: communication: @@ -308,6 +328,7 @@ fr: news: Liste des actualités news_article: Actualité spécifique news_category: Catégorie d'actualités + organizations: Liste des tierces parties page: Page spécifique program: Formation spécifique programs: Liste des formations diff --git a/config/locales/en.yml b/config/locales/en.yml index a07167520f99ab724299d056b8e36c63660e76e4..49586fa67c5b553e343b068df01bb7d30bb144ed 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -16,11 +16,14 @@ en: role: Role roles: admin: Administrator + author: Author + contributor: Contributor program_manager: Program manager server_admin: Server admin teacher: Teacher visitor: Visitor website_manager: Website manager + websites_to_manage: Websites managed errors: models: user: diff --git a/config/locales/fr.yml b/config/locales/fr.yml index cfb4f9c6e825a5e1a49203a8d982ad65e2e16602..2963ff7588bcd53d3ef6666f8267e72bb08564de 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -16,11 +16,14 @@ fr: role: Rôle roles: admin: Administrateur + author: Auteur + contributor: Contributeur program_manager: Responsable de formation server_admin: Administrateur du serveur teacher: Enseignant·e visitor: Visiteur website_manager: Responsable de site web + websites_to_manage: Sites gérés errors: models: user: diff --git a/config/locales/university/en.yml b/config/locales/university/en.yml index 7762500fbf91d803ec8cc59e4c2d96097239854c..dcd43222b31c92c6049f9ab1ea77c12c41bc0948 100644 --- a/config/locales/university/en.yml +++ b/config/locales/university/en.yml @@ -18,6 +18,9 @@ en: zipcode: Zipcode university/person: abilities: Abilities + administration: Administrative staff + alumnus: Alumnus + author: Author biography: Biography communication_website_posts: Posts description: Meta Description @@ -37,8 +40,11 @@ en: phone: Phone picture: Profile picture research_journal_articles: Articles + researcher: Researcher + roles: Roles slug: Slug socials: Socials + teacher: Teacher tenure: Has tenure? twitter: Twitter username url: Website @@ -82,8 +88,8 @@ en: one: Alumnus other: Alumni university/organization: - one: Third party - other: Third parties + one: Organization + other: Organizations university/organization/import: one: Import other: Imports diff --git a/config/locales/university/fr.yml b/config/locales/university/fr.yml index 26e9ee1d95282668b412c266859bba48e2c1eac9..a401225ae0a8c5cf267e499a01385dd8b14804fe 100644 --- a/config/locales/university/fr.yml +++ b/config/locales/university/fr.yml @@ -18,6 +18,9 @@ fr: zipcode: Code postal university/person: abilities: Responsabilités + administration: Personnel administratif + alumnus: Alumnus + author: Auteur·rice biography: Biographie communication_website_posts: Actualités description: Meta Description @@ -31,19 +34,17 @@ fr: is_author: Auteur·rice is_researcher: Chercheur·se is_teacher: Enseignant·e - administration: Personnel administratif - alumnus: Alumnus - author: Auteur·rice - researcher: Chercheur·se - teacher: Enseignant·e last_name: Nom de famille linkedin: LinkedIn (URL) name: Nom phone: Téléphone picture: Photo de profil research_journal_articles: Articles + researcher: Chercheur·se + roles: Rôles slug: Slug socials: Réseaux sociaux + teacher: Enseignant·e tenure: Titulaire ? twitter: Twitter (nom d'utilisateur) url: Site web @@ -87,8 +88,8 @@ fr: one: Alumnus other: Alumni university/organization: - one: Tierce partie - other: Tierces parties + one: Organisation + other: Organisations university/organization/import: one: Import other: Imports diff --git a/config/routes/admin/communication.rb b/config/routes/admin/communication.rb index 4ebcf1ce0531974450775c95d87cadc58b771641..8e3cfeb11a6f02f1bd38a25c432cc4585f7f19e5 100644 --- a/config/routes/admin/communication.rb +++ b/config/routes/admin/communication.rb @@ -25,7 +25,9 @@ namespace :communication do end end resources :authors, controller: 'website/authors', only: [:index, :show] - resources :posts, controller: 'website/posts' + resources :posts, controller: 'website/posts' do + post :publish, on: :collection + end resources :curations, path: 'posts/curations', as: :post_curations, @@ -44,7 +46,7 @@ namespace :communication do end get 'structure' => 'website/structure#edit' patch 'structure' => 'website/structure#update' - + end resources :blocks, controller: 'blocks', except: :index do collection do diff --git a/db/migrate/20220425150705_add_is_author_to_university_people.rb b/db/migrate/20220425150705_add_is_author_to_university_people.rb new file mode 100644 index 0000000000000000000000000000000000000000..287c2cb05772e3445ca8518061f49dc0e35df04b --- /dev/null +++ b/db/migrate/20220425150705_add_is_author_to_university_people.rb @@ -0,0 +1,5 @@ +class AddIsAuthorToUniversityPeople < ActiveRecord::Migration[6.1] + def change + add_column :university_people, :is_author, :boolean + end +end diff --git a/db/migrate/20220425152944_add_name_to_university_persons.rb b/db/migrate/20220425152944_add_name_to_university_persons.rb new file mode 100644 index 0000000000000000000000000000000000000000..dbe49902d68fc647fa56e3e8243f834f6b5e7917 --- /dev/null +++ b/db/migrate/20220425152944_add_name_to_university_persons.rb @@ -0,0 +1,5 @@ +class AddNameToUniversityPersons < ActiveRecord::Migration[6.1] + def change + add_column :university_people, :name, :string + end +end diff --git a/db/migrate/20220427072259_create_join_table_university_people_education_academic_year.rb b/db/migrate/20220427072259_create_join_table_university_people_education_academic_year.rb new file mode 100644 index 0000000000000000000000000000000000000000..9e28fe6f4ad5b2a17ce45db7427dec8f3e7925d2 --- /dev/null +++ b/db/migrate/20220427072259_create_join_table_university_people_education_academic_year.rb @@ -0,0 +1,8 @@ +class CreateJoinTableUniversityPeopleEducationAcademicYear < ActiveRecord::Migration[6.1] + def change + create_join_table :university_people, :education_academic_years, column_options: {type: :uuid} do |t| + t.index [:"university_person_id", :"education_academic_year_id"], name: 'index_person_academic_year' + t.index [:"education_academic_year_id", :"university_person_id"], name: 'index_academic_year_person' + end + end +end diff --git a/db/migrate/20220427094234_create_join_table_university_people_education_program.rb b/db/migrate/20220427094234_create_join_table_university_people_education_program.rb new file mode 100644 index 0000000000000000000000000000000000000000..b5452450c595010665c4398fbf656ceed72456bb --- /dev/null +++ b/db/migrate/20220427094234_create_join_table_university_people_education_program.rb @@ -0,0 +1,8 @@ +class CreateJoinTableUniversityPeopleEducationProgram < ActiveRecord::Migration[6.1] + def change + create_join_table :university_people, :education_programs, column_options: {type: :uuid} do |t| + t.index [:"university_person_id", :"education_program_id"], name: 'index_person_program' + t.index [:"education_program_id", :"university_person_id"], name: 'index_program_person' + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 0eae79db7e8a734c78fe9f1aa7e96c7a1b411065..1b22f72bbaac4ee2327c940af97a497eb44db2cf 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_04_21_093107) do +ActiveRecord::Schema.define(version: 2022_04_27_094234) do # These are extensions that must be enabled in order to support this database enable_extension "pgcrypto" @@ -407,6 +407,13 @@ ActiveRecord::Schema.define(version: 2022_04_21_093107) do t.index ["university_id"], name: "index_education_academic_years_on_university_id" end + create_table "education_academic_years_university_people", id: false, force: :cascade do |t| + t.uuid "university_person_id", null: false + t.uuid "education_academic_year_id", null: false + t.index ["education_academic_year_id", "university_person_id"], name: "index_academic_year_person" + t.index ["university_person_id", "education_academic_year_id"], name: "index_person_academic_year" + end + create_table "education_cohorts", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| t.uuid "university_id", null: false t.uuid "program_id", null: false @@ -467,6 +474,13 @@ ActiveRecord::Schema.define(version: 2022_04_21_093107) do t.index ["education_school_id", "education_program_id"], name: "school_program" end + create_table "education_programs_university_people", id: false, force: :cascade do |t| + t.uuid "university_person_id", null: false + t.uuid "education_program_id", null: false + t.index ["education_program_id", "university_person_id"], name: "index_program_person" + t.index ["university_person_id", "education_program_id"], name: "index_person_program" + end + create_table "education_programs_users", id: false, force: :cascade do |t| t.uuid "education_program_id", null: false t.uuid "user_id", null: false @@ -688,6 +702,8 @@ ActiveRecord::Schema.define(version: 2022_04_21_093107) do t.string "linkedin" t.boolean "is_alumnus", default: false t.text "description_short" + t.string "name" + t.boolean "is_author" t.index ["university_id"], name: "index_university_people_on_university_id" t.index ["user_id"], name: "index_university_people_on_user_id" end diff --git a/lib/tasks/app.rake b/lib/tasks/app.rake index 616dfe0f4cbf34b41bc0261d9369ef8b0d4bf344..c83caba11e229f3bca805868771096e0cbde6865 100644 --- a/lib/tasks/app.rake +++ b/lib/tasks/app.rake @@ -8,17 +8,9 @@ namespace :app do desc 'Fix things' task fix: :environment do - Communication::Block.where(template: 'partners').find_each do |partner| - next if partner.data.nil? - data = partner.data - next unless data.has_key? 'elements' - elements = data['elements'] - next if elements.none? - first = elements.first - next unless first.has_key? 'partners' - partner.title = first['title'] - partner.data['elements'] = first['partners'] - partner.save + University::Person.find_each do |person| + person.is_author = person.communication_website_posts.any? + person.save end end